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

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.
@@ -0,0 +1,292 @@
1
+ import { defineComponent as re, computed as r, ref as d, watch as ue, onMounted as oe, onBeforeUnmount as se, openBlock as v, createElementBlock as A, Fragment as R, createVNode as i, unref as l, withCtx as u, createSlots as ie, createTextVNode as m, toDisplayString as y, createBlock as N, createCommentVNode as q } from "vue";
2
+ import { useRoute as ce, useRouter as de, onBeforeRouteLeave as ve } from "vue-router";
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
+ 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";
6
+ const Me = /* @__PURE__ */ re({
7
+ name: "WxCatalogLandingEditor",
8
+ __name: "LandingEditorPage",
9
+ props: {
10
+ base: { default: "/catalog" }
11
+ },
12
+ setup(G) {
13
+ const Q = G, C = he(), f = Ee(C), b = ce(), V = de(), X = fe();
14
+ Ne();
15
+ const a = _e(Ce), w = ke(), p = r(() => `${Q.base}/landings`), h = r(() => b.params.id === void 0 || b.params.id === "new"), _ = r(() => h.value ? null : Number(b.params.id)), n = d(null), o = d({}), k = d(""), Y = d({}), B = d(!0), g = d(!1), W = d({}), x = r(() => C.can("catalog.manage")), L = r(() => (n.value?.deleted_at ?? null) !== null), K = r(() => !x.value || g.value || L.value), M = r(() => JSON.stringify(o.value)), S = r(() => k.value !== "" && M.value !== k.value), Z = r(() => g.value ? "saving" : S.value || h.value ? "unsaved" : "saved"), O = r(
16
+ () => C.state.manifest?.modules.find((e) => e.id === "catalog-landings")?.title ?? a("module.title")
17
+ ), T = r(() => {
18
+ const e = o.value.name;
19
+ return pe(e, X.active.value, "") || a("panel.untitled");
20
+ }), ee = r(() => {
21
+ const e = n.value;
22
+ if (e)
23
+ return [e.category ?? a("landing.whole-catalog"), e.url ?? ""].filter(Boolean).join(" · ");
24
+ });
25
+ Ve({ landing: n, values: o, locked: K, suggested: Y, list: p.value }), xe({ id: r(() => n.value?.id ?? null) });
26
+ function E(e) {
27
+ n.value = e, o.value = Te(e), k.value = JSON.stringify(o.value);
28
+ }
29
+ function ae() {
30
+ n.value = null, o.value = {
31
+ category_id: b.query.category ? Number(b.query.category) : null,
32
+ filters: {},
33
+ name: {},
34
+ slug: {},
35
+ h1: {},
36
+ text_above: {},
37
+ text_below: {},
38
+ sort: null,
39
+ on_category: !1,
40
+ position: 0,
41
+ recommended: [],
42
+ seo: {}
43
+ }, k.value = JSON.stringify(o.value);
44
+ }
45
+ async function $() {
46
+ if (W.value = {}, _.value === null) {
47
+ ae(), B.value = !1;
48
+ return;
49
+ }
50
+ B.value = !0;
51
+ try {
52
+ E(await f.get(_.value));
53
+ } catch (e) {
54
+ s.danger(w(e)), V.push(p.value);
55
+ } finally {
56
+ B.value = !1;
57
+ }
58
+ }
59
+ function j() {
60
+ return { ...o.value, filters: Ae(o.value.filters) };
61
+ }
62
+ async function z() {
63
+ if (!(g.value || !x.value)) {
64
+ g.value = !0, W.value = {};
65
+ try {
66
+ if (_.value === null) {
67
+ const e = await f.create(j());
68
+ E(e), s.success(a("panel.created")), await V.replace(`${p.value}/${e.id}`);
69
+ } else
70
+ E(await f.save(_.value, j())), s.success(a("panel.saved"));
71
+ } catch (e) {
72
+ const t = e.body;
73
+ t?.errors && Object.keys(t.errors).length > 0 ? (W.value = t.errors, s.danger(a("panel.save-failed"))) : s.danger(w(e));
74
+ } finally {
75
+ g.value = !1;
76
+ }
77
+ }
78
+ }
79
+ async function D(e) {
80
+ const t = n.value;
81
+ if (t)
82
+ try {
83
+ const c = await f.publish(t.id, e);
84
+ n.value = { ...t, ...c }, s.success(a(e ? "panel.published-toast" : "panel.unpublished-toast"));
85
+ } catch (c) {
86
+ s.danger(w(c));
87
+ }
88
+ }
89
+ async function te() {
90
+ const e = n.value;
91
+ if (!(!e || !await H({
92
+ title: a("panel.delete-title", { name: T.value }),
93
+ message: a("panel.delete-text"),
94
+ confirmText: a("panel.delete"),
95
+ cancelText: a("panel.cancel"),
96
+ tone: "danger"
97
+ })))
98
+ try {
99
+ await f.remove(e.id), s.success(a("panel.deleted")), k.value = M.value, V.push(p.value);
100
+ } catch (c) {
101
+ s.danger(w(c));
102
+ }
103
+ }
104
+ async function le() {
105
+ const e = n.value;
106
+ if (e)
107
+ try {
108
+ E(await f.restore(e.id)), s.success(a("panel.restored"));
109
+ } catch (t) {
110
+ s.danger(w(t));
111
+ }
112
+ }
113
+ function J(e) {
114
+ S.value && e.preventDefault();
115
+ }
116
+ function P(e) {
117
+ (e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "s" && (e.preventDefault(), (S.value || h.value) && z());
118
+ }
119
+ Se(P), ue(_, (e, t) => {
120
+ t === null && e !== null && n.value?.id === e || $();
121
+ }), oe(() => {
122
+ $(), window.addEventListener("beforeunload", J);
123
+ }), se(() => {
124
+ window.removeEventListener("beforeunload", J);
125
+ }), ve(async () => !S.value || !x.value ? !0 : await H({
126
+ title: a("panel.leave-title"),
127
+ message: a("panel.leave-text"),
128
+ confirmText: a("panel.leave"),
129
+ cancelText: a("panel.cancel"),
130
+ tone: "danger"
131
+ }));
132
+ const ne = r(() => {
133
+ const e = n.value;
134
+ if (!e || !x.value) return [];
135
+ if (L.value)
136
+ return [
137
+ { key: "restore", label: a("panel.restore"), icon: "refresh", run: () => {
138
+ le();
139
+ } }
140
+ ];
141
+ const t = [];
142
+ return e.url && t.push({
143
+ key: "site",
144
+ label: a("panel.open-site"),
145
+ icon: "external-link",
146
+ run: () => {
147
+ window.open(e.url ?? "", "_blank", "noopener");
148
+ }
149
+ }), t.push(
150
+ e.is_published ? {
151
+ key: "unpublish",
152
+ label: a("panel.unpublish"),
153
+ icon: "eye-off",
154
+ run: () => {
155
+ D(!1);
156
+ }
157
+ } : { key: "publish", label: a("panel.publish"), icon: "eye", run: () => {
158
+ D(!0);
159
+ } },
160
+ {
161
+ key: "delete",
162
+ label: a("panel.delete"),
163
+ icon: "trash",
164
+ danger: !0,
165
+ menu: !0,
166
+ run: () => {
167
+ te();
168
+ }
169
+ }
170
+ ), t;
171
+ });
172
+ return (e, t) => (v(), A("div", {
173
+ class: "wx-catalog-landing-editor",
174
+ onKeydown: P
175
+ }, [
176
+ B.value ? (v(), A(R, { key: 0 }, [
177
+ i(l(I), {
178
+ class: "wx-catalog-landing-editor__ghost",
179
+ title: "",
180
+ rows: 1
181
+ }),
182
+ i(l(ge), null, {
183
+ default: u(() => [
184
+ i(l(I), { rows: 6 })
185
+ ]),
186
+ _: 1
187
+ })
188
+ ], 64)) : (v(), A(R, { key: 1 }, [
189
+ i(l(Be), {
190
+ divider: "",
191
+ back: p.value,
192
+ "back-label": O.value,
193
+ title: T.value,
194
+ subtitle: ee.value,
195
+ actions: ne.value
196
+ }, ie({
197
+ trail: u(() => [
198
+ i(l(me), {
199
+ size: "sm",
200
+ label: l(a)("panel.trail")
201
+ }, {
202
+ default: u(() => [
203
+ i(l(U), {
204
+ as: "router-link",
205
+ to: p.value
206
+ }, {
207
+ default: u(() => [
208
+ m(y(O.value), 1)
209
+ ]),
210
+ _: 1
211
+ }, 8, ["to"]),
212
+ i(l(U), { current: "" }, {
213
+ default: u(() => [
214
+ m(y(T.value), 1)
215
+ ]),
216
+ _: 1
217
+ })
218
+ ]),
219
+ _: 1
220
+ }, 8, ["label"])
221
+ ]),
222
+ _: 2
223
+ }, [
224
+ n.value ? {
225
+ name: "title-after",
226
+ fn: u(() => [
227
+ L.value ? (v(), N(l(F), {
228
+ key: 0,
229
+ dot: ""
230
+ }, {
231
+ default: u(() => [
232
+ m(y(l(a)("panel.in-bin")), 1)
233
+ ]),
234
+ _: 1
235
+ })) : (v(), N(l(F), {
236
+ key: 1,
237
+ type: n.value.is_published ? "success" : "default",
238
+ dot: "",
239
+ size: "sm"
240
+ }, {
241
+ default: u(() => [
242
+ m(y(l(a)(n.value.is_published ? "panel.published" : "panel.unpublished")), 1)
243
+ ]),
244
+ _: 1
245
+ }, 8, ["type"]))
246
+ ]),
247
+ key: "0"
248
+ } : void 0
249
+ ]), 1032, ["back", "back-label", "title", "subtitle", "actions"]),
250
+ n.value?.attention ? (v(), N(l(ye), {
251
+ key: 0,
252
+ type: "warning"
253
+ }, {
254
+ default: u(() => [
255
+ m(y(l(a)(`landing.attention-${n.value.attention}`)), 1)
256
+ ]),
257
+ _: 1
258
+ })) : q("", !0),
259
+ i(l(We), {
260
+ modelValue: o.value,
261
+ "onUpdate:modelValue": t[0] || (t[0] = (c) => o.value = c),
262
+ name: "catalog.landing-form",
263
+ errors: W.value,
264
+ disabled: K.value
265
+ }, null, 8, ["modelValue", "errors", "disabled"]),
266
+ x.value && !L.value ? (v(), N(l(be), { key: 1 }, {
267
+ state: u(() => [
268
+ i(l(Le), { state: Z.value }, null, 8, ["state"])
269
+ ]),
270
+ default: u(() => [
271
+ i(l(we), {
272
+ type: "primary",
273
+ loading: g.value,
274
+ disabled: !S.value && !h.value,
275
+ onClick: z
276
+ }, {
277
+ default: u(() => [
278
+ m(y(l(a)(h.value ? "panel.create" : "panel.save")), 1)
279
+ ]),
280
+ _: 1
281
+ }, 8, ["loading", "disabled"])
282
+ ]),
283
+ _: 1
284
+ })) : q("", !0)
285
+ ], 64))
286
+ ], 32));
287
+ }
288
+ }), Je = /* @__PURE__ */ Ke(Me, [["__scopeId", "data-v-0d735844"]]);
289
+ export {
290
+ Je as default
291
+ };
292
+ //# sourceMappingURL=LandingEditorPage-Dt1xmQXl.js.map
@@ -0,0 +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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"}