Compare commits
1 Commits
dba38f71b1
...
sync
| Author | SHA1 | Date | |
|---|---|---|---|
| f27b647eb0 |
@@ -50,13 +50,14 @@ wails3 generate bindings -ts
|
|||||||
Для финальной сборки запустите эту команду в директории проекта:
|
Для финальной сборки запустите эту команду в директории проекта:
|
||||||
|
|
||||||
```
|
```
|
||||||
PRODUCTION=true wails3 build
|
go env -w CGO_ENABLED=1
|
||||||
|
wails3 build -clean -upx -v 2 -webview2 embed
|
||||||
```
|
```
|
||||||
|
|
||||||
**Перед релизом не забыть**:
|
**Перед релизом не забыть**:
|
||||||
- убедиться, что дефолтные данные правильные
|
|
||||||
- убедиться, что приложение запускается
|
- поместить все нужные asset'ы в папку assets
|
||||||
- (опционально) поместить все нужные asset'ы в папку assets
|
- изменить версию схемы БД (пока не нужно)
|
||||||
- приложить сопроводительную записку.
|
- приложить сопроводительную записку.
|
||||||
|
|
||||||
## Работа без GitHub
|
## Работа без GitHub
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" -tags "sqlite_icu"{{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
|
||||||
env:
|
env:
|
||||||
GOOS: darwin
|
GOOS: darwin
|
||||||
CGO_ENABLED: 1
|
CGO_ENABLED: 1
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" -tags "sqlite_icu" {{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
|
||||||
env:
|
env:
|
||||||
GOOS: linux
|
GOOS: linux
|
||||||
CGO_ENABLED: 1
|
CGO_ENABLED: 1
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ tasks:
|
|||||||
- cmd: rm -f *.syso
|
- cmd: rm -f *.syso
|
||||||
platforms: [linux, darwin]
|
platforms: [linux, darwin]
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production sqlite_icu" -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l" -tags "sqlite_icu"{{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l"{{end}}'
|
||||||
env:
|
env:
|
||||||
GOOS: windows
|
GOOS: windows
|
||||||
CGO_ENABLED: 1
|
CGO_ENABLED: 1
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const load = async () => {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await load();
|
await load();
|
||||||
|
console.log(await SortedByOrder({"Comments": "DESC"}))
|
||||||
});
|
});
|
||||||
|
|
||||||
const scheme: Scheme<Author> = reactive({
|
const scheme: Scheme<Author> = reactive({
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const pushOrRemove = (option: T) => {
|
|||||||
} else {
|
} else {
|
||||||
selected.value.push(option)
|
selected.value.push(option)
|
||||||
}
|
}
|
||||||
|
//setNullIds()
|
||||||
}
|
}
|
||||||
|
|
||||||
const setNullIds = () => {
|
const setNullIds = () => {
|
||||||
@@ -26,11 +27,12 @@ const setNullIds = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//onMounted(setNullIds)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="">
|
<div class="">
|
||||||
<ul class="max-h-48 h-auto overflow-y-auto background rounded-md p-3 w-full native-border">
|
<ul class="max-h-48 h-auto overflow-y-auto background rounded-md p-3 w-full border-gray-500 border">
|
||||||
<li v-for="option in options" :key="option.Id" class="flex items-center gap-2">
|
<li v-for="option in options" :key="option.Id" class="flex items-center gap-2">
|
||||||
<Checkbox :checked="selected.some(item => item.Id == option.Id)" @click="pushOrRemove(option)" />
|
<Checkbox :checked="selected.some(item => item.Id == option.Id)" @click="pushOrRemove(option)" />
|
||||||
<label :for="option.Id.toString()">{{ structView(option, path) }}</label>
|
<label :for="option.Id.toString()">{{ structView(option, path) }}</label>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Table from "../table/Table.vue";
|
import Table from "../table/Table.vue";
|
||||||
import {onMounted, reactive, watch} from "vue";
|
import { onMounted, reactive } from "vue";
|
||||||
import { getDefaultValues } from "../utils/structs/defaults.util";
|
import { getDefaultValues } from "../utils/structs/defaults.util";
|
||||||
import Service from "./post.service.ts";
|
import Service from "./post.service.ts";
|
||||||
import type { Scheme } from "../types/scheme.type";
|
import type { Scheme } from "../types/scheme.type";
|
||||||
@@ -16,7 +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 {getDefaultSortOptions} from "../utils/structs/default-sort-options.util.ts";
|
import type { Search } from "../types/search.type.ts";
|
||||||
|
|
||||||
const commentService = new CommentService();
|
const commentService = new CommentService();
|
||||||
|
|
||||||
@@ -33,12 +33,13 @@ const load = async () => {
|
|||||||
(scheme as any).Comments.type!.nested!.values =
|
(scheme as any).Comments.type!.nested!.values =
|
||||||
await commentService.readAll();
|
await commentService.readAll();
|
||||||
|
|
||||||
items.value = await service.sort(sortOptions.value) ;
|
items.value = await service.readAll();
|
||||||
return items.value;
|
return items.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await load();
|
await load();
|
||||||
|
console.log(await SortedByOrder({ "Author": "DESC", "Text": "ASC" }));
|
||||||
});
|
});
|
||||||
|
|
||||||
const scheme: Scheme<Post> = reactive({
|
const scheme: Scheme<Post> = reactive({
|
||||||
@@ -116,6 +117,9 @@ const scheme: Scheme<Post> = reactive({
|
|||||||
values: [],
|
values: [],
|
||||||
field: ["Text"],
|
field: ["Text"],
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
customWindow: {
|
||||||
|
create: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -130,15 +134,15 @@ const validate: Validate<Post> = (entity) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = async (input: string) => {
|
const search: Search<Post> = (input) => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortOptions = ref(getDefaultSortOptions(scheme))
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Table :scheme :service :get-defaults :load :items :validate @on-search="search" v-model:sort-options="sortOptions"></Table>
|
<Table :scheme :service :get-defaults :load :items :validate @on-search="search">
|
||||||
|
<template #CommentsCreate="{ data }">
|
||||||
|
<p>{{ data }}</p>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import {
|
|||||||
Delete,
|
Delete,
|
||||||
GetById,
|
GetById,
|
||||||
Update,
|
Update,
|
||||||
Count, SortedByOrder,
|
Count,
|
||||||
} from "../../bindings/app/internal/services/postservice.ts";
|
} from "../../bindings/app/internal/services/postservice.ts";
|
||||||
import type { Post } from "../../bindings/app/internal/services";
|
import type { Post } from "../../bindings/app/internal/services";
|
||||||
import type { IService } from "../types/service.type.ts";
|
import type { IService } from "../types/service.type.ts";
|
||||||
import type {SortOptions} from "../types/sort-options.type.ts";
|
|
||||||
|
|
||||||
export default class PostService implements IService<Post> {
|
export default class PostService implements IService<Post> {
|
||||||
async read(id: number) {
|
async read(id: number) {
|
||||||
@@ -34,8 +33,4 @@ export default class PostService implements IService<Post> {
|
|||||||
async count() {
|
async count() {
|
||||||
return await Count();
|
return await Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
async sort(options: SortOptions<Post>) {
|
|
||||||
return await SortedByOrder(options) as Post[]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,10 @@
|
|||||||
|
|
||||||
html, body, .background {
|
html, body, .background {
|
||||||
background: white;
|
background: white;
|
||||||
color: rgb(51, 65, 85);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary-background {
|
|
||||||
background: var(--p-content-background)
|
|
||||||
}
|
|
||||||
|
|
||||||
.native-border {
|
|
||||||
border: 1px solid var(--p-select-border-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html, body, .background {
|
html, body, .background {
|
||||||
background: #121212;
|
background: #121212;
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.native-border {
|
|
||||||
border: 1px solid rgb(100, 100, 109);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ async function handleSave() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Dialog v-model:visible="showCreate" class="w-[500px]">
|
<Dialog v-model:visible="showCreate">
|
||||||
<template #header>
|
<template #header>
|
||||||
<h1>{{ props.updateMode ? 'Изменить' : 'Создать' }} {{ props.name?.toLowerCase() }}</h1>
|
<h1>{{ props.updateMode ? 'Изменить' : 'Создать' }} {{ props.name?.toLowerCase() }}</h1>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
<script setup lang="ts" generic="T extends IEntity">
|
|
||||||
import type {IEntity} from "../types/entity.type.ts";
|
|
||||||
import type {SortOptions} from "../types/sort-options.type.ts";
|
|
||||||
import type {Scheme} from "../types/scheme.type.ts";
|
|
||||||
import {Select} from 'primevue'
|
|
||||||
import {watch} from "vue";
|
|
||||||
|
|
||||||
|
|
||||||
const options = defineModel<SortOptions<T>>()
|
|
||||||
const optionsKeys = Object.keys(options.value as T) as (keyof T)[]
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
scheme: Scheme<T>
|
|
||||||
load: () => Promise<T[]>
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ul class="flex flex-col gap-2 native-border secondary-background p-3 rounded-md">
|
|
||||||
<li v-for="optionKey in optionsKeys" class="flex items-center justify-between w-full">
|
|
||||||
<h1>{{ scheme[optionKey].russian }}</h1>
|
|
||||||
<Select size="small" class="w-24" :options="['ASC', 'DESC']" v-model="options![optionKey]" @value-change="load"></Select>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
@@ -8,11 +8,13 @@ import FloatingButton from "../components/buttons/FloatingButton.vue";
|
|||||||
import type { IEntity } from "../types/entity.type";
|
import type { IEntity } from "../types/entity.type";
|
||||||
import DialogWindow from "./DialogWindow.vue";
|
import DialogWindow from "./DialogWindow.vue";
|
||||||
import { viewDate } from "../utils/date/view.util";
|
import { viewDate } from "../utils/date/view.util";
|
||||||
import SortingOptions from "./SortingOptions.vue";
|
|
||||||
import type {SortOptions} from "../types/sort-options.type.ts";
|
|
||||||
|
|
||||||
const props = defineProps<TableProps<T>>();
|
const props = defineProps<TableProps<T>>();
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
props.load();
|
||||||
|
});
|
||||||
|
|
||||||
type Key = keyof T;
|
type Key = keyof T;
|
||||||
const keys = Object.keys(props.scheme) as Key[];
|
const keys = Object.keys(props.scheme) as Key[];
|
||||||
const emits = defineEmits<TableEmits>();
|
const emits = defineEmits<TableEmits>();
|
||||||
@@ -54,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();
|
||||||
@@ -63,60 +65,70 @@ 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 = ref('')
|
|
||||||
const sortOptions = defineModel<SortOptions<T>>('sort-options');
|
|
||||||
const showSortOptions = ref(false)
|
|
||||||
|
|
||||||
|
const input = defineModel<string>("search", { default: "" });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="m-2 flex flex-col items-center gap-2">
|
<div class="flex h-10 justify-center m-4 gap-2">
|
||||||
<div class="flex flex-col gap-2 relative">
|
<InputText v-model="input" placeholder="Поиск" class="h-full w-64" />
|
||||||
<div class="flex items-center justify-center gap-2 h-10">
|
<Button class="h-full aspect-square" severity="secondary">
|
||||||
<Button severity="secondary" class="h-full aspect-square" @click="showSortOptions = !showSortOptions">
|
|
||||||
<span class="pi pi-sort"></span>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<InputText class="h-full w-64" v-model="input"/>
|
|
||||||
<Button severity="secondary" class="h-full aspect-square" @click="emits('onSearch', input)">
|
|
||||||
<span class="pi pi-search"></span>
|
<span class="pi pi-search"></span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<SortingOptions v-model="sortOptions as SortOptions<T>" :scheme v-if="showSortOptions"
|
<DialogWindow
|
||||||
class="absolute z-10 w-full top-full translate-y-2" :load="props.load"></SortingOptions>
|
:name
|
||||||
</div>
|
:load
|
||||||
|
:items
|
||||||
</div>
|
:validate
|
||||||
<DialogWindow :name :load :items :validate :scheme :service :get-defaults v-model:item="<T>createItem"
|
:scheme
|
||||||
v-model:show="showCreate" @on-save="data => emits('onSave', data)"
|
:service
|
||||||
@on-save-create="data => emits('onSaveCreate', data)">
|
: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="data"></slot>
|
<slot :name="<string>key" :data></slot>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="key in keys" #[createSlotName(key)]="{ data }">
|
<template v-for="key in keys" #[createSlotName(key)]="{ data }">
|
||||||
<slot :name="createSlotName(key)" :data="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="data"></slot>
|
<slot :name="<string>key" :data></slot>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="key in keys" #[updateSlotName(key)]="{ data }">
|
<template v-for="key in keys" #[updateSlotName(key)]="{ data }">
|
||||||
<slot :name="updateSlotName(key)" :data="data"></slot>
|
<slot :name="updateSlotName(key)" :data></slot>
|
||||||
</template>
|
</template>
|
||||||
</DialogWindow>
|
</DialogWindow>
|
||||||
<div>
|
<div>
|
||||||
@@ -125,17 +137,31 @@ const showSortOptions = ref(false)
|
|||||||
<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>
|
||||||
@@ -144,27 +170,31 @@ const showSortOptions = ref(false)
|
|||||||
<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>
|
||||||
<template #paginatorstart>
|
|
||||||
<Button severity="secondary" @click="props.load">
|
|
||||||
<span class="pi pi-refresh"></span>
|
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
<template #paginatorend>
|
|
||||||
<span></span>
|
|
||||||
</template>
|
|
||||||
</DataTable>
|
</DataTable>
|
||||||
<FloatingButton @click="handleFloatingButtonClick" />
|
<FloatingButton @click="handleFloatingButtonClick" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
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[]
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { IEntity } from "./entity.type";
|
|
||||||
import type { Sorting } from "./sorting.type";
|
|
||||||
|
|
||||||
export type SortOptions<T extends IEntity> = {
|
|
||||||
[key in keyof Partial<T>]: Sorting
|
|
||||||
}
|
|
||||||
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[]
|
||||||
@@ -1 +0,0 @@
|
|||||||
export type Sorting = "DESC" | "ASC"
|
|
||||||
@@ -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> {
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import type { IEntity } from "../../types/entity.type";
|
|
||||||
import type { Scheme } from "../../types/scheme.type";
|
|
||||||
import type { SortOptions } from "../../types/sort-options.type";
|
|
||||||
|
|
||||||
export const getDefaultSortOptions = <T extends IEntity>(scheme: Scheme<T>): SortOptions<T> => {
|
|
||||||
const keys = Object.keys(scheme) as (keyof T)[]
|
|
||||||
const result: Partial<SortOptions<T>> = {}
|
|
||||||
|
|
||||||
keys.forEach(key => {
|
|
||||||
if (!scheme[key].hidden && key !== 'entityId' && !scheme[key].many) {
|
|
||||||
result[key] = 'ASC'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return result as SortOptions<T>
|
|
||||||
}
|
|
||||||
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>) => {
|
||||||
|
|
||||||
|
}
|
||||||
18
package-lock.json
generated
Normal file
18
package-lock.json
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "boilerplate",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"@wailsio/runtime": "3.0.0-alpha.66"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@wailsio/runtime": {
|
||||||
|
"version": "3.0.0-alpha.66",
|
||||||
|
"resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.66.tgz",
|
||||||
|
"integrity": "sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"@wailsio/runtime": "3.0.0-alpha.66"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
pnpm-lock.yaml
generated
Normal file
22
pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@wailsio/runtime':
|
||||||
|
specifier: 3.0.0-alpha.66
|
||||||
|
version: 3.0.0-alpha.66
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@wailsio/runtime@3.0.0-alpha.66':
|
||||||
|
resolution: {integrity: sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==}
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@wailsio/runtime@3.0.0-alpha.66': {}
|
||||||
Reference in New Issue
Block a user