@feedmepos/mf-menu 0.32.12-dev → 0.32.13

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 (64) hide show
  1. package/dist/{App-D0JZMDPU.js → App-D70-FH5L.js} +7 -7
  2. package/dist/{ApplyProduct.vue_vue_type_script_setup_true_lang-C5fI7pDt.js → ApplyProduct.vue_vue_type_script_setup_true_lang-BJdja2N0.js} +3 -3
  3. package/dist/{Catalog-BIVVmu4F.js → Catalog-WMpN3a0p.js} +6 -6
  4. package/dist/{Category-Cmf6dD5G.js → Category-BwHhFTZ-.js} +6 -6
  5. package/dist/{Category-DoEzIDPA.js → Category-C_VsQIHU.js} +4 -4
  6. package/dist/{CookingGuide-DxQ5vDF5.js → CookingGuide-D9RNkYDL.js} +4 -4
  7. package/dist/{CustomAttributeChip.vue_vue_type_script_setup_true_lang-BQscJC6_.js → CustomAttributeChip.vue_vue_type_script_setup_true_lang-DtmrxDZm.js} +1 -1
  8. package/dist/{Group-EAACXFDr.js → Group-DexONgr2.js} +1 -1
  9. package/dist/{Group-l59a7MQy.js → Group-qRZlg5ST.js} +3 -3
  10. package/dist/{Group.vue_vue_type_script_setup_true_lang-CdIKM2jO.js → Group.vue_vue_type_script_setup_true_lang-DtPY9uUt.js} +7 -7
  11. package/dist/{GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-CendqbFI.js → GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-B5Qpmj2f.js} +5 -5
  12. package/dist/{ImportProductDialog.vue_vue_type_script_setup_true_lang-B3I3jPxC.js → ImportProductDialog.vue_vue_type_script_setup_true_lang-BqhNkaw_.js} +27456 -27454
  13. package/dist/{Ingredient-B7kPk3oV.js → Ingredient-BuOS_Wvm.js} +3 -3
  14. package/dist/{InventoryBinding.vue_vue_type_script_setup_true_lang-CzpY9mWg.js → InventoryBinding.vue_vue_type_script_setup_true_lang-DFvXklj9.js} +2 -2
  15. package/dist/{LinkProductSideSheet-CeXhbGnn.js → LinkProductSideSheet-DJj8Nn4X.js} +3 -3
  16. package/dist/{MenuSetting-CCtL2qui.js → MenuSetting-D6B0gCGV.js} +5 -5
  17. package/dist/{PrintRoute-DMLRAZJg.js → PrintRoute-B7G8f1iC.js} +4 -4
  18. package/dist/{Product-BAcGhIEf.js → Product-DpS5EepJ.js} +1 -1
  19. package/dist/{Product.vue_vue_type_script_setup_true_lang-V8-_F7WQ.js → Product.vue_vue_type_script_setup_true_lang-CdIukLqA.js} +12 -12
  20. package/dist/{ProductInternalTools-BrQwrwyG.js → ProductInternalTools-CBCyWHOS.js} +6 -6
  21. package/dist/Products-CcyGNlUl.js +794 -0
  22. package/dist/{Publish-CtKo19_y.js → Publish-rZLHFaJ5.js} +54 -52
  23. package/dist/{Recipe-ORx3rnvx.js → Recipe-D14rkATU.js} +4 -4
  24. package/dist/{RuleView.vue_vue_type_script_setup_true_lang-biTDrokQ.js → RuleView.vue_vue_type_script_setup_true_lang-CdH2ius3.js} +134 -134
  25. package/dist/{Scheduler-B7v3W8eG.js → Scheduler-DWZqa-jf.js} +3 -3
  26. package/dist/{ServingSequence-DczYH8BU.js → ServingSequence-Mx7ovvJ1.js} +3 -3
  27. package/dist/{Setting-fNLED9R0.js → Setting-DmHuVXVn.js} +5 -5
  28. package/dist/{Subcategory-DjK1PTao.js → Subcategory-DixZPdnT.js} +4 -4
  29. package/dist/{Takeaway-LjEJbd4e.js → Takeaway-BVIymFV_.js} +4 -4
  30. package/dist/{Takeaway-ChMYycO_.js → Takeaway-DDKeDEbV.js} +1 -1
  31. package/dist/{Takeaway.vue_vue_type_script_setup_true_lang-CMdZM60P.js → Takeaway.vue_vue_type_script_setup_true_lang-CTaCQgRv.js} +5 -5
  32. package/dist/{Thumbnail.vue_vue_type_script_setup_true_lang-Yh_aUxqS.js → Thumbnail.vue_vue_type_script_setup_true_lang-DveI9xvU.js} +4 -4
  33. package/dist/{TreeEditorOpenner.vue_vue_type_script_setup_true_lang-CEmOkHc5.js → TreeEditorOpenner.vue_vue_type_script_setup_true_lang-2nBbq_Yk.js} +14 -14
  34. package/dist/{Unit-DGZ9xVpM.js → Unit-utuaNZBw.js} +2 -2
  35. package/dist/{Variant-CUasE1B5.js → Variant-CzuJNwen.js} +3 -3
  36. package/dist/{_id_-CXV1a1UW.js → _id_-DMDhPQCr.js} +9 -9
  37. package/dist/{app--9ZjQ_dH.js → app-BQUkvrAS.js} +26 -26
  38. package/dist/{app-E7mszfIB.js → app-Bqj3cAPJ.js} +1 -1
  39. package/dist/app.js +1 -1
  40. package/dist/apps/mf-menu/src/helper/menuExport.d.ts +22 -0
  41. package/dist/apps/mf-menu/tsconfig.app.tsbuildinfo +1 -1
  42. package/dist/assets/{validate-menu-BS4T4zZm.js → linked-status-ILQVL8r9.js} +7 -7
  43. package/dist/assets/{override-menu-BWkFILg4.js → override-menu-DVkGhbA9.js} +2 -2
  44. package/dist/assets/{linked-status-Doclb1U6.js → validate-menu-y_NQUL02.js} +7 -7
  45. package/dist/{catalog-PkvD9BV_.js → catalog-BYzITAmC.js} +1 -1
  46. package/dist/{catalogSetting-Cd9aIJs2.js → catalogSetting-DAo5tN3P.js} +1 -1
  47. package/dist/{category-1NLh1OVo.js → category-D4x8r_lY.js} +1 -1
  48. package/dist/{currency-J1RZcMOx.js → currency-CvoBdMM2.js} +1 -1
  49. package/dist/{dayjs.min-CXjOYO85.js → dayjs.min-C6xioui7.js} +1 -1
  50. package/dist/{index-BPpNi-Hh.js → index-6lju0f3r.js} +3 -3
  51. package/dist/{index-BiCSP8Fy.js → index-BLUIaanj.js} +1 -1
  52. package/dist/{index-D9h3wl03.js → index-LuH6PJzW.js} +4 -4
  53. package/dist/{index.vue_vue_type_script_setup_true_lang-B3Eku0Ig.js → index.vue_vue_type_script_setup_true_lang-DxF14kn9.js} +2664 -2664
  54. package/dist/{item-Ctnd-m_D.js → item-lXMLaKOb.js} +13 -13
  55. package/dist/{jszip.min-Bwz_vC7R.js → jszip.min-CdZ-wY5m.js} +2 -2
  56. package/dist/{menu-DpTANxng.js → menu-PJc2dQHQ.js} +1 -1
  57. package/dist/{menuV2-BBMwj4p0.js → menuV2-DinFmdTL.js} +131 -131
  58. package/dist/{priceTier-DAG2W_y3.js → priceTier-CzKIo11g.js} +1 -1
  59. package/dist/{scheduler-DYuLkKsc.js → scheduler-DQjxnoCk.js} +4 -4
  60. package/dist/{subcategory-BJ0oG92x.js → subcategory-CLkDImEU.js} +2 -2
  61. package/dist/{toExcel-C5_3G21q.js → toExcel-DPh8DaM0.js} +2 -2
  62. package/dist/{unit-CNwmGzjU.js → unit-QYkVoC6_.js} +2 -2
  63. package/package.json +1 -1
  64. package/dist/Products-O5YVYdlT.js +0 -692
@@ -0,0 +1,794 @@
1
+ var fe = Object.defineProperty;
2
+ var he = (I, t, n) => t in I ? fe(I, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : I[t] = n;
3
+ var G = (I, t, n) => he(I, typeof t != "symbol" ? t + "" : t, n);
4
+ import { defineComponent as B, computed as T, ref as te, resolveComponent as K, createBlock as D, openBlock as F, unref as p, withCtx as E, createElementVNode as S, toDisplayString as oe, createVNode as w, createCommentVNode as ae, createElementBlock as J, Fragment as z } from "vue";
5
+ import { D as H } from "./dayjs.min-C6xioui7.js";
6
+ import { J as ge, F as be } from "./jszip.min-CdZ-wY5m.js";
7
+ import { u as re, G as ne, B as Y, H as q, A as ie, D as ye, I as ke, J as X } from "./index.vue_vue_type_script_setup_true_lang-DxF14kn9.js";
8
+ import { m as $, A as W, f as y, a as O, b as P, e as N, n as R, w as _e } from "./ImportProductDialog.vue_vue_type_script_setup_true_lang-BqhNkaw_.js";
9
+ import { useCoreStore as se, useI18n as we } from "@feedmepos/mf-common";
10
+ import { useDialog as ce, useDialogChild as ve, useSnackbar as me, useBreakpoints as xe, FmButtonVariant as U, FmButtonColorThemeVariant as V } from "@feedmepos/ui-library";
11
+ import { _ as j } from "./ResponsiveFabButton.vue_vue_type_script_setup_true_lang-Cn-3MRBO.js";
12
+ import { _ as Ce, a as Z } from "./BottomSheetMenuItem.vue_vue_type_script_setup_true_lang-DhrXKy3b.js";
13
+ import { _ as Ie } from "./PageLayout.vue_vue_type_script_setup_true_lang-2f0QfweQ.js";
14
+ import { u as Se, a as Ee } from "./menu-PJc2dQHQ.js";
15
+ import { u as Fe } from "./item-lXMLaKOb.js";
16
+ import { _ as Q, a as Te } from "./Product.vue_vue_type_script_setup_true_lang-CdIukLqA.js";
17
+ import { L as ee } from "./LinkProductSideSheet-DJj8Nn4X.js";
18
+ import { _ as Me } from "./TreeEditorOpenner.vue_vue_type_script_setup_true_lang-2nBbq_Yk.js";
19
+ import { u as Ne } from "./Thumbnail.vue_vue_type_script_setup_true_lang-DveI9xvU.js";
20
+ import { m as De } from "./toExcel-DPh8DaM0.js";
21
+ const Ge = { class: "space-y-24 mb-24" }, Re = ["innerHTML"], Ve = { class: "flex justify-end gap-8" }, Ke = /* @__PURE__ */ B({
22
+ __name: "ConfirmActionDialog",
23
+ props: {
24
+ description: {},
25
+ value: {},
26
+ message: { default: "To confirm your action, type <b>[[value]]</b> in the text field." }
27
+ },
28
+ setup(I) {
29
+ const t = I, n = T(() => t.message.replace("[[value]]", t.value)), i = te(""), e = ce(), { emitAction: o } = ve();
30
+ return (r, a) => {
31
+ const c = K("FmTextField"), m = K("FmButton"), u = K("FmForm");
32
+ return F(), D(u, {
33
+ "on-validation-success": () => p(o)("primary"),
34
+ "blame-form-child-on-validation-failed": ""
35
+ }, {
36
+ default: E(() => [
37
+ S("div", Ge, [
38
+ S("div", null, oe(r.description), 1),
39
+ S("div", { innerHTML: n.value }, null, 8, Re),
40
+ S("div", null, [
41
+ w(c, {
42
+ modelValue: i.value,
43
+ "onUpdate:modelValue": [
44
+ a[0] || (a[0] = (s) => i.value = s),
45
+ a[1] || (a[1] = () => {
46
+ })
47
+ ],
48
+ placeholder: r.value,
49
+ rules: [(s) => s === r.value || "Value does not match"]
50
+ }, null, 8, ["modelValue", "placeholder", "rules"])
51
+ ]),
52
+ S("div", Ve, [
53
+ w(m, {
54
+ label: "Cancel",
55
+ variant: "secondary",
56
+ onClick: a[2] || (a[2] = (s) => p(e).close())
57
+ }),
58
+ w(m, {
59
+ label: "Confirm",
60
+ type: "submit"
61
+ })
62
+ ])
63
+ ])
64
+ ]),
65
+ _: 1
66
+ }, 8, ["on-validation-success"]);
67
+ };
68
+ }
69
+ }), Ae = /* @__PURE__ */ B({
70
+ __name: "Migrate",
71
+ setup(I) {
72
+ const t = re(), n = se(), i = me(), { minor: e } = ne(i), o = te(!1), r = ce();
73
+ async function a() {
74
+ c.value || o.value || r.open({
75
+ title: "Migrate to new version",
76
+ contentComponent: Ke,
77
+ contentComponentProps: {
78
+ value: "MIGRATE",
79
+ description: "Do you want to migrate to new version? Once migrate it will unable to revert to the older version."
80
+ }
81
+ }).onPrimary(async () => {
82
+ r.close(), await e(
83
+ async () => {
84
+ await t.migrate(), setTimeout(() => {
85
+ window.location.reload();
86
+ }, 2e3);
87
+ },
88
+ {
89
+ isLoading: o,
90
+ customId: t.state.menu._id,
91
+ message: "Migrating menu",
92
+ successMessage: "Migration completed"
93
+ }
94
+ );
95
+ });
96
+ }
97
+ const c = T(() => {
98
+ const m = n.restaurants.value;
99
+ if (!m.length) return "Required at least one restaurant to migrate";
100
+ const u = m.filter((l) => !l.posVersion || !Y.Pos.canUse({ feature: q.F_FEATURE.enum.menuV4, posVersion: l.posVersion }));
101
+ return u.length ? `Upgrade POS to V${Y.Pos.minVersionToUse(q.F_FEATURE.enum.menuV4)} to use new menu: ${u.map((l) => l.profile.name).join(", ")}` : null;
102
+ });
103
+ return T(() => c.value ? c.value : "Migrate your menu to new version to enjoy more features. Content of new menu will remain the same as current."), (m, u) => {
104
+ const s = K("FmSnackbar");
105
+ return !c.value && p(t).version !== p(ie.F_MENU_VERSION).enum.v4 ? (F(), D(s, {
106
+ key: 0,
107
+ class: "!max-w-full",
108
+ title: "New version of menu is out now!",
109
+ description: "Migrate your current menu version to the latest to enjoy more features such as product sequential dispatch, serving sequence, scheduler and more! Your content and current setting will be preserved.",
110
+ variant: "info",
111
+ action: "Migrate",
112
+ "z-index": 0,
113
+ onOnAction: a
114
+ })) : ae("", !0);
115
+ };
116
+ }
117
+ });
118
+ class $e {
119
+ constructor(t, n) {
120
+ G(this, "menu");
121
+ G(this, "categoryMap");
122
+ G(this, "takeawayMap");
123
+ G(this, "subCategoryMap");
124
+ G(this, "attributeSettings");
125
+ this.menu = t, this.attributeSettings = n, this.categoryMap = t.modules.category.reduce((e, o) => (e[o._id] = o, e), {}), this.takeawayMap = t.modules.takeaway.reduce((e, o) => (e[o._id] = o, e), {});
126
+ const i = t.modules.subCategory || [];
127
+ this.subCategoryMap = i.reduce((e, o) => (e[o._id] = o, e), {});
128
+ }
129
+ transformData() {
130
+ const t = [];
131
+ return this.menu.modules.item.forEach((n) => {
132
+ var r;
133
+ const i = n.variant ? $(this.menu, n.variant.variantGroupIds) : {}, e = this.transformProductToDataRow(n, i);
134
+ t.push(e);
135
+ const o = ((r = n.variant) == null ? void 0 : r.variantCombinations) ?? [];
136
+ for (const a of o)
137
+ t.push(
138
+ this.transformProductToDataRow(n, i, a.combinationKey)
139
+ );
140
+ }), {
141
+ rows: t,
142
+ metaData: {
143
+ priceTiers: []
144
+ }
145
+ };
146
+ }
147
+ transformOverrideData(t) {
148
+ const n = [], i = [], e = t.reduce(
149
+ (o, r) => (o[r._id] || (o[r._id] = []), r.combinationKey && o[r._id].push(r.combinationKey), o),
150
+ {}
151
+ );
152
+ for (let o = 0; o < t.length; o++) {
153
+ const r = t[o], a = this.menu.modules.item.find((c) => c._id === r._id);
154
+ if (a && a.variant) {
155
+ const c = a.variant.variantCombinations.map(
156
+ (l) => l.combinationKey
157
+ ), m = e[r._id] || [], u = c.filter((l) => !m.includes(l)), s = [];
158
+ if (u.forEach((l) => {
159
+ const d = a.variant.variantCombinations.find(
160
+ (f) => f.combinationKey === l
161
+ );
162
+ d && (s.push({
163
+ _id: r._id,
164
+ combinationKey: l,
165
+ price: d.price,
166
+ orderFrom: d.orderFrom
167
+ }), e[r._id].push(l));
168
+ }), s.length > 0) {
169
+ const l = t.findIndex((f) => f._id === r._id && !f.combinationKey), d = l >= 0 ? l + 1 : o + 1;
170
+ t.splice(d, 0, ...s), o += s.length;
171
+ }
172
+ }
173
+ }
174
+ for (let o = 0; o < t.length; o++) {
175
+ const r = t[o], a = this.menu.modules.item.find((s) => s._id === r._id);
176
+ if (!a)
177
+ throw new Error(`Invalid item ${r._id} in catalog`);
178
+ const c = a.variant ? $(this.menu, a.variant.variantGroupIds) : {}, u = [this.transformOverrideDataToRow(r, c)];
179
+ i.push(...u.flatMap((s) => Object.keys(s.priceTier))), n.push(...u);
180
+ }
181
+ return {
182
+ rows: n,
183
+ metaData: {
184
+ priceTiers: []
185
+ }
186
+ };
187
+ }
188
+ getSubCategoryNames(t, n) {
189
+ return n || !t.subCategories ? "" : t.subCategories.map((i) => {
190
+ var e;
191
+ return ((e = this.subCategoryMap[i]) == null ? void 0 : e.name) || "";
192
+ }).filter((i) => i).join(",");
193
+ }
194
+ transformProductToDataRow(t, n, i) {
195
+ var c, m, u;
196
+ const e = (c = t.variant) == null ? void 0 : c.variantCombinations.find(
197
+ (s) => s.combinationKey === i
198
+ );
199
+ if (i && !e)
200
+ throw new Error(`Invalid combination key ${i}`);
201
+ const o = t.category ? (m = this.categoryMap[t.category]) == null ? void 0 : m.name : W;
202
+ let r;
203
+ if (e ? r = e.takeawayUsed ? this.takeawayMap[e.takeawayUsed] : void 0 : r = t.takeawayUsed ? this.takeawayMap[t.takeawayUsed] : void 0, !o)
204
+ throw new Error(`Invalid category ${t.category}`);
205
+ const a = this.getSubCategoryNames(t, !!e);
206
+ return {
207
+ _id: t._id,
208
+ code: e && e.code || t.code,
209
+ name: t.name,
210
+ variantKey: (e == null ? void 0 : e.combinationKey) ?? "",
211
+ variantName: e ? n[e.combinationKey] : "",
212
+ category: o,
213
+ subCategories: a,
214
+ orderFrom: e ? e.orderFrom ?? t.orderFrom : t.orderFrom,
215
+ perXUnit: t.perXUnit || "",
216
+ unit: t.unit || "",
217
+ openPrice: t.openPrice === !0 ? "T" : "",
218
+ price: e ? e.price ? parseFloat(y(e.price)) : parseFloat(y(t.price)) : parseFloat(y(t.price)),
219
+ priceTier: t.priceTiers || {},
220
+ trackingCost: t.costing ? parseFloat(y(t.costing)) : "",
221
+ minPrice: t.minPrice ? parseFloat(y(t.minPrice)) : "",
222
+ groupByParent: ((u = t.print) == null ? void 0 : u.toRoot) === !0 ? "" : "T",
223
+ takeawayName: (r == null ? void 0 : r.name) || "",
224
+ takeawayPrice: r != null && r.price ? parseFloat(y(r == null ? void 0 : r.price)) : "",
225
+ tag: t.customAttributes || {}
226
+ };
227
+ }
228
+ transformOverrideDataToRow(t, n, i) {
229
+ var m, u;
230
+ const e = this.menu.modules.item.find((s) => s._id === t._id);
231
+ if (!e)
232
+ throw new Error(`Invalid item ${t._id} in catelog`);
233
+ const o = (m = e.variant) == null ? void 0 : m.variantCombinations.find(
234
+ (s) => s.combinationKey === t.combinationKey
235
+ );
236
+ if (i && !o)
237
+ throw new Error(`Invalid combination key ${i}`);
238
+ const r = () => {
239
+ var s, l;
240
+ return t.category ? t.category ? (l = this.categoryMap[t.category]) == null ? void 0 : l.name : W : e.category ? (s = this.categoryMap[e.category]) == null ? void 0 : s.name : W;
241
+ };
242
+ let a;
243
+ o ? t.takeawayUsed ? a = t.takeawayUsed ? this.takeawayMap[t.takeawayUsed] : void 0 : a = o.takeawayUsed ? this.takeawayMap[o.takeawayUsed] : void 0 : t.takeawayUsed ? a = t.takeawayUsed ? this.takeawayMap[t.takeawayUsed] : void 0 : a = e.takeawayUsed ? this.takeawayMap[e.takeawayUsed] : void 0;
244
+ const c = this.getSubCategoryNames(t, !!o);
245
+ return {
246
+ _id: t._id,
247
+ code: t.code ? t.code : o && o.code || e.code,
248
+ name: e.name,
249
+ variantKey: t.combinationKey ? t.combinationKey : (o == null ? void 0 : o.combinationKey) ?? "",
250
+ variantName: o ? n[o.combinationKey] : "",
251
+ category: r(),
252
+ subCategories: c,
253
+ orderFrom: t.orderFrom ? t.orderFrom : o ? o.orderFrom ?? e.orderFrom : e.orderFrom,
254
+ perXUnit: e.perXUnit || "",
255
+ unit: e.unit || "",
256
+ openPrice: e.openPrice === !0 ? "T" : "",
257
+ price: t.price ? parseFloat(y(t.price)) : o ? o.price ? parseFloat(y(o.price)) : parseFloat(y(e.price)) : parseFloat(y(e.price)),
258
+ priceTier: e.priceTiers || {},
259
+ trackingCost: e.costing ? parseFloat(y(e.costing)) : "",
260
+ minPrice: t.minPrice ? parseFloat(y(t.minPrice)) : e.minPrice ? parseFloat(y(e.minPrice)) : "",
261
+ groupByParent: ((u = e.print) == null ? void 0 : u.toRoot) === !0 ? "" : "T",
262
+ takeawayName: (a == null ? void 0 : a.name) || "",
263
+ takeawayPrice: a != null && a.price ? parseFloat(y(a == null ? void 0 : a.price)) : "",
264
+ tag: e.customAttributes || {}
265
+ };
266
+ }
267
+ transformAddonGroup() {
268
+ return this.mapAddonGroup(this.menu.modules.group);
269
+ }
270
+ transformOverrideAddonGroup(t) {
271
+ return this.mapCatalogAddonGroup(t);
272
+ }
273
+ mapCatalogAddonGroup(t) {
274
+ const n = this.menu.modules.group.map((e) => e._id), i = t.map((e) => e._id);
275
+ return n.forEach((e) => {
276
+ if (!i.includes(e)) {
277
+ const o = this.menu.modules.group.find((r) => r._id === e);
278
+ t.push({
279
+ ...o,
280
+ groupKey: ""
281
+ });
282
+ }
283
+ }), t.sort((e, o) => n.indexOf(e._id) - n.indexOf(o._id)), t.flatMap((e) => {
284
+ const o = this.menu.modules.group.find((a) => a._id === e._id);
285
+ if (!o)
286
+ throw new Error("Invalid addon group id");
287
+ const r = {};
288
+ return o.items.map((a, c) => {
289
+ var h, v, x;
290
+ const m = this.menu.modules.item.find((k) => k._id === a._id);
291
+ if (!m)
292
+ throw new Error("Invalid item id");
293
+ let u;
294
+ a.combinationKey && (u = (h = m.variant) == null ? void 0 : h.variantCombinations.find(
295
+ (k) => k.combinationKey === a.combinationKey
296
+ ));
297
+ const s = (v = e.items) == null ? void 0 : v.find(
298
+ (k) => k._id === a._id && k.combinationKey === a.combinationKey
299
+ ), l = m.name, d = $(
300
+ this.menu,
301
+ ((x = m.variant) == null ? void 0 : x.variantGroupIds) ?? []
302
+ ), f = (s == null ? void 0 : s.price) ?? a.price ?? (u == null ? void 0 : u.price) ?? m.price;
303
+ return a.name && !a.combinationKey && (r[a._id] = a.name), {
304
+ id: e._id,
305
+ name: o.name,
306
+ min: o.min,
307
+ max: o.max,
308
+ stackable: o.stackable === !0 ? "T" : "",
309
+ itemId: a._id,
310
+ itemCode: m.code || "",
311
+ itemName: l,
312
+ itemNameOverrider: r[a._id] || "",
313
+ combinationKey: a.combinationKey ?? "",
314
+ combinationName: a.combinationKey ? d[a.combinationKey] : "",
315
+ price: parseFloat(y(f)),
316
+ priceTier: a.priceTiers || {},
317
+ orderFrom: (s == null ? void 0 : s.orderFrom) ?? a.orderFrom ?? m.orderFrom ?? "ALL",
318
+ isDefault: a.isDefault === !0 ? "T" : "",
319
+ index: c
320
+ };
321
+ });
322
+ });
323
+ }
324
+ mapAddonGroup(t) {
325
+ return t.flatMap((n) => {
326
+ let i = {};
327
+ return i = n.items.reduce((e, o) => (e[o._id] || o.name && !o.combinationKey && (e[o._id] = o.name), e), {}), n.items.map((e, o) => {
328
+ var u, s;
329
+ const r = this.menu.modules.item.find((l) => l._id === e._id);
330
+ if (!r)
331
+ throw new Error("Invalid item id");
332
+ let a;
333
+ e.combinationKey && (a = (u = r.variant) == null ? void 0 : u.variantCombinations.find(
334
+ (l) => l.combinationKey === e.combinationKey
335
+ ));
336
+ const c = e.price ?? (a == null ? void 0 : a.price) ?? r.price, m = $(
337
+ this.menu,
338
+ ((s = r.variant) == null ? void 0 : s.variantGroupIds) ?? []
339
+ );
340
+ return {
341
+ id: n._id,
342
+ name: n.name,
343
+ min: n.min,
344
+ max: n.max,
345
+ stackable: n.stackable === !0 ? "T" : "",
346
+ itemId: e._id,
347
+ itemCode: r.code || "",
348
+ itemName: r.name,
349
+ itemNameOverrider: i[e._id] || "",
350
+ combinationKey: e.combinationKey ?? "",
351
+ combinationName: e.combinationKey ? m[e.combinationKey] : "",
352
+ price: parseFloat(y(c)),
353
+ priceTier: e.priceTiers || {},
354
+ orderFrom: e.orderFrom ?? r.orderFrom,
355
+ isDefault: e.isDefault === !0 ? "T" : "",
356
+ index: o
357
+ };
358
+ });
359
+ });
360
+ }
361
+ transformItemsLinkWithGroup() {
362
+ const t = {}, n = this.menu.modules.item.reduce((i, e) => (i[e._id] = {
363
+ itemId: e._id,
364
+ itemName: e.name,
365
+ defaultCatalog: ""
366
+ }, i), {});
367
+ return this.menu.modules.group.forEach((i) => {
368
+ t[i._id] = JSON.parse(JSON.stringify(n));
369
+ }), this.menu.modules.item.forEach((i) => {
370
+ i.groups.length > 0 && i.groups.forEach((e) => {
371
+ t[e._id][i._id] = {
372
+ ...t[e._id][i._id],
373
+ defaultCatalog: "T"
374
+ };
375
+ });
376
+ }), t;
377
+ }
378
+ /**
379
+ * @deprecated Use {@link exportToExcelStreaming} instead.
380
+ * This method builds all 3 workbooks in memory simultaneously, which causes
381
+ * out-of-memory errors for large menus (e.g. 262 catalogs × 923 items).
382
+ * It also duplicates catalog data via intermediate workbook copying.
383
+ */
384
+ exportToExcel() {
385
+ var f;
386
+ const t = [], { rows: n, metaData: i } = this.transformData();
387
+ i.priceTiers = ((f = this.menu.priceTierSettings) == null ? void 0 : f.map((h) => h.key)) || [];
388
+ const e = n.map(({ priceTier: h, tag: v, ...x }) => {
389
+ const k = Object.entries(x), _ = k.findIndex(([b]) => b === "price");
390
+ return [
391
+ ...k.slice(0, _ + 1).map(([, b]) => b),
392
+ ...i.priceTiers.map(
393
+ (b) => parseFloat(y(h[b])) || ""
394
+ ),
395
+ ...k.slice(_ + 1).map(([, b]) => b),
396
+ ...this.attributeSettings.map((b) => v[b.key] || "")
397
+ ];
398
+ }), o = this.createWorkbookExcelJS(
399
+ e,
400
+ "Default Catalog",
401
+ this.exportCatalogToExcelExcelJS()
402
+ ), r = o.worksheets[0];
403
+ O(r, this.attributeSettings, i.priceTiers), this.formatWorkbookCell(o);
404
+ const c = this.transformAddonGroup().map(({ priceTier: h, ...v }) => {
405
+ const { index: x, ...k } = v, _ = Object.entries(k), b = _.findIndex(([g]) => g === "price");
406
+ return [
407
+ ..._.slice(0, b + 1).map(([, g]) => g),
408
+ ...i.priceTiers.map(
409
+ (g) => parseFloat(y(h[g])) || ""
410
+ ),
411
+ ..._.slice(b + 1).map(([, g]) => g)
412
+ ];
413
+ }), m = this.createWorkbookExcelJS(
414
+ c,
415
+ "Default AddonGroup",
416
+ this.exportCatalogAddonToExcelExcelJS()
417
+ ), u = m.worksheets[0];
418
+ P(u, i.priceTiers), this.formatWorkbookCell(m);
419
+ const s = this.transformItemsLinkWithGroup(), l = Object.keys(s), d = new N.Workbook();
420
+ if (l.length > 0)
421
+ l.forEach((h, v) => {
422
+ const x = Object.values(s[h]), k = this.menu.modules.group.find((g) => g._id === h);
423
+ if (!k) throw new Error(`Group not found for id: ${h}`);
424
+ const _ = R(`${v + 1}. ${k.name}`), b = d.addWorksheet(_);
425
+ b.columns = [
426
+ { header: "Group ID", key: "groupId" },
427
+ { header: "Item ID", key: "itemId" },
428
+ { header: "Item Name", key: "itemName" },
429
+ { header: "Default Catalog", key: "defaultCatalog" }
430
+ ], x.forEach((g) => {
431
+ b.addRow({
432
+ groupId: h,
433
+ itemId: g.itemId,
434
+ itemName: g.itemName,
435
+ defaultCatalog: g.defaultCatalog
436
+ });
437
+ });
438
+ });
439
+ else {
440
+ const h = d.addWorksheet("Group Name");
441
+ h.columns = [
442
+ { header: "Group ID", key: "groupId" },
443
+ { header: "Item ID", key: "itemId" },
444
+ { header: "Item Name", key: "itemName" },
445
+ { header: "Default Catalog", key: "defaultCatalog" }
446
+ ];
447
+ }
448
+ return this.formatWorkbookCell(d), t.push(o, m, d), t;
449
+ }
450
+ /**
451
+ * Memory-optimized export that processes each workbook sequentially.
452
+ *
453
+ * Key optimizations over {@link exportToExcel}:
454
+ * 1. Sequential processing — only 1 workbook in memory at a time (vs all 3).
455
+ * Each workbook is built, passed to the callback for serialization, then released for GC.
456
+ * 2. Direct catalog sheets — catalog override sheets are added directly to the target workbook,
457
+ * eliminating the intermediate workbook + row-by-row copy used by exportCatalogToExcelExcelJS.
458
+ * 3. Set-based item-group linking (Book 3) — uses Map<groupId, Set<itemId>> instead of
459
+ * deep-cloning all items for every group via JSON.parse(JSON.stringify(...)).
460
+ *
461
+ * @param onWorkbook - Called for each workbook (menu, addonGroup, itemLinkedAddon) in order.
462
+ * The caller should serialize the workbook (e.g. writeBuffer) before the promise resolves.
463
+ * After the callback resolves, the workbook reference is released.
464
+ */
465
+ async exportToExcelStreaming(t) {
466
+ var i;
467
+ const n = ((i = this.menu.priceTierSettings) == null ? void 0 : i.map((e) => e.key)) || [];
468
+ {
469
+ const e = new N.Workbook(), { rows: o } = this.transformData(), r = o.map(({ priceTier: c, tag: m, ...u }) => {
470
+ const s = Object.entries(u), l = s.findIndex(([d]) => d === "price");
471
+ return [
472
+ ...s.slice(0, l + 1).map(([, d]) => d),
473
+ ...n.map(
474
+ (d) => parseFloat(y(c[d])) || ""
475
+ ),
476
+ ...s.slice(l + 1).map(([, d]) => d),
477
+ ...this.attributeSettings.map((d) => m[d.key] || "")
478
+ ];
479
+ }), a = e.addWorksheet("Default Catalog");
480
+ r.forEach((c) => a.addRow(c)), O(a, this.attributeSettings, n), this.menu.modules.catalog.forEach((c) => {
481
+ const m = Object.values(c.override.items).flatMap(
482
+ (h) => h
483
+ ), { rows: u, metaData: s } = this.transformOverrideData(m), l = u.map(({ priceTier: h, tag: v, ...x }) => [
484
+ ...Object.entries(x).map(([, _]) => _),
485
+ ...this.attributeSettings.map((_) => v[_.key] || "")
486
+ ]), d = R(c.name), f = e.addWorksheet(d);
487
+ l.forEach((h) => f.addRow(h)), O(f, this.attributeSettings, s.priceTiers, c);
488
+ }), this.formatWorkbookCell(e), await t(e);
489
+ }
490
+ {
491
+ const e = new N.Workbook(), r = this.transformAddonGroup().map(({ priceTier: c, ...m }) => {
492
+ const { index: u, ...s } = m, l = Object.entries(s), d = l.findIndex(([f]) => f === "price");
493
+ return [
494
+ ...l.slice(0, d + 1).map(([, f]) => f),
495
+ ...n.map(
496
+ (f) => parseFloat(y(c[f])) || ""
497
+ ),
498
+ ...l.slice(d + 1).map(([, f]) => f)
499
+ ];
500
+ }), a = e.addWorksheet("Default AddonGroup");
501
+ r.forEach((c) => a.addRow(c)), P(a, n), this.menu.modules.catalog.forEach((c) => {
502
+ const m = Object.values(c.override.groups).flatMap(
503
+ (f) => f
504
+ ), s = this.transformOverrideAddonGroup(m).map(({ priceTier: f, ...h }) => {
505
+ const { index: v, ...x } = h;
506
+ return [...Object.entries(x).map(([, _]) => _)];
507
+ }), l = R(c.name), d = e.addWorksheet(l);
508
+ s.forEach((f) => d.addRow(f)), P(d);
509
+ }), this.formatWorkbookCell(e), await t(e);
510
+ }
511
+ {
512
+ const e = new N.Workbook(), o = this.menu.modules.group;
513
+ if (o.length > 0) {
514
+ const r = /* @__PURE__ */ new Map();
515
+ for (const a of o)
516
+ r.set(a._id, /* @__PURE__ */ new Set());
517
+ for (const a of this.menu.modules.item)
518
+ for (const c of a.groups) {
519
+ const m = r.get(c._id);
520
+ if (!m)
521
+ throw new Error(
522
+ `Unknown group id "${c._id}" referenced by item "${a._id}" in menu export`
523
+ );
524
+ m.add(a._id);
525
+ }
526
+ o.forEach((a, c) => {
527
+ const m = R(`${c + 1}. ${a.name}`), u = e.addWorksheet(m);
528
+ u.columns = [
529
+ { header: "Group ID", key: "groupId" },
530
+ { header: "Item ID", key: "itemId" },
531
+ { header: "Item Name", key: "itemName" },
532
+ { header: "Default Catalog", key: "defaultCatalog" }
533
+ ];
534
+ const s = r.get(a._id);
535
+ for (const l of this.menu.modules.item)
536
+ u.addRow({
537
+ groupId: a._id,
538
+ itemId: l._id,
539
+ itemName: l.name,
540
+ defaultCatalog: s.has(l._id) ? "T" : ""
541
+ });
542
+ });
543
+ } else {
544
+ const r = e.addWorksheet("Group Name");
545
+ r.columns = [
546
+ { header: "Group ID", key: "groupId" },
547
+ { header: "Item ID", key: "itemId" },
548
+ { header: "Item Name", key: "itemName" },
549
+ { header: "Default Catalog", key: "defaultCatalog" }
550
+ ];
551
+ }
552
+ this.formatWorkbookCell(e), await t(e);
553
+ }
554
+ }
555
+ createWorkbookExcelJS(t, n, i) {
556
+ const e = new N.Workbook(), o = e.addWorksheet(n);
557
+ return t.forEach((r) => {
558
+ o.addRow(r);
559
+ }), i && i.worksheets.forEach((r) => {
560
+ const a = e.addWorksheet(r.name);
561
+ r.eachRow({ includeEmpty: !0 }, (c) => {
562
+ const m = c.values;
563
+ a.addRow(m.slice(1));
564
+ });
565
+ }), e;
566
+ }
567
+ formatWorkbookCell(t) {
568
+ t.eachSheet((n) => {
569
+ n.eachRow({ includeEmpty: !0 }, (e) => {
570
+ e.eachCell({ includeEmpty: !0 }, (o) => {
571
+ o.font = {
572
+ name: "Calibri",
573
+ size: 12
574
+ }, e.number === 1 && (o.fill = {
575
+ type: "pattern",
576
+ pattern: "solid",
577
+ fgColor: { argb: "FABF8F" }
578
+ }, o.alignment = { horizontal: "center", vertical: "middle" });
579
+ });
580
+ });
581
+ const i = n.getRow(1);
582
+ n.autoFilter = {
583
+ from: {
584
+ row: 1,
585
+ column: 1
586
+ },
587
+ to: {
588
+ row: 1,
589
+ column: i.cellCount
590
+ }
591
+ };
592
+ });
593
+ }
594
+ exportCatalogToExcelExcelJS() {
595
+ const t = new N.Workbook();
596
+ return this.menu.modules.catalog.forEach((n) => {
597
+ const i = Object.values(n.override.items).flatMap((m) => m), { rows: e, metaData: o } = this.transformOverrideData(i), r = e.map(({ priceTier: m, tag: u, ...s }) => [
598
+ ...Object.entries(s).map(([, d]) => d),
599
+ ...this.attributeSettings.map((d) => u[d.key] || "")
600
+ ]), a = R(n.name), c = t.addWorksheet(a);
601
+ r.forEach((m) => {
602
+ c.addRow(m);
603
+ }), O(c, this.attributeSettings, o.priceTiers, n);
604
+ }), t;
605
+ }
606
+ exportCatalogAddonToExcelExcelJS() {
607
+ const t = new N.Workbook();
608
+ return this.menu.modules.catalog.forEach((n) => {
609
+ const i = Object.values(n.override.groups).flatMap(
610
+ (c) => c
611
+ ), o = this.transformOverrideAddonGroup(i).map(({ priceTier: c, ...m }) => {
612
+ const { index: u, ...s } = m;
613
+ return [...Object.entries(s).map(([, d]) => d)];
614
+ }), r = R(n.name), a = t.addWorksheet(r);
615
+ o.forEach((c) => {
616
+ a.addRow(c);
617
+ }), P(a);
618
+ }), t;
619
+ }
620
+ }
621
+ const Oe = { class: "flex-1 flex justify-between gap-8 pl-8" }, Pe = { class: "flex items-center" }, We = { class: "bg-fm-color-neutral-gray-100 rounded-md px-8 py-4" }, Ue = { class: "fm-typo-en-body-md-600 font-semibold" }, je = { class: "flex gap-8" }, ct = /* @__PURE__ */ B({
622
+ __name: "Products",
623
+ setup(I) {
624
+ const { t } = we(), n = se(), i = ne(me()), e = re(), o = T(() => e.rules.item), r = Fe(), a = T(() => !e.state.currentSchedulerId), { selectedCategories: c } = Se(), m = T(() => ({
625
+ ...ye.menuV4ToV3(ke(e.state.menu)),
626
+ _id: e.state.menu._id,
627
+ _rev: e.state.menu._rev
628
+ })), u = T(() => {
629
+ const b = X.flatten(c.value.map((g) => g.items));
630
+ return X.uniqBy(b, (g) => g._id).length;
631
+ });
632
+ async function s() {
633
+ await i.minor(
634
+ async () => {
635
+ var b;
636
+ if (await e.readMenu(), e.version === ie.F_MENU_VERSION.enum.v4) {
637
+ const g = e.state.menu, M = new $e(
638
+ g,
639
+ ((b = n.currentBusiness.value) == null ? void 0 : b.attributeSettings) ?? []
640
+ ), C = new ge(), A = H().format("DD-MM-YYYY_HH-mm"), le = [
641
+ `menu_${A}`,
642
+ `addonGroup_${A}`,
643
+ `itemLinkedAddon${A}`
644
+ ];
645
+ let L = 0;
646
+ await M.exportToExcelStreaming(async (de) => {
647
+ const pe = await de.xlsx.writeBuffer();
648
+ C.file(`${le[L]}.xlsx`, pe), L++;
649
+ });
650
+ const ue = await C.generateAsync({ type: "blob" });
651
+ be.saveAs(ue, `books_${A}.zip`);
652
+ } else {
653
+ const g = De(m.value), M = `menu_${H().format("DD-MM-YYYY_HH-mm")}`;
654
+ await _e(g, `${M}.xlsx`, {
655
+ bookType: "xlsx",
656
+ bookSST: !1,
657
+ type: "array"
658
+ });
659
+ }
660
+ },
661
+ { successMessage: "Menu exported", customId: e.state.menu._id }
662
+ );
663
+ }
664
+ const {
665
+ menuItems: l,
666
+ categories: d,
667
+ linkItemRules: f,
668
+ handleSubmit: h,
669
+ catalogManager: v,
670
+ schedulerManager: x
671
+ } = Ne(!1), k = xe(), _ = T(() => k.breakpoints.value.xs);
672
+ return Ee().resetOnMount(), (b, g) => {
673
+ const M = K("fm-button");
674
+ return F(), D(Ie, {
675
+ heading: p(t)("menu.products.title")
676
+ }, {
677
+ default: E(() => [
678
+ w(Ae),
679
+ w(Te)
680
+ ]),
681
+ "append-heading": E(() => [
682
+ S("div", Oe, [
683
+ S("div", Pe, [
684
+ S("div", We, [
685
+ S("p", Ue, oe(u.value), 1)
686
+ ])
687
+ ]),
688
+ S("div", je, [
689
+ _.value ? (F(), D(Q, { key: 1 }, {
690
+ default: E(({ trigger: C }) => [
691
+ w(Ce, null, {
692
+ default: E(() => [
693
+ w(Z, {
694
+ label: p(t)("menu.products.actions.export"),
695
+ onClick: s
696
+ }, null, 8, ["label"]),
697
+ w(Z, {
698
+ label: p(t)("menu.products.actions.import"),
699
+ onClick: C
700
+ }, null, 8, ["label", "onClick"])
701
+ ]),
702
+ _: 2
703
+ }, 1024)
704
+ ]),
705
+ _: 1
706
+ })) : (F(), J(z, { key: 0 }, [
707
+ w(Me, null, {
708
+ default: E(({ trigger: C }) => [
709
+ w(M, {
710
+ label: p(t)("menu.tree_editor.title"),
711
+ "bg-color": p(V).NeutralGray100,
712
+ "text-color": p(V).TypoSecondary,
713
+ variant: p(U).Primary,
714
+ onClick: C
715
+ }, null, 8, ["label", "bg-color", "text-color", "variant", "onClick"])
716
+ ]),
717
+ _: 1
718
+ }),
719
+ w(M, {
720
+ "bg-color": p(V).NeutralGray100,
721
+ "text-color": p(V).TypoSecondary,
722
+ variant: p(U).Primary,
723
+ label: p(t)("menu.products.actions.export"),
724
+ onClick: s
725
+ }, null, 8, ["bg-color", "text-color", "variant", "label"]),
726
+ w(Q, null, {
727
+ default: E(({ trigger: C }) => [
728
+ w(M, {
729
+ "bg-color": p(V).NeutralGray100,
730
+ "text-color": p(V).TypoSecondary,
731
+ variant: p(U).Primary,
732
+ label: p(t)("menu.products.actions.import"),
733
+ onClick: C
734
+ }, null, 8, ["bg-color", "text-color", "variant", "label", "onClick"])
735
+ ]),
736
+ _: 1
737
+ })
738
+ ], 64)),
739
+ u.value > 0 ? (F(), J(z, { key: 2 }, [
740
+ o.value.create ? (F(), D(j, {
741
+ key: 0,
742
+ label: p(t)("menu.products.actions.add"),
743
+ "prepend-icon": "add",
744
+ onClick: g[0] || (g[0] = (C) => p(r).create(null))
745
+ }, null, 8, ["label"])) : a.value ? (F(), D(ee, {
746
+ key: 1,
747
+ "categorized-items": p(v).linkableItems.value,
748
+ "initial-value": p(v).currentItems.value,
749
+ "show-variant": !1,
750
+ "menu-items": p(l),
751
+ categories: p(d),
752
+ "link-item-rules": p(f),
753
+ "no-scheduler": a.value,
754
+ onSubmit: p(h)
755
+ }, {
756
+ default: E(({ trigger: C }) => [
757
+ w(j, {
758
+ label: p(t)("menu.products.actions.link"),
759
+ "prepend-icon": "link",
760
+ onClick: C
761
+ }, null, 8, ["label", "onClick"])
762
+ ]),
763
+ _: 1
764
+ }, 8, ["categorized-items", "initial-value", "menu-items", "categories", "link-item-rules", "no-scheduler", "onSubmit"])) : (F(), D(ee, {
765
+ key: 2,
766
+ "categorized-items": p(x).linkableItems.value,
767
+ "initial-value": p(x).currentItems.value,
768
+ "show-variant": !1,
769
+ "menu-items": p(l),
770
+ categories: p(d),
771
+ "link-item-rules": p(f),
772
+ "no-scheduler": a.value,
773
+ onSubmit: p(h)
774
+ }, {
775
+ default: E(({ trigger: C }) => [
776
+ w(j, {
777
+ label: p(t)("menu.products.actions.apply_scheduler"),
778
+ onClick: C
779
+ }, null, 8, ["label", "onClick"])
780
+ ]),
781
+ _: 1
782
+ }, 8, ["categorized-items", "initial-value", "menu-items", "categories", "link-item-rules", "no-scheduler", "onSubmit"]))
783
+ ], 64)) : ae("", !0)
784
+ ])
785
+ ])
786
+ ]),
787
+ _: 1
788
+ }, 8, ["heading"]);
789
+ };
790
+ }
791
+ });
792
+ export {
793
+ ct as default
794
+ };