This commit is contained in:
2025-03-13 20:45:12 +07:00
parent 9c8dc41870
commit f27b647eb0
7 changed files with 123 additions and 41 deletions

View File

@@ -16,6 +16,7 @@ const posttypeService = new PosttypeService();
import CommentService from "../comment/comment.service.ts"; import CommentService from "../comment/comment.service.ts";
import { SortedByOrder } from "../../bindings/app/internal/services/postservice.ts"; import { SortedByOrder } from "../../bindings/app/internal/services/postservice.ts";
import type { Search } from "../types/search.type.ts";
const commentService = new CommentService(); const commentService = new CommentService();
@@ -132,10 +133,14 @@ const validate: Validate<Post> = (entity) => {
status: "success", status: "success",
}; };
}; };
const search: Search<Post> = (input) => {
}
</script> </script>
<template> <template>
<Table :scheme :service :get-defaults :load :items :validate > <Table :scheme :service :get-defaults :load :items :validate @on-search="search">
<template #CommentsCreate="{ data }"> <template #CommentsCreate="{ data }">
<p>{{ data }}</p> <p>{{ data }}</p>
</template> </template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts" generic="T extends IEntity"> <script setup lang="ts" generic="T extends IEntity">
import { onMounted, ref, watch, type UnwrapRef } from "vue"; import { onMounted, ref, watch, type UnwrapRef } from "vue";
import type { TableProps } from "../types/table-props.type"; import type { TableProps } from "../types/table-props.type";
import { DataTable, Column, Button } from "primevue"; import { DataTable, Column, Button, InputText } from "primevue";
import { manyStructsView } from "../utils/structs/structs-view.util"; import { manyStructsView } from "../utils/structs/structs-view.util";
import type { TableEmits } from "../types/table-emits.type"; import type { TableEmits } from "../types/table-emits.type";
import FloatingButton from "../components/buttons/FloatingButton.vue"; import FloatingButton from "../components/buttons/FloatingButton.vue";
@@ -12,7 +12,7 @@ import { viewDate } from "../utils/date/view.util";
const props = defineProps<TableProps<T>>(); const props = defineProps<TableProps<T>>();
onMounted(async () => { onMounted(async () => {
props.load() props.load();
}); });
type Key = keyof T; type Key = keyof T;
@@ -56,8 +56,8 @@ watch(createItem, (value) => {
}); });
const handleFloatingButtonClick = () => { const handleFloatingButtonClick = () => {
emits('onCreateOpen') emits("onCreateOpen");
emits('onOpen') emits("onOpen");
showCreate.value = true; showCreate.value = true;
}; };
const slots = defineSlots(); const slots = defineSlots();
@@ -65,23 +65,44 @@ const slots = defineSlots();
const createSlotName = (key: any) => key + "Create"; const createSlotName = (key: any) => key + "Create";
const updateSlotName = (key: any) => key + "Update"; const updateSlotName = (key: any) => key + "Update";
watch(() => props.items, () => { watch(
() => props.items,
() => {
if (props.colorize) { if (props.colorize) {
const trs = document.querySelectorAll("tr"); const trs = document.querySelectorAll("tr");
props.items.forEach(item => { props.items.forEach((item) => {
const tr = trs[item.Id]; const tr = trs[item.Id];
if (tr) { if (tr) {
tr.style.backgroundColor = props.colorize!(item); tr.style.backgroundColor = props.colorize!(item);
} }
}) });
} }
}) },
);
const input = defineModel<string>("search", { default: "" });
</script> </script>
<template> <template>
<DialogWindow :name :load :items :validate :scheme :service :get-defaults v-model:item="<T>createItem" <div class="flex h-10 justify-center m-4 gap-2">
v-model:show="showCreate" @on-save="data => emits('onSave', data)" <InputText v-model="input" placeholder="Поиск" class="h-full w-64" />
@on-save-create="data => emits('onSaveCreate', data)"> <Button class="h-full aspect-square" severity="secondary">
<span class="pi pi-search"></span>
</Button>
</div>
<DialogWindow
:name
:load
:items
:validate
:scheme
:service
:get-defaults
v-model:item="<T>createItem"
v-model:show="showCreate"
@on-save="(data) => emits('onSave', data)"
@on-save-create="(data) => emits('onSaveCreate', data)"
>
<template v-for="key in keys" #[key]="{ data }"> <template v-for="key in keys" #[key]="{ data }">
<slot :name="<string>key" :data></slot> <slot :name="<string>key" :data></slot>
</template> </template>
@@ -89,9 +110,20 @@ watch(() => props.items, () => {
<slot :name="createSlotName(key)" :data></slot> <slot :name="createSlotName(key)" :data></slot>
</template> </template>
</DialogWindow> </DialogWindow>
<DialogWindow :name :load :items :validate :scheme update-mode :service :get-defaults v-model:item="<T>updateItem" <DialogWindow
v-model:show="showUpdate" @on-save="data => emits('onSave', data)" :name
@on-save-update="data => emits('onSaveUpdate', data)"> :load
:items
:validate
:scheme
update-mode
:service
:get-defaults
v-model:item="<T>updateItem"
v-model:show="showUpdate"
@on-save="(data) => emits('onSave', data)"
@on-save-update="(data) => emits('onSaveUpdate', data)"
>
<template v-for="key in keys" #[key]="{ data }"> <template v-for="key in keys" #[key]="{ data }">
<slot :name="<string>key" :data></slot> <slot :name="<string>key" :data></slot>
</template> </template>
@@ -105,17 +137,31 @@ watch(() => props.items, () => {
<p>{{ props.name }}</p> <p>{{ props.name }}</p>
</template> </template>
<template v-for="key in keys"> <template v-for="key in keys">
<Column :header="props.scheme[key]?.russian" v-if="!props.scheme[key].hidden"> <Column
:header="props.scheme[key]?.russian"
v-if="!props.scheme[key].hidden"
>
<template #body="{ data }"> <template #body="{ data }">
<p class="truncate max-w-56" v-tooltip="viewDate(manyStructsView( <p
class="truncate max-w-56"
v-tooltip="
viewDate(
manyStructsView(
data[key], data[key],
props.scheme[key]?.type?.nested?.field, props.scheme[key]?.type?.nested?.field,
), scheme[key]?.type?.primitive)"> ),
scheme[key]?.type?.primitive,
)
"
>
{{ {{
viewDate(manyStructsView( viewDate(
manyStructsView(
data[key], data[key],
props.scheme[key]?.type?.nested?.field, props.scheme[key]?.type?.nested?.field,
), scheme[key]?.type?.primitive) ),
scheme[key]?.type?.primitive,
)
}} }}
</p> </p>
</template> </template>
@@ -124,16 +170,28 @@ watch(() => props.items, () => {
<Column header="Действия"> <Column header="Действия">
<template #body="{ data }"> <template #body="{ data }">
<div class="flex gap-2"> <div class="flex gap-2">
<Button severity="secondary" icon="pi pi-pencil" @click="async () => { <Button
await emits('onUpdateOpen') severity="secondary"
await emits('onOpen') icon="pi pi-pencil"
updateItem = data @click="
}"></Button> async () => {
<Button severity="danger" icon="pi pi-trash" @click="async () => { await emits('onUpdateOpen');
await emits('onDelete', data) await emits('onOpen');
await props.service.delete(data.Id) updateItem = data;
await load() }
}"></Button> "
></Button>
<Button
severity="danger"
icon="pi pi-trash"
@click="
async () => {
await emits('onDelete', data);
await props.service.delete(data.Id);
await load();
}
"
></Button>
</div> </div>
</template> </template>
</Column> </Column>

View File

@@ -0,0 +1,3 @@
import type { IEntity } from "./entity.type";
export type Search<T extends IEntity> = (input: string) => T[]

View File

@@ -0,0 +1,7 @@
import type { IEntity } from "./entity.type";
export type SortOptions<T extends IEntity> = {
[key in keyof T]: "ASC" | "DESC"
}
export type Sort<T extends IEntity> = (options: SortOptions<T>) => T[]

View File

@@ -9,4 +9,5 @@ export type TableEmits = {
(e: 'onSaveUpdate', data: any): Promise<void> | void (e: 'onSaveUpdate', data: any): Promise<void> | void
(e: 'onSaveCreate', data: any): Promise<void> | void (e: 'onSaveCreate', data: any): Promise<void> | void
(e: 'onSave', data: any): Promise<void> | void (e: 'onSave', data: any): Promise<void> | void
(e: 'onSearch', input: string): Promise<void> | void
} }

View File

@@ -1,6 +1,8 @@
import type { IEntity } from "./entity.type"; import type { IEntity } from "./entity.type";
import type { Scheme } from "./scheme.type"; import type { Scheme } from "./scheme.type";
import type { Search } from "./search.type";
import type { IService } from "./service.type"; import type { IService } from "./service.type";
import type { Sort } from "./sort.type";
import type { Validate } from "./validate.type"; import type { Validate } from "./validate.type";
export interface TableProps<T extends IEntity> { export interface TableProps<T extends IEntity> {

View File

@@ -0,0 +1,6 @@
import type { IEntity } from "../../types/entity.type";
import type { Scheme } from "../../types/scheme.type";
export const defaultSort = <T extends IEntity>(scheme: Scheme<T>) => {
}