@opengis/cms 0.0.57 → 0.0.59

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 (56) hide show
  1. package/README.md +1 -1
  2. package/dist/AddNewItemInTree-05PSSEFi.js +76 -0
  3. package/dist/ArticlesPage-BjYzvTWM.js +298 -0
  4. package/dist/CollectionsBreadcrumb-HePNJb-d.js +4 -0
  5. package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-BJh-tjam.js +53 -0
  6. package/dist/CollectionsPage-DHfPNql6.js +124 -0
  7. package/dist/{CreateForm-BMOBeP4G.js → CreateForm-5FvT45vH.js} +1 -1
  8. package/dist/Dashboard-CXkg_pk8.js +358 -0
  9. package/dist/EditCollectionPage-CqYHpEON.js +187 -0
  10. package/dist/{EmptyData-DaZt_nAm.js → EmptyData-DxPrSXhV.js} +1 -1
  11. package/dist/{MenuAddPage-Bf48Z-ah.js → MenuAddPage-QTnwCoGh.js} +40 -35
  12. package/dist/MenuBody-Bi0ONVZf.js +125 -0
  13. package/dist/MenuItemPage-B7Y9KFyb.js +1027 -0
  14. package/dist/MenuList-BLIpeqSd.js +172 -0
  15. package/dist/MenuPage-3W6jZ15H.js +107 -0
  16. package/dist/MenuWrapper-OrOv6sOb.js +12 -0
  17. package/dist/MonacoEditor-ByPT8pnv.js +4 -0
  18. package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-C8cip9Ci.js +84 -0
  19. package/dist/{UniversalTable.vue_vue_type_script_setup_true_lang-CJGTsd1V.js → UniversalTable-GBd_pStq.js} +81 -81
  20. package/dist/{UniversalTablePagination.vue_vue_type_script_setup_true_lang-GYZd_gkA.js → UniversalTablePagination-Dw2hc0nc.js} +47 -47
  21. package/dist/VsFormTags-CMjiu9sY.js +114 -0
  22. package/dist/VsPreview-DwETkOpb.js +63 -0
  23. package/dist/contentForm-Buku-lel.js +489 -0
  24. package/dist/getField-CpwVE28P.js +179 -0
  25. package/dist/index.d.ts +8 -0
  26. package/dist/index.js +72 -71
  27. package/dist/style.css +1 -1
  28. package/dist/vs-builder-edit-D-q1o8tF.js +604 -0
  29. package/dist/vs-builder-monaco-Cw-f19gc.js +33 -0
  30. package/dist/vs-builder-preview-BH4VAM3a.js +44 -0
  31. package/dist/vs-form-custom-datatable-BDZo48w3.js +317 -0
  32. package/dist/vs-form-integer-BZ855R3g.js +61 -0
  33. package/dist/vs-form-media-select-NY27EaG1.js +837 -0
  34. package/dist/vs-form-reference-list-Dtv8fJJU.js +1536 -0
  35. package/dist/vs-form-reletion-link-BhzNQszm.js +34 -0
  36. package/dist/vs-form-tiptap-DDFQjRjY.js +4 -0
  37. package/dist/vs-form-tiptap.vue_vue_type_script_setup_true_lang-DGgsqXwg.js +11 -0
  38. package/dist/vs-richtext-md-C098v_6Q.js +4 -0
  39. package/dist/vs-richtext-md.vue_vue_type_script_setup_true_lang-Ct8uTV-J.js +14 -0
  40. package/locales/en.json +1 -0
  41. package/locales/uk.json +1 -0
  42. package/package.json +69 -68
  43. package/server/functions/utils/mock.reply.js +7 -7
  44. package/server/routes/cms/controllers/getPermissions.js +15 -15
  45. package/server/routes/cms/controllers/setPermissions.js +49 -49
  46. package/server/templates/select/core.user_mentioned.sql +1 -1
  47. package/dist/ArticlesPage-BcR1hbds.js +0 -286
  48. package/dist/BuilderPage-CK_osM89.js +0 -386
  49. package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-CnOe9ORD.js +0 -45
  50. package/dist/CollectionsPage-JfmrHNR_.js +0 -110
  51. package/dist/EditCollectionPage-Cw3GQYRe.js +0 -809
  52. package/dist/MenuItemPage-CXn5HC8j.js +0 -1366
  53. package/dist/MenuPage-tJZtK46W.js +0 -106
  54. package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-B1DrxmQX.js +0 -84
  55. package/dist/contentForm-B6gHgGkz.js +0 -586
  56. package/dist/getField-Y5WXnRR0.js +0 -2948
package/README.md CHANGED
@@ -63,7 +63,7 @@ export default [
63
63
  },
64
64
  {
65
65
  path: '/cms.content/:type?/:id?',
66
- component: () => import('@opengis/cms').then(el => el.Contnet),
66
+ component: () => import('@opengis/cms').then(el => el.Content),
67
67
  },
68
68
  {
69
69
  path: '/cms.menu/:id?',
@@ -0,0 +1,76 @@
1
+ import { defineComponent as g, mergeModels as x, useModel as w, ref as m, openBlock as y, createBlock as C, unref as i, withCtx as u, createElementVNode as s, toDisplayString as d, createVNode as k } from "vue";
2
+ import { useI18n as V } from "vue-i18n";
3
+ import M from "@opengis/form";
4
+ import { VsModal as h, notify as q } from "@opengis/core";
5
+ const I = { class: "flex justify-end p-[20px] gap-[10px] border-t w-full" }, F = /* @__PURE__ */ g({
6
+ __name: "AddNewItemInTree",
7
+ props: {
8
+ isOpen: { type: Boolean, required: !0 },
9
+ isOpenModifiers: {}
10
+ },
11
+ emits: /* @__PURE__ */ x(["addNewItem"], ["update:isOpen"]),
12
+ setup(p, { emit: c }) {
13
+ const { t } = V(), a = w(p, "isOpen"), n = m({}), f = c, o = m({}), v = {
14
+ title: {
15
+ type: "text",
16
+ label: t("cms.menu.form.name"),
17
+ required: !0,
18
+ placeholder: t("cms.menu.form.name"),
19
+ validators: ["required"]
20
+ },
21
+ value: {
22
+ type: "text",
23
+ label: t("cms.menu.form.value"),
24
+ required: !0,
25
+ placeholder: t("cms.menu.form.value"),
26
+ validators: ["required"]
27
+ }
28
+ }, b = async () => {
29
+ if (await n.value.validate()) {
30
+ q({
31
+ type: "warning",
32
+ title: t("cms.common.actions.warning"),
33
+ message: t("cms.menu.createMenuFailed")
34
+ });
35
+ return;
36
+ }
37
+ f("addNewItem", o.value), o.value = {};
38
+ };
39
+ return (r, e) => (y(), C(i(h), {
40
+ teleport: "#modal",
41
+ visible: a.value,
42
+ title: r.$t("cms.menu.createMenu"),
43
+ template: "default",
44
+ closeClickBack: !1,
45
+ onClose: e[3] || (e[3] = (l) => a.value = !1)
46
+ }, {
47
+ footer: u(() => [
48
+ s("div", I, [
49
+ s("button", {
50
+ 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",
51
+ onClick: e[2] || (e[2] = (l) => {
52
+ a.value = !1, o.value = {};
53
+ })
54
+ }, d(r.$t("cms.common.actions.cancel")), 1),
55
+ s("button", {
56
+ onClick: b,
57
+ 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"
58
+ }, d(r.$t("cms.common.actions.save")), 1)
59
+ ])
60
+ ]),
61
+ default: u(() => [
62
+ k(i(M), {
63
+ form: n.value,
64
+ "onUpdate:form": e[0] || (e[0] = (l) => n.value = l),
65
+ modelValue: o.value,
66
+ "onUpdate:modelValue": e[1] || (e[1] = (l) => o.value = l),
67
+ schema: v
68
+ }, null, 8, ["form", "modelValue"])
69
+ ]),
70
+ _: 1
71
+ }, 8, ["visible", "title"]));
72
+ }
73
+ });
74
+ export {
75
+ F as default
76
+ };
@@ -0,0 +1,298 @@
1
+ import { defineComponent as ce, defineAsyncComponent as D, ref as o, inject as ue, computed as R, onMounted as de, watch as L, nextTick as z, openBlock as n, createElementBlock as d, createVNode as A, unref as u, createElementVNode as r, toDisplayString as b, createTextVNode as me, createCommentVNode as h, createStaticVNode as pe, createBlock as N } from "vue";
2
+ import { useRoute as ve, useRouter as fe } from "vue-router";
3
+ import { HelpCircle as he, Plus as ge, ChevronDown as be, Calendar as G, User as ye, Globe as we, FileText as xe } from "lucide-vue-next";
4
+ import { VsInputCheckbox as ke } from "@opengis/form";
5
+ import Ce from "@opengis/filter";
6
+ import { confirm as H } from "@opengis/core";
7
+ import { useI18n as _e } from "vue-i18n";
8
+ const $e = { class: "space-y-6 mx-auto max-w-[90%]" }, Ae = { class: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between" }, Ee = { class: "flex items-center gap-2" }, Te = { class: "text-3xl font-bold text-slate-800 dark:text-white mb-2" }, Ue = ["href", "title"], je = { class: "flex items-center gap-2" }, qe = {
9
+ key: 0,
10
+ class: "text-card-foreground shadow-lg border-0 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm"
11
+ }, Fe = {
12
+ key: 1,
13
+ class: "text-card-foreground shadow-lg border-0 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm"
14
+ }, Ve = {
15
+ key: 0,
16
+ class: "p-2 border-b border-gray-200 sm:px-4 sm:py-2 dark:border-gray-700"
17
+ }, De = { class: "flex flex-col gap-4 sm:flex-row" }, Ne = { class: "relative flex items-center gap-2 ml-auto" }, Be = {
18
+ key: 1,
19
+ class: "absolute top-full right-2/3 translate-x-1/2 min-w-[150%] p-4 z-10 bg-white border border-gray-300 rounded-md mt-2 dark:bg-slate-800 dark:border-slate-700 shadow-lg"
20
+ }, Oe = { class: "max-h-60 overflow-y-auto overflow-x-hidden" }, Le = { key: 2 }, Ke = /* @__PURE__ */ ce({
21
+ __name: "ArticlesPage",
22
+ setup(Se) {
23
+ const K = D(
24
+ () => import("./UniversalTable-GBd_pStq.js")
25
+ ), Q = D(
26
+ () => import("./UniversalTablePagination-Dw2hc0nc.js")
27
+ ), J = D(
28
+ () => import("./EmptyData-DxPrSXhV.js")
29
+ ), W = D(
30
+ () => import("./CollectionsBreadcrumb-HePNJb-d.js")
31
+ ), s = ve(), m = fe(), c = o(null), X = o(""), { t: y, locale: Y } = _e(), E = o([]), Z = ue("cms.menu") || [], T = o(""), v = o(""), U = o(null), j = o(1), w = o(!1), p = o(["title", "slug", "author", "publish_at", "published_at", "status"]), q = o([]), x = o([]), F = o([]), k = o({}), V = o(0), C = o(!1), S = () => {
32
+ var l;
33
+ let t = (l = c.value) == null ? void 0 : l.columns.filter((e) => {
34
+ var a;
35
+ return (a = p == null ? void 0 : p.value) == null ? void 0 : a.includes(e.name);
36
+ });
37
+ q.value = t.map((e) => {
38
+ switch (e.name) {
39
+ case "title":
40
+ return {
41
+ ...e,
42
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "--",
43
+ icon: xe
44
+ };
45
+ case "slug":
46
+ return {
47
+ ...e,
48
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "-",
49
+ icon: we
50
+ };
51
+ case "author":
52
+ return {
53
+ ...e,
54
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "-",
55
+ icon: ye
56
+ };
57
+ case "publish_at":
58
+ return {
59
+ ...e,
60
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "-",
61
+ icon: G
62
+ };
63
+ case "published_at":
64
+ return {
65
+ ...e,
66
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "-",
67
+ icon: G
68
+ };
69
+ default:
70
+ return {
71
+ ...e,
72
+ title: e.name ? e.name.charAt(0).toUpperCase() + e.name.slice(1) : "-"
73
+ };
74
+ }
75
+ }), w.value = !1;
76
+ }, I = R(
77
+ () => {
78
+ var e, a, i, f;
79
+ const t = (s.params.id || "").toString(), l = t === "pages" ? y("cms.articles.title") : t;
80
+ return ((e = U.value) == null ? void 0 : e.title) || ((a = c.value) == null ? void 0 : a.title) || T.value || ((f = (i = Z.value) == null ? void 0 : i.find(($) => $.id === s.params.id)) == null ? void 0 : f.title) || l;
81
+ }
82
+ ), M = async () => {
83
+ try {
84
+ const t = await fetch("/api/cms-type?type=collection");
85
+ if (!t.ok)
86
+ return;
87
+ const e = ((await t.json()).rows || []).find((a) => a.id === s.params.id);
88
+ e && (U.value = e);
89
+ } catch (t) {
90
+ console.error("Error fetching collection meta:", t);
91
+ }
92
+ }, ee = R(() => [
93
+ {
94
+ label: I.value || s.params.id,
95
+ route: `collections/${s.params.id}`
96
+ }
97
+ ]), te = (t) => {
98
+ t === "collections" ? m.push("/collections") : m.push(`/${t}`);
99
+ }, P = () => {
100
+ m.push(`/collections/${s.params.id}/create`);
101
+ }, ae = () => {
102
+ m.push(`/collections/${s.params.id}/edit`);
103
+ }, le = async () => {
104
+ H({
105
+ title: y("cms.builder.deleteTitle"),
106
+ message: y("cms.builder.deleteObject"),
107
+ type: "error",
108
+ onConfirm: async () => {
109
+ try {
110
+ await fetch(`/api/cms-type/${s.params.id}`, { method: "DELETE" }), m.push("/collections");
111
+ } catch (t) {
112
+ console.error("Failed to delete collection:", t);
113
+ }
114
+ }
115
+ });
116
+ }, se = async (t) => {
117
+ H({
118
+ title: y("cms.builder.deleteTitle"),
119
+ message: y("cms.builder.deleteObject"),
120
+ type: "error",
121
+ onConfirm: async () => {
122
+ await fetch(`/api/cms/${s.params.id}/${t.id}`, { method: "DELETE" }), _();
123
+ }
124
+ });
125
+ }, ie = (t) => {
126
+ m.push(`/collections/${s.params.id}/${t.id}`);
127
+ }, _ = async () => {
128
+ var t, l;
129
+ if (!C.value) {
130
+ C.value = !0;
131
+ try {
132
+ const a = await (await fetch(
133
+ `/api/cms/${s.params.id}?page=${j.value}&filter=${v.value}&limit=12`
134
+ )).json();
135
+ if (E.value = a.rows || [], c.value = a, (a == null ? void 0 : a.type) === "single" && ((l = (t = a == null ? void 0 : a.rows) == null ? void 0 : t[0]) != null && l.title) && (T.value = a.rows[0].title), !F.value.length) {
136
+ const i = (a.filters || []).map((f) => {
137
+ const { extra: $, title: O, ...g } = f;
138
+ return g;
139
+ });
140
+ F.value = i;
141
+ }
142
+ s.params.id === "pages" && p.value.push("type"), oe(), S();
143
+ } finally {
144
+ C.value = !1;
145
+ }
146
+ }
147
+ }, oe = () => {
148
+ var l;
149
+ if (!((l = c.value) != null && l.columns))
150
+ return;
151
+ const t = c.value.columns.map((e, a) => ({
152
+ text: e.label,
153
+ id: e.name
154
+ }));
155
+ x.value = [
156
+ ...p.value.map((e) => t.find((a) => a.id === e)).filter(Boolean),
157
+ ...t.filter((e) => !p.value.includes(e.id))
158
+ ];
159
+ }, ne = (t, l) => {
160
+ if (!l)
161
+ return !0;
162
+ const e = l.toLowerCase();
163
+ return q.value.some((a) => {
164
+ const i = t[a.name];
165
+ return i && i.toString().toLowerCase().includes(e);
166
+ });
167
+ }, re = (t) => {
168
+ const l = Object.entries(t == null ? void 0 : t.data).filter(([, a]) => a != null).map(([a, i]) => `${a}=${i}`).join("|");
169
+ v.value = l;
170
+ const e = { ...s.query };
171
+ l ? e.filter = l : delete e.filter, m.replace({ query: e });
172
+ }, B = () => {
173
+ if (s.query.filter) {
174
+ v.value = s.query.filter;
175
+ const t = s.query.filter.split("|"), l = {};
176
+ t.forEach((e) => {
177
+ const [a, i] = e.split("=");
178
+ a && i && (l[a] = i);
179
+ }), k.value = l;
180
+ } else
181
+ v.value = "", k.value = {}, V.value++;
182
+ };
183
+ return de(() => {
184
+ B(), M(), _();
185
+ }), L(() => s.params.id, () => {
186
+ k.value = {}, v.value = "", F.value = [], U.value = null, T.value = "";
187
+ const t = { ...s.query };
188
+ delete t.filter, m.replace({ query: t }), V.value++, B(), M(), _();
189
+ }), L(() => s.query, async () => {
190
+ B(), await z(), _();
191
+ }, { deep: !0 }), L(j, async () => {
192
+ s.query.filter || (v.value = "", k.value = {}, V.value++), await z(), _();
193
+ }), (t, l) => {
194
+ var e, a, i, f, $, O;
195
+ return n(), d("div", $e, [
196
+ A(u(W), {
197
+ items: ee.value,
198
+ loading: C.value && !((e = U.value) != null && e.title) && !((a = c.value) != null && a.title) && !T.value,
199
+ onNavigate: te
200
+ }, null, 8, ["items", "loading"]),
201
+ r("div", Ae, [
202
+ r("div", Ee, [
203
+ r("h1", Te, b(I.value), 1),
204
+ r("a", {
205
+ href: `https://cms.opengis.info/${u(Y)}/guides/content/`,
206
+ target: "_blank",
207
+ title: t.$t("cms.guide.content")
208
+ }, [
209
+ A(u(he), { class: "w-5 h-5" })
210
+ ], 8, Ue)
211
+ ]),
212
+ r("div", je, [
213
+ E.value.length ? (n(), d("button", {
214
+ key: 0,
215
+ onClick: P,
216
+ class: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium h-9 px-4 py-2 bg-blue-600 text-white shadow-md transition-all duration-200 transform hover:bg-blue-700 hover:shadow-lg hover:scale-105 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
217
+ }, [
218
+ A(u(ge), { class: "w-4 h-4 mr-2" }),
219
+ me(" " + b(t.$t("cms.articles.createArticle")), 1)
220
+ ])) : h("", !0),
221
+ ((i = c.value) == null ? void 0 : i.type) === "collection" ? (n(), d("button", {
222
+ key: 1,
223
+ onClick: ae,
224
+ class: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium h-9 px-4 py-2 border border-slate-300 bg-white text-slate-700 shadow-sm transition-all duration-200 transform hover:bg-slate-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
225
+ }, b(t.$t("cms.common.actions.edit")), 1)) : h("", !0),
226
+ r("button", {
227
+ onClick: le,
228
+ class: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium h-9 px-4 py-2 border border-red-300 bg-white text-red-600 shadow-sm transition-all duration-200 transform hover:bg-red-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
229
+ }, b(t.$t("cms.common.actions.delete")), 1)
230
+ ])
231
+ ]),
232
+ C.value ? (n(), d("div", qe, [...l[3] || (l[3] = [
233
+ pe('<div class="p-4 border-b border-gray-200 sm:px-4 sm:py-3 dark:border-gray-700"><div class="flex flex-col gap-4 sm:flex-row sm:items-center"><div class="h-10 w-full rounded-md bg-gray-100 animate-pulse sm:max-w-2xl"></div><div class="h-10 w-40 rounded-md bg-gray-100 animate-pulse sm:ml-auto"></div></div></div><div class="p-4 space-y-3"><div class="h-12 rounded-md bg-gray-100 animate-pulse"></div><div class="h-12 rounded-md bg-gray-100 animate-pulse"></div><div class="h-12 rounded-md bg-gray-100 animate-pulse"></div><div class="h-12 rounded-md bg-gray-100 animate-pulse"></div><div class="h-12 rounded-md bg-gray-100 animate-pulse"></div></div>', 2)
234
+ ])])) : E.value.length || v.value.length ? (n(), d("div", Fe, [
235
+ (n(), d("div", Ve, [
236
+ r("div", De, [
237
+ (n(), N(u(Ce), {
238
+ key: V.value,
239
+ schema: F.value,
240
+ history: !0,
241
+ value: k.value,
242
+ view: "inline",
243
+ onChange: re
244
+ }, null, 8, ["schema", "value"])),
245
+ r("div", Ne, [
246
+ x.value.length > 0 ? (n(), d("div", {
247
+ key: 0,
248
+ class: "flex items-center gap-2 cursor-pointer text-sm border border-gray-300 rounded-md p-2 dark:text-white",
249
+ onClick: l[0] || (l[0] = (g) => w.value = !w.value)
250
+ }, [
251
+ r("p", null, b(t.$t("cms.articles.showColumns")), 1),
252
+ A(u(be), { class: "w-4 h-4" })
253
+ ])) : h("", !0),
254
+ x.value.length > 0 && w.value ? (n(), d("div", Be, [
255
+ r("div", Oe, [
256
+ x.value.length > 0 && w.value ? (n(), N(u(ke), {
257
+ key: 0,
258
+ options: x.value,
259
+ modelValue: p.value,
260
+ "onUpdate:modelValue": l[1] || (l[1] = (g) => p.value = g)
261
+ }, null, 8, ["options", "modelValue"])) : h("", !0)
262
+ ]),
263
+ r("button", {
264
+ class: "text-sm bg-blue-600 text-white rounded-md p-2 mt-4 w-full",
265
+ onClick: S
266
+ }, b(t.$t("cms.articles.update")), 1)
267
+ ])) : h("", !0)
268
+ ])
269
+ ])
270
+ ])),
271
+ q.value.length > 0 ? (n(), N(u(K), {
272
+ key: 1,
273
+ class: "max-h-[calc(100vh-290px)] overflow-y-auto",
274
+ rows: E.value,
275
+ columns: q.value,
276
+ query: X.value,
277
+ filterFn: ne,
278
+ onDelete: se,
279
+ onEdit: ie
280
+ }, null, 8, ["rows", "columns", "query"])) : h("", !0),
281
+ ((f = c.value) == null ? void 0 : f.total) > 20 ? (n(), N(u(Q), {
282
+ key: 2,
283
+ total: ($ = c.value) == null ? void 0 : $.filtered,
284
+ count: (O = c.value) == null ? void 0 : O.count,
285
+ page: j.value,
286
+ "onUpdate:page": l[2] || (l[2] = (g) => j.value = g),
287
+ limit: 20
288
+ }, null, 8, ["total", "count", "page"])) : h("", !0)
289
+ ])) : (n(), d("div", Le, [
290
+ A(u(J), { onAction: P })
291
+ ]))
292
+ ]);
293
+ };
294
+ }
295
+ });
296
+ export {
297
+ Ke as default
298
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as f } from "./CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-BJh-tjam.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,53 @@
1
+ import { defineComponent as k, openBlock as e, createElementBlock as s, createElementVNode as a, createVNode as m, unref as n, toDisplayString as u, Fragment as r, createBlock as c, createCommentVNode as p, renderList as b } from "vue";
2
+ import { Layers as x, ChevronRight as i } from "lucide-vue-next";
3
+ const h = { class: "flex items-center space-x-1 mb-4 overflow-hidden" }, g = { class: "truncate block max-w-[12rem]" }, w = ["onClick"], f = { class: "truncate block max-w-[20rem]" }, v = {
4
+ key: 1,
5
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium text-slate-700 dark:text-slate-300 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis"
6
+ }, y = { class: "truncate block max-w-[20rem]" }, N = /* @__PURE__ */ k({
7
+ __name: "CollectionsBreadcrumb",
8
+ props: {
9
+ items: {},
10
+ loading: { type: Boolean }
11
+ },
12
+ emits: ["navigate"],
13
+ setup(C) {
14
+ return (t, l) => (e(), s("div", h, [
15
+ a("button", {
16
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium transition-all duration-200 text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis",
17
+ onClick: l[0] || (l[0] = (o) => t.$emit("navigate", "collections"))
18
+ }, [
19
+ m(n(x), { class: "w-3 h-3 flex-shrink-0" }),
20
+ a("span", g, u(t.$t("cms.navigation.collections")), 1)
21
+ ]),
22
+ t.loading ? (e(), s(r, { key: 0 }, [
23
+ m(n(i), { class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0" }),
24
+ l[1] || (l[1] = a("div", { class: "h-7 w-24 rounded bg-slate-200 dark:bg-slate-700 animate-pulse" }, null, -1)),
25
+ m(n(i), { class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0" }),
26
+ l[2] || (l[2] = a("div", { class: "h-7 w-20 rounded bg-slate-200 dark:bg-slate-700 animate-pulse" }, null, -1))
27
+ ], 64)) : (e(), s(r, { key: 1 }, [
28
+ t.items.length > 0 ? (e(), c(n(i), {
29
+ key: 0,
30
+ class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0"
31
+ })) : p("", !0),
32
+ (e(!0), s(r, null, b(t.items, (o, d) => (e(), s(r, { key: d }, [
33
+ d < t.items.length - 1 ? (e(), s("button", {
34
+ key: 0,
35
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium transition-all duration-200 text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis",
36
+ onClick: (_) => t.$emit("navigate", o.route)
37
+ }, [
38
+ a("span", f, u(o.label), 1)
39
+ ], 8, w)) : (e(), s("span", v, [
40
+ a("span", y, u(o.label), 1)
41
+ ])),
42
+ d < t.items.length - 1 ? (e(), c(n(i), {
43
+ key: 2,
44
+ class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0"
45
+ })) : p("", !0)
46
+ ], 64))), 128))
47
+ ], 64))
48
+ ]));
49
+ }
50
+ });
51
+ export {
52
+ N as _
53
+ };
@@ -0,0 +1,124 @@
1
+ import { defineComponent as E, defineAsyncComponent as f, inject as L, ref as u, computed as V, onMounted as B, openBlock as i, createElementBlock as n, createElementVNode as e, toDisplayString as a, unref as r, createVNode as d, withDirectives as F, vModelText as A, Fragment as y, renderList as v, createStaticVNode as D, createBlock as _ } from "vue";
2
+ import { useRouter as N } from "vue-router";
3
+ import { HelpCircle as S, Search as M, File as R, Layers as T, ChevronRight as q } from "lucide-vue-next";
4
+ import { useI18n as H } from "vue-i18n";
5
+ const I = { class: "space-y-6 mx-auto max-w-[90%]" }, P = { class: "flex items-center justify-between mb-8" }, Q = { class: "flex gap-4" }, U = { class: "text-3xl font-bold text-slate-800 dark:text-slate-100 mb-2" }, z = { class: "text-slate-600 dark:text-slate-300" }, G = ["href", "title"], J = { class: "flex items-center gap-3" }, K = { class: "relative w-full max-w-sm" }, O = { class: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none" }, W = ["placeholder"], X = {
6
+ key: 0,
7
+ class: "grid grid-cols-1 gap-4 mb-6 md:grid-cols-2 lg:grid-cols-3"
8
+ }, Y = { key: 1 }, Z = { class: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6" }, ee = ["onClick"], te = { class: "flex items-start justify-between" }, se = { class: "flex items-start gap-3" }, oe = { class: "text-sm font-semibold text-gray-800 mb-1" }, le = { class: "flex items-center gap-2" }, ie = { class: "text-xs text-gray-500 whitespace-nowrap" }, re = { class: "pl-8 text-xs text-gray-600 line-clamp-2" }, ne = {
9
+ key: 2,
10
+ class: "flex items-center justify-center min-h-[400px]"
11
+ }, pe = /* @__PURE__ */ E({
12
+ __name: "CollectionsPage",
13
+ setup(ae) {
14
+ const x = f(
15
+ () => import("./EmptyData-DxPrSXhV.js")
16
+ ), b = f(
17
+ () => import("./CreateForm-5FvT45vH.js")
18
+ ), { t: de, locale: w } = H(), k = N();
19
+ L("fetchContentTypes");
20
+ const h = u([]), c = u(""), g = u(!0), p = V(() => {
21
+ const s = h.value.filter(
22
+ (t) => t.type !== "single"
23
+ ), l = c.value.trim().toLowerCase();
24
+ return [...l ? s.filter((t) => [t == null ? void 0 : t.title, t == null ? void 0 : t.name, t == null ? void 0 : t.id, t == null ? void 0 : t.description].filter(Boolean).join(" ").toLowerCase().includes(l)) : s].sort((t, m) => t.id === "pages" ? -1 : m.id === "pages" ? 1 : 0);
25
+ });
26
+ async function C() {
27
+ try {
28
+ const s = await fetch("/api/cms-type?type=collection");
29
+ if (!s.ok)
30
+ throw new Error("Failed to fetch collections");
31
+ const l = await s.json();
32
+ h.value = l.rows || [];
33
+ } catch (s) {
34
+ console.error("Error fetching collections:", s);
35
+ } finally {
36
+ g.value = !1;
37
+ }
38
+ }
39
+ const $ = (s) => {
40
+ k.push(`/collections/${s.id}`);
41
+ };
42
+ return B(() => {
43
+ C();
44
+ }), (s, l) => (i(), n("div", I, [
45
+ e("div", P, [
46
+ e("div", Q, [
47
+ e("div", null, [
48
+ e("h1", U, a(s.$t("cms.navigation.collections")), 1),
49
+ e("p", z, a(s.$t("cms.collections.selectCollection")), 1)
50
+ ]),
51
+ e("a", {
52
+ href: `https://cms.opengis.info/${r(w)}/guides/collections/`,
53
+ target: "_blank",
54
+ title: s.$t("cms.guide.collections"),
55
+ class: "mt-2"
56
+ }, [
57
+ d(r(S), { class: "w-5 h-5" })
58
+ ], 8, G)
59
+ ]),
60
+ e("div", J, [
61
+ e("div", K, [
62
+ e("div", O, [
63
+ d(r(M), { class: "w-5 h-5 text-gray-400" })
64
+ ]),
65
+ F(e("input", {
66
+ "onUpdate:modelValue": l[0] || (l[0] = (o) => c.value = o),
67
+ type: "text",
68
+ class: "block w-full py-2 pl-10 pr-3 leading-5 text-gray-900 placeholder-gray-500 transition-colors bg-white border border-gray-300 rounded-md dark:border-gray-600 dark:bg-gray-700 dark:placeholder-gray-400 focus:outline-none focus:ring-sky-500 focus:border-sky-500 dark:text-white sm:text-sm",
69
+ placeholder: s.$t("cms.collections.searchCollections")
70
+ }, null, 8, W), [
71
+ [A, c.value]
72
+ ])
73
+ ]),
74
+ d(r(b), {
75
+ redirectAfterCreate: (o) => `/collections/${o.id}`
76
+ }, null, 8, ["redirectAfterCreate"])
77
+ ])
78
+ ]),
79
+ g.value ? (i(), n("div", X, [
80
+ (i(), n(y, null, v(6, (o) => e("div", {
81
+ key: o,
82
+ class: "rounded-lg border border-gray-200 bg-white p-4 animate-pulse"
83
+ }, [...l[1] || (l[1] = [
84
+ D('<div class="flex items-start justify-between"><div class="flex items-start gap-3 flex-1"><div class="h-5 w-5 rounded bg-gray-200 shrink-0"></div><div class="flex-1 space-y-2"><div class="h-4 w-32 rounded bg-gray-200"></div><div class="h-3 w-20 rounded bg-gray-100"></div></div></div><div class="h-4 w-16 rounded bg-gray-100"></div></div>', 1)
85
+ ])])), 64))
86
+ ])) : p.value.length > 0 ? (i(), n("div", Y, [
87
+ e("div", Z, [
88
+ (i(!0), n(y, null, v(p.value, (o) => (i(), n("button", {
89
+ key: o.id,
90
+ onClick: (j) => $(o),
91
+ class: "w-full border border-gray-200 bg-white rounded-lg p-4 text-left hover:shadow-md transition-all hover:border-gray-300"
92
+ }, [
93
+ e("div", null, [
94
+ e("div", te, [
95
+ e("div", se, [
96
+ o.id === "pages" ? (i(), _(r(R), {
97
+ key: 0,
98
+ class: "shrink-0 lucide lucide-page w-5 h-5 text-blue-600"
99
+ })) : (i(), _(r(T), {
100
+ key: 1,
101
+ class: "shrink-0 lucide lucide-layers w-5 h-5 text-blue-600"
102
+ })),
103
+ e("div", null, [
104
+ e("h4", oe, a(o.title), 1)
105
+ ])
106
+ ]),
107
+ e("div", le, [
108
+ e("span", ie, a(o.entries) + " записів", 1),
109
+ d(r(q), { class: "w-4 h-4 text-gray-400" })
110
+ ])
111
+ ]),
112
+ e("p", re, a(o.description || "Опис відсутній"), 1)
113
+ ])
114
+ ], 8, ee))), 128))
115
+ ])
116
+ ])) : (i(), n("div", ne, [
117
+ d(r(x))
118
+ ]))
119
+ ]));
120
+ }
121
+ });
122
+ export {
123
+ pe as default
124
+ };
@@ -121,5 +121,5 @@ const O = { class: "flex justify-end p-[20px] gap-[10px] border-t w-full" }, D =
121
121
  }
122
122
  };
123
123
  export {
124
- D as _
124
+ D as default
125
125
  };