@webx-ui/module-catalog-landings 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1653,54 +1653,50 @@ const Oa = /* @__PURE__ */ ge({
1653
1653
  ]),
1654
1654
  _: 1
1655
1655
  }, 8, ["label"]),
1656
- n(e(K), {
1657
- label: e(u)("panel.filter-attention")
1658
- }, {
1656
+ n(e(K), null, {
1659
1657
  default: l(() => [
1660
1658
  n(e(he), {
1661
1659
  modelValue: $.value,
1662
1660
  "onUpdate:modelValue": k[1] || (k[1] = (d) => $.value = d),
1663
- size: "sm"
1664
- }, null, 8, ["modelValue"])
1661
+ size: "sm",
1662
+ label: e(u)("panel.filter-attention")
1663
+ }, null, 8, ["modelValue", "label"])
1665
1664
  ]),
1666
1665
  _: 1
1667
- }, 8, ["label"]),
1668
- n(e(K), {
1669
- label: e(u)("panel.filter-published")
1670
- }, {
1666
+ }),
1667
+ n(e(K), null, {
1671
1668
  default: l(() => [
1672
1669
  n(e(he), {
1673
1670
  modelValue: A.value,
1674
1671
  "onUpdate:modelValue": k[2] || (k[2] = (d) => A.value = d),
1675
- size: "sm"
1676
- }, null, 8, ["modelValue"])
1672
+ size: "sm",
1673
+ label: e(u)("panel.filter-published")
1674
+ }, null, 8, ["modelValue", "label"])
1677
1675
  ]),
1678
1676
  _: 1
1679
- }, 8, ["label"]),
1680
- n(e(K), {
1681
- label: e(u)("panel.filter-empty")
1682
- }, {
1677
+ }),
1678
+ n(e(K), null, {
1683
1679
  default: l(() => [
1684
1680
  n(e(he), {
1685
1681
  modelValue: b.value,
1686
1682
  "onUpdate:modelValue": k[3] || (k[3] = (d) => b.value = d),
1687
- size: "sm"
1688
- }, null, 8, ["modelValue"])
1683
+ size: "sm",
1684
+ label: e(u)("panel.filter-empty")
1685
+ }, null, 8, ["modelValue", "label"])
1689
1686
  ]),
1690
1687
  _: 1
1691
- }, 8, ["label"]),
1692
- n(e(K), {
1693
- label: e(u)("panel.filter-trashed")
1694
- }, {
1688
+ }),
1689
+ n(e(K), null, {
1695
1690
  default: l(() => [
1696
1691
  n(e(he), {
1697
1692
  modelValue: H.value,
1698
1693
  "onUpdate:modelValue": k[4] || (k[4] = (d) => H.value = d),
1699
- size: "sm"
1700
- }, null, 8, ["modelValue"])
1694
+ size: "sm",
1695
+ label: e(u)("panel.filter-trashed")
1696
+ }, null, 8, ["modelValue", "label"])
1701
1697
  ]),
1702
1698
  _: 1
1703
- }, 8, ["label"]),
1699
+ }),
1704
1700
  D.value.length > 0 ? (v(), O(e(se), {
1705
1701
  key: 0,
1706
1702
  variant: "text",
@@ -1839,7 +1835,7 @@ const Oa = /* @__PURE__ */ ge({
1839
1835
  }, 8, ["title", "actions"])
1840
1836
  ]));
1841
1837
  }
1842
- }), vl = /* @__PURE__ */ ye(cl, [["__scopeId", "data-v-3465bf8b"]]);
1838
+ }), vl = /* @__PURE__ */ ye(cl, [["__scopeId", "data-v-eccbf1d9"]]);
1843
1839
  function bl(y = {}) {
1844
1840
  const i = y.path ?? "/catalog", g = { base: i };
1845
1841
  return [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/api.ts","../src/editor.ts","../src/messages.ts","../src/i18n.ts","../src/LandingEditorPage.vue","../src/LandingProductsField.vue","../src/LandingSetField.vue","../src/LandingSlugField.vue","../src/LandingSortField.vue","../src/GenerateDialog.vue","../src/LandingsPage.vue","../src/module.ts"],"sourcesContent":["import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n BaseFacet,\n GenerateParams,\n GeneratePreview,\n GenerateRun,\n LandingDetail,\n LandingFilters,\n LandingQuery,\n LandingsPage,\n SetCount,\n} from './types'\n\n/** Where the landings answer under the panel's API (§8.4 of the landings spec). */\nexport const LANDINGS_API = 'catalog/landings'\n\n/** The list's question as a query string; a filter left unset is not sent at all. */\nexport function landingSearch(query: LandingQuery): URLSearchParams {\n const search = new URLSearchParams()\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') continue\n\n search.set(key, typeof value === 'boolean' ? (value ? '1' : '0') : String(value))\n }\n\n return search\n}\n\nexport interface CatalogLandingsApi {\n list(query?: LandingQuery): Promise<LandingsPage>\n get(id: number): Promise<LandingDetail>\n create(values: Record<string, unknown>): Promise<LandingDetail>\n save(id: number, values: Record<string, unknown>): Promise<LandingDetail>\n remove(id: number): Promise<void>\n restore(id: number): Promise<LandingDetail>\n publish(id: number, on: boolean): Promise<LandingDetail>\n count(\n categoryId: number | null,\n filters: LandingFilters,\n except?: number | null,\n ): Promise<SetCount>\n facets(categoryId: number | null): Promise<BaseFacet[]>\n preview(params: GenerateParams): Promise<GeneratePreview>\n generate(params: GenerateParams): Promise<GenerateRun>\n run(id: number): Promise<GenerateRun>\n}\n\nexport function createLandingsApi(admin: AdminContext): CatalogLandingsApi {\n const base = `${admin.apiPath}/${LANDINGS_API}`\n const data = <T>(body: { data: T }): T => body.data\n\n return {\n list: (query = {}) => {\n const search = landingSearch(query)\n\n return admin.http.get<LandingsPage>(search.size > 0 ? `${base}?${search}` : base)\n },\n get: (id) => admin.http.get<{ data: LandingDetail }>(`${base}/${id}`).then(data),\n create: (values) => admin.http.post<{ data: LandingDetail }>(base, values).then(data),\n save: (id, values) =>\n admin.http.put<{ data: LandingDetail }>(`${base}/${id}`, values).then(data),\n remove: (id) => admin.http.delete<void>(`${base}/${id}`).then(() => undefined),\n restore: (id) =>\n admin.http.post<{ data: LandingDetail }>(`${base}/${id}/restore`, {}).then(data),\n publish: (id, on) =>\n admin.http\n .post<{ data: LandingDetail }>(`${base}/${id}/${on ? 'publish' : 'unpublish'}`, {})\n .then(data),\n count: (categoryId, filters, except = null) =>\n admin.http\n .post<{ data: SetCount }>(`${base}/count`, { category_id: categoryId, filters, except })\n .then(data),\n facets: (categoryId) =>\n admin.http\n .get<{\n data: BaseFacet[]\n }>(categoryId === null ? `${base}/facets` : `${base}/facets?category=${categoryId}`)\n .then(data),\n preview: (params) =>\n admin.http\n .post<{ data: GeneratePreview }>(`${base}/generate`, { ...params, dry_run: true })\n .then(data),\n generate: (params) =>\n admin.http.post<{ data: GenerateRun }>(`${base}/generate`, params).then(data),\n run: (id) => admin.http.get<{ data: GenerateRun }>(`${base}/generate/${id}`).then(data),\n }\n}\n\n/** The fields of the form a save sends; what the list shows beside them is not the form's. */\nexport const FORM_FIELDS = [\n 'category_id',\n 'filters',\n 'name',\n 'slug',\n 'h1',\n 'text_above',\n 'text_below',\n 'sort',\n 'on_category',\n 'position',\n 'recommended',\n 'seo',\n] as const\n\n/** A landing's values as the form holds them. */\nexport function formValues(detail: LandingDetail): Record<string, unknown> {\n const values: Record<string, unknown> = {}\n\n for (const field of FORM_FIELDS) values[field] = detail[field] ?? null\n\n // The table keeps an empty set as `[]` when PHP encodes an empty array.\n if (Array.isArray(values.filters)) values.filters = {}\n\n return values\n}\n\n/**\n * A set without the facets that say nothing — a list with no value, a range with no end — so\n * that a half-built facet neither counts nor fails a save.\n */\nexport function cleanSet(filters: LandingFilters | null | undefined): LandingFilters {\n const clean: LandingFilters = {}\n\n for (const [key, choice] of Object.entries(filters ?? {})) {\n if ('values' in choice) {\n if (choice.values.length > 0) clean[key] = { values: [...choice.values] }\n } else if (choice.min !== null || choice.max !== null) {\n clean[key] = { min: choice.min, max: choice.max }\n }\n }\n\n return clean\n}\n","import { inject, provide, type InjectionKey, type Ref } from 'vue'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport type { LandingDetail } from './types'\n\n/**\n * What the landing's form shares with the fields of its screen: the set builder reads the base\n * from the values, the address reads the set's suggestion, the recommended products read the\n * names the server sent with the ids.\n */\nexport interface LandingEditorContext {\n /** As the server last answered; `null` for a landing not created yet. */\n landing: Ref<LandingDetail | null>\n values: Ref<ScreenModel>\n locked: Ref<boolean>\n /** The slugs the set suggests, per language — written by the set builder after each count. */\n suggested: Ref<Record<string, string>>\n /** Where the landings' list is: `/catalog/landings`. */\n list: string\n}\n\nexport const landingEditorKey: InjectionKey<LandingEditorContext> = Symbol('wx-catalog-landing')\n\nexport function provideLandingEditor(context: LandingEditorContext): void {\n provide(landingEditorKey, context)\n}\n\n/** `null` outside the landing's page — a field put on another screen keeps working on its own. */\nexport function useLandingEditor(): LandingEditorContext | null {\n return inject(landingEditorKey, null)\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * The English this package speaks on its own, before the server's dictionary arrives, or without\n * one. The server ships the same lines under `webx-catalog-landings::` and overrides these — the\n * Russian is there; `messages.test.ts` keeps the two sets of keys equal.\n */\nexport const catalogLandingsMessages: Record<string, Messages> = {\n module: {\n title: 'Landings',\n landing: 'Landing',\n },\n landing: {\n category_id: 'Base',\n filters: 'Set',\n name: 'Name',\n slug: 'Address',\n h1: 'H1',\n text_above: 'Text above the list',\n text_below: 'Text under the list',\n sort: 'Default sort',\n on_category: 'In the category’s collections',\n position: 'Order',\n is_published: 'Published',\n attention: 'Needs attention',\n 'whole-catalog': 'The whole catalogue',\n 'tab-main': 'Main',\n 'tab-texts': 'Texts',\n 'tab-recommended': 'Recommended',\n 'tab-seo': 'SEO',\n 'tab-history': 'History',\n display: 'On the site',\n 'name-help': 'The label in the panel and in the links of the collections.',\n 'category-help': 'The list the landing narrows. Empty — the whole catalogue.',\n 'slug-help': 'From the site’s root, like a category’s: /laptops-apple/.',\n 'sort-help': 'The order a reader sees first; the one they choose wins.',\n 'sort-default': 'As the category',\n 'on-category-help': 'A link in «Collections» on the page of the base.',\n 'position-help': 'Smaller first, in the collections and among the neighbours.',\n 'h1-help': 'Empty — the name.',\n 'text-help': 'Shown on the landing’s first page with nothing more chosen.',\n recommended: 'Recommended products',\n 'recommended-help': 'A strip over the list, in this order; the list itself does not change.',\n 'recommended-search': 'Find a product by name or SKU',\n 'recommended-empty': 'No products picked.',\n 'recommended-remove': 'Remove',\n 'set-add': 'Add a facet',\n 'set-empty': 'Add a facet and choose its values.',\n 'set-remove': 'Remove the facet',\n 'set-values': 'Choose values',\n 'set-from': 'From',\n 'set-to': 'To',\n 'set-count': 'Products: :count',\n 'set-counting': 'Counting…',\n 'set-taken': 'This set on this base is already the landing «:name».',\n 'set-open-taken': 'Open it',\n 'slug-suggested': 'Suggested: :slug',\n 'slug-use': 'Use',\n 'attention-value_removed': 'A value of the set was deleted',\n 'attention-duplicate': 'The set became another landing’s',\n 'attention-empty_set': 'Nothing is left of the set',\n },\n panel: {\n new: 'New landing',\n generate: 'Create in bulk',\n empty: 'No landings yet.',\n 'empty-help':\n 'A landing is a category’s list with filters chosen in advance, under an address, texts and SEO of its own.',\n 'nothing-found': 'Nothing matches the filters.',\n search: 'Name or address',\n 'column-name': 'Name',\n 'column-base': 'Base',\n 'column-set': 'Set',\n 'column-count': 'Products',\n 'column-state': 'State',\n 'column-updated': 'Updated',\n 'filter-base': 'Base',\n 'filter-attention': 'Needs attention',\n 'filter-published': 'Published only',\n 'filter-empty': 'Empty only',\n 'filter-trashed': 'In the bin',\n published: 'Published',\n unpublished: 'Not published',\n 'not-counted': 'Not counted yet',\n open: 'Open',\n 'open-site': 'Open on the site',\n publish: 'Publish',\n unpublish: 'Unpublish',\n delete: 'Delete',\n restore: 'Restore',\n 'delete-title': 'Delete «:name»?',\n 'delete-text':\n 'It goes to the bin, and its address stops answering. Its set stays taken until it is gone for good.',\n deleted: 'The landing is in the bin.',\n restored: 'The landing is back.',\n 'published-toast': 'The landing is published.',\n 'unpublished-toast': 'The landing is unpublished.',\n saved: 'The landing is saved.',\n created: 'The landing is created.',\n save: 'Save',\n create: 'Create',\n 'save-failed': 'Not saved — see the fields.',\n cancel: 'Cancel',\n 'leave-title': 'Leave without saving?',\n 'leave-text': 'What you changed here will be lost.',\n leave: 'Leave',\n untitled: 'A new landing',\n 'in-bin': 'In the bin',\n trail: 'Where you are',\n },\n generate: {\n title: 'Create landings in bulk',\n bases: 'Bases',\n 'bases-help': 'One category or several; a landing per category and value.',\n subtree: 'With every category under them',\n facet: 'Facet',\n values: 'Values',\n 'values-help': 'Empty — every value with products on the base.',\n 'min-products': 'At least products',\n 'min-products-help': 'For «every value»: values with fewer products on the base are left out.',\n templates: 'Templates',\n 'templates-help':\n '{category} and {value} are replaced: the slugs in the address, the names in the texts.',\n slug: 'Address',\n name: 'Name',\n h1: 'H1',\n 'seo-title': 'SEO title',\n 'seo-description': 'SEO description',\n 'template-empty': 'Empty — not set',\n publish: 'Publish at once',\n preview: 'Preview',\n back: 'Back',\n run: 'Create :count',\n close: 'Close',\n 'column-address': 'Address',\n 'column-h1': 'H1',\n 'column-count': 'Products',\n 'column-conflict': 'Skipped because',\n summary: 'Will be created: :free; skipped: :skipped.',\n nothing: 'Nothing to create: every row is skipped.',\n running: 'Creating landings…',\n done: 'Created: :done; skipped: :skipped; refused: :failed.',\n failed: 'The generation stopped. What was created stays.',\n 'conflict-slug-taken': 'The address :slug is taken.',\n 'conflict-set-taken': 'The set is already the landing «:name».',\n 'conflict-empty': 'No products.',\n 'conflict-no-slug': 'A slug or a name to fill the template with is missing.',\n },\n}\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { catalogLandingsMessages } from './messages'\n\n/** The server's dictionary for this package: `webx-catalog-landings::`. */\nexport const NAMESPACE = 'webx-catalog-landings'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useCatalogLandingsMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults(NAMESPACE, catalogLandingsMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { onBeforeRouteLeave, useRoute, useRouter } from 'vue-router'\nimport {\n confirm,\n localizedValue,\n toast,\n useLocales,\n WxActionBar,\n WxAlert,\n WxBadge,\n WxBreadcrumb,\n WxBreadcrumbItem,\n WxButton,\n WxCard,\n WxSkeleton,\n type LocalizedValue,\n} from '@webx-ui/core'\nimport {\n provideHistorySubject,\n useAdmin,\n useBodyKeys,\n useErrorText,\n useTranslate,\n WxSaveState,\n WxScreen,\n WxScreenHead,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport { cleanSet, createLandingsApi, formValues } from './api'\nimport { provideLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { LandingDetail, LandingFilters } from './types'\n\n/**\n * One landing (§8.2 of the landings spec): a head, `catalog.landing-form` under it — base, set,\n * address, texts, order, recommended, SEO, history — and one button. A new landing is the same\n * page at `…/landings/new`: its first save creates it and the address moves to its id.\n */\ndefineOptions({ name: 'WxCatalogLandingEditor' })\n\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/catalog' })\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst route = useRoute()\nconst router = useRouter()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst list = computed(() => `${props.base}/landings`)\nconst creating = computed(() => route.params.id === undefined || route.params.id === 'new')\nconst id = computed(() => (creating.value ? null : Number(route.params.id)))\n\nconst landing = ref<LandingDetail | null>(null)\nconst values = ref<ScreenModel>({})\nconst snapshot = ref('')\nconst suggested = ref<Record<string, string>>({})\n\nconst loading = ref(true)\nconst saving = ref(false)\nconst errors = ref<Record<string, string[]>>({})\n\nconst canManage = computed(() => admin.can('catalog.manage'))\nconst trashed = computed(() => (landing.value?.deleted_at ?? null) !== null)\nconst locked = computed(() => !canManage.value || saving.value || trashed.value)\n\nconst current = computed(() => JSON.stringify(values.value))\nconst dirty = computed(() => snapshot.value !== '' && current.value !== snapshot.value)\n\nconst state = computed<'saving' | 'unsaved' | 'saved'>(() => {\n if (saving.value) return 'saving'\n\n return dirty.value || creating.value ? 'unsaved' : 'saved'\n})\n\nconst section = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'catalog-landings')?.title ??\n t('module.title'),\n)\n\n/** The name follows the field: a rename shows at the top as it is typed. */\nconst title = computed(() => {\n const written = values.value.name as LocalizedValue | string | null | undefined\n\n return localizedValue(written, locales.active.value, '') || t('panel.untitled')\n})\n\nconst subtitle = computed(() => {\n const row = landing.value\n\n if (!row) return undefined\n\n return [row.category ?? t('landing.whole-catalog'), row.url ?? ''].filter(Boolean).join(' · ')\n})\n\nprovideLandingEditor({ landing, values, locked, suggested, list: list.value })\nprovideHistorySubject({ id: computed(() => landing.value?.id ?? null) })\n\nfunction take(detail: LandingDetail): void {\n landing.value = detail\n values.value = formValues(detail)\n snapshot.value = JSON.stringify(values.value)\n}\n\nfunction blank(): void {\n landing.value = null\n values.value = {\n category_id: route.query.category ? Number(route.query.category) : null,\n filters: {},\n name: {},\n slug: {},\n h1: {},\n text_above: {},\n text_below: {},\n sort: null,\n on_category: false,\n position: 0,\n recommended: [],\n seo: {},\n }\n snapshot.value = JSON.stringify(values.value)\n}\n\nasync function load(): Promise<void> {\n errors.value = {}\n\n if (id.value === null) {\n blank()\n loading.value = false\n\n return\n }\n\n loading.value = true\n\n try {\n take(await api.get(id.value))\n } catch (error) {\n toast.danger(message(error))\n void router.push(list.value)\n } finally {\n loading.value = false\n }\n}\n\n/** What a save sends: the form's fields, the set without its half-built facets. */\nfunction payload(): Record<string, unknown> {\n return { ...values.value, filters: cleanSet(values.value.filters as LandingFilters) }\n}\n\nasync function save(): Promise<void> {\n if (saving.value || !canManage.value) return\n\n saving.value = true\n errors.value = {}\n\n try {\n if (id.value === null) {\n const created = await api.create(payload())\n\n take(created)\n toast.success(t('panel.created'))\n await router.replace(`${list.value}/${created.id}`)\n } else {\n take(await api.save(id.value, payload()))\n toast.success(t('panel.saved'))\n }\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors && Object.keys(body.errors).length > 0) {\n errors.value = body.errors\n toast.danger(t('panel.save-failed'))\n } else {\n toast.danger(message(error))\n }\n } finally {\n saving.value = false\n }\n}\n\nasync function publish(on: boolean): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n try {\n const answer = await api.publish(row.id, on)\n\n // Only the state: what is being typed in the form stays.\n landing.value = { ...row, ...answer }\n toast.success(t(on ? 'panel.published-toast' : 'panel.unpublished-toast'))\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n const agreed = await confirm({\n title: t('panel.delete-title', { name: title.value }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(row.id)\n toast.success(t('panel.deleted'))\n snapshot.value = current.value\n void router.push(list.value)\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n try {\n take(await api.restore(row.id))\n toast.success(t('panel.restored'))\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction leaveGuard(event: BeforeUnloadEvent): void {\n if (dirty.value) event.preventDefault()\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault()\n if (dirty.value || creating.value) void save()\n }\n}\n\nuseBodyKeys(onKeydown)\n\nwatch(id, (next, previous) => {\n // The first save of a new landing moves the address to its id — nothing to read again.\n if (previous === null && next !== null && landing.value?.id === next) return\n\n void load()\n})\n\nonMounted(() => {\n void load()\n window.addEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeRouteLeave(async () => {\n if (!dirty.value || !canManage.value) return true\n\n return await confirm({\n title: t('panel.leave-title'),\n message: t('panel.leave-text'),\n confirmText: t('panel.leave'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n})\n\nconst actions = computed<ScreenAction[]>(() => {\n const row = landing.value\n\n if (!row || !canManage.value) return []\n\n if (trashed.value) {\n return [\n { key: 'restore', label: t('panel.restore'), icon: 'refresh', run: () => void restore() },\n ]\n }\n\n const leads: ScreenAction[] = []\n\n if (row.url) {\n leads.push({\n key: 'site',\n label: t('panel.open-site'),\n icon: 'external-link',\n run: () => void window.open(row.url ?? '', '_blank', 'noopener'),\n })\n }\n\n leads.push(\n row.is_published\n ? {\n key: 'unpublish',\n label: t('panel.unpublish'),\n icon: 'eye-off',\n run: () => void publish(false),\n }\n : { key: 'publish', label: t('panel.publish'), icon: 'eye', run: () => void publish(true) },\n {\n key: 'delete',\n label: t('panel.delete'),\n icon: 'trash',\n danger: true,\n menu: true,\n run: () => void remove(),\n },\n )\n\n return leads\n})\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-editor\" @keydown=\"onKeydown\">\n <template v-if=\"loading\">\n <wx-skeleton class=\"wx-catalog-landing-editor__ghost\" title :rows=\"1\" />\n <wx-card><wx-skeleton :rows=\"6\" /></wx-card>\n </template>\n\n <template v-else>\n <wx-screen-head\n divider\n :back=\"list\"\n :back-label=\"section\"\n :title=\"title\"\n :subtitle=\"subtitle\"\n :actions=\"actions\"\n >\n <template #trail>\n <wx-breadcrumb size=\"sm\" :label=\"t('panel.trail')\">\n <wx-breadcrumb-item :as=\"'router-link'\" :to=\"list\">{{ section }}</wx-breadcrumb-item>\n <wx-breadcrumb-item current>{{ title }}</wx-breadcrumb-item>\n </wx-breadcrumb>\n </template>\n\n <template v-if=\"landing\" #title-after>\n <wx-badge v-if=\"trashed\" dot>{{ t('panel.in-bin') }}</wx-badge>\n <wx-badge v-else :type=\"landing.is_published ? 'success' : 'default'\" dot size=\"sm\">\n {{ t(landing.is_published ? 'panel.published' : 'panel.unpublished') }}\n </wx-badge>\n </template>\n </wx-screen-head>\n\n <wx-alert v-if=\"landing?.attention\" type=\"warning\">\n {{ t(`landing.attention-${landing.attention}`) }}\n </wx-alert>\n\n <wx-screen v-model=\"values\" name=\"catalog.landing-form\" :errors=\"errors\" :disabled=\"locked\" />\n\n <wx-action-bar v-if=\"canManage && !trashed\">\n <template #state>\n <wx-save-state :state=\"state\" />\n </template>\n\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!dirty && !creating\" @click=\"save\">\n {{ t(creating ? 'panel.create' : 'panel.save') }}\n </wx-button>\n </wx-action-bar>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-editor {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n container-type: inline-size;\n}\n\n.wx-catalog-landing-editor__ghost {\n max-width: 420px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport {\n WxAutocomplete,\n WxBadge,\n WxButton,\n WxIcon,\n WxSortableList,\n WxText,\n type AutocompleteOption,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { createCatalogApi } from '@webx-ui/module-catalog'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { RecommendedItem } from './types'\n\n/**\n * `wx-catalog-landing-products`: the recommended strip of a landing (decision 8) — products found\n * by name or SKU and put in order by dragging. The field's value is the ids in their order; the\n * names come with the landing from the server and with each product found, so the list never asks\n * for products one by one.\n */\ndefineOptions({ name: 'WxCatalogLandingProducts' })\n\nconst value = defineModel<number[] | null>({ default: null })\n\nconst admin = useAdmin()\nconst catalog = createCatalogApi(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst locked = computed(() => editor?.locked.value ?? false)\n\n/** Every product this field has seen a name for: the saved ones and the ones found since. */\nconst known = ref(new Map<number, RecommendedItem>())\n\nwatch(\n () => editor?.landing.value?.recommended_items,\n (items) => {\n for (const item of items ?? []) known.value.set(item.id, item)\n },\n { immediate: true },\n)\n\nconst items = computed<RecommendedItem[]>({\n get: () =>\n (value.value ?? []).map(\n (id) => known.value.get(id) ?? { id, name: `#${id}`, sku: null, deleted: false },\n ),\n set: (next) => {\n value.value = next.map((item) => item.id)\n },\n})\n\nconst term = ref('')\nconst options = ref<AutocompleteOption[]>([])\nconst searching = ref(false)\nconst failed = ref('')\nlet asked = 0\n\nasync function search(q: string): Promise<void> {\n const ticket = ++asked\n\n searching.value = true\n failed.value = ''\n\n try {\n const page = await catalog.products({ q, per_page: 10 })\n\n if (ticket !== asked) return\n\n const taken = new Set(value.value ?? [])\n\n options.value = page.data\n .filter((product) => !taken.has(product.id))\n .map((product) => {\n known.value.set(product.id, { id: product.id, name: product.name, sku: product.sku })\n\n return {\n value: String(product.id),\n label: product.name,\n description: product.sku ?? undefined,\n }\n })\n } catch (error) {\n if (ticket === asked) failed.value = message(error)\n } finally {\n if (ticket === asked) searching.value = false\n }\n}\n\nfunction pick(option: AutocompleteOption): void {\n const id = Number(option.value)\n\n if (!Number.isFinite(id) || (value.value ?? []).includes(id)) return\n\n value.value = [...(value.value ?? []), id]\n term.value = ''\n options.value = []\n}\n\nfunction drop(id: number): void {\n value.value = (value.value ?? []).filter((one) => one !== id)\n}\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-products\">\n <wx-autocomplete\n v-if=\"!locked\"\n v-model=\"term\"\n :options=\"options\"\n remote\n :loading=\"searching\"\n :min-length=\"1\"\n clearable\n :placeholder=\"t('landing.recommended-search')\"\n :aria-label=\"t('landing.recommended-search')\"\n @search=\"search\"\n @select=\"pick\"\n />\n <wx-text v-if=\"failed\" size=\"sm\" tone=\"danger\">{{ failed }}</wx-text>\n\n <wx-sortable-list\n v-model=\"items\"\n item-key=\"id\"\n item-label=\"name\"\n size=\"sm\"\n :disabled=\"locked\"\n :empty-text=\"t('landing.recommended-empty')\"\n :aria-label=\"t('landing.recommended')\"\n >\n <template #default=\"{ item }\">\n <span class=\"wx-catalog-landing-products__item\">\n <span class=\"wx-catalog-landing-products__name\">{{ item.name }}</span>\n <wx-text v-if=\"item.sku\" size=\"sm\" tone=\"muted\">{{ item.sku }}</wx-text>\n <wx-badge v-if=\"item.deleted\" size=\"sm\" type=\"warning\" round>\n {{ t('panel.in-bin') }}\n </wx-badge>\n </span>\n </template>\n <template #actions=\"{ item }\">\n <wx-button\n v-if=\"!locked\"\n variant=\"text\"\n size=\"sm\"\n :aria-label=\"`${t('landing.recommended-remove')}: ${item.name}`\"\n @click=\"drop(item.id)\"\n >\n <template #icon><wx-icon name=\"close\" /></template>\n </wx-button>\n </template>\n </wx-sortable-list>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-products {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-catalog-landing-products__item {\n display: flex;\n align-items: baseline;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-catalog-landing-products__name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { RouterLink } from 'vue-router'\nimport {\n WxAlert,\n WxBadge,\n WxButton,\n WxIcon,\n WxInputNumber,\n WxLink,\n WxSelect,\n WxText,\n type SelectOption,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { cleanSet, createLandingsApi } from './api'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { BaseFacet, LandingFilters, SetChoice, SetCount } from './types'\n\n/**\n * `wx-catalog-landing-set`: the set of a landing (§8.2 of the landings spec) — «add a facet» out of\n * the facets the base offers, its values in the same controls the products' filter uses (a list\n * of values with search, a range from–to), and beside them the live number of products and a\n * warning when another landing of the base already holds the set.\n *\n * The facets are asked again when the base changes; a facet of the set the new base does not offer\n * stays, labelled by its key, so that changing the base never drops a choice silently — the save\n * says whether the set still makes sense.\n */\ndefineOptions({ name: 'WxCatalogLandingSet' })\n\nconst value = defineModel<LandingFilters | null>({ default: null })\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst locked = computed(() => editor?.locked.value ?? false)\n\nconst category = computed<number | null>(() => {\n const id = editor?.values.value.category_id\n\n return typeof id === 'number' ? id : id ? Number(id) : null\n})\n\nconst offered = ref<BaseFacet[]>([])\nconst loadFailed = ref('')\nconst set = computed<LandingFilters>(() =>\n value.value && !Array.isArray(value.value) ? value.value : {},\n)\n\nconst facetOf = (key: string) => offered.value.find((facet) => facet.key === key)\n\nconst adding = computed<SelectOption[]>(() =>\n offered.value\n .filter((facet) => !(facet.key in set.value))\n .map((facet) => ({ value: facet.key, label: facet.label })),\n)\n\nlet asked = 0\n\nasync function loadFacets(): Promise<void> {\n const ticket = ++asked\n\n loadFailed.value = ''\n\n try {\n const answer = await api.facets(category.value)\n\n if (ticket === asked) offered.value = answer\n } catch (error) {\n if (ticket === asked) loadFailed.value = message(error)\n }\n}\n\nwatch(category, () => void loadFacets(), { immediate: true })\n\nfunction isRange(key: string, choice: SetChoice): boolean {\n const facet = facetOf(key)\n\n return facet ? facet.kind === 'range' : !('values' in choice)\n}\n\nfunction write(next: LandingFilters): void {\n value.value = next\n}\n\nfunction add(key: unknown): void {\n const facet = facetOf(String(key))\n\n if (!facet) return\n\n write({\n ...set.value,\n [facet.key]: facet.kind === 'range' ? { min: null, max: null } : { values: [] },\n })\n}\n\nfunction remove(key: string): void {\n const next = { ...set.value }\n\n delete next[key]\n write(next)\n}\n\nfunction valuesOf(choice: SetChoice): string[] {\n return 'values' in choice ? choice.values : []\n}\n\nfunction rangeOf(choice: SetChoice): { min: number | null; max: number | null } {\n return 'values' in choice ? { min: null, max: null } : choice\n}\n\nfunction optionsOf(key: string, choice: SetChoice): SelectOption[] {\n const known = facetOf(key)?.values ?? []\n const options: SelectOption[] = known.map((one) => ({\n value: one.value,\n label: `${one.label} (${one.count})`,\n }))\n\n // A chosen value the base has no products of is still a choice: shown, not dropped.\n for (const chosen of valuesOf(choice)) {\n if (!known.some((one) => one.value === chosen)) {\n const word = chipWord(key, chosen)\n options.push({ value: chosen, label: `${word} (0)` })\n }\n }\n\n return options\n}\n\n/** The saved landing's chip says what a value is called when the base no longer counts it. */\nfunction chipWord(key: string, chosen: string): string {\n return editor?.landing.value?.chips.find((chip) => chip.key === key)?.text ?? `#${chosen}`\n}\n\nfunction pick(key: string, picked: unknown): void {\n write({ ...set.value, [key]: { values: Array.isArray(picked) ? picked.map(String) : [] } })\n}\n\nfunction bound(key: string, end: 'min' | 'max', picked: number | null | undefined): void {\n const choice = set.value[key]\n const range = choice ? rangeOf(choice) : { min: null, max: null }\n\n write({ ...set.value, [key]: { ...range, [end]: picked ?? null } })\n}\n\nfunction labelOf(key: string): string {\n return facetOf(key)?.label ?? key\n}\n\n/* -------------------------------------------------------------------- the count --- */\n\nconst counted = ref<SetCount | null>(null)\nconst counting = ref(false)\nconst countFailed = ref('')\nlet timer: ReturnType<typeof setTimeout> | undefined\nlet countTicket = 0\n\nconst question = computed(() => JSON.stringify([category.value, cleanSet(set.value)]))\n\nasync function count(): Promise<void> {\n const ticket = ++countTicket\n const clean = cleanSet(set.value)\n\n if (Object.keys(clean).length === 0) {\n counted.value = null\n counting.value = false\n if (editor) editor.suggested.value = {}\n\n return\n }\n\n counting.value = true\n countFailed.value = ''\n\n try {\n const answer = await api.count(category.value, clean, editor?.landing.value?.id ?? null)\n\n if (ticket !== countTicket) return\n\n counted.value = answer\n if (editor) editor.suggested.value = Array.isArray(answer.suggested) ? {} : answer.suggested\n } catch (error) {\n if (ticket === countTicket) {\n counted.value = null\n countFailed.value = message(error)\n }\n } finally {\n if (ticket === countTicket) counting.value = false\n }\n}\n\nwatch(\n question,\n () => {\n clearTimeout(timer)\n timer = setTimeout(() => void count(), 350)\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst takenLink = computed(() =>\n counted.value?.taken && editor ? `${editor.list}/${counted.value.taken.id}` : null,\n)\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-set\">\n <wx-alert v-if=\"loadFailed\" type=\"danger\">{{ loadFailed }}</wx-alert>\n\n <wx-text v-if=\"Object.keys(set).length === 0\" tone=\"muted\" size=\"sm\">\n {{ t('landing.set-empty') }}\n </wx-text>\n\n <div\n v-for=\"(choice, key) in set\"\n :key=\"key\"\n class=\"wx-catalog-landing-set__row\"\n :data-facet=\"key\"\n >\n <wx-text class=\"wx-catalog-landing-set__label\" size=\"sm\" weight=\"medium\">\n {{ labelOf(String(key)) }}\n </wx-text>\n\n <div v-if=\"isRange(String(key), choice)\" class=\"wx-catalog-landing-set__range\">\n <wx-input-number\n :model-value=\"rangeOf(choice).min\"\n :controls=\"false\"\n :disabled=\"locked\"\n size=\"sm\"\n :placeholder=\"facetOf(String(key))?.min?.toString() ?? t('landing.set-from')\"\n :aria-label=\"`${labelOf(String(key))}: ${t('landing.set-from')}`\"\n @update:model-value=\"\n (picked: number | null | undefined) => bound(String(key), 'min', picked)\n \"\n />\n <wx-input-number\n :model-value=\"rangeOf(choice).max\"\n :controls=\"false\"\n :disabled=\"locked\"\n size=\"sm\"\n :placeholder=\"facetOf(String(key))?.max?.toString() ?? t('landing.set-to')\"\n :aria-label=\"`${labelOf(String(key))}: ${t('landing.set-to')}`\"\n @update:model-value=\"\n (picked: number | null | undefined) => bound(String(key), 'max', picked)\n \"\n />\n </div>\n\n <wx-select\n v-else\n class=\"wx-catalog-landing-set__values\"\n :model-value=\"valuesOf(choice)\"\n :options=\"optionsOf(String(key), choice)\"\n multiple\n filterable\n clearable\n size=\"sm\"\n :disabled=\"locked\"\n :placeholder=\"t('landing.set-values')\"\n :aria-label=\"labelOf(String(key))\"\n @update:model-value=\"(picked: unknown) => pick(String(key), picked)\"\n />\n\n <wx-button\n variant=\"text\"\n size=\"sm\"\n :disabled=\"locked\"\n :aria-label=\"t('landing.set-remove')\"\n :title=\"t('landing.set-remove')\"\n @click=\"remove(String(key))\"\n >\n <template #icon><wx-icon name=\"close\" /></template>\n </wx-button>\n </div>\n\n <div class=\"wx-catalog-landing-set__foot\">\n <wx-select\n v-if=\"adding.length > 0\"\n class=\"wx-catalog-landing-set__add\"\n :model-value=\"null\"\n :options=\"adding\"\n filterable\n size=\"sm\"\n :disabled=\"locked\"\n :placeholder=\"t('landing.set-add')\"\n :aria-label=\"t('landing.set-add')\"\n @update:model-value=\"add\"\n />\n\n <wx-text v-if=\"counting\" size=\"sm\" tone=\"muted\">{{ t('landing.set-counting') }}</wx-text>\n <wx-badge\n v-else-if=\"counted\"\n class=\"wx-catalog-landing-set__count\"\n :type=\"counted.count > 0 ? 'success' : 'warning'\"\n size=\"sm\"\n round\n >\n {{ t('landing.set-count', { count: counted.count }) }}\n </wx-badge>\n </div>\n\n <wx-alert v-if=\"countFailed\" type=\"danger\">{{ countFailed }}</wx-alert>\n\n <wx-alert v-if=\"counted?.taken\" type=\"warning\">\n {{ t('landing.set-taken', { name: counted.taken.name }) }}\n <wx-link v-if=\"takenLink\" :as=\"RouterLink\" :to=\"takenLink\">\n {{ t('landing.set-open-taken') }}\n </wx-link>\n </wx-alert>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-set {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n container-type: inline-size;\n min-width: 0;\n}\n\n.wx-catalog-landing-set__row {\n display: grid;\n grid-template-columns: minmax(96px, 160px) minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-catalog-landing-set__range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--wx-space-8);\n}\n\n.wx-catalog-landing-set__foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-12);\n}\n\n.wx-catalog-landing-set__add {\n width: 240px;\n max-width: 100%;\n}\n\n@container (max-width: 480px) {\n .wx-catalog-landing-set__row {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .wx-catalog-landing-set__label {\n grid-column: 1 / -1;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useLocales, WxButton, WxInput, WxText, type LocalizedValue } from '@webx-ui/core'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\n\n/**\n * `wx-catalog-landing-slug`: the address of a landing, per language, with the suggestion its set\n * makes under it — `{category}-{value}` of the slugs, as «Create in bulk» fills it (§8.2). The\n * set builder asks the server and puts the suggestion into the editor; «Use» writes it into the\n * language being edited and into the languages still empty.\n */\ndefineOptions({ name: 'WxCatalogLandingSlug' })\n\nconst props = withDefaults(defineProps<{ localized?: boolean }>(), { localized: false })\nconst value = defineModel<LocalizedValue | string | null>({ default: null })\n\nconst editor = useLandingEditor()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\n\nconst locked = computed(() => editor?.locked.value ?? false)\nconst record = computed<LocalizedValue>(() =>\n value.value && typeof value.value === 'object' ? value.value : {},\n)\n\nconst suggestion = computed(() => {\n const suggested = editor?.suggested.value ?? {}\n const locale = locales.active.value || Object.keys(suggested)[0] || ''\n const slug = suggested[locale]\n\n if (!slug) return null\n\n const current = props.localized ? record.value[locale] : value.value\n\n return current === slug ? null : slug\n})\n\nfunction use(): void {\n const suggested = editor?.suggested.value ?? {}\n\n if (!props.localized) {\n value.value = suggestion.value\n\n return\n }\n\n const next: LocalizedValue = { ...record.value }\n const active = locales.active.value\n\n for (const [locale, slug] of Object.entries(suggested)) {\n if (locale === active || !next[locale]) next[locale] = slug\n }\n\n value.value = next\n}\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-slug\">\n <wx-input\n :model-value=\"value ?? undefined\"\n :localized=\"props.localized\"\n :disabled=\"locked\"\n :maxlength=\"255\"\n @update:model-value=\"(next: unknown) => (value = next as LocalizedValue | string)\"\n />\n <div v-if=\"suggestion && !locked\" class=\"wx-catalog-landing-slug__hint\">\n <wx-text size=\"sm\" tone=\"muted\">{{\n t('landing.slug-suggested', { slug: suggestion })\n }}</wx-text>\n <wx-button size=\"sm\" variant=\"text\" @click=\"use\">{{ t('landing.slug-use') }}</wx-button>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-slug {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n min-width: 0;\n}\n\n.wx-catalog-landing-slug__hint {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted } from 'vue'\nimport { WxSelect, type SelectOption } from '@webx-ui/core'\nimport { useAdmin, useTranslate } from '@webx-ui/module-admin'\nimport { useFacetRegistry } from '@webx-ui/module-catalog'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\n\n/**\n * `wx-catalog-landing-sort`: the landing's default order (decision 7) — one of the catalogue's\n * sorts, or none, which leaves the category's. The sorts come from the same registry the products'\n * list reads, so the panel never offers one the storefront does not know.\n */\ndefineOptions({ name: 'WxCatalogLandingSort' })\n\nconst value = defineModel<string | null>({ default: null })\n\nconst NONE = 'default'\n\nconst admin = useAdmin()\nconst registry = useFacetRegistry(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\n\nconst options = computed<SelectOption[]>(() => [\n // The registry's own 'default' stands for «none of the landing's own»: the category's order.\n { value: NONE, label: t('landing.sort-default') },\n ...registry.sorts.value\n .filter((sort) => sort.key !== NONE)\n .map((sort) => ({ value: sort.key, label: sort.label })),\n])\n\nonMounted(() => void registry.load().catch(() => undefined))\n</script>\n\n<template>\n <wx-select\n :model-value=\"value ?? NONE\"\n :options=\"options\"\n :disabled=\"editor?.locked.value ?? false\"\n @update:model-value=\"\n (picked: unknown) => (value = picked && picked !== NONE ? String(picked) : null)\n \"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport {\n useLocales,\n useModal,\n WxAlert,\n WxButton,\n WxDialog,\n WxFormItem,\n WxInput,\n WxInputNumber,\n WxProgress,\n WxSelect,\n WxSpace,\n WxSwitch,\n WxTable,\n WxText,\n WxTreeSelect,\n type SelectOption,\n type TableColumn,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { useCategoryTree } from '@webx-ui/module-catalog'\nimport { createLandingsApi } from './api'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { BaseFacet, GenerateParams, GeneratePreview, GenerateRow, GenerateRun } from './types'\n\n/**\n * «Create in bulk» (§8.3 of the landings spec), three steps in one dialog: the bases, the facet and\n * its values, the templates — then the preview, a row per landing with the reason it is skipped —\n * then the run, done at once or polled while the queue makes it. Resolves with the run, or `null`\n * when nothing was made.\n */\nconst { open, resolve } = useModal<GenerateRun | null>()\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst tree = useCategoryTree(admin)\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\ntype Step = 'form' | 'preview' | 'run'\n\nconst step = ref<Step>('form')\nconst categories = ref<number[]>([])\nconst subtree = ref(false)\nconst facet = ref<string | null>(null)\nconst values = ref<string[]>([])\nconst minProducts = ref<number | null>(1)\nconst templates = ref({ slug: '', name: '', h1: '', title: '', description: '' })\nconst publish = ref(false)\n\nconst facets = ref<BaseFacet[]>([])\nconst errors = ref<Record<string, string[]>>({})\nconst failure = ref('')\nconst busy = ref(false)\nconst preview = ref<GeneratePreview | null>(null)\nconst run = ref<GenerateRun | null>(null)\n\nonMounted(() => void tree.load().catch(() => undefined))\n\n/* The facets of values the first base offers: a range has no value to make a landing of. */\nwatch(\n () => categories.value[0] ?? null,\n async (first) => {\n if (first === null) {\n facets.value = []\n\n return\n }\n\n try {\n facets.value = (await api.facets(first)).filter((one) => one.kind !== 'range')\n } catch (error) {\n failure.value = message(error)\n }\n },\n)\n\nconst facetOptions = computed<SelectOption[]>(() =>\n facets.value.map((one) => ({ value: one.key, label: one.label })),\n)\n\nconst valueOptions = computed<SelectOption[]>(() =>\n (facets.value.find((one) => one.key === facet.value)?.values ?? []).map((one) => ({\n value: one.value,\n label: `${one.label} (${one.count})`,\n })),\n)\n\nwatch(facet, () => (values.value = []))\n\nconst params = computed<GenerateParams>(() => ({\n categories: categories.value,\n subtree: subtree.value,\n facet: facet.value ?? '',\n values: values.value.length > 0 ? values.value : null,\n min_products: minProducts.value,\n ...templates.value,\n publish: publish.value,\n}))\n\nconst ready = computed(() => categories.value.length > 0 && facet.value !== null)\n\nfunction first(field: string): string | undefined {\n return errors.value[field]?.[0]\n}\n\nfunction refuse(error: unknown): void {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) errors.value = body.errors\n else failure.value = message(error)\n}\n\nasync function toPreview(): Promise<void> {\n if (!ready.value || busy.value) return\n\n busy.value = true\n errors.value = {}\n failure.value = ''\n\n try {\n preview.value = await api.preview(params.value)\n step.value = 'preview'\n } catch (error) {\n refuse(error)\n } finally {\n busy.value = false\n }\n}\n\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nasync function poll(id: number, delay = 1500): Promise<void> {\n timer = setTimeout(async () => {\n try {\n run.value = await api.run(id)\n\n if (run.value.status === 'queued' || run.value.status === 'running') void poll(id)\n } catch {\n void poll(id, Math.min(delay * 2, 15000))\n }\n }, delay)\n}\n\nasync function start(): Promise<void> {\n if (busy.value) return\n\n busy.value = true\n failure.value = ''\n\n try {\n run.value = await api.generate(params.value)\n step.value = 'run'\n\n if (run.value.id !== null && !finished.value) void poll(run.value.id)\n } catch (error) {\n refuse(error)\n step.value = 'form'\n } finally {\n busy.value = false\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst finished = computed(() => run.value?.status === 'done' || run.value?.status === 'failed')\n\nfunction close(): void {\n resolve(run.value && run.value.done > 0 ? run.value : null)\n}\n\n/* --------------------------------------------------------------- the preview --- */\n\nconst word = (record: Record<string, string>) =>\n record[locales.active.value] ?? Object.values(record)[0] ?? ''\n\nconst columns = computed<TableColumn<GenerateRow>[]>(() => [\n { key: 'address', label: t('generate.column-address'), minWidth: 180 },\n { key: 'title', label: t('generate.column-h1'), minWidth: 180, hideBelow: 560 },\n { key: 'count', label: t('generate.column-count'), width: 100, align: 'right' },\n { key: 'conflict', label: t('generate.column-conflict'), minWidth: 180 },\n])\n\nconst rows = computed(() =>\n (preview.value?.rows ?? []).map((row, index) => ({ ...row, id: index })),\n)\n</script>\n\n<template>\n <wx-dialog\n v-model:open=\"open\"\n :title=\"t('generate.title')\"\n :width=\"step === 'form' ? 600 : 860\"\n @update:open=\"(on: boolean) => !on && close()\"\n >\n <wx-alert v-if=\"failure\" type=\"danger\">{{ failure }}</wx-alert>\n\n <div v-if=\"step === 'form'\" class=\"wx-catalog-landings-generate\">\n <wx-form-item\n :label=\"t('generate.bases')\"\n :help=\"t('generate.bases-help')\"\n :error=\"first('categories')\"\n required\n >\n <wx-tree-select\n :model-value=\"categories\"\n :nodes=\"tree.nodes.value ?? []\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n multiple\n check-strictly\n filterable\n clearable\n @update:model-value=\"\n (picked: TreeSelectValue) =>\n (categories = Array.isArray(picked)\n ? picked.map(Number)\n : picked\n ? [Number(picked)]\n : [])\n \"\n />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"subtree\">{{ t('generate.subtree') }}</wx-switch>\n </wx-form-item>\n\n <wx-form-item :label=\"t('generate.facet')\" :error=\"first('facet')\" required>\n <wx-select v-model=\"facet\" :options=\"facetOptions\" :disabled=\"categories.length === 0\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.values')\" :help=\"t('generate.values-help')\">\n <wx-select\n v-model=\"values\"\n :options=\"valueOptions\"\n multiple\n filterable\n clearable\n :disabled=\"facet === null\"\n />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.min-products')\" :help=\"t('generate.min-products-help')\">\n <wx-input-number v-model=\"minProducts\" :min=\"0\" :disabled=\"values.length > 0\" />\n </wx-form-item>\n\n <wx-text weight=\"medium\">{{ t('generate.templates') }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('generate.templates-help') }}</wx-text>\n <wx-form-item :label=\"t('generate.slug')\" :error=\"first('slug')\">\n <wx-input v-model=\"templates.slug\" placeholder=\"{category}-{value}\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.name')\">\n <wx-input v-model=\"templates.name\" placeholder=\"{category} {value}\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.h1')\">\n <wx-input v-model=\"templates.h1\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.seo-title')\">\n <wx-input v-model=\"templates.title\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.seo-description')\">\n <wx-input v-model=\"templates.description\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"publish\">{{ t('generate.publish') }}</wx-switch>\n </wx-form-item>\n </div>\n\n <div v-else-if=\"step === 'preview' && preview\" class=\"wx-catalog-landings-generate\">\n <wx-text>\n {{\n preview.free > 0\n ? t('generate.summary', { free: preview.free, skipped: preview.total - preview.free })\n : t('generate.nothing')\n }}\n </wx-text>\n <wx-table :data=\"rows\" :columns=\"columns\" row-key=\"id\" flush layout=\"fixed\">\n <template #cell-address=\"{ row }\">\n <span class=\"wx-catalog-landings-generate__mono\">/{{ word(row.slug) }}/</span>\n </template>\n <template #cell-title=\"{ row }\">\n {{ word(Object.keys(row.h1).length > 0 ? row.h1 : row.name) }}\n </template>\n <template #cell-conflict=\"{ row }\">\n <wx-text v-if=\"row.conflict\" size=\"sm\" tone=\"warning\">{{ row.message }}</wx-text>\n </template>\n </wx-table>\n </div>\n\n <div v-else-if=\"step === 'run' && run\" class=\"wx-catalog-landings-generate\">\n <template v-if=\"!finished\">\n <wx-text>{{ t('generate.running') }}</wx-text>\n <wx-progress :value=\"run.done + run.failed\" :max=\"Math.max(1, run.total - run.skipped)\" />\n </template>\n <wx-alert v-else :type=\"run.status === 'failed' ? 'danger' : 'success'\">\n {{\n run.status === 'failed'\n ? t('generate.failed')\n : t('generate.done', { done: run.done, skipped: run.skipped, failed: run.failed })\n }}\n </wx-alert>\n <ul v-if=\"run.errors.length > 0\" class=\"wx-catalog-landings-generate__errors\">\n <li v-for=\"(one, index) in run.errors\" :key=\"index\">\n <strong>/{{ one.slug }}/</strong> — {{ one.message }}\n </li>\n </ul>\n </div>\n\n <template #footer>\n <wx-space size=\"sm\">\n <template v-if=\"step === 'form'\">\n <wx-button variant=\"outline\" @click=\"close\">{{ t('panel.cancel') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"busy\" :disabled=\"!ready\" @click=\"toPreview\">\n {{ t('generate.preview') }}\n </wx-button>\n </template>\n <template v-else-if=\"step === 'preview'\">\n <wx-button variant=\"outline\" @click=\"step = 'form'\">{{ t('generate.back') }}</wx-button>\n <wx-button\n type=\"primary\"\n :loading=\"busy\"\n :disabled=\"(preview?.free ?? 0) === 0\"\n @click=\"start\"\n >\n {{ t('generate.run', { count: preview?.free ?? 0 }) }}\n </wx-button>\n </template>\n <wx-button v-else type=\"primary\" :disabled=\"!finished\" @click=\"close\">\n {{ t('generate.close') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-catalog-landings-generate {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-catalog-landings-generate__mono {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-catalog-landings-generate__errors {\n margin: 0;\n padding-inline-start: var(--wx-space-16);\n font-size: var(--wx-font-size-sm);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useRoute, useRouter, type LocationQueryRaw } from 'vue-router'\nimport {\n confirm,\n createModal,\n toast,\n useLocales,\n localizedValue,\n WxBadge,\n WxButton,\n WxFormItem,\n WxIcon,\n WxSwitch,\n WxTable,\n WxText,\n WxTooltip,\n WxTreeSelect,\n type TableColumn,\n type TableState,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport {\n rowMenuWidth,\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxFilterChips,\n WxListScreen,\n WxRowMenu,\n type AppliedFilter,\n type RowAction,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport { useCategoryTree, type CategoryNode } from '@webx-ui/module-catalog'\nimport { createLandingsApi } from './api'\nimport GenerateDialog from './GenerateDialog.vue'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { GenerateRun, LandingQuery, LandingRow, LandingsPage } from './types'\n\n/**\n * The landings (§8.1 of the landings spec): name and address, the base, the set as chips, the\n * products, the state and the mark of attention; filtered by the base as a tree (the whole\n * catalogue is a choice of its own), «needs attention», published, empty, the bin; searched by\n * name and address. The filters live in the address, so coming back from a landing lands where\n * the list was left.\n */\ndefineOptions({ name: 'WxCatalogLandingsPage' })\n\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/catalog' })\n\n/** The base filter's value for «the whole catalogue», beside the categories' ids. */\nconst ROOT = 'root'\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst tree = useCategoryTree(admin)\nconst route = useRoute()\nconst router = useRouter()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst generate = createModal<GenerateRun | null, { base: string }>(GenerateDialog)\n\nconst list = computed(() => `${props.base}/landings`)\nconst canManage = computed(() => admin.can('catalog.manage'))\n\nconst page = ref<LandingsPage | null>(null)\nconst loading = ref(true)\n\nconst flag = (key: string) => route.query[key] === '1'\n\nconst search = ref(String(route.query.q ?? ''))\nconst pageNumber = ref(Number(route.query.page ?? 1) || 1)\nconst chosenBase = ref<string | null>(route.query.category ? String(route.query.category) : null)\nconst attention = ref(flag('attention'))\nconst published = ref(flag('published'))\nconst empty = ref(flag('empty'))\nconst trashed = ref(flag('trashed'))\nlet perPage = 25\n\nconst title = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'catalog-landings')?.title ??\n t('module.title'),\n)\n\n/** The tree of categories with «the whole catalogue» on top of it. */\nconst baseNodes = computed<CategoryNode[]>(() => [\n {\n id: ROOT as unknown as number,\n name: t('landing.whole-catalog'),\n parent_id: null,\n children: [],\n } as unknown as CategoryNode,\n ...(tree.nodes.value ?? []),\n])\n\nconst baseName = computed(() => {\n if (chosenBase.value === null) return ''\n if (chosenBase.value === ROOT) return t('landing.whole-catalog')\n\n const find = (nodes: CategoryNode[]): string =>\n nodes.reduce<string>(\n (found, node) =>\n found || (String(node.id) === chosenBase.value ? node.name : find(node.children ?? [])),\n '',\n )\n\n return find(tree.nodes.value ?? []) || `#${chosenBase.value}`\n})\n\nconst applied = computed<AppliedFilter[]>(() => {\n const chips: AppliedFilter[] = []\n\n if (chosenBase.value !== null) {\n chips.push({\n key: 'base',\n label: `${t('panel.filter-base')}: ${baseName.value}`,\n clear: () => (chosenBase.value = null),\n })\n }\n\n for (const [key, on, word] of [\n ['attention', attention, 'panel.filter-attention'],\n ['published', published, 'panel.filter-published'],\n ['empty', empty, 'panel.filter-empty'],\n ['trashed', trashed, 'panel.filter-trashed'],\n ] as const) {\n if (on.value) chips.push({ key, label: t(word), clear: () => (on.value = false) })\n }\n\n return chips\n})\n\nfunction clearFilters(): void {\n chosenBase.value = null\n attention.value = false\n published.value = false\n empty.value = false\n trashed.value = false\n}\n\nfunction query(state?: TableState): LandingQuery {\n return {\n q: state?.search ?? search.value,\n category: chosenBase.value ?? undefined,\n attention: attention.value || undefined,\n published: published.value || undefined,\n empty: empty.value || undefined,\n trashed: trashed.value || undefined,\n page: state?.page ?? pageNumber.value,\n per_page: state?.perPage ?? perPage,\n }\n}\n\nlet asked = 0\n\nasync function load(state?: TableState): Promise<void> {\n const mine = ++asked\n\n loading.value = true\n\n try {\n const answer = await api.list(query(state))\n\n if (mine === asked) page.value = answer\n } catch (error) {\n toast.danger(message(error))\n } finally {\n if (mine === asked) loading.value = false\n }\n}\n\nfunction remember(): void {\n const wanted: LocationQueryRaw = {}\n const q = query()\n\n if (q.q) wanted.q = q.q\n if (q.category) wanted.category = q.category\n if (q.page && q.page > 1) wanted.page = String(q.page)\n\n for (const key of ['attention', 'published', 'empty', 'trashed'] as const) {\n if (q[key]) wanted[key] = '1'\n }\n\n void router.replace({ query: wanted })\n}\n\nfunction onState(state: TableState): void {\n perPage = state.perPage\n void load(state)\n}\n\nwatch([chosenBase, attention, published, empty, trashed], () => {\n pageNumber.value = 1\n remember()\n void load()\n})\n\nwatch([search, pageNumber], remember)\n\nconst columns = computed<TableColumn<LandingRow>[]>(() => [\n { key: 'name', label: t('panel.column-name'), minWidth: 220 },\n { key: 'category', label: t('panel.column-base'), width: 180, hideBelow: 760 },\n { key: 'chips', label: t('panel.column-set'), minWidth: 180, hideBelow: 640 },\n { key: 'products_count', label: t('panel.column-count'), width: 110, align: 'right' },\n { key: 'state', label: t('panel.column-state'), width: 170, hideBelow: 900 },\n { key: 'updated_at', label: t('panel.column-updated'), width: 130, hideBelow: 1180 },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst nameOf = (row: LandingRow) =>\n localizedValue(row.name, locales.active.value, '') || `#${row.id}`\nconst slugOf = (row: LandingRow) => localizedValue(row.slug, locales.active.value, '')\n\nfunction open(row: LandingRow): void {\n void router.push(`${list.value}/${row.id}`)\n}\n\nasync function publish(row: LandingRow, on: boolean): Promise<void> {\n try {\n await api.publish(row.id, on)\n toast.success(t(on ? 'panel.published-toast' : 'panel.unpublished-toast'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(row: LandingRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-title', { name: nameOf(row) }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(row.id)\n toast.success(t('panel.deleted'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(row: LandingRow): Promise<void> {\n try {\n await api.restore(row.id)\n toast.success(t('panel.restored'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction actionsFor(row: LandingRow): RowAction[] {\n if (row.deleted_at !== null) {\n return canManage.value\n ? [\n {\n key: 'restore',\n icon: 'refresh',\n label: t('panel.restore'),\n run: () => void restore(row),\n },\n ]\n : []\n }\n\n const actions: RowAction[] = [\n { key: 'open', icon: 'edit', label: t('panel.open'), run: () => open(row) },\n ]\n\n if (row.url)\n actions.push({ key: 'site', icon: 'link', label: t('panel.open-site'), href: row.url })\n\n if (canManage.value) {\n actions.push(\n row.is_published\n ? {\n key: 'unpublish',\n icon: 'eye-off',\n label: t('panel.unpublish'),\n run: () => void publish(row, false),\n }\n : {\n key: 'publish',\n icon: 'eye',\n label: t('panel.publish'),\n run: () => void publish(row, true),\n },\n {\n key: 'delete',\n icon: 'trash',\n label: t('panel.delete'),\n danger: true,\n run: () => void remove(row),\n },\n )\n }\n\n return actions\n}\n\nasync function bulk(): Promise<void> {\n const run = await generate({ base: props.base })\n\n if (run) await load()\n}\n\nconst actions = computed<ScreenAction[]>(() =>\n canManage.value\n ? [\n {\n key: 'new',\n label: t('panel.new'),\n icon: 'plus',\n primary: true,\n run: () =>\n void router.push({\n path: `${list.value}/new`,\n query:\n chosenBase.value && chosenBase.value !== ROOT ? { category: chosenBase.value } : {},\n }),\n },\n { key: 'generate', label: t('panel.generate'), icon: 'grid', run: () => void bulk() },\n ]\n : [],\n)\n\nconst emptyText = computed(() =>\n applied.value.length > 0 || search.value ? t('panel.nothing-found') : t('panel.empty'),\n)\n\nonMounted(() => {\n void tree.load().catch(() => undefined)\n})\n</script>\n\n<template>\n <div class=\"wx-catalog-landings\">\n <wx-list-screen :title=\"title\" :actions=\"actions\">\n <wx-table\n v-model:search=\"search\"\n v-model:page=\"pageNumber\"\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n clickable\n hover\n flush\n :loading=\"loading\"\n layout=\"fixed\"\n :filters-count=\"applied.length\"\n :filters-label=\"panel('filters.title')\"\n :search-placeholder=\"t('panel.search')\"\n :empty-text=\"emptyText\"\n :aria-label=\"title\"\n @row-click=\"open\"\n @state-change=\"onState\"\n >\n <template #filters>\n <wx-form-item :label=\"t('panel.filter-base')\">\n <wx-tree-select\n :model-value=\"chosenBase\"\n :nodes=\"baseNodes\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n check-strictly\n filterable\n clearable\n size=\"sm\"\n @update:model-value=\"\n (picked: TreeSelectValue) =>\n (chosenBase =\n picked === null || picked === undefined || Array.isArray(picked)\n ? null\n : String(picked))\n \"\n />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.filter-attention')\">\n <wx-switch v-model=\"attention\" size=\"sm\" />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.filter-published')\">\n <wx-switch v-model=\"published\" size=\"sm\" />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.filter-empty')\">\n <wx-switch v-model=\"empty\" size=\"sm\" />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.filter-trashed')\">\n <wx-switch v-model=\"trashed\" size=\"sm\" />\n </wx-form-item>\n\n <wx-button v-if=\"applied.length > 0\" variant=\"text\" size=\"sm\" block @click=\"clearFilters\">\n <template #icon><wx-icon name=\"close\" /></template>\n {{ panel('filters.reset') }}\n </wx-button>\n </template>\n\n <template #applied>\n <wx-filter-chips :filters=\"applied\" />\n </template>\n\n <template #cell-name=\"{ row }\">\n <div class=\"wx-catalog-landings__name\">\n <span class=\"wx-catalog-landings__title\">{{ nameOf(row) }}</span>\n <span class=\"wx-catalog-landings__slug\">/{{ slugOf(row) }}/</span>\n </div>\n </template>\n\n <template #cell-category=\"{ row }\">\n <wx-text size=\"sm\" truncate :tone=\"row.category === null ? 'muted' : undefined\">\n {{ row.category ?? t('landing.whole-catalog') }}\n </wx-text>\n </template>\n\n <template #cell-chips=\"{ row }\">\n <div class=\"wx-catalog-landings__chips\">\n <wx-badge v-for=\"chip in row.chips\" :key=\"chip.key\" size=\"sm\" variant=\"soft\">\n {{ chip.label }}: {{ chip.text }}\n </wx-badge>\n </div>\n </template>\n\n <template #cell-products_count=\"{ row }\">\n <wx-text v-if=\"row.products_count === null\" size=\"sm\" tone=\"muted\">\n {{ t('panel.not-counted') }}\n </wx-text>\n <wx-badge v-else-if=\"row.products_count === 0\" type=\"warning\" size=\"sm\" round>0</wx-badge>\n <span v-else class=\"wx-catalog-landings__count\">{{ row.products_count }}</span>\n </template>\n\n <template #cell-state=\"{ row }\">\n <div class=\"wx-catalog-landings__state\">\n <wx-badge v-if=\"row.deleted_at\" dot size=\"sm\">{{ t('panel.in-bin') }}</wx-badge>\n <wx-badge v-else :type=\"row.is_published ? 'success' : 'default'\" dot size=\"sm\">\n {{ t(row.is_published ? 'panel.published' : 'panel.unpublished') }}\n </wx-badge>\n <wx-tooltip v-if=\"row.attention\" :content=\"t(`landing.attention-${row.attention}`)\">\n <wx-badge type=\"warning\" size=\"sm\" round>\n <wx-icon name=\"warning\" size=\"sm\" />\n <span class=\"wx-catalog-landings__sr\">{{ t('landing.attention') }}</span>\n </wx-badge>\n </wx-tooltip>\n </div>\n </template>\n\n <template #cell-updated_at=\"{ row }\">\n <wx-date :value=\"row.updated_at\" compact />\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"nameOf(row)\" />\n </template>\n </wx-table>\n </wx-list-screen>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landings {\n min-width: 0;\n}\n\n.wx-catalog-landings__name {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-catalog-landings__title,\n.wx-catalog-landings__slug {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-catalog-landings__slug {\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-catalog-landings__chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n}\n\n.wx-catalog-landings__count {\n font-variant-numeric: tabular-nums;\n}\n\n.wx-catalog-landings__state {\n display: flex;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-catalog-landings__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n</style>\n","import type { AdminModule } from '@webx-ui/module-admin'\nimport LandingEditorPage from './LandingEditorPage.vue'\nimport LandingProductsField from './LandingProductsField.vue'\nimport LandingSetField from './LandingSetField.vue'\nimport LandingSlugField from './LandingSlugField.vue'\nimport LandingSortField from './LandingSortField.vue'\nimport LandingsPage from './LandingsPage.vue'\n\nexport interface CatalogLandingsOptions {\n /** Where the catalogue lives inside the panel — the same as `catalog({ path })`. */\n path?: string\n}\n\n/**\n * Landings as a section of the panel (§8 of the landings spec): the list with its filters and\n * «Create in bulk», and the page of one — new at `…/landings/new` — which is the server's\n * `catalog.landing-form`. «Catalog» → «Landings» after «Brands» on the server's side (order 303).\n *\n * The node types are the parts of that form a plain field cannot be: the set builder with its\n * live count, the address with the set's suggestion, the default sort out of the catalogue's\n * registry, and the recommended products found and put in order.\n */\nexport function catalogLandings(options: CatalogLandingsOptions = {}): AdminModule[] {\n const catalog = options.path ?? '/catalog'\n const props = { base: catalog }\n\n return [\n {\n id: 'catalog-landings',\n path: `${catalog}/landings`,\n routes: [\n {\n path: `${catalog}/landings`,\n name: 'webx.catalog-landings',\n component: LandingsPage,\n props,\n },\n {\n path: `${catalog}/landings/new`,\n name: 'webx.catalog-landings.new',\n component: LandingEditorPage,\n props,\n },\n {\n path: `${catalog}/landings/:id(\\\\d+)`,\n name: 'webx.catalog-landings.edit',\n component: LandingEditorPage,\n props,\n },\n ],\n types: {\n // Wide: a facet's row is a label, a list of values and a button, and half a form is too\n // narrow for a combobox of brands beside its label.\n 'wx-catalog-landing-set': { component: LandingSetField, kind: 'field', wide: true },\n 'wx-catalog-landing-slug': { component: LandingSlugField, kind: 'field' },\n 'wx-catalog-landing-sort': { component: LandingSortField, kind: 'field' },\n 'wx-catalog-landing-products': {\n component: LandingProductsField,\n kind: 'field',\n wide: true,\n },\n },\n },\n ]\n}\n"],"names":["LANDINGS_API","landingSearch","query","search","key","value","createLandingsApi","admin","base","data","body","id","values","on","categoryId","filters","except","params","FORM_FIELDS","formValues","detail","field","cleanSet","clean","choice","landingEditorKey","provideLandingEditor","context","provide","useLandingEditor","inject","catalogLandingsMessages","NAMESPACE","seeded","useCatalogLandingsMessages","i18n","useAdmin","props","__props","api","route","useRoute","router","useRouter","locales","useLocales","useTranslate","message","useErrorText","list","computed","creating","landing","ref","snapshot","suggested","loading","saving","errors","canManage","trashed","locked","current","dirty","state","section","module","title","written","localizedValue","subtitle","row","provideHistorySubject","take","blank","load","error","toast","payload","save","created","publish","answer","remove","confirm","restore","leaveGuard","event","onKeydown","useBodyKeys","watch","next","previous","onMounted","onBeforeUnmount","onBeforeRouteLeave","actions","leads","_createElementBlock","_Fragment","_createVNode","_unref","WxSkeleton","WxCard","WxScreenHead","WxBreadcrumb","WxBreadcrumbItem","_createBlock","WxBadge","WxAlert","WxScreen","$event","WxActionBar","WxSaveState","WxButton","_createTextVNode","_toDisplayString","_useModel","catalog","createCatalogApi","editor","t","known","items","item","term","options","searching","failed","asked","q","ticket","page","taken","product","pick","option","drop","one","_openBlock","_hoisted_1","WxAutocomplete","WxText","WxSortableList","_withCtx","_createElementVNode","_hoisted_2","_hoisted_3","WxIcon","category","offered","loadFailed","set","facetOf","facet","adding","loadFacets","isRange","write","add","valuesOf","rangeOf","optionsOf","chosen","word","chipWord","chip","picked","bound","end","range","labelOf","counted","counting","countFailed","timer","countTicket","question","count","takenLink","_renderList","WxInputNumber","WxSelect","_hoisted_4","WxLink","RouterLink","record","suggestion","locale","slug","use","active","WxInput","_cache","NONE","registry","useFacetRegistry","sort","open","resolve","useModal","tree","useCategoryTree","step","categories","subtree","minProducts","templates","facets","failure","busy","preview","run","first","facetOptions","valueOptions","ready","refuse","toPreview","poll","delay","start","finished","close","columns","rows","index","WxDialog","WxSpace","WxFormItem","WxTreeSelect","WxSwitch","WxTable","WxProgress","_hoisted_5","ROOT","panel","generate","createModal","GenerateDialog","flag","pageNumber","chosenBase","attention","published","empty","perPage","baseNodes","baseName","find","nodes","found","node","applied","chips","clearFilters","mine","remember","wanted","onState","rowMenuWidth","nameOf","slugOf","actionsFor","bulk","emptyText","WxListScreen","WxFilterChips","_hoisted_6","_hoisted_7","WxTooltip","_hoisted_8","WxDate","WxRowMenu","catalogLandings","LandingsPage","LandingEditorPage","LandingSetField","LandingSlugField","LandingSortField","LandingProductsField"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/api.ts","../src/editor.ts","../src/messages.ts","../src/i18n.ts","../src/LandingEditorPage.vue","../src/LandingProductsField.vue","../src/LandingSetField.vue","../src/LandingSlugField.vue","../src/LandingSortField.vue","../src/GenerateDialog.vue","../src/LandingsPage.vue","../src/module.ts"],"sourcesContent":["import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n BaseFacet,\n GenerateParams,\n GeneratePreview,\n GenerateRun,\n LandingDetail,\n LandingFilters,\n LandingQuery,\n LandingsPage,\n SetCount,\n} from './types'\n\n/** Where the landings answer under the panel's API (§8.4 of the landings spec). */\nexport const LANDINGS_API = 'catalog/landings'\n\n/** The list's question as a query string; a filter left unset is not sent at all. */\nexport function landingSearch(query: LandingQuery): URLSearchParams {\n const search = new URLSearchParams()\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null || value === '') continue\n\n search.set(key, typeof value === 'boolean' ? (value ? '1' : '0') : String(value))\n }\n\n return search\n}\n\nexport interface CatalogLandingsApi {\n list(query?: LandingQuery): Promise<LandingsPage>\n get(id: number): Promise<LandingDetail>\n create(values: Record<string, unknown>): Promise<LandingDetail>\n save(id: number, values: Record<string, unknown>): Promise<LandingDetail>\n remove(id: number): Promise<void>\n restore(id: number): Promise<LandingDetail>\n publish(id: number, on: boolean): Promise<LandingDetail>\n count(\n categoryId: number | null,\n filters: LandingFilters,\n except?: number | null,\n ): Promise<SetCount>\n facets(categoryId: number | null): Promise<BaseFacet[]>\n preview(params: GenerateParams): Promise<GeneratePreview>\n generate(params: GenerateParams): Promise<GenerateRun>\n run(id: number): Promise<GenerateRun>\n}\n\nexport function createLandingsApi(admin: AdminContext): CatalogLandingsApi {\n const base = `${admin.apiPath}/${LANDINGS_API}`\n const data = <T>(body: { data: T }): T => body.data\n\n return {\n list: (query = {}) => {\n const search = landingSearch(query)\n\n return admin.http.get<LandingsPage>(search.size > 0 ? `${base}?${search}` : base)\n },\n get: (id) => admin.http.get<{ data: LandingDetail }>(`${base}/${id}`).then(data),\n create: (values) => admin.http.post<{ data: LandingDetail }>(base, values).then(data),\n save: (id, values) =>\n admin.http.put<{ data: LandingDetail }>(`${base}/${id}`, values).then(data),\n remove: (id) => admin.http.delete<void>(`${base}/${id}`).then(() => undefined),\n restore: (id) =>\n admin.http.post<{ data: LandingDetail }>(`${base}/${id}/restore`, {}).then(data),\n publish: (id, on) =>\n admin.http\n .post<{ data: LandingDetail }>(`${base}/${id}/${on ? 'publish' : 'unpublish'}`, {})\n .then(data),\n count: (categoryId, filters, except = null) =>\n admin.http\n .post<{ data: SetCount }>(`${base}/count`, { category_id: categoryId, filters, except })\n .then(data),\n facets: (categoryId) =>\n admin.http\n .get<{\n data: BaseFacet[]\n }>(categoryId === null ? `${base}/facets` : `${base}/facets?category=${categoryId}`)\n .then(data),\n preview: (params) =>\n admin.http\n .post<{ data: GeneratePreview }>(`${base}/generate`, { ...params, dry_run: true })\n .then(data),\n generate: (params) =>\n admin.http.post<{ data: GenerateRun }>(`${base}/generate`, params).then(data),\n run: (id) => admin.http.get<{ data: GenerateRun }>(`${base}/generate/${id}`).then(data),\n }\n}\n\n/** The fields of the form a save sends; what the list shows beside them is not the form's. */\nexport const FORM_FIELDS = [\n 'category_id',\n 'filters',\n 'name',\n 'slug',\n 'h1',\n 'text_above',\n 'text_below',\n 'sort',\n 'on_category',\n 'position',\n 'recommended',\n 'seo',\n] as const\n\n/** A landing's values as the form holds them. */\nexport function formValues(detail: LandingDetail): Record<string, unknown> {\n const values: Record<string, unknown> = {}\n\n for (const field of FORM_FIELDS) values[field] = detail[field] ?? null\n\n // The table keeps an empty set as `[]` when PHP encodes an empty array.\n if (Array.isArray(values.filters)) values.filters = {}\n\n return values\n}\n\n/**\n * A set without the facets that say nothing — a list with no value, a range with no end — so\n * that a half-built facet neither counts nor fails a save.\n */\nexport function cleanSet(filters: LandingFilters | null | undefined): LandingFilters {\n const clean: LandingFilters = {}\n\n for (const [key, choice] of Object.entries(filters ?? {})) {\n if ('values' in choice) {\n if (choice.values.length > 0) clean[key] = { values: [...choice.values] }\n } else if (choice.min !== null || choice.max !== null) {\n clean[key] = { min: choice.min, max: choice.max }\n }\n }\n\n return clean\n}\n","import { inject, provide, type InjectionKey, type Ref } from 'vue'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport type { LandingDetail } from './types'\n\n/**\n * What the landing's form shares with the fields of its screen: the set builder reads the base\n * from the values, the address reads the set's suggestion, the recommended products read the\n * names the server sent with the ids.\n */\nexport interface LandingEditorContext {\n /** As the server last answered; `null` for a landing not created yet. */\n landing: Ref<LandingDetail | null>\n values: Ref<ScreenModel>\n locked: Ref<boolean>\n /** The slugs the set suggests, per language — written by the set builder after each count. */\n suggested: Ref<Record<string, string>>\n /** Where the landings' list is: `/catalog/landings`. */\n list: string\n}\n\nexport const landingEditorKey: InjectionKey<LandingEditorContext> = Symbol('wx-catalog-landing')\n\nexport function provideLandingEditor(context: LandingEditorContext): void {\n provide(landingEditorKey, context)\n}\n\n/** `null` outside the landing's page — a field put on another screen keeps working on its own. */\nexport function useLandingEditor(): LandingEditorContext | null {\n return inject(landingEditorKey, null)\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * The English this package speaks on its own, before the server's dictionary arrives, or without\n * one. The server ships the same lines under `webx-catalog-landings::` and overrides these — the\n * Russian is there; `messages.test.ts` keeps the two sets of keys equal.\n */\nexport const catalogLandingsMessages: Record<string, Messages> = {\n module: {\n title: 'Landings',\n landing: 'Landing',\n },\n landing: {\n category_id: 'Base',\n filters: 'Set',\n name: 'Name',\n slug: 'Address',\n h1: 'H1',\n text_above: 'Text above the list',\n text_below: 'Text under the list',\n sort: 'Default sort',\n on_category: 'In the category’s collections',\n position: 'Order',\n is_published: 'Published',\n attention: 'Needs attention',\n 'whole-catalog': 'The whole catalogue',\n 'tab-main': 'Main',\n 'tab-texts': 'Texts',\n 'tab-recommended': 'Recommended',\n 'tab-seo': 'SEO',\n 'tab-history': 'History',\n display: 'On the site',\n 'name-help': 'The label in the panel and in the links of the collections.',\n 'category-help': 'The list the landing narrows. Empty — the whole catalogue.',\n 'slug-help': 'From the site’s root, like a category’s: /laptops-apple/.',\n 'sort-help': 'The order a reader sees first; the one they choose wins.',\n 'sort-default': 'As the category',\n 'on-category-help': 'A link in «Collections» on the page of the base.',\n 'position-help': 'Smaller first, in the collections and among the neighbours.',\n 'h1-help': 'Empty — the name.',\n 'text-help': 'Shown on the landing’s first page with nothing more chosen.',\n recommended: 'Recommended products',\n 'recommended-help': 'A strip over the list, in this order; the list itself does not change.',\n 'recommended-search': 'Find a product by name or SKU',\n 'recommended-empty': 'No products picked.',\n 'recommended-remove': 'Remove',\n 'set-add': 'Add a facet',\n 'set-empty': 'Add a facet and choose its values.',\n 'set-remove': 'Remove the facet',\n 'set-values': 'Choose values',\n 'set-from': 'From',\n 'set-to': 'To',\n 'set-count': 'Products: :count',\n 'set-counting': 'Counting…',\n 'set-taken': 'This set on this base is already the landing «:name».',\n 'set-open-taken': 'Open it',\n 'slug-suggested': 'Suggested: :slug',\n 'slug-use': 'Use',\n 'attention-value_removed': 'A value of the set was deleted',\n 'attention-duplicate': 'The set became another landing’s',\n 'attention-empty_set': 'Nothing is left of the set',\n },\n panel: {\n new: 'New landing',\n generate: 'Create in bulk',\n empty: 'No landings yet.',\n 'empty-help':\n 'A landing is a category’s list with filters chosen in advance, under an address, texts and SEO of its own.',\n 'nothing-found': 'Nothing matches the filters.',\n search: 'Name or address',\n 'column-name': 'Name',\n 'column-base': 'Base',\n 'column-set': 'Set',\n 'column-count': 'Products',\n 'column-state': 'State',\n 'column-updated': 'Updated',\n 'filter-base': 'Base',\n 'filter-attention': 'Needs attention',\n 'filter-published': 'Published only',\n 'filter-empty': 'Empty only',\n 'filter-trashed': 'In the bin',\n published: 'Published',\n unpublished: 'Not published',\n 'not-counted': 'Not counted yet',\n open: 'Open',\n 'open-site': 'Open on the site',\n publish: 'Publish',\n unpublish: 'Unpublish',\n delete: 'Delete',\n restore: 'Restore',\n 'delete-title': 'Delete «:name»?',\n 'delete-text':\n 'It goes to the bin, and its address stops answering. Its set stays taken until it is gone for good.',\n deleted: 'The landing is in the bin.',\n restored: 'The landing is back.',\n 'published-toast': 'The landing is published.',\n 'unpublished-toast': 'The landing is unpublished.',\n saved: 'The landing is saved.',\n created: 'The landing is created.',\n save: 'Save',\n create: 'Create',\n 'save-failed': 'Not saved — see the fields.',\n cancel: 'Cancel',\n 'leave-title': 'Leave without saving?',\n 'leave-text': 'What you changed here will be lost.',\n leave: 'Leave',\n untitled: 'A new landing',\n 'in-bin': 'In the bin',\n trail: 'Where you are',\n },\n generate: {\n title: 'Create landings in bulk',\n bases: 'Bases',\n 'bases-help': 'One category or several; a landing per category and value.',\n subtree: 'With every category under them',\n facet: 'Facet',\n values: 'Values',\n 'values-help': 'Empty — every value with products on the base.',\n 'min-products': 'At least products',\n 'min-products-help': 'For «every value»: values with fewer products on the base are left out.',\n templates: 'Templates',\n 'templates-help':\n '{category} and {value} are replaced: the slugs in the address, the names in the texts.',\n slug: 'Address',\n name: 'Name',\n h1: 'H1',\n 'seo-title': 'SEO title',\n 'seo-description': 'SEO description',\n 'template-empty': 'Empty — not set',\n publish: 'Publish at once',\n preview: 'Preview',\n back: 'Back',\n run: 'Create :count',\n close: 'Close',\n 'column-address': 'Address',\n 'column-h1': 'H1',\n 'column-count': 'Products',\n 'column-conflict': 'Skipped because',\n summary: 'Will be created: :free; skipped: :skipped.',\n nothing: 'Nothing to create: every row is skipped.',\n running: 'Creating landings…',\n done: 'Created: :done; skipped: :skipped; refused: :failed.',\n failed: 'The generation stopped. What was created stays.',\n 'conflict-slug-taken': 'The address :slug is taken.',\n 'conflict-set-taken': 'The set is already the landing «:name».',\n 'conflict-empty': 'No products.',\n 'conflict-no-slug': 'A slug or a name to fill the template with is missing.',\n },\n}\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { catalogLandingsMessages } from './messages'\n\n/** The server's dictionary for this package: `webx-catalog-landings::`. */\nexport const NAMESPACE = 'webx-catalog-landings'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useCatalogLandingsMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults(NAMESPACE, catalogLandingsMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { onBeforeRouteLeave, useRoute, useRouter } from 'vue-router'\nimport {\n confirm,\n localizedValue,\n toast,\n useLocales,\n WxActionBar,\n WxAlert,\n WxBadge,\n WxBreadcrumb,\n WxBreadcrumbItem,\n WxButton,\n WxCard,\n WxSkeleton,\n type LocalizedValue,\n} from '@webx-ui/core'\nimport {\n provideHistorySubject,\n useAdmin,\n useBodyKeys,\n useErrorText,\n useTranslate,\n WxSaveState,\n WxScreen,\n WxScreenHead,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport { cleanSet, createLandingsApi, formValues } from './api'\nimport { provideLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { LandingDetail, LandingFilters } from './types'\n\n/**\n * One landing (§8.2 of the landings spec): a head, `catalog.landing-form` under it — base, set,\n * address, texts, order, recommended, SEO, history — and one button. A new landing is the same\n * page at `…/landings/new`: its first save creates it and the address moves to its id.\n */\ndefineOptions({ name: 'WxCatalogLandingEditor' })\n\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/catalog' })\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst route = useRoute()\nconst router = useRouter()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst list = computed(() => `${props.base}/landings`)\nconst creating = computed(() => route.params.id === undefined || route.params.id === 'new')\nconst id = computed(() => (creating.value ? null : Number(route.params.id)))\n\nconst landing = ref<LandingDetail | null>(null)\nconst values = ref<ScreenModel>({})\nconst snapshot = ref('')\nconst suggested = ref<Record<string, string>>({})\n\nconst loading = ref(true)\nconst saving = ref(false)\nconst errors = ref<Record<string, string[]>>({})\n\nconst canManage = computed(() => admin.can('catalog.manage'))\nconst trashed = computed(() => (landing.value?.deleted_at ?? null) !== null)\nconst locked = computed(() => !canManage.value || saving.value || trashed.value)\n\nconst current = computed(() => JSON.stringify(values.value))\nconst dirty = computed(() => snapshot.value !== '' && current.value !== snapshot.value)\n\nconst state = computed<'saving' | 'unsaved' | 'saved'>(() => {\n if (saving.value) return 'saving'\n\n return dirty.value || creating.value ? 'unsaved' : 'saved'\n})\n\nconst section = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'catalog-landings')?.title ??\n t('module.title'),\n)\n\n/** The name follows the field: a rename shows at the top as it is typed. */\nconst title = computed(() => {\n const written = values.value.name as LocalizedValue | string | null | undefined\n\n return localizedValue(written, locales.active.value, '') || t('panel.untitled')\n})\n\nconst subtitle = computed(() => {\n const row = landing.value\n\n if (!row) return undefined\n\n return [row.category ?? t('landing.whole-catalog'), row.url ?? ''].filter(Boolean).join(' · ')\n})\n\nprovideLandingEditor({ landing, values, locked, suggested, list: list.value })\nprovideHistorySubject({ id: computed(() => landing.value?.id ?? null) })\n\nfunction take(detail: LandingDetail): void {\n landing.value = detail\n values.value = formValues(detail)\n snapshot.value = JSON.stringify(values.value)\n}\n\nfunction blank(): void {\n landing.value = null\n values.value = {\n category_id: route.query.category ? Number(route.query.category) : null,\n filters: {},\n name: {},\n slug: {},\n h1: {},\n text_above: {},\n text_below: {},\n sort: null,\n on_category: false,\n position: 0,\n recommended: [],\n seo: {},\n }\n snapshot.value = JSON.stringify(values.value)\n}\n\nasync function load(): Promise<void> {\n errors.value = {}\n\n if (id.value === null) {\n blank()\n loading.value = false\n\n return\n }\n\n loading.value = true\n\n try {\n take(await api.get(id.value))\n } catch (error) {\n toast.danger(message(error))\n void router.push(list.value)\n } finally {\n loading.value = false\n }\n}\n\n/** What a save sends: the form's fields, the set without its half-built facets. */\nfunction payload(): Record<string, unknown> {\n return { ...values.value, filters: cleanSet(values.value.filters as LandingFilters) }\n}\n\nasync function save(): Promise<void> {\n if (saving.value || !canManage.value) return\n\n saving.value = true\n errors.value = {}\n\n try {\n if (id.value === null) {\n const created = await api.create(payload())\n\n take(created)\n toast.success(t('panel.created'))\n await router.replace(`${list.value}/${created.id}`)\n } else {\n take(await api.save(id.value, payload()))\n toast.success(t('panel.saved'))\n }\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors && Object.keys(body.errors).length > 0) {\n errors.value = body.errors\n toast.danger(t('panel.save-failed'))\n } else {\n toast.danger(message(error))\n }\n } finally {\n saving.value = false\n }\n}\n\nasync function publish(on: boolean): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n try {\n const answer = await api.publish(row.id, on)\n\n // Only the state: what is being typed in the form stays.\n landing.value = { ...row, ...answer }\n toast.success(t(on ? 'panel.published-toast' : 'panel.unpublished-toast'))\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n const agreed = await confirm({\n title: t('panel.delete-title', { name: title.value }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(row.id)\n toast.success(t('panel.deleted'))\n snapshot.value = current.value\n void router.push(list.value)\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(): Promise<void> {\n const row = landing.value\n\n if (!row) return\n\n try {\n take(await api.restore(row.id))\n toast.success(t('panel.restored'))\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction leaveGuard(event: BeforeUnloadEvent): void {\n if (dirty.value) event.preventDefault()\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault()\n if (dirty.value || creating.value) void save()\n }\n}\n\nuseBodyKeys(onKeydown)\n\nwatch(id, (next, previous) => {\n // The first save of a new landing moves the address to its id — nothing to read again.\n if (previous === null && next !== null && landing.value?.id === next) return\n\n void load()\n})\n\nonMounted(() => {\n void load()\n window.addEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeRouteLeave(async () => {\n if (!dirty.value || !canManage.value) return true\n\n return await confirm({\n title: t('panel.leave-title'),\n message: t('panel.leave-text'),\n confirmText: t('panel.leave'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n})\n\nconst actions = computed<ScreenAction[]>(() => {\n const row = landing.value\n\n if (!row || !canManage.value) return []\n\n if (trashed.value) {\n return [\n { key: 'restore', label: t('panel.restore'), icon: 'refresh', run: () => void restore() },\n ]\n }\n\n const leads: ScreenAction[] = []\n\n if (row.url) {\n leads.push({\n key: 'site',\n label: t('panel.open-site'),\n icon: 'external-link',\n run: () => void window.open(row.url ?? '', '_blank', 'noopener'),\n })\n }\n\n leads.push(\n row.is_published\n ? {\n key: 'unpublish',\n label: t('panel.unpublish'),\n icon: 'eye-off',\n run: () => void publish(false),\n }\n : { key: 'publish', label: t('panel.publish'), icon: 'eye', run: () => void publish(true) },\n {\n key: 'delete',\n label: t('panel.delete'),\n icon: 'trash',\n danger: true,\n menu: true,\n run: () => void remove(),\n },\n )\n\n return leads\n})\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-editor\" @keydown=\"onKeydown\">\n <template v-if=\"loading\">\n <wx-skeleton class=\"wx-catalog-landing-editor__ghost\" title :rows=\"1\" />\n <wx-card><wx-skeleton :rows=\"6\" /></wx-card>\n </template>\n\n <template v-else>\n <wx-screen-head\n divider\n :back=\"list\"\n :back-label=\"section\"\n :title=\"title\"\n :subtitle=\"subtitle\"\n :actions=\"actions\"\n >\n <template #trail>\n <wx-breadcrumb size=\"sm\" :label=\"t('panel.trail')\">\n <wx-breadcrumb-item :as=\"'router-link'\" :to=\"list\">{{ section }}</wx-breadcrumb-item>\n <wx-breadcrumb-item current>{{ title }}</wx-breadcrumb-item>\n </wx-breadcrumb>\n </template>\n\n <template v-if=\"landing\" #title-after>\n <wx-badge v-if=\"trashed\" dot>{{ t('panel.in-bin') }}</wx-badge>\n <wx-badge v-else :type=\"landing.is_published ? 'success' : 'default'\" dot size=\"sm\">\n {{ t(landing.is_published ? 'panel.published' : 'panel.unpublished') }}\n </wx-badge>\n </template>\n </wx-screen-head>\n\n <wx-alert v-if=\"landing?.attention\" type=\"warning\">\n {{ t(`landing.attention-${landing.attention}`) }}\n </wx-alert>\n\n <wx-screen v-model=\"values\" name=\"catalog.landing-form\" :errors=\"errors\" :disabled=\"locked\" />\n\n <wx-action-bar v-if=\"canManage && !trashed\">\n <template #state>\n <wx-save-state :state=\"state\" />\n </template>\n\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!dirty && !creating\" @click=\"save\">\n {{ t(creating ? 'panel.create' : 'panel.save') }}\n </wx-button>\n </wx-action-bar>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-editor {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n container-type: inline-size;\n}\n\n.wx-catalog-landing-editor__ghost {\n max-width: 420px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport {\n WxAutocomplete,\n WxBadge,\n WxButton,\n WxIcon,\n WxSortableList,\n WxText,\n type AutocompleteOption,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { createCatalogApi } from '@webx-ui/module-catalog'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { RecommendedItem } from './types'\n\n/**\n * `wx-catalog-landing-products`: the recommended strip of a landing (decision 8) — products found\n * by name or SKU and put in order by dragging. The field's value is the ids in their order; the\n * names come with the landing from the server and with each product found, so the list never asks\n * for products one by one.\n */\ndefineOptions({ name: 'WxCatalogLandingProducts' })\n\nconst value = defineModel<number[] | null>({ default: null })\n\nconst admin = useAdmin()\nconst catalog = createCatalogApi(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst locked = computed(() => editor?.locked.value ?? false)\n\n/** Every product this field has seen a name for: the saved ones and the ones found since. */\nconst known = ref(new Map<number, RecommendedItem>())\n\nwatch(\n () => editor?.landing.value?.recommended_items,\n (items) => {\n for (const item of items ?? []) known.value.set(item.id, item)\n },\n { immediate: true },\n)\n\nconst items = computed<RecommendedItem[]>({\n get: () =>\n (value.value ?? []).map(\n (id) => known.value.get(id) ?? { id, name: `#${id}`, sku: null, deleted: false },\n ),\n set: (next) => {\n value.value = next.map((item) => item.id)\n },\n})\n\nconst term = ref('')\nconst options = ref<AutocompleteOption[]>([])\nconst searching = ref(false)\nconst failed = ref('')\nlet asked = 0\n\nasync function search(q: string): Promise<void> {\n const ticket = ++asked\n\n searching.value = true\n failed.value = ''\n\n try {\n const page = await catalog.products({ q, per_page: 10 })\n\n if (ticket !== asked) return\n\n const taken = new Set(value.value ?? [])\n\n options.value = page.data\n .filter((product) => !taken.has(product.id))\n .map((product) => {\n known.value.set(product.id, { id: product.id, name: product.name, sku: product.sku })\n\n return {\n value: String(product.id),\n label: product.name,\n description: product.sku ?? undefined,\n }\n })\n } catch (error) {\n if (ticket === asked) failed.value = message(error)\n } finally {\n if (ticket === asked) searching.value = false\n }\n}\n\nfunction pick(option: AutocompleteOption): void {\n const id = Number(option.value)\n\n if (!Number.isFinite(id) || (value.value ?? []).includes(id)) return\n\n value.value = [...(value.value ?? []), id]\n term.value = ''\n options.value = []\n}\n\nfunction drop(id: number): void {\n value.value = (value.value ?? []).filter((one) => one !== id)\n}\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-products\">\n <wx-autocomplete\n v-if=\"!locked\"\n v-model=\"term\"\n :options=\"options\"\n remote\n :loading=\"searching\"\n :min-length=\"1\"\n clearable\n :placeholder=\"t('landing.recommended-search')\"\n :aria-label=\"t('landing.recommended-search')\"\n @search=\"search\"\n @select=\"pick\"\n />\n <wx-text v-if=\"failed\" size=\"sm\" tone=\"danger\">{{ failed }}</wx-text>\n\n <wx-sortable-list\n v-model=\"items\"\n item-key=\"id\"\n item-label=\"name\"\n size=\"sm\"\n :disabled=\"locked\"\n :empty-text=\"t('landing.recommended-empty')\"\n :aria-label=\"t('landing.recommended')\"\n >\n <template #default=\"{ item }\">\n <span class=\"wx-catalog-landing-products__item\">\n <span class=\"wx-catalog-landing-products__name\">{{ item.name }}</span>\n <wx-text v-if=\"item.sku\" size=\"sm\" tone=\"muted\">{{ item.sku }}</wx-text>\n <wx-badge v-if=\"item.deleted\" size=\"sm\" type=\"warning\" round>\n {{ t('panel.in-bin') }}\n </wx-badge>\n </span>\n </template>\n <template #actions=\"{ item }\">\n <wx-button\n v-if=\"!locked\"\n variant=\"text\"\n size=\"sm\"\n :aria-label=\"`${t('landing.recommended-remove')}: ${item.name}`\"\n @click=\"drop(item.id)\"\n >\n <template #icon><wx-icon name=\"close\" /></template>\n </wx-button>\n </template>\n </wx-sortable-list>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-products {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-catalog-landing-products__item {\n display: flex;\n align-items: baseline;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-catalog-landing-products__name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { RouterLink } from 'vue-router'\nimport {\n WxAlert,\n WxBadge,\n WxButton,\n WxIcon,\n WxInputNumber,\n WxLink,\n WxSelect,\n WxText,\n type SelectOption,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { cleanSet, createLandingsApi } from './api'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { BaseFacet, LandingFilters, SetChoice, SetCount } from './types'\n\n/**\n * `wx-catalog-landing-set`: the set of a landing (§8.2 of the landings spec) — «add a facet» out of\n * the facets the base offers, its values in the same controls the products' filter uses (a list\n * of values with search, a range from–to), and beside them the live number of products and a\n * warning when another landing of the base already holds the set.\n *\n * The facets are asked again when the base changes; a facet of the set the new base does not offer\n * stays, labelled by its key, so that changing the base never drops a choice silently — the save\n * says whether the set still makes sense.\n */\ndefineOptions({ name: 'WxCatalogLandingSet' })\n\nconst value = defineModel<LandingFilters | null>({ default: null })\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\nconst locked = computed(() => editor?.locked.value ?? false)\n\nconst category = computed<number | null>(() => {\n const id = editor?.values.value.category_id\n\n return typeof id === 'number' ? id : id ? Number(id) : null\n})\n\nconst offered = ref<BaseFacet[]>([])\nconst loadFailed = ref('')\nconst set = computed<LandingFilters>(() =>\n value.value && !Array.isArray(value.value) ? value.value : {},\n)\n\nconst facetOf = (key: string) => offered.value.find((facet) => facet.key === key)\n\nconst adding = computed<SelectOption[]>(() =>\n offered.value\n .filter((facet) => !(facet.key in set.value))\n .map((facet) => ({ value: facet.key, label: facet.label })),\n)\n\nlet asked = 0\n\nasync function loadFacets(): Promise<void> {\n const ticket = ++asked\n\n loadFailed.value = ''\n\n try {\n const answer = await api.facets(category.value)\n\n if (ticket === asked) offered.value = answer\n } catch (error) {\n if (ticket === asked) loadFailed.value = message(error)\n }\n}\n\nwatch(category, () => void loadFacets(), { immediate: true })\n\nfunction isRange(key: string, choice: SetChoice): boolean {\n const facet = facetOf(key)\n\n return facet ? facet.kind === 'range' : !('values' in choice)\n}\n\nfunction write(next: LandingFilters): void {\n value.value = next\n}\n\nfunction add(key: unknown): void {\n const facet = facetOf(String(key))\n\n if (!facet) return\n\n write({\n ...set.value,\n [facet.key]: facet.kind === 'range' ? { min: null, max: null } : { values: [] },\n })\n}\n\nfunction remove(key: string): void {\n const next = { ...set.value }\n\n delete next[key]\n write(next)\n}\n\nfunction valuesOf(choice: SetChoice): string[] {\n return 'values' in choice ? choice.values : []\n}\n\nfunction rangeOf(choice: SetChoice): { min: number | null; max: number | null } {\n return 'values' in choice ? { min: null, max: null } : choice\n}\n\nfunction optionsOf(key: string, choice: SetChoice): SelectOption[] {\n const known = facetOf(key)?.values ?? []\n const options: SelectOption[] = known.map((one) => ({\n value: one.value,\n label: `${one.label} (${one.count})`,\n }))\n\n // A chosen value the base has no products of is still a choice: shown, not dropped.\n for (const chosen of valuesOf(choice)) {\n if (!known.some((one) => one.value === chosen)) {\n const word = chipWord(key, chosen)\n options.push({ value: chosen, label: `${word} (0)` })\n }\n }\n\n return options\n}\n\n/** The saved landing's chip says what a value is called when the base no longer counts it. */\nfunction chipWord(key: string, chosen: string): string {\n return editor?.landing.value?.chips.find((chip) => chip.key === key)?.text ?? `#${chosen}`\n}\n\nfunction pick(key: string, picked: unknown): void {\n write({ ...set.value, [key]: { values: Array.isArray(picked) ? picked.map(String) : [] } })\n}\n\nfunction bound(key: string, end: 'min' | 'max', picked: number | null | undefined): void {\n const choice = set.value[key]\n const range = choice ? rangeOf(choice) : { min: null, max: null }\n\n write({ ...set.value, [key]: { ...range, [end]: picked ?? null } })\n}\n\nfunction labelOf(key: string): string {\n return facetOf(key)?.label ?? key\n}\n\n/* -------------------------------------------------------------------- the count --- */\n\nconst counted = ref<SetCount | null>(null)\nconst counting = ref(false)\nconst countFailed = ref('')\nlet timer: ReturnType<typeof setTimeout> | undefined\nlet countTicket = 0\n\nconst question = computed(() => JSON.stringify([category.value, cleanSet(set.value)]))\n\nasync function count(): Promise<void> {\n const ticket = ++countTicket\n const clean = cleanSet(set.value)\n\n if (Object.keys(clean).length === 0) {\n counted.value = null\n counting.value = false\n if (editor) editor.suggested.value = {}\n\n return\n }\n\n counting.value = true\n countFailed.value = ''\n\n try {\n const answer = await api.count(category.value, clean, editor?.landing.value?.id ?? null)\n\n if (ticket !== countTicket) return\n\n counted.value = answer\n if (editor) editor.suggested.value = Array.isArray(answer.suggested) ? {} : answer.suggested\n } catch (error) {\n if (ticket === countTicket) {\n counted.value = null\n countFailed.value = message(error)\n }\n } finally {\n if (ticket === countTicket) counting.value = false\n }\n}\n\nwatch(\n question,\n () => {\n clearTimeout(timer)\n timer = setTimeout(() => void count(), 350)\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst takenLink = computed(() =>\n counted.value?.taken && editor ? `${editor.list}/${counted.value.taken.id}` : null,\n)\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-set\">\n <wx-alert v-if=\"loadFailed\" type=\"danger\">{{ loadFailed }}</wx-alert>\n\n <wx-text v-if=\"Object.keys(set).length === 0\" tone=\"muted\" size=\"sm\">\n {{ t('landing.set-empty') }}\n </wx-text>\n\n <div\n v-for=\"(choice, key) in set\"\n :key=\"key\"\n class=\"wx-catalog-landing-set__row\"\n :data-facet=\"key\"\n >\n <wx-text class=\"wx-catalog-landing-set__label\" size=\"sm\" weight=\"medium\">\n {{ labelOf(String(key)) }}\n </wx-text>\n\n <div v-if=\"isRange(String(key), choice)\" class=\"wx-catalog-landing-set__range\">\n <wx-input-number\n :model-value=\"rangeOf(choice).min\"\n :controls=\"false\"\n :disabled=\"locked\"\n size=\"sm\"\n :placeholder=\"facetOf(String(key))?.min?.toString() ?? t('landing.set-from')\"\n :aria-label=\"`${labelOf(String(key))}: ${t('landing.set-from')}`\"\n @update:model-value=\"\n (picked: number | null | undefined) => bound(String(key), 'min', picked)\n \"\n />\n <wx-input-number\n :model-value=\"rangeOf(choice).max\"\n :controls=\"false\"\n :disabled=\"locked\"\n size=\"sm\"\n :placeholder=\"facetOf(String(key))?.max?.toString() ?? t('landing.set-to')\"\n :aria-label=\"`${labelOf(String(key))}: ${t('landing.set-to')}`\"\n @update:model-value=\"\n (picked: number | null | undefined) => bound(String(key), 'max', picked)\n \"\n />\n </div>\n\n <wx-select\n v-else\n class=\"wx-catalog-landing-set__values\"\n :model-value=\"valuesOf(choice)\"\n :options=\"optionsOf(String(key), choice)\"\n multiple\n filterable\n clearable\n size=\"sm\"\n :disabled=\"locked\"\n :placeholder=\"t('landing.set-values')\"\n :aria-label=\"labelOf(String(key))\"\n @update:model-value=\"(picked: unknown) => pick(String(key), picked)\"\n />\n\n <wx-button\n variant=\"text\"\n size=\"sm\"\n :disabled=\"locked\"\n :aria-label=\"t('landing.set-remove')\"\n :title=\"t('landing.set-remove')\"\n @click=\"remove(String(key))\"\n >\n <template #icon><wx-icon name=\"close\" /></template>\n </wx-button>\n </div>\n\n <div class=\"wx-catalog-landing-set__foot\">\n <wx-select\n v-if=\"adding.length > 0\"\n class=\"wx-catalog-landing-set__add\"\n :model-value=\"null\"\n :options=\"adding\"\n filterable\n size=\"sm\"\n :disabled=\"locked\"\n :placeholder=\"t('landing.set-add')\"\n :aria-label=\"t('landing.set-add')\"\n @update:model-value=\"add\"\n />\n\n <wx-text v-if=\"counting\" size=\"sm\" tone=\"muted\">{{ t('landing.set-counting') }}</wx-text>\n <wx-badge\n v-else-if=\"counted\"\n class=\"wx-catalog-landing-set__count\"\n :type=\"counted.count > 0 ? 'success' : 'warning'\"\n size=\"sm\"\n round\n >\n {{ t('landing.set-count', { count: counted.count }) }}\n </wx-badge>\n </div>\n\n <wx-alert v-if=\"countFailed\" type=\"danger\">{{ countFailed }}</wx-alert>\n\n <wx-alert v-if=\"counted?.taken\" type=\"warning\">\n {{ t('landing.set-taken', { name: counted.taken.name }) }}\n <wx-link v-if=\"takenLink\" :as=\"RouterLink\" :to=\"takenLink\">\n {{ t('landing.set-open-taken') }}\n </wx-link>\n </wx-alert>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-set {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n container-type: inline-size;\n min-width: 0;\n}\n\n.wx-catalog-landing-set__row {\n display: grid;\n grid-template-columns: minmax(96px, 160px) minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-catalog-landing-set__range {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--wx-space-8);\n}\n\n.wx-catalog-landing-set__foot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-12);\n}\n\n.wx-catalog-landing-set__add {\n width: 240px;\n max-width: 100%;\n}\n\n@container (max-width: 480px) {\n .wx-catalog-landing-set__row {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .wx-catalog-landing-set__label {\n grid-column: 1 / -1;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useLocales, WxButton, WxInput, WxText, type LocalizedValue } from '@webx-ui/core'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\n\n/**\n * `wx-catalog-landing-slug`: the address of a landing, per language, with the suggestion its set\n * makes under it — `{category}-{value}` of the slugs, as «Create in bulk» fills it (§8.2). The\n * set builder asks the server and puts the suggestion into the editor; «Use» writes it into the\n * language being edited and into the languages still empty.\n */\ndefineOptions({ name: 'WxCatalogLandingSlug' })\n\nconst props = withDefaults(defineProps<{ localized?: boolean }>(), { localized: false })\nconst value = defineModel<LocalizedValue | string | null>({ default: null })\n\nconst editor = useLandingEditor()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\n\nconst locked = computed(() => editor?.locked.value ?? false)\nconst record = computed<LocalizedValue>(() =>\n value.value && typeof value.value === 'object' ? value.value : {},\n)\n\nconst suggestion = computed(() => {\n const suggested = editor?.suggested.value ?? {}\n const locale = locales.active.value || Object.keys(suggested)[0] || ''\n const slug = suggested[locale]\n\n if (!slug) return null\n\n const current = props.localized ? record.value[locale] : value.value\n\n return current === slug ? null : slug\n})\n\nfunction use(): void {\n const suggested = editor?.suggested.value ?? {}\n\n if (!props.localized) {\n value.value = suggestion.value\n\n return\n }\n\n const next: LocalizedValue = { ...record.value }\n const active = locales.active.value\n\n for (const [locale, slug] of Object.entries(suggested)) {\n if (locale === active || !next[locale]) next[locale] = slug\n }\n\n value.value = next\n}\n</script>\n\n<template>\n <div class=\"wx-catalog-landing-slug\">\n <wx-input\n :model-value=\"value ?? undefined\"\n :localized=\"props.localized\"\n :disabled=\"locked\"\n :maxlength=\"255\"\n @update:model-value=\"(next: unknown) => (value = next as LocalizedValue | string)\"\n />\n <div v-if=\"suggestion && !locked\" class=\"wx-catalog-landing-slug__hint\">\n <wx-text size=\"sm\" tone=\"muted\">{{\n t('landing.slug-suggested', { slug: suggestion })\n }}</wx-text>\n <wx-button size=\"sm\" variant=\"text\" @click=\"use\">{{ t('landing.slug-use') }}</wx-button>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landing-slug {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n min-width: 0;\n}\n\n.wx-catalog-landing-slug__hint {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted } from 'vue'\nimport { WxSelect, type SelectOption } from '@webx-ui/core'\nimport { useAdmin, useTranslate } from '@webx-ui/module-admin'\nimport { useFacetRegistry } from '@webx-ui/module-catalog'\nimport { useLandingEditor } from './editor'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\n\n/**\n * `wx-catalog-landing-sort`: the landing's default order (decision 7) — one of the catalogue's\n * sorts, or none, which leaves the category's. The sorts come from the same registry the products'\n * list reads, so the panel never offers one the storefront does not know.\n */\ndefineOptions({ name: 'WxCatalogLandingSort' })\n\nconst value = defineModel<string | null>({ default: null })\n\nconst NONE = 'default'\n\nconst admin = useAdmin()\nconst registry = useFacetRegistry(admin)\nconst editor = useLandingEditor()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\n\nconst options = computed<SelectOption[]>(() => [\n // The registry's own 'default' stands for «none of the landing's own»: the category's order.\n { value: NONE, label: t('landing.sort-default') },\n ...registry.sorts.value\n .filter((sort) => sort.key !== NONE)\n .map((sort) => ({ value: sort.key, label: sort.label })),\n])\n\nonMounted(() => void registry.load().catch(() => undefined))\n</script>\n\n<template>\n <wx-select\n :model-value=\"value ?? NONE\"\n :options=\"options\"\n :disabled=\"editor?.locked.value ?? false\"\n @update:model-value=\"\n (picked: unknown) => (value = picked && picked !== NONE ? String(picked) : null)\n \"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport {\n useLocales,\n useModal,\n WxAlert,\n WxButton,\n WxDialog,\n WxFormItem,\n WxInput,\n WxInputNumber,\n WxProgress,\n WxSelect,\n WxSpace,\n WxSwitch,\n WxTable,\n WxText,\n WxTreeSelect,\n type SelectOption,\n type TableColumn,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { useCategoryTree } from '@webx-ui/module-catalog'\nimport { createLandingsApi } from './api'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { BaseFacet, GenerateParams, GeneratePreview, GenerateRow, GenerateRun } from './types'\n\n/**\n * «Create in bulk» (§8.3 of the landings spec), three steps in one dialog: the bases, the facet and\n * its values, the templates — then the preview, a row per landing with the reason it is skipped —\n * then the run, done at once or polled while the queue makes it. Resolves with the run, or `null`\n * when nothing was made.\n */\nconst { open, resolve } = useModal<GenerateRun | null>()\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst tree = useCategoryTree(admin)\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst message = useErrorText()\n\ntype Step = 'form' | 'preview' | 'run'\n\nconst step = ref<Step>('form')\nconst categories = ref<number[]>([])\nconst subtree = ref(false)\nconst facet = ref<string | null>(null)\nconst values = ref<string[]>([])\nconst minProducts = ref<number | null>(1)\nconst templates = ref({ slug: '', name: '', h1: '', title: '', description: '' })\nconst publish = ref(false)\n\nconst facets = ref<BaseFacet[]>([])\nconst errors = ref<Record<string, string[]>>({})\nconst failure = ref('')\nconst busy = ref(false)\nconst preview = ref<GeneratePreview | null>(null)\nconst run = ref<GenerateRun | null>(null)\n\nonMounted(() => void tree.load().catch(() => undefined))\n\n/* The facets of values the first base offers: a range has no value to make a landing of. */\nwatch(\n () => categories.value[0] ?? null,\n async (first) => {\n if (first === null) {\n facets.value = []\n\n return\n }\n\n try {\n facets.value = (await api.facets(first)).filter((one) => one.kind !== 'range')\n } catch (error) {\n failure.value = message(error)\n }\n },\n)\n\nconst facetOptions = computed<SelectOption[]>(() =>\n facets.value.map((one) => ({ value: one.key, label: one.label })),\n)\n\nconst valueOptions = computed<SelectOption[]>(() =>\n (facets.value.find((one) => one.key === facet.value)?.values ?? []).map((one) => ({\n value: one.value,\n label: `${one.label} (${one.count})`,\n })),\n)\n\nwatch(facet, () => (values.value = []))\n\nconst params = computed<GenerateParams>(() => ({\n categories: categories.value,\n subtree: subtree.value,\n facet: facet.value ?? '',\n values: values.value.length > 0 ? values.value : null,\n min_products: minProducts.value,\n ...templates.value,\n publish: publish.value,\n}))\n\nconst ready = computed(() => categories.value.length > 0 && facet.value !== null)\n\nfunction first(field: string): string | undefined {\n return errors.value[field]?.[0]\n}\n\nfunction refuse(error: unknown): void {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) errors.value = body.errors\n else failure.value = message(error)\n}\n\nasync function toPreview(): Promise<void> {\n if (!ready.value || busy.value) return\n\n busy.value = true\n errors.value = {}\n failure.value = ''\n\n try {\n preview.value = await api.preview(params.value)\n step.value = 'preview'\n } catch (error) {\n refuse(error)\n } finally {\n busy.value = false\n }\n}\n\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nasync function poll(id: number, delay = 1500): Promise<void> {\n timer = setTimeout(async () => {\n try {\n run.value = await api.run(id)\n\n if (run.value.status === 'queued' || run.value.status === 'running') void poll(id)\n } catch {\n void poll(id, Math.min(delay * 2, 15000))\n }\n }, delay)\n}\n\nasync function start(): Promise<void> {\n if (busy.value) return\n\n busy.value = true\n failure.value = ''\n\n try {\n run.value = await api.generate(params.value)\n step.value = 'run'\n\n if (run.value.id !== null && !finished.value) void poll(run.value.id)\n } catch (error) {\n refuse(error)\n step.value = 'form'\n } finally {\n busy.value = false\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst finished = computed(() => run.value?.status === 'done' || run.value?.status === 'failed')\n\nfunction close(): void {\n resolve(run.value && run.value.done > 0 ? run.value : null)\n}\n\n/* --------------------------------------------------------------- the preview --- */\n\nconst word = (record: Record<string, string>) =>\n record[locales.active.value] ?? Object.values(record)[0] ?? ''\n\nconst columns = computed<TableColumn<GenerateRow>[]>(() => [\n { key: 'address', label: t('generate.column-address'), minWidth: 180 },\n { key: 'title', label: t('generate.column-h1'), minWidth: 180, hideBelow: 560 },\n { key: 'count', label: t('generate.column-count'), width: 100, align: 'right' },\n { key: 'conflict', label: t('generate.column-conflict'), minWidth: 180 },\n])\n\nconst rows = computed(() =>\n (preview.value?.rows ?? []).map((row, index) => ({ ...row, id: index })),\n)\n</script>\n\n<template>\n <wx-dialog\n v-model:open=\"open\"\n :title=\"t('generate.title')\"\n :width=\"step === 'form' ? 600 : 860\"\n @update:open=\"(on: boolean) => !on && close()\"\n >\n <wx-alert v-if=\"failure\" type=\"danger\">{{ failure }}</wx-alert>\n\n <div v-if=\"step === 'form'\" class=\"wx-catalog-landings-generate\">\n <wx-form-item\n :label=\"t('generate.bases')\"\n :help=\"t('generate.bases-help')\"\n :error=\"first('categories')\"\n required\n >\n <wx-tree-select\n :model-value=\"categories\"\n :nodes=\"tree.nodes.value ?? []\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n multiple\n check-strictly\n filterable\n clearable\n @update:model-value=\"\n (picked: TreeSelectValue) =>\n (categories = Array.isArray(picked)\n ? picked.map(Number)\n : picked\n ? [Number(picked)]\n : [])\n \"\n />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"subtree\">{{ t('generate.subtree') }}</wx-switch>\n </wx-form-item>\n\n <wx-form-item :label=\"t('generate.facet')\" :error=\"first('facet')\" required>\n <wx-select v-model=\"facet\" :options=\"facetOptions\" :disabled=\"categories.length === 0\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.values')\" :help=\"t('generate.values-help')\">\n <wx-select\n v-model=\"values\"\n :options=\"valueOptions\"\n multiple\n filterable\n clearable\n :disabled=\"facet === null\"\n />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.min-products')\" :help=\"t('generate.min-products-help')\">\n <wx-input-number v-model=\"minProducts\" :min=\"0\" :disabled=\"values.length > 0\" />\n </wx-form-item>\n\n <wx-text weight=\"medium\">{{ t('generate.templates') }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('generate.templates-help') }}</wx-text>\n <wx-form-item :label=\"t('generate.slug')\" :error=\"first('slug')\">\n <wx-input v-model=\"templates.slug\" placeholder=\"{category}-{value}\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.name')\">\n <wx-input v-model=\"templates.name\" placeholder=\"{category} {value}\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.h1')\">\n <wx-input v-model=\"templates.h1\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.seo-title')\">\n <wx-input v-model=\"templates.title\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item :label=\"t('generate.seo-description')\">\n <wx-input v-model=\"templates.description\" :placeholder=\"t('generate.template-empty')\" />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"publish\">{{ t('generate.publish') }}</wx-switch>\n </wx-form-item>\n </div>\n\n <div v-else-if=\"step === 'preview' && preview\" class=\"wx-catalog-landings-generate\">\n <wx-text>\n {{\n preview.free > 0\n ? t('generate.summary', { free: preview.free, skipped: preview.total - preview.free })\n : t('generate.nothing')\n }}\n </wx-text>\n <wx-table :data=\"rows\" :columns=\"columns\" row-key=\"id\" flush layout=\"fixed\">\n <template #cell-address=\"{ row }\">\n <span class=\"wx-catalog-landings-generate__mono\">/{{ word(row.slug) }}/</span>\n </template>\n <template #cell-title=\"{ row }\">\n {{ word(Object.keys(row.h1).length > 0 ? row.h1 : row.name) }}\n </template>\n <template #cell-conflict=\"{ row }\">\n <wx-text v-if=\"row.conflict\" size=\"sm\" tone=\"warning\">{{ row.message }}</wx-text>\n </template>\n </wx-table>\n </div>\n\n <div v-else-if=\"step === 'run' && run\" class=\"wx-catalog-landings-generate\">\n <template v-if=\"!finished\">\n <wx-text>{{ t('generate.running') }}</wx-text>\n <wx-progress :value=\"run.done + run.failed\" :max=\"Math.max(1, run.total - run.skipped)\" />\n </template>\n <wx-alert v-else :type=\"run.status === 'failed' ? 'danger' : 'success'\">\n {{\n run.status === 'failed'\n ? t('generate.failed')\n : t('generate.done', { done: run.done, skipped: run.skipped, failed: run.failed })\n }}\n </wx-alert>\n <ul v-if=\"run.errors.length > 0\" class=\"wx-catalog-landings-generate__errors\">\n <li v-for=\"(one, index) in run.errors\" :key=\"index\">\n <strong>/{{ one.slug }}/</strong> — {{ one.message }}\n </li>\n </ul>\n </div>\n\n <template #footer>\n <wx-space size=\"sm\">\n <template v-if=\"step === 'form'\">\n <wx-button variant=\"outline\" @click=\"close\">{{ t('panel.cancel') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"busy\" :disabled=\"!ready\" @click=\"toPreview\">\n {{ t('generate.preview') }}\n </wx-button>\n </template>\n <template v-else-if=\"step === 'preview'\">\n <wx-button variant=\"outline\" @click=\"step = 'form'\">{{ t('generate.back') }}</wx-button>\n <wx-button\n type=\"primary\"\n :loading=\"busy\"\n :disabled=\"(preview?.free ?? 0) === 0\"\n @click=\"start\"\n >\n {{ t('generate.run', { count: preview?.free ?? 0 }) }}\n </wx-button>\n </template>\n <wx-button v-else type=\"primary\" :disabled=\"!finished\" @click=\"close\">\n {{ t('generate.close') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-catalog-landings-generate {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-catalog-landings-generate__mono {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-catalog-landings-generate__errors {\n margin: 0;\n padding-inline-start: var(--wx-space-16);\n font-size: var(--wx-font-size-sm);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useRoute, useRouter, type LocationQueryRaw } from 'vue-router'\nimport {\n confirm,\n createModal,\n toast,\n useLocales,\n localizedValue,\n WxBadge,\n WxButton,\n WxFormItem,\n WxIcon,\n WxSwitch,\n WxTable,\n WxText,\n WxTooltip,\n WxTreeSelect,\n type TableColumn,\n type TableState,\n type TreeSelectValue,\n} from '@webx-ui/core'\nimport {\n rowMenuWidth,\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxFilterChips,\n WxListScreen,\n WxRowMenu,\n type AppliedFilter,\n type RowAction,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport { useCategoryTree, type CategoryNode } from '@webx-ui/module-catalog'\nimport { createLandingsApi } from './api'\nimport GenerateDialog from './GenerateDialog.vue'\nimport { NAMESPACE, useCatalogLandingsMessages } from './i18n'\nimport type { GenerateRun, LandingQuery, LandingRow, LandingsPage } from './types'\n\n/**\n * The landings (§8.1 of the landings spec): name and address, the base, the set as chips, the\n * products, the state and the mark of attention; filtered by the base as a tree (the whole\n * catalogue is a choice of its own), «needs attention», published, empty, the bin; searched by\n * name and address. The filters live in the address, so coming back from a landing lands where\n * the list was left.\n */\ndefineOptions({ name: 'WxCatalogLandingsPage' })\n\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/catalog' })\n\n/** The base filter's value for «the whole catalogue», beside the categories' ids. */\nconst ROOT = 'root'\n\nconst admin = useAdmin()\nconst api = createLandingsApi(admin)\nconst tree = useCategoryTree(admin)\nconst route = useRoute()\nconst router = useRouter()\nconst locales = useLocales()\nuseCatalogLandingsMessages()\n\nconst t = useTranslate(NAMESPACE)\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\n\nconst generate = createModal<GenerateRun | null, { base: string }>(GenerateDialog)\n\nconst list = computed(() => `${props.base}/landings`)\nconst canManage = computed(() => admin.can('catalog.manage'))\n\nconst page = ref<LandingsPage | null>(null)\nconst loading = ref(true)\n\nconst flag = (key: string) => route.query[key] === '1'\n\nconst search = ref(String(route.query.q ?? ''))\nconst pageNumber = ref(Number(route.query.page ?? 1) || 1)\nconst chosenBase = ref<string | null>(route.query.category ? String(route.query.category) : null)\nconst attention = ref(flag('attention'))\nconst published = ref(flag('published'))\nconst empty = ref(flag('empty'))\nconst trashed = ref(flag('trashed'))\nlet perPage = 25\n\nconst title = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'catalog-landings')?.title ??\n t('module.title'),\n)\n\n/** The tree of categories with «the whole catalogue» on top of it. */\nconst baseNodes = computed<CategoryNode[]>(() => [\n {\n id: ROOT as unknown as number,\n name: t('landing.whole-catalog'),\n parent_id: null,\n children: [],\n } as unknown as CategoryNode,\n ...(tree.nodes.value ?? []),\n])\n\nconst baseName = computed(() => {\n if (chosenBase.value === null) return ''\n if (chosenBase.value === ROOT) return t('landing.whole-catalog')\n\n const find = (nodes: CategoryNode[]): string =>\n nodes.reduce<string>(\n (found, node) =>\n found || (String(node.id) === chosenBase.value ? node.name : find(node.children ?? [])),\n '',\n )\n\n return find(tree.nodes.value ?? []) || `#${chosenBase.value}`\n})\n\nconst applied = computed<AppliedFilter[]>(() => {\n const chips: AppliedFilter[] = []\n\n if (chosenBase.value !== null) {\n chips.push({\n key: 'base',\n label: `${t('panel.filter-base')}: ${baseName.value}`,\n clear: () => (chosenBase.value = null),\n })\n }\n\n for (const [key, on, word] of [\n ['attention', attention, 'panel.filter-attention'],\n ['published', published, 'panel.filter-published'],\n ['empty', empty, 'panel.filter-empty'],\n ['trashed', trashed, 'panel.filter-trashed'],\n ] as const) {\n if (on.value) chips.push({ key, label: t(word), clear: () => (on.value = false) })\n }\n\n return chips\n})\n\nfunction clearFilters(): void {\n chosenBase.value = null\n attention.value = false\n published.value = false\n empty.value = false\n trashed.value = false\n}\n\nfunction query(state?: TableState): LandingQuery {\n return {\n q: state?.search ?? search.value,\n category: chosenBase.value ?? undefined,\n attention: attention.value || undefined,\n published: published.value || undefined,\n empty: empty.value || undefined,\n trashed: trashed.value || undefined,\n page: state?.page ?? pageNumber.value,\n per_page: state?.perPage ?? perPage,\n }\n}\n\nlet asked = 0\n\nasync function load(state?: TableState): Promise<void> {\n const mine = ++asked\n\n loading.value = true\n\n try {\n const answer = await api.list(query(state))\n\n if (mine === asked) page.value = answer\n } catch (error) {\n toast.danger(message(error))\n } finally {\n if (mine === asked) loading.value = false\n }\n}\n\nfunction remember(): void {\n const wanted: LocationQueryRaw = {}\n const q = query()\n\n if (q.q) wanted.q = q.q\n if (q.category) wanted.category = q.category\n if (q.page && q.page > 1) wanted.page = String(q.page)\n\n for (const key of ['attention', 'published', 'empty', 'trashed'] as const) {\n if (q[key]) wanted[key] = '1'\n }\n\n void router.replace({ query: wanted })\n}\n\nfunction onState(state: TableState): void {\n perPage = state.perPage\n void load(state)\n}\n\nwatch([chosenBase, attention, published, empty, trashed], () => {\n pageNumber.value = 1\n remember()\n void load()\n})\n\nwatch([search, pageNumber], remember)\n\nconst columns = computed<TableColumn<LandingRow>[]>(() => [\n { key: 'name', label: t('panel.column-name'), minWidth: 220 },\n { key: 'category', label: t('panel.column-base'), width: 180, hideBelow: 760 },\n { key: 'chips', label: t('panel.column-set'), minWidth: 180, hideBelow: 640 },\n { key: 'products_count', label: t('panel.column-count'), width: 110, align: 'right' },\n { key: 'state', label: t('panel.column-state'), width: 170, hideBelow: 900 },\n { key: 'updated_at', label: t('panel.column-updated'), width: 130, hideBelow: 1180 },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst nameOf = (row: LandingRow) =>\n localizedValue(row.name, locales.active.value, '') || `#${row.id}`\nconst slugOf = (row: LandingRow) => localizedValue(row.slug, locales.active.value, '')\n\nfunction open(row: LandingRow): void {\n void router.push(`${list.value}/${row.id}`)\n}\n\nasync function publish(row: LandingRow, on: boolean): Promise<void> {\n try {\n await api.publish(row.id, on)\n toast.success(t(on ? 'panel.published-toast' : 'panel.unpublished-toast'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(row: LandingRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-title', { name: nameOf(row) }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(row.id)\n toast.success(t('panel.deleted'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(row: LandingRow): Promise<void> {\n try {\n await api.restore(row.id)\n toast.success(t('panel.restored'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction actionsFor(row: LandingRow): RowAction[] {\n if (row.deleted_at !== null) {\n return canManage.value\n ? [\n {\n key: 'restore',\n icon: 'refresh',\n label: t('panel.restore'),\n run: () => void restore(row),\n },\n ]\n : []\n }\n\n const actions: RowAction[] = [\n { key: 'open', icon: 'edit', label: t('panel.open'), run: () => open(row) },\n ]\n\n if (row.url)\n actions.push({ key: 'site', icon: 'link', label: t('panel.open-site'), href: row.url })\n\n if (canManage.value) {\n actions.push(\n row.is_published\n ? {\n key: 'unpublish',\n icon: 'eye-off',\n label: t('panel.unpublish'),\n run: () => void publish(row, false),\n }\n : {\n key: 'publish',\n icon: 'eye',\n label: t('panel.publish'),\n run: () => void publish(row, true),\n },\n {\n key: 'delete',\n icon: 'trash',\n label: t('panel.delete'),\n danger: true,\n run: () => void remove(row),\n },\n )\n }\n\n return actions\n}\n\nasync function bulk(): Promise<void> {\n const run = await generate({ base: props.base })\n\n if (run) await load()\n}\n\nconst actions = computed<ScreenAction[]>(() =>\n canManage.value\n ? [\n {\n key: 'new',\n label: t('panel.new'),\n icon: 'plus',\n primary: true,\n run: () =>\n void router.push({\n path: `${list.value}/new`,\n query:\n chosenBase.value && chosenBase.value !== ROOT ? { category: chosenBase.value } : {},\n }),\n },\n { key: 'generate', label: t('panel.generate'), icon: 'grid', run: () => void bulk() },\n ]\n : [],\n)\n\nconst emptyText = computed(() =>\n applied.value.length > 0 || search.value ? t('panel.nothing-found') : t('panel.empty'),\n)\n\nonMounted(() => {\n void tree.load().catch(() => undefined)\n})\n</script>\n\n<template>\n <div class=\"wx-catalog-landings\">\n <wx-list-screen :title=\"title\" :actions=\"actions\">\n <wx-table\n v-model:search=\"search\"\n v-model:page=\"pageNumber\"\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n clickable\n hover\n flush\n :loading=\"loading\"\n layout=\"fixed\"\n :filters-count=\"applied.length\"\n :filters-label=\"panel('filters.title')\"\n :search-placeholder=\"t('panel.search')\"\n :empty-text=\"emptyText\"\n :aria-label=\"title\"\n @row-click=\"open\"\n @state-change=\"onState\"\n >\n <template #filters>\n <wx-form-item :label=\"t('panel.filter-base')\">\n <wx-tree-select\n :model-value=\"chosenBase\"\n :nodes=\"baseNodes\"\n node-key=\"id\"\n label-key=\"name\"\n children-key=\"children\"\n check-strictly\n filterable\n clearable\n size=\"sm\"\n @update:model-value=\"\n (picked: TreeSelectValue) =>\n (chosenBase =\n picked === null || picked === undefined || Array.isArray(picked)\n ? null\n : String(picked))\n \"\n />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"attention\" size=\"sm\" :label=\"t('panel.filter-attention')\" />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"published\" size=\"sm\" :label=\"t('panel.filter-published')\" />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"empty\" size=\"sm\" :label=\"t('panel.filter-empty')\" />\n </wx-form-item>\n <wx-form-item>\n <wx-switch v-model=\"trashed\" size=\"sm\" :label=\"t('panel.filter-trashed')\" />\n </wx-form-item>\n\n <wx-button v-if=\"applied.length > 0\" variant=\"text\" size=\"sm\" block @click=\"clearFilters\">\n <template #icon><wx-icon name=\"close\" /></template>\n {{ panel('filters.reset') }}\n </wx-button>\n </template>\n\n <template #applied>\n <wx-filter-chips :filters=\"applied\" />\n </template>\n\n <template #cell-name=\"{ row }\">\n <div class=\"wx-catalog-landings__name\">\n <span class=\"wx-catalog-landings__title\">{{ nameOf(row) }}</span>\n <span class=\"wx-catalog-landings__slug\">/{{ slugOf(row) }}/</span>\n </div>\n </template>\n\n <template #cell-category=\"{ row }\">\n <wx-text size=\"sm\" truncate :tone=\"row.category === null ? 'muted' : undefined\">\n {{ row.category ?? t('landing.whole-catalog') }}\n </wx-text>\n </template>\n\n <template #cell-chips=\"{ row }\">\n <div class=\"wx-catalog-landings__chips\">\n <wx-badge v-for=\"chip in row.chips\" :key=\"chip.key\" size=\"sm\" variant=\"soft\">\n {{ chip.label }}: {{ chip.text }}\n </wx-badge>\n </div>\n </template>\n\n <template #cell-products_count=\"{ row }\">\n <wx-text v-if=\"row.products_count === null\" size=\"sm\" tone=\"muted\">\n {{ t('panel.not-counted') }}\n </wx-text>\n <wx-badge v-else-if=\"row.products_count === 0\" type=\"warning\" size=\"sm\" round>0</wx-badge>\n <span v-else class=\"wx-catalog-landings__count\">{{ row.products_count }}</span>\n </template>\n\n <template #cell-state=\"{ row }\">\n <div class=\"wx-catalog-landings__state\">\n <wx-badge v-if=\"row.deleted_at\" dot size=\"sm\">{{ t('panel.in-bin') }}</wx-badge>\n <wx-badge v-else :type=\"row.is_published ? 'success' : 'default'\" dot size=\"sm\">\n {{ t(row.is_published ? 'panel.published' : 'panel.unpublished') }}\n </wx-badge>\n <wx-tooltip v-if=\"row.attention\" :content=\"t(`landing.attention-${row.attention}`)\">\n <wx-badge type=\"warning\" size=\"sm\" round>\n <wx-icon name=\"warning\" size=\"sm\" />\n <span class=\"wx-catalog-landings__sr\">{{ t('landing.attention') }}</span>\n </wx-badge>\n </wx-tooltip>\n </div>\n </template>\n\n <template #cell-updated_at=\"{ row }\">\n <wx-date :value=\"row.updated_at\" compact />\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"nameOf(row)\" />\n </template>\n </wx-table>\n </wx-list-screen>\n </div>\n</template>\n\n<style scoped>\n.wx-catalog-landings {\n min-width: 0;\n}\n\n.wx-catalog-landings__name {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-catalog-landings__title,\n.wx-catalog-landings__slug {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.wx-catalog-landings__slug {\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-catalog-landings__chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n}\n\n.wx-catalog-landings__count {\n font-variant-numeric: tabular-nums;\n}\n\n.wx-catalog-landings__state {\n display: flex;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-catalog-landings__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n</style>\n","import type { AdminModule } from '@webx-ui/module-admin'\nimport LandingEditorPage from './LandingEditorPage.vue'\nimport LandingProductsField from './LandingProductsField.vue'\nimport LandingSetField from './LandingSetField.vue'\nimport LandingSlugField from './LandingSlugField.vue'\nimport LandingSortField from './LandingSortField.vue'\nimport LandingsPage from './LandingsPage.vue'\n\nexport interface CatalogLandingsOptions {\n /** Where the catalogue lives inside the panel — the same as `catalog({ path })`. */\n path?: string\n}\n\n/**\n * Landings as a section of the panel (§8 of the landings spec): the list with its filters and\n * «Create in bulk», and the page of one — new at `…/landings/new` — which is the server's\n * `catalog.landing-form`. «Catalog» → «Landings» after «Brands» on the server's side (order 303).\n *\n * The node types are the parts of that form a plain field cannot be: the set builder with its\n * live count, the address with the set's suggestion, the default sort out of the catalogue's\n * registry, and the recommended products found and put in order.\n */\nexport function catalogLandings(options: CatalogLandingsOptions = {}): AdminModule[] {\n const catalog = options.path ?? '/catalog'\n const props = { base: catalog }\n\n return [\n {\n id: 'catalog-landings',\n path: `${catalog}/landings`,\n routes: [\n {\n path: `${catalog}/landings`,\n name: 'webx.catalog-landings',\n component: LandingsPage,\n props,\n },\n {\n path: `${catalog}/landings/new`,\n name: 'webx.catalog-landings.new',\n component: LandingEditorPage,\n props,\n },\n {\n path: `${catalog}/landings/:id(\\\\d+)`,\n name: 'webx.catalog-landings.edit',\n component: LandingEditorPage,\n props,\n },\n ],\n types: {\n // Wide: a facet's row is a label, a list of values and a button, and half a form is too\n // narrow for a combobox of brands beside its label.\n 'wx-catalog-landing-set': { component: LandingSetField, kind: 'field', wide: true },\n 'wx-catalog-landing-slug': { component: LandingSlugField, kind: 'field' },\n 'wx-catalog-landing-sort': { component: LandingSortField, kind: 'field' },\n 'wx-catalog-landing-products': {\n component: LandingProductsField,\n kind: 'field',\n wide: true,\n },\n },\n },\n ]\n}\n"],"names":["LANDINGS_API","landingSearch","query","search","key","value","createLandingsApi","admin","base","data","body","id","values","on","categoryId","filters","except","params","FORM_FIELDS","formValues","detail","field","cleanSet","clean","choice","landingEditorKey","provideLandingEditor","context","provide","useLandingEditor","inject","catalogLandingsMessages","NAMESPACE","seeded","useCatalogLandingsMessages","i18n","useAdmin","props","__props","api","route","useRoute","router","useRouter","locales","useLocales","useTranslate","message","useErrorText","list","computed","creating","landing","ref","snapshot","suggested","loading","saving","errors","canManage","trashed","locked","current","dirty","state","section","module","title","written","localizedValue","subtitle","row","provideHistorySubject","take","blank","load","error","toast","payload","save","created","publish","answer","remove","confirm","restore","leaveGuard","event","onKeydown","useBodyKeys","watch","next","previous","onMounted","onBeforeUnmount","onBeforeRouteLeave","actions","leads","_createElementBlock","_Fragment","_createVNode","_unref","WxSkeleton","WxCard","WxScreenHead","WxBreadcrumb","WxBreadcrumbItem","_createBlock","WxBadge","WxAlert","WxScreen","$event","WxActionBar","WxSaveState","WxButton","_createTextVNode","_toDisplayString","_useModel","catalog","createCatalogApi","editor","t","known","items","item","term","options","searching","failed","asked","q","ticket","page","taken","product","pick","option","drop","one","_openBlock","_hoisted_1","WxAutocomplete","WxText","WxSortableList","_withCtx","_createElementVNode","_hoisted_2","_hoisted_3","WxIcon","category","offered","loadFailed","set","facetOf","facet","adding","loadFacets","isRange","write","add","valuesOf","rangeOf","optionsOf","chosen","word","chipWord","chip","picked","bound","end","range","labelOf","counted","counting","countFailed","timer","countTicket","question","count","takenLink","_renderList","WxInputNumber","WxSelect","_hoisted_4","WxLink","RouterLink","record","suggestion","locale","slug","use","active","WxInput","_cache","NONE","registry","useFacetRegistry","sort","open","resolve","useModal","tree","useCategoryTree","step","categories","subtree","minProducts","templates","facets","failure","busy","preview","run","first","facetOptions","valueOptions","ready","refuse","toPreview","poll","delay","start","finished","close","columns","rows","index","WxDialog","WxSpace","WxFormItem","WxTreeSelect","WxSwitch","WxTable","WxProgress","_hoisted_5","ROOT","panel","generate","createModal","GenerateDialog","flag","pageNumber","chosenBase","attention","published","empty","perPage","baseNodes","baseName","find","nodes","found","node","applied","chips","clearFilters","mine","remember","wanted","onState","rowMenuWidth","nameOf","slugOf","actionsFor","bulk","emptyText","WxListScreen","WxFilterChips","_hoisted_6","_hoisted_7","WxTooltip","_hoisted_8","WxDate","WxRowMenu","catalogLandings","LandingsPage","LandingEditorPage","LandingSetField","LandingSlugField","LandingSortField","LandingProductsField"],"mappings":"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"}
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .wx-catalog-landing-editor[data-v-0d735844]{display:flex;flex-direction:column;gap:var(--wx-gap, var(--wx-space-16));container-type:inline-size}.wx-catalog-landing-editor__ghost[data-v-0d735844]{max-width:420px}.wx-catalog-landing-products[data-v-e1b47273]{display:flex;flex-direction:column;gap:var(--wx-space-8);min-width:0}.wx-catalog-landing-products__item[data-v-e1b47273]{display:flex;align-items:baseline;gap:var(--wx-space-8);min-width:0}.wx-catalog-landing-products__name[data-v-e1b47273]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-catalog-landing-set[data-v-899dfed0]{display:flex;flex-direction:column;gap:var(--wx-space-8);container-type:inline-size;min-width:0}.wx-catalog-landing-set__row[data-v-899dfed0]{display:grid;grid-template-columns:minmax(96px,160px) minmax(0,1fr) auto;align-items:center;gap:var(--wx-space-8)}.wx-catalog-landing-set__range[data-v-899dfed0]{display:grid;grid-template-columns:1fr 1fr;gap:var(--wx-space-8)}.wx-catalog-landing-set__foot[data-v-899dfed0]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-12)}.wx-catalog-landing-set__add[data-v-899dfed0]{width:240px;max-width:100%}@container (max-width: 480px){.wx-catalog-landing-set__row[data-v-899dfed0]{grid-template-columns:minmax(0,1fr) auto}.wx-catalog-landing-set__label[data-v-899dfed0]{grid-column:1 / -1}}.wx-catalog-landing-slug[data-v-b1f93497]{display:flex;flex-direction:column;gap:var(--wx-space-4);min-width:0}.wx-catalog-landing-slug__hint[data-v-b1f93497]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-8)}.wx-catalog-landings-generate[data-v-9deeece3]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-catalog-landings-generate__mono[data-v-9deeece3]{font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-sm)}.wx-catalog-landings-generate__errors[data-v-9deeece3]{margin:0;padding-inline-start:var(--wx-space-16);font-size:var(--wx-font-size-sm)}.wx-catalog-landings[data-v-3465bf8b]{min-width:0}.wx-catalog-landings__name[data-v-3465bf8b]{display:flex;flex-direction:column;min-width:0}.wx-catalog-landings__title[data-v-3465bf8b],.wx-catalog-landings__slug[data-v-3465bf8b]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-catalog-landings__slug[data-v-3465bf8b]{color:var(--wx-text-muted);font-size:var(--wx-font-size-sm)}.wx-catalog-landings__chips[data-v-3465bf8b]{display:flex;flex-wrap:wrap;gap:var(--wx-space-4)}.wx-catalog-landings__count[data-v-3465bf8b]{font-variant-numeric:tabular-nums}.wx-catalog-landings__state[data-v-3465bf8b]{display:flex;align-items:center;gap:var(--wx-space-6)}.wx-catalog-landings__sr[data-v-3465bf8b]{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
1
+ .wx-catalog-landing-editor[data-v-0d735844]{display:flex;flex-direction:column;gap:var(--wx-gap, var(--wx-space-16));container-type:inline-size}.wx-catalog-landing-editor__ghost[data-v-0d735844]{max-width:420px}.wx-catalog-landing-products[data-v-e1b47273]{display:flex;flex-direction:column;gap:var(--wx-space-8);min-width:0}.wx-catalog-landing-products__item[data-v-e1b47273]{display:flex;align-items:baseline;gap:var(--wx-space-8);min-width:0}.wx-catalog-landing-products__name[data-v-e1b47273]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-catalog-landing-set[data-v-899dfed0]{display:flex;flex-direction:column;gap:var(--wx-space-8);container-type:inline-size;min-width:0}.wx-catalog-landing-set__row[data-v-899dfed0]{display:grid;grid-template-columns:minmax(96px,160px) minmax(0,1fr) auto;align-items:center;gap:var(--wx-space-8)}.wx-catalog-landing-set__range[data-v-899dfed0]{display:grid;grid-template-columns:1fr 1fr;gap:var(--wx-space-8)}.wx-catalog-landing-set__foot[data-v-899dfed0]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-12)}.wx-catalog-landing-set__add[data-v-899dfed0]{width:240px;max-width:100%}@container (max-width: 480px){.wx-catalog-landing-set__row[data-v-899dfed0]{grid-template-columns:minmax(0,1fr) auto}.wx-catalog-landing-set__label[data-v-899dfed0]{grid-column:1 / -1}}.wx-catalog-landing-slug[data-v-b1f93497]{display:flex;flex-direction:column;gap:var(--wx-space-4);min-width:0}.wx-catalog-landing-slug__hint[data-v-b1f93497]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-8)}.wx-catalog-landings-generate[data-v-9deeece3]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-catalog-landings-generate__mono[data-v-9deeece3]{font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-sm)}.wx-catalog-landings-generate__errors[data-v-9deeece3]{margin:0;padding-inline-start:var(--wx-space-16);font-size:var(--wx-font-size-sm)}.wx-catalog-landings[data-v-eccbf1d9]{min-width:0}.wx-catalog-landings__name[data-v-eccbf1d9]{display:flex;flex-direction:column;min-width:0}.wx-catalog-landings__title[data-v-eccbf1d9],.wx-catalog-landings__slug[data-v-eccbf1d9]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-catalog-landings__slug[data-v-eccbf1d9]{color:var(--wx-text-muted);font-size:var(--wx-font-size-sm)}.wx-catalog-landings__chips[data-v-eccbf1d9]{display:flex;flex-wrap:wrap;gap:var(--wx-space-4)}.wx-catalog-landings__count[data-v-eccbf1d9]{font-variant-numeric:tabular-nums}.wx-catalog-landings__state[data-v-eccbf1d9]{display:flex;align-items:center;gap:var(--wx-space-6)}.wx-catalog-landings__sr[data-v-eccbf1d9]{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webx-ui/module-catalog-landings",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Landing pages for the catalogue of the WebX UI admin panel: a category list with filters chosen in advance under an address, texts and SEO of its own, the set builder with a live count, recommended products, and creating landings in bulk.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,10 +46,10 @@
46
46
  "vue-router": "^4.5.0"
47
47
  },
48
48
  "dependencies": {
49
- "@webx-ui/core": "^0.37.0",
50
- "@webx-ui/module-admin": "^0.23.2",
51
- "@webx-ui/module-catalog": "^0.8.2",
52
- "@webx-ui/schema": "^0.7.3"
49
+ "@webx-ui/core": "^0.38.0",
50
+ "@webx-ui/module-admin": "^0.23.5",
51
+ "@webx-ui/module-catalog": "^0.8.3",
52
+ "@webx-ui/schema": "^0.8.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/node": "^24.10.1",