@webx-ui/module-audit 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,3279 @@
1
+ import { defineComponent as se, ref as S, onMounted as ge, openBlock as t, createElementBlock as b, createBlock as u, unref as e, withCtx as a, createTextVNode as n, toDisplayString as s, Fragment as F, createVNode as g, renderList as M, createCommentVNode as C, computed as L, renderSlot as Xe, watch as re, createElementVNode as W, useModel as Ee, mergeModels as Se, normalizeClass as Be, withModifiers as Ye, onBeforeUnmount as He, createSlots as Ze } from "vue";
2
+ import { useAdmin as le, useTranslate as ee, useErrorText as ue, WxListScreen as et, WxDate as ke, useDates as tt, WxScreen as at } from "@webx-ui/module-admin";
3
+ import { WxText as O, WxSkeleton as fe, WxLink as xe, WxBadge as B, WxButton as Q, WxTable as ve, WxSelect as ce, toast as Y, WxDialog as Me, WxFormItem as Ne, WxInput as Je, WxTextarea as st, WxPopover as Ge, WxCard as de, WxAlert as me, WxProgress as je, WxSegmented as Ke, WxEmpty as Te, WxStatistic as Oe, WxDrawer as lt, WxTabs as nt, WxImage as it, WxCheckboxGroup as ut, WxActionBar as ot } from "@webx-ui/core";
4
+ import { useRouter as we, useRoute as Qe } from "vue-router";
5
+ function Re(k) {
6
+ const v = {
7
+ search: k.search || void 0,
8
+ status: k.status || void 0,
9
+ indexable: k.indexable === null || k.indexable === void 0 ? void 0 : k.indexable ? 1 : 0,
10
+ check: k.check || void 0,
11
+ sort: k.sort || void 0,
12
+ page: k.page,
13
+ per_page: k.per_page
14
+ };
15
+ for (const c of k.filters ?? [])
16
+ v[`f[${c.field}]`] = c.value === void 0 || c.value === "" ? c.op : `${c.op}:${c.value}`;
17
+ return v;
18
+ }
19
+ function oe(k) {
20
+ const v = `${k.apiPath}/audit`, c = (l) => l.data, o = (l) => ({
21
+ check: l.check || void 0,
22
+ severity: l.severity || void 0,
23
+ group: l.group || void 0,
24
+ state: l.state || void 0,
25
+ page: l.page,
26
+ per_page: l.per_page
27
+ });
28
+ return {
29
+ latest: () => k.http.get(`${v}/runs/latest`).then(c),
30
+ run: (l) => k.http.get(`${v}/runs/${l}`).then(c),
31
+ runs: (l = {}) => k.http.get(`${v}/runs`, { query: l }).then((r) => ({ ...r.meta, data: r.data })),
32
+ start: (l, r) => k.http.post(`${v}/runs`, l === "urls" ? { scope: l, urls: r } : { scope: l }).then(c),
33
+ cancel: (l) => k.http.post(`${v}/runs/${l}/cancel`, {}).then(c),
34
+ checks: (l, r = {}) => k.http.get(`${v}/runs/${l}/checks`, { query: o(r) }).then(c),
35
+ issues: (l, r = {}) => k.http.get(`${v}/runs/${l}/issues`, { query: o(r) }).then((d) => ({ ...d.meta, data: d.data })),
36
+ pages: (l, r = {}) => k.http.get(`${v}/runs/${l}/pages`, { query: Re(r) }).then((d) => ({ ...d.meta, data: d.data })),
37
+ pagesFile: (l, r, d) => {
38
+ const h = new URLSearchParams();
39
+ for (const [m, f] of Object.entries({
40
+ ...Re(r),
41
+ page: void 0,
42
+ per_page: void 0
43
+ }))
44
+ f !== void 0 && h.set(m, String(f));
45
+ return h.set("columns", d.join(",")), `${v}/runs/${l}/pages/export?${h.toString()}`;
46
+ },
47
+ page: (l, r) => k.http.get(`${v}/runs/${l}/pages/${r}`).then(c),
48
+ links: (l, r, d = {}) => k.http.get(`${v}/runs/${l}/pages/${r}/links`, { query: d }).then((h) => ({ ...h.meta, data: h.data })),
49
+ resources: (l, r, d) => k.http.get(`${v}/runs/${l}/pages/${r}/resources`, { query: d }).then((h) => ({ ...h.meta, data: h.data })),
50
+ fixes: (l, r) => k.http.get(`${v}/runs/${l}/issues/${r}/fixes`).then(c),
51
+ fix: (l, r, d, h = !1) => k.http.post(`${v}/runs/${l}/issues/${r}/fixes/${encodeURIComponent(d)}`, {
52
+ dry_run: h
53
+ }).then(c),
54
+ pageFile: (l, r) => `${v}/runs/${l}/pages/${r}/export`,
55
+ compare: (l, r) => k.http.get(`${v}/runs/compare`, { query: { to: l, from: r ?? void 0 } }).then(c),
56
+ compareIssues: (l) => k.http.get(`${v}/runs/compare/issues`, {
57
+ query: { ...l, from: l.from ?? void 0, check: l.check || void 0 }
58
+ }).then((r) => ({ ...r.meta, data: r.data })),
59
+ hosts: (l = {}) => k.http.get(`${v}/hosts`, {
60
+ query: {
61
+ class: l.class || void 0,
62
+ search: l.search || void 0,
63
+ host: l.host || void 0
64
+ }
65
+ }).then(c),
66
+ ignores: () => k.http.get(`${v}/ignores`).then(c),
67
+ hide: (l) => k.http.post(`${v}/ignores`, l).then(c),
68
+ hidePreview: (l) => k.http.post(`${v}/ignores`, { ...l, dry_run: !0 }).then((r) => r.data.hidden),
69
+ unhide: (l) => k.http.delete(`${v}/ignores/${l}`).then(() => {
70
+ }),
71
+ settings: () => k.http.get(`${v}/settings`).then((l) => l.data.values),
72
+ saveSettings: (l) => k.http.put(`${v}/settings`, { values: l }).then((r) => r.data.values)
73
+ };
74
+ }
75
+ const rt = {
76
+ module: {
77
+ title: "Audit"
78
+ },
79
+ page: {
80
+ overview: "Overview",
81
+ issues: "Findings",
82
+ settings: "Settings",
83
+ run: "Run the audit",
84
+ scope: "Scope",
85
+ "scope-full": "Full",
86
+ "scope-full-help": "Everything the audit can check.",
87
+ "scope-quick": "Quick",
88
+ "scope-quick-help": "The config, the host and the database — takes seconds.",
89
+ start: "Start",
90
+ started: "The audit has started.",
91
+ cancel: "Cancel the run",
92
+ never: "No audit has been run yet.",
93
+ "never-help": "Run the first one to see how the site looks to a visitor and to a search engine.",
94
+ health: "Health",
95
+ errors: "Errors",
96
+ warnings: "Warnings",
97
+ notices: "Notices",
98
+ new: "New",
99
+ fixed: "Fixed",
100
+ "last-run": "Last run",
101
+ "base-url": "Address",
102
+ "status-queued": "Waiting in the queue",
103
+ "status-running": "Running",
104
+ "status-done": "Done",
105
+ "status-failed": "Failed",
106
+ "status-cancelled": "Cancelled",
107
+ "stage-probes": "Config and host",
108
+ "stage-database": "Database",
109
+ "stage-crawl": "Pages",
110
+ "stage-analyse": "Analysis",
111
+ "last-failed": "The last run did not finish: :error",
112
+ "by-group": "By group",
113
+ "group-config": "Configuration",
114
+ "group-host": "Host and addresses",
115
+ "group-hosts": "Outgoing addresses",
116
+ "group-other": "Other",
117
+ sources: "Content searched",
118
+ "sources-missing": "Installed, but not searched:",
119
+ "sync-queue": "The queue runs jobs inside the request (sync), so the panel cannot start a run. Run php artisan webx:audit:run from the terminal or cron.",
120
+ "already-running": "An audit is already running.",
121
+ check: "Check",
122
+ count: "Found",
123
+ severity: "Severity",
124
+ "severity-error": "Error",
125
+ "severity-warning": "Warning",
126
+ "severity-notice": "Notice",
127
+ "any-severity": "Any severity",
128
+ "any-group": "Any group",
129
+ "any-state": "New and persisting",
130
+ "state-new": "New",
131
+ "state-persisting": "Persisting",
132
+ address: "Address",
133
+ empty: "Nothing found.",
134
+ clean: "The last run found nothing.",
135
+ found: "What was found",
136
+ why: "Why it matters",
137
+ fix: "How to fix it",
138
+ explain: "What this check means",
139
+ "open-editor": "Open in the editor",
140
+ "fix-button": "Fix",
141
+ "fix-apply": "Apply",
142
+ "fix-applied": "Done. Run the audit again to see the finding go.",
143
+ "fix-none": "Nothing left to change: no fix can close this finding now.",
144
+ "fix-pressed": "Fixed — waiting for the next run",
145
+ "fix-changes": "Changes",
146
+ "fix-before": "Now",
147
+ "fix-after": "After",
148
+ yes: "Yes",
149
+ no: "No",
150
+ missing: "Missing",
151
+ pages: "Pages",
152
+ "pages-progress": "Pages crawled: :crawled of at most :limit",
153
+ "resources-progress": "Pictures, styles, scripts and external links checked: :checked of :total",
154
+ "pages-none": "No full run has crawled the site yet. Start a full audit to see every page.",
155
+ "pages-run": "Full run of :date",
156
+ "group-indexing": "Indexing",
157
+ "group-redirects": "Redirects",
158
+ "group-page": "Page",
159
+ "group-content": "Content and speed",
160
+ "group-links": "Links",
161
+ "group-images": "Pictures",
162
+ "group-a11y": "Accessibility",
163
+ "group-structure": "Structure",
164
+ columns: "Columns",
165
+ export: "Export CSV",
166
+ "search-url": "Search by address",
167
+ "any-status": "Any answer",
168
+ "status-none": "No answer",
169
+ "any-indexable": "Indexable or not",
170
+ "indexable-yes": "Indexable",
171
+ "indexable-no": "Not indexable",
172
+ "any-check": "With any findings or none",
173
+ "add-filter": "Add a filter",
174
+ "remove-filter": "Remove the filter",
175
+ "op-contains": "contains",
176
+ "op-eq": "is",
177
+ "op-empty": "is empty",
178
+ "op-filled": "is not empty",
179
+ "op-gt": "more than",
180
+ "op-lt": "less than",
181
+ "op-yes": "yes",
182
+ "op-no": "no",
183
+ value: "Value",
184
+ "field-url": "Address",
185
+ "field-status": "Code",
186
+ "field-final_status": "Final code",
187
+ "field-redirect_to": "Redirects to",
188
+ "field-source": "Found through",
189
+ "field-depth": "Depth",
190
+ "field-indexable": "Indexable",
191
+ "field-issues": "Findings",
192
+ "field-title": "Title",
193
+ "field-description": "Description",
194
+ "field-h1": "H1",
195
+ "field-canonical": "Canonical",
196
+ "field-robots_meta": "Meta robots",
197
+ "field-x_robots_tag": "X-Robots-Tag",
198
+ "field-lang": "Language",
199
+ "field-content_type": "Content type",
200
+ "field-bytes": "Size, bytes",
201
+ "field-ttfb_ms": "First byte, ms",
202
+ "field-total_ms": "Answer, ms",
203
+ "field-compression": "Compression",
204
+ "field-word_count": "Words",
205
+ "field-links_in": "Links in",
206
+ "field-links_out_internal": "Internal links out",
207
+ "field-links_out_external": "External links out",
208
+ "field-images": "Pictures",
209
+ "field-images_without_alt": "Pictures without alt",
210
+ "field-in_sitemap": "In the sitemap",
211
+ "field-in_registry": "In the registry",
212
+ "field-blocked_by_robots": "Closed in robots.txt",
213
+ "source-home": "Home page",
214
+ "source-sitemap": "Sitemap",
215
+ "source-registry": "Address registry",
216
+ "source-link": "Link",
217
+ "card-overview": "Overview",
218
+ "card-issues": "Problems",
219
+ "card-incoming": "Incoming",
220
+ "card-outgoing": "Outgoing",
221
+ "card-images": "Pictures",
222
+ "card-css": "CSS",
223
+ "card-js": "JS",
224
+ "card-microdata": "Structured data",
225
+ response: "Response",
226
+ headers: "Headers",
227
+ markup: "Markup",
228
+ "open-page": "Open the page",
229
+ "no-issues": "No problems on this page.",
230
+ "no-links": "No links.",
231
+ kind: "Kind",
232
+ anchor: "Anchor",
233
+ host: "Host",
234
+ size: "Size",
235
+ cache: "Cache",
236
+ alt: "Alt",
237
+ "not-checked": "Not checked",
238
+ "no-resources": "Nothing of this kind on the page.",
239
+ "no-json-ld": "The page has no structured data.",
240
+ "jsonld-block": "Block :number",
241
+ "jsonld-error": "Does not parse:",
242
+ "jsonld-required": "Required fields missing:",
243
+ "jsonld-recommended": "Recommended fields missing:",
244
+ "jsonld-complete": "Every field search engines ask for is there.",
245
+ "host-own": "Own",
246
+ "host-own_mirror": "Other mirror",
247
+ "host-dev": "Stand",
248
+ "host-external": "External",
249
+ error: "Error",
250
+ "source-list": "Recheck list",
251
+ hosts: "Outgoing",
252
+ runs: "Runs",
253
+ "scope-urls": "Recheck",
254
+ "urls-foreign": "None of these addresses is on the audited site.",
255
+ "state-hidden": "Hidden",
256
+ hide: "Hide",
257
+ "hide-title": "Hide this finding",
258
+ "hide-help": "Hidden findings stop counting, in this run and in every later one. Nothing is deleted: the hidden list shows them again.",
259
+ "hide-pattern": "Addresses",
260
+ "hide-pattern-help": "This address, or a mask of them: * is a stretch without a slash, ** one with slashes (/search/**). Empty hides every finding of the check.",
261
+ "hide-reason": "Why it is all right",
262
+ "hide-count": "Findings of the last run it would hide: :count",
263
+ "hidden-done": "Hidden.",
264
+ "hidden-reason": "Hidden: :reason",
265
+ "hidden-by": "Hidden by :who: :reason",
266
+ unhide: "Show again",
267
+ unhidden: "Shown again.",
268
+ recheck: "Recheck",
269
+ "recheck-running": "Rechecking the page…",
270
+ "recheck-fixed": "Fixed since the last full run: :count",
271
+ "recheck-new": "New since the last full run: :count",
272
+ "recheck-compare": "Compare the runs",
273
+ "export-page": "Export",
274
+ "runs-empty": "No runs yet.",
275
+ "run-id": "Run",
276
+ status: "Status",
277
+ "started-at": "Started",
278
+ "started-by": "Started by",
279
+ "by-schedule": "Schedule",
280
+ "by-mcp": "Agent",
281
+ "by-console": "Console",
282
+ "by-person": "Administrator",
283
+ compare: "Compare",
284
+ "compare-help": "Pick two runs: what the later one found that the earlier did not, what both found, and what is gone.",
285
+ "compare-from": "Earlier run",
286
+ "compare-to": "Later run",
287
+ "compare-none": "Both runs found the same.",
288
+ "compare-scopes": "The runs differ in scope: only the checks the later run ran can count as fixed.",
289
+ "kind-new": "New",
290
+ "kind-persisting": "Persisting",
291
+ "kind-fixed": "Fixed",
292
+ "hosts-empty": "No run has seen a link or an address in the database yet.",
293
+ "search-host": "Search by host",
294
+ "any-class": "Any class",
295
+ links: "Links",
296
+ fields: "Fields in the database",
297
+ broken: "Broken",
298
+ "first-seen": "First seen",
299
+ "host-pages": "On pages",
300
+ "host-fields": "In the database",
301
+ record: "Record",
302
+ field: "Field",
303
+ unpublished: "Not published",
304
+ save: "Save",
305
+ saved: "Saved.",
306
+ dismiss: "Cancel",
307
+ "view-full": "View full size"
308
+ }
309
+ }, Fe = /* @__PURE__ */ new WeakSet();
310
+ function ne() {
311
+ try {
312
+ const { i18n: k } = le();
313
+ Fe.has(k) || (k.defaults("webx-audit", rt), Fe.add(k));
314
+ } catch {
315
+ }
316
+ }
317
+ const dt = { class: "wx-audit-places" }, ct = {
318
+ key: 0,
319
+ class: "wx-audit-places__group"
320
+ }, pt = {
321
+ key: 1,
322
+ class: "wx-audit-places__group"
323
+ }, gt = /* @__PURE__ */ se({
324
+ __name: "AuditHostPlaces",
325
+ props: {
326
+ host: {}
327
+ },
328
+ setup(k) {
329
+ const v = k, c = oe(le());
330
+ ne();
331
+ const o = ee("webx-audit"), l = ue(), r = we(), d = S(null), h = S(null);
332
+ return ge(async () => {
333
+ try {
334
+ d.value = await c.hosts({ host: v.host });
335
+ } catch (m) {
336
+ h.value = l(m);
337
+ }
338
+ }), (m, f) => (t(), b("div", dt, [
339
+ h.value ? (t(), u(e(O), {
340
+ key: 0,
341
+ size: "sm",
342
+ tone: "danger"
343
+ }, {
344
+ default: a(() => [
345
+ n(s(h.value), 1)
346
+ ]),
347
+ _: 1
348
+ })) : d.value ? (t(), b(F, { key: 2 }, [
349
+ d.value.pages?.length ? (t(), b("section", ct, [
350
+ g(e(O), {
351
+ size: "sm",
352
+ weight: "semibold"
353
+ }, {
354
+ default: a(() => [
355
+ n(s(e(o)("page.host-pages")), 1)
356
+ ]),
357
+ _: 1
358
+ }),
359
+ (t(!0), b(F, null, M(d.value.pages, (p, P) => (t(), b("div", {
360
+ key: P,
361
+ class: "wx-audit-places__row"
362
+ }, [
363
+ g(e(xe), {
364
+ href: p.page,
365
+ target: "_blank",
366
+ class: "wx-audit-places__url"
367
+ }, {
368
+ default: a(() => [
369
+ n(s(p.page), 1)
370
+ ]),
371
+ _: 2
372
+ }, 1032, ["href"]),
373
+ g(e(O), {
374
+ size: "sm",
375
+ tone: "muted",
376
+ class: "wx-audit-places__url"
377
+ }, {
378
+ default: a(() => [
379
+ n(s(p.kind) + " → " + s(p.url), 1)
380
+ ]),
381
+ _: 2
382
+ }, 1024),
383
+ p.anchor ? (t(), u(e(O), {
384
+ key: 0,
385
+ size: "sm"
386
+ }, {
387
+ default: a(() => [
388
+ n("«" + s(p.anchor) + "»", 1)
389
+ ]),
390
+ _: 2
391
+ }, 1024)) : C("", !0),
392
+ p.status && p.status >= 400 ? (t(), u(e(B), {
393
+ key: 1,
394
+ type: "danger",
395
+ size: "sm"
396
+ }, {
397
+ default: a(() => [
398
+ n(s(p.status), 1)
399
+ ]),
400
+ _: 2
401
+ }, 1024)) : C("", !0)
402
+ ]))), 128))
403
+ ])) : C("", !0),
404
+ d.value.fields?.length ? (t(), b("section", pt, [
405
+ g(e(O), {
406
+ size: "sm",
407
+ weight: "semibold"
408
+ }, {
409
+ default: a(() => [
410
+ n(s(e(o)("page.host-fields")), 1)
411
+ ]),
412
+ _: 1
413
+ }),
414
+ (t(!0), b(F, null, M(d.value.fields, (p, P) => (t(), b("div", {
415
+ key: P,
416
+ class: "wx-audit-places__row"
417
+ }, [
418
+ g(e(O), { size: "sm" }, {
419
+ default: a(() => [
420
+ n(s(p.record_label), 1)
421
+ ]),
422
+ _: 2
423
+ }, 1024),
424
+ g(e(O), {
425
+ size: "sm",
426
+ tone: "muted"
427
+ }, {
428
+ default: a(() => [
429
+ n(s(p.source) + " · " + s(p.field) + s(p.locale ? ` · ${p.locale}` : ""), 1)
430
+ ]),
431
+ _: 2
432
+ }, 1024),
433
+ p.published ? C("", !0) : (t(), u(e(B), {
434
+ key: 0,
435
+ size: "sm"
436
+ }, {
437
+ default: a(() => [
438
+ n(s(e(o)("page.unpublished")), 1)
439
+ ]),
440
+ _: 1
441
+ })),
442
+ g(e(O), {
443
+ size: "sm",
444
+ tone: "muted",
445
+ class: "wx-audit-places__url"
446
+ }, {
447
+ default: a(() => [
448
+ n(s(p.url), 1)
449
+ ]),
450
+ _: 2
451
+ }, 1024),
452
+ p.edit_url ? (t(), u(e(Q), {
453
+ key: 1,
454
+ size: "sm",
455
+ variant: "text",
456
+ icon: "edit",
457
+ onClick: (A) => e(r).push(p.edit_url)
458
+ }, {
459
+ default: a(() => [
460
+ n(s(e(o)("page.open-editor")), 1)
461
+ ]),
462
+ _: 1
463
+ }, 8, ["onClick"])) : C("", !0)
464
+ ]))), 128))
465
+ ])) : C("", !0)
466
+ ], 64)) : (t(), u(e(fe), {
467
+ key: 1,
468
+ rows: 2
469
+ }))
470
+ ]));
471
+ }
472
+ }), ie = (k, v) => {
473
+ const c = k.__vccOpts || k;
474
+ for (const [o, l] of v)
475
+ c[o] = l;
476
+ return c;
477
+ }, vt = /* @__PURE__ */ ie(gt, [["__scopeId", "data-v-1b5ca599"]]), _e = /* @__PURE__ */ se({
478
+ __name: "AuditLayout",
479
+ props: {
480
+ base: {},
481
+ current: {},
482
+ card: { type: Boolean, default: !0 }
483
+ },
484
+ setup(k) {
485
+ const v = k, c = le(), o = we(), l = Qe();
486
+ ne();
487
+ const r = ee("webx-audit"), d = L(
488
+ () => c.state.manifest?.modules.find((p) => p.id === "audit")?.title ?? r("module.title")
489
+ ), h = L(() => [
490
+ { value: "overview", label: r("page.overview") },
491
+ { value: "issues", label: r("page.issues") },
492
+ { value: "pages", label: r("page.pages") },
493
+ { value: "hosts", label: r("page.hosts") },
494
+ { value: "runs", label: r("page.runs") }
495
+ ]), m = L(
496
+ () => v.current === "settings" ? [] : [
497
+ {
498
+ key: "settings",
499
+ label: r("page.settings"),
500
+ icon: "settings",
501
+ run: () => {
502
+ o.push(`${v.base}/settings`);
503
+ }
504
+ }
505
+ ]
506
+ ), f = L({
507
+ /* The settings belong to no tab; the overview's stays lit as the way back. */
508
+ get: () => v.current === "settings" ? "overview" : v.current,
509
+ set: (p) => {
510
+ const P = p === "overview" ? v.base : `${v.base}/${String(p)}`;
511
+ P !== l.path && o.push(P);
512
+ }
513
+ });
514
+ return (p, P) => (t(), u(e(et), {
515
+ view: f.value,
516
+ "onUpdate:view": P[0] || (P[0] = (A) => f.value = A),
517
+ title: d.value,
518
+ views: h.value,
519
+ actions: m.value,
520
+ card: v.card
521
+ }, {
522
+ default: a(() => [
523
+ Xe(p.$slots, "default")
524
+ ]),
525
+ _: 3
526
+ }, 8, ["view", "title", "views", "actions", "card"]));
527
+ }
528
+ }), ft = { class: "wx-audit-hosts__host" }, ht = /* @__PURE__ */ se({
529
+ __name: "AuditHostsPage",
530
+ props: {
531
+ base: {}
532
+ },
533
+ setup(k) {
534
+ const v = k, c = oe(le());
535
+ ne();
536
+ const o = ee("webx-audit"), l = ee("webx-admin"), r = ue(), d = S(null), h = S(!1), m = S(""), f = S(null), p = S([]), P = {
537
+ dev: "danger",
538
+ own_mirror: "warning",
539
+ external: "info",
540
+ own: "success"
541
+ }, A = L(() => [
542
+ { key: "host", label: o("page.host"), minWidth: 220 },
543
+ { key: "links", label: o("page.links"), width: 90, align: "right" },
544
+ { key: "pages", label: o("page.pages"), width: 90, align: "right", hideBelow: 560 },
545
+ { key: "broken", label: o("page.broken"), width: 100, align: "right", hideBelow: 640 },
546
+ { key: "fields", label: o("page.fields"), width: 120, align: "right" },
547
+ { key: "first_seen", label: o("page.first-seen"), minWidth: 140, hideBelow: 760 }
548
+ ]), U = L(
549
+ () => Object.keys(P).map((w) => ({
550
+ value: w,
551
+ label: `${o(`page.host-${w}`)}${d.value?.classes[w] ? ` · ${d.value.classes[w]}` : ""}`
552
+ }))
553
+ );
554
+ function i(w) {
555
+ return typeof w == "string" && w in P ? w : null;
556
+ }
557
+ async function N() {
558
+ h.value = !0;
559
+ try {
560
+ d.value = await c.hosts({ class: f.value, search: m.value }), p.value = [];
561
+ } catch (w) {
562
+ Y.danger(r(w));
563
+ } finally {
564
+ h.value = !1;
565
+ }
566
+ }
567
+ return re([f, m], () => {
568
+ N();
569
+ }), ge(N), (w, j) => (t(), u(_e, {
570
+ base: v.base,
571
+ current: "hosts"
572
+ }, {
573
+ default: a(() => [
574
+ g(e(ve), {
575
+ expanded: p.value,
576
+ "onUpdate:expanded": j[1] || (j[1] = (_) => p.value = _),
577
+ search: m.value,
578
+ "onUpdate:search": j[2] || (j[2] = (_) => m.value = _),
579
+ data: d.value?.hosts ?? [],
580
+ columns: A.value,
581
+ "row-key": "host",
582
+ expandable: "",
583
+ flush: "",
584
+ searchable: "",
585
+ "search-placeholder": e(o)("page.search-host"),
586
+ loading: h.value,
587
+ "filters-count": f.value ? 1 : 0,
588
+ "filters-label": e(l)("filters.title"),
589
+ "row-class": (_) => _.class === "dev" ? "is-stand" : void 0,
590
+ "empty-text": e(o)("page.hosts-empty")
591
+ }, {
592
+ filters: a(() => [
593
+ g(e(ce), {
594
+ "model-value": f.value,
595
+ options: U.value,
596
+ placeholder: e(o)("page.any-class"),
597
+ clearable: "",
598
+ "onUpdate:modelValue": j[0] || (j[0] = (_) => f.value = i(_))
599
+ }, null, 8, ["model-value", "options", "placeholder"])
600
+ ]),
601
+ "cell-host": a(({ row: _ }) => [
602
+ W("span", ft, [
603
+ g(e(B), {
604
+ type: P[_.class],
605
+ size: "sm"
606
+ }, {
607
+ default: a(() => [
608
+ n(s(e(o)(`page.host-${_.class}`)), 1)
609
+ ]),
610
+ _: 2
611
+ }, 1032, ["type"]),
612
+ g(e(O), {
613
+ size: "sm",
614
+ tone: _.class === "dev" ? "danger" : void 0,
615
+ weight: "medium"
616
+ }, {
617
+ default: a(() => [
618
+ n(s(_.host), 1)
619
+ ]),
620
+ _: 2
621
+ }, 1032, ["tone"])
622
+ ])
623
+ ]),
624
+ "cell-broken": a(({ row: _ }) => [
625
+ g(e(O), {
626
+ size: "sm",
627
+ tone: _.broken ? "danger" : "muted"
628
+ }, {
629
+ default: a(() => [
630
+ n(s(_.broken), 1)
631
+ ]),
632
+ _: 2
633
+ }, 1032, ["tone"])
634
+ ]),
635
+ "cell-fields": a(({ row: _ }) => [
636
+ g(e(O), {
637
+ size: "sm",
638
+ tone: _.fields && _.class === "dev" ? "danger" : void 0
639
+ }, {
640
+ default: a(() => [
641
+ n(s(_.fields), 1)
642
+ ]),
643
+ _: 2
644
+ }, 1032, ["tone"])
645
+ ]),
646
+ "cell-first_seen": a(({ row: _ }) => [
647
+ _.first_seen ? (t(), u(e(ke), {
648
+ key: 0,
649
+ value: _.first_seen
650
+ }, null, 8, ["value"])) : C("", !0)
651
+ ]),
652
+ expanded: a(({ row: _ }) => [
653
+ g(vt, {
654
+ host: _.host
655
+ }, null, 8, ["host"])
656
+ ]),
657
+ _: 1
658
+ }, 8, ["expanded", "search", "data", "columns", "search-placeholder", "loading", "filters-count", "filters-label", "row-class", "empty-text"])
659
+ ]),
660
+ _: 1
661
+ }, 8, ["base"]));
662
+ }
663
+ }), mt = /* @__PURE__ */ ie(ht, [["__scopeId", "data-v-44b7e64a"]]), _t = { class: "wx-audit-details" }, yt = {
664
+ key: 1,
665
+ class: "wx-audit-details__scroll"
666
+ }, bt = { class: "wx-audit-details__table" }, kt = /* @__PURE__ */ se({
667
+ __name: "AuditDetails",
668
+ props: {
669
+ details: {}
670
+ },
671
+ setup(k) {
672
+ const v = k, c = we();
673
+ ne();
674
+ const o = ee("webx-audit");
675
+ function l(m) {
676
+ const f = Number(m);
677
+ return f >= 500 || f === 0 ? "danger" : f >= 400 ? "warning" : f >= 300 ? "info" : "success";
678
+ }
679
+ function r(m, f) {
680
+ return m[f.key];
681
+ }
682
+ function d(m) {
683
+ return m == null ? "" : o(m ? "page.yes" : "page.no");
684
+ }
685
+ function h(m) {
686
+ return m == null ? "" : String(m);
687
+ }
688
+ return (m, f) => (t(), b("div", _t, [
689
+ v.details.summary ? (t(), u(e(O), {
690
+ key: 0,
691
+ size: "sm"
692
+ }, {
693
+ default: a(() => [
694
+ n(s(v.details.summary), 1)
695
+ ]),
696
+ _: 1
697
+ })) : C("", !0),
698
+ v.details.table && v.details.table.rows.length ? (t(), b("div", yt, [
699
+ W("table", bt, [
700
+ W("thead", null, [
701
+ W("tr", null, [
702
+ (t(!0), b(F, null, M(v.details.table.columns, (p) => (t(), b("th", {
703
+ key: p.key
704
+ }, s(p.label), 1))), 128))
705
+ ])
706
+ ]),
707
+ W("tbody", null, [
708
+ (t(!0), b(F, null, M(v.details.table.rows, (p, P) => (t(), b("tr", { key: P }, [
709
+ (t(!0), b(F, null, M(v.details.table.columns, (A) => (t(), b("td", {
710
+ key: A.key
711
+ }, [
712
+ A.type === "url" && h(r(p, A)) ? (t(), u(e(xe), {
713
+ key: 0,
714
+ href: h(r(p, A)),
715
+ target: "_blank",
716
+ class: "wx-audit-details__url"
717
+ }, {
718
+ default: a(() => [
719
+ n(s(h(r(p, A))), 1)
720
+ ]),
721
+ _: 2
722
+ }, 1032, ["href"])) : A.type === "status" && r(p, A) !== null ? (t(), u(e(B), {
723
+ key: 1,
724
+ type: l(r(p, A)),
725
+ size: "sm"
726
+ }, {
727
+ default: a(() => [
728
+ n(s(h(r(p, A))), 1)
729
+ ]),
730
+ _: 2
731
+ }, 1032, ["type"])) : A.type === "bool" ? (t(), b(F, { key: 2 }, [
732
+ n(s(d(r(p, A))), 1)
733
+ ], 64)) : A.type === "missing" && !h(r(p, A)) ? (t(), u(e(O), {
734
+ key: 3,
735
+ size: "sm",
736
+ tone: "danger"
737
+ }, {
738
+ default: a(() => [
739
+ n(s(e(o)("page.missing")), 1)
740
+ ]),
741
+ _: 1
742
+ })) : A.type === "edit" && h(r(p, A)) ? (t(), u(e(Q), {
743
+ key: 4,
744
+ size: "sm",
745
+ variant: "text",
746
+ icon: "edit",
747
+ onClick: (U) => e(c).push(h(r(p, A)))
748
+ }, {
749
+ default: a(() => [
750
+ n(s(e(o)("page.open-editor")), 1)
751
+ ]),
752
+ _: 1
753
+ }, 8, ["onClick"])) : (t(), b(F, { key: 5 }, [
754
+ n(s(h(r(p, A))), 1)
755
+ ], 64))
756
+ ]))), 128))
757
+ ]))), 128))
758
+ ])
759
+ ])
760
+ ])) : C("", !0)
761
+ ]));
762
+ }
763
+ }), Ve = /* @__PURE__ */ ie(kt, [["__scopeId", "data-v-55c63cfb"]]), xt = { class: "wx-audit-fix" }, wt = { class: "wx-audit-fix__changes" }, $t = {
764
+ key: 0,
765
+ class: "wx-audit-fix__field"
766
+ }, zt = { class: "wx-audit-fix__value" }, St = {
767
+ key: 0,
768
+ class: "wx-audit-fix__count"
769
+ }, Ct = { class: "wx-audit-fix__value" }, At = { class: "wx-audit-fix__actions" }, Pt = /* @__PURE__ */ se({
770
+ __name: "AuditFixDialog",
771
+ props: /* @__PURE__ */ Se({
772
+ run: {},
773
+ issue: {}
774
+ }, {
775
+ open: { type: Boolean, default: !1 },
776
+ openModifiers: {}
777
+ }),
778
+ emits: /* @__PURE__ */ Se(["fixed"], ["update:open"]),
779
+ setup(k, { emit: v }) {
780
+ const c = k, o = v, l = Ee(k, "open"), r = oe(le());
781
+ ne();
782
+ const d = ee("webx-audit"), h = ue(), m = we(), f = S(null), p = S(null), P = S(null);
783
+ async function A() {
784
+ f.value = null, p.value = null;
785
+ try {
786
+ f.value = await r.fixes(c.run, c.issue.id);
787
+ } catch (N) {
788
+ p.value = h(N);
789
+ }
790
+ }
791
+ async function U(N) {
792
+ P.value = N.id;
793
+ try {
794
+ await r.fix(c.run, c.issue.id, N.id), Y.success(d("page.fix-applied")), o("fixed", N.id), l.value = !1;
795
+ } catch (w) {
796
+ Y.danger(h(w));
797
+ } finally {
798
+ P.value = null;
799
+ }
800
+ }
801
+ function i(N) {
802
+ l.value = !1, m.push(N);
803
+ }
804
+ return re(
805
+ [l, () => c.issue.id],
806
+ ([N]) => {
807
+ N && A();
808
+ },
809
+ { immediate: !0 }
810
+ ), (N, w) => (t(), u(e(Me), {
811
+ open: l.value,
812
+ "onUpdate:open": w[0] || (w[0] = (j) => l.value = j),
813
+ title: e(d)("page.fix-button"),
814
+ width: 640
815
+ }, {
816
+ default: a(() => [
817
+ W("div", xt, [
818
+ p.value ? (t(), u(e(O), {
819
+ key: 0,
820
+ size: "sm",
821
+ tone: "danger"
822
+ }, {
823
+ default: a(() => [
824
+ n(s(p.value), 1)
825
+ ]),
826
+ _: 1
827
+ })) : f.value ? f.value.length === 0 ? (t(), u(e(O), {
828
+ key: 2,
829
+ size: "sm",
830
+ tone: "muted"
831
+ }, {
832
+ default: a(() => [
833
+ n(s(e(d)("page.fix-none")), 1)
834
+ ]),
835
+ _: 1
836
+ })) : C("", !0) : (t(), u(e(fe), {
837
+ key: 1,
838
+ rows: 3
839
+ })),
840
+ (t(!0), b(F, null, M(f.value ?? [], (j) => (t(), b("section", {
841
+ key: j.id,
842
+ class: "wx-audit-fix__offer"
843
+ }, [
844
+ g(e(O), { weight: "semibold" }, {
845
+ default: a(() => [
846
+ n(s(j.title), 1)
847
+ ]),
848
+ _: 2
849
+ }, 1024),
850
+ j.description ? (t(), u(e(O), {
851
+ key: 0,
852
+ size: "sm",
853
+ tone: "muted"
854
+ }, {
855
+ default: a(() => [
856
+ n(s(j.description), 1)
857
+ ]),
858
+ _: 2
859
+ }, 1024)) : C("", !0),
860
+ W("table", wt, [
861
+ W("thead", null, [
862
+ W("tr", null, [
863
+ W("th", null, s(e(d)("page.fix-changes")), 1),
864
+ W("th", null, s(e(d)("page.fix-before")), 1),
865
+ W("th", null, s(e(d)("page.fix-after")), 1),
866
+ w[1] || (w[1] = W("th", null, null, -1))
867
+ ])
868
+ ]),
869
+ W("tbody", null, [
870
+ (t(!0), b(F, null, M(j.changes, (_, J) => (t(), b("tr", { key: J }, [
871
+ W("td", null, [
872
+ W("div", null, s(_.label), 1),
873
+ _.field ? (t(), b("div", $t, s(_.field), 1)) : C("", !0)
874
+ ]),
875
+ W("td", zt, [
876
+ n(s(_.before ?? "") + " ", 1),
877
+ _.count ? (t(), b("span", St, "× " + s(_.count), 1)) : C("", !0)
878
+ ]),
879
+ W("td", Ct, s(_.after ?? ""), 1),
880
+ W("td", null, [
881
+ _.edit_url ? (t(), u(e(Q), {
882
+ key: 0,
883
+ size: "sm",
884
+ variant: "text",
885
+ icon: "edit",
886
+ "aria-label": e(d)("page.open-editor"),
887
+ onClick: (X) => i(_.edit_url)
888
+ }, null, 8, ["aria-label", "onClick"])) : C("", !0)
889
+ ])
890
+ ]))), 128))
891
+ ])
892
+ ]),
893
+ j.note ? (t(), u(e(O), {
894
+ key: 1,
895
+ size: "sm",
896
+ tone: "muted"
897
+ }, {
898
+ default: a(() => [
899
+ n(s(j.note), 1)
900
+ ]),
901
+ _: 2
902
+ }, 1024)) : C("", !0),
903
+ W("div", At, [
904
+ g(e(Q), {
905
+ type: "primary",
906
+ size: "sm",
907
+ loading: P.value === j.id,
908
+ disabled: P.value !== null,
909
+ onClick: (_) => U(j)
910
+ }, {
911
+ default: a(() => [
912
+ n(s(e(d)("page.fix-apply")), 1)
913
+ ]),
914
+ _: 1
915
+ }, 8, ["loading", "disabled", "onClick"])
916
+ ])
917
+ ]))), 128))
918
+ ])
919
+ ]),
920
+ _: 1
921
+ }, 8, ["open", "title"]));
922
+ }
923
+ }), Wt = /* @__PURE__ */ ie(Pt, [["__scopeId", "data-v-28525af3"]]), It = { class: "wx-audit-hide" }, Ot = /* @__PURE__ */ se({
924
+ __name: "AuditHideDialog",
925
+ props: /* @__PURE__ */ Se({
926
+ issue: {},
927
+ title: {}
928
+ }, {
929
+ open: { type: Boolean, default: !1 },
930
+ openModifiers: {}
931
+ }),
932
+ emits: /* @__PURE__ */ Se(["hidden"], ["update:open"]),
933
+ setup(k, { emit: v }) {
934
+ const c = k, o = v, l = Ee(k, "open"), r = oe(le());
935
+ ne();
936
+ const d = ee("webx-audit"), h = ue(), m = S(""), f = S(""), p = S(null), P = S(!1);
937
+ let A;
938
+ function U(j) {
939
+ if (!j) return "";
940
+ try {
941
+ const _ = new URL(j);
942
+ return _.pathname + _.search;
943
+ } catch {
944
+ return j;
945
+ }
946
+ }
947
+ const i = L(() => f.value.trim() !== "");
948
+ function N() {
949
+ clearTimeout(A), A = setTimeout(async () => {
950
+ try {
951
+ p.value = await r.hidePreview({ check: c.issue.check, pattern: m.value });
952
+ } catch {
953
+ p.value = null;
954
+ }
955
+ }, 300);
956
+ }
957
+ async function w() {
958
+ P.value = !0;
959
+ try {
960
+ const j = await r.hide({
961
+ check: c.issue.check,
962
+ pattern: m.value,
963
+ reason: f.value
964
+ });
965
+ Y.success(d("page.hidden-done")), o("hidden", j), l.value = !1;
966
+ } catch (j) {
967
+ Y.danger(h(j));
968
+ } finally {
969
+ P.value = !1;
970
+ }
971
+ }
972
+ return re(
973
+ [l, () => c.issue.id],
974
+ ([j]) => {
975
+ j && (m.value = U(c.issue.url), f.value = "", p.value = null, N());
976
+ },
977
+ { immediate: !0 }
978
+ ), re(m, () => {
979
+ l.value && N();
980
+ }), (j, _) => (t(), u(e(Me), {
981
+ open: l.value,
982
+ "onUpdate:open": _[3] || (_[3] = (J) => l.value = J),
983
+ title: e(d)("page.hide-title"),
984
+ width: 560
985
+ }, {
986
+ footer: a(() => [
987
+ g(e(Q), {
988
+ onClick: _[2] || (_[2] = (J) => l.value = !1)
989
+ }, {
990
+ default: a(() => [
991
+ n(s(e(d)("page.dismiss")), 1)
992
+ ]),
993
+ _: 1
994
+ }),
995
+ g(e(Q), {
996
+ type: "primary",
997
+ loading: P.value,
998
+ disabled: !i.value,
999
+ onClick: w
1000
+ }, {
1001
+ default: a(() => [
1002
+ n(s(e(d)("page.hide")), 1)
1003
+ ]),
1004
+ _: 1
1005
+ }, 8, ["loading", "disabled"])
1006
+ ]),
1007
+ default: a(() => [
1008
+ W("div", It, [
1009
+ g(e(O), { weight: "semibold" }, {
1010
+ default: a(() => [
1011
+ n(s(c.title), 1)
1012
+ ]),
1013
+ _: 1
1014
+ }),
1015
+ g(e(O), {
1016
+ size: "sm",
1017
+ tone: "muted"
1018
+ }, {
1019
+ default: a(() => [
1020
+ n(s(e(d)("page.hide-help")), 1)
1021
+ ]),
1022
+ _: 1
1023
+ }),
1024
+ g(e(Ne), {
1025
+ label: e(d)("page.hide-pattern"),
1026
+ help: e(d)("page.hide-pattern-help")
1027
+ }, {
1028
+ default: a(() => [
1029
+ g(e(Je), {
1030
+ modelValue: m.value,
1031
+ "onUpdate:modelValue": _[0] || (_[0] = (J) => m.value = J),
1032
+ placeholder: "/search/**"
1033
+ }, null, 8, ["modelValue"])
1034
+ ]),
1035
+ _: 1
1036
+ }, 8, ["label", "help"]),
1037
+ g(e(Ne), {
1038
+ label: e(d)("page.hide-reason"),
1039
+ required: ""
1040
+ }, {
1041
+ default: a(() => [
1042
+ g(e(st), {
1043
+ modelValue: f.value,
1044
+ "onUpdate:modelValue": _[1] || (_[1] = (J) => f.value = J),
1045
+ rows: 3
1046
+ }, null, 8, ["modelValue"])
1047
+ ]),
1048
+ _: 1
1049
+ }, 8, ["label"]),
1050
+ p.value !== null ? (t(), u(e(O), {
1051
+ key: 0,
1052
+ size: "sm",
1053
+ tone: "muted"
1054
+ }, {
1055
+ default: a(() => [
1056
+ n(s(e(d)("page.hide-count", { count: p.value })), 1)
1057
+ ]),
1058
+ _: 1
1059
+ })) : C("", !0)
1060
+ ])
1061
+ ]),
1062
+ _: 1
1063
+ }, 8, ["open", "title"]));
1064
+ }
1065
+ }), Ut = /* @__PURE__ */ ie(Ot, [["__scopeId", "data-v-1db364c4"]]), Vt = { class: "wx-audit-issues" }, Nt = { class: "wx-audit-issues__head" }, jt = /* @__PURE__ */ se({
1066
+ __name: "AuditIssueList",
1067
+ props: {
1068
+ run: {},
1069
+ query: {},
1070
+ fixable: { type: Boolean },
1071
+ title: {}
1072
+ },
1073
+ emits: ["changed"],
1074
+ setup(k, { emit: v }) {
1075
+ const c = k, o = v, l = le(), r = oe(l), d = l.can("audit.manage");
1076
+ ne();
1077
+ const h = ee("webx-audit"), m = ue(), f = S(null), p = S(!1), P = S(1), A = S(null), U = S(null), i = S(!1), N = S(null), w = S(!1);
1078
+ function j(V) {
1079
+ N.value = V, w.value = !0;
1080
+ }
1081
+ function _(V) {
1082
+ f.value && !V.pattern ? f.value = [] : f.value && N.value && (f.value = f.value.filter((I) => I.id !== N.value?.id)), o("changed");
1083
+ }
1084
+ async function J(V) {
1085
+ if (V.ignore)
1086
+ try {
1087
+ await r.unhide(V.ignore.id), Y.success(h("page.unhidden")), o("changed");
1088
+ } catch (I) {
1089
+ Y.danger(m(I));
1090
+ }
1091
+ }
1092
+ function X(V) {
1093
+ const I = V.ignore;
1094
+ return I ? I.created_by ? h("page.hidden-by", { who: I.created_by, reason: I.reason }) : h("page.hidden-reason", { reason: I.reason }) : "";
1095
+ }
1096
+ function R(V) {
1097
+ U.value = V, i.value = !0;
1098
+ }
1099
+ function D(V) {
1100
+ U.value && (U.value.fixed_with = V);
1101
+ }
1102
+ async function z(V = 1) {
1103
+ try {
1104
+ const I = await r.issues(c.run, { ...c.query, page: V, per_page: 50 });
1105
+ f.value = V === 1 ? I.data : [...f.value ?? [], ...I.data], P.value = I.current_page, p.value = I.current_page < I.last_page;
1106
+ } catch (I) {
1107
+ A.value = m(I);
1108
+ }
1109
+ }
1110
+ return ge(() => z()), (V, I) => (t(), b("div", Vt, [
1111
+ A.value ? (t(), u(e(O), {
1112
+ key: 0,
1113
+ size: "sm",
1114
+ tone: "danger"
1115
+ }, {
1116
+ default: a(() => [
1117
+ n(s(A.value), 1)
1118
+ ]),
1119
+ _: 1
1120
+ })) : f.value ? (t(), b(F, { key: 2 }, [
1121
+ (t(!0), b(F, null, M(f.value, (q) => (t(), b("div", {
1122
+ key: q.id,
1123
+ class: "wx-audit-issues__item"
1124
+ }, [
1125
+ W("div", Nt, [
1126
+ q.url ? (t(), u(e(xe), {
1127
+ key: 0,
1128
+ href: q.url,
1129
+ target: "_blank",
1130
+ class: "wx-audit-issues__url"
1131
+ }, {
1132
+ default: a(() => [
1133
+ n(s(q.url), 1)
1134
+ ]),
1135
+ _: 2
1136
+ }, 1032, ["href"])) : C("", !0),
1137
+ q.state === "new" ? (t(), u(e(B), {
1138
+ key: 1,
1139
+ type: "primary",
1140
+ size: "sm"
1141
+ }, {
1142
+ default: a(() => [
1143
+ n(s(e(h)("page.state-new")), 1)
1144
+ ]),
1145
+ _: 1
1146
+ })) : C("", !0),
1147
+ q.fixed_with ? (t(), u(e(B), {
1148
+ key: 2,
1149
+ type: "success",
1150
+ size: "sm"
1151
+ }, {
1152
+ default: a(() => [
1153
+ n(s(e(h)("page.fix-pressed")), 1)
1154
+ ]),
1155
+ _: 1
1156
+ })) : k.fixable && e(d) && !q.ignored ? (t(), u(e(Q), {
1157
+ key: 3,
1158
+ size: "sm",
1159
+ variant: "outline",
1160
+ icon: "check",
1161
+ class: "wx-audit-issues__fix",
1162
+ onClick: (he) => R(q)
1163
+ }, {
1164
+ default: a(() => [
1165
+ n(s(e(h)("page.fix-button")), 1)
1166
+ ]),
1167
+ _: 1
1168
+ }, 8, ["onClick"])) : C("", !0),
1169
+ e(d) && q.ignored && q.ignore ? (t(), u(e(Q), {
1170
+ key: 4,
1171
+ size: "sm",
1172
+ variant: "text",
1173
+ icon: "eye",
1174
+ class: "wx-audit-issues__end",
1175
+ onClick: (he) => J(q)
1176
+ }, {
1177
+ default: a(() => [
1178
+ n(s(e(h)("page.unhide")), 1)
1179
+ ]),
1180
+ _: 1
1181
+ }, 8, ["onClick"])) : e(d) && !q.ignored ? (t(), u(e(Q), {
1182
+ key: 5,
1183
+ size: "sm",
1184
+ variant: "text",
1185
+ icon: "eye-off",
1186
+ class: Be({ "wx-audit-issues__end": !k.fixable || q.fixed_with }),
1187
+ onClick: (he) => j(q)
1188
+ }, {
1189
+ default: a(() => [
1190
+ n(s(e(h)("page.hide")), 1)
1191
+ ]),
1192
+ _: 1
1193
+ }, 8, ["class", "onClick"])) : C("", !0)
1194
+ ]),
1195
+ q.ignore ? (t(), u(e(O), {
1196
+ key: 0,
1197
+ size: "sm",
1198
+ tone: "muted"
1199
+ }, {
1200
+ default: a(() => [
1201
+ n(s(X(q)), 1)
1202
+ ]),
1203
+ _: 2
1204
+ }, 1024)) : C("", !0),
1205
+ g(Ve, {
1206
+ details: q.details
1207
+ }, null, 8, ["details"])
1208
+ ]))), 128)),
1209
+ p.value ? (t(), u(e(Q), {
1210
+ key: 0,
1211
+ size: "sm",
1212
+ variant: "text",
1213
+ onClick: I[0] || (I[0] = (q) => z(P.value + 1))
1214
+ }, {
1215
+ default: a(() => [...I[3] || (I[3] = [
1216
+ n("…", -1)
1217
+ ])]),
1218
+ _: 1
1219
+ })) : C("", !0)
1220
+ ], 64)) : (t(), u(e(fe), {
1221
+ key: 1,
1222
+ rows: 2
1223
+ })),
1224
+ U.value ? (t(), u(Wt, {
1225
+ key: 3,
1226
+ open: i.value,
1227
+ "onUpdate:open": I[1] || (I[1] = (q) => i.value = q),
1228
+ run: k.run,
1229
+ issue: U.value,
1230
+ onFixed: D
1231
+ }, null, 8, ["open", "run", "issue"])) : C("", !0),
1232
+ N.value ? (t(), u(Ut, {
1233
+ key: 4,
1234
+ open: w.value,
1235
+ "onUpdate:open": I[2] || (I[2] = (q) => w.value = q),
1236
+ issue: N.value,
1237
+ title: c.title ?? N.value.check,
1238
+ onHidden: _
1239
+ }, null, 8, ["open", "issue", "title"])) : C("", !0)
1240
+ ]));
1241
+ }
1242
+ }), Tt = /* @__PURE__ */ ie(jt, [["__scopeId", "data-v-23ac6ac8"]]), Rt = { class: "wx-audit-findings__filters" }, Ft = { class: "wx-audit-findings__title" }, Lt = { class: "wx-audit-findings__texts" }, Dt = /* @__PURE__ */ se({
1243
+ __name: "AuditIssuesPage",
1244
+ props: {
1245
+ base: {}
1246
+ },
1247
+ setup(k) {
1248
+ const v = k, c = oe(le());
1249
+ ne();
1250
+ const o = ee("webx-audit"), l = ee("webx-admin"), r = ue(), d = S(null), h = S(null), m = S(!1), f = S([]), p = S(null), P = S(null), A = S(null), U = L(() => ({ severity: p.value, group: P.value, state: A.value })), i = L(
1251
+ () => [p.value, P.value, A.value].filter(Boolean).length
1252
+ ), N = {
1253
+ error: "danger",
1254
+ warning: "warning",
1255
+ notice: "info"
1256
+ }, w = L(() => [
1257
+ { key: "severity", label: o("page.severity"), width: 130 },
1258
+ { key: "title", label: o("page.check") },
1259
+ { key: "count", label: o("page.count"), width: 110, align: "right" }
1260
+ ]), j = L(
1261
+ () => ["error", "warning", "notice"].map((D) => ({
1262
+ value: D,
1263
+ label: o(`page.severity-${D}`)
1264
+ }))
1265
+ ), _ = L(
1266
+ () => [
1267
+ "config",
1268
+ "host",
1269
+ "hosts",
1270
+ "indexing",
1271
+ "page",
1272
+ "content",
1273
+ "links",
1274
+ "images",
1275
+ "a11y",
1276
+ "structure"
1277
+ ].map((D) => ({ value: D, label: o(`page.group-${D}`) }))
1278
+ ), J = L(
1279
+ () => ["new", "persisting", "hidden"].map((D) => ({
1280
+ value: D,
1281
+ label: o(`page.state-${D}`)
1282
+ }))
1283
+ );
1284
+ function X(D) {
1285
+ return typeof D == "string" && D !== "" ? D : null;
1286
+ }
1287
+ async function R() {
1288
+ m.value = !0;
1289
+ try {
1290
+ d.value === null && (d.value = (await c.latest()).done?.id ?? null), h.value = d.value === null ? [] : await c.checks(d.value, U.value), f.value = [];
1291
+ } catch (D) {
1292
+ Y.danger(r(D));
1293
+ } finally {
1294
+ m.value = !1;
1295
+ }
1296
+ }
1297
+ return re(U, () => {
1298
+ R();
1299
+ }), ge(R), (D, z) => (t(), u(_e, {
1300
+ base: v.base,
1301
+ current: "issues"
1302
+ }, {
1303
+ default: a(() => [
1304
+ g(e(ve), {
1305
+ expanded: f.value,
1306
+ "onUpdate:expanded": z[4] || (z[4] = (V) => f.value = V),
1307
+ data: h.value ?? [],
1308
+ columns: w.value,
1309
+ "row-key": "id",
1310
+ expandable: "",
1311
+ flush: "",
1312
+ loading: m.value,
1313
+ "filters-count": i.value,
1314
+ "filters-label": e(l)("filters.title"),
1315
+ "empty-text": d.value === null ? e(o)("page.never") : e(o)("page.empty")
1316
+ }, {
1317
+ filters: a(() => [
1318
+ W("div", Rt, [
1319
+ g(e(ce), {
1320
+ "model-value": p.value,
1321
+ options: j.value,
1322
+ placeholder: e(o)("page.any-severity"),
1323
+ clearable: "",
1324
+ "onUpdate:modelValue": z[0] || (z[0] = (V) => p.value = X(V))
1325
+ }, null, 8, ["model-value", "options", "placeholder"]),
1326
+ g(e(ce), {
1327
+ "model-value": P.value,
1328
+ options: _.value,
1329
+ placeholder: e(o)("page.any-group"),
1330
+ clearable: "",
1331
+ "onUpdate:modelValue": z[1] || (z[1] = (V) => P.value = X(V))
1332
+ }, null, 8, ["model-value", "options", "placeholder"]),
1333
+ g(e(ce), {
1334
+ "model-value": A.value,
1335
+ options: J.value,
1336
+ placeholder: e(o)("page.any-state"),
1337
+ clearable: "",
1338
+ "onUpdate:modelValue": z[2] || (z[2] = (V) => A.value = X(V))
1339
+ }, null, 8, ["model-value", "options", "placeholder"])
1340
+ ])
1341
+ ]),
1342
+ "cell-severity": a(({ row: V }) => [
1343
+ g(e(B), {
1344
+ type: N[V.severity],
1345
+ dot: ""
1346
+ }, {
1347
+ default: a(() => [
1348
+ n(s(e(o)(`page.severity-${V.severity}`)), 1)
1349
+ ]),
1350
+ _: 2
1351
+ }, 1032, ["type"])
1352
+ ]),
1353
+ "cell-title": a(({ row: V }) => [
1354
+ W("span", Ft, [
1355
+ g(e(O), { size: "sm" }, {
1356
+ default: a(() => [
1357
+ n(s(V.title), 1)
1358
+ ]),
1359
+ _: 2
1360
+ }, 1024),
1361
+ V.new > 0 ? (t(), u(e(B), {
1362
+ key: 0,
1363
+ type: "primary",
1364
+ size: "sm"
1365
+ }, {
1366
+ default: a(() => [
1367
+ n(s(e(o)("page.state-new")), 1)
1368
+ ]),
1369
+ _: 1
1370
+ })) : C("", !0),
1371
+ g(e(Ge), {
1372
+ title: V.title,
1373
+ width: "360"
1374
+ }, {
1375
+ trigger: a(() => [
1376
+ g(e(Q), {
1377
+ size: "sm",
1378
+ variant: "text",
1379
+ icon: "question",
1380
+ "aria-label": e(o)("page.explain"),
1381
+ onClick: z[3] || (z[3] = Ye(() => {
1382
+ }, ["stop"]))
1383
+ }, null, 8, ["aria-label"])
1384
+ ]),
1385
+ default: a(() => [
1386
+ W("dl", Lt, [
1387
+ W("dt", null, s(e(o)("page.found")), 1),
1388
+ W("dd", null, s(V.found), 1),
1389
+ W("dt", null, s(e(o)("page.why")), 1),
1390
+ W("dd", null, s(V.why), 1),
1391
+ W("dt", null, s(e(o)("page.fix")), 1),
1392
+ W("dd", null, s(V.fix), 1)
1393
+ ])
1394
+ ]),
1395
+ _: 2
1396
+ }, 1032, ["title"])
1397
+ ])
1398
+ ]),
1399
+ expanded: a(({ row: V }) => [
1400
+ d.value !== null ? (t(), u(Tt, {
1401
+ key: 0,
1402
+ run: d.value,
1403
+ query: { ...U.value, check: V.id },
1404
+ fixable: (V.fixes ?? []).length > 0,
1405
+ title: V.title,
1406
+ onChanged: R
1407
+ }, null, 8, ["run", "query", "fixable", "title"])) : C("", !0)
1408
+ ]),
1409
+ _: 1
1410
+ }, 8, ["expanded", "data", "columns", "loading", "filters-count", "filters-label", "empty-text"])
1411
+ ]),
1412
+ _: 1
1413
+ }, 8, ["base"]));
1414
+ }
1415
+ }), qt = /* @__PURE__ */ ie(Dt, [["__scopeId", "data-v-7f790d95"]]), Et = { class: "wx-audit-overview" }, Bt = { class: "wx-audit-overview__row" }, Ht = { class: "wx-audit-overview__row" }, Mt = { class: "wx-audit-overview__summary" }, Jt = { class: "wx-audit-overview__stats" }, Gt = { class: "wx-audit-overview__meta" }, Kt = { class: "wx-audit-overview__groups" }, Qt = { class: "wx-audit-overview__badges" }, Xt = { class: "wx-audit-overview__badges" }, Yt = {
1416
+ key: 0,
1417
+ class: "wx-audit-overview__missing"
1418
+ }, Zt = 2e3, ea = /* @__PURE__ */ se({
1419
+ __name: "AuditOverviewPage",
1420
+ props: {
1421
+ base: {}
1422
+ },
1423
+ setup(k) {
1424
+ const v = k, c = le(), o = oe(c);
1425
+ ne();
1426
+ const l = ee("webx-audit"), r = ue(), d = S(null), h = S("quick"), m = S(!1);
1427
+ let f;
1428
+ const p = c.can("audit.run") || c.can("audit.manage"), P = L(() => d.value?.active ?? null), A = L(() => d.value?.done ?? null), U = L(() => A.value?.counts ?? null), i = L(() => [
1429
+ { value: "quick", label: l("page.scope-quick") },
1430
+ { value: "full", label: l("page.scope-full") }
1431
+ ]), N = [
1432
+ { key: "error", label: "page.errors", tone: "danger" },
1433
+ { key: "warning", label: "page.warnings", tone: "warning" },
1434
+ { key: "notice", label: "page.notices", tone: "info" }
1435
+ ], w = L(() => {
1436
+ const z = U.value?.health ?? 0;
1437
+ return z >= 90 ? "success" : z >= 60 ? "warning" : "danger";
1438
+ }), j = [
1439
+ "config",
1440
+ "host",
1441
+ "hosts",
1442
+ "indexing",
1443
+ "page",
1444
+ "content",
1445
+ "links",
1446
+ "images",
1447
+ "a11y",
1448
+ "structure"
1449
+ ], _ = L(
1450
+ () => Object.entries(U.value?.groups ?? {}).map(([z, V]) => ({
1451
+ id: z,
1452
+ label: l(`page.group-${j.includes(z) ? z : "other"}`),
1453
+ bySeverity: V
1454
+ }))
1455
+ );
1456
+ function J(z) {
1457
+ return z.status === "queued" ? l("page.status-queued") : z.progress.stage ? l(`page.stage-${z.progress.stage}`) : l("page.status-running");
1458
+ }
1459
+ async function X() {
1460
+ try {
1461
+ d.value = await o.latest();
1462
+ } catch (z) {
1463
+ Y.danger(r(z));
1464
+ }
1465
+ clearTimeout(f), d.value?.active && (f = setTimeout(() => {
1466
+ X();
1467
+ }, Zt));
1468
+ }
1469
+ async function R() {
1470
+ m.value = !0;
1471
+ try {
1472
+ await o.start(h.value), Y.success(l("page.started")), await X();
1473
+ } catch (z) {
1474
+ Y.danger(r(z));
1475
+ } finally {
1476
+ m.value = !1;
1477
+ }
1478
+ }
1479
+ async function D(z) {
1480
+ try {
1481
+ await o.cancel(z.id), await X();
1482
+ } catch (V) {
1483
+ Y.danger(r(V));
1484
+ }
1485
+ }
1486
+ return ge(X), He(() => clearTimeout(f)), (z, V) => (t(), u(_e, {
1487
+ base: v.base,
1488
+ current: "overview",
1489
+ card: !1
1490
+ }, {
1491
+ default: a(() => [
1492
+ W("div", Et, [
1493
+ d.value ? (t(), b(F, { key: 1 }, [
1494
+ d.value.queue.sync ? (t(), u(e(me), {
1495
+ key: 0,
1496
+ type: "warning",
1497
+ description: e(l)("page.sync-queue")
1498
+ }, null, 8, ["description"])) : C("", !0),
1499
+ d.value.last && d.value.last.status === "failed" ? (t(), u(e(me), {
1500
+ key: 1,
1501
+ type: "danger",
1502
+ description: e(l)("page.last-failed", { error: d.value.last.error ?? "" })
1503
+ }, null, 8, ["description"])) : C("", !0),
1504
+ P.value ? (t(), u(e(de), {
1505
+ key: 2,
1506
+ class: "wx-audit-overview__active"
1507
+ }, {
1508
+ default: a(() => [
1509
+ W("div", Bt, [
1510
+ g(e(O), { weight: "semibold" }, {
1511
+ default: a(() => [
1512
+ n(s(J(P.value)), 1)
1513
+ ]),
1514
+ _: 1
1515
+ }),
1516
+ g(e(O), {
1517
+ size: "sm",
1518
+ tone: "muted",
1519
+ class: "wx-audit-overview__url"
1520
+ }, {
1521
+ default: a(() => [
1522
+ n(s(P.value.base_url), 1)
1523
+ ]),
1524
+ _: 1
1525
+ }),
1526
+ e(p) ? (t(), u(e(Q), {
1527
+ key: 0,
1528
+ size: "sm",
1529
+ class: "wx-audit-overview__end",
1530
+ onClick: V[0] || (V[0] = (I) => D(P.value))
1531
+ }, {
1532
+ default: a(() => [
1533
+ n(s(e(l)("page.cancel")), 1)
1534
+ ]),
1535
+ _: 1
1536
+ })) : C("", !0)
1537
+ ]),
1538
+ g(e(je), {
1539
+ indeterminate: "",
1540
+ "aria-label": J(P.value)
1541
+ }, null, 8, ["aria-label"]),
1542
+ P.value.progress.resources ? (t(), u(e(O), {
1543
+ key: 0,
1544
+ size: "sm",
1545
+ tone: "muted"
1546
+ }, {
1547
+ default: a(() => [
1548
+ n(s(e(l)("page.resources-progress", {
1549
+ checked: P.value.progress.resources.checked,
1550
+ total: P.value.progress.resources.total
1551
+ })), 1)
1552
+ ]),
1553
+ _: 1
1554
+ })) : P.value.progress.stage === "crawl" ? (t(), u(e(O), {
1555
+ key: 1,
1556
+ size: "sm",
1557
+ tone: "muted"
1558
+ }, {
1559
+ default: a(() => [
1560
+ n(s(e(l)("page.pages-progress", {
1561
+ crawled: P.value.progress.pages.crawled,
1562
+ limit: P.value.progress.pages.limit
1563
+ })), 1)
1564
+ ]),
1565
+ _: 1
1566
+ })) : C("", !0)
1567
+ ]),
1568
+ _: 1
1569
+ })) : e(p) && !d.value.queue.sync ? (t(), u(e(de), { key: 3 }, {
1570
+ default: a(() => [
1571
+ W("div", Ht, [
1572
+ g(e(Ke), {
1573
+ modelValue: h.value,
1574
+ "onUpdate:modelValue": V[1] || (V[1] = (I) => h.value = I),
1575
+ options: i.value,
1576
+ "aria-label": e(l)("page.scope")
1577
+ }, null, 8, ["modelValue", "options", "aria-label"]),
1578
+ g(e(O), {
1579
+ size: "sm",
1580
+ tone: "muted"
1581
+ }, {
1582
+ default: a(() => [
1583
+ n(s(h.value === "full" ? e(l)("page.scope-full-help") : e(l)("page.scope-quick-help")), 1)
1584
+ ]),
1585
+ _: 1
1586
+ }),
1587
+ g(e(Q), {
1588
+ type: "primary",
1589
+ icon: "refresh",
1590
+ loading: m.value,
1591
+ class: "wx-audit-overview__end",
1592
+ onClick: R
1593
+ }, {
1594
+ default: a(() => [
1595
+ n(s(e(l)("page.run")), 1)
1596
+ ]),
1597
+ _: 1
1598
+ }, 8, ["loading"])
1599
+ ])
1600
+ ]),
1601
+ _: 1
1602
+ })) : C("", !0),
1603
+ !A.value && !P.value ? (t(), u(e(de), { key: 4 }, {
1604
+ default: a(() => [
1605
+ g(e(Te), {
1606
+ icon: "check-circle",
1607
+ title: e(l)("page.never"),
1608
+ description: e(l)("page.never-help")
1609
+ }, null, 8, ["title", "description"])
1610
+ ]),
1611
+ _: 1
1612
+ })) : C("", !0),
1613
+ A.value && U.value ? (t(), b(F, { key: 5 }, [
1614
+ g(e(de), null, {
1615
+ default: a(() => [
1616
+ W("div", Mt, [
1617
+ g(e(je), {
1618
+ type: "circle",
1619
+ value: U.value.health,
1620
+ status: w.value,
1621
+ "show-value": "",
1622
+ formatter: (I) => `${I}%`,
1623
+ "aria-label": e(l)("page.health")
1624
+ }, null, 8, ["value", "status", "formatter", "aria-label"]),
1625
+ W("div", Jt, [
1626
+ (t(), b(F, null, M(N, (I) => g(e(Oe), {
1627
+ key: I.key,
1628
+ title: e(l)(I.label),
1629
+ value: U.value.severity[I.key] ?? 0,
1630
+ tone: (U.value.severity[I.key] ?? 0) > 0 ? I.tone : "muted"
1631
+ }, null, 8, ["title", "value", "tone"])), 64)),
1632
+ g(e(Oe), {
1633
+ title: e(l)("page.new"),
1634
+ value: U.value.new
1635
+ }, null, 8, ["title", "value"]),
1636
+ g(e(Oe), {
1637
+ title: e(l)("page.fixed"),
1638
+ value: U.value.fixed,
1639
+ tone: "success"
1640
+ }, null, 8, ["title", "value"])
1641
+ ])
1642
+ ]),
1643
+ W("div", Gt, [
1644
+ g(e(O), {
1645
+ size: "sm",
1646
+ tone: "muted"
1647
+ }, {
1648
+ default: a(() => [
1649
+ n(s(e(l)("page.last-run")) + " ", 1),
1650
+ g(e(ke), {
1651
+ value: A.value.finished_at
1652
+ }, null, 8, ["value"]),
1653
+ n(" · " + s(e(l)(`page.scope-${A.value.scope}`)) + " · ", 1)
1654
+ ]),
1655
+ _: 1
1656
+ }),
1657
+ g(e(O), {
1658
+ size: "sm",
1659
+ tone: "muted",
1660
+ class: "wx-audit-overview__url"
1661
+ }, {
1662
+ default: a(() => [
1663
+ n(s(A.value.base_url), 1)
1664
+ ]),
1665
+ _: 1
1666
+ })
1667
+ ])
1668
+ ]),
1669
+ _: 1
1670
+ }),
1671
+ _.value.length ? (t(), u(e(de), {
1672
+ key: 0,
1673
+ title: e(l)("page.by-group")
1674
+ }, {
1675
+ default: a(() => [
1676
+ W("ul", Kt, [
1677
+ (t(!0), b(F, null, M(_.value, (I) => (t(), b("li", {
1678
+ key: I.id
1679
+ }, [
1680
+ g(e(O), { size: "sm" }, {
1681
+ default: a(() => [
1682
+ n(s(I.label), 1)
1683
+ ]),
1684
+ _: 2
1685
+ }, 1024),
1686
+ W("span", Qt, [
1687
+ (t(), b(F, null, M(N, (q) => (t(), b(F, {
1688
+ key: q.key
1689
+ }, [
1690
+ (I.bySeverity[q.key] ?? 0) > 0 ? (t(), u(e(B), {
1691
+ key: 0,
1692
+ type: q.tone,
1693
+ size: "sm"
1694
+ }, {
1695
+ default: a(() => [
1696
+ n(s(e(l)(q.label)) + " · " + s(I.bySeverity[q.key]), 1)
1697
+ ]),
1698
+ _: 2
1699
+ }, 1032, ["type"])) : C("", !0)
1700
+ ], 64))), 64))
1701
+ ])
1702
+ ]))), 128))
1703
+ ])
1704
+ ]),
1705
+ _: 1
1706
+ }, 8, ["title"])) : (t(), u(e(de), { key: 1 }, {
1707
+ default: a(() => [
1708
+ g(e(Te), {
1709
+ icon: "check-circle",
1710
+ title: e(l)("page.clean"),
1711
+ size: "sm"
1712
+ }, null, 8, ["title"])
1713
+ ]),
1714
+ _: 1
1715
+ })),
1716
+ g(e(de), {
1717
+ title: e(l)("page.sources")
1718
+ }, {
1719
+ default: a(() => [
1720
+ W("div", Xt, [
1721
+ (t(!0), b(F, null, M(U.value.sources.searched, (I) => (t(), u(e(B), {
1722
+ key: I,
1723
+ type: "success"
1724
+ }, {
1725
+ default: a(() => [
1726
+ n(s(I), 1)
1727
+ ]),
1728
+ _: 2
1729
+ }, 1024))), 128))
1730
+ ]),
1731
+ U.value.sources.missing.length ? (t(), b("div", Yt, [
1732
+ g(e(O), {
1733
+ size: "sm",
1734
+ tone: "warning"
1735
+ }, {
1736
+ default: a(() => [
1737
+ n(s(e(l)("page.sources-missing")), 1)
1738
+ ]),
1739
+ _: 1
1740
+ }),
1741
+ (t(!0), b(F, null, M(U.value.sources.missing, (I) => (t(), u(e(B), {
1742
+ key: I,
1743
+ type: "warning"
1744
+ }, {
1745
+ default: a(() => [
1746
+ n(s(I), 1)
1747
+ ]),
1748
+ _: 2
1749
+ }, 1024))), 128))
1750
+ ])) : C("", !0)
1751
+ ]),
1752
+ _: 1
1753
+ }, 8, ["title"])
1754
+ ], 64)) : C("", !0)
1755
+ ], 64)) : (t(), u(e(de), { key: 0 }, {
1756
+ default: a(() => [
1757
+ g(e(fe), { rows: 4 })
1758
+ ]),
1759
+ _: 1
1760
+ }))
1761
+ ])
1762
+ ]),
1763
+ _: 1
1764
+ }, 8, ["base"]));
1765
+ }
1766
+ }), ta = /* @__PURE__ */ ie(ea, [["__scopeId", "data-v-2a1e0d61"]]), aa = { class: "wx-audit-card__title" }, sa = { class: "wx-audit-card__url" }, la = {
1767
+ key: 0,
1768
+ class: "wx-audit-card__extra"
1769
+ }, na = {
1770
+ key: 2,
1771
+ class: "wx-audit-card"
1772
+ }, ia = { class: "wx-audit-card__recheck" }, ua = {
1773
+ key: 0,
1774
+ class: "wx-audit-card__facts"
1775
+ }, oa = { key: 0 }, ra = {
1776
+ key: 1,
1777
+ class: "wx-audit-card__pairs"
1778
+ }, da = {
1779
+ key: 2,
1780
+ class: "wx-audit-card__tags"
1781
+ }, ca = { class: "wx-audit-card__section" }, pa = { class: "wx-audit-card__code" }, ga = { class: "wx-audit-card__code" }, va = {
1782
+ key: 1,
1783
+ class: "wx-audit-card__issues"
1784
+ }, fa = { class: "wx-audit-card__issue-head" }, ha = {
1785
+ key: 0,
1786
+ class: "wx-audit-card__picture"
1787
+ }, ma = { class: "wx-audit-card__url" }, _a = {
1788
+ key: 1,
1789
+ class: "wx-audit-card__url"
1790
+ }, ya = {
1791
+ key: 3,
1792
+ class: "wx-audit-card__issues"
1793
+ }, ba = { class: "wx-audit-card__issue-head" }, ka = {
1794
+ key: 1,
1795
+ class: "wx-audit-card__source"
1796
+ }, xa = { class: "wx-audit-card__url" }, wa = 2e3, $a = /* @__PURE__ */ se({
1797
+ __name: "AuditPageCard",
1798
+ props: {
1799
+ run: {},
1800
+ base: {},
1801
+ pageId: {},
1802
+ titles: {}
1803
+ },
1804
+ emits: ["close"],
1805
+ setup(k, { emit: v }) {
1806
+ const c = k, o = v, l = le(), r = oe(l), d = we();
1807
+ ne();
1808
+ const h = l.can("audit.run") || l.can("audit.manage"), m = S(null), f = S(!1);
1809
+ let p;
1810
+ async function P() {
1811
+ if (w.value) {
1812
+ f.value = !0, m.value = null;
1813
+ try {
1814
+ A(await r.start("urls", [w.value.page.url]));
1815
+ } catch (x) {
1816
+ f.value = !1, Y.danger(N(x));
1817
+ }
1818
+ }
1819
+ }
1820
+ function A(x) {
1821
+ if (clearTimeout(p), x.status === "queued" || x.status === "running") {
1822
+ p = setTimeout(async () => {
1823
+ try {
1824
+ A(await r.run(x.id));
1825
+ } catch (G) {
1826
+ f.value = !1, Y.danger(N(G));
1827
+ }
1828
+ }, wa);
1829
+ return;
1830
+ }
1831
+ f.value = !1, m.value = x;
1832
+ }
1833
+ function U() {
1834
+ m.value && c.base && d.push({ path: `${c.base}/runs`, query: { to: String(m.value.id) } });
1835
+ }
1836
+ He(() => clearTimeout(p));
1837
+ const i = ee("webx-audit"), N = ue(), w = S(null), j = S(null), _ = S("overview"), J = S(null), X = S(!1), R = S(null), D = S(!1), z = ["images", "css", "js"], V = L({
1838
+ get: () => c.pageId !== null,
1839
+ set: (x) => {
1840
+ x || o("close");
1841
+ }
1842
+ }), I = L(() => [
1843
+ { value: "overview", label: i("page.card-overview") },
1844
+ { value: "issues", label: i("page.card-issues"), badge: w.value?.counts.issues || void 0 },
1845
+ { value: "in", label: i("page.card-incoming"), badge: w.value?.counts.incoming || void 0 },
1846
+ { value: "out", label: i("page.card-outgoing"), badge: w.value?.counts.outgoing || void 0 },
1847
+ { value: "images", label: i("page.card-images"), badge: w.value?.counts.images || void 0 },
1848
+ { value: "css", label: i("page.card-css"), badge: w.value?.counts.css || void 0 },
1849
+ { value: "js", label: i("page.card-js"), badge: w.value?.counts.js || void 0 },
1850
+ {
1851
+ value: "microdata",
1852
+ label: i("page.card-microdata"),
1853
+ badge: w.value?.counts.microdata || void 0
1854
+ }
1855
+ ]), q = L(
1856
+ () => z.includes(_.value) ? _.value : null
1857
+ ), he = {
1858
+ error: "danger",
1859
+ warning: "warning",
1860
+ notice: "info"
1861
+ }, ye = {
1862
+ own: "success",
1863
+ own_mirror: "warning",
1864
+ dev: "danger",
1865
+ external: "info"
1866
+ }, $e = L(() => [
1867
+ { key: "url", label: i("page.address"), minWidth: 220 },
1868
+ { key: "status", label: i("page.field-status"), width: 80 },
1869
+ { key: "kind", label: i("page.kind"), width: 90 },
1870
+ { key: "anchor", label: i("page.anchor"), minWidth: 140 },
1871
+ { key: "host_class", label: i("page.host"), width: 120 }
1872
+ ]), pe = L(() => [
1873
+ { key: "url", label: i("page.address"), minWidth: 220 },
1874
+ { key: "status", label: i("page.field-status"), width: 80 },
1875
+ { key: "bytes", label: i("page.size"), width: 110 },
1876
+ ...q.value === "images" ? [{ key: "alt", label: i("page.alt"), minWidth: 120 }] : [
1877
+ { key: "cache_control", label: i("page.cache"), minWidth: 120 },
1878
+ { key: "compression", label: i("page.field-compression"), width: 100 }
1879
+ ]
1880
+ ]);
1881
+ function Ce(x) {
1882
+ try {
1883
+ return JSON.stringify(JSON.parse(x), null, 2);
1884
+ } catch {
1885
+ return x;
1886
+ }
1887
+ }
1888
+ function Ae(x) {
1889
+ if (x.bytes === null) return "";
1890
+ const G = x.bytes / 1024, y = G >= 1024 ? `${(G / 1024).toFixed(1)} MB` : `${Math.round(G)} KB`;
1891
+ return x.width && x.height ? `${y} · ${x.width}×${x.height}` : y;
1892
+ }
1893
+ const Pe = L(() => {
1894
+ const x = w.value?.page;
1895
+ return x ? [
1896
+ [i("page.field-status"), x.status ?? i("page.status-none")],
1897
+ [i("page.field-final_status"), x.redirect_to ? x.final_status : null],
1898
+ [i("page.field-redirect_to"), x.redirect_to],
1899
+ [i("page.error"), x.error],
1900
+ [i("page.field-content_type"), x.content_type],
1901
+ [i("page.field-bytes"), x.bytes],
1902
+ [i("page.field-ttfb_ms"), x.ttfb_ms],
1903
+ [i("page.field-total_ms"), x.total_ms],
1904
+ [i("page.field-compression"), x.compression],
1905
+ [i("page.field-source"), i(`page.source-${x.source}`)],
1906
+ [i("page.field-depth"), x.depth],
1907
+ [i("page.field-indexable"), x.indexable ? i("page.yes") : i("page.no")],
1908
+ [i("page.field-blocked_by_robots"), x.blocked_by_robots ? i("page.yes") : null],
1909
+ [i("page.field-title"), x.title],
1910
+ [i("page.field-description"), x.description],
1911
+ [i("page.field-h1"), x.h1.join(" · ") || null],
1912
+ [i("page.field-canonical"), x.canonical],
1913
+ [i("page.field-robots_meta"), x.robots_meta],
1914
+ [i("page.field-x_robots_tag"), x.x_robots_tag],
1915
+ [i("page.field-lang"), x.lang],
1916
+ [
1917
+ "hreflang",
1918
+ x.hreflang.length ? { pairs: x.hreflang.map((y) => [y.lang, y.url]) } : null
1919
+ ],
1920
+ [
1921
+ "Open Graph",
1922
+ Object.keys(x.og).length ? { pairs: Object.entries(x.og).map(([y, H]) => [`og:${y}`, String(H)]) } : null
1923
+ ],
1924
+ [
1925
+ "Twitter",
1926
+ Object.keys(x.twitter).length ? {
1927
+ pairs: Object.entries(x.twitter).map(([y, H]) => [
1928
+ `twitter:${y}`,
1929
+ String(H)
1930
+ ])
1931
+ } : null
1932
+ ],
1933
+ [
1934
+ "JSON-LD",
1935
+ x.json_ld.length ? {
1936
+ tags: x.json_ld.flatMap((y) => y.types),
1937
+ error: x.json_ld.find((y) => y.error)?.error ?? null
1938
+ } : null
1939
+ ],
1940
+ [i("page.field-word_count"), x.word_count],
1941
+ [i("page.field-links_in"), x.links_in],
1942
+ [i("page.field-links_out_internal"), x.links_out_internal],
1943
+ [i("page.field-links_out_external"), x.links_out_external],
1944
+ [i("page.field-images"), x.images],
1945
+ [i("page.field-images_without_alt"), x.images_without_alt || null]
1946
+ ].filter(([, y]) => y != null && y !== "").map(([y, H]) => [y, typeof H == "object" ? H : String(H)]) : [];
1947
+ });
1948
+ function be(x) {
1949
+ return x === null || x >= 500 ? "danger" : x >= 400 ? "warning" : x >= 300 ? "info" : "success";
1950
+ }
1951
+ async function ze(x) {
1952
+ clearTimeout(p), f.value = !1, m.value = null, w.value = null, j.value = null, J.value = null, R.value = null, _.value = "overview";
1953
+ try {
1954
+ w.value = await r.page(c.run, x);
1955
+ } catch (G) {
1956
+ j.value = N(G);
1957
+ }
1958
+ }
1959
+ async function We(x) {
1960
+ if (!(c.pageId === null || _.value !== "in" && _.value !== "out")) {
1961
+ X.value = !0;
1962
+ try {
1963
+ J.value = await r.links(c.run, c.pageId, {
1964
+ direction: _.value,
1965
+ page: x.page,
1966
+ per_page: x.perPage
1967
+ });
1968
+ } catch (G) {
1969
+ j.value = N(G);
1970
+ } finally {
1971
+ X.value = !1;
1972
+ }
1973
+ }
1974
+ }
1975
+ async function Ie(x) {
1976
+ const G = q.value;
1977
+ if (!(c.pageId === null || G === null)) {
1978
+ D.value = !0;
1979
+ try {
1980
+ R.value = await r.resources(c.run, c.pageId, {
1981
+ tab: G,
1982
+ page: x.page,
1983
+ per_page: x.perPage
1984
+ });
1985
+ } catch (y) {
1986
+ j.value = N(y);
1987
+ } finally {
1988
+ D.value = !1;
1989
+ }
1990
+ }
1991
+ }
1992
+ return re(
1993
+ () => c.pageId,
1994
+ (x) => {
1995
+ x !== null && ze(x);
1996
+ },
1997
+ { immediate: !0 }
1998
+ ), re(_, () => {
1999
+ J.value = null, R.value = null;
2000
+ }), (x, G) => (t(), u(e(lt), {
2001
+ open: V.value,
2002
+ "onUpdate:open": G[1] || (G[1] = (y) => V.value = y),
2003
+ size: "min(1100px, 75vw)",
2004
+ "min-size": 480,
2005
+ resizable: "",
2006
+ persist: "webx-audit.page-card-wide"
2007
+ }, {
2008
+ title: a(() => [
2009
+ W("span", aa, [
2010
+ w.value ? (t(), u(e(B), {
2011
+ key: 0,
2012
+ type: be(w.value.page.status),
2013
+ size: "sm"
2014
+ }, {
2015
+ default: a(() => [
2016
+ n(s(w.value.page.status ?? "—"), 1)
2017
+ ]),
2018
+ _: 1
2019
+ }, 8, ["type"])) : C("", !0),
2020
+ W("span", sa, s(w.value?.page.url ?? ""), 1)
2021
+ ])
2022
+ ]),
2023
+ extra: a(() => [
2024
+ w.value ? (t(), b("span", la, [
2025
+ e(h) ? (t(), u(e(Q), {
2026
+ key: 0,
2027
+ size: "sm",
2028
+ icon: "refresh",
2029
+ loading: f.value,
2030
+ onClick: P
2031
+ }, {
2032
+ default: a(() => [
2033
+ n(s(e(i)("page.recheck")), 1)
2034
+ ]),
2035
+ _: 1
2036
+ }, 8, ["loading"])) : C("", !0),
2037
+ g(e(Q), {
2038
+ size: "sm",
2039
+ variant: "text",
2040
+ icon: "download",
2041
+ href: e(r).pageFile(c.run, w.value.page.id)
2042
+ }, {
2043
+ default: a(() => [
2044
+ n(s(e(i)("page.export-page")), 1)
2045
+ ]),
2046
+ _: 1
2047
+ }, 8, ["href"]),
2048
+ g(e(xe), {
2049
+ href: w.value.page.url,
2050
+ target: "_blank"
2051
+ }, {
2052
+ default: a(() => [
2053
+ n(s(e(i)("page.open-page")), 1)
2054
+ ]),
2055
+ _: 1
2056
+ }, 8, ["href"])
2057
+ ])) : C("", !0)
2058
+ ]),
2059
+ default: a(() => [
2060
+ j.value ? (t(), u(e(O), {
2061
+ key: 0,
2062
+ tone: "danger"
2063
+ }, {
2064
+ default: a(() => [
2065
+ n(s(j.value), 1)
2066
+ ]),
2067
+ _: 1
2068
+ })) : w.value ? (t(), b("div", na, [
2069
+ f.value ? (t(), u(e(me), {
2070
+ key: 0,
2071
+ type: "info",
2072
+ description: e(i)("page.recheck-running")
2073
+ }, null, 8, ["description"])) : m.value && m.value.status === "done" && m.value.counts ? (t(), u(e(me), {
2074
+ key: 1,
2075
+ type: m.value.counts.new > 0 ? "warning" : "success"
2076
+ }, {
2077
+ default: a(() => [
2078
+ W("div", ia, [
2079
+ W("span", null, s(e(i)("page.recheck-fixed", { count: m.value.counts.fixed })), 1),
2080
+ W("span", null, s(e(i)("page.recheck-new", { count: m.value.counts.new })), 1),
2081
+ c.base ? (t(), u(e(Q), {
2082
+ key: 0,
2083
+ size: "sm",
2084
+ variant: "text",
2085
+ onClick: U
2086
+ }, {
2087
+ default: a(() => [
2088
+ n(s(e(i)("page.recheck-compare")), 1)
2089
+ ]),
2090
+ _: 1
2091
+ })) : C("", !0)
2092
+ ])
2093
+ ]),
2094
+ _: 1
2095
+ }, 8, ["type"])) : m.value ? (t(), u(e(me), {
2096
+ key: 2,
2097
+ type: "danger",
2098
+ description: m.value.error ?? e(i)(`page.status-${m.value.status}`)
2099
+ }, null, 8, ["description"])) : C("", !0),
2100
+ w.value.page.title ? (t(), u(e(O), {
2101
+ key: 3,
2102
+ weight: "semibold"
2103
+ }, {
2104
+ default: a(() => [
2105
+ n(s(w.value.page.title), 1)
2106
+ ]),
2107
+ _: 1
2108
+ })) : C("", !0),
2109
+ g(e(nt), {
2110
+ modelValue: _.value,
2111
+ "onUpdate:modelValue": G[0] || (G[0] = (y) => _.value = y),
2112
+ items: I.value
2113
+ }, {
2114
+ default: a(() => [
2115
+ _.value === "overview" ? (t(), b("dl", ua, [
2116
+ (t(!0), b(F, null, M(Pe.value, ([y, H]) => (t(), b(F, { key: y }, [
2117
+ W("dt", null, s(y), 1),
2118
+ typeof H == "string" ? (t(), b("dd", oa, s(H), 1)) : "pairs" in H ? (t(), b("dd", ra, [
2119
+ (t(!0), b(F, null, M(H.pairs, ([Z, $], E) => (t(), b(F, { key: E }, [
2120
+ g(e(B), {
2121
+ size: "sm",
2122
+ class: "wx-audit-card__key"
2123
+ }, {
2124
+ default: a(() => [
2125
+ n(s(Z), 1)
2126
+ ]),
2127
+ _: 2
2128
+ }, 1024),
2129
+ W("span", null, s($), 1)
2130
+ ], 64))), 128))
2131
+ ])) : (t(), b("dd", da, [
2132
+ (t(!0), b(F, null, M(H.tags, (Z, $) => (t(), u(e(B), {
2133
+ key: $,
2134
+ type: "info",
2135
+ size: "sm"
2136
+ }, {
2137
+ default: a(() => [
2138
+ n(s(Z), 1)
2139
+ ]),
2140
+ _: 2
2141
+ }, 1024))), 128)),
2142
+ H.error ? (t(), u(e(O), {
2143
+ key: 0,
2144
+ size: "sm",
2145
+ tone: "danger"
2146
+ }, {
2147
+ default: a(() => [
2148
+ n(s(H.error), 1)
2149
+ ]),
2150
+ _: 2
2151
+ }, 1024)) : C("", !0)
2152
+ ]))
2153
+ ], 64))), 128)),
2154
+ Object.keys(w.value.page.headers).length ? (t(), b(F, { key: 0 }, [
2155
+ W("dt", ca, s(e(i)("page.headers")), 1),
2156
+ G[2] || (G[2] = W("dd", null, null, -1)),
2157
+ (t(!0), b(F, null, M(w.value.page.headers, (y, H) => (t(), b(F, { key: H }, [
2158
+ W("dt", pa, s(H), 1),
2159
+ W("dd", ga, s(y), 1)
2160
+ ], 64))), 128))
2161
+ ], 64)) : C("", !0)
2162
+ ])) : _.value === "issues" ? (t(), b("div", va, [
2163
+ w.value.issues.length ? C("", !0) : (t(), u(e(O), {
2164
+ key: 0,
2165
+ tone: "muted"
2166
+ }, {
2167
+ default: a(() => [
2168
+ n(s(e(i)("page.no-issues")), 1)
2169
+ ]),
2170
+ _: 1
2171
+ })),
2172
+ (t(!0), b(F, null, M(w.value.issues, (y) => (t(), b("div", {
2173
+ key: y.id,
2174
+ class: "wx-audit-card__issue"
2175
+ }, [
2176
+ W("div", fa, [
2177
+ g(e(B), {
2178
+ type: he[y.severity],
2179
+ dot: ""
2180
+ }, {
2181
+ default: a(() => [
2182
+ n(s(e(i)(`page.severity-${y.severity}`)), 1)
2183
+ ]),
2184
+ _: 2
2185
+ }, 1032, ["type"]),
2186
+ g(e(O), {
2187
+ size: "sm",
2188
+ weight: "semibold"
2189
+ }, {
2190
+ default: a(() => [
2191
+ n(s(c.titles[y.check] ?? y.check), 1)
2192
+ ]),
2193
+ _: 2
2194
+ }, 1024),
2195
+ y.state === "new" ? (t(), u(e(B), {
2196
+ key: 0,
2197
+ type: "primary",
2198
+ size: "sm"
2199
+ }, {
2200
+ default: a(() => [
2201
+ n(s(e(i)("page.state-new")), 1)
2202
+ ]),
2203
+ _: 1
2204
+ })) : C("", !0)
2205
+ ]),
2206
+ g(Ve, {
2207
+ details: y.details
2208
+ }, null, 8, ["details"])
2209
+ ]))), 128))
2210
+ ])) : q.value ? (t(), u(e(ve), {
2211
+ key: `resources-${String(_.value)}`,
2212
+ data: R.value,
2213
+ columns: pe.value,
2214
+ "row-key": "id",
2215
+ flush: "",
2216
+ loading: D.value,
2217
+ "per-page-options": [],
2218
+ "empty-text": e(i)("page.no-resources"),
2219
+ onStateChange: Ie
2220
+ }, {
2221
+ "cell-url": a(({ row: y }) => [
2222
+ q.value === "images" ? (t(), b("span", ha, [
2223
+ g(e(it), {
2224
+ src: y.url,
2225
+ alt: y.alt ?? "",
2226
+ width: 48,
2227
+ height: 48,
2228
+ fit: "cover",
2229
+ radius: "var(--wx-radius-sm)",
2230
+ preview: "",
2231
+ "preview-label": e(i)("page.view-full"),
2232
+ class: "wx-audit-card__thumb"
2233
+ }, null, 8, ["src", "alt", "preview-label"]),
2234
+ W("span", ma, s(y.url), 1)
2235
+ ])) : (t(), b("span", _a, s(y.url), 1)),
2236
+ y.location ? (t(), u(e(O), {
2237
+ key: 2,
2238
+ size: "sm",
2239
+ tone: "muted",
2240
+ class: "wx-audit-card__url"
2241
+ }, {
2242
+ default: a(() => [
2243
+ n(" → " + s(y.location), 1)
2244
+ ]),
2245
+ _: 2
2246
+ }, 1024)) : C("", !0),
2247
+ y.error ? (t(), u(e(O), {
2248
+ key: 3,
2249
+ size: "sm",
2250
+ tone: "danger"
2251
+ }, {
2252
+ default: a(() => [
2253
+ n(s(y.error), 1)
2254
+ ]),
2255
+ _: 2
2256
+ }, 1024)) : C("", !0)
2257
+ ]),
2258
+ "cell-status": a(({ row: y }) => [
2259
+ y.status !== null ? (t(), u(e(B), {
2260
+ key: 0,
2261
+ type: be(y.status),
2262
+ size: "sm"
2263
+ }, {
2264
+ default: a(() => [
2265
+ n(s(y.status), 1)
2266
+ ]),
2267
+ _: 2
2268
+ }, 1032, ["type"])) : y.checked ? (t(), u(e(B), {
2269
+ key: 1,
2270
+ type: "danger",
2271
+ size: "sm"
2272
+ }, {
2273
+ default: a(() => [...G[3] || (G[3] = [
2274
+ n("—", -1)
2275
+ ])]),
2276
+ _: 1
2277
+ })) : (t(), u(e(O), {
2278
+ key: 2,
2279
+ size: "sm",
2280
+ tone: "muted"
2281
+ }, {
2282
+ default: a(() => [
2283
+ n(s(e(i)("page.not-checked")), 1)
2284
+ ]),
2285
+ _: 1
2286
+ }))
2287
+ ]),
2288
+ "cell-bytes": a(({ row: y }) => [
2289
+ n(s(Ae(y)), 1)
2290
+ ]),
2291
+ "cell-alt": a(({ row: y }) => [
2292
+ y.alt === null && y.kind === "img" ? (t(), u(e(O), {
2293
+ key: 0,
2294
+ size: "sm",
2295
+ tone: "danger"
2296
+ }, {
2297
+ default: a(() => [
2298
+ n(s(e(i)("page.missing")), 1)
2299
+ ]),
2300
+ _: 1
2301
+ })) : (t(), b(F, { key: 1 }, [
2302
+ n(s(y.alt ?? ""), 1)
2303
+ ], 64))
2304
+ ]),
2305
+ _: 1
2306
+ }, 8, ["data", "columns", "loading", "empty-text"])) : _.value === "microdata" ? (t(), b("div", ya, [
2307
+ w.value.page.json_ld.length ? C("", !0) : (t(), u(e(O), {
2308
+ key: 0,
2309
+ tone: "muted"
2310
+ }, {
2311
+ default: a(() => [
2312
+ n(s(e(i)("page.no-json-ld")), 1)
2313
+ ]),
2314
+ _: 1
2315
+ })),
2316
+ (t(!0), b(F, null, M(w.value.page.json_ld, (y, H) => (t(), b("div", {
2317
+ key: H,
2318
+ class: "wx-audit-card__issue"
2319
+ }, [
2320
+ W("div", ba, [
2321
+ g(e(O), {
2322
+ size: "sm",
2323
+ weight: "semibold"
2324
+ }, {
2325
+ default: a(() => [
2326
+ n(s(e(i)("page.jsonld-block", { number: H + 1 })), 1)
2327
+ ]),
2328
+ _: 2
2329
+ }, 1024),
2330
+ (t(!0), b(F, null, M(y.types, (Z) => (t(), u(e(B), {
2331
+ key: Z,
2332
+ size: "sm"
2333
+ }, {
2334
+ default: a(() => [
2335
+ n(s(Z), 1)
2336
+ ]),
2337
+ _: 2
2338
+ }, 1024))), 128))
2339
+ ]),
2340
+ y.error ? (t(), u(e(O), {
2341
+ key: 0,
2342
+ size: "sm",
2343
+ tone: "danger"
2344
+ }, {
2345
+ default: a(() => [
2346
+ n(s(e(i)("page.jsonld-error")) + " " + s(y.error), 1)
2347
+ ]),
2348
+ _: 2
2349
+ }, 1024)) : C("", !0),
2350
+ (t(!0), b(F, null, M(y.items ?? [], (Z, $) => (t(), b(F, { key: $ }, [
2351
+ Z.missing.length ? (t(), u(e(O), {
2352
+ key: 0,
2353
+ size: "sm",
2354
+ tone: "danger"
2355
+ }, {
2356
+ default: a(() => [
2357
+ n(s(Z.type) + " — " + s(e(i)("page.jsonld-required")) + " " + s(Z.missing.join(", ")), 1)
2358
+ ]),
2359
+ _: 2
2360
+ }, 1024)) : C("", !0),
2361
+ Z.recommended.length ? (t(), u(e(O), {
2362
+ key: 1,
2363
+ size: "sm",
2364
+ tone: "muted"
2365
+ }, {
2366
+ default: a(() => [
2367
+ n(s(Z.type) + " — " + s(e(i)("page.jsonld-recommended")) + " " + s(Z.recommended.join(", ")), 1)
2368
+ ]),
2369
+ _: 2
2370
+ }, 1024)) : C("", !0),
2371
+ !Z.missing.length && !Z.recommended.length ? (t(), u(e(O), {
2372
+ key: 2,
2373
+ size: "sm",
2374
+ tone: "success"
2375
+ }, {
2376
+ default: a(() => [
2377
+ n(s(Z.type) + " — " + s(e(i)("page.jsonld-complete")), 1)
2378
+ ]),
2379
+ _: 2
2380
+ }, 1024)) : C("", !0)
2381
+ ], 64))), 128)),
2382
+ y.source ? (t(), b("pre", ka, s(Ce(y.source)), 1)) : C("", !0)
2383
+ ]))), 128))
2384
+ ])) : (t(), u(e(ve), {
2385
+ key: String(_.value),
2386
+ data: J.value,
2387
+ columns: $e.value,
2388
+ "row-key": "id",
2389
+ flush: "",
2390
+ loading: X.value,
2391
+ "per-page-options": [],
2392
+ "empty-text": e(i)("page.no-links"),
2393
+ onStateChange: We
2394
+ }, {
2395
+ "cell-url": a(({ row: y }) => [
2396
+ W("span", xa, s(y.url ?? "—"), 1)
2397
+ ]),
2398
+ "cell-status": a(({ row: y }) => [
2399
+ y.status !== null ? (t(), u(e(B), {
2400
+ key: 0,
2401
+ type: be(y.status),
2402
+ size: "sm"
2403
+ }, {
2404
+ default: a(() => [
2405
+ n(s(y.status), 1)
2406
+ ]),
2407
+ _: 2
2408
+ }, 1032, ["type"])) : C("", !0)
2409
+ ]),
2410
+ "cell-host_class": a(({ row: y }) => [
2411
+ y.host_class ? (t(), u(e(B), {
2412
+ key: 0,
2413
+ type: ye[y.host_class] ?? "info",
2414
+ size: "sm"
2415
+ }, {
2416
+ default: a(() => [
2417
+ n(s(e(i)(`page.host-${y.host_class}`)), 1)
2418
+ ]),
2419
+ _: 2
2420
+ }, 1032, ["type"])) : C("", !0)
2421
+ ]),
2422
+ _: 1
2423
+ }, 8, ["data", "columns", "loading", "empty-text"]))
2424
+ ]),
2425
+ _: 1
2426
+ }, 8, ["modelValue", "items"])
2427
+ ])) : (t(), u(e(fe), {
2428
+ key: 1,
2429
+ rows: 6
2430
+ }))
2431
+ ]),
2432
+ _: 1
2433
+ }, 8, ["open"]));
2434
+ }
2435
+ }), za = /* @__PURE__ */ ie($a, [["__scopeId", "data-v-46e97525"]]), ae = {
2436
+ url: "url",
2437
+ status: "status",
2438
+ final_status: "status",
2439
+ redirect_to: "url",
2440
+ source: "source",
2441
+ depth: "number",
2442
+ indexable: "bool",
2443
+ issues: "number",
2444
+ title: "text",
2445
+ description: "text",
2446
+ h1: "text",
2447
+ canonical: "url",
2448
+ robots_meta: "text",
2449
+ x_robots_tag: "text",
2450
+ lang: "text",
2451
+ content_type: "text",
2452
+ bytes: "number",
2453
+ ttfb_ms: "number",
2454
+ total_ms: "number",
2455
+ compression: "text",
2456
+ word_count: "number",
2457
+ links_in: "number",
2458
+ links_out_internal: "number",
2459
+ links_out_external: "number",
2460
+ images: "number",
2461
+ images_without_alt: "number",
2462
+ in_sitemap: "bool",
2463
+ in_registry: "bool",
2464
+ blocked_by_robots: "bool"
2465
+ }, Sa = [
2466
+ "url",
2467
+ "status",
2468
+ "indexable",
2469
+ "title",
2470
+ "word_count",
2471
+ "links_in",
2472
+ "issues"
2473
+ ], Le = ["h1"], De = {
2474
+ url: ["contains", "eq", "empty", "filled"],
2475
+ text: ["contains", "eq", "empty", "filled"],
2476
+ number: ["gt", "lt", "eq", "empty"],
2477
+ status: ["eq", "gt", "lt", "empty"],
2478
+ bool: ["yes", "no"],
2479
+ source: ["eq"]
2480
+ }, Ue = ["contains", "eq", "gt", "lt"], Ca = ["home", "sitemap", "registry", "link"], Aa = { class: "wx-audit-pages__filters" }, qe = "webx-audit.pages.columns", Pa = /* @__PURE__ */ se({
2481
+ __name: "AuditPagesPage",
2482
+ props: {
2483
+ base: {}
2484
+ },
2485
+ setup(k) {
2486
+ const v = k, c = oe(le());
2487
+ ne();
2488
+ const o = ee("webx-audit"), l = ee("webx-admin"), r = ue(), d = tt(), h = S(null), m = S(!1), f = S(null), p = S(!1), P = S(null), A = S({}), U = S(null), i = S(null), N = S(null), w = S([]);
2489
+ let j = { page: 1, perPage: 50, sort: null, search: "" };
2490
+ const _ = S(J());
2491
+ function J() {
2492
+ try {
2493
+ const $ = JSON.parse(window.localStorage.getItem(qe) ?? "null");
2494
+ if (Array.isArray($)) {
2495
+ const E = $.filter((T) => T in ae);
2496
+ if (E.length) return E;
2497
+ }
2498
+ } catch {
2499
+ }
2500
+ return [...Sa];
2501
+ }
2502
+ re(_, ($) => {
2503
+ try {
2504
+ window.localStorage.setItem(qe, JSON.stringify($));
2505
+ } catch {
2506
+ }
2507
+ });
2508
+ const X = Object.keys(ae), R = L(
2509
+ () => X.map(($) => ({ value: $, label: o(`page.field-${$}`) }))
2510
+ ), D = L(
2511
+ () => X.filter(($) => !Le.includes($)).map(($) => ({ value: $, label: o(`page.field-${$}`) }))
2512
+ ), z = L(
2513
+ () => (
2514
+ /* The picker keeps the order things were ticked in; the table keeps the card's order. */
2515
+ X.filter(($) => _.value.includes($)).map(($) => ({
2516
+ key: $,
2517
+ label: o(`page.field-${$}`),
2518
+ sortable: !Le.includes($),
2519
+ minWidth: ae[$] === "url" || ae[$] === "text" ? 220 : void 0,
2520
+ align: ae[$] === "number" ? "right" : void 0
2521
+ }))
2522
+ )
2523
+ ), V = L(() => [
2524
+ ...["2xx", "3xx", "4xx", "5xx"].map(($) => ({ value: $, label: $ })),
2525
+ { value: "none", label: o("page.status-none") }
2526
+ ]), I = L(() => [
2527
+ { value: "1", label: o("page.indexable-yes") },
2528
+ { value: "0", label: o("page.indexable-no") }
2529
+ ]), q = L(
2530
+ () => Object.entries(A.value).map(([$, E]) => ({ value: $, label: E }))
2531
+ ), he = L(
2532
+ () => [U.value, i.value, N.value].filter(Boolean).length + w.value.filter($e).length
2533
+ ), ye = L(() => ({
2534
+ status: U.value,
2535
+ indexable: i.value === null ? null : i.value === "1",
2536
+ check: N.value,
2537
+ filters: w.value.filter($e)
2538
+ }));
2539
+ function $e($) {
2540
+ return !Ue.includes($.op) || ($.value ?? "").trim() !== "";
2541
+ }
2542
+ function pe($) {
2543
+ return typeof $ == "string" && $ !== "" ? $ : null;
2544
+ }
2545
+ function Ce($) {
2546
+ return De[ae[$]].map((E) => ({ value: E, label: o(`page.op-${E}`) }));
2547
+ }
2548
+ function Ae() {
2549
+ w.value = [...w.value, { field: "title", op: "empty" }];
2550
+ }
2551
+ function Pe($, E) {
2552
+ const T = pe(E);
2553
+ T && (w.value = w.value.map(
2554
+ (K, te) => te === $ ? { field: T, op: De[ae[T]][0], value: "" } : K
2555
+ ));
2556
+ }
2557
+ function be($, E) {
2558
+ const T = pe(E);
2559
+ T && (w.value = w.value.map((K, te) => te === $ ? { ...K, op: T } : K));
2560
+ }
2561
+ function ze($, E) {
2562
+ w.value = w.value.map((T, K) => K === $ ? { ...T, value: E } : T);
2563
+ }
2564
+ function We($) {
2565
+ w.value = w.value.filter((E, T) => T !== $);
2566
+ }
2567
+ function Ie($) {
2568
+ const E = $.filter((T) => String(T) in ae);
2569
+ _.value = E.length ? E : ["url"];
2570
+ }
2571
+ const x = {
2572
+ 2: "success",
2573
+ 3: "info",
2574
+ 4: "warning",
2575
+ 5: "danger"
2576
+ };
2577
+ function G($) {
2578
+ return x[String($ ?? "").charAt(0)] ?? "danger";
2579
+ }
2580
+ function y($) {
2581
+ return $ == null || $ === "" ? "—" : String($);
2582
+ }
2583
+ async function H($ = j) {
2584
+ if (j = $, h.value !== null) {
2585
+ p.value = !0;
2586
+ try {
2587
+ f.value = await c.pages(h.value.id, {
2588
+ ...ye.value,
2589
+ search: $.search,
2590
+ sort: $.sort ? `${$.sort.order === "desc" ? "-" : ""}${$.sort.key}` : null,
2591
+ page: $.page,
2592
+ per_page: $.perPage
2593
+ });
2594
+ } catch (E) {
2595
+ Y.danger(r(E));
2596
+ } finally {
2597
+ p.value = !1;
2598
+ }
2599
+ }
2600
+ }
2601
+ function Z() {
2602
+ h.value !== null && window.location.assign(
2603
+ c.pagesFile(
2604
+ h.value.id,
2605
+ { ...ye.value, search: j.search },
2606
+ z.value.map(($) => $.key)
2607
+ )
2608
+ );
2609
+ }
2610
+ return re(ye, () => {
2611
+ H({ ...j, page: 1 });
2612
+ }, { deep: !0 }), ge(async () => {
2613
+ try {
2614
+ if (h.value = (await c.latest()).crawled, h.value !== null) {
2615
+ const $ = await c.checks(h.value.id);
2616
+ A.value = Object.fromEntries($.map((E) => [E.id, E.title]));
2617
+ }
2618
+ } catch ($) {
2619
+ Y.danger(r($));
2620
+ } finally {
2621
+ m.value = !0;
2622
+ }
2623
+ H();
2624
+ }), ($, E) => (t(), u(_e, {
2625
+ base: v.base,
2626
+ current: "pages"
2627
+ }, {
2628
+ default: a(() => [
2629
+ m.value && h.value === null ? (t(), u(e(O), {
2630
+ key: 0,
2631
+ tone: "muted",
2632
+ class: "wx-audit-pages__none"
2633
+ }, {
2634
+ default: a(() => [
2635
+ n(s(e(o)("page.pages-none")), 1)
2636
+ ]),
2637
+ _: 1
2638
+ })) : (t(), u(e(ve), {
2639
+ key: 1,
2640
+ data: f.value,
2641
+ columns: z.value,
2642
+ "row-key": "id",
2643
+ searchable: "",
2644
+ clickable: "",
2645
+ hover: "",
2646
+ flush: "",
2647
+ loading: p.value || !m.value,
2648
+ "per-page-options": [50, 100, 200],
2649
+ "search-placeholder": e(o)("page.search-url"),
2650
+ "filters-count": he.value,
2651
+ "filters-label": e(l)("filters.title"),
2652
+ "filters-width": 420,
2653
+ "empty-text": e(o)("page.empty"),
2654
+ onStateChange: H,
2655
+ onRowClick: E[3] || (E[3] = (T) => P.value = T.id)
2656
+ }, Ze({
2657
+ title: a(() => [
2658
+ h.value ? (t(), u(e(O), {
2659
+ key: 0,
2660
+ size: "sm",
2661
+ tone: "muted"
2662
+ }, {
2663
+ default: a(() => [
2664
+ n(s(e(o)("page.pages-run", { date: e(d).short(h.value.finished_at) })), 1)
2665
+ ]),
2666
+ _: 1
2667
+ })) : C("", !0)
2668
+ ]),
2669
+ actions: a(() => [
2670
+ g(e(Ge), {
2671
+ title: e(o)("page.columns"),
2672
+ width: "300"
2673
+ }, {
2674
+ trigger: a(() => [
2675
+ g(e(Q), {
2676
+ size: "sm",
2677
+ variant: "text",
2678
+ icon: "sliders"
2679
+ }, {
2680
+ default: a(() => [
2681
+ n(s(e(o)("page.columns")), 1)
2682
+ ]),
2683
+ _: 1
2684
+ })
2685
+ ]),
2686
+ default: a(() => [
2687
+ g(e(ut), {
2688
+ "model-value": _.value,
2689
+ options: R.value,
2690
+ size: "sm",
2691
+ class: "wx-audit-pages__picker",
2692
+ "onUpdate:modelValue": Ie
2693
+ }, null, 8, ["model-value", "options"])
2694
+ ]),
2695
+ _: 1
2696
+ }, 8, ["title"]),
2697
+ g(e(Q), {
2698
+ size: "sm",
2699
+ variant: "text",
2700
+ icon: "download",
2701
+ disabled: !h.value,
2702
+ onClick: Z
2703
+ }, {
2704
+ default: a(() => [
2705
+ n(s(e(o)("page.export")), 1)
2706
+ ]),
2707
+ _: 1
2708
+ }, 8, ["disabled"])
2709
+ ]),
2710
+ filters: a(() => [
2711
+ W("div", Aa, [
2712
+ g(e(ce), {
2713
+ "model-value": U.value,
2714
+ options: V.value,
2715
+ placeholder: e(o)("page.any-status"),
2716
+ clearable: "",
2717
+ "onUpdate:modelValue": E[0] || (E[0] = (T) => U.value = pe(T))
2718
+ }, null, 8, ["model-value", "options", "placeholder"]),
2719
+ g(e(ce), {
2720
+ "model-value": i.value,
2721
+ options: I.value,
2722
+ placeholder: e(o)("page.any-indexable"),
2723
+ clearable: "",
2724
+ "onUpdate:modelValue": E[1] || (E[1] = (T) => i.value = pe(T))
2725
+ }, null, 8, ["model-value", "options", "placeholder"]),
2726
+ g(e(ce), {
2727
+ "model-value": N.value,
2728
+ options: q.value,
2729
+ placeholder: e(o)("page.any-check"),
2730
+ clearable: "",
2731
+ filterable: "",
2732
+ "onUpdate:modelValue": E[2] || (E[2] = (T) => N.value = pe(T))
2733
+ }, null, 8, ["model-value", "options", "placeholder"]),
2734
+ (t(!0), b(F, null, M(w.value, (T, K) => (t(), b("div", {
2735
+ key: K,
2736
+ class: "wx-audit-pages__filter"
2737
+ }, [
2738
+ g(e(ce), {
2739
+ "model-value": T.field,
2740
+ options: D.value,
2741
+ filterable: "",
2742
+ size: "sm",
2743
+ "onUpdate:modelValue": (te) => Pe(K, te)
2744
+ }, null, 8, ["model-value", "options", "onUpdate:modelValue"]),
2745
+ g(e(ce), {
2746
+ "model-value": T.op,
2747
+ options: Ce(T.field),
2748
+ size: "sm",
2749
+ "onUpdate:modelValue": (te) => be(K, te)
2750
+ }, null, 8, ["model-value", "options", "onUpdate:modelValue"]),
2751
+ e(Ue).includes(T.op) && e(ae)[T.field] === "source" ? (t(), u(e(ce), {
2752
+ key: 0,
2753
+ "model-value": T.value ?? null,
2754
+ options: e(Ca).map((te) => ({ value: te, label: e(o)(`page.source-${te}`) })),
2755
+ size: "sm",
2756
+ "onUpdate:modelValue": (te) => ze(K, pe(te) ?? "")
2757
+ }, null, 8, ["model-value", "options", "onUpdate:modelValue"])) : e(Ue).includes(T.op) ? (t(), u(e(Je), {
2758
+ key: 1,
2759
+ "model-value": T.value ?? "",
2760
+ placeholder: e(o)("page.value"),
2761
+ size: "sm",
2762
+ "onUpdate:modelValue": (te) => ze(K, String(te ?? ""))
2763
+ }, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"])) : C("", !0),
2764
+ g(e(Q), {
2765
+ size: "sm",
2766
+ variant: "text",
2767
+ icon: "close",
2768
+ "aria-label": e(o)("page.remove-filter"),
2769
+ onClick: (te) => We(K)
2770
+ }, null, 8, ["aria-label", "onClick"])
2771
+ ]))), 128)),
2772
+ g(e(Q), {
2773
+ size: "sm",
2774
+ variant: "text",
2775
+ icon: "plus",
2776
+ onClick: Ae
2777
+ }, {
2778
+ default: a(() => [
2779
+ n(s(e(o)("page.add-filter")), 1)
2780
+ ]),
2781
+ _: 1
2782
+ })
2783
+ ])
2784
+ ]),
2785
+ _: 2
2786
+ }, [
2787
+ M(_.value, (T) => ({
2788
+ name: `cell-${T}`,
2789
+ fn: a(({ row: K }) => [
2790
+ e(ae)[T] === "status" && K[T] !== null ? (t(), u(e(B), {
2791
+ key: 0,
2792
+ type: G(K[T]),
2793
+ size: "sm"
2794
+ }, {
2795
+ default: a(() => [
2796
+ n(s(K[T]), 1)
2797
+ ]),
2798
+ _: 2
2799
+ }, 1032, ["type"])) : e(ae)[T] === "status" ? (t(), u(e(O), {
2800
+ key: 1,
2801
+ size: "sm",
2802
+ tone: "danger"
2803
+ }, {
2804
+ default: a(() => [
2805
+ n(s(e(o)("page.status-none")), 1)
2806
+ ]),
2807
+ _: 1
2808
+ })) : e(ae)[T] === "bool" ? (t(), b(F, { key: 2 }, [
2809
+ n(s(K[T] ? e(o)("page.yes") : e(o)("page.no")), 1)
2810
+ ], 64)) : e(ae)[T] === "source" ? (t(), b(F, { key: 3 }, [
2811
+ n(s(e(o)(`page.source-${K[T]}`)), 1)
2812
+ ], 64)) : T === "issues" && K.issues > 0 ? (t(), u(e(B), {
2813
+ key: 4,
2814
+ type: "warning",
2815
+ size: "sm"
2816
+ }, {
2817
+ default: a(() => [
2818
+ n(s(K.issues), 1)
2819
+ ]),
2820
+ _: 2
2821
+ }, 1024)) : (t(), b("span", {
2822
+ key: 5,
2823
+ class: Be({ "wx-audit-pages__long": e(ae)[T] === "url" })
2824
+ }, s(y(K[T])), 3))
2825
+ ])
2826
+ }))
2827
+ ]), 1032, ["data", "columns", "loading", "search-placeholder", "filters-count", "filters-label", "empty-text"])),
2828
+ h.value ? (t(), u(za, {
2829
+ key: 2,
2830
+ run: h.value.id,
2831
+ base: v.base,
2832
+ "page-id": P.value,
2833
+ titles: A.value,
2834
+ onClose: E[4] || (E[4] = (T) => P.value = null)
2835
+ }, null, 8, ["run", "base", "page-id", "titles"])) : C("", !0)
2836
+ ]),
2837
+ _: 1
2838
+ }, 8, ["base"]));
2839
+ }
2840
+ }), Wa = /* @__PURE__ */ ie(Pa, [["__scopeId", "data-v-7850735f"]]), Ia = { class: "wx-audit-compare" }, Oa = /* @__PURE__ */ se({
2841
+ __name: "AuditCompareIssues",
2842
+ props: {
2843
+ from: {},
2844
+ to: {},
2845
+ row: {}
2846
+ },
2847
+ setup(k) {
2848
+ const v = k, c = oe(le());
2849
+ ne();
2850
+ const o = ee("webx-audit"), l = ue(), r = ["new", "fixed", "persisting"], d = S(r.find((U) => v.row[U] > 0) ?? "new"), h = S(null), m = S(1), f = S(!1), p = S(null), P = L(
2851
+ () => r.map((U) => ({
2852
+ value: U,
2853
+ label: `${o(`page.kind-${U}`)} · ${v.row[U]}`,
2854
+ disabled: v.row[U] === 0
2855
+ }))
2856
+ );
2857
+ async function A(U = 1) {
2858
+ p.value = null;
2859
+ try {
2860
+ const i = await c.compareIssues({
2861
+ from: v.from,
2862
+ to: v.to,
2863
+ kind: d.value,
2864
+ check: v.row.check,
2865
+ page: U,
2866
+ per_page: 50
2867
+ });
2868
+ h.value = U === 1 ? i.data : [...h.value ?? [], ...i.data], m.value = i.current_page, f.value = i.current_page < i.last_page;
2869
+ } catch (i) {
2870
+ p.value = l(i);
2871
+ }
2872
+ }
2873
+ return re(
2874
+ d,
2875
+ () => {
2876
+ h.value = null, A();
2877
+ },
2878
+ { immediate: !0 }
2879
+ ), (U, i) => (t(), b("div", Ia, [
2880
+ g(e(Ke), {
2881
+ modelValue: d.value,
2882
+ "onUpdate:modelValue": i[0] || (i[0] = (N) => d.value = N),
2883
+ options: P.value,
2884
+ size: "sm",
2885
+ "aria-label": e(o)("page.compare")
2886
+ }, null, 8, ["modelValue", "options", "aria-label"]),
2887
+ p.value ? (t(), u(e(O), {
2888
+ key: 0,
2889
+ size: "sm",
2890
+ tone: "danger"
2891
+ }, {
2892
+ default: a(() => [
2893
+ n(s(p.value), 1)
2894
+ ]),
2895
+ _: 1
2896
+ })) : h.value ? (t(), b(F, { key: 2 }, [
2897
+ (t(!0), b(F, null, M(h.value, (N) => (t(), b("div", {
2898
+ key: N.id,
2899
+ class: "wx-audit-compare__item"
2900
+ }, [
2901
+ N.url ? (t(), u(e(xe), {
2902
+ key: 0,
2903
+ href: N.url,
2904
+ target: "_blank",
2905
+ class: "wx-audit-compare__url"
2906
+ }, {
2907
+ default: a(() => [
2908
+ n(s(N.url), 1)
2909
+ ]),
2910
+ _: 2
2911
+ }, 1032, ["href"])) : C("", !0),
2912
+ g(Ve, {
2913
+ details: N.details
2914
+ }, null, 8, ["details"])
2915
+ ]))), 128)),
2916
+ f.value ? (t(), u(e(Q), {
2917
+ key: 0,
2918
+ size: "sm",
2919
+ variant: "text",
2920
+ onClick: i[1] || (i[1] = (N) => A(m.value + 1))
2921
+ }, {
2922
+ default: a(() => [...i[2] || (i[2] = [
2923
+ n("…", -1)
2924
+ ])]),
2925
+ _: 1
2926
+ })) : C("", !0)
2927
+ ], 64)) : (t(), u(e(fe), {
2928
+ key: 1,
2929
+ rows: 2
2930
+ }))
2931
+ ]));
2932
+ }
2933
+ }), Ua = /* @__PURE__ */ ie(Oa, [["__scopeId", "data-v-02d42bdb"]]), Va = { class: "wx-audit-runs" }, Na = {
2934
+ key: 0,
2935
+ class: "wx-audit-runs__counts"
2936
+ }, ja = /* @__PURE__ */ se({
2937
+ __name: "AuditRunsPage",
2938
+ props: {
2939
+ base: {}
2940
+ },
2941
+ setup(k) {
2942
+ const v = k, c = oe(le()), o = Qe();
2943
+ ne();
2944
+ const l = ee("webx-audit"), r = ue(), d = S(null), h = S(!1), m = S([]), f = S(null), p = S(!1), P = S([]), A = {
2945
+ queued: "info",
2946
+ running: "primary",
2947
+ done: "success",
2948
+ failed: "danger",
2949
+ cancelled: "warning"
2950
+ }, U = {
2951
+ error: "danger",
2952
+ warning: "warning",
2953
+ notice: "info"
2954
+ }, i = L(() => [
2955
+ { key: "id", label: l("page.run-id"), width: 90 },
2956
+ { key: "created_at", label: l("page.started-at"), minWidth: 160 },
2957
+ { key: "scope", label: l("page.scope"), width: 120 },
2958
+ { key: "status", label: l("page.status"), width: 130 },
2959
+ { key: "health", label: l("page.health"), width: 100, align: "right" },
2960
+ { key: "severity", label: l("page.severity"), minWidth: 170, hideBelow: 640 },
2961
+ { key: "started_by", label: l("page.started-by"), minWidth: 130, hideBelow: 760 }
2962
+ ]), N = L(() => [
2963
+ { key: "severity", label: l("page.severity"), width: 130 },
2964
+ { key: "title", label: l("page.check") },
2965
+ { key: "new", label: l("page.kind-new"), width: 90, align: "right" },
2966
+ { key: "fixed", label: l("page.kind-fixed"), width: 100, align: "right" },
2967
+ { key: "persisting", label: l("page.kind-persisting"), width: 120, align: "right" }
2968
+ ]), w = L(() => {
2969
+ const R = m.value.map(Number).sort((D, z) => D - z);
2970
+ return R.length === 0 ? null : R.length === 1 ? { to: R[0], from: null } : { to: R[R.length - 1], from: R[0] };
2971
+ }), j = L(
2972
+ () => f.value !== null && f.value.from.scope !== f.value.to.scope
2973
+ );
2974
+ function _(R) {
2975
+ return R.started_by === "schedule" ? l("page.by-schedule") : R.started_by === "mcp" ? l("page.by-mcp") : R.started_by === "console" ? l("page.by-console") : R.started_by ? l("page.by-person") : "";
2976
+ }
2977
+ async function J(R) {
2978
+ h.value = !0;
2979
+ try {
2980
+ d.value = await c.runs({ page: R?.page ?? 1, per_page: R?.perPage ?? 20 });
2981
+ } catch (D) {
2982
+ Y.danger(r(D));
2983
+ } finally {
2984
+ h.value = !1;
2985
+ }
2986
+ }
2987
+ async function X() {
2988
+ const R = w.value;
2989
+ if (f.value = null, P.value = [], !!R) {
2990
+ p.value = !0;
2991
+ try {
2992
+ f.value = await c.compare(R.to, R.from);
2993
+ } catch (D) {
2994
+ Y.danger(r(D));
2995
+ } finally {
2996
+ p.value = !1;
2997
+ }
2998
+ }
2999
+ }
3000
+ return ge(() => {
3001
+ const R = Number(o.query.to);
3002
+ Number.isInteger(R) && R > 0 && (m.value = [R]);
3003
+ }), re(m, (R) => {
3004
+ R.length > 2 ? m.value = R.slice(-2) : X();
3005
+ }), (R, D) => (t(), u(_e, {
3006
+ base: v.base,
3007
+ current: "runs",
3008
+ card: !1
3009
+ }, {
3010
+ default: a(() => [
3011
+ W("div", Va, [
3012
+ g(e(de), null, {
3013
+ default: a(() => [
3014
+ g(e(ve), {
3015
+ selected: m.value,
3016
+ "onUpdate:selected": D[0] || (D[0] = (z) => m.value = z),
3017
+ data: d.value,
3018
+ columns: i.value,
3019
+ "row-key": "id",
3020
+ selectable: "",
3021
+ "selectable-if": (z) => z.status === "done",
3022
+ flush: "",
3023
+ loading: h.value,
3024
+ "empty-text": e(l)("page.runs-empty"),
3025
+ onStateChange: J
3026
+ }, {
3027
+ "cell-created_at": a(({ row: z }) => [
3028
+ g(e(ke), {
3029
+ value: z.created_at
3030
+ }, null, 8, ["value"])
3031
+ ]),
3032
+ "cell-scope": a(({ row: z }) => [
3033
+ n(s(e(l)(`page.scope-${z.scope}`)), 1)
3034
+ ]),
3035
+ "cell-status": a(({ row: z }) => [
3036
+ g(e(B), {
3037
+ type: A[z.status],
3038
+ dot: ""
3039
+ }, {
3040
+ default: a(() => [
3041
+ n(s(e(l)(`page.status-${z.status}`)), 1)
3042
+ ]),
3043
+ _: 2
3044
+ }, 1032, ["type"])
3045
+ ]),
3046
+ "cell-health": a(({ row: z }) => [
3047
+ n(s(z.counts ? `${z.counts.health}%` : ""), 1)
3048
+ ]),
3049
+ "cell-severity": a(({ row: z }) => [
3050
+ z.counts ? (t(), b("span", Na, [
3051
+ (t(), b(F, null, M(U, (V, I) => (t(), b(F, { key: I }, [
3052
+ z.counts.severity[I] ? (t(), u(e(B), {
3053
+ key: 0,
3054
+ type: V,
3055
+ size: "sm"
3056
+ }, {
3057
+ default: a(() => [
3058
+ n(s(z.counts.severity[I]), 1)
3059
+ ]),
3060
+ _: 2
3061
+ }, 1032, ["type"])) : C("", !0)
3062
+ ], 64))), 64))
3063
+ ])) : C("", !0)
3064
+ ]),
3065
+ "cell-started_by": a(({ row: z }) => [
3066
+ n(s(_(z)), 1)
3067
+ ]),
3068
+ _: 1
3069
+ }, 8, ["selected", "data", "columns", "selectable-if", "loading", "empty-text"])
3070
+ ]),
3071
+ _: 1
3072
+ }),
3073
+ w.value ? (t(), u(e(de), {
3074
+ key: 1,
3075
+ title: e(l)("page.compare")
3076
+ }, {
3077
+ default: a(() => [
3078
+ f.value ? (t(), u(e(O), {
3079
+ key: 0,
3080
+ size: "sm",
3081
+ tone: "muted",
3082
+ class: "wx-audit-runs__pair"
3083
+ }, {
3084
+ default: a(() => [
3085
+ n(s(e(l)("page.compare-from")) + " #" + s(f.value.from.id) + " · ", 1),
3086
+ g(e(ke), {
3087
+ value: f.value.from.created_at
3088
+ }, null, 8, ["value"]),
3089
+ n(" → " + s(e(l)("page.compare-to")) + " #" + s(f.value.to.id) + " · ", 1),
3090
+ g(e(ke), {
3091
+ value: f.value.to.created_at
3092
+ }, null, 8, ["value"])
3093
+ ]),
3094
+ _: 1
3095
+ })) : C("", !0),
3096
+ j.value ? (t(), u(e(me), {
3097
+ key: 1,
3098
+ type: "info",
3099
+ description: e(l)("page.compare-scopes"),
3100
+ class: "wx-audit-runs__note"
3101
+ }, null, 8, ["description"])) : C("", !0),
3102
+ g(e(ve), {
3103
+ expanded: P.value,
3104
+ "onUpdate:expanded": D[1] || (D[1] = (z) => P.value = z),
3105
+ data: f.value?.checks ?? [],
3106
+ columns: N.value,
3107
+ "row-key": "check",
3108
+ expandable: "",
3109
+ flush: "",
3110
+ pagination: !1,
3111
+ loading: p.value,
3112
+ "empty-text": e(l)("page.compare-none")
3113
+ }, {
3114
+ "cell-severity": a(({ row: z }) => [
3115
+ g(e(B), {
3116
+ type: U[z.severity],
3117
+ dot: ""
3118
+ }, {
3119
+ default: a(() => [
3120
+ n(s(e(l)(`page.severity-${z.severity}`)), 1)
3121
+ ]),
3122
+ _: 2
3123
+ }, 1032, ["type"])
3124
+ ]),
3125
+ "cell-new": a(({ row: z }) => [
3126
+ g(e(O), {
3127
+ tone: z.new ? "danger" : "muted",
3128
+ size: "sm"
3129
+ }, {
3130
+ default: a(() => [
3131
+ n(s(z.new), 1)
3132
+ ]),
3133
+ _: 2
3134
+ }, 1032, ["tone"])
3135
+ ]),
3136
+ "cell-fixed": a(({ row: z }) => [
3137
+ g(e(O), {
3138
+ tone: z.fixed ? "success" : "muted",
3139
+ size: "sm"
3140
+ }, {
3141
+ default: a(() => [
3142
+ n(s(z.fixed), 1)
3143
+ ]),
3144
+ _: 2
3145
+ }, 1032, ["tone"])
3146
+ ]),
3147
+ expanded: a(({ row: z }) => [
3148
+ f.value ? (t(), u(Ua, {
3149
+ key: 0,
3150
+ from: f.value.from.id,
3151
+ to: f.value.to.id,
3152
+ row: z
3153
+ }, null, 8, ["from", "to", "row"])) : C("", !0)
3154
+ ]),
3155
+ _: 1
3156
+ }, 8, ["expanded", "data", "columns", "loading", "empty-text"])
3157
+ ]),
3158
+ _: 1
3159
+ }, 8, ["title"])) : (t(), u(e(O), {
3160
+ key: 0,
3161
+ size: "sm",
3162
+ tone: "muted"
3163
+ }, {
3164
+ default: a(() => [
3165
+ n(s(e(l)("page.compare-help")), 1)
3166
+ ]),
3167
+ _: 1
3168
+ }))
3169
+ ])
3170
+ ]),
3171
+ _: 1
3172
+ }, 8, ["base"]));
3173
+ }
3174
+ }), Ta = /* @__PURE__ */ ie(ja, [["__scopeId", "data-v-abbed1f9"]]), Ra = { class: "wx-audit-settings" }, Fa = /* @__PURE__ */ se({
3175
+ __name: "AuditSettingsPage",
3176
+ props: {
3177
+ base: {}
3178
+ },
3179
+ setup(k) {
3180
+ const v = k, c = le(), o = oe(c);
3181
+ ne();
3182
+ const l = ee("webx-audit"), r = ue(), d = S({}), h = S({}), m = S(!0), f = S(!1), p = c.can("audit.manage");
3183
+ ge(async () => {
3184
+ try {
3185
+ d.value = await o.settings();
3186
+ } catch (A) {
3187
+ Y.danger(r(A));
3188
+ } finally {
3189
+ m.value = !1;
3190
+ }
3191
+ });
3192
+ async function P() {
3193
+ f.value = !0, h.value = {};
3194
+ try {
3195
+ d.value = await o.saveSettings(d.value), Y.success(l("page.saved"));
3196
+ } catch (A) {
3197
+ const U = A.body;
3198
+ U?.errors && (h.value = U.errors), Y.danger(r(A));
3199
+ } finally {
3200
+ f.value = !1;
3201
+ }
3202
+ }
3203
+ return (A, U) => (t(), u(_e, {
3204
+ base: v.base,
3205
+ current: "settings",
3206
+ card: !1
3207
+ }, {
3208
+ default: a(() => [
3209
+ W("div", Ra, [
3210
+ m.value ? (t(), u(e(fe), {
3211
+ key: 0,
3212
+ rows: 6
3213
+ })) : (t(), u(e(at), {
3214
+ key: 1,
3215
+ modelValue: d.value,
3216
+ "onUpdate:modelValue": U[0] || (U[0] = (i) => d.value = i),
3217
+ name: "audit.settings",
3218
+ errors: h.value,
3219
+ disabled: !e(p)
3220
+ }, null, 8, ["modelValue", "errors", "disabled"])),
3221
+ e(p) && !m.value ? (t(), u(e(ot), { key: 2 }, {
3222
+ default: a(() => [
3223
+ g(e(Q), {
3224
+ type: "primary",
3225
+ loading: f.value,
3226
+ onClick: P
3227
+ }, {
3228
+ default: a(() => [
3229
+ n(s(e(l)("page.save")), 1)
3230
+ ]),
3231
+ _: 1
3232
+ }, 8, ["loading"])
3233
+ ]),
3234
+ _: 1
3235
+ })) : C("", !0)
3236
+ ])
3237
+ ]),
3238
+ _: 1
3239
+ }, 8, ["base"]));
3240
+ }
3241
+ }), La = /* @__PURE__ */ ie(Fa, [["__scopeId", "data-v-4b3f5a3f"]]);
3242
+ function Ha(k = {}) {
3243
+ const v = k.path ?? "/audit", c = { base: v };
3244
+ return {
3245
+ id: "audit",
3246
+ path: v,
3247
+ routes: [
3248
+ { path: v, name: "webx.audit", component: ta, props: c },
3249
+ { path: `${v}/issues`, name: "webx.audit.issues", component: qt, props: c },
3250
+ { path: `${v}/pages`, name: "webx.audit.pages", component: Wa, props: c },
3251
+ { path: `${v}/hosts`, name: "webx.audit.hosts", component: mt, props: c },
3252
+ { path: `${v}/runs`, name: "webx.audit.runs", component: Ta, props: c },
3253
+ {
3254
+ path: `${v}/settings`,
3255
+ name: "webx.audit.settings",
3256
+ component: La,
3257
+ props: c
3258
+ }
3259
+ ]
3260
+ };
3261
+ }
3262
+ export {
3263
+ Sa as DEFAULT_COLUMNS,
3264
+ ae as PAGE_FIELDS,
3265
+ Ve as WxAuditDetails,
3266
+ Ut as WxAuditHideDialog,
3267
+ mt as WxAuditHostsPage,
3268
+ qt as WxAuditIssuesPage,
3269
+ ta as WxAuditOverviewPage,
3270
+ za as WxAuditPageCard,
3271
+ Wa as WxAuditPagesPage,
3272
+ Ta as WxAuditRunsPage,
3273
+ La as WxAuditSettingsPage,
3274
+ Ha as audit,
3275
+ rt as auditMessages,
3276
+ oe as createAuditApi,
3277
+ Re as pageParams
3278
+ };
3279
+ //# sourceMappingURL=index.js.map