@webx-ui/module-pages 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1603 @@
1
+ import { inject as je, provide as Ge, defineComponent as H, ref as P, computed as V, openBlock as d, createBlock as x, unref as e, withCtx as n, createElementVNode as N, createElementBlock as M, createVNode as f, createTextVNode as h, toDisplayString as g, createCommentVNode as D, useTemplateRef as Pe, watch as ae, onMounted as ye, onBeforeUnmount as Je, Fragment as F, renderList as ie, normalizeClass as Qe, useModel as Xe, mergeModels as Ye, withModifiers as xe, nextTick as Ze, isRef as Re, withKeys as De } from "vue";
2
+ import { useRouter as Ce, useRoute as qe, onBeforeRouteLeave as et } from "vue-router";
3
+ import { useAdmin as X, useTranslate as j, WxScreen as tt } from "@webx-ui/module-admin";
4
+ import { WxCard as Oe, WxText as O, WxButton as R, confirm as le, toast as z, useLocales as Ue, useElementWidth as Ie, localizedValue as at, WxSkeleton as ke, WxBreadcrumb as lt, WxBreadcrumbItem as we, WxBadge as We, WxDropdown as Le, WxDropdownItem as re, WxAction as $e, WxAlert as Ve, WxEmpty as nt, WxTreeSelect as st, WxFormItem as ue, WxActions as ot, useModal as Fe, WxDialog as Ke, WxInput as Me, WxSpace as Te, createModal as Ae, WxHeading as it, WxTable as rt, WxSegmented as ut } from "@webx-ui/core";
5
+ import { provideBlocksPreview as dt } from "@webx-ui/module-blocks";
6
+ function Z(v) {
7
+ const u = `${v.apiPath}/pages`, p = (l) => l.data;
8
+ return {
9
+ list: (l = {}) => {
10
+ const i = new URLSearchParams();
11
+ l.parent != null && i.set("parent", String(l.parent)), l.search && i.set("search", l.search), l.status && i.set("status", l.status), l.trashed && i.set("trashed", "1"), l.flat && i.set("flat", "1");
12
+ const t = i.size > 0 ? `?${i}` : "";
13
+ return v.http.get(`${u}${t}`).then(p);
14
+ },
15
+ get: (l) => v.http.get(`${u}/${l}`).then(p),
16
+ create: (l) => v.http.post(u, l).then(p),
17
+ save: (l, i) => v.http.put(`${u}/${l}`, i).then(p),
18
+ move: (l, i, t) => v.http.post(`${u}/${l}/move`, { target: i, zone: t }).then(p),
19
+ duplicate: (l) => v.http.post(`${u}/${l}/duplicate`, {}).then(p),
20
+ publish: (l) => v.http.post(`${u}/${l}/publish`, {}).then(p),
21
+ unpublish: (l) => v.http.post(`${u}/${l}/unpublish`, {}).then(p),
22
+ remove: (l) => v.http.delete(`${u}/${l}`).then((i) => i.data.trashed),
23
+ restore: (l) => v.http.post(`${u}/${l}/restore`, {}).then((i) => i.data.restored),
24
+ versions: (l) => v.http.get(`${u}/${l}/versions`).then(p),
25
+ restoreVersion: (l, i) => v.http.post(`${u}/${l}/versions/${i}/restore`, {}).then(p)
26
+ };
27
+ }
28
+ const He = /* @__PURE__ */ Symbol("wx-page-editor");
29
+ function ct(v) {
30
+ Ge(He, v);
31
+ }
32
+ function ze() {
33
+ return je(He, null);
34
+ }
35
+ const pt = {
36
+ module: {
37
+ title: "Pages"
38
+ },
39
+ pages: {
40
+ home: "Home"
41
+ },
42
+ page: {
43
+ new: "New page",
44
+ search: "Search by title or address",
45
+ empty: "No pages yet.",
46
+ "empty-help": "A site is its pages. The first one goes inside the home page.",
47
+ "empty-search": "Nothing matches that.",
48
+ "empty-bin": "The bin is empty.",
49
+ "column-title": "Title",
50
+ "column-address": "Address",
51
+ "column-status": "Status",
52
+ "column-updated": "Updated",
53
+ "column-deleted": "Deleted",
54
+ "status-draft": "Draft",
55
+ "status-published": "Published",
56
+ "status-modified": "Edited",
57
+ "no-address": "No address in this language",
58
+ "filter-all": "All",
59
+ "filter-draft": "Drafts",
60
+ "filter-published": "Published",
61
+ "filter-modified": "Edited",
62
+ bin: "Bin",
63
+ open: "Open",
64
+ "add-child": "Add a page inside",
65
+ duplicate: "Duplicate",
66
+ move: "Move…",
67
+ "copy-address": "Copy the address",
68
+ "open-on-site": "Open on the site",
69
+ delete: "Delete",
70
+ restore: "Restore",
71
+ cancel: "Cancel",
72
+ "new-title": "New page",
73
+ "field-title": "Title",
74
+ "field-slug": "Address",
75
+ "slug-help": "The last part of the address. Left empty, it is made from the title.",
76
+ "field-parent": "Inside",
77
+ create: "Create and open",
78
+ "move-title": "Move “:title”",
79
+ "move-help": "Pick the page it goes inside. Everything under it moves too, and their addresses change with it.",
80
+ "move-confirm": "Move",
81
+ moved: "Moved. :count addresses changed; the old ones now redirect to the new ones.",
82
+ "moved-one": "Moved. The address changed; the old one now redirects to it.",
83
+ "delete-title": "Delete “:title”?",
84
+ "delete-text": "The page goes to the bin and stops answering on the site.",
85
+ "delete-branch": "The :count pages inside it go with it.",
86
+ deleted: "The page is in the bin.",
87
+ restored: "The page is back.",
88
+ "copy-of": ":title (copy)",
89
+ duplicated: "The copy is ready, and it is not on the site.",
90
+ "address-copied": "The address is on the clipboard.",
91
+ // The editor.
92
+ trail: "Where this page sits",
93
+ untitled: "Untitled",
94
+ "state-saved": "Saved",
95
+ "state-saving": "Saving…",
96
+ "state-unsaved": "Not saved yet",
97
+ save: "Save",
98
+ "save-failed": "The page was not saved.",
99
+ publish: "Publish",
100
+ published: "The page is on the site.",
101
+ preview: "Preview",
102
+ more: "More",
103
+ address: "Address",
104
+ "parent-help": "The page it sits inside. A move happens at once, not on publication.",
105
+ "parent-warning": "Everything inside this page moves with it. The old addresses keep working and lead to the new ones.",
106
+ danger: "Off the site",
107
+ unpublish: "Unpublish",
108
+ "unpublish-title": "Take “:title” off the site?",
109
+ "unpublish-text": "The page stops answering. Nothing written is lost, and publishing puts it back.",
110
+ "unpublish-help": "The page stops answering on the site. What is written stays.",
111
+ unpublished: "The page is off the site.",
112
+ "delete-help": "The page goes to the bin, with everything inside it.",
113
+ "delete-home": "The home page cannot be deleted.",
114
+ "conflict-title": "The page changed while you were editing",
115
+ "conflict-theirs": "Take the newer version",
116
+ "conflict-theirs-title": "Give up what you wrote?",
117
+ "conflict-theirs-text": "The page is read again as it now is, and what you have typed since goes.",
118
+ "conflict-mine": "Keep mine",
119
+ "leave-title": "Leave without saving?",
120
+ "leave-text": "The page could not be saved, and what you wrote is not on the server.",
121
+ leave: "Leave",
122
+ "history-empty": "This page has never been published.",
123
+ version: "#:number",
124
+ "version-live": "On the site",
125
+ "source-panel": "From the panel",
126
+ "source-mcp": "By an agent",
127
+ "source-import": "Imported",
128
+ "restore-title": "Restore version :number?",
129
+ "restore-text": "It becomes the draft. The site keeps showing what is published until you publish this.",
130
+ "restored-version": "Version :number is now the draft."
131
+ }
132
+ }, Be = /* @__PURE__ */ new WeakSet();
133
+ function G() {
134
+ try {
135
+ const { i18n: v } = X();
136
+ Be.has(v) || (v.defaults("webx-pages", pt), Be.add(v));
137
+ } catch {
138
+ }
139
+ }
140
+ const gt = { class: "wx-page-danger" }, vt = {
141
+ key: 0,
142
+ class: "wx-page-danger__row"
143
+ }, ft = { class: "wx-page-danger__what" }, ht = { class: "wx-page-danger__row" }, mt = { class: "wx-page-danger__what" }, yt = /* @__PURE__ */ H({
144
+ name: "WxPageDanger",
145
+ __name: "PageDanger",
146
+ setup(v) {
147
+ const u = X(), p = Z(u), l = Ce(), i = ze();
148
+ G();
149
+ const t = j("webx-pages"), c = P(!1), a = V(() => i?.page.value ?? null), o = V(() => u.can("pages.manage"));
150
+ async function s() {
151
+ const $ = a.value;
152
+ if (!(!$ || !await le({
153
+ title: t("page.unpublish-title", { title: $.title }),
154
+ message: t("page.unpublish-text"),
155
+ confirmText: t("page.unpublish"),
156
+ cancelText: t("page.cancel"),
157
+ tone: "danger"
158
+ }))) {
159
+ c.value = !0;
160
+ try {
161
+ await p.unpublish($.id), await i?.reload(), z.success(t("page.unpublished"));
162
+ } catch (y) {
163
+ z.danger(k(y));
164
+ } finally {
165
+ c.value = !1;
166
+ }
167
+ }
168
+ }
169
+ async function C() {
170
+ const $ = a.value;
171
+ if (!(!$ || !await le({
172
+ title: t("page.delete-title", { title: $.title }),
173
+ // The whole branch, not the level under it (§7): a catalogue with two sections and forty
174
+ // products is forty-two pages leaving the site at once.
175
+ message: $.descendants_count > 0 ? `${t("page.delete-text")} ${t("page.delete-branch", { count: $.descendants_count })}` : t("page.delete-text"),
176
+ confirmText: t("page.delete"),
177
+ cancelText: t("page.cancel"),
178
+ tone: "danger"
179
+ }))) {
180
+ c.value = !0;
181
+ try {
182
+ await p.remove($.id), z.success(t("page.deleted")), l.push(i?.base ?? "/pages");
183
+ } catch (y) {
184
+ z.danger(k(y));
185
+ } finally {
186
+ c.value = !1;
187
+ }
188
+ }
189
+ }
190
+ function k($) {
191
+ return $.body?.message ?? String($);
192
+ }
193
+ return ($, T) => a.value && o.value ? (d(), x(e(Oe), {
194
+ key: 0,
195
+ title: e(t)("page.danger")
196
+ }, {
197
+ default: n(() => [
198
+ N("div", gt, [
199
+ a.value.status !== "draft" ? (d(), M("div", vt, [
200
+ N("div", ft, [
201
+ f(e(O), { weight: "medium" }, {
202
+ default: n(() => [
203
+ h(g(e(t)("page.unpublish")), 1)
204
+ ]),
205
+ _: 1
206
+ }),
207
+ f(e(O), {
208
+ size: "sm",
209
+ tone: "muted"
210
+ }, {
211
+ default: n(() => [
212
+ h(g(e(t)("page.unpublish-help")), 1)
213
+ ]),
214
+ _: 1
215
+ })
216
+ ]),
217
+ f(e(R), {
218
+ variant: "outline",
219
+ loading: c.value,
220
+ onClick: s
221
+ }, {
222
+ default: n(() => [
223
+ h(g(e(t)("page.unpublish")), 1)
224
+ ]),
225
+ _: 1
226
+ }, 8, ["loading"])
227
+ ])) : D("", !0),
228
+ N("div", ht, [
229
+ N("div", mt, [
230
+ f(e(O), { weight: "medium" }, {
231
+ default: n(() => [
232
+ h(g(e(t)("page.delete")), 1)
233
+ ]),
234
+ _: 1
235
+ }),
236
+ f(e(O), {
237
+ size: "sm",
238
+ tone: "muted"
239
+ }, {
240
+ default: n(() => [
241
+ h(g(a.value.can.delete ? e(t)("page.delete-help") : e(t)("page.delete-home")), 1)
242
+ ]),
243
+ _: 1
244
+ })
245
+ ]),
246
+ f(e(R), {
247
+ type: "danger",
248
+ variant: "outline",
249
+ disabled: !a.value.can.delete,
250
+ loading: c.value,
251
+ onClick: C
252
+ }, {
253
+ default: n(() => [
254
+ h(g(e(t)("page.delete")), 1)
255
+ ]),
256
+ _: 1
257
+ }, 8, ["disabled", "loading"])
258
+ ])
259
+ ])
260
+ ]),
261
+ _: 1
262
+ }, 8, ["title"])) : D("", !0);
263
+ }
264
+ }), de = (v, u) => {
265
+ const p = v.__vccOpts || v;
266
+ for (const [l, i] of u)
267
+ p[l] = i;
268
+ return p;
269
+ }, bt = /* @__PURE__ */ de(yt, [["__scopeId", "data-v-94c0abe4"]]), _t = { class: "wx-page-editor__head" }, wt = { class: "wx-page-editor__id" }, xt = { class: "wx-page-editor__name" }, kt = { class: "wx-page-editor__title" }, $t = { class: "wx-page-editor__actions" }, Tt = { class: "wx-page-editor__screen" }, Pt = 1200, Ct = 720, Wt = /* @__PURE__ */ H({
270
+ __name: "PageEditorPage",
271
+ props: {
272
+ base: { default: "/pages" }
273
+ },
274
+ setup(v) {
275
+ const u = v, p = X(), l = Z(p), i = qe(), t = Ce(), c = Ue();
276
+ G();
277
+ const a = j("webx-pages"), o = V(() => Number(i.params.id)), s = P(null), C = P([]), k = P({}), $ = P(""), T = P(null), y = P({}), S = P(!0), W = P(!1), _ = P(!1), A = P({}), U = P(null), q = P(""), ce = P(0), I = V(() => p.can("pages.manage")), pe = Pe("root"), ge = Ie(pe), L = V(() => ge.value > 0 && ge.value < Ct), ee = V(() => JSON.stringify(k.value)), B = V(() => q.value !== "" && ee.value !== q.value), ne = V(() => W.value ? "saving" : B.value ? "unsaved" : "saved"), se = V(() => {
278
+ const m = k.value.title;
279
+ return at(m, c.active.value, s.value?.title ?? "");
280
+ }), ve = V(
281
+ () => C.value.map((m) => ({
282
+ id: m.id,
283
+ label: m.is_home ? a("pages.home") : m.title
284
+ }))
285
+ );
286
+ dt({ url: V(() => T.value), reload: ce }), ct({
287
+ page: s,
288
+ ancestors: C,
289
+ values: k,
290
+ prefixes: y,
291
+ base: u.base,
292
+ canManage: I.value,
293
+ reload: () => J(!0),
294
+ save: () => K()
295
+ });
296
+ function be(m) {
297
+ s.value = m.page, C.value = m.ancestors, k.value = m.values, $.value = m.revision, T.value = m.preview_url, y.value = m.address_prefix, q.value = JSON.stringify(m.values), U.value = null;
298
+ }
299
+ async function J(m = !1) {
300
+ m || (S.value = !0);
301
+ try {
302
+ be(await l.get(o.value));
303
+ } catch (te) {
304
+ z.danger(r(te)), t.push(u.base);
305
+ } finally {
306
+ S.value = !1;
307
+ }
308
+ }
309
+ let Q;
310
+ function fe() {
311
+ !I.value || U.value || !B.value || (clearTimeout(Q), Q = setTimeout(() => {
312
+ K();
313
+ }, Pt));
314
+ }
315
+ function he() {
316
+ !I.value || U.value || !B.value || W.value || (clearTimeout(Q), K());
317
+ }
318
+ async function K() {
319
+ if (!s.value || W.value || !I.value) return;
320
+ clearTimeout(Q);
321
+ const m = ee.value, te = k.value;
322
+ W.value = !0, A.value = {};
323
+ try {
324
+ const E = await l.save(s.value.id, { values: te, revision: $.value });
325
+ s.value = E.page, C.value = E.ancestors, $.value = E.revision, T.value = E.preview_url, y.value = E.address_prefix, U.value = null, ee.value === m && (q.value = m), ce.value += 1;
326
+ } catch (E) {
327
+ const oe = E;
328
+ oe.status === 409 && oe.body?.data ? U.value = oe.body : oe.body?.errors ? (A.value = oe.body.errors, z.danger(a("page.save-failed"))) : z.danger(r(E));
329
+ } finally {
330
+ W.value = !1;
331
+ }
332
+ }
333
+ async function me() {
334
+ await le({
335
+ title: a("page.conflict-theirs-title"),
336
+ message: a("page.conflict-theirs-text"),
337
+ confirmText: a("page.conflict-theirs"),
338
+ cancelText: a("page.cancel"),
339
+ tone: "danger"
340
+ }) && await J(!0);
341
+ }
342
+ async function Y() {
343
+ const m = U.value;
344
+ m && ($.value = m.data.revision, U.value = null, await K());
345
+ }
346
+ async function _e() {
347
+ if (s.value && (B.value && await K(), !U.value)) {
348
+ _.value = !0;
349
+ try {
350
+ await l.publish(s.value.id), await J(!0), z.success(a("page.published"));
351
+ } catch (m) {
352
+ z.danger(r(m));
353
+ } finally {
354
+ _.value = !1;
355
+ }
356
+ }
357
+ }
358
+ function r(m) {
359
+ return m.body?.message ?? String(m);
360
+ }
361
+ function b() {
362
+ return s.value?.status === "published" ? "success" : s.value?.status === "modified" ? "warning" : "default";
363
+ }
364
+ function w(m) {
365
+ B.value && m.preventDefault();
366
+ }
367
+ return ae(ee, fe), ae(o, () => {
368
+ J();
369
+ }), ye(() => {
370
+ J(), window.addEventListener("beforeunload", w);
371
+ }), Je(() => {
372
+ clearTimeout(Q), window.removeEventListener("beforeunload", w);
373
+ }), et(async () => !B.value || !I.value || (await K(), !B.value) ? !0 : await le({
374
+ title: a("page.leave-title"),
375
+ message: a("page.leave-text"),
376
+ confirmText: a("page.leave"),
377
+ cancelText: a("page.cancel"),
378
+ tone: "danger"
379
+ })), (m, te) => (d(), M("div", {
380
+ ref_key: "root",
381
+ ref: pe,
382
+ class: "wx-page-editor",
383
+ "data-wx-fill": "",
384
+ onFocusout: he
385
+ }, [
386
+ S.value || !s.value ? (d(), M(F, { key: 0 }, [
387
+ f(e(ke), {
388
+ class: "wx-page-editor__ghost",
389
+ title: "",
390
+ rows: 1
391
+ }),
392
+ f(e(ke), { rows: 8 })
393
+ ], 64)) : (d(), M(F, { key: 1 }, [
394
+ N("div", _t, [
395
+ N("div", wt, [
396
+ f(e(lt), {
397
+ size: "sm",
398
+ label: e(a)("page.trail")
399
+ }, {
400
+ default: n(() => [
401
+ f(e(we), {
402
+ as: "router-link",
403
+ to: v.base
404
+ }, {
405
+ default: n(() => [
406
+ h(g(e(a)("module.title")), 1)
407
+ ]),
408
+ _: 1
409
+ }, 8, ["to"]),
410
+ (d(!0), M(F, null, ie(ve.value, (E) => (d(), x(e(we), {
411
+ key: E.id,
412
+ as: "router-link",
413
+ to: `${v.base}/${E.id}`
414
+ }, {
415
+ default: n(() => [
416
+ h(g(E.label), 1)
417
+ ]),
418
+ _: 2
419
+ }, 1032, ["to"]))), 128)),
420
+ f(e(we), { current: "" }, {
421
+ default: n(() => [
422
+ h(g(s.value.is_home ? e(a)("pages.home") : se.value), 1)
423
+ ]),
424
+ _: 1
425
+ })
426
+ ]),
427
+ _: 1
428
+ }, 8, ["label"]),
429
+ N("div", xt, [
430
+ N("span", kt, g(s.value.is_home ? e(a)("pages.home") : se.value || e(a)("page.untitled")), 1),
431
+ f(e(We), {
432
+ type: b(),
433
+ dot: ""
434
+ }, {
435
+ default: n(() => [
436
+ h(g(e(a)(`page.status-${s.value.status}`)), 1)
437
+ ]),
438
+ _: 1
439
+ }, 8, ["type"]),
440
+ f(e(O), {
441
+ size: "sm",
442
+ tone: "muted",
443
+ class: "wx-page-editor__state"
444
+ }, {
445
+ default: n(() => [
446
+ h(g(e(a)(`page.state-${ne.value}`)), 1)
447
+ ]),
448
+ _: 1
449
+ })
450
+ ])
451
+ ]),
452
+ N("div", $t, [
453
+ L.value ? (d(), x(e(Le), {
454
+ key: 0,
455
+ align: "end"
456
+ }, {
457
+ trigger: n(() => [
458
+ f(e($e), {
459
+ type: "more",
460
+ title: e(a)("page.more")
461
+ }, null, 8, ["title"])
462
+ ]),
463
+ default: n(() => [
464
+ T.value ? (d(), x(e(re), {
465
+ key: 0,
466
+ icon: "eye",
467
+ href: T.value,
468
+ target: "_blank",
469
+ rel: "noopener"
470
+ }, {
471
+ default: n(() => [
472
+ h(g(e(a)("page.preview")), 1)
473
+ ]),
474
+ _: 1
475
+ }, 8, ["href"])) : D("", !0),
476
+ s.value.url && s.value.status !== "draft" ? (d(), x(e(re), {
477
+ key: 1,
478
+ icon: "link",
479
+ href: s.value.url,
480
+ target: "_blank",
481
+ rel: "noopener"
482
+ }, {
483
+ default: n(() => [
484
+ h(g(e(a)("page.open-on-site")), 1)
485
+ ]),
486
+ _: 1
487
+ }, 8, ["href"])) : D("", !0),
488
+ I.value ? (d(), x(e(re), {
489
+ key: 2,
490
+ icon: "check",
491
+ disabled: !B.value,
492
+ onClick: K
493
+ }, {
494
+ default: n(() => [
495
+ h(g(e(a)("page.save")), 1)
496
+ ]),
497
+ _: 1
498
+ }, 8, ["disabled"])) : D("", !0)
499
+ ]),
500
+ _: 1
501
+ })) : (d(), M(F, { key: 1 }, [
502
+ T.value ? (d(), x(e(R), {
503
+ key: 0,
504
+ variant: "text",
505
+ icon: "eye",
506
+ href: T.value,
507
+ target: "_blank",
508
+ rel: "noopener"
509
+ }, {
510
+ default: n(() => [
511
+ h(g(e(a)("page.preview")), 1)
512
+ ]),
513
+ _: 1
514
+ }, 8, ["href"])) : D("", !0),
515
+ s.value.url && s.value.status !== "draft" ? (d(), x(e(R), {
516
+ key: 1,
517
+ variant: "text",
518
+ icon: "link",
519
+ href: s.value.url,
520
+ target: "_blank",
521
+ rel: "noopener"
522
+ }, {
523
+ default: n(() => [
524
+ h(g(e(a)("page.open-on-site")), 1)
525
+ ]),
526
+ _: 1
527
+ }, 8, ["href"])) : D("", !0),
528
+ I.value ? (d(), x(e(R), {
529
+ key: 2,
530
+ variant: "outline",
531
+ loading: W.value,
532
+ disabled: !B.value,
533
+ onClick: K
534
+ }, {
535
+ default: n(() => [
536
+ h(g(e(a)("page.save")), 1)
537
+ ]),
538
+ _: 1
539
+ }, 8, ["loading", "disabled"])) : D("", !0)
540
+ ], 64)),
541
+ I.value ? (d(), x(e(R), {
542
+ key: 2,
543
+ type: "primary",
544
+ loading: _.value,
545
+ disabled: s.value.status === "published" && !B.value,
546
+ onClick: _e
547
+ }, {
548
+ default: n(() => [
549
+ h(g(e(a)("page.publish")), 1)
550
+ ]),
551
+ _: 1
552
+ }, 8, ["loading", "disabled"])) : D("", !0)
553
+ ])
554
+ ]),
555
+ U.value ? (d(), x(e(Ve), {
556
+ key: 0,
557
+ type: "warning",
558
+ title: e(a)("page.conflict-title"),
559
+ description: U.value.message
560
+ }, {
561
+ actions: n(() => [
562
+ f(e(R), {
563
+ size: "sm",
564
+ variant: "outline",
565
+ onClick: me
566
+ }, {
567
+ default: n(() => [
568
+ h(g(e(a)("page.conflict-theirs")), 1)
569
+ ]),
570
+ _: 1
571
+ }),
572
+ f(e(R), {
573
+ size: "sm",
574
+ type: "primary",
575
+ onClick: Y
576
+ }, {
577
+ default: n(() => [
578
+ h(g(e(a)("page.conflict-mine")), 1)
579
+ ]),
580
+ _: 1
581
+ })
582
+ ]),
583
+ _: 1
584
+ }, 8, ["title", "description"])) : D("", !0),
585
+ N("div", Tt, [
586
+ f(e(tt), {
587
+ modelValue: k.value,
588
+ "onUpdate:modelValue": te[0] || (te[0] = (E) => k.value = E),
589
+ name: "pages.form",
590
+ errors: A.value,
591
+ disabled: !I.value || _.value
592
+ }, null, 8, ["modelValue", "errors", "disabled"])
593
+ ])
594
+ ], 64))
595
+ ], 544));
596
+ }
597
+ }), Vt = /* @__PURE__ */ de(Wt, [["__scopeId", "data-v-861519ac"]]), zt = { class: "wx-page-history" }, St = { class: "wx-page-history__number" }, Dt = { class: "wx-page-history__who" }, Mt = /* @__PURE__ */ H({
598
+ name: "WxPageHistory",
599
+ __name: "PageHistory",
600
+ setup(v) {
601
+ const u = X(), p = Z(u), l = ze();
602
+ G();
603
+ const i = j("webx-pages"), t = P(null), c = P(!1), a = V(() => l?.page.value ?? null), o = V(() => u.can("pages.manage")), s = V(
604
+ () => a.value?.published_at ? t.value?.[0]?.number ?? null : null
605
+ );
606
+ async function C() {
607
+ const y = a.value;
608
+ if (y)
609
+ try {
610
+ t.value = await p.versions(y.id);
611
+ } catch (S) {
612
+ t.value = [], z.danger(T(S));
613
+ }
614
+ }
615
+ async function k(y) {
616
+ const S = a.value;
617
+ if (!(!S || !await le({
618
+ title: i("page.restore-title", { number: y.number }),
619
+ message: i("page.restore-text"),
620
+ confirmText: i("page.restore"),
621
+ cancelText: i("page.cancel")
622
+ }))) {
623
+ c.value = !0;
624
+ try {
625
+ await p.restoreVersion(S.id, y.number), await l?.reload(), z.success(i("page.restored-version", { number: y.number }));
626
+ } catch (_) {
627
+ z.danger(T(_));
628
+ } finally {
629
+ c.value = !1;
630
+ }
631
+ }
632
+ }
633
+ function $(y) {
634
+ return y.created_at ? new Date(y.created_at).toLocaleString(u.i18n.state.locale) : "";
635
+ }
636
+ function T(y) {
637
+ return y.body?.message ?? String(y);
638
+ }
639
+ return ae(
640
+ () => [a.value?.id, a.value?.published_at, a.value?.updated_at],
641
+ () => {
642
+ C();
643
+ },
644
+ {
645
+ immediate: !0
646
+ }
647
+ ), (y, S) => (d(), M("div", zt, [
648
+ t.value === null ? (d(), x(e(ke), {
649
+ key: 0,
650
+ rows: 3
651
+ })) : t.value.length === 0 ? (d(), x(e(nt), {
652
+ key: 1,
653
+ description: e(i)("page.history-empty")
654
+ }, null, 8, ["description"])) : (d(!0), M(F, { key: 2 }, ie(t.value, (W) => (d(), M("div", {
655
+ key: W.number,
656
+ class: Qe(["wx-page-history__row", { "is-live": W.number === s.value }])
657
+ }, [
658
+ N("code", St, g(e(i)("page.version", { number: W.number })), 1),
659
+ N("div", Dt, [
660
+ f(e(O), null, {
661
+ default: n(() => [
662
+ h(g($(W)), 1)
663
+ ]),
664
+ _: 2
665
+ }, 1024),
666
+ f(e(O), {
667
+ size: "sm",
668
+ tone: "muted"
669
+ }, {
670
+ default: n(() => [
671
+ h(g(W.author ?? e(i)(`page.source-${W.source}`)) + " ", 1),
672
+ W.comment ? (d(), M(F, { key: 0 }, [
673
+ h(" · " + g(W.comment), 1)
674
+ ], 64)) : D("", !0)
675
+ ]),
676
+ _: 2
677
+ }, 1024)
678
+ ]),
679
+ W.number === s.value ? (d(), x(e(We), {
680
+ key: 0,
681
+ type: "success",
682
+ dot: ""
683
+ }, {
684
+ default: n(() => [
685
+ h(g(e(i)("page.version-live")), 1)
686
+ ]),
687
+ _: 1
688
+ })) : D("", !0),
689
+ o.value && W.number !== s.value ? (d(), x(e(R), {
690
+ key: 1,
691
+ size: "sm",
692
+ variant: "outline",
693
+ loading: c.value,
694
+ onClick: (_) => k(W)
695
+ }, {
696
+ default: n(() => [
697
+ h(g(e(i)("page.restore")), 1)
698
+ ]),
699
+ _: 1
700
+ }, 8, ["loading", "onClick"])) : D("", !0)
701
+ ], 2))), 128))
702
+ ]));
703
+ }
704
+ }), At = /* @__PURE__ */ de(Mt, [["__scopeId", "data-v-d24bb671"]]), Se = /* @__PURE__ */ H({
705
+ __name: "PagePicker",
706
+ props: /* @__PURE__ */ Ye({
707
+ exclude: { default: () => [] },
708
+ placeholder: { default: void 0 },
709
+ selected: { default: () => [] }
710
+ }, {
711
+ modelValue: { default: null },
712
+ modelModifiers: {}
713
+ }),
714
+ emits: ["update:modelValue"],
715
+ setup(v) {
716
+ const u = v, p = Xe(v, "modelValue"), l = X(), i = Z(l);
717
+ G();
718
+ const t = j("webx-pages"), c = P([]);
719
+ ye(async () => {
720
+ const s = await i.list();
721
+ s.home && (c.value = [
722
+ a(
723
+ s.home,
724
+ s.items.map((C) => a(C))
725
+ )
726
+ ]);
727
+ });
728
+ function a(s, C) {
729
+ return {
730
+ id: s.id,
731
+ label: s.is_home ? t("pages.home") : s.title,
732
+ disabled: u.exclude.includes(s.id),
733
+ leaf: s.children_count === 0,
734
+ ...C ? { children: C } : {}
735
+ };
736
+ }
737
+ async function o(s) {
738
+ return (await i.list({ parent: Number(s.id) })).items.map((k) => a(k));
739
+ }
740
+ return (s, C) => (d(), x(e(st), {
741
+ modelValue: p.value,
742
+ "onUpdate:modelValue": C[0] || (C[0] = (k) => p.value = k),
743
+ nodes: c.value,
744
+ lazy: "",
745
+ load: o,
746
+ "show-path": "",
747
+ clearable: "",
748
+ "selected-path": u.selected.map((k) => ({
749
+ id: k.id,
750
+ label: k.is_home ? e(t)("pages.home") : k.title
751
+ })),
752
+ placeholder: u.placeholder ?? e(t)("page.field-parent"),
753
+ "aria-label": e(t)("page.field-parent"),
754
+ teleport: ""
755
+ }, null, 8, ["modelValue", "nodes", "selected-path", "placeholder", "aria-label"]));
756
+ }
757
+ }), Bt = {
758
+ key: 0,
759
+ class: "wx-page-place"
760
+ }, Nt = /* @__PURE__ */ H({
761
+ name: "WxPagePlace",
762
+ __name: "PagePlace",
763
+ setup(v) {
764
+ const u = X(), p = Z(u), l = ze(), i = Ue();
765
+ G();
766
+ const t = j("webx-pages"), c = P(!1), a = P(null), o = V(() => l?.page.value ?? null), s = V(() => l?.ancestors.value.length === 0 ? null : l?.prefixes.value[i.active.value] ?? null), C = V(() => {
767
+ const T = l?.values.value.slug;
768
+ return typeof T == "string" ? T : T?.[i.active.value] ?? "";
769
+ }), k = V(() => o.value?.is_home ? "/" : s.value === null || C.value === "" ? null : `/${[s.value, C.value].filter(Boolean).join("/")}`);
770
+ ae(
771
+ o,
772
+ (T) => {
773
+ a.value = T?.parent_id ?? null;
774
+ },
775
+ { immediate: !0 }
776
+ );
777
+ async function $(T) {
778
+ const y = o.value;
779
+ if (!(!y || T === null || T === y.parent_id || c.value)) {
780
+ c.value = !0;
781
+ try {
782
+ const S = await p.move(y.id, T, "inside");
783
+ z.success(
784
+ S.addresses_changed > 1 ? t("page.moved", { count: S.addresses_changed }) : t("page.moved-one")
785
+ ), await l?.reload();
786
+ } catch (S) {
787
+ z.danger(S.body?.message ?? String(S)), a.value = y.parent_id;
788
+ } finally {
789
+ c.value = !1;
790
+ }
791
+ }
792
+ }
793
+ return (T, y) => o.value ? (d(), M("div", Bt, [
794
+ f(e(ue), {
795
+ label: e(t)("page.address")
796
+ }, {
797
+ default: n(() => [
798
+ k.value ? (d(), x(e(O), {
799
+ key: 0,
800
+ mono: "",
801
+ class: "wx-page-place__address"
802
+ }, {
803
+ default: n(() => [
804
+ h(g(k.value), 1)
805
+ ]),
806
+ _: 1
807
+ })) : (d(), x(e(O), {
808
+ key: 1,
809
+ size: "sm",
810
+ tone: "muted"
811
+ }, {
812
+ default: n(() => [
813
+ h(g(e(t)("page.no-address")), 1)
814
+ ]),
815
+ _: 1
816
+ }))
817
+ ]),
818
+ _: 1
819
+ }, 8, ["label"]),
820
+ o.value.can.move ? (d(), M(F, { key: 0 }, [
821
+ f(e(ue), {
822
+ label: e(t)("page.field-parent"),
823
+ help: e(t)("page.parent-help")
824
+ }, {
825
+ default: n(() => [
826
+ f(Se, {
827
+ modelValue: a.value,
828
+ "onUpdate:modelValue": [
829
+ y[0] || (y[0] = (S) => a.value = S),
830
+ $
831
+ ],
832
+ exclude: [o.value.id],
833
+ selected: e(l)?.ancestors.value ?? []
834
+ }, null, 8, ["modelValue", "exclude", "selected"])
835
+ ]),
836
+ _: 1
837
+ }, 8, ["label", "help"]),
838
+ f(e(Ve), {
839
+ type: "info",
840
+ variant: "soft",
841
+ description: e(t)("page.parent-warning")
842
+ }, null, 8, ["description"])
843
+ ], 64)) : D("", !0)
844
+ ])) : D("", !0);
845
+ }
846
+ }), Et = /* @__PURE__ */ de(Nt, [["__scopeId", "data-v-1adcb4ab"]]), Ne = /* @__PURE__ */ H({
847
+ __name: "PageActions",
848
+ props: {
849
+ page: {},
850
+ inBin: { type: Boolean, default: !1 },
851
+ menuOnly: { type: Boolean, default: !1 }
852
+ },
853
+ emits: ["open", "add", "duplicate", "move", "copy", "remove", "restore"],
854
+ setup(v, { emit: u }) {
855
+ const p = v, l = u;
856
+ G();
857
+ const i = j("webx-pages"), t = V(() => {
858
+ const c = p.page;
859
+ if (p.inBin)
860
+ return [
861
+ {
862
+ key: "restore",
863
+ type: "restore",
864
+ icon: "refresh",
865
+ label: i("page.restore"),
866
+ run: () => l("restore", c)
867
+ }
868
+ ];
869
+ const a = [
870
+ {
871
+ key: "open",
872
+ type: "edit",
873
+ icon: "edit",
874
+ label: i("page.open"),
875
+ run: () => l("open", c)
876
+ },
877
+ {
878
+ key: "add",
879
+ type: "add",
880
+ icon: "plus",
881
+ label: i("page.add-child"),
882
+ run: () => l("add", c)
883
+ }
884
+ ];
885
+ return c.is_home || a.push({
886
+ key: "duplicate",
887
+ type: "copy",
888
+ icon: "copy",
889
+ label: i("page.duplicate"),
890
+ run: () => l("duplicate", c)
891
+ }), c.can.move && a.push({
892
+ key: "move",
893
+ type: "sort",
894
+ icon: "drag",
895
+ label: i("page.move"),
896
+ run: () => l("move", c)
897
+ }), a.push(
898
+ {
899
+ key: "copy-address",
900
+ type: "link",
901
+ icon: "link",
902
+ label: i("page.copy-address"),
903
+ disabled: !c.url,
904
+ run: () => l("copy", c)
905
+ },
906
+ {
907
+ key: "on-site",
908
+ type: "goto",
909
+ icon: "external-link",
910
+ label: i("page.open-on-site"),
911
+ disabled: !c.url,
912
+ href: c.url ?? void 0
913
+ }
914
+ ), c.can.delete && a.push({
915
+ key: "delete",
916
+ type: "remove",
917
+ icon: "trash",
918
+ label: i("page.delete"),
919
+ danger: !0,
920
+ run: () => l("remove", c)
921
+ }), a;
922
+ });
923
+ return (c, a) => p.menuOnly ? (d(), x(e(Le), {
924
+ key: 0,
925
+ align: "end",
926
+ onClick: a[0] || (a[0] = xe(() => {
927
+ }, ["stop"]))
928
+ }, {
929
+ trigger: n(() => [
930
+ f(e($e), {
931
+ type: "more",
932
+ size: "sm",
933
+ title: p.page.title
934
+ }, null, 8, ["title"])
935
+ ]),
936
+ default: n(() => [
937
+ (d(!0), M(F, null, ie(t.value, (o) => (d(), x(e(re), {
938
+ key: o.key,
939
+ icon: o.icon,
940
+ tone: o.danger ? "danger" : "default",
941
+ href: o.href,
942
+ target: o.href ? "_blank" : void 0,
943
+ disabled: o.disabled,
944
+ onClick: (s) => o.run?.()
945
+ }, {
946
+ default: n(() => [
947
+ h(g(o.label), 1)
948
+ ]),
949
+ _: 2
950
+ }, 1032, ["icon", "tone", "href", "target", "disabled", "onClick"]))), 128))
951
+ ]),
952
+ _: 1
953
+ })) : (d(), x(e(ot), {
954
+ key: 1,
955
+ size: "sm",
956
+ align: "end",
957
+ collapse: "",
958
+ "aria-label": p.page.title,
959
+ onClick: a[1] || (a[1] = xe(() => {
960
+ }, ["stop"]))
961
+ }, {
962
+ collapsed: n(() => [
963
+ (d(!0), M(F, null, ie(t.value, (o) => (d(), x(e(re), {
964
+ key: o.key,
965
+ icon: o.icon,
966
+ tone: o.danger ? "danger" : "default",
967
+ href: o.href,
968
+ target: o.href ? "_blank" : void 0,
969
+ disabled: o.disabled,
970
+ onClick: (s) => o.run?.()
971
+ }, {
972
+ default: n(() => [
973
+ h(g(o.label), 1)
974
+ ]),
975
+ _: 2
976
+ }, 1032, ["icon", "tone", "href", "target", "disabled", "onClick"]))), 128))
977
+ ]),
978
+ default: n(() => [
979
+ (d(!0), M(F, null, ie(t.value, (o) => (d(), x(e($e), {
980
+ key: o.key,
981
+ type: o.type,
982
+ title: o.label,
983
+ href: o.href,
984
+ target: o.href ? "_blank" : void 0,
985
+ disabled: o.disabled,
986
+ onClick: (s) => o.run?.()
987
+ }, null, 8, ["type", "title", "href", "target", "disabled", "onClick"]))), 128))
988
+ ]),
989
+ _: 1
990
+ }, 8, ["aria-label"]));
991
+ }
992
+ }), Rt = {
993
+ а: "a",
994
+ б: "b",
995
+ в: "v",
996
+ г: "g",
997
+ ґ: "g",
998
+ д: "d",
999
+ е: "e",
1000
+ ё: "e",
1001
+ є: "ie",
1002
+ ж: "zh",
1003
+ з: "z",
1004
+ и: "i",
1005
+ і: "i",
1006
+ ї: "i",
1007
+ й: "i",
1008
+ к: "k",
1009
+ л: "l",
1010
+ м: "m",
1011
+ н: "n",
1012
+ о: "o",
1013
+ п: "p",
1014
+ р: "r",
1015
+ с: "s",
1016
+ т: "t",
1017
+ у: "u",
1018
+ ф: "f",
1019
+ х: "h",
1020
+ ц: "ts",
1021
+ ч: "ch",
1022
+ ш: "sh",
1023
+ щ: "shch",
1024
+ ъ: "",
1025
+ ы: "y",
1026
+ ь: "",
1027
+ э: "e",
1028
+ ю: "iu",
1029
+ я: "ia",
1030
+ ä: "a",
1031
+ ö: "o",
1032
+ ü: "u",
1033
+ ß: "ss",
1034
+ å: "a",
1035
+ ø: "o",
1036
+ æ: "ae",
1037
+ ç: "c",
1038
+ ğ: "g",
1039
+ ı: "i",
1040
+ ş: "s",
1041
+ ą: "a",
1042
+ ć: "c",
1043
+ ę: "e",
1044
+ ł: "l",
1045
+ ń: "n",
1046
+ ó: "o",
1047
+ ś: "s",
1048
+ ź: "z",
1049
+ ż: "z"
1050
+ };
1051
+ function Ot(v) {
1052
+ return v.toLowerCase().split("").map((u) => Rt[u] ?? u).join("").normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
1053
+ }
1054
+ const Ut = /* @__PURE__ */ H({
1055
+ __name: "PageCreateDialog",
1056
+ props: {
1057
+ parent: { default: null }
1058
+ },
1059
+ setup(v) {
1060
+ const u = v, { open: p, resolve: l, dismiss: i } = Fe(), t = X(), c = Z(t);
1061
+ G();
1062
+ const a = j("webx-pages"), o = P(""), s = P(""), C = P(u.parent?.id ?? null), k = P(!1), $ = P({}), T = Pe("field"), y = P(!1);
1063
+ ae(o, (W) => {
1064
+ y.value || (s.value = Ot(W));
1065
+ }), ye(async () => {
1066
+ await Ze(), T.value?.querySelector("input")?.focus();
1067
+ });
1068
+ async function S() {
1069
+ if (!(o.value.trim() === "" || k.value)) {
1070
+ k.value = !0, $.value = {};
1071
+ try {
1072
+ l(
1073
+ await c.create({
1074
+ title: o.value.trim(),
1075
+ slug: s.value.trim(),
1076
+ parent_id: C.value
1077
+ })
1078
+ );
1079
+ } catch (W) {
1080
+ $.value = W.body?.errors ?? {};
1081
+ } finally {
1082
+ k.value = !1;
1083
+ }
1084
+ }
1085
+ }
1086
+ return (W, _) => (d(), x(e(Ke), {
1087
+ open: e(p),
1088
+ "onUpdate:open": _[5] || (_[5] = (A) => Re(p) ? p.value = A : null),
1089
+ title: e(a)("page.new-title"),
1090
+ width: 460
1091
+ }, {
1092
+ footer: n(() => [
1093
+ f(e(Te), { size: "sm" }, {
1094
+ default: n(() => [
1095
+ f(e(R), {
1096
+ variant: "outline",
1097
+ onClick: _[4] || (_[4] = (A) => e(i)())
1098
+ }, {
1099
+ default: n(() => [
1100
+ h(g(e(a)("page.cancel")), 1)
1101
+ ]),
1102
+ _: 1
1103
+ }),
1104
+ f(e(R), {
1105
+ type: "primary",
1106
+ loading: k.value,
1107
+ disabled: o.value.trim() === "",
1108
+ onClick: S
1109
+ }, {
1110
+ default: n(() => [
1111
+ h(g(e(a)("page.create")), 1)
1112
+ ]),
1113
+ _: 1
1114
+ }, 8, ["loading", "disabled"])
1115
+ ]),
1116
+ _: 1
1117
+ })
1118
+ ]),
1119
+ default: n(() => [
1120
+ f(e(ue), {
1121
+ label: e(a)("page.field-title"),
1122
+ error: $.value.title?.[0],
1123
+ required: ""
1124
+ }, {
1125
+ default: n(() => [
1126
+ N("div", {
1127
+ ref_key: "field",
1128
+ ref: T
1129
+ }, [
1130
+ f(e(Me), {
1131
+ modelValue: o.value,
1132
+ "onUpdate:modelValue": _[0] || (_[0] = (A) => o.value = A),
1133
+ "aria-label": e(a)("page.field-title"),
1134
+ onKeyup: De(S, ["enter"])
1135
+ }, null, 8, ["modelValue", "aria-label"])
1136
+ ], 512)
1137
+ ]),
1138
+ _: 1
1139
+ }, 8, ["label", "error"]),
1140
+ f(e(ue), {
1141
+ label: e(a)("page.field-slug"),
1142
+ error: $.value.slug?.[0],
1143
+ help: e(a)("page.slug-help")
1144
+ }, {
1145
+ default: n(() => [
1146
+ f(e(Me), {
1147
+ modelValue: s.value,
1148
+ "onUpdate:modelValue": _[1] || (_[1] = (A) => s.value = A),
1149
+ "aria-label": e(a)("page.field-slug"),
1150
+ onInput: _[2] || (_[2] = (A) => y.value = !0),
1151
+ onKeyup: De(S, ["enter"])
1152
+ }, null, 8, ["modelValue", "aria-label"])
1153
+ ]),
1154
+ _: 1
1155
+ }, 8, ["label", "error", "help"]),
1156
+ f(e(ue), {
1157
+ label: e(a)("page.field-parent"),
1158
+ error: $.value.parent_id?.[0]
1159
+ }, {
1160
+ default: n(() => [
1161
+ f(Se, {
1162
+ modelValue: C.value,
1163
+ "onUpdate:modelValue": _[3] || (_[3] = (A) => C.value = A),
1164
+ selected: u.parent ? [u.parent] : []
1165
+ }, null, 8, ["modelValue", "selected"])
1166
+ ]),
1167
+ _: 1
1168
+ }, 8, ["label", "error"])
1169
+ ]),
1170
+ _: 1
1171
+ }, 8, ["open", "title"]));
1172
+ }
1173
+ }), It = /* @__PURE__ */ H({
1174
+ __name: "PageMoveDialog",
1175
+ props: {
1176
+ page: {}
1177
+ },
1178
+ setup(v) {
1179
+ const u = v, { open: p, resolve: l, dismiss: i } = Fe();
1180
+ G();
1181
+ const t = j("webx-pages"), c = P(u.page.parent_id);
1182
+ return (a, o) => (d(), x(e(Ke), {
1183
+ open: e(p),
1184
+ "onUpdate:open": o[3] || (o[3] = (s) => Re(p) ? p.value = s : null),
1185
+ title: e(t)("page.move-title", { title: u.page.title }),
1186
+ width: 460
1187
+ }, {
1188
+ footer: n(() => [
1189
+ f(e(Te), { size: "sm" }, {
1190
+ default: n(() => [
1191
+ f(e(R), {
1192
+ variant: "outline",
1193
+ onClick: o[1] || (o[1] = (s) => e(i)())
1194
+ }, {
1195
+ default: n(() => [
1196
+ h(g(e(t)("page.cancel")), 1)
1197
+ ]),
1198
+ _: 1
1199
+ }),
1200
+ f(e(R), {
1201
+ type: "primary",
1202
+ disabled: c.value === null || c.value === u.page.parent_id,
1203
+ onClick: o[2] || (o[2] = (s) => e(l)(c.value))
1204
+ }, {
1205
+ default: n(() => [
1206
+ h(g(e(t)("page.move-confirm")), 1)
1207
+ ]),
1208
+ _: 1
1209
+ }, 8, ["disabled"])
1210
+ ]),
1211
+ _: 1
1212
+ })
1213
+ ]),
1214
+ default: n(() => [
1215
+ f(e(Te), {
1216
+ direction: "vertical",
1217
+ size: "md",
1218
+ fill: ""
1219
+ }, {
1220
+ default: n(() => [
1221
+ f(e(Ve), {
1222
+ type: "info",
1223
+ variant: "soft",
1224
+ description: e(t)("page.move-help")
1225
+ }, null, 8, ["description"]),
1226
+ f(Se, {
1227
+ modelValue: c.value,
1228
+ "onUpdate:modelValue": o[0] || (o[0] = (s) => c.value = s),
1229
+ exclude: [u.page.id]
1230
+ }, null, 8, ["modelValue", "exclude"])
1231
+ ]),
1232
+ _: 1
1233
+ })
1234
+ ]),
1235
+ _: 1
1236
+ }, 8, ["open", "title"]));
1237
+ }
1238
+ }), Lt = { class: "wx-pages__head" }, Ft = { class: "wx-pages__title" }, Kt = ["href"], Ee = 640, Ht = /* @__PURE__ */ H({
1239
+ __name: "PagesPage",
1240
+ props: {
1241
+ base: { default: "/pages" }
1242
+ },
1243
+ setup(v) {
1244
+ const u = v, p = X(), l = Z(p), i = Ce();
1245
+ G();
1246
+ const t = j("webx-pages"), c = P(null), a = P([]), o = P(!0), s = P(""), C = P(""), k = Pe("root"), $ = Ie(k), T = V(() => $.value > 0 && $.value < Ee), y = Ae(Ut), S = Ae(It), W = V(() => p.can("pages.manage")), _ = V(() => C.value === "trashed"), A = V(() => !_.value && !T.value && s.value.trim() === ""), U = V(
1247
+ () => p.state.manifest?.modules.find((r) => r.id === "pages")?.title ?? t("module.title")
1248
+ ), q = V(() => [
1249
+ { value: "", label: t("page.filter-all") },
1250
+ { value: "draft", label: t("page.filter-draft") },
1251
+ { value: "published", label: t("page.filter-published") },
1252
+ { value: "modified", label: t("page.filter-modified") },
1253
+ { value: "trashed", label: t("page.bin"), icon: "trash" }
1254
+ ]), ce = V(
1255
+ () => A.value && c.value ? [{ ...c.value, children_count: 0 }, ...a.value] : a.value
1256
+ ), I = V(() => [
1257
+ { key: "title", label: t("page.column-title"), minWidth: 200 },
1258
+ { key: "path", label: t("page.column-address"), width: 200 },
1259
+ // In the bin the state of a page is not what it was published as — it is off the site either
1260
+ // way — so the column says when it went in, which is what decides whether to bring it back.
1261
+ {
1262
+ key: "status",
1263
+ label: _.value ? t("page.column-deleted") : t("page.column-status"),
1264
+ align: "center",
1265
+ width: 130,
1266
+ hideBelow: 620
1267
+ },
1268
+ {
1269
+ key: "updated_at",
1270
+ label: t("page.column-updated"),
1271
+ width: 180,
1272
+ hideBelow: 900,
1273
+ hideOnCards: !0,
1274
+ hidden: _.value
1275
+ },
1276
+ { key: "actions", label: "", width: 48, align: "right", hideOnCards: !0 }
1277
+ ]), pe = V(
1278
+ () => A.value ? {
1279
+ childrenKey: "children",
1280
+ hasChildrenKey: "children_count",
1281
+ lazy: !0,
1282
+ load: (r) => l.list({ parent: r.id }).then((b) => b.items),
1283
+ draggable: W.value,
1284
+ allowDrag: (r) => r.can.move,
1285
+ allowDrop: ge
1286
+ } : void 0
1287
+ );
1288
+ function ge(r, b, w) {
1289
+ return b.is_home ? w === "inside" : r.id !== b.id;
1290
+ }
1291
+ async function L() {
1292
+ o.value = !0;
1293
+ try {
1294
+ const r = await l.list({
1295
+ search: s.value.trim(),
1296
+ status: _.value ? "" : C.value,
1297
+ trashed: _.value,
1298
+ flat: T.value
1299
+ });
1300
+ c.value = r.home, a.value = r.items;
1301
+ } catch (r) {
1302
+ z.danger(Y(r));
1303
+ } finally {
1304
+ o.value = !1;
1305
+ }
1306
+ }
1307
+ function ee(r) {
1308
+ r.search !== s.value && (s.value = r.search, L());
1309
+ }
1310
+ function B(r) {
1311
+ const b = `${u.base}/${r.id}`;
1312
+ i.resolve(b).matched.length > 0 && i.push(b);
1313
+ }
1314
+ async function ne(r) {
1315
+ const b = await y({ parent: r });
1316
+ b && (await L(), B(b));
1317
+ }
1318
+ async function se(r) {
1319
+ try {
1320
+ await l.duplicate(r.id), z.success(t("page.duplicated")), await L();
1321
+ } catch (b) {
1322
+ z.danger(Y(b));
1323
+ }
1324
+ }
1325
+ async function ve(r) {
1326
+ const b = await S({ page: r });
1327
+ b != null && await J(r, b, "inside");
1328
+ }
1329
+ async function be(r) {
1330
+ await J(r.row, r.target.id, r.zone);
1331
+ }
1332
+ async function J(r, b, w) {
1333
+ try {
1334
+ const m = await l.move(r.id, b, w);
1335
+ z.success(
1336
+ m.addresses_changed > 1 ? t("page.moved", { count: m.addresses_changed }) : t("page.moved-one")
1337
+ );
1338
+ } catch (m) {
1339
+ z.danger(Y(m));
1340
+ } finally {
1341
+ await L();
1342
+ }
1343
+ }
1344
+ async function Q(r) {
1345
+ if (await le({
1346
+ title: t("page.delete-title", { title: r.title }),
1347
+ message: (
1348
+ // The whole branch, not the level under it: a catalogue with two sections and forty
1349
+ // products is forty-two pages leaving the site, and "2" would be a comforting lie.
1350
+ r.descendants_count > 0 ? `${t("page.delete-text")} ${t("page.delete-branch", { count: r.descendants_count })}` : t("page.delete-text")
1351
+ ),
1352
+ confirmText: t("page.delete"),
1353
+ cancelText: t("page.cancel"),
1354
+ tone: "danger"
1355
+ }))
1356
+ try {
1357
+ await l.remove(r.id), z.success(t("page.deleted")), await L();
1358
+ } catch (w) {
1359
+ z.danger(Y(w));
1360
+ }
1361
+ }
1362
+ async function fe(r) {
1363
+ try {
1364
+ await l.restore(r.id), z.success(t("page.restored")), await L();
1365
+ } catch (b) {
1366
+ z.danger(Y(b));
1367
+ }
1368
+ }
1369
+ async function he(r) {
1370
+ if (r.url)
1371
+ try {
1372
+ await navigator.clipboard.writeText(r.url), z.success(t("page.address-copied"));
1373
+ } catch {
1374
+ }
1375
+ }
1376
+ function K(r) {
1377
+ return r === "published" ? "success" : r === "modified" ? "warning" : "default";
1378
+ }
1379
+ function me(r) {
1380
+ const b = _.value ? r.deleted_at : r.updated_at;
1381
+ return b ? new Date(b).toLocaleDateString() : "";
1382
+ }
1383
+ function Y(r) {
1384
+ return r.body?.message ?? String(r);
1385
+ }
1386
+ function _e() {
1387
+ L();
1388
+ }
1389
+ return ae(T, () => {
1390
+ L();
1391
+ }), ye(L), (r, b) => (d(), M("div", {
1392
+ ref_key: "root",
1393
+ ref: k,
1394
+ class: "wx-pages"
1395
+ }, [
1396
+ N("div", Lt, [
1397
+ f(e(it), { level: 2 }, {
1398
+ default: n(() => [
1399
+ h(g(U.value), 1)
1400
+ ]),
1401
+ _: 1
1402
+ }),
1403
+ W.value ? (d(), x(e(R), {
1404
+ key: 0,
1405
+ type: "primary",
1406
+ icon: "plus",
1407
+ onClick: b[0] || (b[0] = (w) => ne(null))
1408
+ }, {
1409
+ default: n(() => [
1410
+ h(g(e(t)("page.new")), 1)
1411
+ ]),
1412
+ _: 1
1413
+ })) : D("", !0)
1414
+ ]),
1415
+ f(e(Oe), null, {
1416
+ header: n(() => [
1417
+ f(e(ut), {
1418
+ modelValue: C.value,
1419
+ "onUpdate:modelValue": b[1] || (b[1] = (w) => C.value = w),
1420
+ options: q.value,
1421
+ size: "sm",
1422
+ "aria-label": e(t)("page.column-status"),
1423
+ onChange: _e
1424
+ }, null, 8, ["modelValue", "options", "aria-label"])
1425
+ ]),
1426
+ default: n(() => [
1427
+ f(e(rt), {
1428
+ data: ce.value,
1429
+ columns: I.value,
1430
+ "row-key": "id",
1431
+ tree: pe.value,
1432
+ searchable: "",
1433
+ hover: "",
1434
+ flush: "",
1435
+ layout: "fixed",
1436
+ loading: o.value,
1437
+ "cards-below": Ee,
1438
+ "search-placeholder": e(t)("page.search"),
1439
+ "empty-text": _.value ? e(t)("page.empty-bin") : s.value ? e(t)("page.empty-search") : e(t)("page.empty"),
1440
+ "aria-label": U.value,
1441
+ onStateChange: ee,
1442
+ onNodeDrop: be,
1443
+ onRowClick: B
1444
+ }, {
1445
+ "cell-title": n(({ row: w }) => [
1446
+ N("span", Ft, g(w.is_home ? e(t)("pages.home") : w.title), 1)
1447
+ ]),
1448
+ "cell-path": n(({ row: w }) => [
1449
+ _.value ? (d(), x(e(O), {
1450
+ key: 0,
1451
+ size: "sm",
1452
+ tone: "muted"
1453
+ }, {
1454
+ default: n(() => [...b[3] || (b[3] = [
1455
+ h("—", -1)
1456
+ ])]),
1457
+ _: 1
1458
+ })) : w.url && w.status !== "draft" ? (d(), M("a", {
1459
+ key: 1,
1460
+ class: "wx-pages__address",
1461
+ href: w.url,
1462
+ target: "_blank",
1463
+ rel: "noopener",
1464
+ onClick: b[2] || (b[2] = xe(() => {
1465
+ }, ["stop"]))
1466
+ }, " /" + g(w.path), 9, Kt)) : w.path !== null ? (d(), x(e(O), {
1467
+ key: 2,
1468
+ mono: "",
1469
+ size: "sm",
1470
+ tone: "muted"
1471
+ }, {
1472
+ default: n(() => [
1473
+ h("/" + g(w.path), 1)
1474
+ ]),
1475
+ _: 2
1476
+ }, 1024)) : (d(), x(e(O), {
1477
+ key: 3,
1478
+ size: "sm",
1479
+ tone: "muted"
1480
+ }, {
1481
+ default: n(() => [
1482
+ h(g(e(t)("page.no-address")), 1)
1483
+ ]),
1484
+ _: 1
1485
+ }))
1486
+ ]),
1487
+ "cell-status": n(({ row: w }) => [
1488
+ _.value ? (d(), x(e(O), {
1489
+ key: 0,
1490
+ size: "sm",
1491
+ tone: "muted"
1492
+ }, {
1493
+ default: n(() => [
1494
+ h(g(me(w)), 1)
1495
+ ]),
1496
+ _: 2
1497
+ }, 1024)) : (d(), x(e(We), {
1498
+ key: 1,
1499
+ type: K(w.status),
1500
+ dot: ""
1501
+ }, {
1502
+ default: n(() => [
1503
+ h(g(e(t)(`page.status-${w.status}`)), 1)
1504
+ ]),
1505
+ _: 2
1506
+ }, 1032, ["type"]))
1507
+ ]),
1508
+ "cell-updated_at": n(({ row: w }) => [
1509
+ f(e(O), {
1510
+ size: "sm",
1511
+ tone: "muted"
1512
+ }, {
1513
+ default: n(() => [
1514
+ h(g(me(w)), 1),
1515
+ w.edited_by && !_.value ? (d(), M(F, { key: 0 }, [
1516
+ h(", " + g(w.edited_by), 1)
1517
+ ], 64)) : D("", !0)
1518
+ ]),
1519
+ _: 2
1520
+ }, 1024)
1521
+ ]),
1522
+ "cell-actions": n(({ row: w }) => [
1523
+ W.value ? (d(), x(Ne, {
1524
+ key: 0,
1525
+ page: w,
1526
+ "in-bin": _.value,
1527
+ onOpen: B,
1528
+ onAdd: ne,
1529
+ onDuplicate: se,
1530
+ onMove: ve,
1531
+ onCopy: he,
1532
+ onRemove: Q,
1533
+ onRestore: fe
1534
+ }, null, 8, ["page", "in-bin"])) : D("", !0)
1535
+ ]),
1536
+ "card-actions": n(({ row: w }) => [
1537
+ W.value ? (d(), x(Ne, {
1538
+ key: 0,
1539
+ "menu-only": "",
1540
+ page: w,
1541
+ "in-bin": _.value,
1542
+ onOpen: B,
1543
+ onAdd: ne,
1544
+ onDuplicate: se,
1545
+ onMove: ve,
1546
+ onCopy: he,
1547
+ onRemove: Q,
1548
+ onRestore: fe
1549
+ }, null, 8, ["page", "in-bin"])) : D("", !0)
1550
+ ]),
1551
+ _: 1
1552
+ }, 8, ["data", "columns", "tree", "loading", "search-placeholder", "empty-text", "aria-label"])
1553
+ ]),
1554
+ _: 1
1555
+ })
1556
+ ], 512));
1557
+ }
1558
+ }), jt = /* @__PURE__ */ de(Ht, [["__scopeId", "data-v-681ec89c"]]);
1559
+ function Zt(v = {}) {
1560
+ const u = v.path ?? "/pages";
1561
+ return {
1562
+ id: "pages",
1563
+ path: u,
1564
+ routes: [
1565
+ { path: u, name: "webx.pages", component: jt, props: { base: u } },
1566
+ {
1567
+ path: `${u}/:id(\\d+)`,
1568
+ name: "webx.pages.edit",
1569
+ component: Vt,
1570
+ props: { base: u }
1571
+ }
1572
+ ],
1573
+ /*
1574
+ * The parts of `pages.form` that are not fields.
1575
+ *
1576
+ * The editor is a described screen so that a module can add a tab to it with a patch, and
1577
+ * the price of that is that everything on it has to be a node type — where the page sits,
1578
+ * what may be done to it, what its history is. Each of these draws only, and each reads the
1579
+ * page from the editor above it rather than from the description.
1580
+ */
1581
+ types: {
1582
+ "wx-page-place": { component: Et, kind: "display" },
1583
+ "wx-page-danger": { component: bt, kind: "display" },
1584
+ "wx-page-history": { component: At, kind: "display" }
1585
+ }
1586
+ };
1587
+ }
1588
+ export {
1589
+ bt as WxPageDanger,
1590
+ Vt as WxPageEditorPage,
1591
+ At as WxPageHistory,
1592
+ Se as WxPagePicker,
1593
+ Et as WxPagePlace,
1594
+ jt as WxPagesPage,
1595
+ Z as createPagesApi,
1596
+ He as pageEditorKey,
1597
+ Zt as pages,
1598
+ pt as pagesMessages,
1599
+ ct as providePageEditor,
1600
+ Ot as slugify,
1601
+ ze as usePageEditor
1602
+ };
1603
+ //# sourceMappingURL=index.js.map