@webx-ui/module-catalog-properties 0.1.13 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1875 @@
1
+ import { defineComponent as ae, computed as S, ref as x, watch as ee, openBlock as d, createElementBlock as R, createBlock as I, unref as e, Fragment as oe, createVNode as M, withCtx as V, createTextVNode as G, toDisplayString as U, renderList as ye, createElementVNode as K, createCommentVNode as j, provide as Je, inject as ze, useModel as ke, onBeforeUnmount as Ee, mergeModels as Te, mergeProps as Qe, isRef as Be, useTemplateRef as Xe, onMounted as Ze, nextTick as qe, withKeys as Ne, normalizeStyle as ea, withModifiers as aa, h as ta, defineAsyncComponent as Fe } from "vue";
2
+ import { useAdmin as ie, useTranslate as se, useErrorText as ge, WxRowMenu as Ie, categoryRoutes as la } from "@webx-ui/module-admin";
3
+ import { localizedValue as oa, WxAlert as re, WxSkeleton as Ae, WxText as ne, WxSortableList as Re, WxButton as q, WxSelect as Ve, toast as te, WxAction as ra, WxInput as de, WxInputNumber as Ce, useLocales as De, WxTreeSelect as na, WxFormItem as fe, WxSwitch as sa, confirm as Le, useModal as je, WxDialog as Ge, WxSpace as Ke, WxColorPicker as ia, createModal as Me, WxTree as Ue } from "@webx-ui/core";
4
+ import { useCatalogCategoryEditor as ua, createCatalogApi as da, useProductEditor as ca } from "@webx-ui/module-catalog";
5
+ import { screenErrorsKey as pa } from "@webx-ui/schema";
6
+ import { openMediaPicker as va } from "@webx-ui/module-media";
7
+ const ma = "catalog/properties", fa = "catalog/property-groups", ga = "catalog/property-sets";
8
+ function ha(l) {
9
+ const a = new URLSearchParams();
10
+ l.q && a.set("q", l.q), l.type && a.set("type", l.type), l.group != null && a.set("group", String(l.group)), l.trashed && a.set("trashed", "1");
11
+ for (const n of l.ids ?? []) a.append("ids[]", String(n));
12
+ return l.page && l.page > 1 && a.set("page", String(l.page)), l.per_page && a.set("per_page", String(l.per_page)), a;
13
+ }
14
+ function ue(l) {
15
+ const a = `${l.apiPath}/${ma}`, n = (t) => t.data, y = (t, m) => m.size > 0 ? `${t}?${m}` : t;
16
+ return {
17
+ list: (t = {}) => l.http.get(y(a, ha({ per_page: 500, ...t }))),
18
+ get: (t) => l.http.get(`${a}/${t}`).then(n),
19
+ create: (t) => l.http.post(a, { values: t }).then(n),
20
+ save: (t, m) => l.http.put(`${a}/${t}`, { values: m }).then(n),
21
+ reorder: (t) => l.http.post(`${a}/reorder`, { ids: t }).then(() => {
22
+ }),
23
+ remove: (t) => l.http.delete(`${a}/${t}`).then(() => {
24
+ }),
25
+ restore: (t) => l.http.post(`${a}/${t}/restore`, {}).then(n),
26
+ saveIntervals: (t, m) => l.http.put(`${a}/${t}/intervals`, {
27
+ intervals: m.map(({ id: s, title: i, slug: p, min: C, max: h }) => ({
28
+ id: s ?? null,
29
+ title: i,
30
+ slug: p,
31
+ min: C,
32
+ max: h
33
+ }))
34
+ }).then(n),
35
+ values: (t, m = null) => {
36
+ const s = new URLSearchParams();
37
+ return m !== null && s.set("parent_id", String(m)), l.http.get(y(`${a}/${t}/values`, s)).then(n);
38
+ },
39
+ searchValues: (t, m, s = 50) => l.http.get(y(`${a}/${t}/values`, new URLSearchParams({ q: m, per_page: String(s) }))).then(n),
40
+ valuesById: (t, m) => {
41
+ if (m.length === 0) return Promise.resolve([]);
42
+ const s = new URLSearchParams();
43
+ for (const i of m) s.append("ids[]", String(i));
44
+ return l.http.get(y(`${a}/${t}/values`, s)).then(n);
45
+ },
46
+ createValue: (t, m) => l.http.post(`${a}/${t}/values`, m).then(n),
47
+ saveValue: (t, m, s) => l.http.put(`${a}/${t}/values/${m}`, s).then(n),
48
+ moveValue: (t, m, s, i) => l.http.post(`${a}/${t}/values/${m}/move`, {
49
+ parent_id: s,
50
+ before_id: i
51
+ }).then(n),
52
+ mergeValue: (t, m, s, i = !1) => l.http.post(`${a}/${t}/values/${m}/merge`, {
53
+ into: s,
54
+ dry_run: i
55
+ }).then((p) => p.data.moved),
56
+ removeValue: (t, m) => l.http.delete(`${a}/${t}/values/${m}`).then(() => {
57
+ }),
58
+ categorySet: (t) => l.http.get(`${l.apiPath}/catalog/categories/${t}/properties`).then(n),
59
+ saveCategorySet: (t, m) => l.http.put(`${l.apiPath}/catalog/categories/${t}/properties`, { ids: m }).then(n),
60
+ effectiveSet: (t) => l.http.get(`${l.apiPath}/${ga}/${t}`).then(n)
61
+ };
62
+ }
63
+ function Y(l, a, n = "") {
64
+ return l == null || Array.isArray(l) ? n : oa(l, a, n);
65
+ }
66
+ function Z(l, a) {
67
+ return Y(l.title, a) || Y(l.code, a) || `#${l.id}`;
68
+ }
69
+ function Ye(l, a, n) {
70
+ const y = Math.max(0, Math.min(6, Math.trunc(a.precision ?? 0)));
71
+ let t;
72
+ try {
73
+ t = new Intl.NumberFormat(n || void 0, {
74
+ minimumFractionDigits: y,
75
+ maximumFractionDigits: y
76
+ }).format(l);
77
+ } catch {
78
+ t = l.toFixed(y);
79
+ }
80
+ return `${a.prefix ?? ""}${t}${a.suffix ?? ""}`;
81
+ }
82
+ function ya(l) {
83
+ const a = Math.max(0, Math.min(6, Math.trunc(l ?? 0)));
84
+ return a === 0 ? 12 : Number(12.5.toFixed(Math.min(a, 1)));
85
+ }
86
+ function ba(l, a) {
87
+ const n = a === null ? 0 : String(a).split(".")[1]?.length ?? 0;
88
+ return Math.min(6, Math.max(l, n));
89
+ }
90
+ const _a = {
91
+ module: {
92
+ title: "Properties",
93
+ property: "Property",
94
+ group: "Property group",
95
+ value: "Property value"
96
+ },
97
+ property: {
98
+ "tab-main": "Main",
99
+ "tab-values": "Values",
100
+ "tab-intervals": "Intervals",
101
+ "tab-history": "History",
102
+ "card-values": "Values",
103
+ "card-filter": "Filter and search",
104
+ "card-showing": "Where it is shown",
105
+ title: "Name",
106
+ code: "Code",
107
+ "code-help": "Latin letters, digits and hyphens: the property in a filter address (color_black), per language. Made from the name when left empty.",
108
+ type: "Type",
109
+ "type-help": "Chosen once: the values of the products have its shape.",
110
+ types: {
111
+ select: "Reference book",
112
+ number: "Number",
113
+ text: "Text",
114
+ bool: "Yes / no"
115
+ },
116
+ group_id: "Group",
117
+ is_multiple: "Several values",
118
+ is_tree: "Values in a tree",
119
+ leaves_only: "Only the last level",
120
+ is_filterable: "In the filter",
121
+ filter_mode: "Filter by",
122
+ modes: {
123
+ slider: "Slider",
124
+ intervals: "Intervals"
125
+ },
126
+ is_indexable: "Pages of one value open to search engines",
127
+ is_searchable: "Search by value",
128
+ in_card: "On the card in the catalogue",
129
+ on_page: "In the specifications of the product",
130
+ in_list: "Column in the list of products",
131
+ value_order: "Order of values",
132
+ orders: {
133
+ alpha: "Alphabetical",
134
+ manual: "By hand"
135
+ },
136
+ has_color: "Values have a colour",
137
+ has_image: "Values have a picture",
138
+ unit_prefix: "Before the number",
139
+ unit_suffix: "After the number",
140
+ precision: "Digits after the point",
141
+ toggle_slug: "The word for «yes» in an address",
142
+ seo_pattern: "Page title pattern",
143
+ "seo-pattern-help": "{category}, {property} and {value} are replaced. Empty — the catalogue's own pattern."
144
+ },
145
+ value: {
146
+ title: "Name",
147
+ slug: "Slug",
148
+ color: "Colour",
149
+ image: "Picture",
150
+ merged: "Merged",
151
+ "merged-line": ":value, products: :count"
152
+ },
153
+ product: {
154
+ tab: "Specifications",
155
+ properties: "Properties",
156
+ property: "Property",
157
+ value: "Value",
158
+ yes: "Yes"
159
+ },
160
+ group: {
161
+ title: "Name",
162
+ is_visible: "Heading on the page",
163
+ "visible-help": "Off, the properties of the group stand in the specifications without its heading.",
164
+ new: "New group",
165
+ empty: "No groups yet.",
166
+ "empty-help": "A group is a heading of the specifications — «Screen», «Processor». A property without one stands last, without a heading.",
167
+ order: "The order here is the order of the headings in the specifications of a product",
168
+ hidden: "Heading not shown",
169
+ count: "Properties: :count",
170
+ "delete-blocked": "While properties are in this group it cannot go — move them to another first.",
171
+ "delete-text": "It goes to the bin.",
172
+ deleted: "The group is in the bin.",
173
+ saved: "The group is saved."
174
+ },
175
+ panel: {
176
+ "category-tab": "Properties",
177
+ new: "New property",
178
+ groups: "Groups",
179
+ "groups-title": "Groups of properties",
180
+ "view-all": "Properties",
181
+ "view-deleted": "Deleted",
182
+ "type-any": "Any type",
183
+ "group-any": "Any group",
184
+ empty: "No properties yet.",
185
+ "empty-help": "A property is what a product is described by — a colour, a weight, Wi-Fi — and, when it is in the filter, what the catalogue is narrowed by.",
186
+ "empty-found": "Nothing here.",
187
+ order: "The order here is the order of the filter's blocks, unless a category sets its own on its «Filters» tab.",
188
+ "order-narrowed": "The order is dragged on the whole list: clear the type and the group first.",
189
+ count: "Products: :count",
190
+ edit: "Edit",
191
+ delete: "Delete",
192
+ restore: "Restore",
193
+ cancel: "Cancel",
194
+ create: "Create",
195
+ save: "Save",
196
+ add: "Add",
197
+ search: "Search",
198
+ searching: "Searching…",
199
+ "nothing-found": "Nothing found",
200
+ "delete-title": "Delete «:name»?",
201
+ "delete-text": "It goes to «Deleted»: its filter and its old addresses go, the values of the products stay, and a restore brings everything back.",
202
+ deleted: "The property is in «Deleted».",
203
+ restored: "The property is back.",
204
+ "in-bin": "Deleted",
205
+ "reorder-failed": "The order was not saved.",
206
+ saved: "The property is saved.",
207
+ "save-failed": "Not saved: check the marked fields.",
208
+ untitled: "Untitled",
209
+ trail: "Where you are",
210
+ "leave-title": "Leave without saving?",
211
+ "leave-text": "The changes to «Main» are not saved yet.",
212
+ leave: "Leave",
213
+ example: "On the site:",
214
+ "slug-help": "The value in a filter's address: /laptops/color_black/. Made from the name when left empty.",
215
+ "values-unsaved": "The values are written once the property is saved as a reference book.",
216
+ "values-failed": "The values did not load. Reload the page.",
217
+ "values-empty": "No values yet.",
218
+ "values-order-manual": "By hand: the order and the nesting are dragged, and the site shows them so.",
219
+ "values-order-alpha": "Alphabetical: the site sorts them by name in each language. Switch the order to «By hand» on «Main» to drag them.",
220
+ "value-new": "New value — its name, then Enter",
221
+ "value-new-inside": "New value in «:name»",
222
+ "value-add-inside": "Add inside",
223
+ "value-delete-title": "Delete «:name»?",
224
+ "value-delete-text": "No product holds it. Its old address leads to the category without it.",
225
+ "value-delete-branch": "No product holds it, nor anything under it. Everything under it goes too.",
226
+ "value-in-use": "Products hold this value: merge it into another instead. Products: :count",
227
+ "picture-pick": "Choose a picture",
228
+ "picture-change": "Another picture",
229
+ "picture-remove": "Remove",
230
+ "value-pick": "Choose",
231
+ "value-create": "Create «:name»",
232
+ "merge-with": "Merge with…",
233
+ "merge-title": "Merge «:name»",
234
+ "merge-into": "Into",
235
+ "merge-help": "Its products get the value chosen here, its addresses lead there, and it is gone.",
236
+ "merge-confirm": "«:name» becomes «:target» on the products. Products: :count",
237
+ merge: "Merge",
238
+ merged: "Merged. Products moved: :count",
239
+ "intervals-unsaved": "Intervals are the filter of a number by steps: save the property with «Filter by: Intervals» first.",
240
+ "intervals-help": "A step includes its lower end and not its upper one: «1–2 kg» and «2–3 kg» do not share a product of exactly 2 kg. An empty end is open.",
241
+ "intervals-empty": "No intervals yet.",
242
+ "interval-title": "Label",
243
+ "interval-min": "From",
244
+ "interval-max": "Up to",
245
+ "interval-slug": "Slug",
246
+ "interval-open": "Open",
247
+ "interval-add": "Add an interval",
248
+ "intervals-sort": "Sort by bounds",
249
+ "intervals-save": "Save the intervals",
250
+ "intervals-saved": "The intervals are saved.",
251
+ "set-unsaved": "The set is chosen once the category is saved.",
252
+ "set-failed": "The properties did not load. Reload the page.",
253
+ "set-help": "The products of the category and of everything under it are described by these properties. The ones from above come with the category and are removed where they were added.",
254
+ "set-from": "from «:name»",
255
+ "set-empty": "The category adds no properties of its own.",
256
+ "set-add": "Add a property…",
257
+ "set-remove": "Remove «:name» from the set",
258
+ "product-no-category": "The properties of a product are those of its main category: choose one on «Main».",
259
+ "product-empty-set": "The main category has no properties. They are chosen on the category's «Properties» tab.",
260
+ outside: "Outside the category's set: :count",
261
+ "outside-help": "The product holds these, but its main category does not have them: they are not shown anywhere. Moved back to such a category, the product shows them again.",
262
+ "outside-clear": "Delete these values",
263
+ "outside-clear-title": "Delete the values outside the set?",
264
+ "outside-clear-text": "They are deleted from the product for good; the journal keeps what they were.",
265
+ "outside-cleared": "The values outside the set are deleted."
266
+ }
267
+ }, X = "webx-catalog-properties", We = /* @__PURE__ */ new WeakSet();
268
+ function be() {
269
+ try {
270
+ const { i18n: l } = ie();
271
+ We.has(l) || (l.defaults(X, _a), We.add(l));
272
+ } catch {
273
+ }
274
+ }
275
+ const wa = { class: "wx-catalog-category-properties" }, xa = {
276
+ key: 0,
277
+ class: "wx-catalog-category-properties__inherited"
278
+ }, ka = { class: "wx-catalog-category-properties__name" }, Va = { class: "wx-catalog-category-properties__row" }, $a = { class: "wx-catalog-category-properties__name" }, Pa = /* @__PURE__ */ ae({
279
+ name: "WxCatalogCategoryProperties",
280
+ __name: "CategoryPropertiesField",
281
+ setup(l) {
282
+ const a = ie(), n = ue(a), y = ua();
283
+ be();
284
+ const t = se(X), m = ge(), s = S(() => a.i18n.state.locale), i = S(() => y?.category.value?.id ?? null), p = S(() => (y?.locked.value ?? !0) || !a.can("catalog.manage")), C = x(null), h = x([]), P = x([]), W = x(!0), O = x(!1), $ = x(!1), b = x(null), F = S(
285
+ () => /* @__PURE__ */ new Set([
286
+ ...(C.value?.inherited ?? []).map((o) => o.property.id),
287
+ ...h.value.map((o) => o.id)
288
+ ])
289
+ ), D = S(
290
+ () => P.value.filter((o) => !F.value.has(o.id)).map((o) => ({ value: o.id, label: Z(o, s.value) }))
291
+ );
292
+ function z(o) {
293
+ C.value = o, h.value = [...o.own];
294
+ }
295
+ async function f() {
296
+ if (i.value !== null) {
297
+ W.value = !0, O.value = !1;
298
+ try {
299
+ const [o, k] = await Promise.all([n.categorySet(i.value), n.list()]);
300
+ z(o), P.value = k.data;
301
+ } catch {
302
+ O.value = !0;
303
+ } finally {
304
+ W.value = !1;
305
+ }
306
+ }
307
+ }
308
+ ee(i, () => {
309
+ f();
310
+ }, { immediate: !0 }), ee(
311
+ () => y?.category.value?.parent_id,
312
+ (o, k) => {
313
+ k !== void 0 && o !== k && f();
314
+ }
315
+ );
316
+ async function N(o) {
317
+ if (i.value !== null) {
318
+ $.value = !0;
319
+ try {
320
+ z(await n.saveCategorySet(i.value, o));
321
+ } catch (k) {
322
+ const g = k.body, Q = g?.errors ? Object.values(g.errors)[0]?.[0] : void 0;
323
+ te.danger(Q ?? m(k)), C.value && (h.value = [...C.value.own]);
324
+ } finally {
325
+ $.value = !1;
326
+ }
327
+ }
328
+ }
329
+ function E(o) {
330
+ typeof o == "number" && (b.value = null, N([...h.value.map((k) => k.id), o]));
331
+ }
332
+ function J(o) {
333
+ N(h.value.filter((k) => k.id !== o).map((k) => k.id));
334
+ }
335
+ function r() {
336
+ N(h.value.map((o) => o.id));
337
+ }
338
+ const u = (o) => t(`property.types.${o.type}`);
339
+ return (o, k) => (d(), R("div", wa, [
340
+ i.value === null ? (d(), I(e(re), {
341
+ key: 0,
342
+ type: "info",
343
+ variant: "soft",
344
+ description: e(t)("panel.set-unsaved")
345
+ }, null, 8, ["description"])) : W.value ? (d(), I(e(Ae), {
346
+ key: 1,
347
+ rows: 4
348
+ })) : O.value ? (d(), I(e(re), {
349
+ key: 2,
350
+ type: "warning",
351
+ variant: "soft",
352
+ description: e(t)("panel.set-failed")
353
+ }, null, 8, ["description"])) : (d(), R(oe, { key: 3 }, [
354
+ M(e(ne), {
355
+ size: "sm",
356
+ tone: "muted"
357
+ }, {
358
+ default: V(() => [
359
+ G(U(e(t)("panel.set-help")), 1)
360
+ ]),
361
+ _: 1
362
+ }),
363
+ C.value && C.value.inherited.length > 0 ? (d(), R("ul", xa, [
364
+ (d(!0), R(oe, null, ye(C.value.inherited, (g) => (d(), R("li", {
365
+ key: g.property.id,
366
+ class: "wx-catalog-category-properties__row is-inherited"
367
+ }, [
368
+ K("span", ka, U(e(Z)(g.property, s.value)), 1),
369
+ M(e(ne), {
370
+ size: "sm",
371
+ tone: "muted",
372
+ truncate: ""
373
+ }, {
374
+ default: V(() => [
375
+ G(U(u(g.property)) + " · " + U(e(t)("panel.set-from", { name: g.from.name })), 1)
376
+ ]),
377
+ _: 2
378
+ }, 1024)
379
+ ]))), 128))
380
+ ])) : j("", !0),
381
+ M(e(Re), {
382
+ modelValue: h.value,
383
+ "onUpdate:modelValue": k[0] || (k[0] = (g) => h.value = g),
384
+ size: "sm",
385
+ "item-key": "id",
386
+ "item-label": (g) => e(Z)(g, s.value),
387
+ disabled: p.value || $.value,
388
+ "empty-text": e(t)("panel.set-empty"),
389
+ onMove: r
390
+ }, {
391
+ default: V(({ item: g }) => [
392
+ K("span", Va, [
393
+ K("span", $a, U(e(Z)(g, s.value)), 1),
394
+ M(e(ne), {
395
+ size: "sm",
396
+ tone: "muted",
397
+ truncate: ""
398
+ }, {
399
+ default: V(() => [
400
+ G(U(u(g)), 1)
401
+ ]),
402
+ _: 2
403
+ }, 1024)
404
+ ])
405
+ ]),
406
+ actions: V(({ item: g }) => [
407
+ p.value ? j("", !0) : (d(), I(e(q), {
408
+ key: 0,
409
+ size: "sm",
410
+ variant: "text",
411
+ icon: "close",
412
+ disabled: $.value,
413
+ "aria-label": e(t)("panel.set-remove", { name: e(Z)(g, s.value) }),
414
+ onClick: (Q) => J(g.id)
415
+ }, null, 8, ["disabled", "aria-label", "onClick"]))
416
+ ]),
417
+ _: 1
418
+ }, 8, ["modelValue", "item-label", "disabled", "empty-text"]),
419
+ p.value ? j("", !0) : (d(), I(e(Ve), {
420
+ key: 1,
421
+ class: "wx-catalog-category-properties__add",
422
+ "model-value": b.value,
423
+ options: D.value,
424
+ placeholder: e(t)("panel.set-add"),
425
+ "empty-text": e(t)("panel.nothing-found"),
426
+ disabled: $.value,
427
+ filterable: "",
428
+ "onUpdate:modelValue": E
429
+ }, null, 8, ["model-value", "options", "placeholder", "empty-text", "disabled"]))
430
+ ], 64))
431
+ ]));
432
+ }
433
+ }), ce = (l, a) => {
434
+ const n = l.__vccOpts || l;
435
+ for (const [y, t] of a)
436
+ n[y] = t;
437
+ return n;
438
+ }, Sa = /* @__PURE__ */ ce(Pa, [["__scopeId", "data-v-eb81b022"]]), He = /* @__PURE__ */ Symbol("wx-catalog-property");
439
+ function yt(l) {
440
+ Je(He, l);
441
+ }
442
+ function $e() {
443
+ return ze(He, null);
444
+ }
445
+ const Ca = { class: "wx-catalog-intervals" }, Ta = {
446
+ class: "wx-catalog-intervals__head",
447
+ "aria-hidden": "true"
448
+ }, Aa = { class: "wx-catalog-intervals__row" }, Na = {
449
+ key: 0,
450
+ class: "wx-catalog-intervals__bar"
451
+ }, Ia = /* @__PURE__ */ ae({
452
+ name: "WxCatalogPropertyIntervals",
453
+ __name: "IntervalsField",
454
+ setup(l) {
455
+ const a = ie(), n = ue(a), y = $e();
456
+ be();
457
+ const t = se(X), m = ge(), s = S(() => y?.property.value ?? null), i = S(() => y?.locked.value ?? !0), p = x([]), C = x(""), h = x(!1), P = x({});
458
+ let W = 0;
459
+ const O = (r) => r && !Array.isArray(r) ? { ...r } : {};
460
+ function $(r) {
461
+ return {
462
+ key: r.id ? `i${r.id}` : `n${++W}`,
463
+ id: r.id ?? null,
464
+ title: O(r.title),
465
+ slug: O(r.slug),
466
+ min: r.min,
467
+ max: r.max
468
+ };
469
+ }
470
+ const b = (r) => JSON.stringify(r.map(({ id: u, title: o, slug: k, min: g, max: Q }) => ({ id: u, title: o, slug: k, min: g, max: Q })));
471
+ function F(r) {
472
+ p.value = r.map($), C.value = b(p.value);
473
+ }
474
+ ee(
475
+ () => y?.intervals.value,
476
+ (r) => F(r ?? []),
477
+ { immediate: !0 }
478
+ );
479
+ const D = S(() => b(p.value) !== C.value);
480
+ function z() {
481
+ const r = p.value[p.value.length - 1];
482
+ p.value = [
483
+ ...p.value,
484
+ { key: `n${++W}`, id: null, title: {}, slug: {}, min: r?.max ?? null, max: null }
485
+ ];
486
+ }
487
+ function f(r) {
488
+ p.value = p.value.filter((u) => u.key !== r);
489
+ }
490
+ function N() {
491
+ const r = (o) => o.min ?? Number.NEGATIVE_INFINITY, u = (o) => o.max ?? Number.POSITIVE_INFINITY;
492
+ p.value = [...p.value].sort((o, k) => r(o) - r(k) || u(o) - u(k));
493
+ }
494
+ function E(r, u) {
495
+ const o = `intervals.${r}.${u}`, k = Object.keys(P.value).find(
496
+ (g) => g === o || g.startsWith(`${o}.`)
497
+ );
498
+ return k === void 0 ? void 0 : P.value[k]?.[0];
499
+ }
500
+ async function J() {
501
+ if (!(!s.value || h.value)) {
502
+ h.value = !0, P.value = {};
503
+ try {
504
+ const r = await n.saveIntervals(
505
+ s.value.id,
506
+ p.value.map(({ id: u, title: o, slug: k, min: g, max: Q }) => ({ id: u, title: o, slug: k, min: g, max: Q }))
507
+ );
508
+ y ? y.intervals.value = r : F(r), te.success(t("panel.intervals-saved"));
509
+ } catch (r) {
510
+ const u = r.body;
511
+ u?.errors ? (P.value = u.errors, te.danger(t("panel.save-failed"))) : te.danger(m(r));
512
+ } finally {
513
+ h.value = !1;
514
+ }
515
+ }
516
+ }
517
+ return (r, u) => (d(), R("div", Ca, [
518
+ !s.value || s.value.filter_mode !== "intervals" ? (d(), I(e(re), {
519
+ key: 0,
520
+ type: "info",
521
+ variant: "soft",
522
+ description: e(t)("panel.intervals-unsaved")
523
+ }, null, 8, ["description"])) : (d(), R(oe, { key: 1 }, [
524
+ M(e(ne), {
525
+ size: "sm",
526
+ tone: "muted"
527
+ }, {
528
+ default: V(() => [
529
+ G(U(e(t)("panel.intervals-help")), 1)
530
+ ]),
531
+ _: 1
532
+ }),
533
+ K("div", Ta, [
534
+ K("span", null, U(e(t)("panel.interval-title")), 1),
535
+ K("span", null, U(e(t)("panel.interval-min")), 1),
536
+ K("span", null, U(e(t)("panel.interval-max")), 1),
537
+ K("span", null, U(e(t)("panel.interval-slug")), 1)
538
+ ]),
539
+ M(e(Re), {
540
+ modelValue: p.value,
541
+ "onUpdate:modelValue": u[0] || (u[0] = (o) => p.value = o),
542
+ class: "wx-catalog-intervals__list",
543
+ "item-key": "key",
544
+ "item-label": (o) => o.title[e(a).i18n.state.locale] ?? "",
545
+ disabled: i.value,
546
+ "empty-text": e(t)("panel.intervals-empty")
547
+ }, {
548
+ default: V(({ item: o, index: k }) => [
549
+ K("div", Aa, [
550
+ M(e(de), {
551
+ modelValue: o.title,
552
+ "onUpdate:modelValue": (g) => o.title = g,
553
+ localized: "",
554
+ size: "sm",
555
+ disabled: i.value,
556
+ "aria-label": e(t)("panel.interval-title"),
557
+ status: E(k, "title") ? "error" : void 0
558
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled", "aria-label", "status"]),
559
+ M(e(Ce), {
560
+ modelValue: o.min,
561
+ "onUpdate:modelValue": (g) => o.min = g,
562
+ size: "sm",
563
+ controls: !1,
564
+ disabled: i.value,
565
+ placeholder: e(t)("panel.interval-open"),
566
+ "aria-label": e(t)("panel.interval-min")
567
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled", "placeholder", "aria-label"]),
568
+ M(e(Ce), {
569
+ modelValue: o.max,
570
+ "onUpdate:modelValue": (g) => o.max = g,
571
+ size: "sm",
572
+ controls: !1,
573
+ disabled: i.value,
574
+ placeholder: e(t)("panel.interval-open"),
575
+ "aria-label": e(t)("panel.interval-max"),
576
+ status: E(k, "max") ? "error" : void 0
577
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled", "placeholder", "aria-label", "status"]),
578
+ M(e(de), {
579
+ modelValue: o.slug,
580
+ "onUpdate:modelValue": (g) => o.slug = g,
581
+ localized: "",
582
+ size: "sm",
583
+ disabled: i.value,
584
+ "aria-label": e(t)("panel.interval-slug"),
585
+ status: E(k, "slug") ? "error" : void 0
586
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled", "aria-label", "status"]),
587
+ (d(!0), R(oe, null, ye(["title", "max", "slug"].map((g) => E(k, g)).filter(Boolean), (g) => (d(), I(e(ne), {
588
+ key: g,
589
+ class: "wx-catalog-intervals__error",
590
+ size: "sm"
591
+ }, {
592
+ default: V(() => [
593
+ G(U(g), 1)
594
+ ]),
595
+ _: 2
596
+ }, 1024))), 128))
597
+ ])
598
+ ]),
599
+ actions: V(({ item: o }) => [
600
+ M(e(ra), {
601
+ type: "remove",
602
+ label: e(t)("panel.delete"),
603
+ disabled: i.value,
604
+ onClick: (k) => f(o.key)
605
+ }, null, 8, ["label", "disabled", "onClick"])
606
+ ]),
607
+ _: 1
608
+ }, 8, ["modelValue", "item-label", "disabled", "empty-text"]),
609
+ i.value ? j("", !0) : (d(), R("div", Na, [
610
+ M(e(q), {
611
+ size: "sm",
612
+ icon: "plus",
613
+ onClick: z
614
+ }, {
615
+ default: V(() => [
616
+ G(U(e(t)("panel.interval-add")), 1)
617
+ ]),
618
+ _: 1
619
+ }),
620
+ M(e(q), {
621
+ size: "sm",
622
+ variant: "outline",
623
+ disabled: p.value.length < 2,
624
+ onClick: N
625
+ }, {
626
+ default: V(() => [
627
+ G(U(e(t)("panel.intervals-sort")), 1)
628
+ ]),
629
+ _: 1
630
+ }, 8, ["disabled"]),
631
+ u[1] || (u[1] = K("span", { class: "wx-catalog-intervals__spacer" }, null, -1)),
632
+ M(e(q), {
633
+ type: "primary",
634
+ size: "sm",
635
+ loading: h.value,
636
+ disabled: !D.value,
637
+ onClick: J
638
+ }, {
639
+ default: V(() => [
640
+ G(U(e(t)("panel.intervals-save")), 1)
641
+ ]),
642
+ _: 1
643
+ }, 8, ["loading", "disabled"])
644
+ ]))
645
+ ], 64))
646
+ ]));
647
+ }
648
+ }), Ma = /* @__PURE__ */ ce(Ia, [["__scopeId", "data-v-998ebd41"]]), Ua = { class: "wx-catalog-property-example__value" }, Wa = /* @__PURE__ */ ae({
649
+ name: "WxCatalogPropertyExample",
650
+ __name: "NumberExample",
651
+ setup(l) {
652
+ const a = $e(), n = De(), y = se(X), t = S(() => {
653
+ const m = a?.values.value ?? {}, s = n.active.value, i = Number(m.precision ?? 0);
654
+ return Ye(
655
+ ya(i),
656
+ {
657
+ precision: i,
658
+ prefix: Y(m.unit_prefix, s),
659
+ suffix: Y(m.unit_suffix, s)
660
+ },
661
+ s
662
+ );
663
+ });
664
+ return (m, s) => (d(), I(e(ne), {
665
+ class: "wx-catalog-property-example",
666
+ size: "sm",
667
+ tone: "muted"
668
+ }, {
669
+ default: V(() => [
670
+ G(U(e(y)("panel.example")) + " ", 1),
671
+ K("span", Ua, U(t.value), 1)
672
+ ]),
673
+ _: 1
674
+ }));
675
+ }
676
+ }), Oa = /* @__PURE__ */ ce(Wa, [["__scopeId", "data-v-54ac1b0d"]]), Se = -1, za = /* @__PURE__ */ ae({
677
+ name: "WxCatalogPropertyValueSelect",
678
+ __name: "ValueSelect",
679
+ props: /* @__PURE__ */ Te({
680
+ property: {},
681
+ disabled: { type: Boolean, default: !1 },
682
+ ariaLabel: { default: void 0 }
683
+ }, {
684
+ modelValue: { default: null },
685
+ modelModifiers: {}
686
+ }),
687
+ emits: ["update:modelValue"],
688
+ setup(l) {
689
+ const a = l, n = ke(l, "modelValue"), y = ie(), t = ue(y), m = se(X), s = ge(), i = S(() => y.i18n.state.locale), p = S(() => y.can("catalog.manage")), C = x(/* @__PURE__ */ new Map()), h = x([]), P = x(""), W = x(!1), O = S(
690
+ () => n.value === null ? [] : Array.isArray(n.value) ? n.value : [n.value]
691
+ );
692
+ function $(r) {
693
+ const u = new Map(C.value);
694
+ for (const o of r) u.set(o.id, Y(o.title, i.value, `#${o.id}`));
695
+ return C.value = u, r.map((o) => o.id);
696
+ }
697
+ const b = S(() => {
698
+ const r = P.value.trim().toLocaleLowerCase(i.value);
699
+ return [...C.value.values()].some((u) => u.toLocaleLowerCase(i.value) === r);
700
+ }), F = S(() => {
701
+ const u = [.../* @__PURE__ */ new Set([...O.value, ...h.value])].map((o) => ({
702
+ value: o,
703
+ label: C.value.get(o) ?? `#${o}`
704
+ }));
705
+ return p.value && P.value.trim() !== "" && !b.value && u.push({ value: Se, label: m("panel.value-create", { name: P.value.trim() }) }), u;
706
+ });
707
+ ee(
708
+ O,
709
+ async (r) => {
710
+ const u = r.filter((o) => !C.value.has(o));
711
+ if (u.length !== 0)
712
+ try {
713
+ $(await t.valuesById(a.property.id, u));
714
+ } catch {
715
+ }
716
+ },
717
+ { immediate: !0 }
718
+ );
719
+ let D, z = 0;
720
+ async function f(r) {
721
+ const u = ++z;
722
+ try {
723
+ const o = await t.searchValues(a.property.id, r.trim(), 30);
724
+ u === z && (h.value = $(o));
725
+ } catch {
726
+ u === z && (h.value = []);
727
+ }
728
+ }
729
+ function N(r) {
730
+ P.value = r, clearTimeout(D), D = setTimeout(() => {
731
+ f(r);
732
+ }, 200);
733
+ }
734
+ Ee(() => clearTimeout(D));
735
+ async function E() {
736
+ const r = P.value.trim();
737
+ if (r === "" || W.value) return null;
738
+ W.value = !0;
739
+ try {
740
+ const [u] = $([
741
+ await t.createValue(a.property.id, { title: { [i.value]: r } })
742
+ ]);
743
+ return P.value = "", u ?? null;
744
+ } catch (u) {
745
+ return te.danger(s(u)), null;
746
+ } finally {
747
+ W.value = !1;
748
+ }
749
+ }
750
+ async function J(r) {
751
+ const u = r === null ? [] : Array.isArray(r) ? r.map(Number) : [Number(r)];
752
+ if (u.includes(Se)) {
753
+ const o = await E(), k = u.filter((g) => g !== Se);
754
+ o !== null && k.push(o), n.value = a.property.is_multiple ? k : o ?? O.value[0] ?? null;
755
+ return;
756
+ }
757
+ n.value = a.property.is_multiple ? u : u[0] ?? null;
758
+ }
759
+ return (r, u) => (d(), I(e(Ve), {
760
+ "model-value": a.property.is_multiple ? O.value : O.value[0] ?? null,
761
+ options: F.value,
762
+ multiple: a.property.is_multiple,
763
+ disabled: a.disabled || W.value,
764
+ "aria-label": a.ariaLabel,
765
+ placeholder: e(m)("panel.value-pick"),
766
+ "empty-text": e(m)("panel.nothing-found"),
767
+ filterable: "",
768
+ clearable: "",
769
+ "onUpdate:modelValue": J,
770
+ onSearch: N,
771
+ onOpen: u[0] || (u[0] = (o) => f(P.value))
772
+ }, null, 8, ["model-value", "options", "multiple", "disabled", "aria-label", "placeholder", "empty-text"]));
773
+ }
774
+ }), Ea = /* @__PURE__ */ ae({
775
+ name: "WxCatalogPropertyValueTree",
776
+ __name: "ValueTreeSelect",
777
+ props: /* @__PURE__ */ Te({
778
+ property: {},
779
+ disabled: { type: Boolean, default: !1 },
780
+ ariaLabel: { default: void 0 }
781
+ }, {
782
+ modelValue: { default: null },
783
+ modelModifiers: {}
784
+ }),
785
+ emits: ["update:modelValue"],
786
+ setup(l) {
787
+ const a = l, n = ke(l, "modelValue"), y = ie(), t = ue(y), m = se(X), s = S(() => y.i18n.state.locale), i = x([]), p = x([]);
788
+ function C(b) {
789
+ return {
790
+ ...b,
791
+ label: Y(b.title, s.value, `#${b.id}`),
792
+ leaf: !b.has_children,
793
+ blocked: a.property.leaves_only && b.has_children,
794
+ children: void 0
795
+ };
796
+ }
797
+ const h = S(
798
+ () => n.value === null ? [] : Array.isArray(n.value) ? n.value : [n.value]
799
+ );
800
+ async function P() {
801
+ try {
802
+ i.value = (await t.values(a.property.id)).map(C);
803
+ } catch {
804
+ i.value = [];
805
+ }
806
+ }
807
+ P(), ee(
808
+ h,
809
+ async (b) => {
810
+ const F = new Set(p.value.map((z) => z[z.length - 1]?.id)), D = b.filter((z) => !F.has(z));
811
+ if (D.length !== 0)
812
+ try {
813
+ const z = await t.valuesById(a.property.id, D);
814
+ p.value = [
815
+ ...p.value.filter((f) => b.includes(f[f.length - 1]?.id ?? -1)),
816
+ ...z.map((f) => [...(f.ancestors ?? []).map(C), C(f)])
817
+ ];
818
+ } catch {
819
+ }
820
+ },
821
+ { immediate: !0 }
822
+ );
823
+ const W = S(
824
+ () => a.property.is_multiple ? p.value : p.value.find((b) => b[b.length - 1]?.id === h.value[0]) ?? []
825
+ );
826
+ async function O(b) {
827
+ return (await t.values(a.property.id, b.id)).map(C);
828
+ }
829
+ function $(b) {
830
+ const F = b === null ? [] : Array.isArray(b) ? b.map(Number) : [Number(b)];
831
+ n.value = a.property.is_multiple ? F : F[0] ?? null;
832
+ }
833
+ return (b, F) => (d(), I(e(na), {
834
+ "model-value": a.property.is_multiple ? h.value : h.value[0] ?? null,
835
+ nodes: i.value,
836
+ multiple: a.property.is_multiple,
837
+ "check-strictly": !0,
838
+ "selected-path": W.value,
839
+ load: O,
840
+ lazy: "",
841
+ "node-key": "id",
842
+ "label-key": "label",
843
+ "leaf-key": "leaf",
844
+ "disabled-key": "blocked",
845
+ "show-path": "",
846
+ clearable: "",
847
+ disabled: a.disabled,
848
+ "aria-label": a.ariaLabel,
849
+ placeholder: e(m)("panel.value-pick"),
850
+ "empty-text": e(m)("panel.values-empty"),
851
+ "onUpdate:modelValue": $
852
+ }, null, 8, ["model-value", "nodes", "multiple", "selected-path", "disabled", "aria-label", "placeholder", "empty-text"]));
853
+ }
854
+ }), Ba = { class: "wx-catalog-product-properties" }, Fa = {
855
+ key: 2,
856
+ class: "wx-catalog-product-properties__number"
857
+ }, Ra = {
858
+ key: 0,
859
+ class: "wx-catalog-product-properties__unit"
860
+ }, Da = {
861
+ key: 1,
862
+ class: "wx-catalog-product-properties__unit"
863
+ }, La = {
864
+ key: 2,
865
+ class: "wx-catalog-product-properties__outside"
866
+ }, ja = { class: "wx-catalog-product-properties__list" }, Ga = /* @__PURE__ */ ae({
867
+ name: "WxCatalogProductProperties",
868
+ __name: "ProductPropertiesField",
869
+ props: {
870
+ modelValue: { default: null },
871
+ modelModifiers: {}
872
+ },
873
+ emits: ["update:modelValue"],
874
+ setup(l) {
875
+ const a = ke(l, "modelValue"), n = ze(pa, x(void 0)), y = ie(), t = ue(y), m = da(y), s = ca(), i = De();
876
+ be();
877
+ const p = se(X), C = ge(), h = S(() => y.i18n.state.locale), P = S(() => s?.locked.value ?? !1), W = S(() => i.active.value || h.value), O = S(() => {
878
+ const v = s?.values?.value.category_id;
879
+ return typeof v == "number" ? v : v ? Number(v) : null;
880
+ }), $ = x(null), b = x(!1), F = x(!1), D = x({}), z = x(/* @__PURE__ */ new Map()), f = x(/* @__PURE__ */ new Map()), N = x(!1), E = S(
881
+ () => new Set(($.value?.groups ?? []).flatMap((v) => v.properties.map((T) => T.id)))
882
+ ), J = S(
883
+ () => Object.entries(D.value).filter(([v]) => !E.value.has(Number(v))).map(([v, T]) => ({ id: Number(v), value: T }))
884
+ );
885
+ ee(
886
+ () => s?.product.value,
887
+ () => {
888
+ const v = s?.values?.value["properties.outside"] ?? {};
889
+ D.value = { ...Array.isArray(v) ? {} : v, ...a.value ?? {} };
890
+ },
891
+ { immediate: !0 }
892
+ );
893
+ function r() {
894
+ const v = {}, T = a.value ?? {};
895
+ for (const B of E.value) {
896
+ const L = String(B);
897
+ L in T ? v[L] = T[L] ?? null : L in D.value && (v[L] = D.value[L] ?? null);
898
+ }
899
+ JSON.stringify(v) !== JSON.stringify(T) && (a.value = v);
900
+ }
901
+ let u = 0;
902
+ async function o() {
903
+ const v = ++u;
904
+ if (O.value === null) {
905
+ $.value = { groups: [] }, r();
906
+ return;
907
+ }
908
+ b.value = !0, F.value = !1;
909
+ try {
910
+ const T = await t.effectiveSet(O.value);
911
+ if (v !== u) return;
912
+ $.value = T, r();
913
+ } catch {
914
+ v === u && (F.value = !0);
915
+ } finally {
916
+ v === u && (b.value = !1);
917
+ }
918
+ }
919
+ ee(O, () => {
920
+ o();
921
+ }, { immediate: !0 }), ee(
922
+ J,
923
+ async (v) => {
924
+ const T = v.map((B) => B.id).filter((B) => !z.value.has(B));
925
+ if (T.length !== 0)
926
+ try {
927
+ const B = await t.list({ ids: T }), L = new Map(z.value);
928
+ for (const H of B.data) L.set(H.id, H);
929
+ z.value = L;
930
+ const _ = new Map(f.value);
931
+ for (const H of v) {
932
+ const xe = L.get(H.id);
933
+ xe && _.set(H.id, await k(xe, H.value));
934
+ }
935
+ f.value = _;
936
+ } catch {
937
+ }
938
+ },
939
+ { immediate: !0 }
940
+ );
941
+ async function k(v, T) {
942
+ if (T === null) return "";
943
+ switch (v.type) {
944
+ case "select": {
945
+ const B = Array.isArray(T) ? T : [T];
946
+ return (await t.valuesById(v.id, B)).map((_) => Y(_.title, h.value, `#${_.id}`)).join(", ");
947
+ }
948
+ case "number":
949
+ return Ye(
950
+ Number(T),
951
+ {
952
+ precision: v.precision,
953
+ prefix: Y(v.unit_prefix, h.value),
954
+ suffix: Y(v.unit_suffix, h.value)
955
+ },
956
+ h.value
957
+ );
958
+ case "bool":
959
+ return p("product.yes");
960
+ default:
961
+ return Y(T, h.value);
962
+ }
963
+ }
964
+ function g(v) {
965
+ return a.value?.[String(v)] ?? null;
966
+ }
967
+ function Q(v, T) {
968
+ const B = T === null || Array.isArray(T) && T.length === 0 || typeof T == "object" && !Array.isArray(T) && Object.values(T).every((L) => (L ?? "").trim() === "");
969
+ a.value = { ...a.value ?? {}, [String(v)]: B ? null : T };
970
+ }
971
+ function pe(v) {
972
+ const T = g(v);
973
+ return typeof T == "number" || Array.isArray(T) ? T : null;
974
+ }
975
+ function ve(v) {
976
+ return typeof v == "number" ? v : null;
977
+ }
978
+ function _e(v) {
979
+ return v && typeof v == "object" && !Array.isArray(v) ? v : {};
980
+ }
981
+ function Pe(v) {
982
+ const T = `properties.values.${v}`, B = n.value ?? {}, L = Object.keys(B).find((_) => _ === T || _.startsWith(`${T}.`));
983
+ return L === void 0 ? void 0 : B[L]?.[0];
984
+ }
985
+ async function he() {
986
+ const v = s?.product.value;
987
+ if (!(!v || !await Le({
988
+ title: p("panel.outside-clear-title"),
989
+ message: p("panel.outside-clear-text"),
990
+ confirmText: p("panel.delete"),
991
+ cancelText: p("panel.cancel"),
992
+ tone: "danger"
993
+ }))) {
994
+ N.value = !0;
995
+ try {
996
+ await m.startBulk("clear-outside-set", {}, { ids: [v.id] });
997
+ const B = {};
998
+ for (const [L, _] of Object.entries(D.value))
999
+ E.value.has(Number(L)) && (B[L] = _);
1000
+ D.value = B, te.success(p("panel.outside-cleared"));
1001
+ } catch (B) {
1002
+ te.danger(C(B));
1003
+ } finally {
1004
+ N.value = !1;
1005
+ }
1006
+ }
1007
+ }
1008
+ const we = (v) => v.group ? Y(v.group.title, h.value) : "";
1009
+ return (v, T) => (d(), R("div", Ba, [
1010
+ b.value && !$.value ? (d(), I(e(Ae), {
1011
+ key: 0,
1012
+ rows: 4
1013
+ })) : F.value ? (d(), I(e(re), {
1014
+ key: 1,
1015
+ type: "warning",
1016
+ variant: "soft",
1017
+ description: e(p)("panel.set-failed")
1018
+ }, null, 8, ["description"])) : $.value ? (d(), R(oe, { key: 2 }, [
1019
+ O.value === null ? (d(), I(e(re), {
1020
+ key: 0,
1021
+ type: "info",
1022
+ variant: "soft",
1023
+ description: e(p)("panel.product-no-category")
1024
+ }, null, 8, ["description"])) : $.value.groups.length === 0 ? (d(), I(e(re), {
1025
+ key: 1,
1026
+ type: "info",
1027
+ variant: "soft",
1028
+ description: e(p)("panel.product-empty-set")
1029
+ }, null, 8, ["description"])) : j("", !0),
1030
+ (d(!0), R(oe, null, ye($.value.groups, (B, L) => (d(), R("section", {
1031
+ key: B.group?.id ?? `none-${L}`,
1032
+ class: "wx-catalog-product-properties__group"
1033
+ }, [
1034
+ we(B) ? (d(), I(e(ne), {
1035
+ key: 0,
1036
+ class: "wx-catalog-product-properties__heading",
1037
+ weight: "semibold"
1038
+ }, {
1039
+ default: V(() => [
1040
+ G(U(we(B)), 1)
1041
+ ]),
1042
+ _: 2
1043
+ }, 1024)) : j("", !0),
1044
+ (d(!0), R(oe, null, ye(B.properties, (_) => (d(), I(e(fe), {
1045
+ key: _.id,
1046
+ label: _.type === "bool" ? void 0 : e(Z)(_, h.value),
1047
+ error: Pe(_.id)
1048
+ }, {
1049
+ default: V(() => [
1050
+ _.type === "select" && _.is_tree ? (d(), I(Ea, {
1051
+ key: 0,
1052
+ property: _,
1053
+ "model-value": pe(_.id),
1054
+ disabled: P.value,
1055
+ "aria-label": e(Z)(_, h.value),
1056
+ "onUpdate:modelValue": (H) => Q(_.id, H)
1057
+ }, null, 8, ["property", "model-value", "disabled", "aria-label", "onUpdate:modelValue"])) : _.type === "select" ? (d(), I(za, {
1058
+ key: 1,
1059
+ property: _,
1060
+ "model-value": pe(_.id),
1061
+ disabled: P.value,
1062
+ "aria-label": e(Z)(_, h.value),
1063
+ "onUpdate:modelValue": (H) => Q(_.id, H)
1064
+ }, null, 8, ["property", "model-value", "disabled", "aria-label", "onUpdate:modelValue"])) : _.type === "number" ? (d(), R("span", Fa, [
1065
+ e(Y)(_.unit_prefix, W.value) ? (d(), R("span", Ra, U(e(Y)(_.unit_prefix, W.value)), 1)) : j("", !0),
1066
+ M(e(Ce), {
1067
+ "model-value": ve(g(_.id)),
1068
+ precision: e(ba)(_.precision, ve(g(_.id))),
1069
+ controls: !1,
1070
+ disabled: P.value,
1071
+ "aria-label": e(Z)(_, h.value),
1072
+ "onUpdate:modelValue": (H) => Q(_.id, H ?? null)
1073
+ }, null, 8, ["model-value", "precision", "disabled", "aria-label", "onUpdate:modelValue"]),
1074
+ e(Y)(_.unit_suffix, W.value) ? (d(), R("span", Da, U(e(Y)(_.unit_suffix, W.value)), 1)) : j("", !0)
1075
+ ])) : _.type === "bool" ? (d(), I(e(sa), {
1076
+ key: 3,
1077
+ "model-value": g(_.id) === !0,
1078
+ disabled: P.value,
1079
+ label: e(Z)(_, h.value),
1080
+ "onUpdate:modelValue": (H) => Q(_.id, H ? !0 : null)
1081
+ }, null, 8, ["model-value", "disabled", "label", "onUpdate:modelValue"])) : (d(), I(e(de), {
1082
+ key: 4,
1083
+ "model-value": _e(g(_.id)),
1084
+ localized: "",
1085
+ disabled: P.value,
1086
+ "aria-label": e(Z)(_, h.value),
1087
+ "onUpdate:modelValue": (H) => Q(_.id, H)
1088
+ }, null, 8, ["model-value", "disabled", "aria-label", "onUpdate:modelValue"]))
1089
+ ]),
1090
+ _: 2
1091
+ }, 1032, ["label", "error"]))), 128))
1092
+ ]))), 128)),
1093
+ J.value.length > 0 ? (d(), R("details", La, [
1094
+ K("summary", null, [
1095
+ M(e(ne), { weight: "medium" }, {
1096
+ default: V(() => [
1097
+ G(U(e(p)("panel.outside", { count: J.value.length })), 1)
1098
+ ]),
1099
+ _: 1
1100
+ })
1101
+ ]),
1102
+ M(e(ne), {
1103
+ size: "sm",
1104
+ tone: "muted"
1105
+ }, {
1106
+ default: V(() => [
1107
+ G(U(e(p)("panel.outside-help")), 1)
1108
+ ]),
1109
+ _: 1
1110
+ }),
1111
+ K("dl", ja, [
1112
+ (d(!0), R(oe, null, ye(J.value, (B) => (d(), R(oe, {
1113
+ key: B.id
1114
+ }, [
1115
+ K("dt", null, U(z.value.get(B.id) ? e(Z)(z.value.get(B.id), h.value) : `#${B.id}`), 1),
1116
+ K("dd", null, U(f.value.get(B.id) ?? "…"), 1)
1117
+ ], 64))), 128))
1118
+ ]),
1119
+ !P.value && e(y).can("catalog.manage") ? (d(), I(e(q), {
1120
+ key: 0,
1121
+ size: "sm",
1122
+ variant: "outline",
1123
+ icon: "trash",
1124
+ loading: N.value,
1125
+ onClick: he
1126
+ }, {
1127
+ default: V(() => [
1128
+ G(U(e(p)("panel.outside-clear")), 1)
1129
+ ]),
1130
+ _: 1
1131
+ }, 8, ["loading"])) : j("", !0)
1132
+ ])) : j("", !0)
1133
+ ], 64)) : j("", !0)
1134
+ ]));
1135
+ }
1136
+ }), Ka = /* @__PURE__ */ ce(Ga, [["__scopeId", "data-v-c26faef7"]]), Ya = /* @__PURE__ */ ae({
1137
+ name: "WxCatalogPropertyType",
1138
+ inheritAttrs: !1,
1139
+ __name: "TypeField",
1140
+ props: /* @__PURE__ */ Te({
1141
+ options: { default: () => [] }
1142
+ }, {
1143
+ modelValue: { default: null },
1144
+ modelModifiers: {}
1145
+ }),
1146
+ emits: ["update:modelValue"],
1147
+ setup(l) {
1148
+ const a = l, n = ke(l, "modelValue"), y = $e(), t = S(() => (y?.property.value?.id ?? null) !== null);
1149
+ return (m, s) => (d(), I(e(Ve), Qe(m.$attrs, {
1150
+ modelValue: n.value,
1151
+ "onUpdate:modelValue": s[0] || (s[0] = (i) => n.value = i),
1152
+ options: a.options,
1153
+ disabled: t.value || void 0
1154
+ }), null, 16, ["modelValue", "options", "disabled"]));
1155
+ }
1156
+ }), Ha = /* @__PURE__ */ ae({
1157
+ name: "WxCatalogPropertyMergeDialog",
1158
+ __name: "MergeDialog",
1159
+ props: {
1160
+ property: {},
1161
+ value: {}
1162
+ },
1163
+ setup(l) {
1164
+ const a = l, { open: n, resolve: y, dismiss: t } = je(), m = ie(), s = ue(m), i = se(X), p = ge(), C = S(() => m.i18n.state.locale), h = S(() => Y(a.value.title, C.value, `#${a.value.id}`)), P = x([]), W = x(null), O = x(null), $ = x(!1), b = x(!1), F = x(""), D = S(
1165
+ () => P.value.filter((r) => r.id !== a.value.id).map((r) => ({ value: r.id, label: Y(r.title, C.value, `#${r.id}`) }))
1166
+ ), z = S(
1167
+ () => D.value.find((r) => r.value === W.value)?.label ?? ""
1168
+ );
1169
+ let f = 0;
1170
+ async function N(r) {
1171
+ const u = ++f;
1172
+ try {
1173
+ const o = await s.searchValues(a.property, r.trim(), 30);
1174
+ u === f && (P.value = o);
1175
+ } catch {
1176
+ u === f && (P.value = []);
1177
+ }
1178
+ }
1179
+ N(""), ee(W, async (r) => {
1180
+ if (O.value = null, F.value = "", r !== null) {
1181
+ $.value = !0;
1182
+ try {
1183
+ O.value = await s.mergeValue(a.property, a.value.id, r, !0);
1184
+ } catch (u) {
1185
+ F.value = p(u);
1186
+ } finally {
1187
+ $.value = !1;
1188
+ }
1189
+ }
1190
+ });
1191
+ function E(r) {
1192
+ W.value = typeof r == "number" ? r : null;
1193
+ }
1194
+ async function J() {
1195
+ if (!(W.value === null || b.value)) {
1196
+ b.value = !0, F.value = "";
1197
+ try {
1198
+ y(await s.mergeValue(a.property, a.value.id, W.value));
1199
+ } catch (r) {
1200
+ F.value = p(r);
1201
+ } finally {
1202
+ b.value = !1;
1203
+ }
1204
+ }
1205
+ }
1206
+ return (r, u) => (d(), I(e(Ge), {
1207
+ open: e(n),
1208
+ "onUpdate:open": u[1] || (u[1] = (o) => Be(n) ? n.value = o : null),
1209
+ title: e(i)("panel.merge-title", { name: h.value }),
1210
+ width: 480
1211
+ }, {
1212
+ footer: V(() => [
1213
+ M(e(Ke), { size: "sm" }, {
1214
+ default: V(() => [
1215
+ M(e(q), {
1216
+ variant: "outline",
1217
+ onClick: u[0] || (u[0] = (o) => e(t)())
1218
+ }, {
1219
+ default: V(() => [
1220
+ G(U(e(i)("panel.cancel")), 1)
1221
+ ]),
1222
+ _: 1
1223
+ }),
1224
+ M(e(q), {
1225
+ type: "primary",
1226
+ loading: b.value || $.value,
1227
+ disabled: W.value === null || O.value === null,
1228
+ onClick: J
1229
+ }, {
1230
+ default: V(() => [
1231
+ G(U(e(i)("panel.merge")), 1)
1232
+ ]),
1233
+ _: 1
1234
+ }, 8, ["loading", "disabled"])
1235
+ ]),
1236
+ _: 1
1237
+ })
1238
+ ]),
1239
+ default: V(() => [
1240
+ M(e(fe), {
1241
+ label: e(i)("panel.merge-into"),
1242
+ help: e(i)("panel.merge-help")
1243
+ }, {
1244
+ default: V(() => [
1245
+ M(e(Ve), {
1246
+ "model-value": W.value,
1247
+ options: D.value,
1248
+ placeholder: e(i)("panel.search"),
1249
+ "empty-text": e(i)("panel.nothing-found"),
1250
+ filterable: "",
1251
+ "onUpdate:modelValue": E,
1252
+ onSearch: N
1253
+ }, null, 8, ["model-value", "options", "placeholder", "empty-text"])
1254
+ ]),
1255
+ _: 1
1256
+ }, 8, ["label", "help"]),
1257
+ F.value ? (d(), I(e(re), {
1258
+ key: 0,
1259
+ type: "danger",
1260
+ variant: "soft",
1261
+ description: F.value
1262
+ }, null, 8, ["description"])) : W.value !== null && O.value !== null ? (d(), I(e(re), {
1263
+ key: 1,
1264
+ type: "warning",
1265
+ variant: "soft",
1266
+ description: e(i)("panel.merge-confirm", { name: h.value, target: z.value, count: O.value })
1267
+ }, null, 8, ["description"])) : j("", !0)
1268
+ ]),
1269
+ _: 1
1270
+ }, 8, ["open", "title"]));
1271
+ }
1272
+ }), Ja = { class: "wx-catalog-value-dialog__picture" }, Qa = ["src"], Xa = /* @__PURE__ */ ae({
1273
+ name: "WxCatalogPropertyValueDialog",
1274
+ __name: "ValueDialog",
1275
+ props: {
1276
+ property: {},
1277
+ value: { default: null },
1278
+ parent: { default: null },
1279
+ title: {},
1280
+ color: { type: Boolean, default: !1 },
1281
+ image: { type: Boolean, default: !1 }
1282
+ },
1283
+ setup(l) {
1284
+ const a = l, { open: n, resolve: y, dismiss: t } = je(), m = ue(ie()), s = se(X), i = (f) => f && !Array.isArray(f) ? { ...f } : {}, p = x(i(a.value?.title)), C = x(i(a.value?.slug)), h = x(a.value?.color ?? null), P = x(
1285
+ a.value?.image ? { id: a.value.image.id, url: a.value.image.thumb ?? a.value.image.url } : null
1286
+ ), W = x(!1), O = x({}), $ = Xe("field");
1287
+ Ze(async () => {
1288
+ await qe(), $.value?.querySelector("input")?.focus();
1289
+ });
1290
+ function b(f) {
1291
+ const N = Object.keys(O.value).find((E) => E === f || E.startsWith(`${f}.`));
1292
+ return N === void 0 ? void 0 : O.value[N]?.[0];
1293
+ }
1294
+ const F = () => Object.values(p.value).some((f) => f.trim() !== "");
1295
+ async function D() {
1296
+ const f = await va({ accept: "image" });
1297
+ f && (P.value = { id: f.id, url: f.thumb ?? f.url });
1298
+ }
1299
+ async function z() {
1300
+ if (!F() || W.value) return;
1301
+ W.value = !0, O.value = {};
1302
+ const f = { title: p.value, slug: C.value };
1303
+ a.color && (f.color = h.value), a.image && (f.image_id = P.value?.id ?? null);
1304
+ try {
1305
+ y(
1306
+ a.value ? await m.saveValue(a.property, a.value.id, f) : await m.createValue(a.property, { ...f, parent_id: a.parent })
1307
+ );
1308
+ } catch (N) {
1309
+ O.value = N.body?.errors ?? {};
1310
+ } finally {
1311
+ W.value = !1;
1312
+ }
1313
+ }
1314
+ return (f, N) => (d(), I(e(Ge), {
1315
+ open: e(n),
1316
+ "onUpdate:open": N[5] || (N[5] = (E) => Be(n) ? n.value = E : null),
1317
+ title: a.title,
1318
+ width: 480
1319
+ }, {
1320
+ footer: V(() => [
1321
+ M(e(Ke), { size: "sm" }, {
1322
+ default: V(() => [
1323
+ M(e(q), {
1324
+ variant: "outline",
1325
+ onClick: N[4] || (N[4] = (E) => e(t)())
1326
+ }, {
1327
+ default: V(() => [
1328
+ G(U(e(s)("panel.cancel")), 1)
1329
+ ]),
1330
+ _: 1
1331
+ }),
1332
+ M(e(q), {
1333
+ type: "primary",
1334
+ loading: W.value,
1335
+ disabled: !F(),
1336
+ onClick: z
1337
+ }, {
1338
+ default: V(() => [
1339
+ G(U(a.value ? e(s)("panel.save") : e(s)("panel.create")), 1)
1340
+ ]),
1341
+ _: 1
1342
+ }, 8, ["loading", "disabled"])
1343
+ ]),
1344
+ _: 1
1345
+ })
1346
+ ]),
1347
+ default: V(() => [
1348
+ M(e(fe), {
1349
+ label: e(s)("value.title"),
1350
+ error: b("title"),
1351
+ required: ""
1352
+ }, {
1353
+ default: V(() => [
1354
+ K("div", {
1355
+ ref_key: "field",
1356
+ ref: $
1357
+ }, [
1358
+ M(e(de), {
1359
+ modelValue: p.value,
1360
+ "onUpdate:modelValue": N[0] || (N[0] = (E) => p.value = E),
1361
+ localized: "",
1362
+ "aria-label": e(s)("value.title"),
1363
+ onKeyup: Ne(z, ["enter"])
1364
+ }, null, 8, ["modelValue", "aria-label"])
1365
+ ], 512)
1366
+ ]),
1367
+ _: 1
1368
+ }, 8, ["label", "error"]),
1369
+ M(e(fe), {
1370
+ label: e(s)("value.slug"),
1371
+ help: e(s)("panel.slug-help"),
1372
+ error: b("slug")
1373
+ }, {
1374
+ default: V(() => [
1375
+ M(e(de), {
1376
+ modelValue: C.value,
1377
+ "onUpdate:modelValue": N[1] || (N[1] = (E) => C.value = E),
1378
+ localized: "",
1379
+ "aria-label": e(s)("value.slug"),
1380
+ onKeyup: Ne(z, ["enter"])
1381
+ }, null, 8, ["modelValue", "aria-label"])
1382
+ ]),
1383
+ _: 1
1384
+ }, 8, ["label", "help", "error"]),
1385
+ a.color ? (d(), I(e(fe), {
1386
+ key: 0,
1387
+ label: e(s)("value.color"),
1388
+ error: b("color")
1389
+ }, {
1390
+ default: V(() => [
1391
+ M(e(ia), {
1392
+ modelValue: h.value,
1393
+ "onUpdate:modelValue": N[2] || (N[2] = (E) => h.value = E),
1394
+ clearable: "",
1395
+ "aria-label": e(s)("value.color")
1396
+ }, null, 8, ["modelValue", "aria-label"])
1397
+ ]),
1398
+ _: 1
1399
+ }, 8, ["label", "error"])) : j("", !0),
1400
+ a.image ? (d(), I(e(fe), {
1401
+ key: 1,
1402
+ label: e(s)("value.image"),
1403
+ error: b("image_id")
1404
+ }, {
1405
+ default: V(() => [
1406
+ K("div", Ja, [
1407
+ P.value ? (d(), R("img", {
1408
+ key: 0,
1409
+ src: P.value.url,
1410
+ alt: ""
1411
+ }, null, 8, Qa)) : j("", !0),
1412
+ M(e(q), {
1413
+ size: "sm",
1414
+ variant: "outline",
1415
+ icon: "image",
1416
+ onClick: D
1417
+ }, {
1418
+ default: V(() => [
1419
+ G(U(P.value ? e(s)("panel.picture-change") : e(s)("panel.picture-pick")), 1)
1420
+ ]),
1421
+ _: 1
1422
+ }),
1423
+ P.value ? (d(), I(e(q), {
1424
+ key: 1,
1425
+ size: "sm",
1426
+ variant: "text",
1427
+ onClick: N[3] || (N[3] = (E) => P.value = null)
1428
+ }, {
1429
+ default: V(() => [
1430
+ G(U(e(s)("panel.picture-remove")), 1)
1431
+ ]),
1432
+ _: 1
1433
+ })) : j("", !0)
1434
+ ])
1435
+ ]),
1436
+ _: 1
1437
+ }, 8, ["label", "error"])) : j("", !0)
1438
+ ]),
1439
+ _: 1
1440
+ }, 8, ["open", "title"]));
1441
+ }
1442
+ }), Za = /* @__PURE__ */ ce(Xa, [["__scopeId", "data-v-4c730a6b"]]), qa = { class: "wx-catalog-value-row" }, et = ["src"], at = { class: "wx-catalog-value-row__title" }, tt = {
1443
+ key: 2,
1444
+ class: "wx-catalog-value-row__slug"
1445
+ }, lt = { class: "wx-catalog-value-row__count" }, ot = /* @__PURE__ */ ae({
1446
+ name: "WxCatalogPropertyValueRow",
1447
+ __name: "ValueRow",
1448
+ props: {
1449
+ node: {},
1450
+ locale: {}
1451
+ },
1452
+ setup(l) {
1453
+ const a = l, n = se(X), y = S(() => {
1454
+ const t = a.node.slug;
1455
+ return t && !Array.isArray(t) ? t[a.locale] ?? "" : "";
1456
+ });
1457
+ return (t, m) => (d(), R("span", qa, [
1458
+ a.node.image ? (d(), R("img", {
1459
+ key: 0,
1460
+ class: "wx-catalog-value-row__image",
1461
+ src: a.node.image.thumb ?? a.node.image.url,
1462
+ alt: ""
1463
+ }, null, 8, et)) : a.node.color ? (d(), R("span", {
1464
+ key: 1,
1465
+ class: "wx-catalog-value-row__swatch",
1466
+ style: ea({ background: a.node.color }),
1467
+ "aria-hidden": "true"
1468
+ }, null, 4)) : j("", !0),
1469
+ K("span", at, U(a.node.label), 1),
1470
+ y.value ? (d(), R("span", tt, U(y.value), 1)) : j("", !0),
1471
+ K("span", lt, U(e(n)("panel.count", { count: a.node.products_count })), 1)
1472
+ ]));
1473
+ }
1474
+ }), Oe = /* @__PURE__ */ ce(ot, [["__scopeId", "data-v-13648e79"]]), rt = { class: "wx-catalog-values" }, nt = { class: "wx-catalog-values__bar" }, st = /* @__PURE__ */ ae({
1475
+ name: "WxCatalogPropertyValues",
1476
+ __name: "ValuesField",
1477
+ setup(l) {
1478
+ const a = ie(), n = ue(a), y = $e();
1479
+ be();
1480
+ const t = se(X), m = ge(), s = S(() => y?.property.value ?? null), i = S(() => s.value?.id ?? null), p = S(() => a.i18n.state.locale), C = S(() => y?.locked.value ?? !0), h = S(() => !!y?.values.value.has_color), P = S(() => !!y?.values.value.has_image), W = S(() => s.value?.is_tree ?? !1), O = S(() => s.value?.value_order === "manual"), $ = x([]), b = x([]), F = x(!0), D = x(!1), z = x(""), f = x(null), N = S(() => z.value.trim() !== ""), E = x(""), J = x(!1), r = S(() => !C.value && O.value && !N.value), u = Me(Za), o = Me(Ha);
1481
+ function k(c) {
1482
+ return {
1483
+ ...c,
1484
+ label: Y(c.title, p.value, `#${c.id}`),
1485
+ leaf: !c.has_children,
1486
+ children: void 0
1487
+ };
1488
+ }
1489
+ async function g() {
1490
+ if (i.value !== null) {
1491
+ F.value = !0, D.value = !1;
1492
+ try {
1493
+ $.value = (await n.values(i.value)).map(k), b.value = [];
1494
+ } catch {
1495
+ D.value = !0;
1496
+ } finally {
1497
+ F.value = !1;
1498
+ }
1499
+ }
1500
+ }
1501
+ ee(i, () => {
1502
+ g();
1503
+ }, { immediate: !0 }), ee(
1504
+ () => [s.value?.value_order, s.value?.is_tree],
1505
+ (c, w) => {
1506
+ w !== void 0 && (c[0] !== w[0] || c[1] !== w[1]) && g();
1507
+ }
1508
+ );
1509
+ async function Q(c) {
1510
+ return i.value === null ? [] : (await n.values(i.value, c.id)).map(k);
1511
+ }
1512
+ let pe, ve = 0;
1513
+ ee(z, (c) => {
1514
+ if (clearTimeout(pe), c.trim() === "") {
1515
+ f.value = null;
1516
+ return;
1517
+ }
1518
+ pe = setTimeout(async () => {
1519
+ if (i.value === null) return;
1520
+ const w = ++ve;
1521
+ try {
1522
+ const A = (await n.searchValues(i.value, c.trim(), 100)).map((le) => ({
1523
+ ...k(le),
1524
+ leaf: !0
1525
+ }));
1526
+ w === ve && (f.value = A);
1527
+ } catch {
1528
+ w === ve && (f.value = []);
1529
+ }
1530
+ }, 250);
1531
+ }), Ee(() => clearTimeout(pe));
1532
+ function _e(c, w = $.value) {
1533
+ for (const A of w)
1534
+ c(A), A.children && _e(c, A.children);
1535
+ if (w === $.value && f.value) for (const A of f.value) c(A);
1536
+ }
1537
+ function Pe(c) {
1538
+ _e((w) => {
1539
+ w.id === c.id && Object.assign(w, {
1540
+ ...c,
1541
+ label: Y(c.title, p.value, `#${c.id}`),
1542
+ leaf: !c.has_children && !(w.children && w.children.length > 0),
1543
+ children: w.children
1544
+ });
1545
+ });
1546
+ }
1547
+ function he(c) {
1548
+ te.danger(m(c));
1549
+ }
1550
+ async function we() {
1551
+ const c = E.value.trim();
1552
+ if (!(c === "" || i.value === null || J.value)) {
1553
+ J.value = !0;
1554
+ try {
1555
+ const w = k(await n.createValue(i.value, { title: { [p.value]: c } }));
1556
+ E.value = "", $.value = O.value ? [...$.value, w] : [...$.value, w].sort((A, le) => A.label.localeCompare(le.label, p.value));
1557
+ } catch (w) {
1558
+ he(w);
1559
+ } finally {
1560
+ J.value = !1;
1561
+ }
1562
+ }
1563
+ }
1564
+ async function v(c) {
1565
+ if (i.value === null) return;
1566
+ const w = await u({
1567
+ property: i.value,
1568
+ parent: c.id,
1569
+ title: t("panel.value-new-inside", { name: c.label }),
1570
+ color: h.value,
1571
+ image: P.value
1572
+ });
1573
+ w !== void 0 && (c.children && c.children.push(k(w)), c.has_children = !0, c.leaf = !1, b.value.includes(c.id) || (b.value = [...b.value, c.id]));
1574
+ }
1575
+ async function T(c) {
1576
+ if (i.value === null) return;
1577
+ const w = await u({
1578
+ property: i.value,
1579
+ value: c,
1580
+ title: c.label,
1581
+ color: h.value,
1582
+ image: P.value
1583
+ });
1584
+ w !== void 0 && Pe(w);
1585
+ }
1586
+ async function B(c) {
1587
+ if (i.value === null) return;
1588
+ const w = await o({ property: i.value, value: c });
1589
+ w !== void 0 && (te.success(t("panel.merged", { count: w })), z.value = "", await g());
1590
+ }
1591
+ async function L(c) {
1592
+ if (i.value === null) return;
1593
+ if (c.products_count > 0) {
1594
+ te.warning(t("panel.value-in-use", { count: c.products_count }));
1595
+ return;
1596
+ }
1597
+ if (await Le({
1598
+ title: t("panel.value-delete-title", { name: c.label }),
1599
+ message: c.has_children ? t("panel.value-delete-branch") : t("panel.value-delete-text"),
1600
+ confirmText: t("panel.delete"),
1601
+ cancelText: t("panel.cancel"),
1602
+ tone: "danger"
1603
+ }))
1604
+ try {
1605
+ await n.removeValue(i.value, c.id);
1606
+ const A = (le) => le.filter((me) => me.id !== c.id).map((me) => me.children ? Object.assign(me, { children: A(me.children) }) : me);
1607
+ $.value = A($.value), f.value && (f.value = A(f.value));
1608
+ } catch (A) {
1609
+ const le = A.body?.meta?.products;
1610
+ le ? te.warning(t("panel.value-in-use", { count: le })) : he(A);
1611
+ }
1612
+ }
1613
+ function _(c) {
1614
+ if (C.value) return [];
1615
+ const w = [
1616
+ { key: "edit", label: t("panel.edit"), icon: "edit", run: () => {
1617
+ T(c);
1618
+ } }
1619
+ ];
1620
+ return W.value && !N.value && w.push({
1621
+ key: "inside",
1622
+ label: t("panel.value-add-inside"),
1623
+ icon: "plus",
1624
+ run: () => {
1625
+ v(c);
1626
+ }
1627
+ }), w.push(
1628
+ { key: "merge", label: t("panel.merge-with"), icon: "copy", run: () => {
1629
+ B(c);
1630
+ } },
1631
+ {
1632
+ key: "delete",
1633
+ label: t("panel.delete"),
1634
+ icon: "trash",
1635
+ danger: !0,
1636
+ run: () => {
1637
+ L(c);
1638
+ }
1639
+ }
1640
+ ), w;
1641
+ }
1642
+ function H(c, w, A) {
1643
+ return W.value || A !== "inside";
1644
+ }
1645
+ async function xe(c) {
1646
+ if (i.value === null) return;
1647
+ const A = (c.parent ? c.parent.children ?? [] : $.value)[c.index + 1] ?? null;
1648
+ c.parent && (c.parent.has_children = !0, c.parent.leaf = !1);
1649
+ try {
1650
+ await n.moveValue(i.value, c.node.id, c.parent?.id ?? null, A?.id ?? null);
1651
+ } catch (le) {
1652
+ he(le), await g();
1653
+ }
1654
+ }
1655
+ return (c, w) => (d(), R("div", rt, [
1656
+ s.value ? (d(), R(oe, { key: 1 }, [
1657
+ K("div", nt, [
1658
+ C.value ? j("", !0) : (d(), R("form", {
1659
+ key: 0,
1660
+ class: "wx-catalog-values__add",
1661
+ onSubmit: aa(we, ["prevent"])
1662
+ }, [
1663
+ M(e(de), {
1664
+ modelValue: E.value,
1665
+ "onUpdate:modelValue": w[0] || (w[0] = (A) => E.value = A),
1666
+ placeholder: e(t)("panel.value-new"),
1667
+ "aria-label": e(t)("panel.value-new"),
1668
+ size: "sm"
1669
+ }, null, 8, ["modelValue", "placeholder", "aria-label"]),
1670
+ M(e(q), {
1671
+ "native-type": "submit",
1672
+ size: "sm",
1673
+ loading: J.value,
1674
+ disabled: E.value.trim() === ""
1675
+ }, {
1676
+ default: V(() => [
1677
+ G(U(e(t)("panel.add")), 1)
1678
+ ]),
1679
+ _: 1
1680
+ }, 8, ["loading", "disabled"])
1681
+ ], 32)),
1682
+ M(e(de), {
1683
+ modelValue: z.value,
1684
+ "onUpdate:modelValue": w[1] || (w[1] = (A) => z.value = A),
1685
+ class: "wx-catalog-values__search",
1686
+ placeholder: e(t)("panel.search"),
1687
+ "aria-label": e(t)("panel.search"),
1688
+ clearable: "",
1689
+ size: "sm"
1690
+ }, null, 8, ["modelValue", "placeholder", "aria-label"])
1691
+ ]),
1692
+ F.value ? (d(), I(e(Ae), {
1693
+ key: 0,
1694
+ rows: 4
1695
+ })) : D.value ? (d(), I(e(re), {
1696
+ key: 1,
1697
+ type: "warning",
1698
+ variant: "soft",
1699
+ description: e(t)("panel.values-failed")
1700
+ }, null, 8, ["description"])) : N.value ? (d(), I(e(Ue), {
1701
+ key: 2,
1702
+ "model-value": f.value ?? [],
1703
+ class: "wx-catalog-values__tree",
1704
+ "empty-text": f.value === null ? e(t)("panel.searching") : e(t)("panel.nothing-found"),
1705
+ "aria-label": e(t)("property.tab-values")
1706
+ }, {
1707
+ default: V(({ node: A }) => [
1708
+ M(Oe, {
1709
+ node: A,
1710
+ locale: p.value
1711
+ }, null, 8, ["node", "locale"])
1712
+ ]),
1713
+ actions: V(({ node: A }) => [
1714
+ C.value ? j("", !0) : (d(), I(e(Ie), {
1715
+ key: 0,
1716
+ actions: _(A),
1717
+ label: A.label
1718
+ }, null, 8, ["actions", "label"]))
1719
+ ]),
1720
+ _: 1
1721
+ }, 8, ["model-value", "empty-text", "aria-label"])) : (d(), I(e(Ue), {
1722
+ key: 3,
1723
+ modelValue: $.value,
1724
+ "onUpdate:modelValue": w[2] || (w[2] = (A) => $.value = A),
1725
+ expanded: b.value,
1726
+ "onUpdate:expanded": w[3] || (w[3] = (A) => b.value = A),
1727
+ class: "wx-catalog-values__tree",
1728
+ lazy: "",
1729
+ load: Q,
1730
+ "leaf-key": "leaf",
1731
+ draggable: r.value,
1732
+ "allow-drop": H,
1733
+ "empty-text": e(t)("panel.values-empty"),
1734
+ "aria-label": e(t)("property.tab-values"),
1735
+ onDrop: xe
1736
+ }, {
1737
+ default: V(({ node: A }) => [
1738
+ M(Oe, {
1739
+ node: A,
1740
+ locale: p.value
1741
+ }, null, 8, ["node", "locale"])
1742
+ ]),
1743
+ actions: V(({ node: A }) => [
1744
+ C.value ? j("", !0) : (d(), I(e(Ie), {
1745
+ key: 0,
1746
+ actions: _(A),
1747
+ label: A.label
1748
+ }, null, 8, ["actions", "label"]))
1749
+ ]),
1750
+ _: 1
1751
+ }, 8, ["modelValue", "expanded", "draggable", "empty-text", "aria-label"])),
1752
+ !F.value && !D.value && !N.value ? (d(), I(e(ne), {
1753
+ key: 4,
1754
+ size: "sm",
1755
+ tone: "muted"
1756
+ }, {
1757
+ default: V(() => [
1758
+ G(U(O.value ? e(t)("panel.values-order-manual") : e(t)("panel.values-order-alpha")), 1)
1759
+ ]),
1760
+ _: 1
1761
+ })) : j("", !0)
1762
+ ], 64)) : (d(), I(e(re), {
1763
+ key: 0,
1764
+ type: "info",
1765
+ variant: "soft",
1766
+ description: e(t)("panel.values-unsaved")
1767
+ }, null, 8, ["description"]))
1768
+ ]));
1769
+ }
1770
+ }), it = /* @__PURE__ */ ce(st, [["__scopeId", "data-v-7e854528"]]), ut = [
1771
+ "new",
1772
+ "empty",
1773
+ "empty-help",
1774
+ "order",
1775
+ "hidden",
1776
+ "count",
1777
+ "delete-blocked",
1778
+ "delete-text",
1779
+ "deleted",
1780
+ "saved"
1781
+ ];
1782
+ function dt(l = {}) {
1783
+ const a = l.path ?? "/catalog";
1784
+ return {
1785
+ api: fa,
1786
+ path: `${a}/properties/groups`,
1787
+ name: "webx.catalog-properties.groups",
1788
+ module: "catalog-properties",
1789
+ title: `${X}::panel.groups-title`,
1790
+ back: { path: `${a}/properties`, label: `${X}::module.title` },
1791
+ screen: "catalog.property-group-form",
1792
+ manage: "catalog.manage",
1793
+ count: "properties_count",
1794
+ words: Object.fromEntries(ut.map((n) => [n, `${X}::group.${n}`]))
1795
+ };
1796
+ }
1797
+ function ct(l) {
1798
+ const a = l.component;
1799
+ return a === void 0 ? l : {
1800
+ ...l,
1801
+ component: ae({
1802
+ name: "WxCatalogPropertyGroupsView",
1803
+ setup() {
1804
+ return be(), () => ta(a);
1805
+ }
1806
+ })
1807
+ };
1808
+ }
1809
+ function bt(l = {}) {
1810
+ const a = l.path ?? "/catalog", n = { base: a };
1811
+ return [
1812
+ {
1813
+ id: "catalog-properties",
1814
+ path: `${a}/properties`,
1815
+ routes: [
1816
+ {
1817
+ path: `${a}/properties`,
1818
+ name: "webx.catalog-properties",
1819
+ component: () => import("./PropertiesPage-B1jxbWZh.js"),
1820
+ props: n
1821
+ },
1822
+ {
1823
+ path: `${a}/properties/:id(\\d+)`,
1824
+ name: "webx.catalog-properties.edit",
1825
+ component: () => import("./PropertyEditorPage-C0o03q-A.js"),
1826
+ props: n
1827
+ },
1828
+ ...la(dt(l)).map(ct)
1829
+ ],
1830
+ types: {
1831
+ "wx-catalog-property-type": { component: Ya, kind: "field" },
1832
+ "wx-catalog-property-example": { component: Oa, kind: "display" },
1833
+ "wx-catalog-property-values": { component: it, kind: "display" },
1834
+ "wx-catalog-property-intervals": { component: Ma, kind: "display" },
1835
+ "wx-catalog-category-properties": { component: Sa, kind: "display" },
1836
+ // Wide: a group of the card is a column of fields, and half a form is too narrow for a
1837
+ // combobox of values beside its label.
1838
+ "wx-catalog-product-properties": {
1839
+ component: Ka,
1840
+ kind: "field",
1841
+ wide: !0
1842
+ }
1843
+ }
1844
+ }
1845
+ ];
1846
+ }
1847
+ const _t = Fe(() => import("./PropertiesPage-B1jxbWZh.js")), wt = Fe(
1848
+ () => import("./PropertyEditorPage-C0o03q-A.js")
1849
+ );
1850
+ export {
1851
+ Sa as C,
1852
+ fa as G,
1853
+ Ma as I,
1854
+ X as N,
1855
+ ma as P,
1856
+ ga as S,
1857
+ it as V,
1858
+ _t as W,
1859
+ ce as _,
1860
+ yt as a,
1861
+ Ka as b,
1862
+ ue as c,
1863
+ wt as d,
1864
+ bt as e,
1865
+ _a as f,
1866
+ Ye as g,
1867
+ He as h,
1868
+ dt as i,
1869
+ ha as j,
1870
+ $e as k,
1871
+ Z as p,
1872
+ be as u,
1873
+ Y as w
1874
+ };
1875
+ //# sourceMappingURL=index-B2Yl11Yn.js.map