@webx-ui/module-catalog-landings 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { defineComponent as re, computed as r, ref as d, watch as ue, onMounted
2
2
  import { useRoute as ce, useRouter as de, onBeforeRouteLeave as ve } from "vue-router";
3
3
  import { useLocales as fe, localizedValue as pe, confirm as H, WxSkeleton as I, WxCard as ge, WxBreadcrumb as me, WxBreadcrumbItem as U, WxBadge as F, WxAlert as ye, WxActionBar as be, WxButton as we, toast as s } from "@webx-ui/core";
4
4
  import { useAdmin as he, useTranslate as _e, useErrorText as ke, provideHistorySubject as xe, useBodyKeys as Se, WxScreenHead as Be, WxScreen as We, WxSaveState as Le } from "@webx-ui/module-admin";
5
- import { c as Ee, u as Ne, N as Ce, p as Ve, f as Te, a as Ae, _ as Ke } from "./index-DEreqbgG.js";
5
+ import { c as Ee, u as Ne, N as Ce, p as Ve, f as Te, a as Ae, _ as Ke } from "./index-CL_q1v5T.js";
6
6
  const Me = /* @__PURE__ */ re({
7
7
  name: "WxCatalogLandingEditor",
8
8
  __name: "LandingEditorPage",
@@ -289,4 +289,4 @@ const Me = /* @__PURE__ */ re({
289
289
  export {
290
290
  Je as default
291
291
  };
292
- //# sourceMappingURL=LandingEditorPage-Dt1xmQXl.js.map
292
+ //# sourceMappingURL=LandingEditorPage-sarEsyTC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LandingEditorPage-Dt1xmQXl.js","sources":["../src/LandingEditorPage.vue"],"sourcesContent":["<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"],"names":["props","__props","admin","useAdmin","api","createLandingsApi","route","useRoute","router","useRouter","locales","useLocales","useCatalogLandingsMessages","t","useTranslate","NAMESPACE","message","useErrorText","list","computed","creating","id","landing","ref","values","snapshot","suggested","loading","saving","errors","canManage","trashed","locked","current","dirty","state","section","module","title","written","localizedValue","subtitle","row","provideLandingEditor","provideHistorySubject","take","detail","formValues","blank","load","error","toast","payload","cleanSet","save","created","body","publish","on","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"],"mappings":"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"}
1
+ {"version":3,"file":"LandingEditorPage-sarEsyTC.js","sources":["../src/LandingEditorPage.vue"],"sourcesContent":["<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"],"names":["props","__props","admin","useAdmin","api","createLandingsApi","route","useRoute","router","useRouter","locales","useLocales","useCatalogLandingsMessages","t","useTranslate","NAMESPACE","message","useErrorText","list","computed","creating","id","landing","ref","values","snapshot","suggested","loading","saving","errors","canManage","trashed","locked","current","dirty","state","section","module","title","written","localizedValue","subtitle","row","provideLandingEditor","provideHistorySubject","take","detail","formValues","blank","load","error","toast","payload","cleanSet","save","created","body","publish","on","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"],"mappings":"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"}