@opengis/gis 0.2.116 → 0.2.118

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 (42) hide show
  1. package/dist/CardIcon-FxpK90rl.js +51 -0
  2. package/dist/EntityCreatePage-Da8XgBKU.js +141 -0
  3. package/dist/EntityEditPage-QktKEAxz.js +167 -0
  4. package/dist/EntityTablePage-ii-Wz0YZ.js +286 -0
  5. package/dist/ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-Bl5ZwNQX.js +70 -0
  6. package/dist/FileEdit-C7tteUeG.js +37 -0
  7. package/dist/HeaderActions.vue_vue_type_script_setup_true_lang-CKEep8BL.js +796 -0
  8. package/dist/MapSettings-CjJ7WWkn.js +672 -0
  9. package/dist/MapSettingsTabs.vue_vue_type_script_setup_true_lang-CKCK3NqY.js +29 -0
  10. package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-Bs7gz6Lt.js +408 -0
  11. package/dist/RastersTablePage-DpKkFOyo.js +359 -0
  12. package/dist/TableFormHeader.vue_vue_type_script_setup_true_lang-Mci_tseM.js +47 -0
  13. package/dist/cartocss-C_O8qG3h.js +892 -0
  14. package/dist/import-utils-BbZ1gVp-.js +123 -0
  15. package/dist/index-4aSsUBB8.js +10020 -0
  16. package/dist/index.css +1 -1
  17. package/dist/index.js +16 -17634
  18. package/dist/index.umd.cjs +41 -244
  19. package/dist/raster-Du8ZMtjf.js +664 -0
  20. package/dist/register-B2gF-GzA.js +780 -0
  21. package/dist/service-BnPCDVwm.js +2573 -0
  22. package/dist/vs-datatable-QKks38xL.js +800 -0
  23. package/module/gis/form/feedback.answer.form.json +11 -0
  24. package/module/gis/form/gis.cartocss.form.json +8 -0
  25. package/module/gis/form/gis.metadata_new.form.json +196 -0
  26. package/module/gis/form/gis.ogc_service.form.json +8 -2
  27. package/module/gis/select/layer_list_text.sql +7 -0
  28. package/module/gis/select/pg.column_name.geometry.sql +13 -0
  29. package/module/gis/table/gis.metadata_new.table.json +138 -0
  30. package/module/gis/table/site.gis.registers.table.json +1 -1
  31. package/package.json +3 -4
  32. package/server/routes/gis/cartocss/get.cartocss.js +1 -1
  33. package/server/routes/mapnik/controllers/clearTiles.js +8 -4
  34. package/server/routes/mapnik/controllers/createXmlMulti.js +1 -1
  35. package/server/routes/mapnik/controllers/fileSearch.js +6 -2
  36. package/server/routes/mapnik/controllers/fileStat.js +4 -3
  37. package/server/routes/mapnik/controllers/mapnikLogger.js +1 -1
  38. package/server/routes/mapnik/controllers/mapnikStat.js +1 -1
  39. package/server/routes/mapnik/controllers/rasterInfo.js +5 -2
  40. package/server/routes/mapnik/controllers/readDir.js +5 -2
  41. package/server/routes/mapnik/controllers/rtile.js +16 -3
  42. package/server/routes/mapnik/index.js +0 -1
@@ -0,0 +1,796 @@
1
+ import { openBlock as m, createElementBlock as v, createElementVNode as r, defineComponent as J, normalizeClass as he, createVNode as j, createBlock as le, unref as E, defineAsyncComponent as W, ref as b, watch as ve, computed as y, createTextVNode as _e, Fragment as ae, renderList as ue, toDisplayString as z, withCtx as X, nextTick as we, onMounted as ke, onUnmounted as xe, withModifiers as ze, Teleport as Ve, normalizeStyle as Ce, createCommentVNode as te } from "vue";
2
+ import { _ as Ee } from "./index-4aSsUBB8.js";
3
+ import { Settings as Me, BrushCleaning as ce, SquareCode as Le, Pencil as Te } from "lucide-vue-next";
4
+ import { notify as D } from "@opengis/core";
5
+ const Se = {}, $e = {
6
+ xmlns: "http://www.w3.org/2000/svg",
7
+ width: "24",
8
+ height: "24",
9
+ viewBox: "0 0 24 24",
10
+ fill: "none",
11
+ stroke: "currentColor",
12
+ "stroke-width": "2",
13
+ "stroke-linecap": "round",
14
+ "stroke-linejoin": "round",
15
+ class: "inline-block shrink-0"
16
+ };
17
+ function Ue(l, h) {
18
+ return m(), v("svg", $e, [...h[0] || (h[0] = [
19
+ r("path", { d: "M8 3 4 7l4 4" }, null, -1),
20
+ r("path", { d: "M4 7h16" }, null, -1),
21
+ r("path", { d: "m16 21 4-4-4-4" }, null, -1),
22
+ r("path", { d: "M20 17H4" }, null, -1)
23
+ ])]);
24
+ }
25
+ const je = /* @__PURE__ */ Ee(Se, [["render", Ue]]), Ie = ["aria-label"], vt = /* @__PURE__ */ J({
26
+ __name: "PanelToggleButton",
27
+ props: {
28
+ open: { type: Boolean },
29
+ topClass: { default: "top-5" }
30
+ },
31
+ emits: ["toggle"],
32
+ setup(l) {
33
+ return (h, u) => (m(), v("button", {
34
+ type: "button",
35
+ onClick: u[0] || (u[0] = (B) => h.$emit("toggle")),
36
+ class: he([
37
+ "absolute right-0 w-5 h-9 shrink-0 rounded-l-lg inline-flex items-center justify-center",
38
+ "text-gray-600 hover:bg-gray-100 hover:text-gray-800 transition border border-gray-100 shadow-md bg-white z-[21]",
39
+ l.topClass
40
+ ]),
41
+ "aria-label": l.open ? "Закрити панель" : "Відкрити панель"
42
+ }, [
43
+ j(je, { class: "h-3 w-3" })
44
+ ], 10, Ie));
45
+ }
46
+ }), pt = /* @__PURE__ */ J({
47
+ __name: "SettingsIcon",
48
+ setup(l) {
49
+ return (h, u) => (m(), le(E(Me), {
50
+ size: 16,
51
+ class: "lucide lucide-settings"
52
+ }));
53
+ }
54
+ });
55
+ function Ae(l) {
56
+ const h = [
57
+ {
58
+ name: "description",
59
+ type: "textarea",
60
+ label: "Опис",
61
+ col: 12
62
+ },
63
+ {
64
+ name: "group_id",
65
+ type: "Autocomplete",
66
+ label: "Група",
67
+ data: "gis.group_list",
68
+ col: 6
69
+ },
70
+ {
71
+ name: "keywords",
72
+ type: "Tags",
73
+ label: "Ключові слова",
74
+ placeholder: "Введіть тег та натисніть Enter",
75
+ col: 12
76
+ },
77
+ {
78
+ name: "is_public",
79
+ type: "switcher",
80
+ label: "Публічність",
81
+ col: 6,
82
+ data: "yes_no"
83
+ },
84
+ {
85
+ name: "is_active",
86
+ type: "switcher",
87
+ label: "Активність",
88
+ col: 6,
89
+ data: "yes_no"
90
+ }
91
+ ], u = (e, _) => {
92
+ const I = Array.isArray(e == null ? void 0 : e.config) ? e.config[0] : null;
93
+ return l.normalizeValue(I == null ? void 0 : I[_]);
94
+ }, B = (e) => !Array.isArray(e == null ? void 0 : e.bounds) || e.bounds.length < 4 ? "" : e.bounds.map((_) => String(_)).join(", "), f = (e) => !Array.isArray(e == null ? void 0 : e.bounds) || e.bounds.length < 4 ? "" : e.bounds.map((_) => String(_)).join(", "), H = (e) => !Array.isArray(e == null ? void 0 : e.bands) || !e.bands.length ? "" : e.bands.join(", "), p = (e) => typeof e != "boolean" ? "" : e ? "Так" : "Ні", M = [
95
+ { label: "Група", value: (e) => l.normalizeValue((e == null ? void 0 : e.group_name) ?? l.resolvedGroupName ?? (e == null ? void 0 : e.group_id)) },
96
+ { label: "Статус", value: (e) => l.normalizeValue(l.statusLabel(e)) },
97
+ { label: "Видимість", value: (e) => l.normalizeValue(l.visibilityLabel(e)) },
98
+ { label: "Тип сервісу", value: (e) => l.normalizeValue(e == null ? void 0 : e.service_type) },
99
+ { label: "Тип джерела", value: (e) => l.normalizeValue(e == null ? void 0 : e.source_type) },
100
+ { label: "Шлях до джерела", value: (e) => l.normalizeValue(e == null ? void 0 : e.source_path) },
101
+ { label: "Тип геометрії", value: (e) => l.normalizeValue(e == null ? void 0 : e.geom_type) },
102
+ { label: "Геометрична колонка", value: (e) => l.normalizeValue(e == null ? void 0 : e.geometry_column) },
103
+ { label: "SRID", value: (e) => l.normalizeValue(e == null ? void 0 : e.srid) },
104
+ { label: "Кількість обʼєктів", value: (e) => l.normalizeValue(e == null ? void 0 : e.count) },
105
+ { label: "Створено", value: (e) => e != null && e.created_at ? l.formatDate(e.created_at) : "" },
106
+ { label: "Оновлено", value: (e) => e != null && e.updated_at ? l.formatDate(e.updated_at) : "" }
107
+ ], L = [
108
+ { label: "Ключ сервісу", value: (e) => l.normalizeValue(e == null ? void 0 : e.service_key) },
109
+ { label: "Виробник", value: (e) => l.normalizeValue((e == null ? void 0 : e.holder) ?? (e == null ? void 0 : e.producer)) },
110
+ { label: "Категорія", value: (e) => l.normalizeValue(e == null ? void 0 : e.category) },
111
+ { label: "Ліцензія", value: (e) => l.normalizeValue(e == null ? void 0 : e.license) },
112
+ { label: "Рік", value: (e) => l.normalizeValue(e == null ? void 0 : e.year) },
113
+ { label: "Ключові слова", value: (e) => l.normalizeValue(e == null ? void 0 : e.keywords) },
114
+ { label: "URL сервісу", value: (e) => l.normalizeValue(e == null ? void 0 : e.service_url) },
115
+ { label: "Metadata URL", value: (e) => l.normalizeValue(e == null ? void 0 : e.metadata_url) },
116
+ { label: "Thumbnail URL", value: (e) => l.normalizeValue(e == null ? void 0 : e.thumbnail_url) },
117
+ { label: "SQL / Query", value: (e) => l.normalizeValue(e == null ? void 0 : e.query) }
118
+ ];
119
+ return {
120
+ service: {
121
+ general: M,
122
+ meta: L,
123
+ edit: [
124
+ ...h,
125
+ { name: "service_key", type: "text", label: "Ключ сервісу", col: 6 },
126
+ { name: "producer", type: "text", label: "Виробник", col: 6 },
127
+ { name: "category", type: "text", label: "Категорія", col: 6 },
128
+ { name: "license", type: "text", label: "Ліцензія", col: 6 },
129
+ { name: "year", type: "number", label: "Рік", col: 6 },
130
+ { name: "service_url", type: "text", label: "URL сервісу", col: 12 },
131
+ { name: "metadata_url", type: "text", label: "Metadata URL", col: 12 },
132
+ { name: "thumbnail_url", type: "text", label: "Thumbnail URL", col: 12 },
133
+ { name: "query", type: "textarea", label: "SQL / Query", col: 12 }
134
+ ]
135
+ },
136
+ dataset: {
137
+ general: M,
138
+ meta: L,
139
+ edit: [
140
+ ...h,
141
+ { name: "service_key", type: "text", label: "Ключ сервісу", col: 6 },
142
+ { name: "producer", type: "text", label: "Виробник", col: 6 },
143
+ { name: "category", type: "text", label: "Категорія", col: 6 },
144
+ { name: "license", type: "text", label: "Ліцензія", col: 6 },
145
+ { name: "year", type: "number", label: "Рік", col: 6 },
146
+ { name: "service_url", type: "text", label: "URL сервісу", col: 12 },
147
+ { name: "metadata_url", type: "text", label: "Metadata URL", col: 12 },
148
+ { name: "thumbnail_url", type: "text", label: "Thumbnail URL", col: 12 },
149
+ { name: "query", type: "textarea", label: "SQL / Query", col: 12 }
150
+ ]
151
+ },
152
+ raster: {
153
+ general: [
154
+ { label: "Статус", value: (e) => l.normalizeValue(l.statusLabel(e)) },
155
+ { label: "Видимість", value: (e) => l.normalizeValue(l.visibilityLabel(e)) },
156
+ { label: "Формат", value: (e) => l.normalizeValue(e == null ? void 0 : e.extension) },
157
+ { label: "SRID", value: (e) => l.normalizeValue(e == null ? void 0 : e.srid) },
158
+ { label: "Файл джерела", value: (e) => l.normalizeValue(e == null ? void 0 : e.source_path) },
159
+ { label: "Кеш", value: (e) => p(e == null ? void 0 : e.cache) },
160
+ { label: "XML", value: (e) => p(e == null ? void 0 : e.xml) }
161
+ ],
162
+ meta: [
163
+ { label: "Tile URL", value: (e) => l.normalizeValue(e == null ? void 0 : e.url) },
164
+ { label: "Extent", value: (e) => f(e) },
165
+ { label: "Розмір", value: (e) => l.normalizeValue(e == null ? void 0 : e.total_size) },
166
+ { label: "Ширина", value: (e) => l.normalizeValue(e == null ? void 0 : e.width) },
167
+ { label: "Висота", value: (e) => l.normalizeValue(e == null ? void 0 : e.height) },
168
+ { label: "Кількість каналів", value: (e) => l.normalizeValue(e == null ? void 0 : e.bands_count) },
169
+ { label: "Канали", value: (e) => H(e) },
170
+ { label: "Роздільна здатність", value: (e) => l.normalizeValue(e == null ? void 0 : e.resolution) },
171
+ { label: "Глибина кольору", value: (e) => l.normalizeValue(e == null ? void 0 : e.color_depth) },
172
+ { label: "Стиснення", value: (e) => l.normalizeValue(e == null ? void 0 : e.compression) },
173
+ { label: "Proj4", value: (e) => l.normalizeValue(e == null ? void 0 : e.proj4) }
174
+ ],
175
+ edit: [
176
+ {
177
+ name: "description",
178
+ type: "textarea",
179
+ label: "Опис",
180
+ col: 12
181
+ },
182
+ {
183
+ name: "group_id",
184
+ type: "Autocomplete",
185
+ label: "Група",
186
+ data: "gis.group_list",
187
+ col: 6
188
+ },
189
+ {
190
+ name: "is_public",
191
+ type: "switcher",
192
+ label: "Публічність",
193
+ col: 6,
194
+ data: "yes_no"
195
+ },
196
+ {
197
+ name: "is_active",
198
+ type: "switcher",
199
+ label: "Активність",
200
+ col: 6,
201
+ data: "yes_no"
202
+ }
203
+ ]
204
+ },
205
+ css: {
206
+ general: [
207
+ { label: "Група", value: (e) => l.normalizeValue((e == null ? void 0 : e.group_name) ?? l.resolvedGroupName ?? (e == null ? void 0 : e.group_id)) },
208
+ { label: "Статус", value: (e) => l.normalizeValue(l.statusLabel(e)) },
209
+ { label: "Видимість", value: (e) => l.normalizeValue(l.visibilityLabel(e)) },
210
+ { label: "Ключ CartoCSS", value: (e) => l.normalizeValue(e == null ? void 0 : e.cartocss_key) },
211
+ { label: "Таблиця джерела", value: (e) => u(e, "table") || l.normalizeValue(e == null ? void 0 : e.source_path) },
212
+ { label: "Ключ набору", value: (e) => u(e, "key") },
213
+ { label: "Авто-картка", value: (e) => p(e == null ? void 0 : e.card_auto) },
214
+ { label: "Інфо по кліку", value: (e) => p(e == null ? void 0 : e.info) },
215
+ { label: "Статичний", value: (e) => p(e == null ? void 0 : e.is_static) }
216
+ ],
217
+ meta: [
218
+ { label: "Tile URL", value: (e) => l.normalizeValue(e == null ? void 0 : e.url) },
219
+ { label: "Bounds", value: (e) => B(e) },
220
+ { label: "SRID", value: (e) => u(e, "srid") },
221
+ { label: "Таблиця картки", value: (e) => l.normalizeValue(e == null ? void 0 : e.card_table) },
222
+ { label: "Min zoom", value: (e) => u(e, "minzoom") },
223
+ { label: "Max zoom", value: (e) => u(e, "maxzoom") }
224
+ ],
225
+ edit: [
226
+ {
227
+ name: "description",
228
+ type: "textarea",
229
+ label: "Опис",
230
+ col: 12
231
+ },
232
+ {
233
+ name: "group_id",
234
+ type: "Autocomplete",
235
+ label: "Група",
236
+ data: "gis.group_list",
237
+ col: 6
238
+ },
239
+ {
240
+ name: "is_public",
241
+ type: "switcher",
242
+ label: "Публічність",
243
+ col: 6,
244
+ data: "yes_no"
245
+ },
246
+ {
247
+ name: "enabled",
248
+ type: "switcher",
249
+ label: "Активність",
250
+ col: 6,
251
+ data: "yes_no"
252
+ },
253
+ {
254
+ name: "is_static",
255
+ type: "switcher",
256
+ label: "Статичний",
257
+ col: 6,
258
+ data: "yes_no"
259
+ }
260
+ ]
261
+ }
262
+ };
263
+ }
264
+ const Fe = { class: "flex-1 overflow-y-auto p-4" }, Re = { class: "space-y-4" }, Be = { class: "border border-gray-200 rounded-lg p-4" }, Ne = {
265
+ key: 0,
266
+ class: "grid grid-cols-2 gap-2"
267
+ }, De = { class: "text-xs text-gray-500 mb-1" }, He = { class: "text-sm font-semibold text-gray-900" }, Oe = {
268
+ key: 1,
269
+ class: "text-sm text-gray-700 leading-relaxed"
270
+ }, Ge = { class: "border border-gray-200 rounded-lg p-4" }, Pe = { class: "text-sm text-gray-700 leading-relaxed" }, Qe = { class: "border border-gray-200 rounded-lg p-4" }, qe = {
271
+ key: 0,
272
+ class: "grid grid-cols-2 gap-2"
273
+ }, We = { class: "text-xs text-gray-500 mb-1" }, Xe = { class: "text-sm font-semibold text-gray-900" }, Je = {
274
+ key: 1,
275
+ class: "text-sm text-gray-700 leading-relaxed"
276
+ }, Ye = { class: "flex justify-end gap-2 px-4 py-3 border-t border-gray-100 w-full" }, Ke = ["disabled"], Ze = ["disabled"], C = "-", bt = /* @__PURE__ */ J({
277
+ __name: "MetaDataTab",
278
+ props: {
279
+ data: {},
280
+ entityId: {},
281
+ entityType: {}
282
+ },
283
+ emits: ["saved"],
284
+ setup(l, { emit: h }) {
285
+ const u = W(() => import("@opengis/core").then((t) => t.VsModal)), B = W(() => import("@opengis/form")), f = l, H = h, p = b(null);
286
+ async function M(t) {
287
+ var a;
288
+ try {
289
+ const n = await fetch("/api/suggest/gis.group_list");
290
+ if (!n.ok) return null;
291
+ const V = (a = (await n.json()).data) == null ? void 0 : a.find((N) => String(N.id) === String(t));
292
+ return (V == null ? void 0 : V.text) ?? null;
293
+ } catch {
294
+ return null;
295
+ }
296
+ }
297
+ ve(
298
+ () => f.data,
299
+ async (t) => {
300
+ if (p.value = null, (t == null ? void 0 : t.group_id) != null) {
301
+ const a = await M(String(t.group_id));
302
+ p.value = a;
303
+ }
304
+ },
305
+ { immediate: !0 }
306
+ );
307
+ function L(t) {
308
+ if (!t || typeof t != "string") return C;
309
+ try {
310
+ const a = new Date(t);
311
+ return Number.isNaN(a.getTime()) ? C : a.toLocaleDateString("uk-UA", {
312
+ day: "numeric",
313
+ month: "long",
314
+ year: "numeric"
315
+ });
316
+ } catch {
317
+ return C;
318
+ }
319
+ }
320
+ function e(t) {
321
+ return typeof (t == null ? void 0 : t.is_active) == "boolean" ? t.is_active ? "Активний" : "Неактивний" : typeof (t == null ? void 0 : t.enabled) == "boolean" ? t.enabled ? "Активний" : "Неактивний" : C;
322
+ }
323
+ function _(t) {
324
+ return typeof (t == null ? void 0 : t.is_public) != "boolean" ? C : t.is_public ? "Публічний" : "Приватний";
325
+ }
326
+ function I(t) {
327
+ if (t == null) return "";
328
+ if (Array.isArray(t)) return t.filter(Boolean).join(", ");
329
+ if (typeof t == "boolean") return t ? "Так" : "Ні";
330
+ if (typeof t == "object") return "";
331
+ const a = String(t).trim();
332
+ return a === "" ? "" : a;
333
+ }
334
+ function A(t, a) {
335
+ return a.map((n) => ({ label: n.label, value: n.value(t) })).filter((n) => n.value && n.value !== C);
336
+ }
337
+ const F = y(() => A(f.data, d().general)), T = y(() => {
338
+ var a;
339
+ const t = (a = f.data) == null ? void 0 : a.description;
340
+ return t != null && t !== "" ? t : C;
341
+ }), S = y(() => A(f.data, d().meta)), w = b(!1), $ = b({}), k = b(null), x = b(!1);
342
+ function d() {
343
+ const t = Ae({
344
+ resolvedGroupName: p.value,
345
+ normalizeValue: I,
346
+ statusLabel: e,
347
+ visibilityLabel: _,
348
+ formatDate: L
349
+ });
350
+ return t[f.entityType || "service"] || t.service;
351
+ }
352
+ const U = y(() => d().edit);
353
+ function O() {
354
+ const t = f.data, a = {};
355
+ for (const n of d().edit)
356
+ switch (n.name) {
357
+ case "group_id":
358
+ a.group_id = (t == null ? void 0 : t.group_id) != null ? String(t.group_id) : "";
359
+ break;
360
+ case "producer":
361
+ a.producer = (t == null ? void 0 : t.holder) ?? (t == null ? void 0 : t.producer) ?? "";
362
+ break;
363
+ case "keywords":
364
+ a.keywords = Array.isArray(t == null ? void 0 : t.keywords) ? [...t.keywords] : [];
365
+ break;
366
+ case "is_public":
367
+ a.is_public = (t == null ? void 0 : t.is_public) ?? !1;
368
+ break;
369
+ case "is_active":
370
+ a.is_active = typeof (t == null ? void 0 : t.is_active) == "boolean" ? t.is_active : (t == null ? void 0 : t.enabled) ?? !1;
371
+ break;
372
+ case "enabled":
373
+ a.enabled = (t == null ? void 0 : t.enabled) ?? (t == null ? void 0 : t.is_active) ?? !1;
374
+ break;
375
+ case "info":
376
+ a.info = (t == null ? void 0 : t.info) ?? !1;
377
+ break;
378
+ case "is_static":
379
+ a.is_static = (t == null ? void 0 : t.is_static) ?? !1;
380
+ break;
381
+ case "card_auto":
382
+ a.card_auto = (t == null ? void 0 : t.card_auto) ?? !1;
383
+ break;
384
+ default:
385
+ a[n.name] = (t == null ? void 0 : t[n.name]) ?? "";
386
+ break;
387
+ }
388
+ $.value = a, k.value = null, w.value = !0;
389
+ }
390
+ async function Y() {
391
+ var t, a;
392
+ if (!(!f.entityId || !f.entityType)) {
393
+ if (k.value) {
394
+ const n = (a = (t = k.value).validate) == null ? void 0 : a.call(t);
395
+ if (n) {
396
+ D({
397
+ type: "warning",
398
+ title: "Валідація",
399
+ message: Object.entries(n).map(([R, V]) => `${R}: ${V}`).join(`
400
+ `)
401
+ });
402
+ return;
403
+ }
404
+ }
405
+ x.value = !0;
406
+ try {
407
+ const n = new Set(U.value.map((G) => G.name)), R = Object.fromEntries(
408
+ Object.entries($.value).filter(([G]) => n.has(G))
409
+ ), V = f.entityType === "css" ? {
410
+ url: `/api/gis-css/${encodeURIComponent(f.entityId)}`,
411
+ method: "POST"
412
+ } : {
413
+ url: `/api/gis-metadata/${encodeURIComponent(f.entityType)}/${encodeURIComponent(f.entityId)}`,
414
+ method: "POST"
415
+ }, N = await fetch(V.url, {
416
+ method: V.method,
417
+ headers: { "Content-Type": "application/json" },
418
+ body: JSON.stringify(R)
419
+ });
420
+ if (!N.ok) throw new Error(`Failed to save metadata: ${N.status}`);
421
+ D({ type: "success", title: "Збережено", message: "Метадані оновлено" }), w.value = !1, H("saved");
422
+ } catch (n) {
423
+ console.error("Failed to save metadata", n), D({ type: "error", title: "Помилка", message: "Не вдалося зберегти метадані" });
424
+ } finally {
425
+ x.value = !1;
426
+ }
427
+ }
428
+ }
429
+ return (t, a) => (m(), v("div", Fe, [
430
+ r("div", Re, [
431
+ r("div", Be, [
432
+ r("div", { class: "flex items-center justify-between mb-3" }, [
433
+ a[5] || (a[5] = r("h2", { class: "text-xs font-semibold text-gray-500 uppercase tracking-wider" }, " Загальна інформація ", -1)),
434
+ r("button", {
435
+ type: "button",
436
+ onClick: O,
437
+ class: "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-medium transition-colors bg-sky-50 text-sky-600 hover:bg-sky-100"
438
+ }, [...a[4] || (a[4] = [
439
+ r("svg", {
440
+ xmlns: "http://www.w3.org/2000/svg",
441
+ class: "h-3.5 w-3.5",
442
+ fill: "none",
443
+ viewBox: "0 0 24 24",
444
+ stroke: "currentColor",
445
+ "stroke-width": "2"
446
+ }, [
447
+ r("path", {
448
+ "stroke-linecap": "round",
449
+ "stroke-linejoin": "round",
450
+ d: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
451
+ })
452
+ ], -1),
453
+ _e(" Редагувати ", -1)
454
+ ])])
455
+ ]),
456
+ F.value.length ? (m(), v("div", Ne, [
457
+ (m(!0), v(ae, null, ue(F.value, (n) => (m(), v("div", {
458
+ key: n.label,
459
+ class: "bg-gray-50 rounded-md p-2 border border-gray-100"
460
+ }, [
461
+ r("p", De, z(n.label), 1),
462
+ r("p", He, z(n.value), 1)
463
+ ]))), 128))
464
+ ])) : (m(), v("p", Oe, z(C)))
465
+ ]),
466
+ r("div", Ge, [
467
+ a[6] || (a[6] = r("h2", { class: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3" }, " Повний опис ", -1)),
468
+ r("p", Pe, z(T.value), 1)
469
+ ]),
470
+ r("div", Qe, [
471
+ a[7] || (a[7] = r("h2", { class: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3" }, " Метадані ", -1)),
472
+ S.value.length ? (m(), v("div", qe, [
473
+ (m(!0), v(ae, null, ue(S.value, (n) => (m(), v("div", {
474
+ key: n.label,
475
+ class: "bg-gray-50 rounded-md p-2 border border-gray-100"
476
+ }, [
477
+ r("p", We, z(n.label), 1),
478
+ r("p", Xe, z(n.value), 1)
479
+ ]))), 128))
480
+ ])) : (m(), v("p", Je, z(C)))
481
+ ])
482
+ ]),
483
+ j(E(u), {
484
+ teleport: "#modal",
485
+ visible: w.value,
486
+ "onUpdate:visible": a[3] || (a[3] = (n) => w.value = n),
487
+ title: "Редагування метаданих",
488
+ size: "lg"
489
+ }, {
490
+ footer: X(() => [
491
+ r("div", Ye, [
492
+ r("button", {
493
+ type: "button",
494
+ class: "px-4 py-2 rounded bg-gray-100 text-gray-700 text-sm",
495
+ disabled: x.value,
496
+ onClick: a[2] || (a[2] = (n) => w.value = !1)
497
+ }, " Скасувати ", 8, Ke),
498
+ r("button", {
499
+ type: "button",
500
+ class: "px-4 py-2 rounded bg-blue-600 text-white text-sm",
501
+ disabled: x.value,
502
+ onClick: Y
503
+ }, z(x.value ? "Збереження…" : "Зберегти"), 9, Ze)
504
+ ])
505
+ ]),
506
+ default: X(() => [
507
+ j(E(B), {
508
+ values: $.value,
509
+ "onUpdate:values": a[0] || (a[0] = (n) => $.value = n),
510
+ form: k.value,
511
+ "onUpdate:form": a[1] || (a[1] = (n) => k.value = n),
512
+ schema: U.value
513
+ }, null, 8, ["values", "form", "schema"])
514
+ ]),
515
+ _: 1
516
+ }, 8, ["visible"])
517
+ ]));
518
+ }
519
+ }), et = ["href"], tt = ["href"], lt = {
520
+ key: 0,
521
+ class: "py-6 px-4 text-sm text-gray-500"
522
+ }, at = {
523
+ key: 1,
524
+ class: "py-6 px-4 text-sm text-red-600"
525
+ }, nt = { class: "flex justify-end gap-2 px-4 py-3 border-t border-gray-100 w-full" }, ot = ["disabled"], rt = ["disabled"], st = 192, me = 8, P = 8, ft = /* @__PURE__ */ J({
526
+ __name: "HeaderActions",
527
+ props: {
528
+ entityId: {},
529
+ entityInfo: {},
530
+ table: {},
531
+ formEndpoint: {},
532
+ saveEndpoint: {},
533
+ entityLabel: {},
534
+ editButtonText: {},
535
+ saveMethod: {},
536
+ showXmlItem: { type: Boolean, default: !0 },
537
+ clearTilesHandler: {}
538
+ },
539
+ emits: ["saved"],
540
+ setup(l, { emit: h }) {
541
+ const u = l, B = h, f = W(() => import("@opengis/core").then((o) => o.VsModal)), H = W(() => import("@opengis/form")), p = b(!1), M = b(null), L = b(null), e = b(null), _ = b(null), I = y(() => _.value ? {
542
+ position: "fixed",
543
+ top: `${_.value.top}px`,
544
+ left: `${_.value.left}px`
545
+ } : {});
546
+ ve(p, (o) => {
547
+ o && we(K);
548
+ });
549
+ const A = b(!1), F = b(null), T = b({}), S = b(null), w = b(""), $ = b(!1), k = b(!1), x = b(null), d = y(() => u.entityId || ""), U = (o, s) => o ? typeof o == "function" ? o(s) : typeof o != "string" ? "" : o.includes(":id") ? s ? o.replace(":id", encodeURIComponent(s)) : "" : o : "", O = y(() => {
550
+ var o;
551
+ return (o = u.table) == null ? void 0 : o.trim();
552
+ }), Y = y(() => {
553
+ if (u.formEndpoint) return u.formEndpoint;
554
+ if (O.value)
555
+ return (o) => `/api/form/${O.value}/${o}`;
556
+ }), t = y(() => {
557
+ if (u.saveEndpoint) return u.saveEndpoint;
558
+ if (O.value)
559
+ return (o) => `/api/table/${o}`;
560
+ }), a = y(() => U(Y.value, d.value)), n = y(() => u.saveEndpoint ? U(u.saveEndpoint, d.value) : x.value ? `/api/table/${encodeURIComponent(x.value)}` : U(t.value, d.value)), R = y(() => U("/api/gis-clear-rtile/:id", d.value)), V = y(() => U("/api/gis-xml/:id", d.value)), N = y(() => {
561
+ var c, g, i;
562
+ const o = (g = (c = u.entityInfo) == null ? void 0 : c.name) == null ? void 0 : g.trim();
563
+ if (o) return `Редагування ${o}`;
564
+ const s = (i = u.entityLabel) == null ? void 0 : i.trim();
565
+ return s ? `Редагування ${s}` : "Редагування";
566
+ }), G = y(() => u.editButtonText || "Редагувати"), pe = y(() => (u.saveMethod || "POST").toUpperCase());
567
+ function be() {
568
+ p.value || K(), p.value = !p.value;
569
+ }
570
+ function Q() {
571
+ p.value = !1;
572
+ }
573
+ async function fe() {
574
+ const o = u.clearTilesHandler;
575
+ !o || !d.value || (Q(), await o(d.value));
576
+ }
577
+ function K() {
578
+ var ie;
579
+ if (typeof window > "u" || !L.value) return;
580
+ const o = L.value.getBoundingClientRect(), s = window.innerWidth, c = window.innerHeight, g = o.left, i = Math.max(s - st - P, P), Z = Math.min(Math.max(g, P), i), ee = ((ie = e.value) == null ? void 0 : ie.offsetHeight) ?? 0, re = o.bottom + me;
581
+ let se = re;
582
+ if (ee && re + ee > c - P) {
583
+ const de = o.top - me - ee;
584
+ se = Math.max(de, P);
585
+ }
586
+ _.value = { top: se, left: Z };
587
+ }
588
+ function ne(o) {
589
+ var c, g;
590
+ if (!M.value && !e.value) return;
591
+ const s = o.target;
592
+ s && ((c = M.value) != null && c.contains(s) || (g = e.value) != null && g.contains(s)) || (p.value = !1);
593
+ }
594
+ function q() {
595
+ p.value && K();
596
+ }
597
+ ke(() => {
598
+ window.addEventListener("click", ne), window.addEventListener("resize", q), window.addEventListener("scroll", q, !0);
599
+ }), xe(() => {
600
+ window.removeEventListener("click", ne), window.removeEventListener("resize", q), window.removeEventListener("scroll", q, !0);
601
+ });
602
+ async function ye() {
603
+ var o, s, c;
604
+ if (!(!d.value || !a.value)) {
605
+ Q(), A.value = !0, $.value = !0, w.value = "", F.value = null, T.value = {}, x.value = null;
606
+ try {
607
+ const g = await fetch(a.value);
608
+ if (!g.ok)
609
+ throw new Error(`Failed to load form: ${g.status}`);
610
+ const i = await g.json();
611
+ T.value = (i == null ? void 0 : i.data) || {}, F.value = (i == null ? void 0 : i.schema) || null;
612
+ const Z = typeof (i == null ? void 0 : i.token) == "string" && i.token || typeof ((o = i == null ? void 0 : i.tokens) == null ? void 0 : o.edit) == "string" && i.tokens.edit || typeof ((s = i == null ? void 0 : i.tokens) == null ? void 0 : s.edit_token) == "string" && i.tokens.edit_token || typeof ((c = i == null ? void 0 : i.data) == null ? void 0 : c.token) == "string" && i.data.token || null;
613
+ x.value = Z, S.value = null;
614
+ } catch (g) {
615
+ console.error("Failed to load edit form", g), w.value = "Не вдалося завантажити форму редагування";
616
+ } finally {
617
+ $.value = !1;
618
+ }
619
+ }
620
+ }
621
+ function oe() {
622
+ A.value = !1, F.value = null, w.value = "", x.value = null;
623
+ }
624
+ async function ge() {
625
+ var o, s;
626
+ if (!(!d.value || !n.value)) {
627
+ if (S.value) {
628
+ const c = (s = (o = S.value).validate) == null ? void 0 : s.call(o);
629
+ if (c) {
630
+ D({
631
+ type: "warning",
632
+ title: "Validation",
633
+ message: Object.entries(c).map(([g, i]) => `${g}: ${i}`).join(`
634
+ `)
635
+ });
636
+ return;
637
+ }
638
+ }
639
+ k.value = !0;
640
+ try {
641
+ const c = await fetch(n.value, {
642
+ method: pe.value,
643
+ headers: { "Content-Type": "application/json" },
644
+ body: JSON.stringify(T.value)
645
+ });
646
+ if (!c.ok) throw new Error(`Failed to save: ${c.status}`);
647
+ D({
648
+ type: "success",
649
+ title: "Збережено",
650
+ message: "Зміни збережено"
651
+ }), B("saved", T.value), oe();
652
+ } catch (c) {
653
+ console.error("Failed to save edit form", c), D({
654
+ type: "error",
655
+ title: "Помилка",
656
+ message: "Не вдалося зберегти зміни"
657
+ });
658
+ } finally {
659
+ k.value = !1;
660
+ }
661
+ }
662
+ }
663
+ return (o, s) => (m(), v("div", {
664
+ ref_key: "root",
665
+ ref: M,
666
+ class: "relative flex items-center"
667
+ }, [
668
+ r("button", {
669
+ ref_key: "triggerButton",
670
+ ref: L,
671
+ type: "button",
672
+ onClick: ze(be, ["stop"]),
673
+ class: "flex items-center justify-center w-9 h-9 hover:rounded-md hover:border hover:border-gray-200 bg-white text-gray-600 hover:bg-gray-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-500",
674
+ "aria-label": "Дії"
675
+ }, [...s[3] || (s[3] = [
676
+ r("svg", {
677
+ xmlns: "http://www.w3.org/2000/svg",
678
+ class: "h-5 w-5",
679
+ fill: "none",
680
+ viewBox: "0 0 24 24",
681
+ stroke: "currentColor"
682
+ }, [
683
+ r("path", {
684
+ "stroke-linecap": "round",
685
+ "stroke-linejoin": "round",
686
+ "stroke-width": "2",
687
+ d: "M12 5.5v.01M12 12v.01M12 18.5v.01"
688
+ })
689
+ ], -1)
690
+ ])], 512),
691
+ (m(), le(Ve, { to: "body" }, [
692
+ p.value ? (m(), v("div", {
693
+ key: 0,
694
+ ref_key: "menuContainer",
695
+ ref: e,
696
+ style: Ce(I.value),
697
+ class: "absolute top-0 left-0 mt-2 w-48 rounded-xl border border-gray-200 bg-white shadow-lg text-sm z-[1000]"
698
+ }, [
699
+ R.value || l.clearTilesHandler ? (m(), v(ae, { key: 0 }, [
700
+ l.clearTilesHandler ? (m(), v("button", {
701
+ key: 0,
702
+ type: "button",
703
+ class: "flex items-center gap-2 w-full px-4 py-2 text-left text-gray-700 hover:bg-slate-50 hover:rounded-t-xl",
704
+ onClick: fe
705
+ }, [
706
+ j(E(ce), {
707
+ size: 16,
708
+ class: "lucide lucide-brush-cleaning text-gray-500"
709
+ }),
710
+ s[4] || (s[4] = r("span", null, "Очистити тайли", -1))
711
+ ])) : (m(), v("a", {
712
+ key: 1,
713
+ href: R.value,
714
+ target: "_blank",
715
+ rel: "noreferrer",
716
+ class: "flex items-center gap-2 px-4 py-2 text-left text-gray-700 hover:bg-slate-50 hover:rounded-t-xl",
717
+ onClick: Q
718
+ }, [
719
+ j(E(ce), {
720
+ size: 16,
721
+ class: "lucide lucide-brush-cleaning text-gray-500"
722
+ }),
723
+ s[5] || (s[5] = r("span", null, "Очистити тайли", -1))
724
+ ], 8, et))
725
+ ], 64)) : te("", !0),
726
+ l.showXmlItem ? (m(), v("a", {
727
+ key: 1,
728
+ href: V.value,
729
+ target: "_blank",
730
+ rel: "noreferrer",
731
+ class: "flex items-center gap-2 px-4 py-2 text-left text-gray-700 hover:bg-slate-50 hover:rounded-t-xl",
732
+ onClick: Q
733
+ }, [
734
+ j(E(Le), {
735
+ size: 16,
736
+ class: "lucide lucide-square-code text-gray-500"
737
+ }),
738
+ s[6] || (s[6] = r("span", null, "Створити XML", -1))
739
+ ], 8, tt)) : te("", !0),
740
+ r("button", {
741
+ type: "button",
742
+ class: "flex items-center gap-2 w-full px-4 py-2 text-left text-gray-700 hover:bg-slate-50 hover:rounded-b-xl",
743
+ onClick: ye
744
+ }, [
745
+ j(E(Te), {
746
+ size: 16,
747
+ class: "lucide lucide-pencil text-gray-500"
748
+ }),
749
+ r("span", null, z(G.value), 1)
750
+ ])
751
+ ], 4)) : te("", !0)
752
+ ])),
753
+ j(E(f), {
754
+ teleport: "#modal",
755
+ visible: A.value,
756
+ "onUpdate:visible": s[2] || (s[2] = (c) => A.value = c),
757
+ title: N.value,
758
+ size: "lg"
759
+ }, {
760
+ footer: X(() => [
761
+ r("div", nt, [
762
+ r("button", {
763
+ type: "button",
764
+ class: "px-4 py-2 rounded bg-gray-100 text-gray-700",
765
+ onClick: oe,
766
+ disabled: k.value
767
+ }, " Скасувати ", 8, ot),
768
+ r("button", {
769
+ type: "button",
770
+ class: "px-4 py-2 rounded bg-blue-600 text-white",
771
+ onClick: ge,
772
+ disabled: k.value
773
+ }, z(k.value ? "Зберігається…" : "Зберегти"), 9, rt)
774
+ ])
775
+ ]),
776
+ default: X(() => [
777
+ $.value ? (m(), v("div", lt, " Завантаження форми редагування… ")) : w.value ? (m(), v("div", at, z(w.value), 1)) : (m(), le(E(H), {
778
+ key: 2,
779
+ values: T.value,
780
+ "onUpdate:values": s[0] || (s[0] = (c) => T.value = c),
781
+ form: S.value,
782
+ "onUpdate:form": s[1] || (s[1] = (c) => S.value = c),
783
+ schema: F.value
784
+ }, null, 8, ["values", "form", "schema"]))
785
+ ]),
786
+ _: 1
787
+ }, 8, ["visible", "title"])
788
+ ], 512));
789
+ }
790
+ });
791
+ export {
792
+ ft as _,
793
+ vt as a,
794
+ bt as b,
795
+ pt as c
796
+ };