@hywax/cms 0.0.23 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nuxt/cms/editor/index.ts +0 -2
- package/.nuxt/cms/form-panel-section.ts +2 -2
- package/.nuxt/cms/index.ts +8 -21
- package/.nuxt/cms/table-search-input.ts +6 -0
- package/dist/module.json +3 -3
- package/dist/module.mjs +78 -203
- package/dist/runtime/components/AutocompleteSelect.d.vue.ts +56 -0
- package/dist/runtime/components/AutocompleteSelect.vue +131 -77
- package/dist/runtime/components/AutocompleteSelect.vue.d.ts +43 -29
- package/dist/runtime/components/{ButtonDelete.vue.d.ts → ButtonDeleteConfirm.d.vue.ts} +4 -3
- package/dist/runtime/components/{ButtonDelete.vue → ButtonDeleteConfirm.vue} +1 -1
- package/dist/runtime/components/ButtonDeleteConfirm.vue.d.ts +36 -0
- package/dist/runtime/components/DatePicker.d.vue.ts +43 -0
- package/dist/runtime/components/DatePicker.vue +232 -0
- package/dist/runtime/components/DatePicker.vue.d.ts +43 -0
- package/dist/runtime/components/EditorFull.d.vue.ts +13 -0
- package/dist/runtime/components/EditorFull.vue +127 -0
- package/dist/runtime/components/EditorFull.vue.d.ts +13 -0
- package/dist/runtime/components/EditorLinkPopover.d.vue.ts +8 -0
- package/dist/runtime/components/EditorLinkPopover.vue +137 -0
- package/dist/runtime/components/EditorLinkPopover.vue.d.ts +8 -0
- package/dist/runtime/components/FormPanel.d.vue.ts +47 -0
- package/dist/runtime/components/FormPanel.vue +10 -7
- package/dist/runtime/components/FormPanel.vue.d.ts +21 -15
- package/dist/runtime/components/FormPanelAsideSection.d.vue.ts +24 -0
- package/dist/runtime/components/FormPanelAsideSection.vue.d.ts +2 -1
- package/dist/runtime/components/FormPanelSection.d.vue.ts +21 -0
- package/dist/runtime/components/FormPanelSection.vue +2 -2
- package/dist/runtime/components/FormPanelSection.vue.d.ts +3 -2
- package/dist/runtime/components/Layout.d.vue.ts +27 -0
- package/dist/runtime/components/Layout.vue +79 -0
- package/dist/runtime/components/Layout.vue.d.ts +27 -0
- package/dist/runtime/components/ModalConfirm.d.vue.ts +33 -0
- package/dist/runtime/components/ModalConfirm.vue.d.ts +3 -2
- package/dist/runtime/components/TableColumnSorting.d.vue.ts +17 -0
- package/dist/runtime/components/{TablePanelColumnSorting.vue → TableColumnSorting.vue} +27 -18
- package/dist/runtime/components/TableColumnSorting.vue.d.ts +17 -0
- package/dist/runtime/components/TableColumnVisibility.d.vue.ts +24 -0
- package/dist/runtime/components/TableColumnVisibility.vue +111 -0
- package/dist/runtime/components/TableColumnVisibility.vue.d.ts +24 -0
- package/dist/runtime/components/TableFilters.d.vue.ts +90 -0
- package/dist/runtime/components/TableFilters.vue +198 -0
- package/dist/runtime/components/TableFilters.vue.d.ts +90 -0
- package/dist/runtime/components/TablePanel.d.vue.ts +95 -0
- package/dist/runtime/components/TablePanel.vue +207 -66
- package/dist/runtime/components/TablePanel.vue.d.ts +76 -31
- package/dist/runtime/components/TableSearchInput.d.vue.ts +33 -0
- package/dist/runtime/components/TableSearchInput.vue +96 -0
- package/dist/runtime/components/TableSearchInput.vue.d.ts +33 -0
- package/dist/runtime/components/UploraImage.d.vue.ts +35 -0
- package/dist/runtime/components/UploraImage.vue.d.ts +3 -2
- package/dist/runtime/components/prose/UploraImage.d.vue.ts +14 -0
- package/dist/runtime/components/prose/UploraImage.vue.d.ts +2 -1
- package/dist/runtime/composables/useAdmin.d.ts +1 -1
- package/dist/runtime/composables/useAdmin.js +2 -1
- package/dist/runtime/composables/useApi.d.ts +1 -1
- package/dist/runtime/composables/useAsyncHandler.d.ts +1 -1
- package/dist/runtime/composables/useAsyncHandler.js +1 -1
- package/dist/runtime/composables/useEditorDragHandle.d.ts +16 -0
- package/dist/runtime/composables/useEditorDragHandle.js +95 -0
- package/dist/runtime/composables/useEditorSuggestions.d.ts +68 -0
- package/dist/runtime/composables/useEditorSuggestions.js +24 -0
- package/dist/runtime/composables/useEditorToolbar.d.ts +120 -0
- package/dist/runtime/composables/useEditorToolbar.js +87 -0
- package/dist/runtime/composables/useFormState.d.ts +12 -0
- package/dist/runtime/composables/useFormState.js +33 -0
- package/dist/runtime/composables/useLogout.d.ts +1 -1
- package/dist/runtime/composables/useLogout.js +3 -1
- package/dist/runtime/composables/useNotification.d.ts +12 -0
- package/dist/runtime/composables/useNotification.js +46 -0
- package/dist/runtime/composables/useQueryState.d.ts +28 -0
- package/dist/runtime/composables/useQueryState.js +105 -0
- package/dist/runtime/composables/useRouteQuery.d.ts +37 -0
- package/dist/runtime/composables/useRouteQuery.js +81 -0
- package/dist/runtime/composables/useRowSelection.d.ts +8 -0
- package/dist/runtime/composables/useRowSelection.js +46 -0
- package/dist/runtime/composables/useTable.d.ts +17 -11
- package/dist/runtime/composables/useTable.js +47 -53
- package/dist/runtime/composables/useUplora.d.ts +1 -1
- package/dist/runtime/composables/useUplora.js +2 -1
- package/dist/runtime/index.css +1 -1
- package/dist/runtime/plugins/zod.d.ts +2 -0
- package/dist/runtime/plugins/zod.js +26 -0
- package/dist/runtime/server/api/uplora/[id].delete.d.ts +1 -5
- package/dist/runtime/tv.d.ts +1 -1
- package/dist/runtime/types/date.d.ts +5 -0
- package/dist/runtime/types/index.d.ts +3 -21
- package/dist/runtime/types/index.js +1 -21
- package/dist/runtime/types/utils.d.ts +7 -0
- package/dist/runtime/utils/date.d.ts +9 -0
- package/dist/runtime/utils/date.js +28 -0
- package/dist/runtime/utils/formatters.d.ts +2 -0
- package/dist/runtime/utils/formatters.js +8 -0
- package/dist/runtime/utils/index.d.ts +5 -2
- package/dist/runtime/utils/index.js +5 -2
- package/dist/runtime/utils/storage.d.ts +2 -0
- package/dist/runtime/utils/storage.js +10 -0
- package/dist/runtime/utils/table.d.ts +23 -0
- package/dist/runtime/utils/table.js +51 -0
- package/package.json +26 -25
- package/.nuxt/cms/button-clear.ts +0 -5
- package/.nuxt/cms/button-copy.ts +0 -5
- package/.nuxt/cms/button-delete.ts +0 -5
- package/.nuxt/cms/editor/callout.ts +0 -21
- package/.nuxt/cms/editor/uplora-image.ts +0 -5
- package/.nuxt/cms/editor-content-full.ts +0 -13
- package/.nuxt/cms/editor-content-light.ts +0 -13
- package/.nuxt/cms/input-seo.ts +0 -5
- package/.nuxt/cms/input-slug.ts +0 -5
- package/.nuxt/cms/input-uplora-image.ts +0 -22
- package/.nuxt/cms/table-cell-preview.ts +0 -9
- package/.nuxt/cms/table-cell-seo.ts +0 -5
- package/.nuxt/cms/table-cell-user.ts +0 -9
- package/.nuxt/cms/table-panel-column-sorting.ts +0 -5
- package/.nuxt/cms/table-panel-column-visibility.ts +0 -5
- package/.nuxt/cms/table-panel-filters.ts +0 -5
- package/dist/runtime/components/ButtonClear.vue +0 -35
- package/dist/runtime/components/ButtonClear.vue.d.ts +0 -35
- package/dist/runtime/components/ButtonCopy.vue +0 -40
- package/dist/runtime/components/ButtonCopy.vue.d.ts +0 -23
- package/dist/runtime/components/EditorContentFull.vue +0 -67
- package/dist/runtime/components/EditorContentFull.vue.d.ts +0 -23
- package/dist/runtime/components/EditorContentLight.vue +0 -60
- package/dist/runtime/components/EditorContentLight.vue.d.ts +0 -23
- package/dist/runtime/components/InputSeo.vue +0 -73
- package/dist/runtime/components/InputSeo.vue.d.ts +0 -19
- package/dist/runtime/components/InputSlug.vue +0 -70
- package/dist/runtime/components/InputSlug.vue.d.ts +0 -29
- package/dist/runtime/components/InputUploraImage.vue +0 -156
- package/dist/runtime/components/InputUploraImage.vue.d.ts +0 -38
- package/dist/runtime/components/TableCellPreview.vue +0 -41
- package/dist/runtime/components/TableCellPreview.vue.d.ts +0 -18
- package/dist/runtime/components/TableCellSeo.vue +0 -34
- package/dist/runtime/components/TableCellSeo.vue.d.ts +0 -13
- package/dist/runtime/components/TableCellUser.vue +0 -40
- package/dist/runtime/components/TableCellUser.vue.d.ts +0 -18
- package/dist/runtime/components/TablePanelColumnSorting.vue.d.ts +0 -20
- package/dist/runtime/components/TablePanelColumnVisibility.vue +0 -49
- package/dist/runtime/components/TablePanelColumnVisibility.vue.d.ts +0 -20
- package/dist/runtime/components/TablePanelFilters.vue +0 -79
- package/dist/runtime/components/TablePanelFilters.vue.d.ts +0 -34
- package/dist/runtime/composables/useDeleteConfirm.d.ts +0 -15
- package/dist/runtime/composables/useDeleteConfirm.js +0 -27
- package/dist/runtime/composables/useSeoStats.d.ts +0 -12
- package/dist/runtime/composables/useSeoStats.js +0 -44
- package/dist/runtime/editor/components/BlockMenu.vue +0 -43
- package/dist/runtime/editor/components/BlockMenu.vue.d.ts +0 -2
- package/dist/runtime/editor/components/SlashCommand.vue +0 -92
- package/dist/runtime/editor/components/SlashCommand.vue.d.ts +0 -7
- package/dist/runtime/editor/components/TooltipLink.vue +0 -81
- package/dist/runtime/editor/components/TooltipLink.vue.d.ts +0 -9
- package/dist/runtime/editor/components/TooltipMenu.vue +0 -75
- package/dist/runtime/editor/components/TooltipMenu.vue.d.ts +0 -9
- package/dist/runtime/editor/extensions/callout/CalloutView.vue +0 -85
- package/dist/runtime/editor/extensions/callout/CalloutView.vue.d.ts +0 -7
- package/dist/runtime/editor/extensions/callout/extension.d.ts +0 -13
- package/dist/runtime/editor/extensions/callout/extension.js +0 -48
- package/dist/runtime/editor/extensions/callout/index.d.ts +0 -2
- package/dist/runtime/editor/extensions/callout/index.js +0 -2
- package/dist/runtime/editor/extensions/callout/types.d.ts +0 -3
- package/dist/runtime/editor/extensions/index.d.ts +0 -26
- package/dist/runtime/editor/extensions/index.js +0 -85
- package/dist/runtime/editor/extensions/uplora-image/UploraImageView.vue +0 -29
- package/dist/runtime/editor/extensions/uplora-image/UploraImageView.vue.d.ts +0 -7
- package/dist/runtime/editor/extensions/uplora-image/extension.d.ts +0 -13
- package/dist/runtime/editor/extensions/uplora-image/extension.js +0 -60
- package/dist/runtime/editor/extensions/uplora-image/index.d.ts +0 -2
- package/dist/runtime/editor/extensions/uplora-image/index.js +0 -2
- package/dist/runtime/editor/extensions/uplora-image/types.d.ts +0 -5
- package/dist/runtime/editor/extensions/uplora-image/types.js +0 -0
- package/dist/runtime/editor/markdown/index.d.ts +0 -3
- package/dist/runtime/editor/markdown/index.js +0 -47
- package/dist/runtime/editor/markdown/nodes/callout.d.ts +0 -2
- package/dist/runtime/editor/markdown/nodes/callout.js +0 -21
- package/dist/runtime/editor/markdown/nodes/uploraImage.d.ts +0 -2
- package/dist/runtime/editor/markdown/nodes/uploraImage.js +0 -31
- package/dist/runtime/utils/dictionaries.d.ts +0 -4
- package/dist/runtime/utils/dictionaries.js +0 -6
- /package/.nuxt/cms/{autocomplete-select.ts → button-delete-confirm.ts} +0 -0
- /package/dist/runtime/{editor/extensions/callout/types.js → types/date.js} +0 -0
- /package/dist/runtime/utils/{image.d.ts → uplora.d.ts} +0 -0
- /package/dist/runtime/utils/{image.js → uplora.js} +0 -0
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
<template #right>
|
|
13
13
|
<slot name="actions" />
|
|
14
|
+
|
|
14
15
|
<UButton
|
|
15
16
|
type="submit"
|
|
16
17
|
label="Сохранить"
|
|
17
18
|
:form="formId"
|
|
18
|
-
:loading="
|
|
19
|
+
:loading="loading"
|
|
19
20
|
loading-auto
|
|
20
21
|
/>
|
|
21
22
|
</template>
|
|
@@ -24,7 +25,6 @@
|
|
|
24
25
|
<template #body>
|
|
25
26
|
<UForm
|
|
26
27
|
:id="formId"
|
|
27
|
-
ref="form"
|
|
28
28
|
:state="state"
|
|
29
29
|
:schema="schema"
|
|
30
30
|
:class="ui.form({ class: props.ui?.form })"
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
|
|
44
44
|
<script>
|
|
45
45
|
import theme from "#build/cms/form-panel";
|
|
46
|
-
import {
|
|
46
|
+
import { useAppConfig } from "#imports";
|
|
47
|
+
import { computed, useId } from "vue";
|
|
47
48
|
import { tv } from "../tv";
|
|
48
49
|
</script>
|
|
49
50
|
|
|
@@ -51,18 +52,20 @@ import { tv } from "../tv";
|
|
|
51
52
|
const props = defineProps({
|
|
52
53
|
title: { type: String, required: false },
|
|
53
54
|
toBack: { type: null, required: false },
|
|
54
|
-
formId: { type: String, required:
|
|
55
|
-
schema: { type:
|
|
55
|
+
formId: { type: String, required: false },
|
|
56
|
+
schema: { type: null, required: true },
|
|
56
57
|
state: { type: Object, required: true },
|
|
58
|
+
loading: { type: Boolean, required: false },
|
|
59
|
+
handler: { type: Function, required: true },
|
|
57
60
|
asideDivide: { type: Boolean, required: false },
|
|
58
|
-
|
|
61
|
+
showReset: { type: Boolean, required: false },
|
|
59
62
|
class: { type: null, required: false },
|
|
60
63
|
ui: { type: null, required: false }
|
|
61
64
|
});
|
|
62
65
|
defineEmits(["update:state"]);
|
|
63
66
|
defineSlots();
|
|
64
67
|
const appConfig = useAppConfig();
|
|
65
|
-
const
|
|
68
|
+
const formId = computed(() => props.formId ?? `form-${useId()}`);
|
|
66
69
|
async function submitHandler(event) {
|
|
67
70
|
await props.handler?.(event);
|
|
68
71
|
}
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
-
import type { FormSubmitEvent } from '@nuxt/ui';
|
|
2
|
+
import type { FormData, FormSchema, FormSubmitEvent } from '@nuxt/ui';
|
|
3
3
|
import type { RouteLocationRaw } from 'vue-router';
|
|
4
|
-
import type { ZodSchema } from 'zod';
|
|
5
4
|
import type { ComponentConfig } from '../types';
|
|
6
5
|
import theme from '#build/cms/form-panel';
|
|
7
6
|
type FormPanel = ComponentConfig<typeof theme, AppConfig, 'formPanel'>;
|
|
8
|
-
export interface FormPanelProps<T> {
|
|
7
|
+
export interface FormPanelProps<S extends FormSchema, T extends FormData<S> = FormData<S>> {
|
|
9
8
|
title?: string;
|
|
10
9
|
toBack?: RouteLocationRaw;
|
|
11
|
-
formId
|
|
12
|
-
schema:
|
|
10
|
+
formId?: string;
|
|
11
|
+
schema: S;
|
|
13
12
|
state: Partial<T>;
|
|
13
|
+
loading?: boolean;
|
|
14
|
+
handler: (event: FormSubmitEvent<T>) => Promise<void>;
|
|
14
15
|
asideDivide?: boolean;
|
|
15
|
-
|
|
16
|
+
showReset?: boolean;
|
|
16
17
|
class?: any;
|
|
17
18
|
ui?: FormPanel['slots'];
|
|
18
19
|
}
|
|
19
|
-
export interface FormPanelEmits<T> {
|
|
20
|
+
export interface FormPanelEmits<S extends FormSchema, T extends FormData<S> = FormData<S>> {
|
|
20
21
|
'update:state': [value: T];
|
|
21
22
|
}
|
|
22
23
|
export interface FormPanelSlots {
|
|
@@ -24,18 +25,23 @@ export interface FormPanelSlots {
|
|
|
24
25
|
sidebar?: () => any;
|
|
25
26
|
actions?: () => any;
|
|
26
27
|
}
|
|
27
|
-
declare const _default:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
declare const __VLS_export: <S extends FormSchema, T extends FormData<S> = FormData<S>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
31
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<FormPanelProps<S, T> & {
|
|
32
|
+
"onUpdate:state"?: ((value: T) => any) | undefined;
|
|
33
|
+
}> & (typeof globalThis extends {
|
|
34
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
35
|
+
} ? P : {});
|
|
36
|
+
expose: (exposed: {}) => void;
|
|
32
37
|
attrs: any;
|
|
33
38
|
slots: FormPanelSlots;
|
|
34
39
|
emit: (evt: "update:state", value: T) => void;
|
|
35
40
|
}>) => import("vue").VNode & {
|
|
36
41
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
37
42
|
};
|
|
38
|
-
|
|
39
|
-
type __VLS_PrettifyLocal<T> = {
|
|
43
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
40
44
|
[K in keyof T]: T[K];
|
|
41
|
-
}
|
|
45
|
+
} : {
|
|
46
|
+
[K in keyof T as K]: T[K];
|
|
47
|
+
}) & {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { ComponentConfig } from '../types';
|
|
3
|
+
import theme from '#build/cms/form-panel-aside-section';
|
|
4
|
+
type FormPanelAsideSection = ComponentConfig<typeof theme, AppConfig, 'formPanelAsideSection'>;
|
|
5
|
+
export interface FormPanelAsideSectionProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
divide?: boolean;
|
|
9
|
+
class?: any;
|
|
10
|
+
ui?: FormPanelAsideSection['slots'];
|
|
11
|
+
}
|
|
12
|
+
export interface FormPanelAsideSectionSlots {
|
|
13
|
+
default?: () => any;
|
|
14
|
+
icon?: () => any;
|
|
15
|
+
title?: () => any;
|
|
16
|
+
}
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelAsideSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelAsideSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelAsideSectionSlots>;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -14,8 +14,9 @@ export interface FormPanelAsideSectionSlots {
|
|
|
14
14
|
icon?: () => any;
|
|
15
15
|
title?: () => any;
|
|
16
16
|
}
|
|
17
|
-
declare const _default:
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
18
|
export default _default;
|
|
19
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelAsideSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelAsideSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelAsideSectionSlots>;
|
|
19
20
|
type __VLS_WithSlots<T, S> = T & {
|
|
20
21
|
new (): {
|
|
21
22
|
$slots: S;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { ComponentConfig } from '../types';
|
|
3
|
+
import theme from '#build/cms/form-panel-section';
|
|
4
|
+
type FormPanelSection = ComponentConfig<typeof theme, AppConfig, 'formPanelSection'>;
|
|
5
|
+
export interface FormPanelSectionProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
class?: any;
|
|
9
|
+
ui?: FormPanelSection['slots'];
|
|
10
|
+
}
|
|
11
|
+
export interface FormPanelSectionSlots {
|
|
12
|
+
default?: () => any;
|
|
13
|
+
}
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelSectionSlots>;
|
|
17
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
18
|
+
new (): {
|
|
19
|
+
$slots: S;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="ui.root({ class: [props.ui?.root, props.class] })">
|
|
3
|
-
<div :class="ui.title({ class: props.ui?.title })">
|
|
3
|
+
<div v-if="title" :class="ui.title({ class: props.ui?.title })">
|
|
4
4
|
{{ title }}
|
|
5
5
|
</div>
|
|
6
6
|
<div v-if="description" :class="ui.description({ class: props.ui?.description })">
|
|
@@ -20,7 +20,7 @@ import { tv } from "../tv";
|
|
|
20
20
|
|
|
21
21
|
<script setup>
|
|
22
22
|
const props = defineProps({
|
|
23
|
-
title: { type: String, required:
|
|
23
|
+
title: { type: String, required: false },
|
|
24
24
|
description: { type: String, required: false },
|
|
25
25
|
class: { type: null, required: false },
|
|
26
26
|
ui: { type: null, required: false }
|
|
@@ -3,7 +3,7 @@ import type { ComponentConfig } from '../types';
|
|
|
3
3
|
import theme from '#build/cms/form-panel-section';
|
|
4
4
|
type FormPanelSection = ComponentConfig<typeof theme, AppConfig, 'formPanelSection'>;
|
|
5
5
|
export interface FormPanelSectionProps {
|
|
6
|
-
title
|
|
6
|
+
title?: string;
|
|
7
7
|
description?: string;
|
|
8
8
|
class?: any;
|
|
9
9
|
ui?: FormPanelSection['slots'];
|
|
@@ -11,8 +11,9 @@ export interface FormPanelSectionProps {
|
|
|
11
11
|
export interface FormPanelSectionSlots {
|
|
12
12
|
default?: () => any;
|
|
13
13
|
}
|
|
14
|
-
declare const _default:
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
15
|
export default _default;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelSectionSlots>;
|
|
16
17
|
type __VLS_WithSlots<T, S> = T & {
|
|
17
18
|
new (): {
|
|
18
19
|
$slots: S;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { NavigationMenuItem } from '@nuxt/ui';
|
|
2
|
+
import type { RouteLocationRaw } from 'vue-router';
|
|
3
|
+
interface LayoutProps {
|
|
4
|
+
navigation: NavigationMenuItem[];
|
|
5
|
+
version: string;
|
|
6
|
+
logotype?: string;
|
|
7
|
+
logotypeIcon?: string;
|
|
8
|
+
logotypeShortIcon?: string;
|
|
9
|
+
homeLink?: RouteLocationRaw;
|
|
10
|
+
}
|
|
11
|
+
interface DashboardLayoutSlots {
|
|
12
|
+
default: () => any;
|
|
13
|
+
logotype: () => any;
|
|
14
|
+
footer: (props: {
|
|
15
|
+
collapsed: boolean | undefined;
|
|
16
|
+
}) => any;
|
|
17
|
+
}
|
|
18
|
+
type __VLS_Slots = DashboardLayoutSlots;
|
|
19
|
+
declare const __VLS_base: import("vue").DefineComponent<LayoutProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<LayoutProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
23
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
24
|
+
new (): {
|
|
25
|
+
$slots: S;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UDashboardGroup unit="rem">
|
|
3
|
+
<UDashboardSidebar
|
|
4
|
+
v-model:open="isSidebarOpen"
|
|
5
|
+
v-model:collapsed="isSidebarCollapsed"
|
|
6
|
+
:ui="{ footer: 'lg:border-t lg:border-default' }"
|
|
7
|
+
collapsible
|
|
8
|
+
>
|
|
9
|
+
<template #header="{ collapsed }">
|
|
10
|
+
<NuxtLink :to="homeLink" class="flex items-center gap-2.5" :class="collapsed && 'mx-auto'">
|
|
11
|
+
<UIcon v-if="logotypeIcon && logotypeShortIcon" :name="collapsed ? logotypeShortIcon : logotypeIcon" />
|
|
12
|
+
<slot v-else name="logotype">
|
|
13
|
+
<span class="text-lg">{{ logotype }}</span>
|
|
14
|
+
</slot>
|
|
15
|
+
|
|
16
|
+
<UBadge
|
|
17
|
+
v-show="!collapsed"
|
|
18
|
+
color="primary"
|
|
19
|
+
variant="soft"
|
|
20
|
+
size="sm"
|
|
21
|
+
:label="version"
|
|
22
|
+
/>
|
|
23
|
+
</NuxtLink>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<template #default="{ collapsed }">
|
|
27
|
+
<UNavigationMenu
|
|
28
|
+
:collapsed="collapsed"
|
|
29
|
+
:items="navigation"
|
|
30
|
+
orientation="vertical"
|
|
31
|
+
tooltip
|
|
32
|
+
popover
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
<UNavigationMenu
|
|
36
|
+
:collapsed="collapsed"
|
|
37
|
+
:items="links"
|
|
38
|
+
orientation="vertical"
|
|
39
|
+
tooltip
|
|
40
|
+
class="mt-auto"
|
|
41
|
+
/>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<template v-if="$slots.footer" #footer="{ collapsed }">
|
|
45
|
+
<div class="my-1">
|
|
46
|
+
<slot name="footer" :collapsed="collapsed" />
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
49
|
+
</UDashboardSidebar>
|
|
50
|
+
|
|
51
|
+
<slot />
|
|
52
|
+
</UDashboardGroup>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script setup>
|
|
56
|
+
import { useAppConfig } from "#imports";
|
|
57
|
+
import { computed } from "vue";
|
|
58
|
+
import { useAdmin } from "../composables/useAdmin";
|
|
59
|
+
defineProps({
|
|
60
|
+
navigation: { type: Array, required: true },
|
|
61
|
+
version: { type: String, required: true },
|
|
62
|
+
logotype: { type: String, required: false },
|
|
63
|
+
logotypeIcon: { type: String, required: false },
|
|
64
|
+
logotypeShortIcon: { type: String, required: false },
|
|
65
|
+
homeLink: { type: null, required: false }
|
|
66
|
+
});
|
|
67
|
+
defineSlots();
|
|
68
|
+
const appConfig = useAppConfig();
|
|
69
|
+
const { isSidebarOpen, isSidebarCollapsed } = useAdmin();
|
|
70
|
+
const links = computed(() => [
|
|
71
|
+
{
|
|
72
|
+
label: isSidebarCollapsed.value ? "\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u043C\u0435\u043D\u044E" : "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u043C\u0435\u043D\u044E",
|
|
73
|
+
icon: isSidebarCollapsed.value ? appConfig.ui.icons.panelClose : appConfig.ui.icons.panelOpen,
|
|
74
|
+
onSelect: () => {
|
|
75
|
+
isSidebarCollapsed.value = !isSidebarCollapsed.value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { NavigationMenuItem } from '@nuxt/ui';
|
|
2
|
+
import type { RouteLocationRaw } from 'vue-router';
|
|
3
|
+
interface LayoutProps {
|
|
4
|
+
navigation: NavigationMenuItem[];
|
|
5
|
+
version: string;
|
|
6
|
+
logotype?: string;
|
|
7
|
+
logotypeIcon?: string;
|
|
8
|
+
logotypeShortIcon?: string;
|
|
9
|
+
homeLink?: RouteLocationRaw;
|
|
10
|
+
}
|
|
11
|
+
interface DashboardLayoutSlots {
|
|
12
|
+
default: () => any;
|
|
13
|
+
logotype: () => any;
|
|
14
|
+
footer: (props: {
|
|
15
|
+
collapsed: boolean | undefined;
|
|
16
|
+
}) => any;
|
|
17
|
+
}
|
|
18
|
+
type __VLS_Slots = DashboardLayoutSlots;
|
|
19
|
+
declare const __VLS_base: import("vue").DefineComponent<LayoutProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<LayoutProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
23
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
24
|
+
new (): {
|
|
25
|
+
$slots: S;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import type { ButtonProps } from '@nuxt/ui';
|
|
3
|
+
import type { ComponentConfig } from '../types';
|
|
4
|
+
import theme from '#build/cms/modal-confirm';
|
|
5
|
+
type ModalConfirm = ComponentConfig<typeof theme, AppConfig, 'modalConfirm'>;
|
|
6
|
+
export interface ModalConfirmProps {
|
|
7
|
+
title?: string;
|
|
8
|
+
message: string;
|
|
9
|
+
confirmText?: string;
|
|
10
|
+
confirmLabel?: string;
|
|
11
|
+
color?: ButtonProps['color'];
|
|
12
|
+
variant?: ButtonProps['variant'];
|
|
13
|
+
size?: ButtonProps['size'];
|
|
14
|
+
onConfirm?: () => Promise<any> | any;
|
|
15
|
+
class?: any;
|
|
16
|
+
ui?: ModalConfirm['slots'];
|
|
17
|
+
}
|
|
18
|
+
export interface ModalConfirmEmits {
|
|
19
|
+
confirm: [];
|
|
20
|
+
close: [];
|
|
21
|
+
}
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
24
|
+
declare const __VLS_export: import("vue").DefineComponent<ModalConfirmProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
|
+
close: () => any;
|
|
26
|
+
confirm: () => any;
|
|
27
|
+
}, string, import("vue").PublicProps, Readonly<ModalConfirmProps> & Readonly<{
|
|
28
|
+
onClose?: (() => any) | undefined;
|
|
29
|
+
onConfirm?: (() => any) | undefined;
|
|
30
|
+
}>, {
|
|
31
|
+
size: "xs" | "sm" | "md" | "lg" | "xl";
|
|
32
|
+
confirmLabel: string;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -19,7 +19,9 @@ export interface ModalConfirmEmits {
|
|
|
19
19
|
confirm: [];
|
|
20
20
|
close: [];
|
|
21
21
|
}
|
|
22
|
-
declare const _default:
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
24
|
+
declare const __VLS_export: import("vue").DefineComponent<ModalConfirmProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
23
25
|
close: () => any;
|
|
24
26
|
confirm: () => any;
|
|
25
27
|
}, string, import("vue").PublicProps, Readonly<ModalConfirmProps> & Readonly<{
|
|
@@ -29,4 +31,3 @@ declare const _default: import("vue").DefineComponent<ModalConfirmProps, {}, {},
|
|
|
29
31
|
size: "xs" | "sm" | "md" | "lg" | "xl";
|
|
30
32
|
confirmLabel: string;
|
|
31
33
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
|
-
export default _default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SortingState, Table } from '@tanstack/vue-table';
|
|
2
|
+
export interface TableColumnSortingProps {
|
|
3
|
+
table?: Table<any>;
|
|
4
|
+
}
|
|
5
|
+
export type TableColumnSortingModel = SortingState;
|
|
6
|
+
type __VLS_Props = TableColumnSortingProps;
|
|
7
|
+
type __VLS_ModelProps = {
|
|
8
|
+
modelValue?: TableColumnSortingModel;
|
|
9
|
+
};
|
|
10
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
"update:modelValue": (value: SortingState) => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
14
|
+
"onUpdate:modelValue"?: ((value: SortingState) => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<UPopover v-if="sortingColumns.length > 0">
|
|
2
|
+
<UPopover v-if="sortingColumns.length > 0" v-model:open="isOpen">
|
|
3
3
|
<UChip :ui="{ base: 'z-1 size-3' }" :show="model.length > 0" size="xl">
|
|
4
4
|
<UButton
|
|
5
|
-
|
|
6
|
-
variant="outline"
|
|
5
|
+
variant="soft"
|
|
7
6
|
color="neutral"
|
|
8
7
|
label="Сортировка"
|
|
8
|
+
:icon="appConfig.ui.icons.sort"
|
|
9
9
|
/>
|
|
10
10
|
</UChip>
|
|
11
11
|
|
|
12
12
|
<template #content>
|
|
13
13
|
<div class="flex flex-col gap-2 p-3">
|
|
14
14
|
<URadioGroup
|
|
15
|
-
:model-value="model[0]?.id"
|
|
15
|
+
:model-value="model[0]?.id ?? noSortColumn.value"
|
|
16
16
|
:items="sortingColumns"
|
|
17
17
|
@update:model-value="updateModel({ id: $event, desc: model[0]?.desc ?? false })"
|
|
18
18
|
/>
|
|
@@ -38,35 +38,44 @@
|
|
|
38
38
|
</UPopover>
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
|
-
<script>
|
|
42
|
-
import theme from "#build/cms/table-panel-column-sorting";
|
|
43
|
-
import { computed, useAppConfig } from "#imports";
|
|
44
|
-
import { tv } from "../tv";
|
|
45
|
-
</script>
|
|
46
|
-
|
|
47
41
|
<script setup>
|
|
42
|
+
import { useAppConfig } from "#imports";
|
|
43
|
+
import { computed, ref } from "vue";
|
|
48
44
|
const props = defineProps({
|
|
49
|
-
table: { type: Object, required: false }
|
|
50
|
-
class: { type: null, required: false },
|
|
51
|
-
ui: { type: null, required: false }
|
|
45
|
+
table: { type: Object, required: false }
|
|
52
46
|
});
|
|
53
47
|
const model = defineModel({ type: Array, ...{ default: [] } });
|
|
54
48
|
const appConfig = useAppConfig();
|
|
49
|
+
const noSortColumn = { label: "\u0411\u0435\u0437 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438", value: "null" };
|
|
55
50
|
const sortingColumns = computed(() => {
|
|
56
51
|
if (!props.table) {
|
|
57
52
|
return [];
|
|
58
53
|
}
|
|
59
|
-
|
|
60
|
-
label
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
const items = props.table.getAllColumns().filter((column) => column.columnDef.enableSorting).map((column) => {
|
|
55
|
+
const label = column.columnDef.meta?.headerLabel ?? (typeof column.columnDef.header === "string" ? column.columnDef.header : column.columnDef.id);
|
|
56
|
+
return {
|
|
57
|
+
label,
|
|
58
|
+
value: column.id
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
items.length > 0 && items.unshift(noSortColumn);
|
|
62
|
+
return items;
|
|
63
63
|
});
|
|
64
64
|
const sortOrder = [
|
|
65
65
|
{ icon: appConfig.ui.icons.sortAsc, label: "\u0410-\u042F", desc: false },
|
|
66
66
|
{ icon: appConfig.ui.icons.sortDesc, label: "\u042F-\u0410", desc: true }
|
|
67
67
|
];
|
|
68
68
|
function updateModel(value) {
|
|
69
|
+
const currentSort = model.value[0];
|
|
70
|
+
const shouldUpdate = currentSort?.id !== value.id || currentSort?.desc !== value.desc || value.id === noSortColumn.value && model.value.length > 0;
|
|
71
|
+
if (!shouldUpdate) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (value.id === noSortColumn.value) {
|
|
75
|
+
model.value = [];
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
69
78
|
model.value = [value];
|
|
70
79
|
}
|
|
71
|
-
const
|
|
80
|
+
const isOpen = ref(false);
|
|
72
81
|
</script>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SortingState, Table } from '@tanstack/vue-table';
|
|
2
|
+
export interface TableColumnSortingProps {
|
|
3
|
+
table?: Table<any>;
|
|
4
|
+
}
|
|
5
|
+
export type TableColumnSortingModel = SortingState;
|
|
6
|
+
type __VLS_Props = TableColumnSortingProps;
|
|
7
|
+
type __VLS_ModelProps = {
|
|
8
|
+
modelValue?: TableColumnSortingModel;
|
|
9
|
+
};
|
|
10
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
"update:modelValue": (value: SortingState) => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
14
|
+
"onUpdate:modelValue"?: ((value: SortingState) => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ColumnOrderState, Table, VisibilityState } from '@tanstack/vue-table';
|
|
2
|
+
export interface TableColumnVisibilityProps {
|
|
3
|
+
storageKey?: string;
|
|
4
|
+
table?: Table<any>;
|
|
5
|
+
}
|
|
6
|
+
export type TableColumnVisibilityModel = VisibilityState;
|
|
7
|
+
export type TableColumnVisibilityOrderModel = ColumnOrderState;
|
|
8
|
+
type __VLS_Props = TableColumnVisibilityProps;
|
|
9
|
+
type __VLS_ModelProps = {
|
|
10
|
+
'visibility'?: TableColumnVisibilityModel;
|
|
11
|
+
'order'?: TableColumnVisibilityOrderModel;
|
|
12
|
+
};
|
|
13
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
15
|
+
"update:visibility": (value: VisibilityState) => any;
|
|
16
|
+
"update:order": (value: ColumnOrderState) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
18
|
+
"onUpdate:visibility"?: ((value: VisibilityState) => any) | undefined;
|
|
19
|
+
"onUpdate:order"?: ((value: ColumnOrderState) => any) | undefined;
|
|
20
|
+
}>, {
|
|
21
|
+
storageKey: string;
|
|
22
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const _default: typeof __VLS_export;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UPopover v-model:open="isOpen">
|
|
3
|
+
<UChip
|
|
4
|
+
:ui="{ base: 'z-1 size-3' }"
|
|
5
|
+
:show="hiddenColumnsCount > 0"
|
|
6
|
+
:text="hiddenColumnsCount"
|
|
7
|
+
size="xl"
|
|
8
|
+
>
|
|
9
|
+
<UButton
|
|
10
|
+
variant="soft"
|
|
11
|
+
color="neutral"
|
|
12
|
+
label="Колонки"
|
|
13
|
+
:icon="appConfig.ui.icons.columns"
|
|
14
|
+
/>
|
|
15
|
+
</UChip>
|
|
16
|
+
|
|
17
|
+
<template #content>
|
|
18
|
+
<div class="p-3 min-w-64">
|
|
19
|
+
<h3 class="text-sm mb-2 text-muted">
|
|
20
|
+
Настройка колонок:
|
|
21
|
+
</h3>
|
|
22
|
+
|
|
23
|
+
<div ref="container">
|
|
24
|
+
<div
|
|
25
|
+
v-for="column in sortedItems"
|
|
26
|
+
v-show="column.label"
|
|
27
|
+
:key="column.id"
|
|
28
|
+
class="flex items-center gap-2 rounded hover:bg-elevated"
|
|
29
|
+
>
|
|
30
|
+
<UIcon
|
|
31
|
+
:name="appConfig.ui.icons.drag"
|
|
32
|
+
class="w-4 h-7 text-dimmed cursor-move shrink-0 handle"
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
<UCheckbox
|
|
36
|
+
class="flex-1 py-1"
|
|
37
|
+
:model-value="column.visible"
|
|
38
|
+
:label="column.label"
|
|
39
|
+
:disabled="!column.canHide"
|
|
40
|
+
@update:model-value="toggleColumnVisibility(column.id, $event)"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
</UPopover>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script setup>
|
|
50
|
+
import { useAppConfig, useRoute } from "#imports";
|
|
51
|
+
import { syncRef, useLocalStorage } from "@vueuse/core";
|
|
52
|
+
import { useSortable } from "@vueuse/integrations/useSortable";
|
|
53
|
+
import { computed, ref, useTemplateRef, watch } from "vue";
|
|
54
|
+
import { getCmsStorageKey } from "../utils";
|
|
55
|
+
const props = defineProps({
|
|
56
|
+
storageKey: { type: String, required: false, default: () => useRoute().name },
|
|
57
|
+
table: { type: Object, required: false }
|
|
58
|
+
});
|
|
59
|
+
const visibility = defineModel("visibility", { type: Object, ...{ default: {} } });
|
|
60
|
+
const storedVisibility = useLocalStorage(getCmsStorageKey(`column-visibility:${props.storageKey}`), visibility.value);
|
|
61
|
+
syncRef(storedVisibility, visibility, {
|
|
62
|
+
transform: { ltr: (value) => value }
|
|
63
|
+
});
|
|
64
|
+
const order = defineModel("order", { type: Array, ...{ default: [] } });
|
|
65
|
+
const storedOrder = useLocalStorage(getCmsStorageKey(`column-order:${props.storageKey}`), order.value);
|
|
66
|
+
syncRef(storedOrder, order, {
|
|
67
|
+
transform: { ltr: (value) => value }
|
|
68
|
+
});
|
|
69
|
+
const appConfig = useAppConfig();
|
|
70
|
+
const isOpen = ref(false);
|
|
71
|
+
const columns = computed(() => {
|
|
72
|
+
if (!props.table) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
return props.table.getAllColumns().map((column) => {
|
|
76
|
+
const label = column.columnDef.meta?.headerLabel ?? (typeof column.columnDef.header === "string" ? column.columnDef.header : void 0);
|
|
77
|
+
return {
|
|
78
|
+
id: column.id,
|
|
79
|
+
label,
|
|
80
|
+
visible: column.getIsVisible(),
|
|
81
|
+
canHide: column.getCanHide(),
|
|
82
|
+
onUpdateChecked: (checked) => toggleColumnVisibility(column.id, checked)
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
const sortedItems = computed(() => {
|
|
87
|
+
const sortOrder = Object.fromEntries(order.value.map((id, index) => [id, index]));
|
|
88
|
+
return columns.value.toSorted((a, b) => sortOrder[a.id] - sortOrder[b.id]);
|
|
89
|
+
});
|
|
90
|
+
const hiddenColumnsCount = computed(() => {
|
|
91
|
+
return columns.value.filter((column) => !column.visible).length;
|
|
92
|
+
});
|
|
93
|
+
function toggleColumnVisibility(columnId, visible) {
|
|
94
|
+
visibility.value = { ...visibility.value, [columnId]: !!visible };
|
|
95
|
+
}
|
|
96
|
+
const containerRef = useTemplateRef("container");
|
|
97
|
+
const { start: startSortable, stop: stopSortable } = useSortable(containerRef, order, {
|
|
98
|
+
handle: ".handle",
|
|
99
|
+
animation: 150,
|
|
100
|
+
onUpdate: (e) => {
|
|
101
|
+
const newColumnOrder = order.value.length !== sortedItems.value.length ? sortedItems.value.map((column) => column.id) : [...order.value];
|
|
102
|
+
newColumnOrder.splice(
|
|
103
|
+
e.newIndex,
|
|
104
|
+
0,
|
|
105
|
+
newColumnOrder.splice(e.oldIndex, 1)[0]
|
|
106
|
+
);
|
|
107
|
+
order.value = newColumnOrder;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
watch(containerRef, (value) => value ? startSortable() : stopSortable());
|
|
111
|
+
</script>
|