@hywax/cms 0.0.4 → 0.0.6

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.
Files changed (98) hide show
  1. package/.nuxt/cms/autocomplete-select.ts +5 -0
  2. package/.nuxt/cms/button-copy.ts +5 -0
  3. package/.nuxt/cms/button-delete.ts +5 -0
  4. package/.nuxt/cms/editor/callout.ts +21 -0
  5. package/.nuxt/cms/editor/index.ts +2 -0
  6. package/.nuxt/cms/editor/uplora-image.ts +5 -0
  7. package/.nuxt/cms/form-panel-aside-section.ts +9 -0
  8. package/.nuxt/cms/form-panel-section.ts +8 -0
  9. package/.nuxt/cms/form-panel.ts +15 -0
  10. package/.nuxt/cms/index.ts +16 -0
  11. package/.nuxt/cms/input-seo.ts +5 -0
  12. package/.nuxt/cms/input-slug.ts +5 -0
  13. package/.nuxt/cms/modal-confirm.ts +5 -0
  14. package/.nuxt/cms/table-cell-preview.ts +9 -0
  15. package/.nuxt/cms/table-cell-seo.ts +5 -0
  16. package/.nuxt/cms/table-cell-user.ts +5 -0
  17. package/.nuxt/cms/table-panel-column-sorting.ts +5 -0
  18. package/.nuxt/cms/table-panel-column-visibility.ts +5 -0
  19. package/.nuxt/cms/table-panel-filters.ts +5 -0
  20. package/.nuxt/cms/table-panel.ts +8 -0
  21. package/cli/templates.mjs +4 -3
  22. package/dist/module.json +1 -1
  23. package/dist/module.mjs +213 -11
  24. package/dist/runtime/components/AutocompleteSelect.vue +170 -0
  25. package/dist/runtime/components/AutocompleteSelect.vue.d.ts +42 -0
  26. package/dist/runtime/components/ButtonCopy.vue +40 -0
  27. package/dist/runtime/components/ButtonCopy.vue.d.ts +23 -0
  28. package/dist/runtime/components/ButtonDelete.vue +59 -0
  29. package/dist/runtime/components/ButtonDelete.vue.d.ts +34 -0
  30. package/dist/runtime/components/FormPanel.vue +70 -0
  31. package/dist/runtime/components/FormPanel.vue.d.ts +41 -0
  32. package/dist/runtime/components/FormPanelAsideSection.vue +41 -0
  33. package/dist/runtime/components/FormPanelAsideSection.vue.d.ts +23 -0
  34. package/dist/runtime/components/FormPanelSection.vue +31 -0
  35. package/dist/runtime/components/FormPanelSection.vue.d.ts +20 -0
  36. package/dist/runtime/components/InputSeo.vue +73 -0
  37. package/dist/runtime/components/InputSeo.vue.d.ts +19 -0
  38. package/dist/runtime/components/InputSlug.vue +74 -0
  39. package/dist/runtime/components/InputSlug.vue.d.ts +31 -0
  40. package/dist/runtime/components/ModalConfirm.vue +96 -0
  41. package/dist/runtime/components/ModalConfirm.vue.d.ts +32 -0
  42. package/dist/runtime/components/TableCellPreview.vue +40 -0
  43. package/dist/runtime/components/TableCellPreview.vue.d.ts +18 -0
  44. package/dist/runtime/components/TableCellSeo.vue +34 -0
  45. package/dist/runtime/components/TableCellSeo.vue.d.ts +13 -0
  46. package/dist/runtime/components/TableCellUser.vue +33 -0
  47. package/dist/runtime/components/TableCellUser.vue.d.ts +15 -0
  48. package/dist/runtime/components/TablePanel.vue +153 -0
  49. package/dist/runtime/components/TablePanel.vue.d.ts +50 -0
  50. package/dist/runtime/components/TablePanelColumnSorting.vue +72 -0
  51. package/dist/runtime/components/TablePanelColumnSorting.vue.d.ts +20 -0
  52. package/dist/runtime/components/TablePanelColumnVisibility.vue +49 -0
  53. package/dist/runtime/components/TablePanelColumnVisibility.vue.d.ts +20 -0
  54. package/dist/runtime/components/TablePanelFilters.vue +79 -0
  55. package/dist/runtime/components/TablePanelFilters.vue.d.ts +34 -0
  56. package/dist/runtime/components/prose/UploraImage.vue +8 -3
  57. package/dist/runtime/composables/useAdmin.d.ts +6 -0
  58. package/dist/runtime/composables/useAdmin.js +14 -0
  59. package/dist/runtime/composables/useDeleteConfirm.d.ts +15 -0
  60. package/dist/runtime/composables/useDeleteConfirm.js +27 -0
  61. package/dist/runtime/composables/useSeoStats.d.ts +2 -2
  62. package/dist/runtime/composables/useSeoStats.js +1 -1
  63. package/dist/runtime/composables/useTable.d.ts +19 -0
  64. package/dist/runtime/composables/useTable.js +90 -0
  65. package/dist/runtime/editor/extensions/callout/CalloutView.vue +79 -0
  66. package/dist/runtime/editor/extensions/callout/CalloutView.vue.d.ts +7 -0
  67. package/dist/runtime/editor/extensions/callout/extension.d.ts +13 -0
  68. package/dist/runtime/editor/extensions/callout/extension.js +48 -0
  69. package/dist/runtime/editor/extensions/callout/index.d.ts +2 -0
  70. package/dist/runtime/editor/extensions/callout/index.js +2 -0
  71. package/dist/runtime/editor/extensions/callout/types.d.ts +3 -0
  72. package/dist/runtime/editor/extensions/callout/types.js +0 -0
  73. package/dist/runtime/editor/extensions/index.d.ts +26 -0
  74. package/dist/runtime/editor/extensions/index.js +85 -0
  75. package/dist/runtime/editor/extensions/uplora-image/UploraImageView.vue +26 -0
  76. package/dist/runtime/editor/extensions/uplora-image/UploraImageView.vue.d.ts +7 -0
  77. package/dist/runtime/editor/extensions/uplora-image/extension.d.ts +13 -0
  78. package/dist/runtime/editor/extensions/uplora-image/extension.js +60 -0
  79. package/dist/runtime/editor/extensions/uplora-image/index.d.ts +2 -0
  80. package/dist/runtime/editor/extensions/uplora-image/index.js +2 -0
  81. package/dist/runtime/editor/extensions/uplora-image/types.d.ts +5 -0
  82. package/dist/runtime/editor/extensions/uplora-image/types.js +0 -0
  83. package/dist/runtime/editor/markdown/index.d.ts +3 -0
  84. package/dist/runtime/editor/markdown/index.js +47 -0
  85. package/dist/runtime/editor/markdown/nodes/callout.d.ts +2 -0
  86. package/dist/runtime/editor/markdown/nodes/callout.js +21 -0
  87. package/dist/runtime/editor/markdown/nodes/uploraImage.d.ts +2 -0
  88. package/dist/runtime/editor/markdown/nodes/uploraImage.js +31 -0
  89. package/dist/runtime/server/api/uplora/[id].delete.d.ts +2 -0
  90. package/dist/runtime/server/api/uplora/[id].delete.js +4 -0
  91. package/dist/runtime/server/api/uplora/index.post.d.ts +2 -0
  92. package/dist/runtime/server/api/uplora/index.post.js +4 -0
  93. package/dist/runtime/server/utils/validation.d.ts +2 -2
  94. package/dist/runtime/types/index.d.ts +16 -0
  95. package/dist/runtime/types/index.js +16 -0
  96. package/dist/runtime/types/query.d.ts +3 -1
  97. package/dist/runtime/types/tv.d.ts +9 -3
  98. package/package.json +5 -5
@@ -0,0 +1,19 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { ComponentConfig, SEO } from '../types';
3
+ import theme from '#build/cms/input-seo';
4
+ type InputSeo = ComponentConfig<typeof theme, AppConfig, 'inputSeo'>;
5
+ export interface InputSeoProps {
6
+ as?: any;
7
+ class?: any;
8
+ ui?: InputSeo['slots'];
9
+ }
10
+ declare const _default: import("vue").DefineComponent<InputSeoProps & {
11
+ modelValue?: SEO;
12
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
+ "update:modelValue": (value: SEO) => any;
14
+ }, string, import("vue").PublicProps, Readonly<InputSeoProps & {
15
+ modelValue?: SEO;
16
+ }> & Readonly<{
17
+ "onUpdate:modelValue"?: ((value: SEO) => any) | undefined;
18
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ export default _default;
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <UFormField
4
+ :label="label"
5
+ :name="titleKey"
6
+ >
7
+ <UInput
8
+ v-model="title"
9
+ :color="color"
10
+ :variant="variant"
11
+ :size="size"
12
+ class="w-full"
13
+ />
14
+ </UFormField>
15
+ <UFormField :name="slugKey" class="-mt-3" eager-validation>
16
+ <UInput
17
+ v-model="slug"
18
+ class="w-full"
19
+ size="xs"
20
+ variant="none"
21
+ :placeholder="isRegenerate ? '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A' : '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043B\u0430\u0433'"
22
+ :disabled="isRegenerate"
23
+ :ui="{
24
+ base: 'text-muted'
25
+ }"
26
+ >
27
+ <template #leading>
28
+ <UButton
29
+ size="xs"
30
+ variant="link"
31
+ :icon="appConfig.ui.icons.link"
32
+ class="p-0"
33
+ :color="isRegenerate ? 'success' : 'neutral'"
34
+ @click="isRegenerate = !isRegenerate"
35
+ />
36
+ </template>
37
+ </UInput>
38
+ </UFormField>
39
+ </Primitive>
40
+ </template>
41
+
42
+ <script>
43
+ import theme from "#build/cms/input-slug";
44
+ import { computed, ref, useAppConfig, watch } from "#imports";
45
+ import { Primitive } from "reka-ui";
46
+ import { slugify } from "../utils/slugify";
47
+ import { tv } from "../utils/tv";
48
+ </script>
49
+
50
+ <script setup>
51
+ const props = defineProps({
52
+ regenerate: { type: Boolean, required: false },
53
+ label: { type: String, required: false },
54
+ titleKey: { type: String, required: false },
55
+ slugKey: { type: String, required: false },
56
+ color: { type: null, required: false },
57
+ variant: { type: null, required: false },
58
+ size: { type: null, required: false },
59
+ as: { type: null, required: false },
60
+ class: { type: null, required: false },
61
+ ui: { type: null, required: false }
62
+ });
63
+ const title = defineModel("title", { type: String });
64
+ const slug = defineModel("slug", { type: String });
65
+ const appConfig = useAppConfig();
66
+ const isRegenerate = ref(props.regenerate);
67
+ watch(title, () => {
68
+ if (!isRegenerate.value) {
69
+ return;
70
+ }
71
+ slug.value = slugify(title.value);
72
+ });
73
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.inputSlug || {} })());
74
+ </script>
@@ -0,0 +1,31 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { InputProps } from '@nuxt/ui';
3
+ import type { ComponentConfig } from '../types';
4
+ import theme from '#build/cms/input-slug';
5
+ type InputSlug = ComponentConfig<typeof theme, AppConfig, 'inputSlug'>;
6
+ export interface InputSlugProps {
7
+ regenerate?: boolean;
8
+ label?: string;
9
+ titleKey?: string;
10
+ slugKey?: string;
11
+ color?: InputProps['color'];
12
+ variant?: InputProps['variant'];
13
+ size?: InputProps['size'];
14
+ as?: any;
15
+ class?: any;
16
+ ui?: InputSlug['slots'];
17
+ }
18
+ declare const _default: import("vue").DefineComponent<InputSlugProps & {
19
+ title?: string;
20
+ slug?: string;
21
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
22
+ "update:title": (value: string | undefined) => any;
23
+ "update:slug": (value: string | undefined) => any;
24
+ }, string, import("vue").PublicProps, Readonly<InputSlugProps & {
25
+ title?: string;
26
+ slug?: string;
27
+ }> & Readonly<{
28
+ "onUpdate:title"?: ((value: string | undefined) => any) | undefined;
29
+ "onUpdate:slug"?: ((value: string | undefined) => any) | undefined;
30
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ export default _default;
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <UModal
3
+ :title="title"
4
+ :ui="{
5
+ content: 'divide-y-0',
6
+ body: 'py-0! text-sm',
7
+ description: 'hidden'
8
+ }"
9
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
10
+ >
11
+ <template #description />
12
+ <template #body>
13
+ {{ message }}
14
+
15
+ <UForm
16
+ v-if="confirmText"
17
+ id="confirm-form"
18
+ ref="form"
19
+ class="pt-3"
20
+ :state="state"
21
+ @submit="handleConfirmClick()"
22
+ >
23
+ <UFormField name="confirmTextValue">
24
+ <template #label>
25
+ Введите <strong class="text-highlighted">{{ confirmText }}</strong> для подтверждения
26
+ </template>
27
+
28
+ <UInput v-model="state.confirmTextValue" class="w-full" />
29
+ </UFormField>
30
+ </UForm>
31
+ </template>
32
+
33
+ <template #footer>
34
+ <UButton
35
+ color="neutral"
36
+ label="Закрыть"
37
+ variant="ghost"
38
+ :size="size"
39
+ @click="emit('close')"
40
+ />
41
+
42
+ <UButton
43
+ v-if="confirmText"
44
+ form="confirm-form"
45
+ type="submit"
46
+ :label="confirmLabel"
47
+ :disabled="state.confirmTextValue !== confirmText"
48
+ :loading="form?.loading"
49
+ :color="color"
50
+ :variant="variant"
51
+ :size="size"
52
+ />
53
+ <UButton
54
+ v-else
55
+ label="Подтвердить"
56
+ loading-auto
57
+ :color="color"
58
+ :variant="variant"
59
+ :size="size"
60
+ @click="handleConfirmClick()"
61
+ />
62
+ </template>
63
+ </UModal>
64
+ </template>
65
+
66
+ <script>
67
+ import theme from "#build/cms/modal-confirm";
68
+ import { computed, reactive, useAppConfig, useTemplateRef } from "#imports";
69
+ import { tv } from "../utils/tv";
70
+ </script>
71
+
72
+ <script setup>
73
+ const props = defineProps({
74
+ title: { type: String, required: false },
75
+ message: { type: String, required: true },
76
+ confirmText: { type: String, required: false },
77
+ confirmLabel: { type: String, required: false, default: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C" },
78
+ color: { type: null, required: false },
79
+ variant: { type: null, required: false },
80
+ size: { type: null, required: false, default: "lg" },
81
+ onConfirm: { type: Function, required: false },
82
+ class: { type: null, required: false },
83
+ ui: { type: null, required: false }
84
+ });
85
+ const emit = defineEmits(["confirm", "close"]);
86
+ const appConfig = useAppConfig();
87
+ const form = useTemplateRef("form");
88
+ const state = reactive({
89
+ confirmTextValue: ""
90
+ });
91
+ async function handleConfirmClick() {
92
+ await props.onConfirm?.();
93
+ emit("close");
94
+ }
95
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.modalConfirm || {} })());
96
+ </script>
@@ -0,0 +1,32 @@
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: import("vue").DefineComponent<ModalConfirmProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
+ close: () => any;
24
+ confirm: () => any;
25
+ }, string, import("vue").PublicProps, Readonly<ModalConfirmProps> & Readonly<{
26
+ onClose?: (() => any) | undefined;
27
+ onConfirm?: (() => any) | undefined;
28
+ }>, {
29
+ size: "xs" | "sm" | "md" | "lg" | "xl";
30
+ confirmLabel: string;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ export default _default;
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <ULink :to="to" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <UploraImage
4
+ v-if="thumbnail"
5
+ :id="thumbnail.id"
6
+ :alt="title"
7
+ :lqip="thumbnail.lqip"
8
+ :sizes="[{ width: 30, height: 30, descriptor: '1x' }]"
9
+ :ui="{ picture: 'aspect-square' }"
10
+ :class="ui.image({ class: props.ui?.image })"
11
+ />
12
+ <div :class="ui.container({ class: props.ui?.container })">
13
+ <p :class="ui.title({ class: props.ui?.title })">
14
+ {{ title }}
15
+ </p>
16
+ <p v-if="description" :class="ui.description({ class: props.ui?.description })">
17
+ {{ description }}
18
+ </p>
19
+ </div>
20
+ </ULink>
21
+ </template>
22
+
23
+ <script>
24
+ import theme from "#build/cms/table-cell-preview";
25
+ import { computed, useAppConfig } from "#imports";
26
+ import { tv } from "../utils/tv";
27
+ </script>
28
+
29
+ <script setup>
30
+ const props = defineProps({
31
+ title: { type: String, required: true },
32
+ description: { type: String, required: false },
33
+ thumbnail: { type: Object, required: false },
34
+ to: { type: null, required: false },
35
+ class: { type: null, required: false },
36
+ ui: { type: null, required: false }
37
+ });
38
+ const appConfig = useAppConfig();
39
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.tableCellPreview || {} })());
40
+ </script>
@@ -0,0 +1,18 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { RouteLocationRaw } from 'vue-router';
3
+ import type { ComponentConfig } from '../types';
4
+ import theme from '#build/cms/table-cell-preview';
5
+ type TableCellPreview = ComponentConfig<typeof theme, AppConfig, 'tableCellPreview'>;
6
+ export interface TableCellPreviewProps {
7
+ title: string;
8
+ description?: string;
9
+ thumbnail?: {
10
+ id: string;
11
+ lqip?: string;
12
+ };
13
+ to?: RouteLocationRaw;
14
+ class?: any;
15
+ ui?: TableCellPreview['slots'];
16
+ }
17
+ declare const _default: import("vue").DefineComponent<TableCellPreviewProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<TableCellPreviewProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ export default _default;
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <UBadge
4
+ :label="title.progress"
5
+ :color="title.color"
6
+ variant="subtle"
7
+ />
8
+ <UBadge
9
+ :label="description.progress"
10
+ :color="description.color"
11
+ variant="subtle"
12
+ />
13
+ </Primitive>
14
+ </template>
15
+
16
+ <script>
17
+ import theme from "#build/cms/table-cell-seo";
18
+ import { computed, useAppConfig } from "#imports";
19
+ import { Primitive } from "reka-ui";
20
+ import { useSeoStats } from "../composables/useSeoStats";
21
+ import { tv } from "../utils/tv";
22
+ </script>
23
+
24
+ <script setup>
25
+ const props = defineProps({
26
+ seo: { type: Object, required: true },
27
+ as: { type: null, required: false },
28
+ class: { type: null, required: false },
29
+ ui: { type: null, required: false }
30
+ });
31
+ const appConfig = useAppConfig();
32
+ const { title, description } = useSeoStats(props.seo);
33
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.tableCellSeo || {} })());
34
+ </script>
@@ -0,0 +1,13 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { ComponentConfig } from '../types';
3
+ import type { SEO } from '../types/seo';
4
+ import theme from '#build/cms/table-cell-seo';
5
+ type TableCellSeo = ComponentConfig<typeof theme, AppConfig, 'tableCellSeo'>;
6
+ export interface TableCellSeoProps {
7
+ seo: SEO;
8
+ as?: any;
9
+ class?: any;
10
+ ui?: TableCellSeo['slots'];
11
+ }
12
+ declare const _default: import("vue").DefineComponent<TableCellSeoProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<TableCellSeoProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ export default _default;
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <UUser
3
+ :name="name"
4
+ :description="description"
5
+ :to="to"
6
+ :avatar="{
7
+ src: createAvatarByName(name)
8
+ }"
9
+ size="sm"
10
+ :as="as"
11
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
12
+ />
13
+ </template>
14
+
15
+ <script>
16
+ import theme from "#build/cms/table-cell-user";
17
+ import { computed, useAppConfig } from "#imports";
18
+ import { createAvatarByName } from "../utils/avatar";
19
+ import { tv } from "../utils/tv";
20
+ </script>
21
+
22
+ <script setup>
23
+ const props = defineProps({
24
+ name: { type: String, required: true },
25
+ description: { type: String, required: false },
26
+ to: { type: null, required: false },
27
+ as: { type: null, required: false },
28
+ class: { type: null, required: false },
29
+ ui: { type: null, required: false }
30
+ });
31
+ const appConfig = useAppConfig();
32
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.tableCellUser || {} })());
33
+ </script>
@@ -0,0 +1,15 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { RouteLocationRaw } from 'vue-router';
3
+ import type { ComponentConfig } from '../types';
4
+ import theme from '#build/cms/table-cell-user';
5
+ type TableCellUser = ComponentConfig<typeof theme, AppConfig, 'tableCellUser'>;
6
+ export interface TableCellUserProps {
7
+ name: string;
8
+ description?: string;
9
+ to?: RouteLocationRaw;
10
+ as?: any;
11
+ class?: any;
12
+ ui?: TableCellUser['slots'];
13
+ }
14
+ declare const _default: import("vue").DefineComponent<TableCellUserProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<TableCellUserProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ export default _default;
@@ -0,0 +1,153 @@
1
+ <template>
2
+ <UDashboardPanel
3
+ :ui="{ body: 'border-b border-default relative' }"
4
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
5
+ >
6
+ <template #header>
7
+ <UDashboardNavbar :title="title">
8
+ <template #right>
9
+ <slot name="navbar-right" />
10
+ </template>
11
+ </UDashboardNavbar>
12
+ <UDashboardToolbar>
13
+ <template #left>
14
+ <slot name="toolbar-left" />
15
+ </template>
16
+ <template #right>
17
+ <slot name="toolbar-right" />
18
+
19
+ <TablePanelColumnSorting
20
+ :model-value="sorting"
21
+ :table="tableRef?.tableApi"
22
+ @update:model-value="emit('update:sorting', $event)"
23
+ />
24
+ <TablePanelColumnVisibility
25
+ v-if="props.columnVisibility"
26
+ v-model="columnVisibility"
27
+ :table="tableRef?.tableApi"
28
+ />
29
+ </template>
30
+ </UDashboardToolbar>
31
+ </template>
32
+ <template #body>
33
+ <div v-show="loading" :class="ui.loader({ class: props.ui?.loader })">
34
+ <UIcon :name="appConfig.ui.icons.loading" :class="ui.loaderIcon({ class: props.ui?.loaderIcon })" />
35
+ </div>
36
+
37
+ <UTable
38
+ ref="table"
39
+ v-model:column-visibility="columnVisibility"
40
+ :class="ui.table({ class: props.ui?.table })"
41
+ :column-pinning="columnPinning"
42
+ :columns="tableColumns"
43
+ :data="data"
44
+ :sorting-options="{ manualSorting: hasPagination }"
45
+ :sticky="sticky"
46
+ :ui="{
47
+ base: 'table-fixed border-separate border-spacing-0',
48
+ thead: '[&>tr]:bg-elevated/50 [&>tr]:after:content-none',
49
+ tbody: '[&>tr]:last:[&>td]:border-b-0',
50
+ th: 'py-2 first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r',
51
+ td: 'border-b border-default'
52
+ }"
53
+ >
54
+ <template v-for="(_, name) in tableProxySlots" #[name]="slotData">
55
+ <slot :name="name" v-bind="slotData" />
56
+ </template>
57
+ </UTable>
58
+ </template>
59
+
60
+ <template v-if="hasPagination" #footer>
61
+ <div class="flex justify-between items-center py-3 px-4">
62
+ <div>
63
+ <span class="text-sm text-muted">
64
+ Всего: {{ total ?? 0 }}
65
+ </span>
66
+ </div>
67
+ <div class="flex items-center gap-2">
68
+ <span class="text-sm text-muted">
69
+ Строк на странице:
70
+ </span>
71
+ <USelect
72
+ :model-value="paginationProps.itemsPerPage"
73
+ :items="itemsPerPageList"
74
+ class="w-18"
75
+ @update:model-value="emit('update:itemsPerPage', Number($event))"
76
+ />
77
+ <UPagination
78
+ v-bind="paginationProps"
79
+ :sibling-count="1"
80
+ variant="ghost"
81
+ show-edges
82
+ @update:page="emit('update:page', $event)"
83
+ />
84
+ </div>
85
+ </div>
86
+ </template>
87
+ </UDashboardPanel>
88
+ </template>
89
+
90
+ <script>
91
+ import theme from "#build/cms/table-panel";
92
+ import { UButton, UDropdownMenu } from "#components";
93
+ import { computed, h, ref, useAppConfig, useTemplateRef } from "#imports";
94
+ import { objectOmit, reactivePick } from "@vueuse/core";
95
+ import { useForwardProps } from "reka-ui";
96
+ import { tv } from "../utils/tv";
97
+ </script>
98
+
99
+ <script setup>
100
+ const props = defineProps({
101
+ title: { type: String, required: false },
102
+ page: { type: Number, required: false },
103
+ itemsPerPage: { type: Number, required: false },
104
+ total: { type: Number, required: false },
105
+ data: { type: Array, required: false },
106
+ columns: { type: null, required: false },
107
+ sticky: { type: Boolean, required: false, default: true },
108
+ columnPinning: { type: Object, required: false },
109
+ columnVisibility: { type: Boolean, required: false, default: true },
110
+ defaultHiddenColumns: { type: Array, required: false, default: () => [] },
111
+ sorting: { type: Array, required: false },
112
+ loading: { type: Boolean, required: false },
113
+ actions: { type: Function, required: false },
114
+ class: { type: null, required: false },
115
+ ui: { type: null, required: false }
116
+ });
117
+ const emit = defineEmits(["update:sorting", "update:page", "update:itemsPerPage"]);
118
+ const slots = defineSlots();
119
+ const appConfig = useAppConfig();
120
+ const tableColumns = computed(() => [
121
+ ...props.columns ?? [],
122
+ ...props.actions ? [{
123
+ id: "actions",
124
+ meta: { class: { td: "w-20" } },
125
+ enableHiding: false,
126
+ cell: ({ row }) => h(
127
+ "div",
128
+ { class: "text-right" },
129
+ h(
130
+ UDropdownMenu,
131
+ {
132
+ content: { align: "end" },
133
+ items: props.actions?.(row.original) ?? []
134
+ },
135
+ () => h(UButton, {
136
+ icon: "lucide:ellipsis-vertical",
137
+ color: "neutral",
138
+ variant: "ghost",
139
+ class: "ml-auto"
140
+ })
141
+ )
142
+ )
143
+ }] : []
144
+ ]);
145
+ const paginationProps = useForwardProps(reactivePick(props, "page", "itemsPerPage", "total"));
146
+ const tableProxySlots = objectOmit(slots, ["toolbar-left", "toolbar-right", "navbar-right"]);
147
+ const tableRef = useTemplateRef("table");
148
+ const initialVisibilityState = Object.fromEntries(props.defaultHiddenColumns.map((column) => [column, false]));
149
+ const columnVisibility = ref(initialVisibilityState);
150
+ const hasPagination = computed(() => props.page !== void 0);
151
+ const itemsPerPageList = [10, 20, 50, 100];
152
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.tablePanel || {} })());
153
+ </script>
@@ -0,0 +1,50 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { DropdownMenuItem, TableProps, TableSlots } from '@nuxt/ui';
3
+ import type { ColumnPinningState, SortingState } from '@tanstack/vue-table';
4
+ import type { ComponentConfig } from '../types';
5
+ import theme from '#build/cms/table-panel';
6
+ type TablePanel = ComponentConfig<typeof theme, AppConfig, 'tablePanel'>;
7
+ export interface TablePanelProps<T> {
8
+ title?: string;
9
+ page?: number;
10
+ itemsPerPage?: number;
11
+ total?: number;
12
+ data?: T[];
13
+ columns?: TableProps<T>['columns'];
14
+ sticky?: boolean;
15
+ columnPinning?: ColumnPinningState;
16
+ columnVisibility?: boolean;
17
+ defaultHiddenColumns?: string[];
18
+ sorting?: SortingState;
19
+ loading?: boolean;
20
+ actions?: (row: T) => DropdownMenuItem[];
21
+ class?: any;
22
+ ui?: TablePanel['slots'];
23
+ }
24
+ export interface TablePanelEmits {
25
+ 'update:sorting': [value: SortingState];
26
+ 'update:page': [value: number];
27
+ 'update:itemsPerPage': [value: number];
28
+ }
29
+ export type TablePanelSlots<T> = Omit<TableSlots<T>, 'toolbar-left' | 'toolbar-right' | 'navbar-right'> & {
30
+ 'toolbar-left'?: () => any;
31
+ 'navbar-right'?: () => any;
32
+ 'toolbar-right'?: () => any;
33
+ };
34
+ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
35
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
36
+ readonly "onUpdate:sorting"?: ((value: SortingState) => any) | undefined;
37
+ readonly "onUpdate:page"?: ((value: number) => any) | undefined;
38
+ readonly "onUpdate:itemsPerPage"?: ((value: number) => any) | undefined;
39
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:sorting" | "onUpdate:page" | "onUpdate:itemsPerPage"> & TablePanelProps<T> & Partial<{}>> & import("vue").PublicProps;
40
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
41
+ attrs: any;
42
+ slots: TablePanelSlots<T>;
43
+ emit: ((evt: "update:sorting", value: SortingState) => void) & ((evt: "update:page", value: number) => void) & ((evt: "update:itemsPerPage", value: number) => void);
44
+ }>) => import("vue").VNode & {
45
+ __ctx?: Awaited<typeof __VLS_setup>;
46
+ };
47
+ export default _default;
48
+ type __VLS_PrettifyLocal<T> = {
49
+ [K in keyof T]: T[K];
50
+ } & {};