@opengis/cms 0.0.22 → 0.0.24

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 (211) hide show
  1. package/package.json +2 -10
  2. package/src/index.js +23 -0
  3. package/module/cms/card/cms.content.table/index.yml +0 -17
  4. package/module/cms/card/cms.content.table/main_info.hbs +0 -26
  5. package/module/cms/card/cms.menu.table/content_info.hbs +0 -16
  6. package/module/cms/card/cms.menu.table/index.yml +0 -18
  7. package/module/cms/card/cms.menu.table/main_info.hbs +0 -22
  8. package/module/cms/card/cms.settings.table/index.yml +0 -13
  9. package/module/cms/card/cms.settings.table/main_info.hbs +0 -20
  10. package/module/cms/cls/content.status.json +0 -18
  11. package/module/cms/cls/user_type.json +0 -10
  12. package/module/cms/form/admin.users.form.json +0 -78
  13. package/module/cms/form/cms.content.form.json +0 -79
  14. package/module/cms/form/cms.menu.form.json +0 -69
  15. package/module/cms/form/cms.settings.form.json +0 -32
  16. package/module/cms/menu.json +0 -24
  17. package/module/cms/router.js +0 -169
  18. package/module/cms/select/cms.page_type.sql +0 -2
  19. package/module/cms/select/collection.sql +0 -1
  20. package/module/cms/select/locale.sql +0 -17
  21. package/module/cms/select/news_tag_id.sql +0 -12
  22. package/module/cms/select/tag_id.sql +0 -1
  23. package/module/cms/table/admin.users.table.json +0 -54
  24. package/module/cms/table/cms.content.table.json +0 -106
  25. package/module/cms/table/cms.menu.table.json +0 -73
  26. package/module/cms/table/cms.settings.table.json +0 -57
  27. package/module/cms/table/collection.default.table.json +0 -102
  28. package/module/cms/table/single.default.table.json +0 -115
  29. package/src/App.css +0 -52
  30. package/src/App.vue +0 -62
  31. package/src/assets/image.png +0 -0
  32. package/src/assets/main.css +0 -3
  33. package/src/assets/tailwind-3.4.17.js +0 -113
  34. package/src/components/LanguageSwitcher.vue +0 -73
  35. package/src/components/SettingsCard.vue +0 -40
  36. package/src/components/builder/CreateForm.vue +0 -128
  37. package/src/components/builder/formTypeSchema.js +0 -145
  38. package/src/components/builder/tabs/index.ts +0 -9
  39. package/src/components/builder/tabs/vs-builder-edit.vue +0 -133
  40. package/src/components/builder/tabs/vs-builder-monaco.vue +0 -29
  41. package/src/components/builder/tabs/vs-builder-preview.vue +0 -39
  42. package/src/components/builder/vs-builder-datatable-controls.vue +0 -138
  43. package/src/components/builder/vs-builder-datatable-form.vue +0 -80
  44. package/src/components/builder/vs-builder-datatable.vue +0 -191
  45. package/src/components/builder/vs-builder-list-item.vue +0 -110
  46. package/src/components/collections/CollectionsBreadcrumb.vue +0 -52
  47. package/src/components/collections/CollectionsGrid.vue +0 -176
  48. package/src/components/collections/ContentBlock.vue +0 -75
  49. package/src/components/collections/formWrapper.vue +0 -156
  50. package/src/components/dashboard/ContentItem.vue +0 -82
  51. package/src/components/dashboard/DashboardHeader.vue +0 -33
  52. package/src/components/dashboard/QuickActions.vue +0 -84
  53. package/src/components/dashboard/RecentContent.vue +0 -54
  54. package/src/components/dashboard/StatCard.vue +0 -63
  55. package/src/components/dashboard/StatsGrid.vue +0 -28
  56. package/src/components/form-components/MonacoEditor.vue +0 -104
  57. package/src/components/form-components/VsFormMeta.vue +0 -40
  58. package/src/components/form-components/VsFormTags.vue +0 -150
  59. package/src/components/form-components/custom-datatable/vs-form-custom-datatable-add.vue +0 -84
  60. package/src/components/form-components/custom-datatable/vs-form-custom-datatable-controls.vue +0 -106
  61. package/src/components/form-components/index.js +0 -23
  62. package/src/components/form-components/reference/vs-form-reference-add.vue +0 -92
  63. package/src/components/form-components/reference/vs-form-reference-controls.vue +0 -101
  64. package/src/components/form-components/reference-list/referenceOptionList.js +0 -78
  65. package/src/components/form-components/reference-list/vs-form-reference-add.vue +0 -145
  66. package/src/components/form-components/reference-list/vs-form-reference-choce.vue +0 -39
  67. package/src/components/form-components/reference-list/vs-form-reference-controls.vue +0 -110
  68. package/src/components/form-components/reference-skeleton/about-skeleton.vue +0 -37
  69. package/src/components/form-components/reference-skeleton/banner-skeleton.vue +0 -29
  70. package/src/components/form-components/reference-skeleton/body-skeleton.vue +0 -56
  71. package/src/components/form-components/reference-skeleton/cards-skeleton.vue +0 -47
  72. package/src/components/form-components/reference-skeleton/documents-skeleton.vue +0 -64
  73. package/src/components/form-components/reference-skeleton/faq-skeleton.vue +0 -64
  74. package/src/components/form-components/reference-skeleton/form-skeleton.vue +0 -41
  75. package/src/components/form-components/reference-skeleton/index.js +0 -36
  76. package/src/components/form-components/reference-skeleton/infoLine-skeleton.vue +0 -37
  77. package/src/components/form-components/reference-skeleton/news-skeleton.vue +0 -54
  78. package/src/components/form-components/reference-skeleton/slider-skeleton.vue +0 -41
  79. package/src/components/form-components/reference-skeleton/tabs-skeleton.vue +0 -40
  80. package/src/components/form-components/reference-skeleton/team-skeleton.vue +0 -103
  81. package/src/components/form-components/reference-skeleton/usefulLinks-skeleton.vue +0 -52
  82. package/src/components/form-components/reference-skeleton/video-skeleton.vue +0 -36
  83. package/src/components/form-components/testReferenceTypes.js +0 -773
  84. package/src/components/form-components/vs-form-color-picker.vue +0 -29
  85. package/src/components/form-components/vs-form-custom-datatable.vue +0 -214
  86. package/src/components/form-components/vs-form-integer.vue +0 -86
  87. package/src/components/form-components/vs-form-key-value.vue +0 -201
  88. package/src/components/form-components/vs-form-marcdown-md.vue +0 -3
  89. package/src/components/form-components/vs-form-media-select.vue +0 -780
  90. package/src/components/form-components/vs-form-reference-list.vue +0 -97
  91. package/src/components/form-components/vs-form-reference.vue +0 -59
  92. package/src/components/form-components/vs-form-relation.vue +0 -30
  93. package/src/components/form-components/vs-form-reletion-link.vue +0 -34
  94. package/src/components/form-components/vs-form-select-collection.vue +0 -0
  95. package/src/components/form-components/vs-form-slug.vue +0 -72
  96. package/src/components/form-components/vs-form-tiptap.vue +0 -7
  97. package/src/components/form-components/vs-richtext-md.vue +0 -3
  98. package/src/components/icons/BellIcon.vue +0 -17
  99. package/src/components/icons/GlobeIcon.vue +0 -18
  100. package/src/components/icons/KeyIcon.vue +0 -20
  101. package/src/components/icons/PaletteIcon.vue +0 -22
  102. package/src/components/icons/SettingsIcon.vue +0 -19
  103. package/src/components/icons/ShieldIcon.vue +0 -18
  104. package/src/components/icons/UsersIcon.vue +0 -19
  105. package/src/components/icons/icon-chevron-right.vue +0 -16
  106. package/src/components/icons/icon-drag.vue +0 -20
  107. package/src/components/icons/icon-file-text.vue +0 -21
  108. package/src/components/icons/icon-folder.vue +0 -18
  109. package/src/components/icons/icon-grid.vue +0 -17
  110. package/src/components/icons/icon-group.vue +0 -19
  111. package/src/components/icons/icon-home.vue +0 -16
  112. package/src/components/icons/icon-image.vue +0 -18
  113. package/src/components/icons/icon-list.vue +0 -20
  114. package/src/components/icons/icon-more.vue +0 -17
  115. package/src/components/icons/icon-plus.vue +0 -17
  116. package/src/components/icons-types/icon-array.vue +0 -22
  117. package/src/components/icons-types/icon-boolean.vue +0 -18
  118. package/src/components/icons-types/icon-datalist.vue +0 -22
  119. package/src/components/icons-types/icon-date.vue +0 -20
  120. package/src/components/icons-types/icon-datetime.vue +0 -20
  121. package/src/components/icons-types/icon-file.vue +0 -21
  122. package/src/components/icons-types/icon-gallery.vue +0 -18
  123. package/src/components/icons-types/icon-image.vue +0 -19
  124. package/src/components/icons-types/icon-integer.vue +0 -20
  125. package/src/components/icons-types/icon-merkdown.vue +0 -18
  126. package/src/components/icons-types/icon-multiselect.vue +0 -22
  127. package/src/components/icons-types/icon-number.vue +0 -20
  128. package/src/components/icons-types/icon-radio.vue +0 -22
  129. package/src/components/icons-types/icon-reference-list.vue +0 -22
  130. package/src/components/icons-types/icon-reference.vue +0 -20
  131. package/src/components/icons-types/icon-relation.vue +0 -22
  132. package/src/components/icons-types/icon-richtext.vue +0 -18
  133. package/src/components/icons-types/icon-select.vue +0 -22
  134. package/src/components/icons-types/icon-slug.vue +0 -19
  135. package/src/components/icons-types/icon-text.vue +0 -19
  136. package/src/components/icons-types/index.js +0 -43
  137. package/src/components/layout/Layout.vue +0 -67
  138. package/src/components/layout/Sidebar.vue +0 -128
  139. package/src/components/media/FileUploadProgress.vue +0 -29
  140. package/src/components/media/MediaBreadcrumb.vue +0 -42
  141. package/src/components/media/MediaCreateFolder.vue +0 -59
  142. package/src/components/media/MediaFileInfo.vue +0 -148
  143. package/src/components/media/MediaGrid.vue +0 -148
  144. package/src/components/media/MediaList.vue +0 -148
  145. package/src/components/media/MediaViewControls.vue +0 -38
  146. package/src/components/media/TypeTag.vue +0 -23
  147. package/src/components/menu/AddNewItemInTree.vue +0 -75
  148. package/src/components/menu/MenuBody.vue +0 -149
  149. package/src/components/menu/MenuItem.vue +0 -73
  150. package/src/components/menu/MenuList.vue +0 -101
  151. package/src/components/referencec/index.ts +0 -7
  152. package/src/components/referencec/vs-reference-faq.vue +0 -61
  153. package/src/components/referencec/vs-reference-user-card.vue +0 -40
  154. package/src/components/settings/NotificationSettings.vue +0 -32
  155. package/src/components/settings/SettingsTable.vue +0 -50
  156. package/src/components/settings/SettingsTitle.vue +0 -33
  157. package/src/components/settings/SettingsToggleItem.vue +0 -25
  158. package/src/components/sidebar/DropdownMenu.vue +0 -34
  159. package/src/components/sidebar/SettingsSidebar.vue +0 -121
  160. package/src/components/sidebar/SidebarFooter.vue +0 -52
  161. package/src/components/sidebar/SidebarHeader.vue +0 -57
  162. package/src/components/sidebar/SidebarMenu.vue +0 -78
  163. package/src/components/ui/EmptyData.vue +0 -76
  164. package/src/components/ui/UniversalTable.vue +0 -310
  165. package/src/components/ui/UniversalTableFilters.vue +0 -0
  166. package/src/components/ui/UniversalTablePagination.vue +0 -118
  167. package/src/components/ui/VsPreview.vue +0 -75
  168. package/src/composables/useCollectionView.ts +0 -21
  169. package/src/composables/useDebounce.ts +0 -26
  170. package/src/composables/useMonaco.ts +0 -28
  171. package/src/composables/useTheme.ts +0 -40
  172. package/src/content/test-slug/metadata.json +0 -1
  173. package/src/i18n.ts +0 -75
  174. package/src/index.css +0 -3
  175. package/src/index.ts +0 -122
  176. package/src/locales/en.json +0 -778
  177. package/src/locales/uk.json +0 -797
  178. package/src/main.ts +0 -41
  179. package/src/pages/Dashboard.vue +0 -168
  180. package/src/pages/EmailPage.vue +0 -183
  181. package/src/pages/FeedbackPage.vue +0 -232
  182. package/src/pages/MediaPage.vue +0 -372
  183. package/src/pages/TagsPage.vue +0 -207
  184. package/src/pages/builder/BuilderPage.vue +0 -195
  185. package/src/pages/builder/EditCollectionPage.vue +0 -163
  186. package/src/pages/collections/ArticlesPage.vue +0 -385
  187. package/src/pages/collections/CollectionsPage.vue +0 -146
  188. package/src/pages/collections/SingletonsPage.vue +0 -119
  189. package/src/pages/collections/contentForm.vue +0 -484
  190. package/src/pages/collections/schema/seo.ts +0 -27
  191. package/src/pages/menu/MenuAddPage.vue +0 -123
  192. package/src/pages/menu/MenuItemPage.vue +0 -183
  193. package/src/pages/menu/MenuPage.vue +0 -133
  194. package/src/pages/settings/ApiKeys.vue +0 -75
  195. package/src/pages/settings/Appearance.vue +0 -80
  196. package/src/pages/settings/Logs.vue +0 -260
  197. package/src/pages/settings/PermissionsPage.vue +0 -237
  198. package/src/pages/settings/Settings.vue +0 -186
  199. package/src/pages/settings/Users.vue +0 -109
  200. package/src/pages/settings/general.vue +0 -154
  201. package/src/pages/settings/generalScheme.js +0 -132
  202. package/src/pages/users/AddUser.vue +0 -106
  203. package/src/pages/users/UsersPage.vue +0 -98
  204. package/src/props/builder.ts +0 -67
  205. package/src/props/content.ts +0 -56
  206. package/src/props/media.ts +0 -63
  207. package/src/router/index.ts +0 -181
  208. package/src/types/fastify-auth.d.ts +0 -4
  209. package/src/utils/getField.js +0 -270
  210. package/src/utils/translit.js +0 -19
  211. package/src/vite-env.d.ts +0 -1
@@ -1,63 +0,0 @@
1
- <template>
2
- <div class="rounded-xl text-card-foreground shadow-lg border-0 bg-white dark:bg-slate-800 backdrop-blur-sm hover:shadow-xl transition-all duration-300 transform hover:scale-105">
3
- <div class="p-6">
4
- <div class="flex items-start justify-between">
5
- <div class="flex-1">
6
- <div class="flex items-center space-x-2 mb-2">
7
- <div :class="`p-2 rounded-lg bg-${stat.color}-50 dark:bg-${stat.color}-900/20`">
8
- <component
9
- :is="getIcon(stat.icon)"
10
- :class="`w-5 h-5 text-${stat.color}-600`"
11
- />
12
- </div>
13
- <p class="text-sm font-medium text-slate-600 dark:text-slate-400">
14
- {{ stat.title }}
15
- </p>
16
- </div>
17
- <p class="text-3xl font-bold text-slate-800 dark:text-slate-100 mb-1">
18
- {{ stat.value }}
19
- </p>
20
- <p class="text-xs text-slate-500 dark:text-slate-400 mb-3">
21
- {{ stat.description }}
22
- </p>
23
- </div>
24
- </div>
25
- </div>
26
- </div>
27
- </template>
28
-
29
- <script setup lang="ts">
30
- import {
31
- FileText,
32
- Users,
33
- Image,
34
- Eye,
35
- ArrowUpRight,
36
- ArrowDownRight
37
- } from 'lucide-vue-next';
38
-
39
- interface StatItem {
40
- id: string;
41
- title: string;
42
- value: number | string;
43
- description: string;
44
- icon: string;
45
- color: string;
46
- }
47
-
48
- interface Props {
49
- stat: StatItem;
50
- }
51
-
52
- defineProps<Props>();
53
-
54
- const getIcon = (iconName: string) => {
55
- const icons = {
56
- 'file-text': FileText,
57
- 'users': Users,
58
- 'image': Image,
59
- 'eye': Eye
60
- };
61
- return icons[iconName as keyof typeof icons] || FileText;
62
- };
63
- </script>
@@ -1,28 +0,0 @@
1
- <template>
2
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
3
- <StatCard
4
- v-for="stat in stats"
5
- :key="stat.id"
6
- :stat="stat"
7
- />
8
- </div>
9
- </template>
10
-
11
- <script setup lang="ts">
12
- import StatCard from './StatCard.vue';
13
-
14
- interface StatItem {
15
- id: string;
16
- title: string;
17
- value: number | string;
18
- description: string;
19
- icon: string;
20
- color: string;
21
- }
22
-
23
- interface Props {
24
- stats: StatItem[];
25
- }
26
-
27
- defineProps<Props>();
28
- </script>
@@ -1,104 +0,0 @@
1
- <template>
2
- <div ref="editorContainer" :style="{ width, height }"></div>
3
- </template>
4
-
5
- <script setup lang="ts">
6
- import { ref, onMounted, onBeforeUnmount, watch } from "vue";
7
- import { useMonaco } from "../../composables/useMonaco";
8
-
9
- const props = withDefaults(
10
- defineProps<{
11
- language?: string;
12
- theme?: string;
13
- width?: string;
14
- height?: string;
15
- options?: any;
16
- }>(),
17
- {
18
- language: "javascript",
19
- theme: "vs-dark",
20
- width: "100%",
21
- height: "100%",
22
- options: () => ({
23
- minimap: { enabled: false },
24
- }),
25
- }
26
- );
27
-
28
- const modelValue = defineModel<string>({
29
- required: true,
30
- });
31
-
32
- const editorContainer = ref<HTMLElement | null>(null);
33
- let editor: any = null;
34
- let monaco: any = null;
35
-
36
- // Initialize editor
37
- onMounted(async () => {
38
- if (!editorContainer.value) return;
39
-
40
- try {
41
- // Завантажуємо Monaco Editor через composable
42
- monaco = await useMonaco();
43
-
44
- // Ensure the value is properly formatted with line breaks
45
- const formattedValue = modelValue.value?.replace(/\\n/g, "\n") || "";
46
-
47
- editor = monaco.editor.create(editorContainer.value, {
48
- value: formattedValue,
49
- language: props.language,
50
- theme: props.theme,
51
- automaticLayout: true,
52
- ...props.options,
53
- });
54
-
55
- // Handle value changes from editor
56
- editor.onDidChangeModelContent(() => {
57
- const value = editor?.getValue() || "";
58
- modelValue.value = value;
59
- });
60
- } catch (error) {
61
- console.error('Failed to load Monaco Editor:', error);
62
- }
63
- });
64
-
65
- // Handle prop changes
66
- watch(
67
- () => modelValue.value,
68
- (newValue) => {
69
- if (editor) {
70
- const formattedValue = newValue?.replace(/\\n/g, "\n") || "";
71
- if (formattedValue !== editor.getValue()) {
72
- editor.setValue(formattedValue);
73
- }
74
- }
75
- },
76
- { immediate: true }
77
- );
78
-
79
- watch(
80
- () => props.language,
81
- (newValue) => {
82
- if (editor && newValue && monaco) {
83
- monaco.editor.setModelLanguage(editor.getModel()!, newValue);
84
- }
85
- }
86
- );
87
-
88
- watch(
89
- () => props.theme,
90
- (newValue) => {
91
- if (editor && newValue && monaco) {
92
- monaco.editor.setTheme(newValue);
93
- }
94
- }
95
- );
96
-
97
- // Cleanup
98
- onBeforeUnmount(() => {
99
- if (editor) {
100
- editor.dispose();
101
- editor = null;
102
- }
103
- });
104
- </script>
@@ -1,40 +0,0 @@
1
- <template>
2
- <VsForm v-model:form="form" :schema="scheme" v-model:values="model" />
3
- </template>
4
-
5
- <script setup>
6
- import VsForm from '@opengis/form'
7
- import { ref, provide } from "vue";
8
- import { useI18n } from "vue-i18n";
9
-
10
- const { t } = useI18n();
11
-
12
- const model = ref({});
13
- const form = ref({});
14
-
15
- const scheme = [
16
- {
17
- key: "title",
18
- label: t("common.title"),
19
- type: "text",
20
- },
21
- {
22
- key: "description",
23
- label: t("common.description"),
24
- type: "text",
25
- },
26
- {
27
- key: "keywords",
28
- label: t("common.keywords"),
29
- type: "text",
30
- },
31
- {
32
- key: "meta",
33
- label: t("common.meta"),
34
- type: "key-value",
35
- ignore: ["title", "description", "keywords"],
36
- },
37
- ];
38
- </script>
39
-
40
- <style lang="scss" scoped></style>
@@ -1,150 +0,0 @@
1
- <template>
2
- <VsForm :schema="scheme" v-model="model" @update:model-value="handleUpdate" v-if="model" />
3
-
4
- </template>
5
-
6
- <script setup>
7
- import { ref, provide, onMounted, watch, nextTick, computed } from "vue";
8
- import { useI18n } from "vue-i18n";
9
- const { t } = useI18n();
10
- const model = defineModel({ default: () => [] });
11
- const form = ref({});
12
- const isSubmitting = ref(false);
13
- import VsForm from "@opengis/form";
14
- import { notify } from '@opengis/core';
15
-
16
-
17
- provide("metaParentValue", model);
18
-
19
- // Функція для перетворення тегів з об'єктів в ID
20
- const normalizeTags = (tags) => {
21
- if (!Array.isArray(tags)) return [];
22
- return tags.map(tag => {
23
- if (typeof tag === "object" && tag !== null && tag.id) {
24
- return tag.id;
25
- }
26
- return tag;
27
- });
28
- };
29
-
30
- // Функція для відновлення повних об'єктів тегів з ID
31
- const restoreTagObjects = async (tagIds) => {
32
- if (!Array.isArray(tagIds) || tagIds.length === 0) return [];
33
-
34
- try {
35
- const response = await fetch('/api/tags');
36
- const data = await response.json();
37
- const allTags = data?.rows || [];
38
-
39
- return tagIds.map(id => {
40
- const tag = allTags.find(t => t.tag_id === id);
41
- return tag ? { id: tag.tag_id, text: tag.value, color: tag.color } : { id, text: '', color: '#ababab' };
42
- });
43
- } catch (error) {
44
- console.error('Error fetching tags:', error);
45
- return tagIds.map(id => ({ id, text: '', color: '#ababab' }));
46
- }
47
- };
48
-
49
- onMounted(async () => {
50
- // Чекаємо кілька тиків, щоб форма точно встигла ініціалізуватися
51
- await nextTick();
52
- await nextTick();
53
-
54
- // Додаткова затримка для гарантії ініціалізації форми
55
- setTimeout(() => {
56
- if (Array.isArray(model.value?.tag_list)) {
57
- const normalized = normalizeTags(model.value.tag_list);
58
- if (JSON.stringify(normalized) !== JSON.stringify(model.value.tag_list)) {
59
- model.value.tag_list = normalized;
60
- }
61
- }
62
- }, 100);
63
- });
64
-
65
- // Відстежуємо зміни в tag_list і нормалізуємо їх
66
- watch(() => model.value.tag_list, (newTags) => {
67
- if (Array.isArray(newTags) && !isSubmitting.value) {
68
- const normalized = normalizeTags(newTags);
69
- if (JSON.stringify(normalized) !== JSON.stringify(newTags)) {
70
- model.value.tag_list = normalized;
71
- }
72
- }
73
- }, { deep: true });
74
-
75
- // Додатковий watcher для відстеження змін в моделі
76
- watch(() => model.value, (newModel) => {
77
- if (newModel && Array.isArray(newModel.tag_list) && !isSubmitting.value) {
78
- const normalized = normalizeTags(newModel.tag_list);
79
- if (JSON.stringify(normalized) !== JSON.stringify(newModel.tag_list)) {
80
- newModel.tag_list = normalized;
81
- }
82
- }
83
- }, { deep: true, immediate: true });
84
-
85
- // Watcher для примусового оновлення форми при зміні тегів
86
- watch(() => model.value?.tag_list, (newTags) => {
87
- if (Array.isArray(newTags) && form.value) {
88
- // Примусово оновлюємо форму
89
- nextTick(() => {
90
- if (form.value && form.value.setValue) {
91
- form.value.setValue('tag_list', newTags);
92
- }
93
- });
94
- }
95
- }, { deep: true });
96
-
97
- const handleUpdate = async (value) => {
98
- // Нормалізуємо теги перед валідацією
99
- if (value.tag_list) {
100
- value.tag_list = normalizeTags(value.tag_list);
101
- model.value.tag_list = value.tag_list;
102
- }
103
-
104
- let result = await form.value.validate();
105
- if (result) {
106
- notify({
107
- type: "warning",
108
- title: t("common.actions.warning"),
109
- message: t("builder.editFieldFailed"),
110
- });
111
- return;
112
- }
113
- };
114
-
115
- // Функція для відновлення об'єктів тегів перед відправкою
116
- const restoreTagsBeforeSubmit = async () => {
117
- isSubmitting.value = true;
118
- if (Array.isArray(model.value?.tag_list)) {
119
- console.log('Before restore:', model.value.tag_list);
120
- const restoredTags = await restoreTagObjects(model.value.tag_list);
121
- console.log('After restore:', restoredTags);
122
- model.value.tag_list = restoredTags;
123
- }
124
- // Даємо час для відправки, потім знову включаємо нормалізацію
125
- setTimeout(() => {
126
- isSubmitting.value = false;
127
- }, 2000);
128
- };
129
-
130
- // Експортуємо функцію для використання в батьківському компоненті
131
- defineExpose({
132
- restoreTagsBeforeSubmit
133
- });
134
-
135
- // Використовуємо computed для схеми, щоб вона завжди мала актуальні значення
136
- const scheme = computed(() => [
137
- {
138
- key: "tag_list",
139
- type: "select",
140
- multiple: true,
141
- searchable: false,
142
- placeholder: t("builder.tags"),
143
- data: 'tag_id',
144
- value: model.value?.tag_list || []
145
- },
146
- ]);
147
- </script>
148
-
149
- <style lang="scss" scoped></style>
150
-
@@ -1,84 +0,0 @@
1
- <template>
2
- <div
3
- class="p-6 border-t border-slate-200 dark:border-slate-700 bg-slate-50/30 dark:bg-slate-700/30"
4
- >
5
- <button
6
- class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 shadow-sm h-9 px-4 w-full border-2 border-dashed border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 hover:bg-slate-50 dark:hover:bg-slate-600 hover:border-blue-400 dark:hover:border-blue-500 text-slate-600 dark:text-slate-300 hover:text-blue-600 dark:hover:text-blue-400 py-3 transition-all duration-200"
7
- @click="isOpen = true"
8
- >
9
- <Plus class="w-4 h-4 mr-2" />
10
- {{ $t('common.actions.add') }}
11
- </button>
12
- <VsModal teleport="#modal" :title="$t('common.actions.add')" :visible="isOpen" @close="isOpen = false">
13
-
14
- <VsForm v-model:form="form" :schema="colModel" v-model="formValues" />
15
- <template #footer>
16
- <div class="flex justify-end p-[20px] gap-[10px] border-t w-full">
17
- <button
18
- class="inline-flex items-center px-3 py-2 text-sm text-black duration-300 border border-gray-200 rounded-lg gap-x-2 whitespace-nowrap hover:bg-gray-100"
19
- @click="isOpen = false"
20
- >
21
- {{ $t("common.actions.cancel") }}
22
- </button>
23
- <button
24
- @click="createItem"
25
- class="py-2 px-3 inline-flex items-center gap-x-2 text-sm whitespace-nowrap text-white bg-blue-500 rounded-lg !border-gray-200 hover:bg-blue-700 duration-300"
26
- >
27
- {{ $t("common.actions.save") }}
28
- </button>
29
- </div>
30
- </template>
31
- </VsModal>
32
- </div>
33
- </template>
34
-
35
- <script setup>
36
- import { Plus } from "lucide-vue-next";
37
- import { ref } from "vue";
38
- import VsForm from "@opengis/form";
39
- import { notify } from '@opengis/core';
40
- import { VsModal } from "@opengis/core";
41
- import { useI18n } from "vue-i18n";
42
- const { t } = useI18n();
43
-
44
- defineProps({
45
- colModel: {
46
- type: Array,
47
- required: true,
48
- },
49
- });
50
-
51
- const data = defineModel({
52
- type: Array,
53
- required: true,
54
- });
55
-
56
- const isOpen = ref(false);
57
- const formValues = ref({});
58
- const form = ref({});
59
-
60
- const createItem = async () => {
61
- try {
62
- let result = await form.value.validate();
63
- if (result) {
64
- notify({
65
- type: "warning",
66
- title: t("common.actions.warning"),
67
- message: t("builder.editFieldFailed"),
68
- });
69
- return;
70
- }
71
-
72
- data.value = [
73
- ...(data.value || []),
74
- { ...formValues.value, id: Math.random().toString(36).substring(2, 15) },
75
- ];
76
- isOpen.value = false;
77
- formValues.value = {};
78
- } catch (error) {
79
- console.log(error);
80
- }
81
- };
82
- </script>
83
-
84
- <style scoped></style>
@@ -1,106 +0,0 @@
1
- <template>
2
- <div class="flex items-center justify-end gap-2">
3
- <button
4
- class="inline-flex items-center justify-center whitespace-nowrap font-medium focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border rounded-md text-xs h-8 w-8 p-0 border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 hover:bg-blue-50 dark:hover:bg-slate-600 hover:border-blue-300 dark:hover:border-slate-500 hover:text-blue-600 dark:hover:text-slate-200 transition-all duration-200 shadow-sm"
5
- @click="isOpen = true"
6
- >
7
- <Pencil class="w-4 h-4" />
8
- </button>
9
- <button
10
- @click="openConfirm"
11
- class="inline-flex items-center justify-center whitespace-nowrap font-medium focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border rounded-md text-xs h-8 w-8 p-0 border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 hover:bg-red-50 dark:hover:bg-slate-600 hover:border-red-300 dark:hover:border-slate-500 hover:text-red-600 dark:hover:text-slate-200 transition-all duration-200 shadow-sm"
12
- >
13
- <Trash2 class="w-4 h-4" />
14
- </button>
15
- <VsModal teleport="#modal" :title="$t('builder.editField')" :visible="isOpen" @close="isOpen = false">
16
- <VsForm v-model:form="form" :schema="colModel" v-model="formValues" />
17
- <template #footer>
18
- <div class="flex justify-end p-[20px] gap-[10px] border-t w-full">
19
- <button
20
- class="py-2 px-3 inline-flex items-center gap-x-2 text-sm whitespace-nowrap text-white bg-blue-500 rounded-lg !border-gray-200 hover:bg-blue-700 duration-300"
21
- @click="isOpen = false"
22
- >
23
- {{ $t("common.actions.cancel") }}
24
- </button>
25
- <button
26
- @click="updateItem"
27
- class="py-2 px-3 inline-flex items-center gap-x-2 text-sm whitespace-nowrap text-white bg-blue-500 rounded-lg !border-gray-200 hover:bg-blue-700 duration-300"
28
- >
29
- {{ $t("common.actions.save") }}
30
- </button>
31
- </div>
32
- </template>
33
- </VsModal>
34
- </div>
35
- </template>
36
-
37
- <script setup>
38
- import { Pencil, Trash2 } from "lucide-vue-next";
39
- import { ref, watch } from "vue";
40
- import { confirm, notify } from '@opengis/core';
41
- import { useI18n } from "vue-i18n";
42
- import VsForm from "@opengis/form";
43
- import { VsModal } from "@opengis/core";
44
-
45
- //import VsForm from '../../../../../form/src/index'
46
-
47
-
48
- const { t } = useI18n();
49
-
50
- const props = defineProps({
51
- item: {
52
- type: Object,
53
- required: true,
54
- },
55
- colModel: {
56
- type: Array,
57
- required: true,
58
- },
59
- });
60
-
61
- const data = defineModel({
62
- type: Array,
63
- required: true,
64
- });
65
-
66
- const isOpen = ref(false);
67
- const formValues = ref({});
68
- const form = ref({});
69
-
70
- const openConfirm = () => {
71
- confirm({
72
- title: t("builder.deleteTitle"),
73
- message: t("builder.deleteField"),
74
- type: 'error',
75
- onConfirm: () => {
76
- deleteItem();
77
- },
78
- })
79
- };
80
-
81
- const deleteItem = () => {
82
- data.value = data.value.filter((item) => item.id !== props.item.id);
83
- };
84
-
85
- const updateItem = async () => {
86
- let result = await form.value.validate();
87
- if (result) {
88
- notify({
89
- type: "warning",
90
- title: t("common.actions.warning"),
91
- message: t("builder.editFieldFailed"),
92
- });
93
- return;
94
- }
95
- data.value = data.value.map((item) =>
96
- item.id === props.item.id ? formValues.value : item
97
- );
98
- isOpen.value = false;
99
- };
100
-
101
- watch(isOpen, (newVal) => {
102
- if (newVal) {
103
- formValues.value = props.item;
104
- }
105
- });
106
- </script>
@@ -1,23 +0,0 @@
1
- import VsFormSlug from "./vs-form-slug.vue";
2
- import VsFormMonacoEditor from "./MonacoEditor.vue";
3
- import VsFormReference from "./vs-form-reference-list.vue";
4
- import VsFormRelation from "./vs-form-relation.vue";
5
- import VsFormInteger from "./vs-form-integer.vue";
6
- import VsFormCustomDatatable from "./vs-form-custom-datatable.vue";
7
- import VsFormRichtextMd from "./vs-form-marcdown-md.vue";
8
- import VsFormKeyValue from "./vs-form-key-value.vue";
9
- import VsFormRelationLink from "./vs-form-reletion-link.vue";
10
- import VsFormMediaselect from "./vs-form-media-select.vue";
11
-
12
- export default {
13
- VsFormSlug,
14
- VsFormMonacoEditor,
15
- VsFormReference,
16
- VsFormRelation,
17
- VsFormInteger,
18
- VsFormCustomDatatable,
19
- VsFormRichtextMd,
20
- VsFormKeyValue,
21
- VsFormRelationLink,
22
- VsFormMediaselect,
23
- };
@@ -1,92 +0,0 @@
1
- <template>
2
- <div>
3
- <button
4
- type="button"
5
- class="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-sky-500"
6
- @click="isOpen = !isOpen"
7
- >
8
- {{ $t("builder.create") }}
9
- </button>
10
- <VsDrawer v-model:visible="isOpen" @close="isOpen = false" :title="title" :size="'50vw'">
11
- <VsForm
12
- v-model:form="form"
13
- v-if="schema"
14
- :schema="schema"
15
- v-model="formValue"
16
- class="-mr-[10px] ml-[10px] mt-[10px]"
17
- />
18
- <template #footer>
19
- <div
20
- class="flex items-center justify-between w-full p-4 border-t border-gray-200 dark:border-gray-700"
21
- >
22
- <button
23
- class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600"
24
- >
25
- {{ $t("builder.cancel") }}
26
- </button>
27
- <button
28
- @click="handleCreate"
29
- class="px-4 py-2 bg-sky-600 text-white rounded-md text-sm font-medium hover:bg-sky-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-sky-500"
30
- >
31
- {{ $t("builder.create") }}
32
- </button>
33
- </div>
34
- </template>
35
- </VsDrawer>
36
- </div>
37
- </template>
38
-
39
- <script setup>
40
- import { ref, watch } from "vue";
41
- import VsForm from "@opengis/form";
42
- import { VsDrawer } from "@opengis/core";
43
- import { notify } from '@opengis/core';
44
- import { useI18n } from "vue-i18n";
45
-
46
- const { t } = useI18n();
47
-
48
- const props = defineProps({
49
- title: {
50
- type: String,
51
- default: "",
52
- },
53
-
54
- schema: {
55
- type: Object,
56
- default: () => ({}),
57
- },
58
- });
59
-
60
- const model = defineModel({
61
- type: Object,
62
- default: () => ({}),
63
- });
64
-
65
- const isOpen = ref(false);
66
- const form = ref({});
67
- const formValue = ref({});
68
-
69
- const handleCreate = async () => {
70
- try {
71
- let result = await form.value.validate();
72
- if (result) {
73
- notify({
74
- type: "warning",
75
- title: t("common.actions.warning"),
76
- message: t("builder.editFieldFailed"),
77
- });
78
- return;
79
- }
80
- model.value = { ...formValue.value };
81
- isOpen.value = false;
82
- } catch (error) {
83
- console.log(error);
84
- }
85
- };
86
-
87
- watch(isOpen, (newVal) => {
88
- if (newVal) {
89
- formValue.value = { ...model.value };
90
- }
91
- });
92
- </script>