@feedmepos/mf-menu-portal 1.0.4-dev.3 → 1.0.4-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/{App-nS46pByh.js → App-CrpoLCjA.js} +3 -3
  2. package/dist/{ApplyProduct.vue_vue_type_script_setup_true_lang-C9OSr8ft.js → ApplyProduct.vue_vue_type_script_setup_true_lang-Hdsnu29V.js} +1 -1
  3. package/dist/{BindingTable.vue_vue_type_script_setup_true_lang-DnvN5R5w.js → BindingTable.vue_vue_type_script_setup_true_lang-D3CmOOPY.js} +1 -1
  4. package/dist/{Catalog-B4RS8T29.js → Catalog-VU3HhNro.js} +4 -4
  5. package/dist/{CatalogBinding-6_783kbu.js → CatalogBinding-BNATtZEY.js} +3 -3
  6. package/dist/{CatalogEditTabs.vue_vue_type_script_setup_true_lang-BawCLY5-.js → CatalogEditTabs.vue_vue_type_script_setup_true_lang-BmG-xpW4.js} +3 -3
  7. package/dist/{CatalogEditor.vue_vue_type_script_setup_true_lang-BjP8ZXyb.js → CatalogEditor.vue_vue_type_script_setup_true_lang-BFsRDFpj.js} +7 -7
  8. package/dist/{CatalogLinkProductAction.vue_vue_type_script_setup_true_lang-Diapahfp.js → CatalogLinkProductAction.vue_vue_type_script_setup_true_lang-Bk4FqVmx.js} +14 -14
  9. package/dist/{Category-CqneIGq4.js → Category-DMoXTsfG.js} +5 -5
  10. package/dist/{Category-DNQH1CI7.js → Category-DxjdQ-NN.js} +2 -2
  11. package/dist/CategoryList.vue_vue_type_script_setup_true_lang-B3Ts1O-9.js +847 -0
  12. package/dist/{CookingGuide-DTAiFmEL.js → CookingGuide-DiZZDYD-.js} +5 -5
  13. package/dist/{Group-DeUqUomY.js → Group-DFR8q-tt.js} +5 -5
  14. package/dist/{Group-5xO2j3CL.js → Group-rzfh_o6r.js} +2 -2
  15. package/dist/GroupList.vue_vue_type_script_setup_true_lang-DiN-wQXX.js +1807 -0
  16. package/dist/Ingredient-DpjGIuH9.js +505 -0
  17. package/dist/LinkProductSideSheet.vue_vue_type_script_setup_true_lang-CnI80Ojd.js +782 -0
  18. package/dist/{MenuSetting-DdekHsQy.js → MenuSetting-DR-pDSF_.js} +4 -4
  19. package/dist/OrderPacing-JcTuweqF.js +769 -0
  20. package/dist/{OrderPacingFields.vue_vue_type_script_setup_true_lang-C3SqQPSr.js → OrderPacingFields.vue_vue_type_script_setup_true_lang-HwwJ2mGv.js} +2 -2
  21. package/dist/{Preview-DGTw0POk.js → Preview-BZyun5lZ.js} +1 -1
  22. package/dist/{PriceTierNotice.vue_vue_type_script_setup_true_lang-DffhFv0Y.js → PriceTierNotice.vue_vue_type_script_setup_true_lang-DquqNbE1.js} +1 -1
  23. package/dist/PrintRoute-CzEx2dCt.js +518 -0
  24. package/dist/{Product-CsbcyIgD.js → Product-CQb0n06E.js} +4 -4
  25. package/dist/ProductAttributeFilter.vue_vue_type_script_setup_true_lang-B2KdolJS.js +7931 -0
  26. package/dist/{ProductEditorHost.vue_vue_type_script_setup_true_lang--rBKdKV7.js → ProductEditorHost.vue_vue_type_script_setup_true_lang-CBlDEjqF.js} +9 -9
  27. package/dist/ProductGroupCreateSheet.vue_vue_type_script_setup_true_lang-D8NQTCLx.js +2011 -0
  28. package/dist/{ProductImageEditorDialog.vue_vue_type_script_setup_true_lang-DtCzHjpN.js → ProductImageEditorDialog.vue_vue_type_script_setup_true_lang-cG47Pu-6.js} +1 -1
  29. package/dist/{ProductInlineCreateHost.vue_vue_type_script_setup_true_lang-aDx01-WW.js → ProductInlineCreateHost.vue_vue_type_script_setup_true_lang-0UwUcA2L.js} +630 -587
  30. package/dist/{ProductInternalTools-Ccd4dAmx.js → ProductInternalTools-QrBR1nFp.js} +2 -2
  31. package/dist/{ProductInventoryDialog-DYcKdKHi.js → ProductInventoryDialog-fV38GO1a.js} +1 -1
  32. package/dist/{ProductInventoryDialog.vue_vue_type_script_setup_true_lang-DySFcCJz.js → ProductInventoryDialog.vue_vue_type_script_setup_true_lang-Bzb3RrMg.js} +1 -1
  33. package/dist/ProductList.vue_vue_type_script_setup_true_lang-BwKQESr3.js +2765 -0
  34. package/dist/{ProductVariantTranslationSheet.vue_vue_type_script_setup_true_lang-Dw2xiPYX.js → ProductVariantTranslationSheet.vue_vue_type_script_setup_true_lang-CDYcHXo1.js} +1 -1
  35. package/dist/{Products-phZwCZhU.js → Products-B8tysOAL.js} +3 -3
  36. package/dist/Publish-DTvOvFNa.js +1337 -0
  37. package/dist/Recipe-Ddx31csF.js +388 -0
  38. package/dist/{Scheduler-C-A5m92O.js → Scheduler-CST5L_cw.js} +314 -254
  39. package/dist/ServingSequence-DYyEZI2S.js +374 -0
  40. package/dist/{Setting-C24V-lps.js → Setting-Ip0pGjks.js} +6 -6
  41. package/dist/Subcategory-BIgjzVta.js +459 -0
  42. package/dist/{Takeaway-DywX5BiX.js → Takeaway-CekhGM-m.js} +2 -2
  43. package/dist/{Takeaway-BFP2ohJn.js → Takeaway-aXsPg4JT.js} +5 -5
  44. package/dist/{TakeawayList.vue_vue_type_script_setup_true_lang-B3QS7o1v.js → TakeawayList.vue_vue_type_script_setup_true_lang-CaRR4_j3.js} +4 -4
  45. package/dist/TreeEditorOpenner.vue_vue_type_script_setup_true_lang-CshqYpc9.js +1291 -0
  46. package/dist/Unit-BMW8u0Us.js +424 -0
  47. package/dist/{Variant-BBfWhH-s.js → Variant-CZsrYRMU.js} +5 -5
  48. package/dist/{_id_-BooM3FX1.js → _id_-D4swrvNa.js} +3 -3
  49. package/dist/{app-Bmgb8ACe.js → app-BWwwHsWi.js} +312 -312
  50. package/dist/app.js +1 -1
  51. package/dist/apps/mf-menu/src/app.d.ts +60 -0
  52. package/dist/apps/mf-menu/src/components/Product/BulkCategorySelect.vue.d.ts +37 -0
  53. package/dist/apps/mf-menu/src/components/Product/ProductAttributeFilter.vue.d.ts +11 -1
  54. package/dist/apps/mf-menu/src/components/ProductList.vue.d.ts +2 -2
  55. package/dist/apps/mf-menu/src/components/feature/NestedGroupManager/NestedGroupOverrideSheets.vue.d.ts +27 -0
  56. package/dist/apps/mf-menu/src/components/feature/RestaurantAttributesFilter.vue.d.ts +20 -0
  57. package/dist/apps/mf-menu/tsconfig.app.tsbuildinfo +1 -1
  58. package/dist/assets/{menu-compute-CG-fX5pi.js → menu-compute-D7TdiHt4.js} +4 -4
  59. package/dist/assets/{validate-menu-BeGMWVns.js → validate-menu-DXppWUVq.js} +2 -2
  60. package/dist/mf-menu-portal.css +1 -1
  61. package/dist/{provide-CfF0FmUz.js → provide-CDmXzkhz.js} +67990 -66891
  62. package/dist/{useActionFeedback-DyUCQl2x.js → useActionFeedback-Dm2HDa_2.js} +1 -1
  63. package/dist/{FormSection.vue_vue_type_script_setup_true_lang-pY-_msnM.js → vuedraggable-CBtQLb_S.js} +140 -139
  64. package/package.json +2 -2
  65. package/dist/CategoryList.vue_vue_type_script_setup_true_lang-Bt_onPrP.js +0 -797
  66. package/dist/GroupList.vue_vue_type_script_setup_true_lang-Dgya_JLB.js +0 -2183
  67. package/dist/Ingredient-BlDW3TfZ.js +0 -463
  68. package/dist/LinkProductSideSheet.vue_vue_type_script_setup_true_lang-0tCpJlOf.js +0 -709
  69. package/dist/OrderPacing-Bb2n5wmI.js +0 -698
  70. package/dist/PrintRoute-CJB4gIP2.js +0 -473
  71. package/dist/ProductChipSummary.vue_vue_type_script_setup_true_lang-D8DygCBl.js +0 -110
  72. package/dist/ProductGroupCreateSheet.vue_vue_type_script_setup_true_lang-J6LpJ5wT.js +0 -1257
  73. package/dist/ProductList.vue_vue_type_script_setup_true_lang-DTLslTpK.js +0 -10353
  74. package/dist/Publish-BeKIXu3z.js +0 -1261
  75. package/dist/Recipe-Fo4tBkBv.js +0 -350
  76. package/dist/ServingSequence-BrCwLSO7.js +0 -336
  77. package/dist/Subcategory-B0oZIKbw.js +0 -412
  78. package/dist/TreeEditorOpenner.vue_vue_type_script_setup_true_lang-D7mhnrXx.js +0 -1213
  79. package/dist/Unit-NhEwH-kr.js +0 -385
  80. package/dist/apps/mf-menu/src/views/MenuManagementEditor/RestaurantAttributesFilter.vue.d.ts +0 -2
@@ -0,0 +1,769 @@
1
+ import { defineComponent as Q, resolveComponent as k, openBlock as m, createElementBlock as f, createElementVNode as i, toDisplayString as b, unref as l, createVNode as n, withCtx as c, Fragment as q, renderList as re, createBlock as P, createCommentVNode as C, computed as g, ref as I, shallowRef as oe, h as v, withModifiers as V, onUnmounted as Ce } from "vue";
2
+ import { d as Pe, _ as Fe } from "./vuedraggable-CBtQLb_S.js";
3
+ import { useI18n as se } from "@feedmepos/mf-common";
4
+ import { useDialog as Se, useBreakpoints as Ve, components as L, FmButtonColorThemeVariant as T } from "@feedmepos/ui-library";
5
+ import { _ as Le } from "./index.vue_vue_type_script_setup_true_lang-CGPDazqs.js";
6
+ import { _ as Ue } from "./ApplyProduct.vue_vue_type_script_setup_true_lang-Hdsnu29V.js";
7
+ import { _ as $e } from "./OrderPacingFields.vue_vue_type_script_setup_true_lang-HwwJ2mGv.js";
8
+ import { _ as De } from "./LinkProductSideSheet.vue_vue_type_script_setup_true_lang-CnI80Ojd.js";
9
+ import { _ as ze } from "./PageLayout.vue_vue_type_script_setup_true_lang-B3szUH39.js";
10
+ import { _ as Ie } from "./TranslationSideSheet.vue_vue_type_script_setup_true_lang-B0j2PNih.js";
11
+ import { u as Ne } from "./useActionFeedback-Dm2HDa_2.js";
12
+ import { u as Te } from "./useEditorValidation-Ctef5Bxt.js";
13
+ import { b as Be, u as ne, a as Ee } from "./provide-CDmXzkhz.js";
14
+ const Me = {
15
+ key: 0,
16
+ class: "mt-4"
17
+ }, Oe = { class: "text-fm-color-typo-secondary mb-2" }, je = { class: "fm-typo-en-body-md-400 leading-5 text-fm-color-typo-secondary" }, Re = /* @__PURE__ */ Q({
18
+ __name: "DeleteOrderPacingConfirmation",
19
+ props: {
20
+ name: {},
21
+ linkedProductNames: {}
22
+ },
23
+ setup(B) {
24
+ const { t: p } = se();
25
+ return (e, E) => {
26
+ const M = k("FmIcon"), N = k("FmListItem"), x = k("FmList");
27
+ return m(), f("div", null, [
28
+ i("p", null, b(l(p)("menu.order_pacing.dialogs.delete.message", { name: e.name })), 1),
29
+ e.linkedProductNames.length > 0 ? (m(), f("div", Me, [
30
+ i("p", Oe, b(l(p)("menu.order_pacing.dialogs.delete.unlink_warning", {
31
+ count: e.linkedProductNames.length
32
+ })), 1),
33
+ n(x, { class: "mt-8" }, {
34
+ default: c(() => [
35
+ (m(!0), f(q, null, re(e.linkedProductNames, (y) => (m(), P(N, {
36
+ key: y,
37
+ class: "!p-0 !gap-4",
38
+ clickable: !1
39
+ }, {
40
+ prepend: c(() => [
41
+ n(M, {
42
+ color: "typo-secondary",
43
+ name: "fiber_manual_record",
44
+ size: "sm"
45
+ })
46
+ ]),
47
+ default: c(() => [
48
+ i("span", je, b(y), 1)
49
+ ]),
50
+ _: 2
51
+ }, 1024))), 128))
52
+ ]),
53
+ _: 1
54
+ })
55
+ ])) : C("", !0)
56
+ ]);
57
+ };
58
+ }
59
+ }), Ae = {
60
+ key: 0,
61
+ class: "flex-1 flex justify-between gap-8 pl-8"
62
+ }, Ke = { class: "flex items-center" }, qe = { class: "bg-fm-color-neutral-gray-100 rounded-md px-8 py-4" }, Qe = { class: "fm-typo-en-body-md-600 font-semibold" }, Ge = {
63
+ key: 0,
64
+ class: "flex flex-col items-start gap-8"
65
+ }, He = {
66
+ role: "alert",
67
+ class: "text-fm-color-typo-secondary"
68
+ }, Je = {
69
+ key: 3,
70
+ class: "flex-1 flex flex-col min-h-0"
71
+ }, We = { class: "p-8" }, Xe = ["onClick"], Ye = { class: "min-w-0 flex-1 space-y-4" }, Ze = { class: "fm-typo-en-body-lg-600 break-words" }, ea = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, aa = {
72
+ key: 0,
73
+ class: "fixed right-16 bottom-[72px] z-[100]"
74
+ }, la = { class: "flex justify-end items-center" }, ta = { class: "w-[320px]" }, oa = { class: "fm-typo-en-title-md-600" }, na = { class: "flex flex-col gap-32 h-full min-h-0 py-16" }, ra = { class: "py-12 px-16 space-y-4" }, sa = { key: 0 }, ia = { class: "flex-shrink-0" }, da = { class: "flex gap-8 items-center justify-start" }, ua = { class: "fm-typo-en-title-md-600" }, ca = { class: "flex-shrink-0" }, ma = { class: "flex gap-8 items-center justify-start" }, pa = /* @__PURE__ */ Q({
75
+ __name: "OrderPacingList",
76
+ props: {
77
+ sdk: {}
78
+ },
79
+ setup(B) {
80
+ const p = B, { t: e, n: E } = se(), M = Be(), N = Se(), { run: x } = Ne(), y = ne(p.sdk.orderPacing.list), u = g(
81
+ () => y.value.status === "ready" ? y.value.value : null
82
+ ), O = g(() => {
83
+ var a;
84
+ return ((a = u.value) == null ? void 0 : a.query) ?? "";
85
+ }), { breakpoints: ie } = Ve(), G = g(() => ie.value.xs), H = g(() => {
86
+ var a;
87
+ return [...((a = u.value) == null ? void 0 : a.rows) ?? []];
88
+ }), F = I(!1), U = I(!1), S = I(!1), j = I(!1);
89
+ async function de() {
90
+ j.value = !0;
91
+ try {
92
+ await x(() => p.sdk.orderPacing.retryRead(), {
93
+ showLoading: !1
94
+ });
95
+ } finally {
96
+ j.value = !1;
97
+ }
98
+ }
99
+ const J = ne(
100
+ p.sdk.linkProduct.catalogue
101
+ ), ue = g(
102
+ () => J.value.status === "ready" ? J.value.value : null
103
+ ), d = oe(
104
+ p.sdk.orderPacing.editor()
105
+ ), $ = oe(
106
+ d.value.get()
107
+ );
108
+ let R = d.value.subscribe((a) => {
109
+ $.value = a;
110
+ });
111
+ const s = g(
112
+ () => $.value.status === "ready" ? $.value.value : null
113
+ ), W = Te(() => d.value), ce = g(() => {
114
+ var a;
115
+ return [
116
+ ...((a = s.value) == null ? void 0 : a.linkedProducts) ?? []
117
+ ];
118
+ }), me = g(
119
+ () => {
120
+ var a;
121
+ return ((a = s.value) == null ? void 0 : a.linkedProductIds) ?? [];
122
+ }
123
+ );
124
+ function pe(a) {
125
+ var t, r;
126
+ return ((r = (t = s.value) == null ? void 0 : t.supportedLocales.find(
127
+ (h) => h.code === a
128
+ )) == null ? void 0 : r.name) ?? a;
129
+ }
130
+ function ve() {
131
+ var a;
132
+ ((a = s.value) == null ? void 0 : a.translation.state) === "allowed" && (d.value.beginTranslationEdit(), S.value = !0);
133
+ }
134
+ function _e() {
135
+ d.value.saveTranslationEdit(), S.value = !1;
136
+ }
137
+ function X() {
138
+ d.value.discardTranslationEdit(), S.value = !1;
139
+ }
140
+ function A(a) {
141
+ R(), d.value.dispose(), d.value = p.sdk.orderPacing.editor(a), $.value = d.value.get(), R = d.value.subscribe((t) => {
142
+ $.value = t;
143
+ });
144
+ }
145
+ function K() {
146
+ var a;
147
+ ((a = u.value) == null ? void 0 : a.create.state) === "allowed" && (A(), S.value = !1, F.value = !0);
148
+ }
149
+ function Y(a) {
150
+ A(a.id), S.value = !1, F.value = !0;
151
+ }
152
+ async function ge() {
153
+ var r;
154
+ const a = ((r = s.value) == null ? void 0 : r.name.trim()) ?? "";
155
+ (await x(
156
+ () => W.submit(() => d.value.submit()),
157
+ {
158
+ // The inline field rules are decided in the SDK with no round trip, and
159
+ // the frozen `create/validation-name` frame shows the sheet with no
160
+ // loading indicator — so a rejected submit must not flash one.
161
+ showLoading: () => {
162
+ var h;
163
+ return ((h = s.value) == null ? void 0 : h.status) === "submitting";
164
+ },
165
+ successMessage: e("menu.order_pacing.form.saved", {
166
+ name: a || e("menu.order_pacing.title")
167
+ })
168
+ }
169
+ )).kind === "success" && (F.value = !1);
170
+ }
171
+ function Z(a) {
172
+ if (a.remove.state !== "allowed") return;
173
+ const t = p.sdk.orderPacing.describeDelete(a.id);
174
+ t && N.open({
175
+ title: e("menu.order_pacing.dialogs.delete.title"),
176
+ // Both sentences come from the SDK's view model: the names of the
177
+ // products that will be unlinked are a join over the aggregate, and
178
+ // resolving them here would be the per-feature derivation ADR-0002 §3
179
+ // forbids. The warning is a warning only — the delete always commits
180
+ // and cascades, and there is no referenced-delete guard to migrate.
181
+ // A COMPONENT, not a `message` string. The body is three blocks — the
182
+ // question, a secondary warning line and a bulleted list of the
183
+ // products about to be unlinked — and joining them with '\n' renders
184
+ // one collapsed paragraph, because the dialog puts the string into HTML
185
+ // where a newline is whitespace. The frozen golden
186
+ // `serveDelay/delete/confirm-linked` is 560x244; the collapsed string
187
+ // measured 560x200, which is how the visual gate caught it on
188
+ // 2026-09-07. Legacy passes a `contentComponent` here too
189
+ // (`portal .../manager/menu/order_pacing.ts:111-114`).
190
+ contentComponent: v(Re, {
191
+ name: a.name,
192
+ linkedProductNames: t.linkedProductNames
193
+ }),
194
+ // `close: false` on purpose: two frozen pending states name `.fm-dialog`
195
+ // as this module's delete pending surface, because legacy's manager
196
+ // declares the same and calls `dialog.close()` only after the write
197
+ // resolves (`portal .../manager/menu/order_pacing.ts:115-118,134`).
198
+ // Dismissing on the click would leave the shared loading snackbar as the
199
+ // only pending surface — a behaviour difference from the baseline that
200
+ // nobody approved.
201
+ primaryActions: {
202
+ text: e("menu.common.actions.remove"),
203
+ close: !1
204
+ // NO `variant`, so the library's default Primary applies. Legacy's
205
+ // `primaryActions` declares none either
206
+ // (`portal .../manager/menu/order_pacing.ts:115-118`), and the frozen
207
+ // goldens `serveDelay/delete/confirm` and `.../confirm-linked` show an
208
+ // ORANGE Remove. `FmButtonVariant.Destructive` rendered it red — a
209
+ // difference nobody approved, caught by the visual gate 2026-09-07.
210
+ },
211
+ secondaryActions: {
212
+ text: e("menu.common.actions.cancel"),
213
+ close: !0
214
+ }
215
+ }).onPrimary(async () => {
216
+ await x(() => p.sdk.orderPacing.remove(a.id), {
217
+ // 'removed', not 'saved': legacy's manager passes `isDelete` true and
218
+ // the shared loader picks the other sentence.
219
+ successMessage: e("menu.order_pacing.delete.success", {
220
+ name: a.name
221
+ })
222
+ }), N.close();
223
+ });
224
+ }
225
+ const fe = g(() => {
226
+ var a;
227
+ return ((a = u.value) == null ? void 0 : a.reorder.state) === "allowed";
228
+ });
229
+ function ee(a) {
230
+ var r;
231
+ if (((r = u.value) == null ? void 0 : r.reorder.state) !== "allowed") return;
232
+ const t = a.map((h) => h.id);
233
+ t.length && x(() => p.sdk.orderPacing.reorder(t), {
234
+ // A rearrange carries no single entity, so legacy fed the shared
235
+ // `{name} saved` template the MODULE's own title and the toast reads
236
+ // "Order pacing saved". Each locale carries the whole sentence rather
237
+ // than interpolating a title, because the word order of "{name} saved"
238
+ // does not survive translation.
239
+ successMessage: e("menu.order_pacing.reorder.success")
240
+ });
241
+ }
242
+ const be = g(() => [
243
+ {
244
+ accessorKey: "name",
245
+ header: () => e("menu.order_pacing.columns.timing_label"),
246
+ enableSorting: !1
247
+ },
248
+ {
249
+ accessorKey: "delay",
250
+ header: () => e("menu.order_pacing.columns.delay"),
251
+ enableSorting: !1
252
+ },
253
+ {
254
+ accessorKey: "linkedProductCount",
255
+ header: () => e("menu.order_pacing.columns.items"),
256
+ enableSorting: !1,
257
+ // Legacy renders this cell as a dashed-underline affordance that opens the
258
+ // apply-product sheet on click, stopping propagation so the row's own
259
+ // click does not open the editor (`OrderPacingTable.vue:60-84`).
260
+ cell: (a) => v(L.FmButton, {
261
+ label: e("menu.common.labels.items_linked", {
262
+ count: a.row.original.linkedProductCount
263
+ }),
264
+ variant: "tertiary",
265
+ onClick: V(
266
+ () => ye(a.row.original),
267
+ ["stop", "prevent"]
268
+ )
269
+ })
270
+ },
271
+ {
272
+ id: "actions",
273
+ size: 52,
274
+ meta: { cellClass: "pl-16", headerContentClass: "-mx-16" },
275
+ header: "",
276
+ cell: (a) => v("div", { class: "w-full flex justify-end items-center" }, [
277
+ v(L.FmButton, {
278
+ prependIcon: "delete",
279
+ variant: "tertiary",
280
+ textColor: "neutral-gray-400",
281
+ disabled: a.row.original.remove.state !== "allowed",
282
+ // The one deliberate addition to legacy's DOM, owned by the new
283
+ // app: legacy's control is icon-only and unnamed, so no semantic
284
+ // locator resolves against it.
285
+ "aria-label": e("menu.common.actions.delete"),
286
+ onClick: V(
287
+ () => Z(a.row.original),
288
+ ["stop", "prevent"]
289
+ )
290
+ })
291
+ ])
292
+ }
293
+ ]), D = I(!1);
294
+ function ye(a) {
295
+ A(a.id), D.value = !0;
296
+ }
297
+ async function ke() {
298
+ var t;
299
+ (await x(() => d.value.submitLinks(), {
300
+ showLoading: () => {
301
+ var r;
302
+ return ((r = s.value) == null ? void 0 : r.status) === "submitting";
303
+ },
304
+ successMessage: e("menu.order_pacing.form.saved", {
305
+ name: ((t = s.value) == null ? void 0 : t.name) ?? e("menu.order_pacing.title")
306
+ })
307
+ })).kind === "success" && (D.value = !1);
308
+ }
309
+ const he = g(() => [
310
+ {
311
+ id: "default",
312
+ size: 75,
313
+ enableSorting: !1,
314
+ header: () => e("menu.order_pacing.link_product.table.column.default"),
315
+ cell: (a) => v(L.FmCheckbox, {
316
+ modelValue: a.row.original.isDefault,
317
+ value: "",
318
+ "aria-label": e("menu.common.labels.a11y_labelled_name", {
319
+ label: e("menu.order_pacing.link_product.table.column.default"),
320
+ name: a.row.original.name
321
+ }),
322
+ // Bound one-way from the SDK's draft and pushed back through the
323
+ // editor, so the control cannot hold a state the model does not have.
324
+ // Legacy's does exactly that in create mode — it renders ticked while
325
+ // `isDefault: false` goes to the wire — a defect approved for fixing.
326
+ "onUpdate:modelValue": (t) => d.value.setProductDefault(
327
+ a.row.original.productId,
328
+ t
329
+ )
330
+ })
331
+ },
332
+ {
333
+ accessorKey: "name",
334
+ enableSorting: !1,
335
+ header: () => e("menu.order_pacing.link_product.table.column.product_name"),
336
+ cell: (a) => v("span", { class: "text-wrap" }, a.row.original.name)
337
+ },
338
+ {
339
+ accessorKey: "productCode",
340
+ enableSorting: !1,
341
+ header: () => e("menu.order_pacing.link_product.table.column.product_code"),
342
+ cell: (a) => v("span", { class: "text-wrap" }, a.row.original.productCode ?? "")
343
+ },
344
+ {
345
+ id: "currentDefault",
346
+ enableSorting: !1,
347
+ header: () => e("menu.order_pacing.link_product.table.column.current_default"),
348
+ /**
349
+ * RECORDED ADR-0003 §1 GAP: the library has no outlined chip.
350
+ *
351
+ * Legacy renders this as an OUTLINED chip — transparent ground, primary
352
+ * border and primary text for a set default, grey border for "None"
353
+ * (`LinkProductTable.vue:96-115`). Every `FmChip` variant is FILLED and
354
+ * sets its own background plus white or black text
355
+ * (`plain`→`bg-fm-color-neutral-gray-100`, `neutral`→`bg-…-black`,
356
+ * `info`→`bg-…-blueberry`, `success`→mint, `critical`→salmon,
357
+ * `warning`→mustard), and the union carries no primary at all
358
+ * (`FmChipVariant` in the installed d.ts). So no variant can express this
359
+ * control, and substituting a filled one would change the frozen goldens
360
+ * for `serveDelay/update/form` and
361
+ * `serveDelay/create/form-with-linked-products` — a visual difference only
362
+ * a human may approve (ADR-0003 §5).
363
+ *
364
+ * Colours are `fm-*` tokens, not literals, so §2 holds. Replace this
365
+ * with `FmChip` if the library ever ships an outlined variant.
366
+ */
367
+ cell: (a) => {
368
+ const t = a.row.original.currentDefault;
369
+ return v("div", { class: "pt-1" }, [
370
+ t ? v(
371
+ "span",
372
+ {
373
+ class: "text-fm-color-primary border border-fm-color-primary rounded-md px-8"
374
+ },
375
+ e("menu.order_pacing.columns.mins", { count: t.delay })
376
+ ) : v(
377
+ "span",
378
+ {
379
+ class: "text-fm-color-typo-secondary border rounded-md px-8"
380
+ },
381
+ e("menu.order_pacing.columns.none")
382
+ )
383
+ ]);
384
+ }
385
+ },
386
+ {
387
+ id: "actions",
388
+ size: 40,
389
+ enableSorting: !1,
390
+ header: "",
391
+ /**
392
+ * `cellClass: ''` is load-bearing, not styling taste.
393
+ *
394
+ * `FmTable` falls back to `px-16` for every cell (`cellClass ?? "px-16"`
395
+ * in the installed build), and this table is `table-layout: auto`, so
396
+ * that 32px of padding on a 40px-wide column does not shrink the column —
397
+ * it takes 27px away from the three auto-width columns beside it. Legacy
398
+ * declares `meta: { cellClass: "" }` on exactly this column
399
+ * (`portal .../OrderPacingManager/LinkProductTable.vue`), which is why
400
+ * its columns measure 82/144/143/142/41 where ours measured
401
+ * 82/134/134/134/68 — and why "Current Default" wrapped onto a second
402
+ * line here and onto none in the frozen goldens. The wrap then moved
403
+ * every row below it, which is the whole diff on
404
+ * `serveDelay/create/link-product-picker`,
405
+ * `serveDelay/create/form-with-linked-products` and
406
+ * `serveDelay/update/form`.
407
+ *
408
+ * The button is rendered straight into the cell, as legacy renders it: a
409
+ * `flex justify-end` wrapper inside an unpadded 41px column would push
410
+ * the icon a pixel off the golden for no gain.
411
+ */
412
+ meta: { cellClass: "" },
413
+ cell: (a) => v("div", {}, [
414
+ v(L.FmButton, {
415
+ prependIcon: "delete",
416
+ variant: "tertiary",
417
+ // No `textColor`, unlike the LIST table's own delete at :305.
418
+ // Legacy sets none here either, so the icon takes the tertiary
419
+ // default; forcing `neutral-gray-400` measured 107 against the
420
+ // golden's 29 on the darkest pixel of a 17x18 glyph, and that
421
+ // 200-pixel patch is over a third of what
422
+ // `serveDelay/create/form-with-linked-products` still had to close.
423
+ "aria-label": e("menu.common.actions.delete"),
424
+ onClick: V(
425
+ () => d.value.unlinkProduct(a.row.original.productId),
426
+ ["stop", "prevent"]
427
+ )
428
+ })
429
+ ])
430
+ }
431
+ ]);
432
+ Ce(() => {
433
+ R(), d.value.dispose(), p.sdk.orderPacing.search("");
434
+ });
435
+ function xe(a) {
436
+ d.value.setLinkedProducts(a), U.value = !1;
437
+ }
438
+ return (a, t) => {
439
+ const r = k("FmButton"), h = k("FmCircularProgress"), ae = k("FmSearch"), le = k("FmTable"), we = k("FmTooltip"), te = k("FmSideSheet");
440
+ return m(), P(ze, {
441
+ "data-visual-root": "serveDelay",
442
+ heading: l(e)("menu.order_pacing.title")
443
+ }, {
444
+ "append-heading": c(() => [
445
+ l(y).status === "ready" && u.value ? (m(), f("div", Ae, [
446
+ i("div", Ke, [
447
+ i("div", qe, [
448
+ i("p", Qe, b(l(E)(u.value.totalCount)), 1)
449
+ ])
450
+ ]),
451
+ u.value.totalCount > 0 && !G.value ? (m(), P(r, {
452
+ key: 0,
453
+ disabled: u.value.create.state !== "allowed",
454
+ label: l(e)("menu.order_pacing.add"),
455
+ "prepend-icon": "add",
456
+ onClick: K
457
+ }, null, 8, ["disabled", "label"])) : C("", !0)
458
+ ])) : C("", !0)
459
+ ]),
460
+ default: c(() => [
461
+ l(y).status === "error" ? (m(), f("div", Ge, [
462
+ i("p", He, b(l(M)(l(y).error.message)), 1),
463
+ n(r, {
464
+ label: l(e)("menu.common.actions.retry"),
465
+ loading: j.value,
466
+ variant: "secondary",
467
+ onClick: de
468
+ }, null, 8, ["label", "loading"])
469
+ ])) : l(y).status === "loading" ? (m(), P(h, { key: 1 })) : u.value && u.value.rows.length === 0 && !O.value ? (m(), P(l(Le), {
470
+ key: 2,
471
+ action: { text: l(e)("menu.order_pacing.add"), callback: K },
472
+ title: l(e)("menu.order_pacing.empty.title"),
473
+ subtitle: l(e)("menu.order_pacing.empty.subtitle")
474
+ }, null, 8, ["action", "title", "subtitle"])) : u.value && G.value ? (m(), f("div", Je, [
475
+ i("div", We, [
476
+ n(ae, {
477
+ autofocus: "",
478
+ class: "mb-8",
479
+ "model-value": O.value,
480
+ placeholder: l(e)("menu.common.labels.search_placeholder", {
481
+ type: l(e)("menu.order_pacing.title")
482
+ }),
483
+ "onUpdate:modelValue": p.sdk.orderPacing.search
484
+ }, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"])
485
+ ]),
486
+ n(l(Pe), {
487
+ class: "flex flex-1 flex-col min-h-0 overflow-scroll divide-y divide-fm-color-neutral-gray-100 pb-64",
488
+ disabled: u.value.reorder.state !== "allowed",
489
+ handle: ".handle",
490
+ "item-key": "id",
491
+ "model-value": H.value,
492
+ "onUpdate:modelValue": ee
493
+ }, {
494
+ item: c(({ element: o }) => [
495
+ i("div", {
496
+ class: "flex flex-row items-center py-12 px-16",
497
+ onClick: (_) => Y(o)
498
+ }, [
499
+ n(r, {
500
+ class: "handle cursor-grab mr-8 shrink-0",
501
+ "aria-label": l(e)("menu.common.labels.a11y_labelled_name", {
502
+ label: l(e)("menu.common.actions.move"),
503
+ name: o.name
504
+ }),
505
+ disabled: u.value.reorder.state !== "allowed",
506
+ "prepend-icon": "drag_handle",
507
+ variant: "tertiary",
508
+ onClick: t[0] || (t[0] = V(() => {
509
+ }, ["stop"]))
510
+ }, null, 8, ["aria-label", "disabled"]),
511
+ i("div", Ye, [
512
+ i("p", Ze, b(o.name), 1),
513
+ i("p", ea, b(l(e)("menu.common.labels.product_linked", {
514
+ count: o.linkedProductCount
515
+ })), 1)
516
+ ]),
517
+ n(r, {
518
+ class: "shrink-0",
519
+ "aria-label": l(e)("menu.common.actions.delete"),
520
+ disabled: o.remove.state !== "allowed",
521
+ "prepend-icon": "delete",
522
+ "text-color": "neutral-gray-400",
523
+ variant: "tertiary",
524
+ onClick: V((_) => Z(o), ["stop"])
525
+ }, null, 8, ["aria-label", "disabled", "onClick"])
526
+ ], 8, Xe)
527
+ ]),
528
+ _: 1
529
+ }, 8, ["disabled", "model-value"]),
530
+ u.value.totalCount > 0 ? (m(), f("div", aa, [
531
+ n(r, {
532
+ disabled: u.value.create.state !== "allowed",
533
+ label: l(e)("menu.order_pacing.add"),
534
+ "prepend-icon": "add",
535
+ variant: "fab",
536
+ onClick: K
537
+ }, null, 8, ["disabled", "label"])
538
+ ])) : C("", !0)
539
+ ])) : u.value ? (m(), f(q, { key: 4 }, [
540
+ i("div", la, [
541
+ i("div", ta, [
542
+ n(ae, {
543
+ autofocus: "",
544
+ class: "mb-8",
545
+ "model-value": O.value,
546
+ placeholder: l(e)("menu.common.labels.search_placeholder", {
547
+ type: l(e)("menu.order_pacing.title")
548
+ }),
549
+ "onUpdate:modelValue": p.sdk.orderPacing.search
550
+ }, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"])
551
+ ])
552
+ ]),
553
+ n(le, {
554
+ "column-defs": be.value,
555
+ "hide-footer": "",
556
+ "page-size": u.value.rows.length,
557
+ "pin-header-row": "",
558
+ "row-data": H.value,
559
+ "shrink-at": !1,
560
+ draggable: fe.value,
561
+ onRowClick: t[1] || (t[1] = (o) => Y(o.original)),
562
+ onDndChanged: ee
563
+ }, null, 8, ["column-defs", "page-size", "row-data", "draggable"])
564
+ ], 64)) : C("", !0),
565
+ n(te, {
566
+ modelValue: F.value,
567
+ "onUpdate:modelValue": t[5] || (t[5] = (o) => F.value = o),
568
+ "is-container": l(L).FmForm,
569
+ "is-container-props": {
570
+ onValidationSuccess: ge,
571
+ blameFormChildOnValidationFailed: !0
572
+ },
573
+ "max-width": 600
574
+ }, {
575
+ "side-sheet-header": c(() => {
576
+ var o;
577
+ return [
578
+ i("p", oa, b(((o = s.value) == null ? void 0 : o.mode) === "update" ? l(e)("menu.order_pacing.manager.dialog.update.title") : l(e)("menu.order_pacing.manager.dialog.add.title")), 1)
579
+ ];
580
+ }),
581
+ "side-sheet-footer": c(() => {
582
+ var o, _;
583
+ return [
584
+ i("div", da, [
585
+ n(r, {
586
+ disabled: ((o = s.value) == null ? void 0 : o.submit.state) !== "allowed",
587
+ label: ((_ = s.value) == null ? void 0 : _.mode) === "update" ? l(e)("menu.common.actions.update") : l(e)("menu.order_pacing.manager.dialog.add.action"),
588
+ size: "lg",
589
+ type: "submit",
590
+ variant: "primary"
591
+ }, null, 8, ["disabled", "label"]),
592
+ n(r, {
593
+ label: l(e)("menu.common.actions.cancel"),
594
+ size: "lg",
595
+ variant: "tertiary",
596
+ onClick: t[4] || (t[4] = (z) => F.value = !1)
597
+ }, null, 8, ["label"])
598
+ ])
599
+ ];
600
+ }),
601
+ default: c(() => [
602
+ i("div", na, [
603
+ n($e, {
604
+ view: s.value,
605
+ session: d.value,
606
+ validation: l(W)
607
+ }, {
608
+ "name-append": c(() => [
609
+ n(we, {
610
+ variant: "plain",
611
+ placement: "top",
612
+ "z-index": 999
613
+ }, {
614
+ content: c(() => {
615
+ var o, _;
616
+ return [
617
+ i("div", ra, [
618
+ Object.keys(((o = s.value) == null ? void 0 : o.nameLocale) ?? {}).length === 0 ? (m(), f("div", sa, b(l(e)("menu.common.translation.translation_label")), 1)) : C("", !0),
619
+ (m(!0), f(q, null, re((_ = s.value) == null ? void 0 : _.nameLocale, (z, w) => (m(), f("div", { key: w }, b(l(e)("menu.order_pacing.translation.tooltip_value", {
620
+ value: z,
621
+ locale: pe(w)
622
+ })), 1))), 128))
623
+ ])
624
+ ];
625
+ }),
626
+ default: c(() => [
627
+ n(r, {
628
+ "aria-label": l(e)("menu.common.translation.translation_label"),
629
+ icon: "g_translate",
630
+ variant: "tertiary",
631
+ onClick: ve
632
+ }, null, 8, ["aria-label"])
633
+ ]),
634
+ _: 1
635
+ })
636
+ ]),
637
+ _: 1
638
+ }, 8, ["view", "session", "validation"]),
639
+ n(Fe, {
640
+ title: l(e)("menu.order_pacing.product.title"),
641
+ "sub-title": l(e)("menu.order_pacing.product.subtitle")
642
+ }, {
643
+ "append-title": c(() => [
644
+ i("div", ia, [
645
+ n(r, {
646
+ "border-color": l(T).ColorPrimary,
647
+ label: l(e)("menu.order_pacing.link_product.title"),
648
+ "prepend-icon": "link",
649
+ "text-color": l(T).ColorPrimary,
650
+ variant: "secondary",
651
+ type: "button",
652
+ onPointerdown: t[2] || (t[2] = V(() => {
653
+ }, ["prevent"])),
654
+ onClick: t[3] || (t[3] = (o) => U.value = !0)
655
+ }, null, 8, ["border-color", "label", "text-color"])
656
+ ])
657
+ ]),
658
+ default: c(() => [
659
+ n(le, {
660
+ "column-defs": he.value,
661
+ "hide-footer": "",
662
+ "page-size": 999,
663
+ "row-data": ce.value,
664
+ "shrink-at": !1
665
+ }, null, 8, ["column-defs", "row-data"])
666
+ ]),
667
+ _: 1
668
+ }, 8, ["title", "sub-title"])
669
+ ])
670
+ ]),
671
+ _: 1
672
+ }, 8, ["modelValue", "is-container", "is-container-props"]),
673
+ s.value ? (m(), P(Ie, {
674
+ key: 5,
675
+ "model-value": S.value,
676
+ "onUpdate:modelValue": t[6] || (t[6] = (o) => o || X()),
677
+ dirty: s.value.translationDirty,
678
+ name: s.value.name,
679
+ "name-locale": s.value.nameLocale,
680
+ "name-section-label": l(e)("menu.order_pacing.translation.name_section"),
681
+ "supported-locales": s.value.supportedLocales,
682
+ title: l(e)("menu.order_pacing.translation.title"),
683
+ onDiscard: X,
684
+ onSave: _e,
685
+ "onUpdate:name": d.value.setName,
686
+ "onUpdate:nameLocale": d.value.setNameLocale
687
+ }, null, 8, ["model-value", "dirty", "name", "name-locale", "name-section-label", "supported-locales", "title", "onUpdate:name", "onUpdate:nameLocale"])) : C("", !0),
688
+ n(te, {
689
+ modelValue: D.value,
690
+ "onUpdate:modelValue": t[11] || (t[11] = (o) => D.value = o),
691
+ "is-container": l(L).FmForm,
692
+ "is-container-props": { onValidationSuccess: ke },
693
+ "max-width": 560
694
+ }, {
695
+ "side-sheet-header": c(() => [
696
+ i("p", ua, b(l(e)("menu.order_pacing.link_product.title")), 1)
697
+ ]),
698
+ "side-sheet-footer": c(() => {
699
+ var o;
700
+ return [
701
+ i("div", ma, [
702
+ n(r, {
703
+ disabled: ((o = s.value) == null ? void 0 : o.submit.state) !== "allowed",
704
+ label: l(e)("menu.common.actions.save"),
705
+ size: "lg",
706
+ type: "submit",
707
+ variant: "primary"
708
+ }, null, 8, ["disabled", "label"]),
709
+ n(r, {
710
+ label: l(e)("menu.common.actions.cancel"),
711
+ size: "lg",
712
+ variant: "tertiary",
713
+ onClick: t[10] || (t[10] = (_) => D.value = !1)
714
+ }, null, 8, ["label"])
715
+ ])
716
+ ];
717
+ }),
718
+ default: c(() => {
719
+ var o, _, z;
720
+ return [
721
+ n(Ue, {
722
+ "applied-count": ((o = s.value) == null ? void 0 : o.appliedProductCount) ?? 0,
723
+ groups: ((_ = s.value) == null ? void 0 : _.linkedGroups) ?? [],
724
+ query: ((z = s.value) == null ? void 0 : z.linkedProductQuery) ?? "",
725
+ title: l(e)("menu.order_pacing.product.title"),
726
+ onUnapply: t[8] || (t[8] = (w) => d.value.unlinkProduct(w)),
727
+ "onUpdate:query": t[9] || (t[9] = (w) => d.value.setLinkedProductQuery(w))
728
+ }, {
729
+ "append-title": c(() => [
730
+ i("div", ca, [
731
+ n(r, {
732
+ "border-color": l(T).ColorPrimary,
733
+ label: l(e)("menu.common.actions.apply_product"),
734
+ "prepend-icon": "link",
735
+ "text-color": l(T).ColorPrimary,
736
+ variant: "secondary",
737
+ onClick: t[7] || (t[7] = (w) => U.value = !0)
738
+ }, null, 8, ["border-color", "label", "text-color"])
739
+ ])
740
+ ]),
741
+ _: 1
742
+ }, 8, ["applied-count", "groups", "query", "title"])
743
+ ];
744
+ }),
745
+ _: 1
746
+ }, 8, ["modelValue", "is-container", "is-container-props"]),
747
+ n(De, {
748
+ modelValue: U.value,
749
+ "onUpdate:modelValue": t[12] || (t[12] = (o) => U.value = o),
750
+ catalogue: ue.value,
751
+ "selected-product-ids": me.value,
752
+ title: l(e)("menu.order_pacing.link_product.title"),
753
+ onSubmit: xe
754
+ }, null, 8, ["modelValue", "catalogue", "selected-product-ids", "title"])
755
+ ]),
756
+ _: 1
757
+ }, 8, ["heading"]);
758
+ };
759
+ }
760
+ }), Sa = /* @__PURE__ */ Q({
761
+ __name: "OrderPacing",
762
+ setup(B) {
763
+ const p = Ee();
764
+ return (e, E) => (m(), P(pa, { sdk: l(p) }, null, 8, ["sdk"]));
765
+ }
766
+ });
767
+ export {
768
+ Sa as default
769
+ };