@webx-ui/module-seo 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,1446 @@
1
+ import { defineComponent as F, useModel as Ue, ref as z, computed as S, openBlock as w, createElementBlock as L, createVNode as a, unref as e, withCtx as t, createElementVNode as O, isRef as I, createTextVNode as b, toDisplayString as m, createCommentVNode as j, createBlock as W, resolveDynamicComponent as We, mergeModels as ze, renderSlot as Te, watch as ge, withKeys as De, Fragment as se, renderList as ue, createSlots as fe, withModifiers as Z, markRaw as Oe } from "vue";
2
+ import { useAdmin as P, useTranslate as M } from "@webx-ui/module-admin";
3
+ import { useLocales as Re, WxTabs as je, WxTab as oe, WxFormItem as U, WxInput as N, WxText as R, WxTextarea as ce, WxCheckboxGroup as Le, WxCodeEditor as Be, localizedValue as he, WxHeading as Ie, WxSpace as H, WxSegmented as Ne, WxButton as A, useModal as ie, WxDialog as de, WxSelect as ee, WxSwitch as be, toast as B, WxAlert as pe, WxBadge as J, WxDescriptions as Ae, WxDescriptionsItem as Fe, WxEmpty as Pe, createModal as te, WxCard as ye, WxTable as _e, WxActions as ae, WxAction as le, confirm as xe, WxInputNumber as Me } from "@webx-ui/core";
4
+ import { useRouter as Ee, useRoute as Ke } from "vue-router";
5
+ const He = {
6
+ module: {
7
+ title: "SEO"
8
+ },
9
+ page: {
10
+ rules: "Rules",
11
+ redirects: "Redirects",
12
+ test: "Check an address",
13
+ "new-rule": "New rule",
14
+ "new-redirect": "New redirect",
15
+ "search-rules": "Search by address",
16
+ "search-redirects": "Search by address or destination",
17
+ empty: "Nothing here yet.",
18
+ address: "Address",
19
+ kind: "Kind",
20
+ priority: "Priority",
21
+ state: "State",
22
+ active: "Active",
23
+ inactive: "Off",
24
+ title: "Title",
25
+ target: "Destination",
26
+ status: "Code",
27
+ hits: "Hits",
28
+ "last-hit": "Last used",
29
+ never: "never",
30
+ loop: "Points at itself",
31
+ "any-kind": "Any kind",
32
+ exact: "Exact",
33
+ mask: "Mask",
34
+ regex: "Regular expression",
35
+ rule: "Rule",
36
+ redirect: "Redirect",
37
+ save: "Save",
38
+ cancel: "Cancel",
39
+ delete: "Delete",
40
+ saved: "Saved.",
41
+ deleted: "Deleted.",
42
+ failed: "Some values were not accepted. Check the highlighted fields.",
43
+ "delete-title": "Delete :pattern?",
44
+ "delete-text": "This cannot be undone.",
45
+ "address-help": "A path with its query string. In a mask, * is one segment and ** is any number of them; a regular expression is stored as written, delimiters and all.",
46
+ "target-help": "A path on this site, or a full address elsewhere. $1 puts back what a mask caught.",
47
+ "priority-help": "Among rules of the same kind, the higher number wins.",
48
+ "test-placeholder": "/catalog/shoes?page=2",
49
+ "test-run": "Check",
50
+ "test-empty": "Type an address to see what the site will say about it.",
51
+ "test-matched": "Matched rule",
52
+ "test-none": "No rule matches this address.",
53
+ "test-redirected": "This address is redirected to :target with a :status.",
54
+ "test-result": "What the page will say",
55
+ "test-chain": "Where each part came from"
56
+ },
57
+ card: {
58
+ "section-page": "The page",
59
+ "section-share": "Sharing",
60
+ "section-advanced": "Advanced",
61
+ title: "Title",
62
+ h1: "Heading",
63
+ description: "Description",
64
+ keywords: "Keywords",
65
+ canonical: "Canonical address",
66
+ "canonical-help": "The address this page should be indexed under, when it is not its own.",
67
+ robots: "Indexing",
68
+ "robots-kept": "Also kept, as written: :directives",
69
+ noindex: "Keep out of the index",
70
+ nofollow: "Do not follow the links",
71
+ noarchive: "No cached copy",
72
+ nosnippet: "No snippet",
73
+ noimageindex: "Do not index the images",
74
+ "og-title": "Share title",
75
+ "og-description": "Share description",
76
+ "og-image": "Share image",
77
+ "og-help": "Left empty, a share preview uses the title and description above.",
78
+ "json-ld": "Structured data",
79
+ "json-ld-help": "A JSON-LD object, or a list of them. What the site says about itself comes from the settings; this is for a page that needs markup of its own.",
80
+ "json-ld-invalid": "This is not valid JSON.",
81
+ preview: "In search results"
82
+ }
83
+ }, ve = /* @__PURE__ */ new WeakSet();
84
+ function E() {
85
+ try {
86
+ const { i18n: n } = P();
87
+ ve.has(n) || (n.defaults("webx-seo", He), ve.add(n));
88
+ } catch {
89
+ }
90
+ }
91
+ const ne = [
92
+ "noindex",
93
+ "nofollow",
94
+ "noarchive",
95
+ "nosnippet",
96
+ "noimageindex"
97
+ ], Je = { class: "wx-seo" }, qe = { class: "wx-seo__fields" }, Ge = { class: "wx-seo__count" }, Qe = { class: "wx-seo__count" }, Xe = {
98
+ key: 0,
99
+ class: "wx-seo__preview"
100
+ }, Ye = { class: "wx-seo__snippet" }, Ze = {
101
+ key: 0,
102
+ class: "wx-seo__snippet-address"
103
+ }, et = { class: "wx-seo__snippet-title" }, tt = { class: "wx-seo__snippet-text" }, at = { class: "wx-seo__fields" }, lt = { class: "wx-seo__fields" }, st = /* @__PURE__ */ F({
104
+ name: "WxSeo",
105
+ __name: "SeoCard",
106
+ props: /* @__PURE__ */ ze({
107
+ mediaField: { default: void 0 },
108
+ disabled: { type: Boolean, default: !1 },
109
+ titleLimit: { default: 60 },
110
+ descriptionLimit: { default: 160 },
111
+ site: { default: void 0 },
112
+ structuredData: { type: Boolean, default: !0 }
113
+ }, {
114
+ modelValue: { default: null },
115
+ modelModifiers: {}
116
+ }),
117
+ emits: ["update:modelValue"],
118
+ setup(n) {
119
+ const u = n, i = Ue(n, "modelValue");
120
+ E();
121
+ const c = M("webx-seo"), l = Re(), d = z(null), h = z(!1);
122
+ function o(f) {
123
+ return S({
124
+ get: () => i.value?.[f],
125
+ set: (x) => {
126
+ i.value = { ...i.value ?? {}, [f]: x };
127
+ }
128
+ });
129
+ }
130
+ const y = o("title"), k = o("h1"), p = o("description"), _ = o("keywords"), g = o("og_title"), T = o("og_description"), D = S({
131
+ get: () => i.value?.canonical ?? "",
132
+ set: (f) => {
133
+ i.value = { ...i.value ?? {}, canonical: f.trim() === "" ? null : f };
134
+ }
135
+ }), $ = S({
136
+ get: () => i.value?.og_image ?? null,
137
+ set: (f) => {
138
+ i.value = { ...i.value ?? {}, og_image: f };
139
+ }
140
+ }), v = S(() => (i.value?.robots ?? "").split(",").map((f) => f.trim())), s = S(
141
+ () => v.value.filter((f) => f !== "" && !ne.includes(f))
142
+ ), r = S({
143
+ get: () => v.value.filter((f) => ne.includes(f)),
144
+ set: (f) => {
145
+ const x = [...f, ...s.value].join(", ");
146
+ i.value = { ...i.value ?? {}, robots: x === "" ? null : x };
147
+ }
148
+ }), V = S(
149
+ () => ne.map((f) => ({ value: f, label: c(`card.${f}`) }))
150
+ ), Q = S({
151
+ get: () => {
152
+ if (d.value !== null) return d.value;
153
+ const f = i.value?.json_ld;
154
+ return f == null ? "" : JSON.stringify(f, null, 2);
155
+ },
156
+ set: (f) => {
157
+ if (d.value = f, f.trim() === "") {
158
+ h.value = !1, i.value = { ...i.value ?? {}, json_ld: null };
159
+ return;
160
+ }
161
+ try {
162
+ i.value = { ...i.value ?? {}, json_ld: JSON.parse(f) }, h.value = !1;
163
+ } catch {
164
+ h.value = !0;
165
+ }
166
+ }
167
+ });
168
+ function X(f) {
169
+ return he(f, l.active.value);
170
+ }
171
+ const Y = S(() => ({
172
+ title: X(y.value).length,
173
+ description: X(p.value).length
174
+ })), K = S(() => ({
175
+ title: X(y.value),
176
+ description: X(p.value),
177
+ address: D.value || (u.site ?? "")
178
+ })), Se = S(() => K.value.title !== "" || K.value.description !== ""), Ce = S(
179
+ () => s.value.length === 0 ? void 0 : c("card.robots-kept", { directives: s.value.join(", ") })
180
+ );
181
+ function re(f, x) {
182
+ return f > x ? "warning" : "muted";
183
+ }
184
+ return (f, x) => (w(), L("div", Je, [
185
+ a(e(je), { "keep-alive": "" }, {
186
+ default: t(() => [
187
+ a(e(oe), {
188
+ label: e(c)("card.section-page"),
189
+ value: "page"
190
+ }, {
191
+ default: t(() => [
192
+ O("div", qe, [
193
+ a(e(U), {
194
+ label: e(c)("card.title"),
195
+ disabled: n.disabled
196
+ }, {
197
+ default: t(() => [
198
+ a(e(N), {
199
+ modelValue: e(y),
200
+ "onUpdate:modelValue": x[0] || (x[0] = (C) => I(y) ? y.value = C : null),
201
+ localized: ""
202
+ }, null, 8, ["modelValue"]),
203
+ O("div", Ge, [
204
+ a(e(R), {
205
+ size: "sm",
206
+ tone: re(Y.value.title, n.titleLimit)
207
+ }, {
208
+ default: t(() => [
209
+ b(m(Y.value.title) + " / " + m(n.titleLimit), 1)
210
+ ]),
211
+ _: 1
212
+ }, 8, ["tone"])
213
+ ])
214
+ ]),
215
+ _: 1
216
+ }, 8, ["label", "disabled"]),
217
+ a(e(U), {
218
+ label: e(c)("card.h1"),
219
+ disabled: n.disabled
220
+ }, {
221
+ default: t(() => [
222
+ a(e(N), {
223
+ modelValue: e(k),
224
+ "onUpdate:modelValue": x[1] || (x[1] = (C) => I(k) ? k.value = C : null),
225
+ localized: ""
226
+ }, null, 8, ["modelValue"])
227
+ ]),
228
+ _: 1
229
+ }, 8, ["label", "disabled"]),
230
+ a(e(U), {
231
+ label: e(c)("card.description"),
232
+ disabled: n.disabled
233
+ }, {
234
+ default: t(() => [
235
+ a(e(ce), {
236
+ modelValue: e(p),
237
+ "onUpdate:modelValue": x[2] || (x[2] = (C) => I(p) ? p.value = C : null),
238
+ localized: "",
239
+ rows: 3
240
+ }, null, 8, ["modelValue"]),
241
+ O("div", Qe, [
242
+ a(e(R), {
243
+ size: "sm",
244
+ tone: re(Y.value.description, n.descriptionLimit)
245
+ }, {
246
+ default: t(() => [
247
+ b(m(Y.value.description) + " / " + m(n.descriptionLimit), 1)
248
+ ]),
249
+ _: 1
250
+ }, 8, ["tone"])
251
+ ])
252
+ ]),
253
+ _: 1
254
+ }, 8, ["label", "disabled"]),
255
+ a(e(U), {
256
+ label: e(c)("card.keywords"),
257
+ disabled: n.disabled
258
+ }, {
259
+ default: t(() => [
260
+ a(e(N), {
261
+ modelValue: e(_),
262
+ "onUpdate:modelValue": x[3] || (x[3] = (C) => I(_) ? _.value = C : null),
263
+ localized: ""
264
+ }, null, 8, ["modelValue"])
265
+ ]),
266
+ _: 1
267
+ }, 8, ["label", "disabled"]),
268
+ Se.value ? (w(), L("div", Xe, [
269
+ a(e(R), {
270
+ size: "sm",
271
+ tone: "muted"
272
+ }, {
273
+ default: t(() => [
274
+ b(m(e(c)("card.preview")), 1)
275
+ ]),
276
+ _: 1
277
+ }),
278
+ O("div", Ye, [
279
+ K.value.address ? (w(), L("div", Ze, m(K.value.address), 1)) : j("", !0),
280
+ O("div", et, m(K.value.title), 1),
281
+ O("div", tt, m(K.value.description), 1)
282
+ ])
283
+ ])) : j("", !0)
284
+ ])
285
+ ]),
286
+ _: 1
287
+ }, 8, ["label"]),
288
+ a(e(oe), {
289
+ label: e(c)("card.section-share"),
290
+ value: "share"
291
+ }, {
292
+ default: t(() => [
293
+ O("div", at, [
294
+ n.mediaField ? (w(), W(We(n.mediaField), {
295
+ key: 0,
296
+ modelValue: $.value,
297
+ "onUpdate:modelValue": x[4] || (x[4] = (C) => $.value = C),
298
+ label: e(c)("card.og-image"),
299
+ aspect: "16/9",
300
+ accept: "image",
301
+ disabled: n.disabled
302
+ }, null, 8, ["modelValue", "label", "disabled"])) : j("", !0),
303
+ a(e(U), {
304
+ label: e(c)("card.og-title"),
305
+ help: e(c)("card.og-help"),
306
+ disabled: n.disabled
307
+ }, {
308
+ default: t(() => [
309
+ a(e(N), {
310
+ modelValue: e(g),
311
+ "onUpdate:modelValue": x[5] || (x[5] = (C) => I(g) ? g.value = C : null),
312
+ localized: ""
313
+ }, null, 8, ["modelValue"])
314
+ ]),
315
+ _: 1
316
+ }, 8, ["label", "help", "disabled"]),
317
+ a(e(U), {
318
+ label: e(c)("card.og-description"),
319
+ disabled: n.disabled
320
+ }, {
321
+ default: t(() => [
322
+ a(e(ce), {
323
+ modelValue: e(T),
324
+ "onUpdate:modelValue": x[6] || (x[6] = (C) => I(T) ? T.value = C : null),
325
+ localized: "",
326
+ rows: 2
327
+ }, null, 8, ["modelValue"])
328
+ ]),
329
+ _: 1
330
+ }, 8, ["label", "disabled"])
331
+ ])
332
+ ]),
333
+ _: 1
334
+ }, 8, ["label"]),
335
+ a(e(oe), {
336
+ label: e(c)("card.section-advanced"),
337
+ value: "advanced"
338
+ }, {
339
+ default: t(() => [
340
+ O("div", lt, [
341
+ a(e(U), {
342
+ label: e(c)("card.canonical"),
343
+ help: e(c)("card.canonical-help"),
344
+ disabled: n.disabled
345
+ }, {
346
+ default: t(() => [
347
+ a(e(N), {
348
+ modelValue: D.value,
349
+ "onUpdate:modelValue": x[7] || (x[7] = (C) => D.value = C),
350
+ placeholder: "https://example.com/page"
351
+ }, null, 8, ["modelValue"])
352
+ ]),
353
+ _: 1
354
+ }, 8, ["label", "help", "disabled"]),
355
+ a(e(U), {
356
+ label: e(c)("card.robots"),
357
+ help: Ce.value,
358
+ disabled: n.disabled
359
+ }, {
360
+ default: t(() => [
361
+ a(e(Le), {
362
+ modelValue: r.value,
363
+ "onUpdate:modelValue": x[8] || (x[8] = (C) => r.value = C),
364
+ options: V.value
365
+ }, null, 8, ["modelValue", "options"])
366
+ ]),
367
+ _: 1
368
+ }, 8, ["label", "help", "disabled"]),
369
+ n.structuredData ? (w(), W(e(U), {
370
+ key: 0,
371
+ label: e(c)("card.json-ld"),
372
+ help: e(c)("card.json-ld-help"),
373
+ error: h.value ? e(c)("card.json-ld-invalid") : void 0,
374
+ disabled: n.disabled
375
+ }, {
376
+ default: t(() => [
377
+ a(e(Be), {
378
+ modelValue: Q.value,
379
+ "onUpdate:modelValue": x[9] || (x[9] = (C) => Q.value = C),
380
+ language: "json",
381
+ lint: "",
382
+ "min-height": "120px",
383
+ "max-height": "420px"
384
+ }, null, 8, ["modelValue"])
385
+ ]),
386
+ _: 1
387
+ }, 8, ["label", "help", "error", "disabled"])) : j("", !0)
388
+ ])
389
+ ]),
390
+ _: 1
391
+ }, 8, ["label"])
392
+ ]),
393
+ _: 1
394
+ })
395
+ ]));
396
+ }
397
+ }), q = (n, u) => {
398
+ const i = n.__vccOpts || n;
399
+ for (const [c, l] of u)
400
+ i[c] = l;
401
+ return i;
402
+ }, we = /* @__PURE__ */ q(st, [["__scopeId", "data-v-b7ea284e"]]), ot = { class: "wx-seo-layout" }, nt = { class: "wx-seo-layout__head" }, it = /* @__PURE__ */ F({
403
+ __name: "SeoLayout",
404
+ props: {
405
+ base: {},
406
+ current: {}
407
+ },
408
+ emits: ["test"],
409
+ setup(n, { emit: u }) {
410
+ const i = n, c = u, l = P(), d = Ee(), h = Ke();
411
+ E();
412
+ const o = M("webx-seo"), y = S(
413
+ () => l.state.manifest?.modules.find((_) => _.id === "seo")?.title ?? o("module.title")
414
+ ), k = S(() => [
415
+ { value: "rules", label: o("page.rules") },
416
+ { value: "redirects", label: o("page.redirects") }
417
+ ]), p = S({
418
+ get: () => i.current,
419
+ set: (_) => {
420
+ const g = _ === "redirects" ? `${i.base}/redirects` : i.base;
421
+ g !== h.path && d.push(g);
422
+ }
423
+ });
424
+ return (_, g) => (w(), L("div", ot, [
425
+ O("div", nt, [
426
+ a(e(Ie), { level: 2 }, {
427
+ default: t(() => [
428
+ b(m(y.value), 1)
429
+ ]),
430
+ _: 1
431
+ }),
432
+ a(e(H), { size: "sm" }, {
433
+ default: t(() => [
434
+ a(e(Ne), {
435
+ modelValue: p.value,
436
+ "onUpdate:modelValue": g[0] || (g[0] = (T) => p.value = T),
437
+ options: k.value,
438
+ size: "sm"
439
+ }, null, 8, ["modelValue", "options"]),
440
+ a(e(A), {
441
+ variant: "outline",
442
+ icon: "search",
443
+ onClick: g[1] || (g[1] = (T) => c("test"))
444
+ }, {
445
+ default: t(() => [
446
+ b(m(e(o)("page.test")), 1)
447
+ ]),
448
+ _: 1
449
+ })
450
+ ]),
451
+ _: 1
452
+ })
453
+ ]),
454
+ Te(_.$slots, "default", {}, void 0, !0)
455
+ ]));
456
+ }
457
+ }), ke = /* @__PURE__ */ q(it, [["__scopeId", "data-v-01bc38b5"]]);
458
+ function G(n) {
459
+ const u = `${n.apiPath}/seo`, i = (d) => d.data, c = (d) => ({
460
+ ...d.meta,
461
+ data: d.data
462
+ }), l = (d) => ({
463
+ q: d.q || void 0,
464
+ match_type: d.match_type ?? void 0,
465
+ is_active: d.is_active ?? void 0,
466
+ sort: d.sort || void 0,
467
+ page: d.page,
468
+ per_page: d.per_page
469
+ });
470
+ return {
471
+ urls: (d = {}) => n.http.get(`${u}/urls`, {
472
+ query: l(d)
473
+ }).then(c),
474
+ url: (d) => n.http.get(`${u}/urls/${d}`).then(i),
475
+ createUrl: (d) => n.http.post(`${u}/urls`, d).then(i),
476
+ updateUrl: (d, h) => n.http.put(`${u}/urls/${d}`, h).then(i),
477
+ removeUrl: (d) => n.http.delete(`${u}/urls/${d}`),
478
+ redirects: (d = {}) => n.http.get(
479
+ `${u}/redirects`,
480
+ { query: l(d) }
481
+ ).then(c),
482
+ createRedirect: (d) => n.http.post(`${u}/redirects`, d).then(i),
483
+ updateRedirect: (d, h) => n.http.put(`${u}/redirects/${d}`, h).then(i),
484
+ removeRedirect: (d) => n.http.delete(`${u}/redirects/${d}`),
485
+ // A POST because it carries an address in its body, and an address in a query string is an
486
+ // address somebody has to escape twice.
487
+ test: (d, h = null) => n.http.post(`${u}/test-url`, { url: d, locale: h ?? void 0 }).then(i)
488
+ };
489
+ }
490
+ const dt = { class: "wx-seo-redirect" }, rt = { class: "wx-seo-redirect__row" }, ut = /* @__PURE__ */ F({
491
+ __name: "SeoRedirectDialog",
492
+ props: {
493
+ redirect: { default: null }
494
+ },
495
+ setup(n) {
496
+ const u = n, { resolve: i, dismiss: c, open: l } = ie(), d = P(), h = G(d);
497
+ E();
498
+ const o = M("webx-seo"), y = z(!1), k = z({}), p = z({
499
+ match_type: "exact",
500
+ pattern: "",
501
+ target: "",
502
+ status: 301,
503
+ is_active: !0
504
+ }), _ = S(() => u.redirect !== null), g = S(() => [
505
+ { value: "exact", label: o("page.exact") },
506
+ { value: "mask", label: o("page.mask") },
507
+ { value: "regex", label: o("page.regex") }
508
+ ]), T = [
509
+ { value: 301, label: "301" },
510
+ { value: 302, label: "302" }
511
+ ];
512
+ ge(
513
+ () => u.redirect,
514
+ (v) => {
515
+ p.value = {
516
+ match_type: v?.match_type ?? "exact",
517
+ pattern: v?.pattern ?? "",
518
+ target: v?.target ?? "",
519
+ status: v?.status ?? 301,
520
+ is_active: v?.is_active ?? !0
521
+ }, k.value = {};
522
+ },
523
+ { immediate: !0 }
524
+ );
525
+ function D(v) {
526
+ return k.value[v]?.[0];
527
+ }
528
+ async function $() {
529
+ y.value = !0, k.value = {};
530
+ try {
531
+ const v = u.redirect ? await h.updateRedirect(u.redirect.id, p.value) : await h.createRedirect(p.value);
532
+ B.success(o("page.saved")), i(v);
533
+ } catch (v) {
534
+ const s = v.body;
535
+ s?.errors ? (k.value = s.errors, B.danger(o("page.failed"))) : B.danger(s?.message ?? o("page.failed"));
536
+ } finally {
537
+ y.value = !1;
538
+ }
539
+ }
540
+ return (v, s) => (w(), W(e(de), {
541
+ open: e(l),
542
+ "onUpdate:open": s[6] || (s[6] = (r) => I(l) ? l.value = r : null),
543
+ title: e(o)("page.redirect"),
544
+ width: 640
545
+ }, {
546
+ footer: t(() => [
547
+ a(e(H), { size: "sm" }, {
548
+ default: t(() => [
549
+ a(e(A), {
550
+ variant: "outline",
551
+ onClick: s[5] || (s[5] = (r) => e(c)())
552
+ }, {
553
+ default: t(() => [
554
+ b(m(e(o)("page.cancel")), 1)
555
+ ]),
556
+ _: 1
557
+ }),
558
+ a(e(A), {
559
+ type: "primary",
560
+ loading: y.value,
561
+ onClick: $
562
+ }, {
563
+ default: t(() => [
564
+ b(m(_.value ? e(o)("page.save") : e(o)("page.new-redirect")), 1)
565
+ ]),
566
+ _: 1
567
+ }, 8, ["loading"])
568
+ ]),
569
+ _: 1
570
+ })
571
+ ]),
572
+ default: t(() => [
573
+ O("div", dt, [
574
+ a(e(U), {
575
+ label: e(o)("page.kind")
576
+ }, {
577
+ default: t(() => [
578
+ a(e(ee), {
579
+ modelValue: p.value.match_type,
580
+ "onUpdate:modelValue": s[0] || (s[0] = (r) => p.value.match_type = r),
581
+ options: g.value
582
+ }, null, 8, ["modelValue", "options"])
583
+ ]),
584
+ _: 1
585
+ }, 8, ["label"]),
586
+ a(e(U), {
587
+ label: e(o)("page.address"),
588
+ help: e(o)("page.address-help"),
589
+ error: D("pattern")
590
+ }, {
591
+ default: t(() => [
592
+ a(e(N), {
593
+ modelValue: p.value.pattern,
594
+ "onUpdate:modelValue": s[1] || (s[1] = (r) => p.value.pattern = r),
595
+ placeholder: "/old-address"
596
+ }, null, 8, ["modelValue"])
597
+ ]),
598
+ _: 1
599
+ }, 8, ["label", "help", "error"]),
600
+ a(e(U), {
601
+ label: e(o)("page.target"),
602
+ help: e(o)("page.target-help"),
603
+ error: D("target")
604
+ }, {
605
+ default: t(() => [
606
+ a(e(N), {
607
+ modelValue: p.value.target,
608
+ "onUpdate:modelValue": s[2] || (s[2] = (r) => p.value.target = r),
609
+ placeholder: "/new-address"
610
+ }, null, 8, ["modelValue"])
611
+ ]),
612
+ _: 1
613
+ }, 8, ["label", "help", "error"]),
614
+ O("div", rt, [
615
+ a(e(U), {
616
+ label: e(o)("page.status")
617
+ }, {
618
+ default: t(() => [
619
+ a(e(ee), {
620
+ modelValue: p.value.status,
621
+ "onUpdate:modelValue": s[3] || (s[3] = (r) => p.value.status = r),
622
+ options: T
623
+ }, null, 8, ["modelValue"])
624
+ ]),
625
+ _: 1
626
+ }, 8, ["label"]),
627
+ a(e(U), {
628
+ label: e(o)("page.state")
629
+ }, {
630
+ default: t(() => [
631
+ a(e(be), {
632
+ modelValue: p.value.is_active,
633
+ "onUpdate:modelValue": s[4] || (s[4] = (r) => p.value.is_active = r)
634
+ }, null, 8, ["modelValue"])
635
+ ]),
636
+ _: 1
637
+ }, 8, ["label"])
638
+ ])
639
+ ])
640
+ ]),
641
+ _: 1
642
+ }, 8, ["open", "title"]));
643
+ }
644
+ }), ct = /* @__PURE__ */ q(ut, [["__scopeId", "data-v-b30b1bf0"]]), pt = { class: "wx-seo-test" }, vt = {
645
+ key: 2,
646
+ class: "wx-seo-test__matched"
647
+ }, mt = {
648
+ key: 3,
649
+ class: "wx-seo-test__result"
650
+ }, gt = {
651
+ key: 4,
652
+ class: "wx-seo-test__chain"
653
+ }, ft = /* @__PURE__ */ F({
654
+ __name: "TestUrlDialog",
655
+ setup(n) {
656
+ const { open: u } = ie(), i = P(), c = G(i);
657
+ E();
658
+ const l = M("webx-seo"), d = z(""), h = z(!1), o = z(null), y = S(() => {
659
+ const p = o.value?.seo;
660
+ return p ? [
661
+ { label: l("card.title"), value: p.title },
662
+ { label: l("card.h1"), value: p.h1 },
663
+ { label: l("card.description"), value: p.description },
664
+ { label: l("card.keywords"), value: p.keywords },
665
+ { label: l("card.canonical"), value: p.canonical },
666
+ { label: l("card.robots"), value: p.robots }
667
+ ].filter((_) => _.value) : [];
668
+ });
669
+ async function k() {
670
+ if (d.value.trim() !== "") {
671
+ h.value = !0;
672
+ try {
673
+ o.value = await c.test(d.value);
674
+ } finally {
675
+ h.value = !1;
676
+ }
677
+ }
678
+ }
679
+ return (p, _) => (w(), W(e(de), {
680
+ open: e(u),
681
+ "onUpdate:open": _[1] || (_[1] = (g) => I(u) ? u.value = g : null),
682
+ title: e(l)("page.test"),
683
+ width: 720
684
+ }, {
685
+ default: t(() => [
686
+ O("div", pt, [
687
+ a(e(H), {
688
+ size: "sm",
689
+ class: "wx-seo-test__ask"
690
+ }, {
691
+ default: t(() => [
692
+ a(e(N), {
693
+ modelValue: d.value,
694
+ "onUpdate:modelValue": _[0] || (_[0] = (g) => d.value = g),
695
+ placeholder: e(l)("page.test-placeholder"),
696
+ class: "wx-seo-test__input",
697
+ onKeyup: De(k, ["enter"])
698
+ }, null, 8, ["modelValue", "placeholder"]),
699
+ a(e(A), {
700
+ type: "primary",
701
+ loading: h.value,
702
+ onClick: k
703
+ }, {
704
+ default: t(() => [
705
+ b(m(e(l)("page.test-run")), 1)
706
+ ]),
707
+ _: 1
708
+ }, 8, ["loading"])
709
+ ]),
710
+ _: 1
711
+ }),
712
+ o.value ? (w(), L(se, { key: 0 }, [
713
+ o.value.redirect ? (w(), W(e(pe), {
714
+ key: 0,
715
+ type: "warning",
716
+ description: e(l)("page.test-redirected", {
717
+ target: o.value.redirect.target,
718
+ status: o.value.redirect.status
719
+ })
720
+ }, null, 8, ["description"])) : j("", !0),
721
+ o.value.matched ? (w(), L("div", vt, [
722
+ a(e(R), {
723
+ size: "sm",
724
+ tone: "muted"
725
+ }, {
726
+ default: t(() => [
727
+ b(m(e(l)("page.test-matched")), 1)
728
+ ]),
729
+ _: 1
730
+ }),
731
+ a(e(H), {
732
+ size: "sm",
733
+ align: "center"
734
+ }, {
735
+ default: t(() => [
736
+ a(e(J), null, {
737
+ default: t(() => [
738
+ b(m(e(l)(`page.${o.value.matched.match_type}`)), 1)
739
+ ]),
740
+ _: 1
741
+ }),
742
+ a(e(R), {
743
+ mono: "",
744
+ size: "sm"
745
+ }, {
746
+ default: t(() => [
747
+ b(m(o.value.matched.pattern), 1)
748
+ ]),
749
+ _: 1
750
+ })
751
+ ]),
752
+ _: 1
753
+ })
754
+ ])) : (w(), W(e(pe), {
755
+ key: 1,
756
+ type: "info",
757
+ description: e(l)("page.test-none")
758
+ }, null, 8, ["description"])),
759
+ y.value.length > 0 ? (w(), L("div", mt, [
760
+ a(e(R), {
761
+ size: "sm",
762
+ tone: "muted"
763
+ }, {
764
+ default: t(() => [
765
+ b(m(e(l)("page.test-result")), 1)
766
+ ]),
767
+ _: 1
768
+ }),
769
+ a(e(Ae), {
770
+ columns: 1,
771
+ bordered: "",
772
+ size: "sm"
773
+ }, {
774
+ default: t(() => [
775
+ (w(!0), L(se, null, ue(y.value, (g) => (w(), W(e(Fe), {
776
+ key: g.label,
777
+ label: g.label
778
+ }, {
779
+ default: t(() => [
780
+ b(m(g.value), 1)
781
+ ]),
782
+ _: 2
783
+ }, 1032, ["label"]))), 128))
784
+ ]),
785
+ _: 1
786
+ })
787
+ ])) : j("", !0),
788
+ o.value.chain.length > 0 ? (w(), L("div", gt, [
789
+ a(e(R), {
790
+ size: "sm",
791
+ tone: "muted"
792
+ }, {
793
+ default: t(() => [
794
+ b(m(e(l)("page.test-chain")), 1)
795
+ ]),
796
+ _: 1
797
+ }),
798
+ a(e(H), {
799
+ size: "xs",
800
+ wrap: ""
801
+ }, {
802
+ default: t(() => [
803
+ (w(!0), L(se, null, ue(o.value.chain, (g) => (w(), W(e(J), {
804
+ key: g.source
805
+ }, {
806
+ default: t(() => [
807
+ b(m(g.source) + " · " + m(g.priority), 1)
808
+ ]),
809
+ _: 2
810
+ }, 1024))), 128))
811
+ ]),
812
+ _: 1
813
+ })
814
+ ])) : j("", !0)
815
+ ], 64)) : h.value ? j("", !0) : (w(), W(e(Pe), {
816
+ key: 1,
817
+ icon: "search",
818
+ description: e(l)("page.test-empty")
819
+ }, null, 8, ["description"]))
820
+ ])
821
+ ]),
822
+ _: 1
823
+ }, 8, ["open", "title"]));
824
+ }
825
+ }), Ve = /* @__PURE__ */ q(ft, [["__scopeId", "data-v-59071f71"]]), ht = /* @__PURE__ */ F({
826
+ __name: "SeoRedirectsPage",
827
+ props: {
828
+ base: { default: "/seo" }
829
+ },
830
+ setup(n) {
831
+ const u = n, i = P(), c = G(i);
832
+ E();
833
+ const l = M("webx-seo"), d = z(null), h = z(!1);
834
+ let o = { page: 1, perPage: 20, sort: null, search: "" };
835
+ const y = i.can("seo.manage"), k = te(ct), p = te(Ve), _ = S(() => [
836
+ { key: "pattern", label: l("page.address"), sortable: !0 },
837
+ { key: "target", label: l("page.target") },
838
+ { key: "status", label: l("page.status"), align: "center", hideBelow: 560 },
839
+ { key: "hits", label: l("page.hits"), align: "center", sortable: !0, hideBelow: 760 },
840
+ {
841
+ key: "last_hit_at",
842
+ label: l("page.last-hit"),
843
+ sortable: !0,
844
+ hideBelow: 900,
845
+ hideOnCards: !0
846
+ },
847
+ { key: "is_active", label: l("page.state"), align: "center", hideBelow: 660 },
848
+ {
849
+ key: "actions",
850
+ label: "",
851
+ width: 56,
852
+ align: "right",
853
+ hidden: !y,
854
+ hideOnCards: !0
855
+ }
856
+ ]);
857
+ async function g($) {
858
+ o = $, h.value = !0;
859
+ try {
860
+ d.value = await c.redirects({
861
+ q: $.search,
862
+ sort: $.sort ? `${$.sort.order === "desc" ? "-" : ""}${$.sort.key}` : "-hits",
863
+ page: $.page,
864
+ per_page: $.perPage
865
+ });
866
+ } finally {
867
+ h.value = !1;
868
+ }
869
+ }
870
+ async function T($) {
871
+ await k({ redirect: $ }) && g(o);
872
+ }
873
+ async function D($) {
874
+ if (await xe({
875
+ title: l("page.delete-title", { pattern: $.pattern }),
876
+ message: l("page.delete-text"),
877
+ confirmText: l("page.delete"),
878
+ cancelText: l("page.cancel"),
879
+ tone: "danger"
880
+ }))
881
+ try {
882
+ await c.removeRedirect($.id), B.success(l("page.deleted")), g(o);
883
+ } catch (s) {
884
+ B.danger(s.body?.message ?? String(s));
885
+ }
886
+ }
887
+ return ($, v) => (w(), W(ke, {
888
+ base: u.base,
889
+ current: "redirects",
890
+ onTest: v[4] || (v[4] = (s) => e(p)({}))
891
+ }, {
892
+ default: t(() => [
893
+ a(e(ye), null, fe({
894
+ header: t(() => [
895
+ b(m(e(l)("page.redirects")), 1)
896
+ ]),
897
+ default: t(() => [
898
+ a(e(_e), {
899
+ data: d.value,
900
+ columns: _.value,
901
+ "row-key": "id",
902
+ searchable: "",
903
+ hover: "",
904
+ flush: "",
905
+ loading: h.value,
906
+ "search-placeholder": e(l)("page.search-redirects"),
907
+ "empty-text": e(l)("page.empty"),
908
+ onStateChange: g,
909
+ onRowClick: v[3] || (v[3] = (s) => e(y) ? T(s) : void 0)
910
+ }, {
911
+ "cell-pattern": t(({ row: s }) => [
912
+ a(e(R), {
913
+ mono: "",
914
+ size: "sm"
915
+ }, {
916
+ default: t(() => [
917
+ b(m(s.pattern), 1)
918
+ ]),
919
+ _: 2
920
+ }, 1024),
921
+ s.is_loop ? (w(), W(e(J), {
922
+ key: 0,
923
+ type: "warning"
924
+ }, {
925
+ default: t(() => [
926
+ b(m(e(l)("page.loop")), 1)
927
+ ]),
928
+ _: 1
929
+ })) : j("", !0)
930
+ ]),
931
+ "cell-target": t(({ row: s }) => [
932
+ a(e(R), {
933
+ mono: "",
934
+ size: "sm"
935
+ }, {
936
+ default: t(() => [
937
+ b(m(s.target), 1)
938
+ ]),
939
+ _: 2
940
+ }, 1024)
941
+ ]),
942
+ "cell-last_hit_at": t(({ row: s }) => [
943
+ a(e(R), {
944
+ size: "sm",
945
+ tone: s.last_hit_at ? "default" : "muted"
946
+ }, {
947
+ default: t(() => [
948
+ b(m(s.last_hit_at ? new Date(s.last_hit_at).toLocaleString() : e(l)("page.never")), 1)
949
+ ]),
950
+ _: 2
951
+ }, 1032, ["tone"])
952
+ ]),
953
+ "cell-is_active": t(({ row: s }) => [
954
+ a(e(J), {
955
+ type: s.is_active ? "success" : "default",
956
+ dot: ""
957
+ }, {
958
+ default: t(() => [
959
+ b(m(s.is_active ? e(l)("page.active") : e(l)("page.inactive")), 1)
960
+ ]),
961
+ _: 2
962
+ }, 1032, ["type"])
963
+ ]),
964
+ "card-actions": t(({ row: s }) => [
965
+ e(y) ? (w(), W(e(ae), {
966
+ key: 0,
967
+ size: "sm",
968
+ onClick: v[1] || (v[1] = Z(() => {
969
+ }, ["stop"]))
970
+ }, {
971
+ default: t(() => [
972
+ a(e(le), {
973
+ type: "remove",
974
+ title: e(l)("page.delete"),
975
+ onClick: (r) => D(s)
976
+ }, null, 8, ["title", "onClick"])
977
+ ]),
978
+ _: 2
979
+ }, 1024)) : j("", !0)
980
+ ]),
981
+ "cell-actions": t(({ row: s }) => [
982
+ a(e(ae), {
983
+ size: "sm",
984
+ onClick: v[2] || (v[2] = Z(() => {
985
+ }, ["stop"]))
986
+ }, {
987
+ default: t(() => [
988
+ a(e(le), {
989
+ type: "remove",
990
+ title: e(l)("page.delete"),
991
+ onClick: (r) => D(s)
992
+ }, null, 8, ["title", "onClick"])
993
+ ]),
994
+ _: 2
995
+ }, 1024)
996
+ ]),
997
+ _: 1
998
+ }, 8, ["data", "columns", "loading", "search-placeholder", "empty-text"])
999
+ ]),
1000
+ _: 2
1001
+ }, [
1002
+ e(y) ? {
1003
+ name: "extra",
1004
+ fn: t(() => [
1005
+ a(e(A), {
1006
+ type: "primary",
1007
+ icon: "add",
1008
+ onClick: v[0] || (v[0] = (s) => T(null))
1009
+ }, {
1010
+ default: t(() => [
1011
+ b(m(e(l)("page.new-redirect")), 1)
1012
+ ]),
1013
+ _: 1
1014
+ })
1015
+ ]),
1016
+ key: "0"
1017
+ } : void 0
1018
+ ]), 1024)
1019
+ ]),
1020
+ _: 1
1021
+ }, 8, ["base"]));
1022
+ }
1023
+ }), $e = [
1024
+ "title",
1025
+ "h1",
1026
+ "description",
1027
+ "keywords",
1028
+ "og_title",
1029
+ "og_description",
1030
+ "og_image",
1031
+ "canonical",
1032
+ "robots",
1033
+ "json_ld"
1034
+ ];
1035
+ function me(n, u) {
1036
+ return he(n.title, u);
1037
+ }
1038
+ function bt(n) {
1039
+ if (!n) return {};
1040
+ const u = {};
1041
+ for (const i of $e) {
1042
+ const c = n[i];
1043
+ c != null && Object.assign(u, { [i]: c });
1044
+ }
1045
+ return u;
1046
+ }
1047
+ function yt(n, u) {
1048
+ const i = { ...n };
1049
+ for (const c of $e)
1050
+ Object.assign(i, { [c]: u[c] ?? null });
1051
+ return i;
1052
+ }
1053
+ const _t = { class: "wx-seo-rule" }, xt = { class: "wx-seo-rule__where" }, wt = /* @__PURE__ */ F({
1054
+ __name: "SeoUrlDialog",
1055
+ props: {
1056
+ rule: { default: null },
1057
+ mediaField: { default: void 0 }
1058
+ },
1059
+ setup(n) {
1060
+ const u = n, { resolve: i, dismiss: c, open: l } = ie(), d = P(), h = G(d);
1061
+ E();
1062
+ const o = M("webx-seo"), y = z(!1), k = z({}), p = z({
1063
+ match_type: "exact",
1064
+ pattern: "",
1065
+ priority: 0,
1066
+ is_active: !0
1067
+ }), _ = z({}), g = S(() => u.rule !== null), T = S(() => [
1068
+ { value: "exact", label: o("page.exact") },
1069
+ { value: "mask", label: o("page.mask") },
1070
+ { value: "regex", label: o("page.regex") }
1071
+ ]);
1072
+ ge(
1073
+ () => u.rule,
1074
+ (v) => {
1075
+ p.value = {
1076
+ match_type: v?.match_type ?? "exact",
1077
+ pattern: v?.pattern ?? "",
1078
+ priority: v?.priority ?? 0,
1079
+ is_active: v?.is_active ?? !0
1080
+ }, _.value = bt(v), k.value = {};
1081
+ },
1082
+ { immediate: !0 }
1083
+ );
1084
+ function D(v) {
1085
+ return k.value[v]?.[0];
1086
+ }
1087
+ async function $() {
1088
+ y.value = !0, k.value = {};
1089
+ const v = yt(p.value, _.value);
1090
+ try {
1091
+ const s = u.rule ? await h.updateUrl(u.rule.id, v) : await h.createUrl(v);
1092
+ B.success(o("page.saved")), i(s);
1093
+ } catch (s) {
1094
+ const r = s.body;
1095
+ r?.errors ? (k.value = r.errors, B.danger(o("page.failed"))) : B.danger(r?.message ?? o("page.failed"));
1096
+ } finally {
1097
+ y.value = !1;
1098
+ }
1099
+ }
1100
+ return (v, s) => (w(), W(e(de), {
1101
+ open: e(l),
1102
+ "onUpdate:open": s[6] || (s[6] = (r) => I(l) ? l.value = r : null),
1103
+ title: e(o)("page.rule"),
1104
+ width: 860
1105
+ }, {
1106
+ footer: t(() => [
1107
+ a(e(H), { size: "sm" }, {
1108
+ default: t(() => [
1109
+ a(e(A), {
1110
+ variant: "outline",
1111
+ onClick: s[5] || (s[5] = (r) => e(c)())
1112
+ }, {
1113
+ default: t(() => [
1114
+ b(m(e(o)("page.cancel")), 1)
1115
+ ]),
1116
+ _: 1
1117
+ }),
1118
+ a(e(A), {
1119
+ type: "primary",
1120
+ loading: y.value,
1121
+ onClick: $
1122
+ }, {
1123
+ default: t(() => [
1124
+ b(m(g.value ? e(o)("page.save") : e(o)("page.new-rule")), 1)
1125
+ ]),
1126
+ _: 1
1127
+ }, 8, ["loading"])
1128
+ ]),
1129
+ _: 1
1130
+ })
1131
+ ]),
1132
+ default: t(() => [
1133
+ O("div", _t, [
1134
+ O("div", xt, [
1135
+ a(e(U), {
1136
+ label: e(o)("page.kind")
1137
+ }, {
1138
+ default: t(() => [
1139
+ a(e(ee), {
1140
+ modelValue: p.value.match_type,
1141
+ "onUpdate:modelValue": s[0] || (s[0] = (r) => p.value.match_type = r),
1142
+ options: T.value
1143
+ }, null, 8, ["modelValue", "options"])
1144
+ ]),
1145
+ _: 1
1146
+ }, 8, ["label"]),
1147
+ a(e(U), {
1148
+ label: e(o)("page.address"),
1149
+ help: e(o)("page.address-help"),
1150
+ error: D("pattern"),
1151
+ class: "wx-seo-rule__address"
1152
+ }, {
1153
+ default: t(() => [
1154
+ a(e(N), {
1155
+ modelValue: p.value.pattern,
1156
+ "onUpdate:modelValue": s[1] || (s[1] = (r) => p.value.pattern = r),
1157
+ placeholder: "/catalog/shoes"
1158
+ }, null, 8, ["modelValue"])
1159
+ ]),
1160
+ _: 1
1161
+ }, 8, ["label", "help", "error"]),
1162
+ a(e(U), {
1163
+ label: e(o)("page.priority"),
1164
+ help: e(o)("page.priority-help")
1165
+ }, {
1166
+ default: t(() => [
1167
+ a(e(Me), {
1168
+ modelValue: p.value.priority,
1169
+ "onUpdate:modelValue": s[2] || (s[2] = (r) => p.value.priority = r),
1170
+ step: 10
1171
+ }, null, 8, ["modelValue"])
1172
+ ]),
1173
+ _: 1
1174
+ }, 8, ["label", "help"]),
1175
+ a(e(U), {
1176
+ label: e(o)("page.state")
1177
+ }, {
1178
+ default: t(() => [
1179
+ a(e(be), {
1180
+ modelValue: p.value.is_active,
1181
+ "onUpdate:modelValue": s[3] || (s[3] = (r) => p.value.is_active = r)
1182
+ }, null, 8, ["modelValue"])
1183
+ ]),
1184
+ _: 1
1185
+ }, 8, ["label"])
1186
+ ]),
1187
+ a(we, {
1188
+ modelValue: _.value,
1189
+ "onUpdate:modelValue": s[4] || (s[4] = (r) => _.value = r),
1190
+ "media-field": u.mediaField
1191
+ }, null, 8, ["modelValue", "media-field"])
1192
+ ])
1193
+ ]),
1194
+ _: 1
1195
+ }, 8, ["open", "title"]));
1196
+ }
1197
+ }), kt = /* @__PURE__ */ q(wt, [["__scopeId", "data-v-fd7826d1"]]), Vt = /* @__PURE__ */ F({
1198
+ __name: "SeoUrlsPage",
1199
+ props: {
1200
+ base: { default: "/seo" },
1201
+ mediaField: { default: void 0 }
1202
+ },
1203
+ setup(n) {
1204
+ const u = n, i = P(), c = G(i);
1205
+ E();
1206
+ const l = M("webx-seo"), d = z(null), h = z(!1), o = z("any");
1207
+ let y = { page: 1, perPage: 20, sort: null, search: "" };
1208
+ const k = i.can("seo.manage"), p = te(
1209
+ kt
1210
+ ), _ = te(Ve), g = S(() => [
1211
+ { value: "any", label: l("page.any-kind") },
1212
+ { value: "exact", label: l("page.exact") },
1213
+ { value: "mask", label: l("page.mask") },
1214
+ { value: "regex", label: l("page.regex") }
1215
+ ]), T = S(() => [
1216
+ { key: "pattern", label: l("page.address") },
1217
+ { key: "match_type", label: l("page.kind"), hideBelow: 560 },
1218
+ { key: "title", label: l("page.title"), hideBelow: 900 },
1219
+ { key: "priority", label: l("page.priority"), align: "center", hideBelow: 760 },
1220
+ { key: "is_active", label: l("page.state"), align: "center", hideBelow: 660 },
1221
+ {
1222
+ key: "actions",
1223
+ label: "",
1224
+ width: 56,
1225
+ align: "right",
1226
+ hidden: !k,
1227
+ hideOnCards: !0
1228
+ }
1229
+ ]);
1230
+ async function D(s) {
1231
+ y = s, h.value = !0;
1232
+ try {
1233
+ d.value = await c.urls({
1234
+ q: s.search,
1235
+ match_type: o.value === "any" ? null : o.value,
1236
+ page: s.page,
1237
+ per_page: s.perPage
1238
+ });
1239
+ } finally {
1240
+ h.value = !1;
1241
+ }
1242
+ }
1243
+ async function $(s) {
1244
+ await p({ rule: s, mediaField: u.mediaField }) && D(y);
1245
+ }
1246
+ async function v(s) {
1247
+ if (await xe({
1248
+ title: l("page.delete-title", { pattern: s.pattern }),
1249
+ message: l("page.delete-text"),
1250
+ confirmText: l("page.delete"),
1251
+ cancelText: l("page.cancel"),
1252
+ tone: "danger"
1253
+ }))
1254
+ try {
1255
+ await c.removeUrl(s.id), B.success(l("page.deleted")), D(y);
1256
+ } catch (V) {
1257
+ B.danger(V.body?.message ?? String(V));
1258
+ }
1259
+ }
1260
+ return (s, r) => (w(), W(ke, {
1261
+ base: u.base,
1262
+ current: "rules",
1263
+ onTest: r[5] || (r[5] = (V) => e(_)({}))
1264
+ }, {
1265
+ default: t(() => [
1266
+ a(e(ye), null, fe({
1267
+ header: t(() => [
1268
+ b(m(e(l)("page.rules")), 1)
1269
+ ]),
1270
+ default: t(() => [
1271
+ a(e(_e), {
1272
+ data: d.value,
1273
+ columns: T.value,
1274
+ "row-key": "id",
1275
+ searchable: "",
1276
+ hover: "",
1277
+ flush: "",
1278
+ loading: h.value,
1279
+ "search-placeholder": e(l)("page.search-rules"),
1280
+ "empty-text": e(l)("page.empty"),
1281
+ onStateChange: D,
1282
+ onRowClick: r[4] || (r[4] = (V) => e(k) ? $(V) : void 0)
1283
+ }, {
1284
+ actions: t(() => [
1285
+ a(e(ee), {
1286
+ modelValue: o.value,
1287
+ "onUpdate:modelValue": r[1] || (r[1] = (V) => o.value = V),
1288
+ options: g.value,
1289
+ class: "wx-seo-urls__kind"
1290
+ }, null, 8, ["modelValue", "options"])
1291
+ ]),
1292
+ "cell-pattern": t(({ row: V }) => [
1293
+ a(e(R), {
1294
+ mono: "",
1295
+ size: "sm"
1296
+ }, {
1297
+ default: t(() => [
1298
+ b(m(V.pattern), 1)
1299
+ ]),
1300
+ _: 2
1301
+ }, 1024)
1302
+ ]),
1303
+ "cell-match_type": t(({ row: V }) => [
1304
+ a(e(J), null, {
1305
+ default: t(() => [
1306
+ b(m(e(l)(`page.${V.match_type}`)), 1)
1307
+ ]),
1308
+ _: 2
1309
+ }, 1024)
1310
+ ]),
1311
+ "cell-title": t(({ row: V }) => [
1312
+ e(me)(V) ? (w(), W(e(R), {
1313
+ key: 0,
1314
+ size: "sm"
1315
+ }, {
1316
+ default: t(() => [
1317
+ b(m(e(me)(V)), 1)
1318
+ ]),
1319
+ _: 2
1320
+ }, 1024)) : (w(), W(e(R), {
1321
+ key: 1,
1322
+ size: "sm",
1323
+ tone: "muted"
1324
+ }, {
1325
+ default: t(() => [...r[6] || (r[6] = [
1326
+ b("—", -1)
1327
+ ])]),
1328
+ _: 1
1329
+ }))
1330
+ ]),
1331
+ "cell-is_active": t(({ row: V }) => [
1332
+ a(e(J), {
1333
+ type: V.is_active ? "success" : "default",
1334
+ dot: ""
1335
+ }, {
1336
+ default: t(() => [
1337
+ b(m(V.is_active ? e(l)("page.active") : e(l)("page.inactive")), 1)
1338
+ ]),
1339
+ _: 2
1340
+ }, 1032, ["type"])
1341
+ ]),
1342
+ "card-actions": t(({ row: V }) => [
1343
+ e(k) ? (w(), W(e(ae), {
1344
+ key: 0,
1345
+ size: "sm",
1346
+ onClick: r[2] || (r[2] = Z(() => {
1347
+ }, ["stop"]))
1348
+ }, {
1349
+ default: t(() => [
1350
+ a(e(le), {
1351
+ type: "remove",
1352
+ title: e(l)("page.delete"),
1353
+ onClick: (Q) => v(V)
1354
+ }, null, 8, ["title", "onClick"])
1355
+ ]),
1356
+ _: 2
1357
+ }, 1024)) : j("", !0)
1358
+ ]),
1359
+ "cell-actions": t(({ row: V }) => [
1360
+ a(e(ae), {
1361
+ size: "sm",
1362
+ onClick: r[3] || (r[3] = Z(() => {
1363
+ }, ["stop"]))
1364
+ }, {
1365
+ default: t(() => [
1366
+ a(e(le), {
1367
+ type: "remove",
1368
+ title: e(l)("page.delete"),
1369
+ onClick: (Q) => v(V)
1370
+ }, null, 8, ["title", "onClick"])
1371
+ ]),
1372
+ _: 2
1373
+ }, 1024)
1374
+ ]),
1375
+ _: 1
1376
+ }, 8, ["data", "columns", "loading", "search-placeholder", "empty-text"])
1377
+ ]),
1378
+ _: 2
1379
+ }, [
1380
+ e(k) ? {
1381
+ name: "extra",
1382
+ fn: t(() => [
1383
+ a(e(A), {
1384
+ type: "primary",
1385
+ icon: "add",
1386
+ onClick: r[0] || (r[0] = (V) => $(null))
1387
+ }, {
1388
+ default: t(() => [
1389
+ b(m(e(l)("page.new-rule")), 1)
1390
+ ]),
1391
+ _: 1
1392
+ })
1393
+ ]),
1394
+ key: "0"
1395
+ } : void 0
1396
+ ]), 1024)
1397
+ ]),
1398
+ _: 1
1399
+ }, 8, ["base"]));
1400
+ }
1401
+ }), $t = /* @__PURE__ */ q(Vt, [["__scopeId", "data-v-d9fce714"]]);
1402
+ function zt(n = {}) {
1403
+ const u = n.path ?? "/seo", i = n.mediaField ? Oe(n.mediaField) : void 0;
1404
+ return {
1405
+ id: "seo",
1406
+ path: u,
1407
+ routes: [
1408
+ // The section's own path travels as a prop, so a panel that mounted it somewhere else
1409
+ // still links between its two screens correctly.
1410
+ {
1411
+ path: u,
1412
+ name: "webx.seo",
1413
+ component: $t,
1414
+ props: { base: u, mediaField: i }
1415
+ },
1416
+ {
1417
+ path: `${u}/redirects`,
1418
+ name: "webx.seo.redirects",
1419
+ component: ht,
1420
+ props: { base: u }
1421
+ }
1422
+ ],
1423
+ // What a screen means by `wx-seo`: everything a page says about itself, as one value. The
1424
+ // server registers the same name for what it stores.
1425
+ types: {
1426
+ "wx-seo": {
1427
+ component: we,
1428
+ kind: "field",
1429
+ bind: () => ({ mediaField: i })
1430
+ }
1431
+ }
1432
+ };
1433
+ }
1434
+ export {
1435
+ we as WxSeo,
1436
+ ht as WxSeoRedirectsPage,
1437
+ $t as WxSeoUrlsPage,
1438
+ G as createSeoApi,
1439
+ ne as robotsDirectives,
1440
+ yt as ruleInput,
1441
+ me as ruleTitle,
1442
+ zt as seo,
1443
+ He as seoMessages,
1444
+ bt as seoOf
1445
+ };
1446
+ //# sourceMappingURL=index.js.map