@webx-ui/module-audit 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. package/dist/{AuditHostsPage-CSAlf3jK.js → AuditHostsPage-DZ1vYvZR.js} +3 -3
  2. package/dist/{AuditHostsPage-CSAlf3jK.js.map → AuditHostsPage-DZ1vYvZR.js.map} +1 -1
  3. package/dist/{AuditIssuesPage-DtEJ9Sgq.js → AuditIssuesPage-CdWydT5i.js} +3 -3
  4. package/dist/{AuditIssuesPage-DtEJ9Sgq.js.map → AuditIssuesPage-CdWydT5i.js.map} +1 -1
  5. package/dist/{AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js → AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js} +2 -2
  6. package/dist/{AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js.map → AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js.map} +1 -1
  7. package/dist/{AuditOverviewPage-B5mexNDW.js → AuditOverviewPage-BqTU-JnS.js} +3 -3
  8. package/dist/{AuditOverviewPage-B5mexNDW.js.map → AuditOverviewPage-BqTU-JnS.js.map} +1 -1
  9. package/dist/{AuditPagesPage-C1Akv4Ql.js → AuditPagesPage-CsizUOgz.js} +3 -3
  10. package/dist/{AuditPagesPage-C1Akv4Ql.js.map → AuditPagesPage-CsizUOgz.js.map} +1 -1
  11. package/dist/{AuditRunsPage-SlBisvcG.js → AuditRunsPage-D9hzlpID.js} +3 -3
  12. package/dist/{AuditRunsPage-SlBisvcG.js.map → AuditRunsPage-D9hzlpID.js.map} +1 -1
  13. package/dist/{AuditSettingsPage-ADutjdIO.js → AuditSettingsPage-R9qoNgbJ.js} +3 -3
  14. package/dist/{AuditSettingsPage-ADutjdIO.js.map → AuditSettingsPage-R9qoNgbJ.js.map} +1 -1
  15. package/dist/{index-_DgRf2O6.js → index-BxS_t2W2.js} +435 -419
  16. package/dist/index-BxS_t2W2.js.map +1 -0
  17. package/dist/index.js +1 -1
  18. package/dist/style.css +1 -1
  19. package/package.json +4 -4
  20. package/dist/index-_DgRf2O6.js.map +0 -1
@@ -2,8 +2,8 @@ import { defineComponent as F, ref as v, onMounted as I, openBlock as l, createE
2
2
  import { useAdmin as L, useTranslate as H, useErrorText as M, WxDate as J } from "@webx-ui/module-admin";
3
3
  import { WxText as m, WxSkeleton as K, WxBadge as N, WxButton as O, WxTable as Q, WxSelect as X, toast as Y } from "@webx-ui/core";
4
4
  import { useRouter as Z } from "vue-router";
5
- import { c as j, u as R, A as E, a as U, b as ee, _ as q } from "./index-_DgRf2O6.js";
6
- import { _ as se } from "./AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js";
5
+ import { c as j, u as R, A as E, a as U, b as ee, _ as q } from "./index-BxS_t2W2.js";
6
+ import { _ as se } from "./AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js";
7
7
  const ae = { class: "wx-audit-places" }, te = {
8
8
  key: 0,
9
9
  class: "wx-audit-places__group"
@@ -340,4 +340,4 @@ const ae = { class: "wx-audit-places" }, te = {
340
340
  export {
341
341
  ve as default
342
342
  };
343
- //# sourceMappingURL=AuditHostsPage-CSAlf3jK.js.map
343
+ //# sourceMappingURL=AuditHostsPage-DZ1vYvZR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuditHostsPage-CSAlf3jK.js","sources":["../src/AuditHostPlaces.vue","../src/AuditHostsPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { createAuditApi } from './api'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostTarget, AuditHosts } from './types'\n\n/**\n * Where one host stands, under its row on «Outgoing»: the addresses on it the pages point at, each\n * a card with the pages under it — a font or a profile link sits in the layout and is on every\n * page, so by page it would be the same line forty times — and the fields of the database that\n * hold it, with «Open in the editor». A link's `target` and `rel` sit beside its address, or\n * beside each page when the pages write it differently. Fifty of each, broken links first; a card counts all its\n * pages and lists fifty.\n */\nconst props = defineProps<{ host: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst places = ref<AuditHosts | null>(null)\nconst failure = ref<string | null>(null)\n\n/** What the row's «Broken» counts: an error, or no answer at all (0). */\nconst broken = (status: number | null | undefined) =>\n status !== null && status !== undefined && (status >= 400 || status === 0)\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nfunction keyOf(target: AuditHostTarget): string {\n return `${target.kind} ${target.url}`\n}\n\nfunction shown(target: AuditHostTarget) {\n return open.value.has(keyOf(target)) ? target.places : target.places.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(target: AuditHostTarget): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(target))) next.add(keyOf(target))\n open.value = next\n}\n\nonMounted(async () => {\n try {\n places.value = await api.hosts({ host: props.host })\n } catch (error) {\n failure.value = message(error)\n }\n})\n</script>\n\n<template>\n <div class=\"wx-audit-places\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!places\" :rows=\"2\" />\n\n <template v-else>\n <section v-if=\"places.targets?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-pages') }}</wx-text>\n\n <div v-for=\"target in places.targets\" :key=\"keyOf(target)\" class=\"wx-audit-places__card\">\n <div class=\"wx-audit-places__head\">\n <wx-badge type=\"default\" size=\"sm\" class=\"wx-audit-places__fixed\">{{\n target.kind\n }}</wx-badge>\n <audit-address :href=\"target.url\" strong />\n <audit-link-attrs\n v-if=\"target.kind === 'a' && !target.mixed\"\n :rel=\"target.rel\"\n :target=\"target.target\"\n class=\"wx-audit-places__fixed\"\n />\n <audit-status\n v-if=\"broken(target.status)\"\n :code=\"target.status\"\n class=\"wx-audit-places__fixed\"\n />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-places__count\">{{\n t('page.link-pages', { count: target.pages })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-places__pages\">\n <li v-for=\"(place, index) in shown(target)\" :key=\"index\">\n <audit-address :href=\"place.page\" />\n <wx-text v-if=\"place.anchor\" size=\"sm\" tone=\"muted\" class=\"wx-audit-places__anchor\"\n >«{{ place.anchor }}»</wx-text\n >\n <!-- The pages differ in how they write the link: each says its own. -->\n <audit-link-attrs\n v-if=\"target.kind === 'a' && target.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-places__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"target.places.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-places__more\"\n @click=\"toggle(target)\"\n >{{\n open.has(keyOf(target)) ? t('page.link-collapse') : t('page.link-show-all')\n }}</wx-button\n >\n </div>\n </section>\n\n <section v-if=\"places.fields?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-fields') }}</wx-text>\n\n <div class=\"wx-audit-places__card\">\n <div v-for=\"(field, index) in places.fields\" :key=\"index\" class=\"wx-audit-places__field\">\n <div class=\"wx-audit-places__record\">\n <wx-text size=\"sm\">{{ field.record_label }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\"\n >{{ field.source }} · {{ field.field\n }}{{ field.locale ? ` · ${field.locale}` : '' }}</wx-text\n >\n <wx-badge v-if=\"!field.published\" size=\"sm\">{{ t('page.unpublished') }}</wx-badge>\n </div>\n <audit-address :href=\"field.url\" />\n <wx-button\n v-if=\"field.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n class=\"wx-audit-places__fixed\"\n @click=\"router.push(field.edit_url)\"\n >{{ t('page.open-editor') }}</wx-button\n >\n </div>\n </div>\n </section>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-places {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-places__group {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-places__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-places__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-places__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__anchor {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-audit-places__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n\n/* One grid for every field: the record, where its address is, the editor. */\n.wx-audit-places__field {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) auto;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-6) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__field:last-child {\n border-bottom: 0;\n}\n\n.wx-audit-places__record {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-8);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditHostPlaces from './AuditHostPlaces.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostClass, AuditHostRow, AuditHosts } from './types'\n\n/**\n * «Outgoing» (§8): every host the site points at — in the pages of the last full run and in the\n * fields of the database — by class, development stands on top and in red. A row opens into\n * where the host stands: the pages with their anchors, the records with the field and the way to\n * the editor.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst answer = ref<AuditHosts | null>(null)\nconst loading = ref(false)\nconst search = ref('')\nconst hostClass = ref<AuditHostClass | null>(null)\nconst expanded = ref<RowKey[]>([])\n\nconst classes: Record<AuditHostClass, BadgeType> = {\n dev: 'danger',\n own_mirror: 'warning',\n external: 'info',\n own: 'success',\n}\n\nconst columns = computed<TableColumn<AuditHostRow>[]>(() => [\n { key: 'host', label: t('page.host'), minWidth: 220 },\n { key: 'links', label: t('page.links'), width: 90, align: 'right' },\n { key: 'pages', label: t('page.pages'), width: 90, align: 'right', hideBelow: 560 },\n { key: 'broken', label: t('page.broken'), width: 100, align: 'right', hideBelow: 640 },\n { key: 'fields', label: t('page.fields'), width: 120, align: 'right' },\n { key: 'first_seen', label: t('page.first-seen'), minWidth: 140, hideBelow: 760 },\n])\n\nconst classOptions = computed(() =>\n (Object.keys(classes) as AuditHostClass[]).map((value) => ({\n value,\n label: `${t(`page.host-${value}`)}${answer.value?.classes[value] ? ` · ${answer.value.classes[value]}` : ''}`,\n })),\n)\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): AuditHostClass | null {\n return typeof value === 'string' && value in classes ? (value as AuditHostClass) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n answer.value = await api.hosts({ class: hostClass.value, search: search.value })\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch([hostClass, search], () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"hosts\">\n <wx-table\n v-model:expanded=\"expanded\"\n v-model:search=\"search\"\n :data=\"answer?.hosts ?? []\"\n :columns=\"columns\"\n row-key=\"host\"\n expandable\n flush\n searchable\n :search-placeholder=\"t('page.search-host')\"\n :loading=\"loading\"\n :filters-count=\"hostClass ? 1 : 0\"\n :filters-label=\"panel('filters.title')\"\n :row-class=\"(row: AuditHostRow) => (row.class === 'dev' ? 'is-stand' : undefined)\"\n :empty-text=\"t('page.hosts-empty')\"\n >\n <template #filters>\n <wx-select\n :model-value=\"hostClass\"\n :options=\"classOptions\"\n :placeholder=\"t('page.any-class')\"\n clearable\n @update:model-value=\"hostClass = pick($event)\"\n />\n </template>\n\n <template #cell-host=\"{ row }\">\n <span class=\"wx-audit-hosts__host\">\n <wx-badge :type=\"classes[row.class]\" size=\"sm\">{{\n t(`page.host-${row.class}`)\n }}</wx-badge>\n <wx-text size=\"sm\" :tone=\"row.class === 'dev' ? 'danger' : undefined\" weight=\"medium\">{{\n row.host\n }}</wx-text>\n </span>\n </template>\n <template #cell-broken=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.broken ? 'danger' : 'muted'\">{{ row.broken }}</wx-text>\n </template>\n <template #cell-fields=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.fields && row.class === 'dev' ? 'danger' : undefined\">{{\n row.fields\n }}</wx-text>\n </template>\n <template #cell-first_seen=\"{ row }\">\n <wx-date v-if=\"row.first_seen\" :value=\"row.first_seen\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-host-places :host=\"row.host\" />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-hosts__host {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A stand is the one class that is always a mistake: a red edge, like an error in a list. */\n:deep(.is-stand > td:first-child) {\n box-shadow: inset 3px 0 0 var(--wx-color-danger);\n}\n</style>\n"],"names":["FEW","props","__props","api","createAuditApi","useAdmin","useAuditMessages","t","useTranslate","message","useErrorText","router","useRouter","places","ref","failure","broken","status","open","keyOf","target","shown","toggle","next","onMounted","error","_openBlock","_createElementBlock","_hoisted_1","_createBlock","_unref","WxText","_Fragment","_hoisted_2","_createVNode","_renderList","_createElementVNode","_hoisted_3","WxBadge","_createTextVNode","_toDisplayString","AuditAddress","AuditLinkAttrs","AuditStatus","_hoisted_4","place","index","WxButton","$event","_hoisted_5","_hoisted_6","field","_hoisted_7","WxSkeleton","panel","answer","loading","search","hostClass","expanded","classes","columns","computed","classOptions","value","pick","load","toast","watch","AuditLayout","WxTable","row","WxSelect","_cache","_withCtx","WxDate","AuditHostPlaces"],"mappings":"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"}
1
+ {"version":3,"file":"AuditHostsPage-DZ1vYvZR.js","sources":["../src/AuditHostPlaces.vue","../src/AuditHostsPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxSkeleton, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { createAuditApi } from './api'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostTarget, AuditHosts } from './types'\n\n/**\n * Where one host stands, under its row on «Outgoing»: the addresses on it the pages point at, each\n * a card with the pages under it — a font or a profile link sits in the layout and is on every\n * page, so by page it would be the same line forty times — and the fields of the database that\n * hold it, with «Open in the editor». A link's `target` and `rel` sit beside its address, or\n * beside each page when the pages write it differently. Fifty of each, broken links first; a card counts all its\n * pages and lists fifty.\n */\nconst props = defineProps<{ host: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst places = ref<AuditHosts | null>(null)\nconst failure = ref<string | null>(null)\n\n/** What the row's «Broken» counts: an error, or no answer at all (0). */\nconst broken = (status: number | null | undefined) =>\n status !== null && status !== undefined && (status >= 400 || status === 0)\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nfunction keyOf(target: AuditHostTarget): string {\n return `${target.kind} ${target.url}`\n}\n\nfunction shown(target: AuditHostTarget) {\n return open.value.has(keyOf(target)) ? target.places : target.places.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(target: AuditHostTarget): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(target))) next.add(keyOf(target))\n open.value = next\n}\n\nonMounted(async () => {\n try {\n places.value = await api.hosts({ host: props.host })\n } catch (error) {\n failure.value = message(error)\n }\n})\n</script>\n\n<template>\n <div class=\"wx-audit-places\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!places\" :rows=\"2\" />\n\n <template v-else>\n <section v-if=\"places.targets?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-pages') }}</wx-text>\n\n <div v-for=\"target in places.targets\" :key=\"keyOf(target)\" class=\"wx-audit-places__card\">\n <div class=\"wx-audit-places__head\">\n <wx-badge type=\"default\" size=\"sm\" class=\"wx-audit-places__fixed\">{{\n target.kind\n }}</wx-badge>\n <audit-address :href=\"target.url\" strong />\n <audit-link-attrs\n v-if=\"target.kind === 'a' && !target.mixed\"\n :rel=\"target.rel\"\n :target=\"target.target\"\n class=\"wx-audit-places__fixed\"\n />\n <audit-status\n v-if=\"broken(target.status)\"\n :code=\"target.status\"\n class=\"wx-audit-places__fixed\"\n />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-places__count\">{{\n t('page.link-pages', { count: target.pages })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-places__pages\">\n <li v-for=\"(place, index) in shown(target)\" :key=\"index\">\n <audit-address :href=\"place.page\" />\n <wx-text v-if=\"place.anchor\" size=\"sm\" tone=\"muted\" class=\"wx-audit-places__anchor\"\n >«{{ place.anchor }}»</wx-text\n >\n <!-- The pages differ in how they write the link: each says its own. -->\n <audit-link-attrs\n v-if=\"target.kind === 'a' && target.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-places__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"target.places.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-places__more\"\n @click=\"toggle(target)\"\n >{{\n open.has(keyOf(target)) ? t('page.link-collapse') : t('page.link-show-all')\n }}</wx-button\n >\n </div>\n </section>\n\n <section v-if=\"places.fields?.length\" class=\"wx-audit-places__group\">\n <wx-text size=\"sm\" weight=\"semibold\">{{ t('page.host-fields') }}</wx-text>\n\n <div class=\"wx-audit-places__card\">\n <div v-for=\"(field, index) in places.fields\" :key=\"index\" class=\"wx-audit-places__field\">\n <div class=\"wx-audit-places__record\">\n <wx-text size=\"sm\">{{ field.record_label }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\"\n >{{ field.source }} · {{ field.field\n }}{{ field.locale ? ` · ${field.locale}` : '' }}</wx-text\n >\n <wx-badge v-if=\"!field.published\" size=\"sm\">{{ t('page.unpublished') }}</wx-badge>\n </div>\n <audit-address :href=\"field.url\" />\n <wx-button\n v-if=\"field.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n class=\"wx-audit-places__fixed\"\n @click=\"router.push(field.edit_url)\"\n >{{ t('page.open-editor') }}</wx-button\n >\n </div>\n </div>\n </section>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-places {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-places__group {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-places__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-places__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-places__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-places__anchor {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-audit-places__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n\n/* One grid for every field: the record, where its address is, the editor. */\n.wx-audit-places__field {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) auto;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-6) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-places__field:last-child {\n border-bottom: 0;\n}\n\n.wx-audit-places__record {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-8);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type RowKey,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditHostPlaces from './AuditHostPlaces.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditHostClass, AuditHostRow, AuditHosts } from './types'\n\n/**\n * «Outgoing» (§8): every host the site points at — in the pages of the last full run and in the\n * fields of the database — by class, development stands on top and in red. A row opens into\n * where the host stands: the pages with their anchors, the records with the field and the way to\n * the editor.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst answer = ref<AuditHosts | null>(null)\nconst loading = ref(false)\nconst search = ref('')\nconst hostClass = ref<AuditHostClass | null>(null)\nconst expanded = ref<RowKey[]>([])\n\nconst classes: Record<AuditHostClass, BadgeType> = {\n dev: 'danger',\n own_mirror: 'warning',\n external: 'info',\n own: 'success',\n}\n\nconst columns = computed<TableColumn<AuditHostRow>[]>(() => [\n { key: 'host', label: t('page.host'), minWidth: 220 },\n { key: 'links', label: t('page.links'), width: 90, align: 'right' },\n { key: 'pages', label: t('page.pages'), width: 90, align: 'right', hideBelow: 560 },\n { key: 'broken', label: t('page.broken'), width: 100, align: 'right', hideBelow: 640 },\n { key: 'fields', label: t('page.fields'), width: 120, align: 'right' },\n { key: 'first_seen', label: t('page.first-seen'), minWidth: 140, hideBelow: 760 },\n])\n\nconst classOptions = computed(() =>\n (Object.keys(classes) as AuditHostClass[]).map((value) => ({\n value,\n label: `${t(`page.host-${value}`)}${answer.value?.classes[value] ? ` · ${answer.value.classes[value]}` : ''}`,\n })),\n)\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): AuditHostClass | null {\n return typeof value === 'string' && value in classes ? (value as AuditHostClass) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n answer.value = await api.hosts({ class: hostClass.value, search: search.value })\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch([hostClass, search], () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"hosts\">\n <wx-table\n v-model:expanded=\"expanded\"\n v-model:search=\"search\"\n :data=\"answer?.hosts ?? []\"\n :columns=\"columns\"\n row-key=\"host\"\n expandable\n flush\n searchable\n :search-placeholder=\"t('page.search-host')\"\n :loading=\"loading\"\n :filters-count=\"hostClass ? 1 : 0\"\n :filters-label=\"panel('filters.title')\"\n :row-class=\"(row: AuditHostRow) => (row.class === 'dev' ? 'is-stand' : undefined)\"\n :empty-text=\"t('page.hosts-empty')\"\n >\n <template #filters>\n <wx-select\n :model-value=\"hostClass\"\n :options=\"classOptions\"\n :placeholder=\"t('page.any-class')\"\n clearable\n @update:model-value=\"hostClass = pick($event)\"\n />\n </template>\n\n <template #cell-host=\"{ row }\">\n <span class=\"wx-audit-hosts__host\">\n <wx-badge :type=\"classes[row.class]\" size=\"sm\">{{\n t(`page.host-${row.class}`)\n }}</wx-badge>\n <wx-text size=\"sm\" :tone=\"row.class === 'dev' ? 'danger' : undefined\" weight=\"medium\">{{\n row.host\n }}</wx-text>\n </span>\n </template>\n <template #cell-broken=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.broken ? 'danger' : 'muted'\">{{ row.broken }}</wx-text>\n </template>\n <template #cell-fields=\"{ row }\">\n <wx-text size=\"sm\" :tone=\"row.fields && row.class === 'dev' ? 'danger' : undefined\">{{\n row.fields\n }}</wx-text>\n </template>\n <template #cell-first_seen=\"{ row }\">\n <wx-date v-if=\"row.first_seen\" :value=\"row.first_seen\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-host-places :host=\"row.host\" />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-hosts__host {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* A stand is the one class that is always a mistake: a red edge, like an error in a list. */\n:deep(.is-stand > td:first-child) {\n box-shadow: inset 3px 0 0 var(--wx-color-danger);\n}\n</style>\n"],"names":["FEW","props","__props","api","createAuditApi","useAdmin","useAuditMessages","t","useTranslate","message","useErrorText","router","useRouter","places","ref","failure","broken","status","open","keyOf","target","shown","toggle","next","onMounted","error","_openBlock","_createElementBlock","_hoisted_1","_createBlock","_unref","WxText","_Fragment","_hoisted_2","_createVNode","_renderList","_createElementVNode","_hoisted_3","WxBadge","_createTextVNode","_toDisplayString","AuditAddress","AuditLinkAttrs","AuditStatus","_hoisted_4","place","index","WxButton","$event","_hoisted_5","_hoisted_6","field","_hoisted_7","WxSkeleton","panel","answer","loading","search","hostClass","expanded","classes","columns","computed","classOptions","value","pick","load","toast","watch","AuditLayout","WxTable","row","WxSelect","_cache","_withCtx","WxDate","AuditHostPlaces"],"mappings":";;;;;;;;;;;;uFAqCMA,IAAM;;;;;;AAjBZ,UAAMC,IAAQC,GAERC,IAAMC,EAAeC,GAAU;AACrC,IAAAC,EAAA;AAEA,UAAMC,IAAIC,EAAa,YAAY,GAC7BC,IAAUC,EAAA,GACVC,IAASC,EAAA,GAETC,IAASC,EAAuB,IAAI,GACpCC,IAAUD,EAAmB,IAAI,GAGjCE,IAAS,CAACC,MACdA,KAAW,SAAiCA,KAAU,OAAOA,MAAW,IAKpEC,IAAOJ,EAAI,oBAAI,KAAa;AAElC,aAASK,EAAMC,GAAiC;AAC9C,aAAO,GAAGA,EAAO,IAAI,IAAIA,EAAO,GAAG;AAAA,IACrC;AAEA,aAASC,EAAMD,GAAyB;AACtC,aAAOF,EAAK,MAAM,IAAIC,EAAMC,CAAM,CAAC,IAAIA,EAAO,SAASA,EAAO,OAAO,MAAM,GAAGpB,CAAG;AAAA,IACnF;AAGA,aAASsB,EAAOF,GAA+B;AAC7C,YAAMG,IAAO,IAAI,IAAIL,EAAK,KAAK;AAE/B,MAAKK,EAAK,OAAOJ,EAAMC,CAAM,CAAC,KAAGG,EAAK,IAAIJ,EAAMC,CAAM,CAAC,GACvDF,EAAK,QAAQK;AAAA,IACf;AAEA,WAAAC,EAAU,YAAY;AACpB,UAAI;AACF,QAAAX,EAAO,QAAQ,MAAMV,EAAI,MAAM,EAAE,MAAMF,EAAM,MAAM;AAAA,MACrD,SAASwB,GAAO;AACd,QAAAV,EAAQ,QAAQN,EAAQgB,CAAK;AAAA,MAC/B;AAAA,IACF,CAAC,cAICC,EAAA,GAAAC,EAsFM,OAtFNC,IAsFM;AAAA,MArFWb,EAAA,cAAfc,EAAuEC,EAAAC,CAAA,GAAA;AAAA;QAA/C,MAAK;AAAA,QAAK,MAAK;AAAA,MAAA;mBAAS,MAAa;AAAA,cAAVhB,EAAA,KAAO,GAAA,CAAA;AAAA,QAAA;;YACjCF,EAAA,cAEzBc,EAiFWK,GAAA,EAAA,KAAA,KAAA;AAAA,QAhFMnB,EAAA,MAAO,SAAS,UAA/Ba,KAAAC,EAoDU,WApDVM,IAoDU;AAAA,UAnDRC,EAAyEJ,EAAAC,CAAA,GAAA;AAAA,YAAhE,MAAK;AAAA,YAAK,QAAO;AAAA,UAAA;uBAAW,MAA0B;AAAA,kBAAvBD,EAAAvB,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;WAEzCmB,EAAA,EAAA,GAAAC,EAgDMK,GAAA,MAAAG,EAhDgBtB,EAAA,MAAO,UAAjBO,YAAZO,EAgDM,OAAA;AAAA,YAhDiC,KAAKR,EAAMC,CAAM;AAAA,YAAG,OAAM;AAAA,UAAA;YAC/DgB,EAmBM,OAnBNC,IAmBM;AAAA,cAlBJH,EAEaJ,EAAAQ,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAU,MAAK;AAAA,gBAAK,OAAM;AAAA,cAAA;2BAAyB,MAEhE;AAAA,kBADAC,EAAAC,EAAApB,EAAO,IAAI,GAAA,CAAA;AAAA,gBAAA;;;cAEbc,EAA2CO,GAAA;AAAA,gBAA3B,MAAMrB,EAAO;AAAA,gBAAK,QAAA;AAAA,cAAA;cAE1BA,EAAO,SAAI,OAAA,CAAaA,EAAO,cADvCS,EAKEa,GAAA;AAAA;gBAHC,KAAKtB,EAAO;AAAA,gBACZ,QAAQA,EAAO;AAAA,gBAChB,OAAM;AAAA,cAAA;cAGAJ,EAAOI,EAAO,MAAM,UAD5BS,EAIEc,IAAA;AAAA;gBAFC,MAAMvB,EAAO;AAAA,gBACd,OAAM;AAAA,cAAA;cAERc,EAEYJ,EAAAC,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAK,MAAK;AAAA,gBAAQ,OAAM;AAAA,cAAA;2BAAyB,MAE7D;AAAA,sBADAD,EAAAvB,CAAA,EAAC,mBAAA,EAAA,OAA6Ba,EAAO,MAAA,CAAK,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;YAI9CgB,EAcK,MAdLQ,IAcK;AAAA,eAbHlB,EAAA,EAAA,GAAAC,EAYKK,WAZwBX,EAAMD,CAAM,GAAA,CAA7ByB,GAAOC,YAAnBnB,EAYK,MAAA,EAZwC,KAAKmB,KAAK;AAAA,gBACrDZ,EAAoCO,GAAA;AAAA,kBAApB,MAAMI,EAAM;AAAA,gBAAA;gBACbA,EAAM,eAArBhB,EAECC,EAAAC,CAAA,GAAA;AAAA;kBAF4B,MAAK;AAAA,kBAAK,MAAK;AAAA,kBAAQ,OAAM;AAAA,gBAAA;6BACvD,MAAC;AAAA,oBAADQ,EAAA,MAACC,EAAGK,EAAM,MAAM,IAAG,KAAC,CAAA;AAAA,kBAAA;;;gBAIfzB,EAAO,SAAI,OAAYA,EAAO,cADtCS,EAKEa,GAAA;AAAA;kBAHC,KAAKG,EAAM;AAAA,kBACX,QAAQA,EAAM;AAAA,kBACf,OAAM;AAAA,gBAAA;;;YAMJzB,EAAO,OAAO,SAASpB,UAD/B6B,EASCC,EAAAiB,CAAA,GAAA;AAAA;cAPC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,OAAM;AAAA,cACL,SAAK,CAAAC,MAAE1B,EAAOF,CAAM;AAAA,YAAA;yBACpB,MAEC;AAAA,oBADAF,EAAA,MAAK,IAAIC,EAAMC,CAAM,CAAA,IAAKU,EAAAvB,CAAA,EAAC,oBAAA,IAAyBuB,EAAAvB,CAAA,EAAC,oBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;QAM9CM,EAAA,MAAO,QAAQ,UAA9Ba,KAAAC,EAyBU,WAzBVsB,IAyBU;AAAA,UAxBRf,EAA0EJ,EAAAC,CAAA,GAAA;AAAA,YAAjE,MAAK;AAAA,YAAK,QAAO;AAAA,UAAA;uBAAW,MAA2B;AAAA,kBAAxBD,EAAAvB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEzC6B,EAqBM,OArBNc,IAqBM;AAAA,aApBJxB,EAAA,EAAA,GAAAC,EAmBMK,WAnBwBnB,EAAA,MAAO,QAAM,CAA9BsC,GAAOL,YAApBnB,EAmBM,OAAA;AAAA,cAnBwC,KAAKmB;AAAA,cAAO,OAAM;AAAA,YAAA;cAC9DV,EAOM,OAPNgB,IAOM;AAAA,gBANJlB,EAAqDJ,EAAAC,CAAA,GAAA,EAA5C,MAAK,QAAI;AAAA,6BAAC,MAAwB;AAAA,oBAArBQ,EAAAC,EAAAW,EAAM,YAAY,GAAA,CAAA;AAAA,kBAAA;;;gBACxCjB,EAGCJ,EAAAC,CAAA,GAAA;AAAA,kBAHQ,MAAK;AAAA,kBAAK,MAAK;AAAA,gBAAA;6BACrB,MAAkB;AAAA,oBAAfQ,EAAAC,EAAAW,EAAM,MAAM,IAAG,UAAMA,EAAM,KAAK,IAAAX,EAC/BW,EAAM,SAAM,MAASA,EAAM,MAAM,KAAA,EAAA,GAAA,CAAA;AAAA,kBAAA;;;gBAEvBA,EAAM,8BAAvBtB,EAAkFC,EAAAQ,CAAA,GAAA;AAAA;kBAAhD,MAAK;AAAA,gBAAA;6BAAK,MAA2B;AAAA,wBAAxBR,EAAAvB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;;cAElD2B,EAAmCO,GAAA;AAAA,gBAAnB,MAAMU,EAAM;AAAA,cAAA;cAEpBA,EAAM,iBADdtB,EAQCC,EAAAiB,CAAA,GAAA;AAAA;gBANC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,OAAM;AAAA,gBACL,gBAAOjB,EAAAnB,CAAA,EAAO,KAAKwC,EAAM,QAAQ;AAAA,cAAA;2BACjC,MAA2B;AAAA,sBAAxBrB,EAAAvB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;sBA9EfsB,EAA6CC,EAAAuB,CAAA,GAAA;AAAA;QAAX,MAAM;AAAA,MAAA;;;;;;;;;AC3C5C,UAAMpD,IAAQC,GAERC,IAAMC,EAAeC,GAAU;AACrC,IAAAC,EAAA;AAEA,UAAMC,IAAIC,EAAa,YAAY,GAC7B8C,IAAQ9C,EAAa,YAAY,GACjCC,IAAUC,EAAA,GAEV6C,IAASzC,EAAuB,IAAI,GACpC0C,IAAU1C,EAAI,EAAK,GACnB2C,IAAS3C,EAAI,EAAE,GACf4C,IAAY5C,EAA2B,IAAI,GAC3C6C,IAAW7C,EAAc,EAAE,GAE3B8C,IAA6C;AAAA,MACjD,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,KAAK;AAAA,IAAA,GAGDC,IAAUC,EAAsC,MAAM;AAAA,MAC1D,EAAE,KAAK,QAAQ,OAAOvD,EAAE,WAAW,GAAG,UAAU,IAAA;AAAA,MAChD,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,IAAI,OAAO,QAAA;AAAA,MAC1D,EAAE,KAAK,SAAS,OAAOA,EAAE,YAAY,GAAG,OAAO,IAAI,OAAO,SAAS,WAAW,IAAA;AAAA,MAC9E,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,KAAK,OAAO,SAAS,WAAW,IAAA;AAAA,MACjF,EAAE,KAAK,UAAU,OAAOA,EAAE,aAAa,GAAG,OAAO,KAAK,OAAO,QAAA;AAAA,MAC7D,EAAE,KAAK,cAAc,OAAOA,EAAE,iBAAiB,GAAG,UAAU,KAAK,WAAW,IAAA;AAAA,IAAI,CACjF,GAEKwD,IAAeD;AAAA,MAAS,MAC3B,OAAO,KAAKF,CAAO,EAAuB,IAAI,CAACI,OAAW;AAAA,QACzD,OAAAA;AAAA,QACA,OAAO,GAAGzD,EAAE,aAAayD,CAAK,EAAE,CAAC,GAAGT,EAAO,OAAO,QAAQS,CAAK,IAAI,MAAMT,EAAO,MAAM,QAAQS,CAAK,CAAC,KAAK,EAAE;AAAA,MAAA,EAC3G;AAAA,IAAA;AAGJ,aAASC,EAAKD,GAA8E;AAC1F,aAAO,OAAOA,KAAU,YAAYA,KAASJ,IAAWI,IAA2B;AAAA,IACrF;AAEA,mBAAeE,IAAsB;AACnC,MAAAV,EAAQ,QAAQ;AAEhB,UAAI;AACF,QAAAD,EAAO,QAAQ,MAAMpD,EAAI,MAAM,EAAE,OAAOuD,EAAU,OAAO,QAAQD,EAAO,MAAA,CAAO,GAC/EE,EAAS,QAAQ,CAAA;AAAA,MACnB,SAASlC,GAAO;AACd,QAAA0C,EAAM,OAAO1D,EAAQgB,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAA+B,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,WAAAY,EAAM,CAACV,GAAWD,CAAM,GAAG,MAAA;AAAM,MAAKS;KAAM,GAE5C1C,EAAU0C,CAAI,mBAIZrC,EAqDewC,IAAA;AAAA,MArDA,MAAMpE,EAAM;AAAA,MAAM,SAAQ;AAAA,IAAA;iBACvC,MAmDW;AAAA,QAnDXiC,EAmDWJ,EAAAwC,CAAA,GAAA;AAAA,UAlDD,UAAUX,EAAA;AAAA,sDAAAA,EAAQ,QAAAX;AAAA,UAClB,QAAQS,EAAA;AAAA,oDAAAA,EAAM,QAAAT;AAAA,UACrB,MAAMO,EAAA,OAAQ,SAAK,CAAA;AAAA,UACnB,SAASM,EAAA;AAAA,UACV,WAAQ;AAAA,UACR,YAAA;AAAA,UACA,OAAA;AAAA,UACA,YAAA;AAAA,UACC,sBAAoB/B,EAAAvB,CAAA,EAAC,kBAAA;AAAA,UACrB,SAASiD,EAAA;AAAA,UACT,iBAAeE,EAAA,QAAS,IAAA;AAAA,UACxB,iBAAe5B,EAAAwB,CAAA,EAAK,eAAA;AAAA,UACpB,cAAYiB,MAAuBA,EAAI,+BAA+B;AAAA,UACtE,cAAYzC,EAAAvB,CAAA,EAAC,kBAAA;AAAA,QAAA;UAEH,WACT,MAME;AAAA,YANF2B,EAMEJ,EAAA0C,CAAA,GAAA;AAAA,cALC,eAAad,EAAA;AAAA,cACb,SAASK,EAAA;AAAA,cACT,aAAajC,EAAAvB,CAAA,EAAC,gBAAA;AAAA,cACf,WAAA;AAAA,cACC,uBAAkBkE,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAzB,MAAEU,EAAA,QAAYO,EAAKjB,CAAM;AAAA,YAAA;;UAIrC,aAAS0B,EAClB,CAOO,EARe,KAAAH,QAAG;AAAA,YACzBnC,EAOO,QAPPR,IAOO;AAAA,cANLM,EAEaJ,EAAAQ,CAAA,GAAA;AAAA,gBAFF,MAAMsB,EAAQW,EAAI,KAAK;AAAA,gBAAG,MAAK;AAAA,cAAA;2BAAK,MAE7C;AAAA,sBADAzC,EAAAvB,CAAA,EAAC,aAAcgE,EAAI,KAAK,EAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;cAE1BrC,EAEYJ,EAAAC,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAM,MAAMwC,EAAI,6BAA6B;AAAA,gBAAW,QAAO;AAAA,cAAA;2BAAS,MAEpF;AAAA,kBADAhC,EAAAC,EAAA+B,EAAI,IAAI,GAAA,CAAA;AAAA,gBAAA;;;;;UAIH,eAAWG,EACpB,CAAqF,EAD7D,KAAAH,QAAG;AAAA,YAC3BrC,EAAqFJ,EAAAC,CAAA,GAAA;AAAA,cAA5E,MAAK;AAAA,cAAM,MAAMwC,EAAI,SAAM,WAAA;AAAA,YAAA;yBAAuB,MAAgB;AAAA,gBAAbhC,EAAAC,EAAA+B,EAAI,MAAM,GAAA,CAAA;AAAA,cAAA;;;;UAE/D,eAAWG,EACpB,CAEY,EAHY,KAAAH,QAAG;AAAA,YAC3BrC,EAEYJ,EAAAC,CAAA,GAAA;AAAA,cAFH,MAAK;AAAA,cAAM,MAAMwC,EAAI,UAAUA,EAAI,UAAK,QAAA,WAAwB;AAAA,YAAA;yBAAW,MAElF;AAAA,gBADAhC,EAAAC,EAAA+B,EAAI,MAAM,GAAA,CAAA;AAAA,cAAA;;;;UAGH,mBAAeG,EACxB,CAAyD,EAD7B,KAAAH,QAAG;AAAA,YAChBA,EAAI,mBAAnB1C,EAAyDC,EAAA6C,CAAA,GAAA;AAAA;cAAzB,OAAOJ,EAAI;AAAA,YAAA;;UAGlC,UAAQG,EACjB,CAAsC,EADjB,KAAAH,QAAG;AAAA,YACxBrC,EAAsC0C,IAAA;AAAA,cAAlB,MAAML,EAAI;AAAA,YAAA;;;;;;;;;"}
@@ -1,9 +1,9 @@
1
1
  import { defineComponent as K, useModel as ve, ref as w, watch as oe, openBlock as t, createBlock as u, unref as e, withCtx as n, createElementVNode as y, createTextVNode as f, toDisplayString as o, createCommentVNode as x, createElementBlock as C, Fragment as M, renderList as N, createVNode as k, mergeModels as se, computed as q, onMounted as de, normalizeClass as ge, withModifiers as _e } from "vue";
2
2
  import { useAdmin as te, useTranslate as R, useErrorText as le } from "@webx-ui/module-admin";
3
3
  import { WxDialog as xe, WxText as L, WxSkeleton as ee, WxButton as T, toast as j, WxIcon as me, WxBadge as O, WxSegmented as ye, WxTooltip as ke, WxTable as we, WxPopover as he, WxDescriptions as be, WxDescriptionsItem as Y, WxSelect as Z } from "@webx-ui/core";
4
- import { c as ae, u as Q, _ as X, A as J, d as $e, a as ie, b as ze, e as Ce, f as Ae } from "./index-_DgRf2O6.js";
4
+ import { c as ae, u as Q, _ as X, A as J, d as $e, a as ie, b as ze, e as Ce, f as Ae } from "./index-BxS_t2W2.js";
5
5
  import { useRouter as We } from "vue-router";
6
- import { _ as Ie } from "./AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js";
6
+ import { _ as Ie } from "./AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js";
7
7
  const De = { class: "wx-audit-fix" }, Ve = { class: "wx-audit-fix__changes" }, Be = {
8
8
  key: 0,
9
9
  class: "wx-audit-fix__field"
@@ -715,4 +715,4 @@ ${l.location}`;
715
715
  export {
716
716
  nt as default
717
717
  };
718
- //# sourceMappingURL=AuditIssuesPage-DtEJ9Sgq.js.map
718
+ //# sourceMappingURL=AuditIssuesPage-CdWydT5i.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuditIssuesPage-DtEJ9Sgq.js","sources":["../src/AuditFixDialog.vue","../src/AuditLinkGroups.vue","../src/AuditIssueList.vue","../src/AuditIssuesPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxSkeleton, WxText, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditFixOffer, AuditIssue } from './types'\n\n/**\n * The fix button's dialog (§8, decision 4): the fixes that can close one finding, each with what\n * it would change — the records and fields with their counts, or a setting before and after —\n * and \"Apply\" under each. Nothing changes until it is pressed; the finding then waits for the\n * next run, which is the only thing that says it is gone.\n */\nconst props = defineProps<{ run: number; issue: AuditIssue }>()\nconst emit = defineEmits<{ fixed: [fix: string] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst offers = ref<AuditFixOffer[] | null>(null)\nconst failure = ref<string | null>(null)\nconst applying = ref<string | null>(null)\n\nasync function load(): Promise<void> {\n offers.value = null\n failure.value = null\n\n try {\n offers.value = await api.fixes(props.run, props.issue.id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function apply(offer: AuditFixOffer): Promise<void> {\n applying.value = offer.id\n\n try {\n await api.fix(props.run, props.issue.id, offer.id)\n toast.success(t('page.fix-applied'))\n emit('fixed', offer.id)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n applying.value = null\n }\n}\n\nfunction edit(url: string): void {\n open.value = false\n void router.push(url)\n}\n\n// Immediate: the list mounts the dialog already open, the first time a button is pressed.\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (now) void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.fix-button')\" :width=\"640\">\n <div class=\"wx-audit-fix\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!offers\" :rows=\"3\" />\n <wx-text v-else-if=\"offers.length === 0\" size=\"sm\" tone=\"muted\">{{\n t('page.fix-none')\n }}</wx-text>\n\n <section v-for=\"offer in offers ?? []\" :key=\"offer.id\" class=\"wx-audit-fix__offer\">\n <wx-text weight=\"semibold\">{{ offer.title }}</wx-text>\n <wx-text v-if=\"offer.description\" size=\"sm\" tone=\"muted\">{{ offer.description }}</wx-text>\n\n <table class=\"wx-audit-fix__changes\">\n <thead>\n <tr>\n <th>{{ t('page.fix-changes') }}</th>\n <th>{{ t('page.fix-before') }}</th>\n <th>{{ t('page.fix-after') }}</th>\n <th />\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(change, index) in offer.changes\" :key=\"index\">\n <td>\n <div>{{ change.label }}</div>\n <div v-if=\"change.field\" class=\"wx-audit-fix__field\">{{ change.field }}</div>\n </td>\n <td class=\"wx-audit-fix__value\">\n {{ change.before ?? '' }}\n <span v-if=\"change.count\" class=\"wx-audit-fix__count\">× {{ change.count }}</span>\n </td>\n <td class=\"wx-audit-fix__value\">{{ change.after ?? '' }}</td>\n <td>\n <wx-button\n v-if=\"change.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n :aria-label=\"t('page.open-editor')\"\n @click=\"edit(change.edit_url)\"\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <wx-text v-if=\"offer.note\" size=\"sm\" tone=\"muted\">{{ offer.note }}</wx-text>\n\n <div class=\"wx-audit-fix__actions\">\n <wx-button\n type=\"primary\"\n size=\"sm\"\n :loading=\"applying === offer.id\"\n :disabled=\"applying !== null\"\n @click=\"apply(offer)\"\n >{{ t('page.fix-apply') }}</wx-button\n >\n </div>\n </section>\n </div>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-fix {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-fix__offer {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-fix__changes {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-fix__changes th {\n padding: var(--wx-space-4) var(--wx-space-8);\n color: var(--wx-text-muted);\n font-weight: var(--wx-font-weight-medium);\n text-align: start;\n border-bottom: 1px solid var(--wx-border-default);\n}\n\n.wx-audit-fix__changes td {\n padding: var(--wx-space-6) var(--wx-space-8);\n vertical-align: top;\n border-bottom: 1px solid var(--wx-border-default);\n overflow-wrap: anywhere;\n}\n\n.wx-audit-fix__field,\n.wx-audit-fix__count {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-fix__value {\n white-space: pre-line;\n}\n\n.wx-audit-fix__actions {\n display: flex;\n justify-content: flex-end;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIssue } from './types'\n\n/**\n * The findings of a redirect check turned inside out: one card per link, the pages it is on\n * under it. A link in the footer or the menu is on every page and is fixed once, in one place —\n * by page, it would be the same row forty times.\n */\nconst props = defineProps<{ issues: AuditIssue[] }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\ninterface LinkGroup {\n url: string\n location: string\n status: number | null\n pages: LinkPlace[]\n /** The pages write the link with different `rel` or `target`: each says its own. */\n mixed: boolean\n}\n\ninterface LinkPlace {\n page: string\n rel: string | null\n target: string | null\n}\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nconst groups = computed<LinkGroup[]>(() => {\n const found = new Map<string, LinkGroup>()\n\n for (const issue of props.issues) {\n for (const row of issue.details.table?.rows ?? []) {\n const url = String(row.url ?? '')\n const location = String(row.location ?? '')\n const key = `${url}\\n${location}`\n const group = found.get(key) ?? { url, location, status: null, pages: [], mixed: false }\n const place = { page: issue.url ?? '', rel: attr(row.rel), target: attr(row.target) }\n const first = group.pages[0]\n\n group.status ??= typeof row.status === 'number' ? row.status : null\n if (first && (first.rel !== place.rel || first.target !== place.target)) group.mixed = true\n if (place.page && !group.pages.some((one) => one.page === place.page)) group.pages.push(place)\n found.set(key, group)\n }\n }\n\n return [...found.values()].sort((a, b) => b.pages.length - a.pages.length)\n})\n\nfunction attr(value: unknown): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction keyOf(group: LinkGroup): string {\n return `${group.url}\\n${group.location}`\n}\n\nfunction shown(group: LinkGroup): LinkPlace[] {\n return open.value.has(keyOf(group)) ? group.pages : group.pages.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(group: LinkGroup): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(group))) next.add(keyOf(group))\n open.value = next\n}\n</script>\n\n<template>\n <div class=\"wx-audit-links\">\n <div v-for=\"group in groups\" :key=\"keyOf(group)\" class=\"wx-audit-links__card\">\n <div class=\"wx-audit-links__head\">\n <audit-address :href=\"group.url\" type=\"muted\" class=\"wx-audit-links__from\" />\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-links__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"group.location\" strong class=\"wx-audit-links__to\" />\n <wx-badge\n v-for=\"change in differences(group.url, group.location)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n <audit-link-attrs\n v-if=\"!group.mixed && group.pages[0]\"\n :rel=\"group.pages[0].rel\"\n :target=\"group.pages[0].target\"\n class=\"wx-audit-links__fixed\"\n />\n <audit-status v-if=\"group.status !== null\" :code=\"group.status\" />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-links__count\">{{\n t('page.link-pages', { count: group.pages.length })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-links__pages\">\n <li v-for=\"place in shown(group)\" :key=\"place.page\">\n <audit-address :href=\"place.page\" />\n <audit-link-attrs\n v-if=\"group.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-links__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"group.pages.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-links__more\"\n @click=\"toggle(group)\"\n >{{ open.has(keyOf(group)) ? t('page.link-collapse') : t('page.link-show-all') }}</wx-button\n >\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-links {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-links__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-links__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__from,\n.wx-audit-links__to {\n flex: 0 1 auto;\n}\n\n.wx-audit-links__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-links__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-links__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-links__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-links__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { toast, WxBadge, WxButton, WxSegmented, WxSkeleton, WxText, WxTooltip } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditFixDialog from './AuditFixDialog.vue'\nimport AuditHideDialog from './AuditHideDialog.vue'\nimport AuditLinkGroups from './AuditLinkGroups.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue, AuditIssueQuery } from './types'\n\n/**\n * The addresses of one check, under its row in the findings table: loaded when the row opens,\n * fifty at a time. A check that has fixes gets a button on each address; the dialog shows what\n * it would change before anything does. «Hide» asks for the reason; on the list of hidden ones\n * each says why, and «Show again» removes the rule.\n *\n * Each finding is a card: the address with its count, the table under it. A check of links that\n * redirect can also be read by link — every page loaded, one card per link with its pages.\n */\nconst props = defineProps<{\n run: number\n query: AuditIssueQuery\n fixable?: boolean\n /** The check's title, for the hiding dialog. */\n title?: string\n}>()\n\nconst emit = defineEmits<{ changed: [] }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst can = context.can('audit.manage')\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst issues = ref<AuditIssue[] | null>(null)\nconst more = ref(false)\nconst page = ref(1)\nconst failure = ref<string | null>(null)\nconst fixing = ref<AuditIssue | null>(null)\nconst dialog = ref(false)\nconst hiding = ref<AuditIssue | null>(null)\nconst hideDialog = ref(false)\n\ntype View = 'pages' | 'links'\n\nconst view = ref<View>('pages')\nconst everything = ref<AuditIssue[] | null>(null)\n\n/** Rows with where each address leads: the findings can be grouped by link. */\nconst byLink = computed(() =>\n (issues.value?.[0]?.details.table?.columns ?? []).some((column) => column.key === 'location'),\n)\n\nconst views = computed(() => [\n { value: 'pages', label: t('page.view-pages') },\n { value: 'links', label: t('page.view-links') },\n])\n\n/* By link needs every page of the check, not the fifty loaded: a link is counted on all of them. */\nasync function loadEverything(): Promise<void> {\n if (everything.value) return\n\n try {\n const all: AuditIssue[] = []\n let next = 1\n let last = 1\n\n do {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 200 })\n\n all.push(...answer.data)\n last = answer.last_page\n next++\n } while (next <= last)\n\n everything.value = all\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nfunction switchView(value: View): void {\n view.value = value\n if (value === 'links') loadEverything()\n}\n\nfunction hide(issue: AuditIssue): void {\n hiding.value = issue\n hideDialog.value = true\n}\n\n/* What the rule hid leaves this list at once; the table above counts again. */\nfunction hidden(rule: AuditIgnoreRule): void {\n if (issues.value && !rule.pattern) issues.value = []\n else if (issues.value && hiding.value)\n issues.value = issues.value.filter((one) => one.id !== hiding.value?.id)\n\n emit('changed')\n}\n\nasync function unhide(issue: AuditIssue): Promise<void> {\n if (!issue.ignore) return\n\n try {\n await api.unhide(issue.ignore.id)\n toast.success(t('page.unhidden'))\n emit('changed')\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction why(issue: AuditIssue): string {\n const rule = issue.ignore\n\n if (!rule) return ''\n\n return rule.created_by\n ? t('page.hidden-by', { who: rule.created_by, reason: rule.reason })\n : t('page.hidden-reason', { reason: rule.reason })\n}\n\nfunction fix(issue: AuditIssue): void {\n fixing.value = issue\n dialog.value = true\n}\n\nfunction fixed(id: string): void {\n if (fixing.value) fixing.value.fixed_with = id\n}\n\nasync function load(next = 1): Promise<void> {\n try {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 50 })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nonMounted(() => load())\n</script>\n\n<template>\n <div class=\"wx-audit-issues\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <wx-segmented\n v-if=\"byLink\"\n :model-value=\"view\"\n :options=\"views\"\n size=\"sm\"\n class=\"wx-audit-issues__view\"\n @update:model-value=\"switchView($event as View)\"\n />\n\n <template v-if=\"view === 'links'\">\n <audit-link-groups v-if=\"everything\" :issues=\"everything\" />\n <wx-skeleton v-else :rows=\"2\" />\n </template>\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-issues__item\">\n <div class=\"wx-audit-issues__head\">\n <audit-address v-if=\"issue.url\" :href=\"issue.url\" strong class=\"wx-audit-issues__url\" />\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\" class=\"wx-audit-issues__count\">{{\n issue.details.count\n }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-if=\"issue.fixed_with\" type=\"success\" size=\"sm\">{{\n t('page.fix-pressed')\n }}</wx-badge>\n <wx-button\n v-else-if=\"fixable && can && !issue.ignored\"\n size=\"sm\"\n variant=\"outline\"\n icon=\"check\"\n class=\"wx-audit-issues__fix\"\n @click=\"fix(issue)\"\n >{{ t('page.fix-button') }}</wx-button\n >\n <wx-button\n v-if=\"can && issue.ignored && issue.ignore\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye\"\n class=\"wx-audit-issues__end\"\n @click=\"unhide(issue)\"\n >{{ t('page.unhide') }}</wx-button\n >\n <wx-button\n v-else-if=\"can && !issue.ignored\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye-off\"\n :class=\"{ 'wx-audit-issues__end': !fixable || issue.fixed_with }\"\n @click=\"hide(issue)\"\n >{{ t('page.hide') }}</wx-button\n >\n </div>\n <div class=\"wx-audit-issues__body\">\n <wx-text v-if=\"issue.ignore\" size=\"sm\" tone=\"muted\">{{ why(issue) }}</wx-text>\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n </template>\n\n <audit-fix-dialog\n v-if=\"fixing\"\n v-model:open=\"dialog\"\n :run=\"run\"\n :issue=\"fixing\"\n @fixed=\"fixed\"\n />\n\n <audit-hide-dialog\n v-if=\"hiding\"\n v-model:open=\"hideDialog\"\n :issue=\"hiding\"\n :title=\"props.title ?? hiding.check\"\n @hidden=\"hidden\"\n />\n </div>\n</template>\n\n<style scoped>\n.wx-audit-issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-issues__view {\n align-self: flex-start;\n}\n\n/* A card per finding: the page is the edge, its addresses are inside. */\n.wx-audit-issues__item {\n display: flex;\n flex-direction: column;\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-issues__head {\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n}\n\n.wx-audit-issues__body {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n.wx-audit-issues__body:empty {\n display: none;\n}\n\n.wx-audit-issues__fix,\n.wx-audit-issues__end {\n margin-inline-start: auto;\n}\n\n/* The address gives way to the badges and buttons beside it, one line at any width. */\n.wx-audit-issues__url {\n flex: 0 1 auto;\n}\n\n.wx-audit-issues__count {\n flex-shrink: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxDescriptions,\n WxDescriptionsItem,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditIssueList from './AuditIssueList.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditCheckRow, AuditSeverity } from './types'\n\n/**\n * The findings of the last finished run (§8): one row per check, worst first; a row opens into\n * its addresses. «Hidden» in the state filter lists what the rules hide, each with its reason. The «?» beside a check says what was found, why it matters and how to fix it —\n * the three texts every check carries.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst run = ref<number | null>(null)\nconst checks = ref<AuditCheckRow[] | null>(null)\nconst loading = ref(false)\nconst expanded = ref<(string | number)[]>([])\n\nconst severity = ref<AuditSeverity | null>(null)\nconst group = ref<string | null>(null)\ntype State = 'new' | 'persisting' | 'hidden'\n\nconst state = ref<State | null>(null)\n\nconst query = computed(() => ({ severity: severity.value, group: group.value, state: state.value }))\nconst filtersCount = computed(\n () => [severity.value, group.value, state.value].filter(Boolean).length,\n)\n\nconst types: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditCheckRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'count', label: t('page.count'), width: 110, align: 'right' },\n])\n\nconst severityOptions = computed(() =>\n (['error', 'warning', 'notice'] as const).map((value) => ({\n value,\n label: t(`page.severity-${value}`),\n })),\n)\n\nconst groupOptions = computed(() =>\n [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n ].map((value) => ({ value, label: t(`page.group-${value}`) })),\n)\n\nconst stateOptions = computed(() =>\n (['new', 'persisting', 'hidden'] as const).map((value) => ({\n value,\n label: t(`page.state-${value}`),\n })),\n)\n\n/* The selects hand back `string | number`; the filters only ever hold the values offered. */\nfunction pick<T extends string>(value: SelectValue | SelectValue[] | null | undefined): T | null {\n return typeof value === 'string' && value !== '' ? (value as T) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n if (run.value === null) {\n run.value = (await api.latest()).done?.id ?? null\n }\n\n checks.value = run.value === null ? [] : await api.checks(run.value, query.value)\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch(query, () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"issues\">\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"checks ?? []\"\n :columns=\"columns\"\n row-key=\"id\"\n expandable\n flush\n :loading=\"loading\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :empty-text=\"run === null ? t('page.never') : t('page.empty')\"\n >\n <template #filters>\n <div class=\"wx-audit-findings__filters\">\n <wx-select\n :model-value=\"severity\"\n :options=\"severityOptions\"\n :placeholder=\"t('page.any-severity')\"\n clearable\n @update:model-value=\"severity = pick<AuditSeverity>($event)\"\n />\n <wx-select\n :model-value=\"group\"\n :options=\"groupOptions\"\n :placeholder=\"t('page.any-group')\"\n clearable\n @update:model-value=\"group = pick($event)\"\n />\n <wx-select\n :model-value=\"state\"\n :options=\"stateOptions\"\n :placeholder=\"t('page.any-state')\"\n clearable\n @update:model-value=\"state = pick<State>($event)\"\n />\n </div>\n </template>\n\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"types[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n\n <template #cell-title=\"{ row }\">\n <span class=\"wx-audit-findings__title\">\n <wx-text size=\"sm\">{{ row.title }}</wx-text>\n <wx-badge v-if=\"row.new > 0\" type=\"primary\" size=\"sm\">{{ t('page.state-new') }}</wx-badge>\n <wx-popover :title=\"row.title\" width=\"360\">\n <template #trigger>\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"question\"\n :aria-label=\"t('page.explain')\"\n @click.stop\n />\n </template>\n <wx-descriptions :columns=\"1\" layout=\"vertical\" size=\"sm\">\n <wx-descriptions-item :label=\"t('page.found')\">{{ row.found }}</wx-descriptions-item>\n <wx-descriptions-item :label=\"t('page.why')\">{{ row.why }}</wx-descriptions-item>\n <wx-descriptions-item :label=\"t('page.fix')\">{{ row.fix }}</wx-descriptions-item>\n </wx-descriptions>\n </wx-popover>\n </span>\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-issue-list\n v-if=\"run !== null\"\n :run=\"run\"\n :query=\"{ ...query, check: row.id }\"\n :fixable=\"(row.fixes ?? []).length > 0\"\n :title=\"row.title\"\n @changed=\"load\"\n />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-findings__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-findings__title {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n</style>\n"],"names":["props","__props","emit","__emit","open","_useModel","api","createAuditApi","useAdmin","useAuditMessages","t","useTranslate","message","useErrorText","router","useRouter","offers","ref","failure","applying","load","error","apply","offer","toast","edit","url","watch","now","_createBlock","_unref","WxDialog","$event","_createElementVNode","_hoisted_1","WxText","WxSkeleton","_createElementBlock","_Fragment","_renderList","_createVNode","_createTextVNode","_toDisplayString","_hoisted_2","_openBlock","change","index","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","WxButton","_hoisted_7","FEW","groups","computed","found","issue","row","location","key","group","place","attr","first","one","a","b","value","keyOf","shown","toggle","next","AuditAddress","WxIcon","differences","WxBadge","AuditLinkAttrs","AuditStatus","context","can","issues","more","page","fixing","dialog","hiding","hideDialog","view","everything","byLink","column","views","loadEverything","all","last","answer","switchView","hide","hidden","rule","unhide","why","fix","fixed","id","onMounted","WxSegmented","_cache","AuditLinkGroups","WxTooltip","_normalizeClass","AuditDetails","AuditFixDialog","AuditHideDialog","panel","run","checks","loading","expanded","severity","state","query","filtersCount","types","columns","severityOptions","groupOptions","stateOptions","pick","AuditLayout","WxTable","WxSelect","_withCtx","WxPopover","WxDescriptions","WxDescriptionsItem","AuditIssueList"],"mappings":"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"}
1
+ {"version":3,"file":"AuditIssuesPage-CdWydT5i.js","sources":["../src/AuditFixDialog.vue","../src/AuditLinkGroups.vue","../src/AuditIssueList.vue","../src/AuditIssuesPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxSkeleton, WxText, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditFixOffer, AuditIssue } from './types'\n\n/**\n * The fix button's dialog (§8, decision 4): the fixes that can close one finding, each with what\n * it would change — the records and fields with their counts, or a setting before and after —\n * and \"Apply\" under each. Nothing changes until it is pressed; the finding then waits for the\n * next run, which is the only thing that says it is gone.\n */\nconst props = defineProps<{ run: number; issue: AuditIssue }>()\nconst emit = defineEmits<{ fixed: [fix: string] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\nconst router = useRouter()\n\nconst offers = ref<AuditFixOffer[] | null>(null)\nconst failure = ref<string | null>(null)\nconst applying = ref<string | null>(null)\n\nasync function load(): Promise<void> {\n offers.value = null\n failure.value = null\n\n try {\n offers.value = await api.fixes(props.run, props.issue.id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function apply(offer: AuditFixOffer): Promise<void> {\n applying.value = offer.id\n\n try {\n await api.fix(props.run, props.issue.id, offer.id)\n toast.success(t('page.fix-applied'))\n emit('fixed', offer.id)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n applying.value = null\n }\n}\n\nfunction edit(url: string): void {\n open.value = false\n void router.push(url)\n}\n\n// Immediate: the list mounts the dialog already open, the first time a button is pressed.\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (now) void load()\n },\n { immediate: true },\n)\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.fix-button')\" :width=\"640\">\n <div class=\"wx-audit-fix\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!offers\" :rows=\"3\" />\n <wx-text v-else-if=\"offers.length === 0\" size=\"sm\" tone=\"muted\">{{\n t('page.fix-none')\n }}</wx-text>\n\n <section v-for=\"offer in offers ?? []\" :key=\"offer.id\" class=\"wx-audit-fix__offer\">\n <wx-text weight=\"semibold\">{{ offer.title }}</wx-text>\n <wx-text v-if=\"offer.description\" size=\"sm\" tone=\"muted\">{{ offer.description }}</wx-text>\n\n <table class=\"wx-audit-fix__changes\">\n <thead>\n <tr>\n <th>{{ t('page.fix-changes') }}</th>\n <th>{{ t('page.fix-before') }}</th>\n <th>{{ t('page.fix-after') }}</th>\n <th />\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(change, index) in offer.changes\" :key=\"index\">\n <td>\n <div>{{ change.label }}</div>\n <div v-if=\"change.field\" class=\"wx-audit-fix__field\">{{ change.field }}</div>\n </td>\n <td class=\"wx-audit-fix__value\">\n {{ change.before ?? '' }}\n <span v-if=\"change.count\" class=\"wx-audit-fix__count\">× {{ change.count }}</span>\n </td>\n <td class=\"wx-audit-fix__value\">{{ change.after ?? '' }}</td>\n <td>\n <wx-button\n v-if=\"change.edit_url\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n :aria-label=\"t('page.open-editor')\"\n @click=\"edit(change.edit_url)\"\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <wx-text v-if=\"offer.note\" size=\"sm\" tone=\"muted\">{{ offer.note }}</wx-text>\n\n <div class=\"wx-audit-fix__actions\">\n <wx-button\n type=\"primary\"\n size=\"sm\"\n :loading=\"applying === offer.id\"\n :disabled=\"applying !== null\"\n @click=\"apply(offer)\"\n >{{ t('page.fix-apply') }}</wx-button\n >\n </div>\n </section>\n </div>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-fix {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n.wx-audit-fix__offer {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-fix__changes {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-fix__changes th {\n padding: var(--wx-space-4) var(--wx-space-8);\n color: var(--wx-text-muted);\n font-weight: var(--wx-font-weight-medium);\n text-align: start;\n border-bottom: 1px solid var(--wx-border-default);\n}\n\n.wx-audit-fix__changes td {\n padding: var(--wx-space-6) var(--wx-space-8);\n vertical-align: top;\n border-bottom: 1px solid var(--wx-border-default);\n overflow-wrap: anywhere;\n}\n\n.wx-audit-fix__field,\n.wx-audit-fix__count {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-fix__value {\n white-space: pre-line;\n}\n\n.wx-audit-fix__actions {\n display: flex;\n justify-content: flex-end;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIssue } from './types'\n\n/**\n * The findings of a redirect check turned inside out: one card per link, the pages it is on\n * under it. A link in the footer or the menu is on every page and is fixed once, in one place —\n * by page, it would be the same row forty times.\n */\nconst props = defineProps<{ issues: AuditIssue[] }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\ninterface LinkGroup {\n url: string\n location: string\n status: number | null\n pages: LinkPlace[]\n /** The pages write the link with different `rel` or `target`: each says its own. */\n mixed: boolean\n}\n\ninterface LinkPlace {\n page: string\n rel: string | null\n target: string | null\n}\n\n/** How many pages a card lists before «Show all». */\nconst FEW = 5\n\nconst open = ref(new Set<string>())\n\nconst groups = computed<LinkGroup[]>(() => {\n const found = new Map<string, LinkGroup>()\n\n for (const issue of props.issues) {\n for (const row of issue.details.table?.rows ?? []) {\n const url = String(row.url ?? '')\n const location = String(row.location ?? '')\n const key = `${url}\\n${location}`\n const group = found.get(key) ?? { url, location, status: null, pages: [], mixed: false }\n const place = { page: issue.url ?? '', rel: attr(row.rel), target: attr(row.target) }\n const first = group.pages[0]\n\n group.status ??= typeof row.status === 'number' ? row.status : null\n if (first && (first.rel !== place.rel || first.target !== place.target)) group.mixed = true\n if (place.page && !group.pages.some((one) => one.page === place.page)) group.pages.push(place)\n found.set(key, group)\n }\n }\n\n return [...found.values()].sort((a, b) => b.pages.length - a.pages.length)\n})\n\nfunction attr(value: unknown): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction keyOf(group: LinkGroup): string {\n return `${group.url}\\n${group.location}`\n}\n\nfunction shown(group: LinkGroup): LinkPlace[] {\n return open.value.has(keyOf(group)) ? group.pages : group.pages.slice(0, FEW)\n}\n\n/* «Show all» turns into «Collapse», so a long card folds back where it is read. */\nfunction toggle(group: LinkGroup): void {\n const next = new Set(open.value)\n\n if (!next.delete(keyOf(group))) next.add(keyOf(group))\n open.value = next\n}\n</script>\n\n<template>\n <div class=\"wx-audit-links\">\n <div v-for=\"group in groups\" :key=\"keyOf(group)\" class=\"wx-audit-links__card\">\n <div class=\"wx-audit-links__head\">\n <audit-address :href=\"group.url\" type=\"muted\" class=\"wx-audit-links__from\" />\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-links__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"group.location\" strong class=\"wx-audit-links__to\" />\n <wx-badge\n v-for=\"change in differences(group.url, group.location)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n <audit-link-attrs\n v-if=\"!group.mixed && group.pages[0]\"\n :rel=\"group.pages[0].rel\"\n :target=\"group.pages[0].target\"\n class=\"wx-audit-links__fixed\"\n />\n <audit-status v-if=\"group.status !== null\" :code=\"group.status\" />\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-links__count\">{{\n t('page.link-pages', { count: group.pages.length })\n }}</wx-text>\n </div>\n\n <ul class=\"wx-audit-links__pages\">\n <li v-for=\"place in shown(group)\" :key=\"place.page\">\n <audit-address :href=\"place.page\" />\n <audit-link-attrs\n v-if=\"group.mixed\"\n :rel=\"place.rel\"\n :target=\"place.target\"\n class=\"wx-audit-links__fixed\"\n />\n </li>\n </ul>\n\n <wx-button\n v-if=\"group.pages.length > FEW\"\n size=\"sm\"\n variant=\"text\"\n class=\"wx-audit-links__more\"\n @click=\"toggle(group)\"\n >{{ open.has(keyOf(group)) ? t('page.link-collapse') : t('page.link-show-all') }}</wx-button\n >\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-links {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-links__card {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-links__head {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__from,\n.wx-audit-links__to {\n flex: 0 1 auto;\n}\n\n.wx-audit-links__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-links__fixed {\n flex-shrink: 0;\n}\n\n.wx-audit-links__pages li {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-links__count {\n flex-shrink: 0;\n margin-inline-start: auto;\n white-space: nowrap;\n}\n\n.wx-audit-links__pages {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n margin: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n list-style: none;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-links__more {\n margin: 0 var(--wx-space-12) var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { toast, WxBadge, WxButton, WxSegmented, WxSkeleton, WxText, WxTooltip } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditFixDialog from './AuditFixDialog.vue'\nimport AuditHideDialog from './AuditHideDialog.vue'\nimport AuditLinkGroups from './AuditLinkGroups.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue, AuditIssueQuery } from './types'\n\n/**\n * The addresses of one check, under its row in the findings table: loaded when the row opens,\n * fifty at a time. A check that has fixes gets a button on each address; the dialog shows what\n * it would change before anything does. «Hide» asks for the reason; on the list of hidden ones\n * each says why, and «Show again» removes the rule.\n *\n * Each finding is a card: the address with its count, the table under it. A check of links that\n * redirect can also be read by link — every page loaded, one card per link with its pages.\n */\nconst props = defineProps<{\n run: number\n query: AuditIssueQuery\n fixable?: boolean\n /** The check's title, for the hiding dialog. */\n title?: string\n}>()\n\nconst emit = defineEmits<{ changed: [] }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\n// A boolean, not a computed: the permissions do not change while the screen is open.\nconst can = context.can('audit.manage')\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst issues = ref<AuditIssue[] | null>(null)\nconst more = ref(false)\nconst page = ref(1)\nconst failure = ref<string | null>(null)\nconst fixing = ref<AuditIssue | null>(null)\nconst dialog = ref(false)\nconst hiding = ref<AuditIssue | null>(null)\nconst hideDialog = ref(false)\n\ntype View = 'pages' | 'links'\n\nconst view = ref<View>('pages')\nconst everything = ref<AuditIssue[] | null>(null)\n\n/** Rows with where each address leads: the findings can be grouped by link. */\nconst byLink = computed(() =>\n (issues.value?.[0]?.details.table?.columns ?? []).some((column) => column.key === 'location'),\n)\n\nconst views = computed(() => [\n { value: 'pages', label: t('page.view-pages') },\n { value: 'links', label: t('page.view-links') },\n])\n\n/* By link needs every page of the check, not the fifty loaded: a link is counted on all of them. */\nasync function loadEverything(): Promise<void> {\n if (everything.value) return\n\n try {\n const all: AuditIssue[] = []\n let next = 1\n let last = 1\n\n do {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 200 })\n\n all.push(...answer.data)\n last = answer.last_page\n next++\n } while (next <= last)\n\n everything.value = all\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nfunction switchView(value: View): void {\n view.value = value\n if (value === 'links') loadEverything()\n}\n\nfunction hide(issue: AuditIssue): void {\n hiding.value = issue\n hideDialog.value = true\n}\n\n/* What the rule hid leaves this list at once; the table above counts again. */\nfunction hidden(rule: AuditIgnoreRule): void {\n if (issues.value && !rule.pattern) issues.value = []\n else if (issues.value && hiding.value)\n issues.value = issues.value.filter((one) => one.id !== hiding.value?.id)\n\n emit('changed')\n}\n\nasync function unhide(issue: AuditIssue): Promise<void> {\n if (!issue.ignore) return\n\n try {\n await api.unhide(issue.ignore.id)\n toast.success(t('page.unhidden'))\n emit('changed')\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction why(issue: AuditIssue): string {\n const rule = issue.ignore\n\n if (!rule) return ''\n\n return rule.created_by\n ? t('page.hidden-by', { who: rule.created_by, reason: rule.reason })\n : t('page.hidden-reason', { reason: rule.reason })\n}\n\nfunction fix(issue: AuditIssue): void {\n fixing.value = issue\n dialog.value = true\n}\n\nfunction fixed(id: string): void {\n if (fixing.value) fixing.value.fixed_with = id\n}\n\nasync function load(next = 1): Promise<void> {\n try {\n const answer = await api.issues(props.run, { ...props.query, page: next, per_page: 50 })\n\n issues.value = next === 1 ? answer.data : [...(issues.value ?? []), ...answer.data]\n page.value = answer.current_page\n more.value = answer.current_page < answer.last_page\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nonMounted(() => load())\n</script>\n\n<template>\n <div class=\"wx-audit-issues\">\n <wx-text v-if=\"failure\" size=\"sm\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!issues\" :rows=\"2\" />\n\n <template v-else>\n <wx-segmented\n v-if=\"byLink\"\n :model-value=\"view\"\n :options=\"views\"\n size=\"sm\"\n class=\"wx-audit-issues__view\"\n @update:model-value=\"switchView($event as View)\"\n />\n\n <template v-if=\"view === 'links'\">\n <audit-link-groups v-if=\"everything\" :issues=\"everything\" />\n <wx-skeleton v-else :rows=\"2\" />\n </template>\n\n <template v-else>\n <div v-for=\"issue in issues\" :key=\"issue.id\" class=\"wx-audit-issues__item\">\n <div class=\"wx-audit-issues__head\">\n <audit-address v-if=\"issue.url\" :href=\"issue.url\" strong class=\"wx-audit-issues__url\" />\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\" class=\"wx-audit-issues__count\">{{\n issue.details.count\n }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-if=\"issue.fixed_with\" type=\"success\" size=\"sm\">{{\n t('page.fix-pressed')\n }}</wx-badge>\n <wx-button\n v-else-if=\"fixable && can && !issue.ignored\"\n size=\"sm\"\n variant=\"outline\"\n icon=\"check\"\n class=\"wx-audit-issues__fix\"\n @click=\"fix(issue)\"\n >{{ t('page.fix-button') }}</wx-button\n >\n <wx-button\n v-if=\"can && issue.ignored && issue.ignore\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye\"\n class=\"wx-audit-issues__end\"\n @click=\"unhide(issue)\"\n >{{ t('page.unhide') }}</wx-button\n >\n <wx-button\n v-else-if=\"can && !issue.ignored\"\n size=\"sm\"\n variant=\"text\"\n icon=\"eye-off\"\n :class=\"{ 'wx-audit-issues__end': !fixable || issue.fixed_with }\"\n @click=\"hide(issue)\"\n >{{ t('page.hide') }}</wx-button\n >\n </div>\n <div class=\"wx-audit-issues__body\">\n <wx-text v-if=\"issue.ignore\" size=\"sm\" tone=\"muted\">{{ why(issue) }}</wx-text>\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n\n <wx-button v-if=\"more\" size=\"sm\" variant=\"text\" @click=\"load(page + 1)\">…</wx-button>\n </template>\n </template>\n\n <audit-fix-dialog\n v-if=\"fixing\"\n v-model:open=\"dialog\"\n :run=\"run\"\n :issue=\"fixing\"\n @fixed=\"fixed\"\n />\n\n <audit-hide-dialog\n v-if=\"hiding\"\n v-model:open=\"hideDialog\"\n :issue=\"hiding\"\n :title=\"props.title ?? hiding.check\"\n @hidden=\"hidden\"\n />\n </div>\n</template>\n\n<style scoped>\n.wx-audit-issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-issues__view {\n align-self: flex-start;\n}\n\n/* A card per finding: the page is the edge, its addresses are inside. */\n.wx-audit-issues__item {\n display: flex;\n flex-direction: column;\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-issues__head {\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n}\n\n.wx-audit-issues__body {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n.wx-audit-issues__body:empty {\n display: none;\n}\n\n.wx-audit-issues__fix,\n.wx-audit-issues__end {\n margin-inline-start: auto;\n}\n\n/* The address gives way to the badges and buttons beside it, one line at any width. */\n.wx-audit-issues__url {\n flex: 0 1 auto;\n}\n\n.wx-audit-issues__count {\n flex-shrink: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxDescriptions,\n WxDescriptionsItem,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type BadgeType,\n type SelectValue,\n type TableColumn,\n} from '@webx-ui/core'\nimport AuditIssueList from './AuditIssueList.vue'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditCheckRow, AuditSeverity } from './types'\n\n/**\n * The findings of the last finished run (§8): one row per check, worst first; a row opens into\n * its addresses. «Hidden» in the state filter lists what the rules hide, each with its reason. The «?» beside a check says what was found, why it matters and how to fix it —\n * the three texts every check carries.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst run = ref<number | null>(null)\nconst checks = ref<AuditCheckRow[] | null>(null)\nconst loading = ref(false)\nconst expanded = ref<(string | number)[]>([])\n\nconst severity = ref<AuditSeverity | null>(null)\nconst group = ref<string | null>(null)\ntype State = 'new' | 'persisting' | 'hidden'\n\nconst state = ref<State | null>(null)\n\nconst query = computed(() => ({ severity: severity.value, group: group.value, state: state.value }))\nconst filtersCount = computed(\n () => [severity.value, group.value, state.value].filter(Boolean).length,\n)\n\nconst types: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst columns = computed<TableColumn<AuditCheckRow>[]>(() => [\n { key: 'severity', label: t('page.severity'), width: 130 },\n { key: 'title', label: t('page.check') },\n { key: 'count', label: t('page.count'), width: 110, align: 'right' },\n])\n\nconst severityOptions = computed(() =>\n (['error', 'warning', 'notice'] as const).map((value) => ({\n value,\n label: t(`page.severity-${value}`),\n })),\n)\n\nconst groupOptions = computed(() =>\n [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n ].map((value) => ({ value, label: t(`page.group-${value}`) })),\n)\n\nconst stateOptions = computed(() =>\n (['new', 'persisting', 'hidden'] as const).map((value) => ({\n value,\n label: t(`page.state-${value}`),\n })),\n)\n\n/* The selects hand back `string | number`; the filters only ever hold the values offered. */\nfunction pick<T extends string>(value: SelectValue | SelectValue[] | null | undefined): T | null {\n return typeof value === 'string' && value !== '' ? (value as T) : null\n}\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n if (run.value === null) {\n run.value = (await api.latest()).done?.id ?? null\n }\n\n checks.value = run.value === null ? [] : await api.checks(run.value, query.value)\n expanded.value = []\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nwatch(query, () => void load())\n\nonMounted(load)\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"issues\">\n <wx-table\n v-model:expanded=\"expanded\"\n :data=\"checks ?? []\"\n :columns=\"columns\"\n row-key=\"id\"\n expandable\n flush\n :loading=\"loading\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :empty-text=\"run === null ? t('page.never') : t('page.empty')\"\n >\n <template #filters>\n <div class=\"wx-audit-findings__filters\">\n <wx-select\n :model-value=\"severity\"\n :options=\"severityOptions\"\n :placeholder=\"t('page.any-severity')\"\n clearable\n @update:model-value=\"severity = pick<AuditSeverity>($event)\"\n />\n <wx-select\n :model-value=\"group\"\n :options=\"groupOptions\"\n :placeholder=\"t('page.any-group')\"\n clearable\n @update:model-value=\"group = pick($event)\"\n />\n <wx-select\n :model-value=\"state\"\n :options=\"stateOptions\"\n :placeholder=\"t('page.any-state')\"\n clearable\n @update:model-value=\"state = pick<State>($event)\"\n />\n </div>\n </template>\n\n <template #cell-severity=\"{ row }\">\n <wx-badge :type=\"types[row.severity]\" dot>{{\n t(`page.severity-${row.severity}`)\n }}</wx-badge>\n </template>\n\n <template #cell-title=\"{ row }\">\n <span class=\"wx-audit-findings__title\">\n <wx-text size=\"sm\">{{ row.title }}</wx-text>\n <wx-badge v-if=\"row.new > 0\" type=\"primary\" size=\"sm\">{{ t('page.state-new') }}</wx-badge>\n <wx-popover :title=\"row.title\" width=\"360\">\n <template #trigger>\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"question\"\n :aria-label=\"t('page.explain')\"\n @click.stop\n />\n </template>\n <wx-descriptions :columns=\"1\" layout=\"vertical\" size=\"sm\">\n <wx-descriptions-item :label=\"t('page.found')\">{{ row.found }}</wx-descriptions-item>\n <wx-descriptions-item :label=\"t('page.why')\">{{ row.why }}</wx-descriptions-item>\n <wx-descriptions-item :label=\"t('page.fix')\">{{ row.fix }}</wx-descriptions-item>\n </wx-descriptions>\n </wx-popover>\n </span>\n </template>\n\n <template #expanded=\"{ row }\">\n <audit-issue-list\n v-if=\"run !== null\"\n :run=\"run\"\n :query=\"{ ...query, check: row.id }\"\n :fixable=\"(row.fixes ?? []).length > 0\"\n :title=\"row.title\"\n @changed=\"load\"\n />\n </template>\n </wx-table>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-findings__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-findings__title {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n</style>\n"],"names":["props","__props","emit","__emit","open","_useModel","api","createAuditApi","useAdmin","useAuditMessages","t","useTranslate","message","useErrorText","router","useRouter","offers","ref","failure","applying","load","error","apply","offer","toast","edit","url","watch","now","_createBlock","_unref","WxDialog","$event","_createElementVNode","_hoisted_1","WxText","WxSkeleton","_createElementBlock","_Fragment","_renderList","_createVNode","_createTextVNode","_toDisplayString","_hoisted_2","_openBlock","change","index","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","WxButton","_hoisted_7","FEW","groups","computed","found","issue","row","location","key","group","place","attr","first","one","a","b","value","keyOf","shown","toggle","next","AuditAddress","WxIcon","differences","WxBadge","AuditLinkAttrs","AuditStatus","context","can","issues","more","page","fixing","dialog","hiding","hideDialog","view","everything","byLink","column","views","loadEverything","all","last","answer","switchView","hide","hidden","rule","unhide","why","fix","fixed","id","onMounted","WxSegmented","_cache","AuditLinkGroups","WxTooltip","_normalizeClass","AuditDetails","AuditFixDialog","AuditHideDialog","panel","run","checks","loading","expanded","severity","state","query","filtersCount","types","columns","severityOptions","groupOptions","stateOptions","pick","AuditLayout","WxTable","WxSelect","_withCtx","WxPopover","WxDescriptions","WxDescriptionsItem","AuditIssueList"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as g, computed as o, openBlock as m, createBlock as f, unref as w, withCtx as b, renderSlot as h } from "vue";
2
2
  import { useRouter as _, useRoute as x } from "vue-router";
3
3
  import { useAdmin as $, useTranslate as k, WxListScreen as y } from "@webx-ui/module-admin";
4
- import { u as A } from "./index-_DgRf2O6.js";
4
+ import { u as A } from "./index-BxS_t2W2.js";
5
5
  const R = /* @__PURE__ */ g({
6
6
  __name: "AuditLayout",
7
7
  props: {
@@ -63,4 +63,4 @@ const R = /* @__PURE__ */ g({
63
63
  export {
64
64
  R as _
65
65
  };
66
- //# sourceMappingURL=AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js.map
66
+ //# sourceMappingURL=AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js","sources":["../src/AuditLayout.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useAdmin, useTranslate, WxListScreen, type ScreenAction } from '@webx-ui/module-admin'\nimport type { TabItem, TabValue } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The head of the section: its name, its views — the overview, the findings, the pages, the\n * hosts the site points at and the runs — and the way to the section's own settings.\n */\n/*\n * `card` has its default here and not as `?? true` below: Vue turns a Boolean prop nobody passed\n * into `false`, so the coalescing never fired and every table stood without its card.\n */\nconst props = withDefaults(\n defineProps<{\n base: string\n current: 'overview' | 'issues' | 'pages' | 'hosts' | 'runs' | 'settings'\n /** A card around the slot — the tables want one, the overview draws its own. */\n card?: boolean\n /** What the view itself offers in the head, before the way to the settings. */\n actions?: ScreenAction[]\n }>(),\n { card: true, actions: () => [] },\n)\n\ndefineSlots<{ default?: () => unknown }>()\n\nconst context = useAdmin()\nconst router = useRouter()\nconst route = useRoute()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst title = computed(\n () =>\n context.state.manifest?.modules.find((module) => module.id === 'audit')?.title ??\n t('module.title'),\n)\n\nconst views = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.overview') },\n { value: 'issues', label: t('page.issues') },\n { value: 'pages', label: t('page.pages') },\n { value: 'hosts', label: t('page.hosts') },\n { value: 'runs', label: t('page.runs') },\n])\n\n/* The settings are a view of their own, out of the tabs: opened now and then, not every day. */\nconst actions = computed<ScreenAction[]>(() =>\n props.current === 'settings'\n ? props.actions\n : [\n ...props.actions,\n {\n key: 'settings',\n label: t('page.settings'),\n icon: 'settings',\n run: () => void router.push(`${props.base}/settings`),\n },\n ],\n)\n\nconst where = computed<TabValue>({\n /*\n * The settings belong to no tab, but the tabs need a value of theirs — given one they do not\n * have, they correct it to the first and lead away at once. So «Overview» stays lit, and the\n * settings page has a «Back» of its own beside «Save».\n */\n get: () => (props.current === 'settings' ? 'overview' : props.current),\n set: (next) => {\n const path = next === 'overview' ? props.base : `${props.base}/${String(next)}`\n\n if (path !== route.path) void router.push(path)\n },\n})\n</script>\n\n<template>\n <wx-list-screen\n v-model:view=\"where\"\n :title=\"title\"\n :views=\"views\"\n :actions=\"actions\"\n :card=\"props.card\"\n >\n <slot />\n </wx-list-screen>\n</template>\n"],"names":["props","__props","context","useAdmin","router","useRouter","route","useRoute","useAuditMessages","useTranslate","title","computed","module","views","actions","where","next","path","_createBlock","_unref","WxListScreen","$event","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;AAeA,UAAMA,IAAQC,GAcRC,IAAUC,EAAA,GACVC,IAASC,EAAA,GACTC,IAAQC,EAAA;AAEd,IAAAC,EAAA;AAEA,UAAM,IAAIC,EAAa,YAAY,GAE7BC,IAAQC;AAAA,MACZ,MACET,EAAQ,MAAM,UAAU,QAAQ,KAAK,CAACU,MAAWA,EAAO,OAAO,OAAO,GAAG,SACzE,EAAE,cAAc;AAAA,IAAA,GAGdC,IAAQF,EAAoB,MAAM;AAAA,MACtC,EAAE,OAAO,YAAY,OAAO,EAAE,eAAe,EAAA;AAAA,MAC7C,EAAE,OAAO,UAAU,OAAO,EAAE,aAAa,EAAA;AAAA,MACzC,EAAE,OAAO,SAAS,OAAO,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,SAAS,OAAO,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,QAAQ,OAAO,EAAE,WAAW,EAAA;AAAA,IAAE,CACxC,GAGKG,IAAUH;AAAA,MAAyB,MACvCX,EAAM,YAAY,aACdA,EAAM,UACN;AAAA,QACE,GAAGA,EAAM;AAAA,QACT;AAAA,UACE,KAAK;AAAA,UACL,OAAO,EAAE,eAAe;AAAA,UACxB,MAAM;AAAA,UACN,KAAK,MAAA;AAAM,YAAKI,EAAO,KAAK,GAAGJ,EAAM,IAAI,WAAW;AAAA;AAAA,QAAA;AAAA,MACtD;AAAA,IACF,GAGAe,IAAQJ,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM/B,KAAK,MAAOX,EAAM,YAAY,aAAa,aAAaA,EAAM;AAAA,MAC9D,KAAK,CAACgB,MAAS;AACb,cAAMC,IAAOD,MAAS,aAAahB,EAAM,OAAO,GAAGA,EAAM,IAAI,IAAI,OAAOgB,CAAI,CAAC;AAE7E,QAAIC,MAASX,EAAM,QAAWF,EAAO,KAAKa,CAAI;AAAA,MAChD;AAAA,IAAA,CACD;2BAICC,EAQiBC,EAAAC,CAAA,GAAA;AAAA,MAPP,MAAML,EAAA;AAAA,8CAAAA,EAAK,QAAAM;AAAA,MAClB,OAAOX,EAAA;AAAA,MACP,OAAOG,EAAA;AAAA,MACP,SAASC,EAAA;AAAA,MACT,MAAMd,EAAM;AAAA,IAAA;iBAEb,MAAQ;AAAA,QAARsB,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;"}
1
+ {"version":3,"file":"AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js","sources":["../src/AuditLayout.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useAdmin, useTranslate, WxListScreen, type ScreenAction } from '@webx-ui/module-admin'\nimport type { TabItem, TabValue } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The head of the section: its name, its views — the overview, the findings, the pages, the\n * hosts the site points at and the runs — and the way to the section's own settings.\n */\n/*\n * `card` has its default here and not as `?? true` below: Vue turns a Boolean prop nobody passed\n * into `false`, so the coalescing never fired and every table stood without its card.\n */\nconst props = withDefaults(\n defineProps<{\n base: string\n current: 'overview' | 'issues' | 'pages' | 'hosts' | 'runs' | 'settings'\n /** A card around the slot — the tables want one, the overview draws its own. */\n card?: boolean\n /** What the view itself offers in the head, before the way to the settings. */\n actions?: ScreenAction[]\n }>(),\n { card: true, actions: () => [] },\n)\n\ndefineSlots<{ default?: () => unknown }>()\n\nconst context = useAdmin()\nconst router = useRouter()\nconst route = useRoute()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst title = computed(\n () =>\n context.state.manifest?.modules.find((module) => module.id === 'audit')?.title ??\n t('module.title'),\n)\n\nconst views = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.overview') },\n { value: 'issues', label: t('page.issues') },\n { value: 'pages', label: t('page.pages') },\n { value: 'hosts', label: t('page.hosts') },\n { value: 'runs', label: t('page.runs') },\n])\n\n/* The settings are a view of their own, out of the tabs: opened now and then, not every day. */\nconst actions = computed<ScreenAction[]>(() =>\n props.current === 'settings'\n ? props.actions\n : [\n ...props.actions,\n {\n key: 'settings',\n label: t('page.settings'),\n icon: 'settings',\n run: () => void router.push(`${props.base}/settings`),\n },\n ],\n)\n\nconst where = computed<TabValue>({\n /*\n * The settings belong to no tab, but the tabs need a value of theirs — given one they do not\n * have, they correct it to the first and lead away at once. So «Overview» stays lit, and the\n * settings page has a «Back» of its own beside «Save».\n */\n get: () => (props.current === 'settings' ? 'overview' : props.current),\n set: (next) => {\n const path = next === 'overview' ? props.base : `${props.base}/${String(next)}`\n\n if (path !== route.path) void router.push(path)\n },\n})\n</script>\n\n<template>\n <wx-list-screen\n v-model:view=\"where\"\n :title=\"title\"\n :views=\"views\"\n :actions=\"actions\"\n :card=\"props.card\"\n >\n <slot />\n </wx-list-screen>\n</template>\n"],"names":["props","__props","context","useAdmin","router","useRouter","route","useRoute","useAuditMessages","useTranslate","title","computed","module","views","actions","where","next","path","_createBlock","_unref","WxListScreen","$event","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;AAeA,UAAMA,IAAQC,GAcRC,IAAUC,EAAA,GACVC,IAASC,EAAA,GACTC,IAAQC,EAAA;AAEd,IAAAC,EAAA;AAEA,UAAM,IAAIC,EAAa,YAAY,GAE7BC,IAAQC;AAAA,MACZ,MACET,EAAQ,MAAM,UAAU,QAAQ,KAAK,CAACU,MAAWA,EAAO,OAAO,OAAO,GAAG,SACzE,EAAE,cAAc;AAAA,IAAA,GAGdC,IAAQF,EAAoB,MAAM;AAAA,MACtC,EAAE,OAAO,YAAY,OAAO,EAAE,eAAe,EAAA;AAAA,MAC7C,EAAE,OAAO,UAAU,OAAO,EAAE,aAAa,EAAA;AAAA,MACzC,EAAE,OAAO,SAAS,OAAO,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,SAAS,OAAO,EAAE,YAAY,EAAA;AAAA,MACvC,EAAE,OAAO,QAAQ,OAAO,EAAE,WAAW,EAAA;AAAA,IAAE,CACxC,GAGKG,IAAUH;AAAA,MAAyB,MACvCX,EAAM,YAAY,aACdA,EAAM,UACN;AAAA,QACE,GAAGA,EAAM;AAAA,QACT;AAAA,UACE,KAAK;AAAA,UACL,OAAO,EAAE,eAAe;AAAA,UACxB,MAAM;AAAA,UACN,KAAK,MAAA;AAAM,YAAKI,EAAO,KAAK,GAAGJ,EAAM,IAAI,WAAW;AAAA;AAAA,QAAA;AAAA,MACtD;AAAA,IACF,GAGAe,IAAQJ,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM/B,KAAK,MAAOX,EAAM,YAAY,aAAa,aAAaA,EAAM;AAAA,MAC9D,KAAK,CAACgB,MAAS;AACb,cAAMC,IAAOD,MAAS,aAAahB,EAAM,OAAO,GAAGA,EAAM,IAAI,IAAI,OAAOgB,CAAI,CAAC;AAE7E,QAAIC,MAASX,EAAM,QAAWF,EAAO,KAAKa,CAAI;AAAA,MAChD;AAAA,IAAA,CACD;2BAICC,EAQiBC,EAAAC,CAAA,GAAA;AAAA,MAPP,MAAML,EAAA;AAAA,8CAAAA,EAAK,QAAAM;AAAA,MAClB,OAAOX,EAAA;AAAA,MACP,OAAOG,EAAA;AAAA,MACP,SAASC,EAAA;AAAA,MACT,MAAMd,EAAM;AAAA,IAAA;iBAEb,MAAQ;AAAA,QAARsB,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;"}
@@ -1,8 +1,8 @@
1
1
  import { defineComponent as X, ref as P, computed as k, onMounted as Y, onBeforeUnmount as Z, openBlock as s, createBlock as n, withCtx as t, createElementVNode as g, unref as e, createVNode as l, createElementBlock as _, Fragment as h, createCommentVNode as d, createTextVNode as i, toDisplayString as u, renderList as z } from "vue";
2
2
  import { useAdmin as ee, useTranslate as ae, useErrorText as te, WxDate as se } from "@webx-ui/module-admin";
3
3
  import { WxCard as y, WxSkeleton as le, WxAlert as D, WxText as c, WxButton as $, WxProgress as R, WxSegmented as ue, WxEmpty as j, WxStatistic as O, WxBadge as E, WxPopover as re, toast as S } from "@webx-ui/core";
4
- import { _ as ie } from "./AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js";
5
- import { c as ne, u as oe, _ as ce } from "./index-_DgRf2O6.js";
4
+ import { _ as ie } from "./AuditLayout.vue_vue_type_script_setup_true_lang-BIj7GvJb.js";
5
+ import { c as ne, u as oe, _ as ce } from "./index-BxS_t2W2.js";
6
6
  const de = { class: "wx-audit-overview" }, ve = { class: "wx-audit-overview__row" }, pe = { class: "wx-audit-overview__row" }, ge = { class: "wx-audit-overview__summary" }, _e = { class: "wx-audit-overview__health" }, me = {
7
7
  key: 0,
8
8
  class: "wx-audit-overview__parts"
@@ -429,4 +429,4 @@ const de = { class: "wx-audit-overview" }, ve = { class: "wx-audit-overview__row
429
429
  export {
430
430
  Be as default
431
431
  };
432
- //# sourceMappingURL=AuditOverviewPage-B5mexNDW.js.map
432
+ //# sourceMappingURL=AuditOverviewPage-BqTU-JnS.js.map