Compare commits
1 Commits
dba38f71b1
...
sync
| Author | SHA1 | Date | |
|---|---|---|---|
| f27b647eb0 |
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
3
frontend/src/types/search.type.ts
Normal file
3
frontend/src/types/search.type.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import type { IEntity } from "./entity.type";
|
||||||
|
|
||||||
|
export type Search<T extends IEntity> = (input: string) => T[]
|
||||||
7
frontend/src/types/sort.type.ts
Normal file
7
frontend/src/types/sort.type.ts
Normal 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[]
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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> {
|
||||||
|
|||||||
6
frontend/src/utils/structs/default-sort.util.ts
Normal file
6
frontend/src/utils/structs/default-sort.util.ts
Normal 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>) => {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user