chore: remove files and lists
This commit is contained in:
parent
ba555590ee
commit
165ac3349d
28 changed files with 11 additions and 411 deletions
|
@ -7,8 +7,7 @@ import TheBrandLogo from "./TheBrandLogo.vue";
|
|||
<div class="container">
|
||||
<TheBrandLogo class="logo" />
|
||||
<BaseNav>
|
||||
<RouterLink :to="{ name: 'email_files' }">Файлы</RouterLink>
|
||||
<RouterLink :to="{ name: 'audience' }">Аудитория</RouterLink>
|
||||
<RouterLink :to="{ name: 'audience_contacts' }">Контакты</RouterLink>
|
||||
</BaseNav>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useFilesTableStore } from "./store";
|
||||
import { formatDate } from "@/shared/lib/utils/date";
|
||||
|
||||
const filesStore = useFilesTableStore();
|
||||
|
||||
const columns = computed(() => [
|
||||
{ key: "name", title: "Название" },
|
||||
{ key: "createdAt", title: "Дата создания" },
|
||||
]);
|
||||
|
||||
filesStore.fetchMany();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseTable
|
||||
:loading="filesStore.loading"
|
||||
:columns="columns"
|
||||
:dataItems="filesStore.files"
|
||||
>
|
||||
<template #createdAt="{ dataItem }">
|
||||
{{ formatDate(dataItem.createdAt) }}
|
||||
</template>
|
||||
</BaseTable>
|
||||
</template>
|
|
@ -1,3 +0,0 @@
|
|||
export { default as FilesTable } from "./FilesTable.vue";
|
||||
export * from "./ports";
|
||||
export { FILES_TABLE_API_PROVIDE_KEY } from "./store";
|
|
@ -1,4 +0,0 @@
|
|||
import type { BaseFetchManyApiPort } from "@/shared/lib/ports";
|
||||
import type { AppFile } from "../domain";
|
||||
|
||||
export type FilesTableApiPort = BaseFetchManyApiPort<AppFile>;
|
|
@ -1,28 +0,0 @@
|
|||
import { useLoader } from "@/shared/lib/composables/loader";
|
||||
import { defineInjectKey, validInject } from "@/shared/lib/di";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { reactive } from "vue";
|
||||
import { useFilesStore } from "../store";
|
||||
import type { FilesTableApiPort } from "./ports";
|
||||
|
||||
export const FILES_TABLE_API_PROVIDE_KEY =
|
||||
defineInjectKey<FilesTableApiPort>("FilesTableApi");
|
||||
|
||||
export function useFilesTableStore() {
|
||||
const api = validInject(FILES_TABLE_API_PROVIDE_KEY);
|
||||
|
||||
const filesStore = useFilesStore();
|
||||
const { files } = storeToRefs(filesStore);
|
||||
|
||||
const loader = useLoader();
|
||||
async function fetchMany() {
|
||||
const files = await loader.wait(api.fetchMany({}));
|
||||
filesStore.setFiles(files);
|
||||
}
|
||||
|
||||
return reactive({
|
||||
loading: loader.loading,
|
||||
files,
|
||||
fetchMany,
|
||||
});
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import type { Entity } from "@/shared/lib/entity";
|
||||
|
||||
export interface AppFile extends Entity {
|
||||
name: string;
|
||||
createdAt: Date;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export type { AppFile } from "./file";
|
|
@ -1,3 +0,0 @@
|
|||
import type { FilesTableApiPort } from "./FilesTable";
|
||||
|
||||
export type FileApiPort = FilesTableApiPort;
|
|
@ -1,17 +0,0 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import type { AppFile } from "./domain";
|
||||
|
||||
export const useFilesStore = defineStore("files", () => {
|
||||
const data = ref([] as AppFile[]);
|
||||
|
||||
function setFiles(files: AppFile[]): void {
|
||||
data.value = files;
|
||||
}
|
||||
|
||||
function addFile(file: AppFile): void {
|
||||
data.value.unshift(file);
|
||||
}
|
||||
|
||||
return { files: data, setFiles, addFile };
|
||||
});
|
|
@ -1,35 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, defineEmits } from "vue";
|
||||
import { useListFormStore } from "./store";
|
||||
import type { CreateListData } from "@/app_core/ports/list";
|
||||
|
||||
const emit = defineEmits(["submitForm"]);
|
||||
|
||||
const store = useListFormStore();
|
||||
|
||||
const listData = ref({
|
||||
displayName: "",
|
||||
} as CreateListData);
|
||||
|
||||
async function submitForm() {
|
||||
await store.create(listData.value);
|
||||
emit("submitForm");
|
||||
listData.value = { displayName: "" };
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<label>Отображаемое имя</label>
|
||||
<input v-model="listData.displayName" />
|
||||
</div>
|
||||
<BaseButton
|
||||
:isPrimary="true"
|
||||
:isLoading="store.loading"
|
||||
@click="submitForm"
|
||||
>
|
||||
Добавить
|
||||
</BaseButton>
|
||||
</div>
|
||||
</template>
|
|
@ -1,3 +0,0 @@
|
|||
export { default as AudienceListForm } from "./AudienceListForm.vue";
|
||||
export * from "./ports";
|
||||
export { LIST_FORM_API_PROVIDE_KEY } from "./store";
|
|
@ -1,8 +0,0 @@
|
|||
import type { BaseCreateApiPort } from "@/shared/lib/ports";
|
||||
import type { List } from "../domain";
|
||||
|
||||
export interface ListFormApiCreateProps {
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
export type ListFormApiPort = BaseCreateApiPort<List, ListFormApiCreateProps>;
|
|
@ -1,25 +0,0 @@
|
|||
import { useLoader } from "@/shared/lib/composables/loader";
|
||||
import { defineInjectKey, validInject } from "@/shared/lib/di";
|
||||
import { reactive } from "vue";
|
||||
import { useListsStore } from "../store";
|
||||
import type { ListFormApiCreateProps, ListFormApiPort } from "./ports";
|
||||
|
||||
export const LIST_FORM_API_PROVIDE_KEY =
|
||||
defineInjectKey<ListFormApiPort>("ListFormApi");
|
||||
|
||||
export function useListFormStore() {
|
||||
const api = validInject(LIST_FORM_API_PROVIDE_KEY);
|
||||
|
||||
const listsStore = useListsStore();
|
||||
|
||||
const loader = useLoader();
|
||||
async function create(data: ListFormApiCreateProps) {
|
||||
const list = await loader.wait(api.create(data));
|
||||
listsStore.addList(list);
|
||||
}
|
||||
|
||||
return reactive({
|
||||
loading: loader.loading,
|
||||
create,
|
||||
});
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useListsTableStore } from "./store";
|
||||
|
||||
const store = useListsTableStore();
|
||||
|
||||
const columns = computed(() => [{ key: "displayName", title: "Название" }]);
|
||||
|
||||
store.fetchMany();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseTable
|
||||
:loading="store.loading"
|
||||
:columns="columns"
|
||||
:dataItems="store.lists"
|
||||
>
|
||||
<template #displayName="{ dataItem }">
|
||||
<RouterLink
|
||||
:to="{ name: 'audience_contacts', params: { listId: dataItem.id } }"
|
||||
>
|
||||
{{ dataItem.displayName }}
|
||||
</RouterLink>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</template>
|
|
@ -1,3 +0,0 @@
|
|||
export { default as AudienceListsTable } from "./AudienceListsTable.vue";
|
||||
export * from "./ports";
|
||||
export { LISTS_TABLE_API_PROVIDE_KEY } from "./store";
|
|
@ -1,4 +0,0 @@
|
|||
import type { BaseFetchManyApiPort } from "@/shared/lib/ports";
|
||||
import type { List } from "../domain";
|
||||
|
||||
export type ListsTableApiPort = BaseFetchManyApiPort<List>;
|
|
@ -1,28 +0,0 @@
|
|||
import { useLoader } from "@/shared/lib/composables/loader";
|
||||
import { defineInjectKey, validInject } from "@/shared/lib/di";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { reactive } from "vue";
|
||||
import { useListsStore } from "../store";
|
||||
import type { ListsTableApiPort } from "./ports";
|
||||
|
||||
export const LISTS_TABLE_API_PROVIDE_KEY =
|
||||
defineInjectKey<ListsTableApiPort>("ListsTableApi");
|
||||
|
||||
export function useListsTableStore() {
|
||||
const api = validInject(LISTS_TABLE_API_PROVIDE_KEY);
|
||||
|
||||
const listsStore = useListsStore();
|
||||
const { lists } = storeToRefs(listsStore);
|
||||
|
||||
const loader = useLoader();
|
||||
async function fetchMany() {
|
||||
const lists = await loader.wait(api.fetchMany({}));
|
||||
listsStore.setLists(lists);
|
||||
}
|
||||
|
||||
return reactive({
|
||||
loading: loader.loading,
|
||||
lists,
|
||||
fetchMany,
|
||||
});
|
||||
}
|
|
@ -1,8 +1,3 @@
|
|||
import type { ListsTableApiPort } from "./ListsTable";
|
||||
import type { ListsSelectApiPort } from "./ListsSelect";
|
||||
import type { ListFormApiPort } from "./ListForm";
|
||||
export type { ListFormApiCreateProps } from "./ListForm";
|
||||
|
||||
export type ListApiPort = ListsTableApiPort &
|
||||
ListsSelectApiPort &
|
||||
ListFormApiPort;
|
||||
export type ListApiPort = ListsSelectApiPort;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import type { FileApiPort } from "@/app/files";
|
||||
import type { AppFile } from "@/app/files/domain";
|
||||
import { delay } from "@/shared/lib/utils/promise";
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
let $instance: FileApiPort | undefined;
|
||||
|
||||
export class MockFileApi implements FileApiPort {
|
||||
#files: AppFile[];
|
||||
|
||||
constructor() {
|
||||
this.#files = Array.from(new Array(20).keys()).map((_) => {
|
||||
const id = faker.datatype.uuid();
|
||||
const name = faker.system.fileName();
|
||||
const createdAt = faker.date.birthdate();
|
||||
return { id, name, createdAt };
|
||||
});
|
||||
}
|
||||
|
||||
static getInstance() {
|
||||
if (!$instance) {
|
||||
$instance = new MockFileApi();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
async fetchMany(): Promise<AppFile[]> {
|
||||
await delay(1000);
|
||||
return this.#files.concat();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import type { ListApiPort, ListFormApiCreateProps } from "@/app/lists";
|
||||
import type { ListApiPort } from "@/app/lists";
|
||||
import type { List } from "@/app/lists/domain";
|
||||
import { delay } from "@/shared/lib/utils/promise";
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
@ -23,17 +23,6 @@ export class MockListApi implements ListApiPort {
|
|||
return $instance;
|
||||
}
|
||||
|
||||
async create(createListData: ListFormApiCreateProps): Promise<List> {
|
||||
const list: List = {
|
||||
id: faker.datatype.uuid(),
|
||||
...createListData,
|
||||
};
|
||||
|
||||
this.#lists.unshift(list);
|
||||
await delay(1000);
|
||||
return list;
|
||||
}
|
||||
|
||||
async fetchMany(): Promise<List[]> {
|
||||
await delay(1000);
|
||||
return this.#lists.concat();
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { provide } from "vue";
|
||||
import {
|
||||
FilesTable,
|
||||
FILES_TABLE_API_PROVIDE_KEY,
|
||||
} from "@/app/files/FilesTable";
|
||||
import { useMeta } from "@/shared/lib/composables/meta";
|
||||
import { MockFileApi } from "@/infra/api/file";
|
||||
|
||||
useMeta("Файлы | SM");
|
||||
|
||||
const fileApi = MockFileApi.getInstance();
|
||||
provide(FILES_TABLE_API_PROVIDE_KEY, fileApi);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<BasePageHeader>
|
||||
Файлы
|
||||
<template #extra>
|
||||
<BaseButton :isPrimary="true">Добавить файл</BaseButton>
|
||||
</template>
|
||||
</BasePageHeader>
|
||||
<FilesTable />
|
||||
</div>
|
||||
</template>
|
|
@ -1,33 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { provide } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
AudienceListForm,
|
||||
LIST_FORM_API_PROVIDE_KEY,
|
||||
} from "@/app/lists/ListForm";
|
||||
import { useMeta } from "@/shared/lib/composables/meta";
|
||||
import { MockListApi } from "@/infra/api/list";
|
||||
|
||||
useMeta("Создание списка | Аудитория | SM");
|
||||
|
||||
const listApi = MockListApi.getInstance();
|
||||
provide(LIST_FORM_API_PROVIDE_KEY, listApi);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function redirectToLists() {
|
||||
router.push({ name: "audience_lists" });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<BasePageHeader>
|
||||
Создание списка
|
||||
<template #extra>
|
||||
<BaseButton @click="redirectToLists">Отменить</BaseButton>
|
||||
</template>
|
||||
</BasePageHeader>
|
||||
<AudienceListForm @submitForm="redirectToLists" />
|
||||
</div>
|
||||
</template>
|
|
@ -1,35 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { provide } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
AudienceListsTable,
|
||||
LISTS_TABLE_API_PROVIDE_KEY,
|
||||
} from "@/app/lists/ListsTable";
|
||||
import { useMeta } from "@/shared/lib/composables/meta";
|
||||
import { MockListApi } from "@/infra/api/list";
|
||||
|
||||
useMeta("Списки | Аудитория | SM");
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function openAddListForm() {
|
||||
router.push({ name: "audience_create_list" });
|
||||
}
|
||||
|
||||
const listsApi = MockListApi.getInstance();
|
||||
provide(LISTS_TABLE_API_PROVIDE_KEY, listsApi);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<BasePageHeader>
|
||||
Списки
|
||||
<template #extra>
|
||||
<BaseButton :isPrimary="true" @click="openAddListForm">
|
||||
Добавить список
|
||||
</BaseButton>
|
||||
</template>
|
||||
</BasePageHeader>
|
||||
<AudienceListsTable />
|
||||
</div>
|
||||
</template>
|
|
@ -1,14 +0,0 @@
|
|||
<script>
|
||||
import { useMeta } from "@/shared/lib/composables/meta";
|
||||
useMeta("Аудитория | SM");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<BaseNav>
|
||||
<RouterLink :to="{ name: 'audience_contacts' }">Контакты</RouterLink>
|
||||
<RouterLink :to="{ name: 'audience_lists' }">Списки</RouterLink>
|
||||
</BaseNav>
|
||||
</div>
|
||||
<RouterView />
|
||||
</template>
|
|
@ -53,7 +53,6 @@ provide(LISTS_SELECT_API_PROVIDE_KEY, listApi);
|
|||
Контакты
|
||||
<template #extra>
|
||||
<BaseButton @click="openAddContactForm">Добавить контакт</BaseButton>
|
||||
<BaseButton :isPrimary="true">Импортировать контакты</BaseButton>
|
||||
</template>
|
||||
</BasePageHeader>
|
||||
<AudienceListsSelect
|
|
@ -1,31 +1,13 @@
|
|||
const audienceRoutes = [
|
||||
{
|
||||
path: "/audience",
|
||||
name: "audience",
|
||||
redirect: { name: "audience_contacts" },
|
||||
component: () => import("./AudiencePage.vue"),
|
||||
children: [
|
||||
{
|
||||
path: "contacts/new",
|
||||
name: "audience_create_contact",
|
||||
component: () => import("./AudienceCreateContactPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "contacts/:listId?",
|
||||
name: "audience_contacts",
|
||||
component: () => import("./AudienceContactsPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "lists/new",
|
||||
name: "audience_create_list",
|
||||
component: () => import("./AudienceCreateListPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "lists",
|
||||
name: "audience_lists",
|
||||
component: () => import("./AudienceListsPage.vue"),
|
||||
},
|
||||
],
|
||||
path: "/contacts/new",
|
||||
name: "audience_create_contact",
|
||||
component: () => import("./CreateContactPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "/contacts/:listId?",
|
||||
name: "audience_contacts",
|
||||
component: () => import("./ContactsPage.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -10,11 +10,6 @@ const router = createRouter({
|
|||
redirect: { name: "audience" },
|
||||
},
|
||||
...audienceRoutes,
|
||||
{
|
||||
path: "/files",
|
||||
name: "email_files",
|
||||
component: () => import("./FilesPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "not_found",
|
||||
|
|
Loading…
Reference in a new issue