@feedmepos/mf-inventory-portal 1.7.9-dev.0 → 1.7.9-dev.2

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 (111) hide show
  1. package/dist/App-BYCW0L94.js +1403 -0
  2. package/dist/{ApprovalView-Bc6xo-gg.js → ApprovalView-pmI_SFo7.js} +9 -9
  3. package/dist/{BindingsDialog-BbTkoM05.js → BindingsDialog-D902flPr.js} +2 -2
  4. package/dist/{BindingsPicker-CkK79U9V.js → BindingsPicker-JEKsY59b.js} +2 -2
  5. package/dist/{BindingsTable-CmdCc1mG.js → BindingsTable-DqlzOIxF.js} +4 -4
  6. package/dist/{BulkReceiveRequestView-BOt07CYr.js → BulkReceiveRequestView-Chw7ma2k.js} +19 -19
  7. package/dist/{ChangeLocationComponent.vue_vue_type_script_setup_true_lang-YMRGpkS4.js → ChangeLocationComponent.vue_vue_type_script_setup_true_lang-Cct8Ko19.js} +1 -1
  8. package/dist/{ClosingDraftView-Dec1xuFQ.js → ClosingDraftView-D1ymRsd2.js} +19 -19
  9. package/dist/{ClosingHistoryView-DuX0UpLC.js → ClosingHistoryView-5yr_itIV.js} +5 -5
  10. package/dist/{ClosingTemplateView-DBPGxWt2.js → ClosingTemplateView-MDl5Zq-g.js} +16 -16
  11. package/dist/{CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-DWfblvtV.js → CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-BcG0gWV4.js} +1 -1
  12. package/dist/{DefaultView-D_XfvHrs.js → DefaultView-dOfbL3iF.js} +2 -2
  13. package/dist/{DeliveryOrderPrintPreview-DfAAAfCJ.js → DeliveryOrderPrintPreview-BfVgQOx8.js} +2 -2
  14. package/dist/{EmailDialog.vue_vue_type_script_setup_true_lang-CdcBrUHW.js → EmailDialog.vue_vue_type_script_setup_true_lang-DHspOJQW.js} +2250 -2250
  15. package/dist/{FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-lge1DZ4v.js → FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-B7NLu0us.js} +1 -1
  16. package/dist/{FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-DjYAwlg9.js → FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-C0nunKjx.js} +2 -2
  17. package/dist/{FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-vwp2n9KL.js → FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-CMst9tkA.js} +2 -2
  18. package/dist/{FmMultiselectDialog-BTVaIESZ.js → FmMultiselectDialog-BjBx94pY.js} +1 -1
  19. package/dist/{FmMultiselectDialog-C-kDJtv_.js → FmMultiselectDialog-Dt54hvqw.js} +2 -2
  20. package/dist/{FmUnitInput.vue_vue_type_script_setup_true_lang-Mo-hF_cA.js → FmUnitInput.vue_vue_type_script_setup_true_lang-DtG9Ieo_.js} +6 -6
  21. package/dist/{ImportView-CRAFZVSk.js → ImportView-CdZN8k_Y.js} +6 -6
  22. package/dist/{IngredientBindedItem.vue_vue_type_script_setup_true_lang-CuEDzJ0s.js → IngredientBindedItem.vue_vue_type_script_setup_true_lang-iCpYEneM.js} +1 -1
  23. package/dist/{IngredientGroupView-OeeBfJau.js → IngredientGroupView-BBVS1mKn.js} +5 -5
  24. package/dist/{IngredientsView-BHX3xUDm.js → IngredientsView-BGOaAUzR.js} +17 -16
  25. package/dist/{IntegrationExplorerView-BwxSGD2N.js → IntegrationExplorerView-UUBCmqdR.js} +4 -4
  26. package/dist/{IntegrationView-CevJNVqG.js → IntegrationView-B2YowH-i.js} +14 -14
  27. package/dist/{InventoryBindingForm-wE--IP2D.js → InventoryBindingForm-kDx6Mvhn.js} +1 -1
  28. package/dist/InventoryBindingForm.vue_vue_type_script_setup_true_lang-C8bktmYH.js +563 -0
  29. package/dist/{InventoryBindingSummary-BQ-U7tHs.js → InventoryBindingSummary-DJrBTa8_.js} +1 -1
  30. package/dist/{NumberPrecisionInput.vue_vue_type_script_setup_true_lang-jnXbX2lS.js → NumberPrecisionInput.vue_vue_type_script_setup_true_lang-DHk9uEAP.js} +1 -1
  31. package/dist/{PremiumBadge.vue_vue_type_script_setup_true_lang-BNMCbrIo.js → PremiumBadge.vue_vue_type_script_setup_true_lang-Dx1VktdW.js} +1 -1
  32. package/dist/{ProductionView-CvU9N_mb.js → ProductionView-CxUcsRBP.js} +7 -7
  33. package/dist/{PublishView-BNnxGtEQ.js → PublishView-DtP-Ms7q.js} +3 -3
  34. package/dist/{PurchaseOrderPrintPreview-Bq9kMWdx.js → PurchaseOrderPrintPreview-C_qC2KF5.js} +2 -2
  35. package/dist/{ReceiveRequestView-zUSU0Uvq.js → ReceiveRequestView-Dy3BpqsP.js} +14 -14
  36. package/dist/RecipeView-DeR7pqj8.js +3625 -0
  37. package/dist/{SettingsView-CPgsU8Kr.js → SettingsView-C7ZXmatO.js} +4 -4
  38. package/dist/{StockView-D-TJzHhP.js → StockView-wFLnNSRr.js} +21 -21
  39. package/dist/{SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-B6ez4H3Z.js → SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-Fxh3-Nqi.js} +1 -1
  40. package/dist/{SupplierView-D-rODe-B.js → SupplierView-CeTDNDDK.js} +12 -12
  41. package/dist/{SurchargeView-C88KTCML.js → SurchargeView-BQJnCdPA.js} +6 -6
  42. package/dist/{SystemTrailDialog.vue_vue_type_script_setup_true_lang-CFIK8eEl.js → SystemTrailDialog.vue_vue_type_script_setup_true_lang-D1zxuH66.js} +2 -2
  43. package/dist/{TemplatePublishDialog.vue_vue_type_script_setup_true_lang-BNjjTYtk.js → TemplatePublishDialog.vue_vue_type_script_setup_true_lang-BFkh3Ubb.js} +1 -1
  44. package/dist/{TransferDetails.vue_vue_type_script_setup_true_lang-E0FeDPFB.js → TransferDetails.vue_vue_type_script_setup_true_lang-CZVDhXNz.js} +20 -20
  45. package/dist/{TransferTemplateView-f9A4-wEL.js → TransferTemplateView-XaI2T5fa.js} +20 -20
  46. package/dist/{UnitCostHistoryView-D26St5yl.js → UnitCostHistoryView-DTNW7-mk.js} +4 -4
  47. package/dist/{UnitDisplayControl.vue_vue_type_script_setup_true_lang-D2z5vabu.js → UnitDisplayControl.vue_vue_type_script_setup_true_lang-vRsEjVJc.js} +4 -4
  48. package/dist/{UnitView-algS_4rD.js → UnitView-DXnyzkj3.js} +7 -7
  49. package/dist/{WarehouseView-BRM-euG4.js → WarehouseView-iEHFgIqh.js} +5 -5
  50. package/dist/{WastageTemplateView-BWPYvTMC.js → WastageTemplateView-CGDUCPbr.js} +14 -14
  51. package/dist/api/changelog.d.ts +69 -1
  52. package/dist/{app-BI1fLJ8H.js → app-BIXJtvvD.js} +35 -23
  53. package/dist/app.d.ts +26 -8
  54. package/dist/app.js +1 -1
  55. package/dist/{closing-template-DRQ-A04S.js → closing-template-CLY-r6Cf.js} +1 -1
  56. package/dist/{date2-paxg81i_.js → date2-DbYQycSa.js} +1 -1
  57. package/dist/{dayjs.min-CqWwbKI1.js → dayjs.min-Dv7-fEed.js} +1 -1
  58. package/dist/{decimal-tY0JrFld.js → decimal-B8YR17QC.js} +2 -2
  59. package/dist/{defineDeepModel-CaP78Goh.js → defineDeepModel-C5ncgNxj.js} +1 -1
  60. package/dist/{duplicate-template-pTXXQ0VS.js → duplicate-template-CAlG1nzV.js} +1 -1
  61. package/dist/{feature-B2r32qOO.js → feature-BLSNLI5y.js} +2 -2
  62. package/dist/{format-time-from-id-DXMYus4N.js → format-time-from-id-D5DcWpHS.js} +1 -1
  63. package/dist/{format-unit-display-5hlsZBY2.js → format-unit-display-Ch97dVXx.js} +12 -12
  64. package/dist/{import-export.helper-BiC2Ghbl.js → import-export.helper-CvUFSOa1.js} +6 -6
  65. package/dist/{index-rqdAWR69.js → index-Bk8DOv4n.js} +3306 -3232
  66. package/dist/{index-KP2-U9x_.js → index-CXzVUrJS.js} +3 -3
  67. package/dist/{index-B7eouqPa.js → index-rRPErzP4.js} +1 -1
  68. package/dist/{inventory-core-dart.default-ClRRaGtG.js → inventory-core-dart.default-Cj7CxnpK.js} +1 -1
  69. package/dist/{lz-string-CAl-OrXa.js → lz-string-DWkGPESZ.js} +1 -1
  70. package/dist/{netsuite-cH4OybGV.js → netsuite-Cn0y1rH3.js} +2 -2
  71. package/dist/{number-BzmDQm_s.js → number-CxbQxQwj.js} +3 -3
  72. package/dist/{predefined-templates-Baz8GEGx.js → predefined-templates-CrSoG3R9.js} +1 -1
  73. package/dist/{purchase-order-template-0So3c2iS.js → purchase-order-template-BmQQnrEl.js} +1 -1
  74. package/dist/{recalculationUtils-DJlz5mJL.js → recalculationUtils-CSnowXma.js} +1 -1
  75. package/dist/{rules-BKdtla9-.js → rules-CurdOAcA.js} +2 -2
  76. package/dist/{stock-D8M5e53w.js → stock-BdDR_L8p.js} +1 -1
  77. package/dist/{stock-HCSCwSH0.js → stock-BiqEgcgU.js} +3 -3
  78. package/dist/style.css +1 -1
  79. package/dist/{supplier-1mbcQSiQ.js → supplier-CsjbmP_P.js} +2 -2
  80. package/dist/{surcharge-DuxYBaWV.js → surcharge--kBjIIst.js} +1 -1
  81. package/dist/tsconfig.app.tsbuildinfo +1 -1
  82. package/dist/{uom-rules-Dkbgtow8.js → uom-rules-D8UPS06O.js} +1 -1
  83. package/dist/{use-ingredient-select-dialog-BXvBvELI.js → use-ingredient-select-dialog-BZdrpLOE.js} +2 -2
  84. package/dist/{use-inventory-binding-dialog-2lrzHWdQ.js → use-inventory-binding-dialog-CkNxixT2.js} +2 -2
  85. package/dist/{use-template-enabled-locations-CrDuAaCj.js → use-template-enabled-locations-Dkl1_1F-.js} +2 -2
  86. package/dist/{use-transfer-locations-C4oTuW_f.js → use-transfer-locations-Bmj4zTJj.js} +2 -2
  87. package/dist/{useHrmPermission-CxeYlUgA.js → useHrmPermission-DcBe_-Q6.js} +1 -1
  88. package/dist/{useNavigationMenu-BWgwgA4U.js → useNavigationMenu-CsRbtAc7.js} +2 -2
  89. package/dist/{useSseClient-DPA1zg96.js → useSseClient-hl2SQF5b.js} +1 -1
  90. package/dist/views/changelog/components/ChangelogPanel.spec.d.ts +1 -0
  91. package/dist/views/changelog/components/ChangelogPanel.vue.d.ts +2 -0
  92. package/dist/views/changelog/composables/use-changelog.d.ts +54 -2
  93. package/dist/views/changelog/composables/use-inventory-record-commits.d.ts +97 -0
  94. package/dist/views/changelog/composables/use-inventory-record-commits.spec.d.ts +1 -0
  95. package/dist/views/changelog/composables/use-snapshot-diff.d.ts +29 -0
  96. package/dist/views/changelog/composables/use-snapshot-diff.spec.d.ts +1 -0
  97. package/dist/views/changelog/composables/value-tree.d.ts +14 -0
  98. package/dist/views/changelog/composables/value-tree.spec.d.ts +1 -0
  99. package/dist/views/ingredients/components/inventory-binding/InventoryBindingForm.vue.d.ts +2 -0
  100. package/dist/views/ingredients/components/inventory-binding/RecipeBindingBreakdown.vue.d.ts +25 -0
  101. package/dist/views/ingredients/components/inventory-binding/composables/recipe-breakdown.d.ts +34 -0
  102. package/dist/views/ingredients/components/inventory-binding/composables/recipe-breakdown.spec.d.ts +1 -0
  103. package/dist/views/ingredients/components/inventory-binding/v2/InventoryBindingFormV2.vue.d.ts +2 -0
  104. package/dist/views/ingredients/components/inventory-binding/v2/components/InventoryRecipeBindingV2Field.vue.d.ts +4 -0
  105. package/dist/views/recipe/composables/use-recipe-table.d.ts +11 -0
  106. package/dist/{vue-i18n-BSfpVmaF.js → vue-i18n-yL99yI4f.js} +169 -169
  107. package/dist/{xlsx.util-DSA9o0Zu.js → xlsx.util-B8azJxkS.js} +2 -2
  108. package/package.json +2 -2
  109. package/dist/App-DvBMEcuJ.js +0 -1155
  110. package/dist/InventoryBindingForm.vue_vue_type_script_setup_true_lang-O5IbSGWu.js +0 -441
  111. package/dist/RecipeView-DkXOK1Iy.js +0 -3584
@@ -0,0 +1,3625 @@
1
+ import { defineComponent as le, ref as W, onMounted as pt, resolveComponent as G, createElementBlock as V, openBlock as g, Fragment as Q, createElementVNode as y, toDisplayString as U, createVNode as x, createCommentVNode as T, h as re, computed as F, watch as ue, unref as n, withCtx as J, createBlock as Y, renderList as me, isRef as Me, mergeProps as Ie, createTextVNode as mt, withModifiers as ft, normalizeClass as De, normalizeStyle as vt, Teleport as yt, normalizeProps as bt, guardReactiveProps as gt } from "vue";
2
+ import { a as ne, c as Oe, S as _t, F as ge, u as tt, t as kt, v as ht, j as Je } from "./app-BIXJtvvD.js";
3
+ import { useDialog as je, useSnackbar as Le, components as ye, useProxiedModel as Ge, useBreakpoints as xt } from "@feedmepos/ui-library";
4
+ import { i as wt, _ as $t, m as It } from "./menu-usage-module-BdjYEk3s.js";
5
+ import { F as de } from "./form-mode.enum-BKiNVH6A.js";
6
+ import { _ as nt } from "./IngredientBindedItem.vue_vue_type_script_setup_true_lang-iCpYEneM.js";
7
+ import { defineStore as ot, storeToRefs as Et } from "pinia";
8
+ import { D as He, R as Ve } from "./row-action.enum-ncgDYAjP.js";
9
+ import { c as Vt } from "./component-BmLAdDiY.js";
10
+ import { a as Z, c as Ke } from "./number-CxbQxQwj.js";
11
+ import { useI18n as ie, useCoreStore as St } from "@feedmepos/mf-common";
12
+ import { u as Ct, _ as Bt } from "./SingleColumnLayout.vue_vue_type_script_setup_true_lang-DwrLsWX_.js";
13
+ import { b as it, c as qe, I as Rt, A as Ne, U as lt, R as Ft } from "./rules-CurdOAcA.js";
14
+ import { a as At, _ as Tt } from "./InventoryBindingForm.vue_vue_type_script_setup_true_lang-C8bktmYH.js";
15
+ import { a as Ue } from "./FmMultiselectDialog-Dt54hvqw.js";
16
+ import { d as at } from "./defineDeepModel-C5ncgNxj.js";
17
+ import { L as Ut, P as Pt, D as Mt } from "./app-C39bYJmq.js";
18
+ import { _ as Ce, c as Dt, d as Gt, e as be } from "./FmUnitInput.vue_vue_type_script_setup_true_lang-DtG9Ieo_.js";
19
+ import { u as Nt } from "./FmMultiselectDialog-BjBx94pY.js";
20
+ import { u as zt } from "./vue-i18n-yL99yI4f.js";
21
+ import { F as Ot } from "./inventory-core-dart.default-Cj7CxnpK.js";
22
+ import { _ as jt } from "./FmCustomAttribute.vue_vue_type_script_setup_true_lang-CG1m-B2p.js";
23
+ import { u as We } from "./feature-BLSNLI5y.js";
24
+ import { F as he } from "./decimal-B8YR17QC.js";
25
+ import { _ as Be } from "./FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-C0nunKjx.js";
26
+ import { b as rt, d as st } from "./xlsx.util-B8azJxkS.js";
27
+ import { f as dt } from "./date2-DbYQycSa.js";
28
+ import { _ as Lt, F as Qe } from "./TableActionableRow.vue_vue_type_script_setup_true_lang-DAMpuZ1X.js";
29
+ import { _ as Kt } from "./FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-CMst9tkA.js";
30
+ const qt = {
31
+ key: 0,
32
+ class: "flex flex-col items-center w-full h-full gap-24"
33
+ }, Wt = { key: 1 }, Yt = { key: 0 }, Jt = /* @__PURE__ */ le({
34
+ __name: "DeleteDialog",
35
+ props: {
36
+ type: {},
37
+ data: {},
38
+ message: {},
39
+ bindedItems: {}
40
+ },
41
+ setup(m) {
42
+ const s = m, l = W(s.bindedItems || []), t = W(!1);
43
+ pt(() => {
44
+ o();
45
+ });
46
+ async function o() {
47
+ var a, $;
48
+ !t.value && ((a = s.data) != null && a._id) && (t.value = !0, l.value = await ne().getAffectedMenu(($ = s.data) == null ? void 0 : $._id), t.value = !1);
49
+ }
50
+ return (a, $) => {
51
+ const d = G("FmSpacer"), r = G("FmCircularProgress");
52
+ return g(), V(Q, null, [
53
+ y("p", null, U(a.message), 1),
54
+ t.value ? (g(), V("div", qt, [
55
+ x(d),
56
+ y("div", null, [
57
+ x(r, { size: "xl" })
58
+ ]),
59
+ $[0] || ($[0] = y("div", { class: "fm-typo-en-body-lg-400 text-fm-color-typo-secondary pl-8" }, "Loading...", -1)),
60
+ x(d)
61
+ ])) : (g(), V("div", Wt, [
62
+ $[2] || ($[2] = y("br", null, null, -1)),
63
+ l.value.length > 0 ? (g(), V("div", Yt, [
64
+ $[1] || ($[1] = y("p", { class: "fm-typo-en-body-lg-600" }, "Affected menu items:", -1)),
65
+ x(nt, {
66
+ name: "Menu",
67
+ bindings: l.value
68
+ }, null, 8, ["bindings"])
69
+ ])) : T("", !0)
70
+ ]))
71
+ ], 64);
72
+ };
73
+ }
74
+ }), ze = ot("recipeForm", function() {
75
+ const s = je(), l = Le(), t = ne(), o = W(!1), a = W();
76
+ function $() {
77
+ const i = {
78
+ recipe: {},
79
+ mode: de.CREATE,
80
+ show: !0,
81
+ "onUpdate:show"(f) {
82
+ a.value.show = f;
83
+ }
84
+ };
85
+ a.value = i;
86
+ }
87
+ async function d(i) {
88
+ const f = {
89
+ recipe: Oe(i),
90
+ mode: de.UPDATE,
91
+ show: !0,
92
+ "onUpdate:show"(v) {
93
+ a.value.show = v;
94
+ }
95
+ };
96
+ a.value = f;
97
+ }
98
+ async function r(i) {
99
+ o.value = !0;
100
+ try {
101
+ await t.deleteRecipe(i), l.open({
102
+ title: "Success",
103
+ message: `Deleted ${i.name}`,
104
+ type: "success"
105
+ });
106
+ } catch (f) {
107
+ if (f instanceof _t && wt(f)) {
108
+ s.open({
109
+ title: "Cannot delete recipe",
110
+ contentComponent: $t,
111
+ contentComponentProps: {
112
+ subject: (i == null ? void 0 : i.name) ?? "",
113
+ items: f.errorResponse.errors.map((v) => {
114
+ var C;
115
+ return {
116
+ chain: [
117
+ {
118
+ itemName: v.name,
119
+ moduleKey: (C = v.message) != null && C.startsWith("modules.") ? It(v.message) : v.module
120
+ }
121
+ ]
122
+ };
123
+ })
124
+ },
125
+ secondaryActions: {
126
+ text: "Close",
127
+ close: !0
128
+ }
129
+ });
130
+ return;
131
+ }
132
+ l.open({
133
+ title: `Cannot delete ${i == null ? void 0 : i.name}`,
134
+ message: "Please try again.",
135
+ type: "error"
136
+ }), console.error("failed to delete recipe", f);
137
+ } finally {
138
+ o.value = !1;
139
+ }
140
+ }
141
+ function u(i) {
142
+ s.open({
143
+ title: `Delete ${(i == null ? void 0 : i.name) ?? "recipe"}?`,
144
+ closeButton: !1,
145
+ primaryActions: {
146
+ text: "Delete",
147
+ close: !0,
148
+ variant: "destructive"
149
+ },
150
+ secondaryActions: {
151
+ text: "Cancel",
152
+ close: !0
153
+ },
154
+ contentComponent: Jt,
155
+ contentComponentProps: {
156
+ type: "menu",
157
+ data: i,
158
+ message: "You may not be able to delete this recipe if it is linked in any of the inventory modules."
159
+ }
160
+ }).onPrimary(() => r(i));
161
+ }
162
+ return {
163
+ createRecipe: $,
164
+ updateRecipe: d,
165
+ deleteRecipe: u,
166
+ recipeDialogProps: a,
167
+ recipeViewLoading: o
168
+ };
169
+ });
170
+ function Ht() {
171
+ const { updateRecipe: m, deleteRecipe: s } = ze(), l = ne(), { t } = ie();
172
+ async function o(i, f) {
173
+ const v = Oe(f);
174
+ if (i === Ve.Edit) {
175
+ await m(v);
176
+ return;
177
+ }
178
+ if (i === Ve.Delete) {
179
+ await s(v);
180
+ return;
181
+ }
182
+ }
183
+ function a(i, f) {
184
+ const v = i.filter((c) => c.type === ge.enum.SKU), C = i.filter(
185
+ (c) => c.type === ge.enum.SKU_GROUP
186
+ ), w = i.filter((c) => c.type === ge.enum.RECIPE);
187
+ return [
188
+ ...v.map((c) => ({ ...c, recipeIds: [...f] })),
189
+ ...C.map((c) => ({ ...c, isGroup: !0, recipeIds: [...f] })),
190
+ ...w.filter((c) => l.recipeById[c.id] && !f.has(c.id)).flatMap(
191
+ (c) => a(l.recipeById[c.id].contains, /* @__PURE__ */ new Set([...f, c.id]))
192
+ )
193
+ ];
194
+ }
195
+ const $ = [
196
+ {
197
+ accessorKey: "recipe",
198
+ header: () => t("inventory.recipe.name"),
199
+ size: 400
200
+ },
201
+ {
202
+ accessorKey: "ingredients",
203
+ header: () => t("inventory.recipe.ingredients"),
204
+ size: "auto",
205
+ // accessor keeps the plain text so filtering still matches; the cell only restyles it
206
+ cell: (i) => re(
207
+ "div",
208
+ { class: "flex flex-col items-start gap-4" },
209
+ i.row.original.bindings.map(
210
+ (f) => re(
211
+ "div",
212
+ {
213
+ class: "flex flex-wrap items-center gap-8 border-1 border-fm-color-neutral-gray-200 fm-corner-radius-md px-8 py-4"
214
+ },
215
+ [
216
+ f.parentRecipe ? re(ye.FmChip, { compact: !0 }, f.parentRecipe) : null,
217
+ f.labels.join(", ")
218
+ ]
219
+ )
220
+ )
221
+ )
222
+ },
223
+ {
224
+ id: "action",
225
+ header: "",
226
+ cell(i) {
227
+ return Vt(
228
+ [He[Ve.Edit], He[Ve.Delete]],
229
+ (f) => {
230
+ o(f, i.row.original.original);
231
+ }
232
+ );
233
+ },
234
+ enableSorting: !1,
235
+ size: 40,
236
+ meta: {
237
+ cellClass: "",
238
+ headerClass: ""
239
+ }
240
+ }
241
+ ];
242
+ function d(i) {
243
+ const f = ne();
244
+ return a(i.contains, /* @__PURE__ */ new Set([i._id])).map((v) => {
245
+ var c, k, I;
246
+ const C = v.recipeIds.slice(1).length ? ((c = f.recipeById[v.recipeIds.at(-1) ?? ""]) == null ? void 0 : c.name) ?? null : null;
247
+ if (v.isGroup) {
248
+ const _ = f.skuGroupById[v.id];
249
+ return _ ? { parentRecipe: C, label: `${_.name} (x${Z(v.amount)})` } : null;
250
+ }
251
+ const w = f.skuById[v.id];
252
+ return w ? {
253
+ parentRecipe: C,
254
+ label: `${w.name} (${Z(v.amount)}${((k = v.measurement) == null ? void 0 : k.abbrev) ?? ((I = w == null ? void 0 : w.unit) == null ? void 0 : I.abbrev)})`
255
+ } : null;
256
+ }).filter((v) => !!v);
257
+ }
258
+ function r(i) {
259
+ const f = [];
260
+ for (const v of i) {
261
+ const C = v.parentRecipe ? f.find((w) => w.parentRecipe === v.parentRecipe) : void 0;
262
+ C ? C.labels.push(v.label) : f.push({ parentRecipe: v.parentRecipe, labels: [v.label] });
263
+ }
264
+ return f;
265
+ }
266
+ function u(i) {
267
+ return i.map((f) => {
268
+ const v = d(f);
269
+ return {
270
+ recipe: f.name,
271
+ ingredients: v.map((C) => C.parentRecipe ? `(${C.parentRecipe}) ${C.label}` : C.label).join(", "),
272
+ bindings: r(v),
273
+ original: f
274
+ };
275
+ });
276
+ }
277
+ return { columnDefs: $, formatRowData: u };
278
+ }
279
+ function Qt() {
280
+ const m = ne(), s = je();
281
+ async function l(a, $, d, r = []) {
282
+ var w, c;
283
+ const u = a.filter((k) => k.type === "SKU"), i = a.filter((k) => k.type !== "SKU"), f = /* @__PURE__ */ new Set();
284
+ if (d)
285
+ for (const k of m.skus)
286
+ !r.some((_) => _ === k._id) && k._id !== d && !((c = (w = k.convert) == null ? void 0 : w.inventoryBindings) != null && c.some((_) => _.id === d)) || f.add(k._id);
287
+ const v = m.skus.map((k) => ({
288
+ label: k.name,
289
+ sublabel: `${k.code}${f.has(k._id) ? " (Cannot bind, will cause recursive binding)" : ""}`,
290
+ value: k,
291
+ disabled: f.has(k._id)
292
+ })), C = v.filter(
293
+ (k) => u.find((I) => I.id === k.value._id) && !f.has(k.value._id)
294
+ ).map((k) => k.value);
295
+ s.open({
296
+ title: "Select ingredients",
297
+ contentComponent: Ue,
298
+ contentComponentProps: {
299
+ items: v,
300
+ modelValue: C,
301
+ virtualScroll: !0
302
+ },
303
+ primaryActions: {
304
+ text: "Confirm",
305
+ close: !0
306
+ },
307
+ secondaryActions: {
308
+ text: "Close",
309
+ close: !0,
310
+ variant: "tertiary"
311
+ }
312
+ }).onPrimary((k) => {
313
+ const I = [
314
+ ...i,
315
+ ...a.filter((_) => k.find((e) => e._id === _.id)),
316
+ ...k.filter((_) => !a.find((e) => e.id === _._id)).map((_) => ({
317
+ type: "SKU",
318
+ id: _._id,
319
+ amount: {
320
+ amount: 1,
321
+ precision: 0
322
+ }
323
+ }))
324
+ ];
325
+ $(I);
326
+ });
327
+ }
328
+ async function t(a, $, d = []) {
329
+ var C;
330
+ const r = a.filter((w) => w.type === "RECIPE"), u = a.filter((w) => w.type !== "RECIPE"), i = /* @__PURE__ */ new Set();
331
+ if (d.length)
332
+ for (const w of m.recipes) {
333
+ const c = ((C = m.recipeBindingFlattenCache[w._id]) == null ? void 0 : C.inventoryBindings) ?? [], k = c.some(
334
+ (e) => e.bindingPaths.some((S) => d.some((p) => p === S.id))
335
+ ), I = c.some(
336
+ (e) => "success" in e && d.includes(e.ingredient._id)
337
+ );
338
+ (d.some((e) => e === w._id) || k || I) && i.add(w._id);
339
+ }
340
+ const f = m.recipes.filter((w) => !d.includes(w._id)).map((w) => ({
341
+ label: w.name,
342
+ sublabel: i.has(w._id) ? "(Cannot bind, will cause recursive binding)" : `${w.contains.length} inventory bindings`,
343
+ value: w,
344
+ disabled: i.has(w._id)
345
+ })), v = f.filter(
346
+ (w) => r.find((c) => c.id === w.value._id) && !i.has(w.value._id)
347
+ ).map((w) => w.value);
348
+ s.open({
349
+ title: "Select recipes",
350
+ contentComponent: Ue,
351
+ contentComponentProps: {
352
+ items: f,
353
+ modelValue: v,
354
+ virtualScroll: !0
355
+ },
356
+ primaryActions: {
357
+ text: "Confirm",
358
+ close: !0
359
+ },
360
+ secondaryActions: {
361
+ text: "Close",
362
+ close: !0,
363
+ variant: "tertiary"
364
+ }
365
+ }).onPrimary((w) => {
366
+ const c = [
367
+ ...a.filter((k) => w.find((I) => I._id === k.id)),
368
+ ...w.filter((k) => !a.find((I) => I.id === k._id)).map((k) => ({
369
+ type: "RECIPE",
370
+ id: k._id,
371
+ amount: {
372
+ amount: 1,
373
+ precision: 0
374
+ }
375
+ })),
376
+ ...u
377
+ ];
378
+ $(c);
379
+ });
380
+ }
381
+ async function o(a, $, d = []) {
382
+ const r = a.filter((v) => v.type === "SKU_GROUP"), u = a.filter((v) => v.type !== "SKU_GROUP"), i = m.skuGroups.filter((v) => !d.includes(v._id)).map((v) => ({
383
+ label: v.name,
384
+ value: v
385
+ })), f = i.filter((v) => r.find((C) => C.id === v.value._id)).map((v) => v.value);
386
+ s.open({
387
+ title: "Select ingredient group",
388
+ contentComponent: Ue,
389
+ contentComponentProps: {
390
+ items: i,
391
+ modelValue: f,
392
+ virtualScroll: !0
393
+ },
394
+ primaryActions: {
395
+ text: "Confirm",
396
+ close: !0
397
+ },
398
+ secondaryActions: {
399
+ text: "Close",
400
+ close: !0,
401
+ variant: "tertiary"
402
+ }
403
+ }).onPrimary((v) => {
404
+ const C = [
405
+ ...a.filter((w) => v.find((c) => c._id === w.id)),
406
+ ...v.filter((w) => !a.find((c) => c.id === w._id)).map((w) => ({
407
+ type: "SKU_GROUP",
408
+ id: w._id,
409
+ amount: {
410
+ amount: 1,
411
+ precision: 0
412
+ }
413
+ })),
414
+ ...u
415
+ ];
416
+ $(C);
417
+ });
418
+ }
419
+ return {
420
+ promptIngredientsBinding: l,
421
+ promptRecipesBinding: t,
422
+ promptIngredientGroupsBinding: o
423
+ };
424
+ }
425
+ const Xt = { class: "flex flex-col" }, Zt = { class: "flex flex-col gap-4" }, Re = /* @__PURE__ */ le({
426
+ __name: "InventoryBindingRule",
427
+ props: {
428
+ disabled: { type: Boolean },
429
+ modelValue: {},
430
+ minCount: {},
431
+ maxCount: {}
432
+ },
433
+ emits: ["update:modelValue"],
434
+ setup(m, { emit: s }) {
435
+ const l = m, t = s, { t: o } = ie(), a = St(), $ = tt(), d = F(() => {
436
+ var w;
437
+ const v = /* @__PURE__ */ new Map(), C = a.restaurants.value.map((c) => c.customAttributes ?? {});
438
+ for (const c of C)
439
+ for (const [k, I] of Object.entries(c))
440
+ v.has(k) || v.set(k, /* @__PURE__ */ new Set()), I && ((w = v.get(k)) == null || w.add(I));
441
+ return v;
442
+ }), r = F(
443
+ () => a.restaurants.value.filter((v) => {
444
+ var C;
445
+ return (C = v.profile) == null ? void 0 : C.code;
446
+ }).map((v) => ({ value: v.profile.code, label: `${v.profile.name} (${v.profile.code})` }))
447
+ ), u = F(() => [
448
+ ...[...d.value.entries()].map(([C, w]) => ({
449
+ type: "string",
450
+ key: C,
451
+ entity: "restaurant",
452
+ values: [...w]
453
+ })),
454
+ {
455
+ type: "string",
456
+ key: "state",
457
+ entity: "restaurant",
458
+ values: [
459
+ ...new Set($.locations.map((C) => C.doc.profile.address.state).filter(Boolean))
460
+ ]
461
+ },
462
+ ...r.value.length > 0 ? [
463
+ {
464
+ type: "string",
465
+ key: "outlet",
466
+ entity: "restaurant",
467
+ options: r.value
468
+ }
469
+ ] : []
470
+ ]), i = W(null);
471
+ let f = null;
472
+ return ue(
473
+ () => l.modelValue,
474
+ (v) => {
475
+ JSON.stringify(v) !== JSON.stringify(f) && (i.value = v ? Ut.build(v) : null);
476
+ },
477
+ { immediate: !0 }
478
+ ), ue(
479
+ i,
480
+ (v) => {
481
+ f = v ? Pt.build(v) : null, t("update:modelValue", f);
482
+ },
483
+ { deep: !0 }
484
+ ), (v, C) => {
485
+ const w = G("FmLabel"), c = G("FmFormGroup");
486
+ return g(), V("div", Xt, [
487
+ y("div", Zt, [
488
+ x(w, {
489
+ label: n(o)("inventory.ingredientGroup.form.rules.title"),
490
+ required: v.minCount != null && v.minCount > 0
491
+ }, null, 8, ["label", "required"]),
492
+ x(n(Mt), {
493
+ modelValue: i.value,
494
+ "onUpdate:modelValue": C[0] || (C[0] = (k) => i.value = k),
495
+ attributes: u.value
496
+ }, null, 8, ["modelValue", "attributes"])
497
+ ]),
498
+ x(c, {
499
+ "model-value": i.value,
500
+ rules: [
501
+ (k) => {
502
+ const I = k ? 1 : 0;
503
+ return l.minCount !== void 0 && I < l.minCount ? n(o)("inventory.ingredientGroup.form.rules.validation.minCount", {
504
+ count: l.minCount
505
+ }) : l.maxCount !== void 0 && I > l.maxCount ? n(o)("inventory.ingredientGroup.form.rules.validation.maxCount", {
506
+ count: l.maxCount
507
+ }) : !0;
508
+ }
509
+ ]
510
+ }, null, 8, ["model-value", "rules"])
511
+ ]);
512
+ };
513
+ }
514
+ }), en = { class: "border-1 mx-3 my-1 rounded-md" }, tn = { class: "flex flex-col w-full border-b border-fm-color-neutral-gray-100" }, nn = {
515
+ class: "flex items-center",
516
+ style: { "min-height": "48px" }
517
+ }, on = { class: "flex-1 fm-typo-en-body-md-400 py-8 px-12" }, ln = { class: "line-clamp-1" }, an = { class: "w-[200px]" }, rn = {
518
+ key: 0,
519
+ class: "w-[52px]"
520
+ }, sn = {
521
+ key: 0,
522
+ class: "flex gap-4 text-fm-color-system-error-400 fm-typo-en-body-sm-400 px-8"
523
+ }, dn = { class: "px-12 pb-4" }, un = /* @__PURE__ */ le({
524
+ __name: "InventoryRecipeBindingV2Field",
525
+ props: {
526
+ disabled: { type: Boolean },
527
+ readonly: { type: Boolean },
528
+ modelValue: {},
529
+ displayName: {},
530
+ showError: { type: Boolean },
531
+ allowRecipeDecimal: { type: Boolean }
532
+ },
533
+ emits: ["update:modelValue", "delete", "settings"],
534
+ setup(m, { emit: s }) {
535
+ const l = s, { t } = ie(), o = at("modelValue"), a = W(Z(o.amount)), $ = F(() => +a.value);
536
+ ue(
537
+ () => o.amount,
538
+ (u) => {
539
+ const i = Z(u);
540
+ +a.value != +i && (a.value = i);
541
+ }
542
+ );
543
+ let d = null;
544
+ function r(u) {
545
+ a.value = u, d && clearTimeout(d), d = setTimeout(() => {
546
+ const i = +u;
547
+ u.length > 0 && isFinite(i) ? o.amount = Ke(i) : o.amount = { amount: 0, precision: 0 };
548
+ }, 300);
549
+ }
550
+ return (u, i) => {
551
+ const f = G("FmTooltip"), v = G("FmTextField"), C = G("FmFormGroup"), w = G("FmButton"), c = G("FmIcon");
552
+ return g(), V("div", en, [
553
+ y("div", tn, [
554
+ y("div", nn, [
555
+ y("div", on, [
556
+ x(f, {
557
+ zIndex: 51,
558
+ variant: "plain",
559
+ placement: "top",
560
+ content: u.displayName
561
+ }, {
562
+ default: J(() => [
563
+ y("span", ln, U(u.displayName), 1)
564
+ ]),
565
+ _: 1
566
+ }, 8, ["content"])
567
+ ]),
568
+ y("div", an, [
569
+ x(C, {
570
+ disabled: u.disabled,
571
+ modelValue: $.value,
572
+ rules: [n(it)(u.allowRecipeDecimal ? 5 : 0), n(qe)(-1)]
573
+ }, {
574
+ default: J(({ invalid: k }) => [
575
+ x(v, {
576
+ class: "w-full",
577
+ disabled: u.disabled,
578
+ modelValue: a.value,
579
+ "onUpdate:modelValue": i[0] || (i[0] = (I) => r(I)),
580
+ invalid: k
581
+ }, null, 8, ["disabled", "modelValue", "invalid"])
582
+ ]),
583
+ _: 1
584
+ }, 8, ["disabled", "modelValue", "rules"])
585
+ ]),
586
+ u.readonly ? T("", !0) : (g(), V("div", rn, [
587
+ x(w, {
588
+ disabled: u.disabled,
589
+ type: "button",
590
+ variant: "plain",
591
+ icon: "delete",
592
+ "icon-color": "#000000",
593
+ onClick: i[1] || (i[1] = () => l("delete", n(o).id))
594
+ }, null, 8, ["disabled"])
595
+ ]))
596
+ ]),
597
+ x(At, {
598
+ "recipe-id": n(o).id,
599
+ multiplier: a.value
600
+ }, null, 8, ["recipe-id", "multiplier"]),
601
+ u.showError ? (g(), V("div", sn, [
602
+ x(c, {
603
+ name: "error",
604
+ color: "system-error-300",
605
+ size: "sm"
606
+ }),
607
+ y("div", null, U(n(t)("inventory.inventoryBindings.circularError")), 1)
608
+ ])) : T("", !0)
609
+ ]),
610
+ y("div", dn, [
611
+ x(Re, {
612
+ modelValue: n(o).rules,
613
+ "onUpdate:modelValue": i[2] || (i[2] = (k) => n(o).rules = k),
614
+ disabled: u.disabled
615
+ }, null, 8, ["modelValue", "disabled"])
616
+ ])
617
+ ]);
618
+ };
619
+ }
620
+ });
621
+ function cn(m) {
622
+ const s = Nt(), { t: l } = zt(), t = ne(), o = F(() => [
623
+ {
624
+ id: "delete",
625
+ header: "",
626
+ cell(d) {
627
+ const r = d.row.original;
628
+ return re(
629
+ "div",
630
+ { class: "w-full flex justify-end" },
631
+ re(ye.FmButton, {
632
+ class: "delete-button",
633
+ key: r._id,
634
+ type: "button",
635
+ icon: "delete",
636
+ variant: "tertiary",
637
+ size: "md",
638
+ disabled: m.disabled ?? !1,
639
+ onClick: () => {
640
+ m.bindingAlternatives = m.bindingAlternatives.filter(
641
+ (u) => u._id !== r._id
642
+ );
643
+ }
644
+ })
645
+ );
646
+ },
647
+ enableSorting: !1,
648
+ size: 40,
649
+ meta: {
650
+ cellClass: "",
651
+ headerClass: ""
652
+ }
653
+ },
654
+ {
655
+ id: "alternative",
656
+ header: () => l("inventory.inventoryBindings.alternativeTable.ingredient"),
657
+ accessorFn: (d) => {
658
+ var r, u;
659
+ return `${((r = t.skuById[d._id]) == null ? void 0 : r.name) ?? ""} (${((u = t.skuById[d._id]) == null ? void 0 : u.code) ?? ""})`;
660
+ },
661
+ cell: ({ row: d }) => {
662
+ const r = t.skuById[d.original._id];
663
+ return re(
664
+ "div",
665
+ {
666
+ class: "w-full flex flex-col"
667
+ },
668
+ [
669
+ re("div", { class: "fm-typo-en-body-lg-400 line-clamp-1" }, r.name),
670
+ re(
671
+ "div",
672
+ { class: "fm-typo-en-body-md-400 line-clamp-1 text-fm-color-typo-secondary" },
673
+ r.code
674
+ )
675
+ ]
676
+ );
677
+ },
678
+ size: "auto",
679
+ enableSorting: !1
680
+ },
681
+ {
682
+ id: "unit",
683
+ header: () => l("inventory.inventoryBindings.alternativeTable.unit"),
684
+ accessorFn: (d) => {
685
+ const r = t.skuById[d._id];
686
+ return r.unit.measurements.computeFirst(
687
+ (u) => u.id === d.trackingMeasurement ? u.name : null
688
+ ) ?? r.unit.name;
689
+ },
690
+ enableSorting: !1
691
+ },
692
+ {
693
+ id: "unitOption",
694
+ header: () => l("inventory.inventoryBindings.alternativeTable.unit"),
695
+ accessorKey: "trackingMeasurement",
696
+ cell(d) {
697
+ const r = t.skuById[d.row.original._id];
698
+ if (!r) return null;
699
+ const u = [
700
+ {
701
+ label: r.unit.name,
702
+ sublabel: r.unit.abbrev,
703
+ value: null
704
+ },
705
+ ...r.unit.measurements.map((i) => ({
706
+ label: `${i.name} (${i.abbrev})`,
707
+ sublabel: l("inventory.inventoryBindings.alternativeTable.measurementOption"),
708
+ value: i.id
709
+ }))
710
+ ].filter((i) => !i.label.toLowerCase().includes("inactive"));
711
+ return re(ye.FmSelect, {
712
+ modelValue: d.row.original.trackingMeasurement ?? null,
713
+ items: u,
714
+ disabled: m.disabled ?? !1,
715
+ "onUpdate:modelValue": (i) => {
716
+ m.bindingAlternatives = m.bindingAlternatives.map((f) => f._id === d.row.original._id ? { ...f, trackingMeasurement: i } : f);
717
+ }
718
+ });
719
+ },
720
+ enableSorting: !1
721
+ },
722
+ {
723
+ id: "priority",
724
+ header: () => l("inventory.inventoryBindings.alternativeTable.priority"),
725
+ accessorKey: "priority",
726
+ enableSorting: !0,
727
+ cell(d) {
728
+ const r = d.row.original;
729
+ return re(ye.FmTextField, {
730
+ modelValue: r.priority ?? d.row.index + 1,
731
+ rules: [
732
+ Rt(),
733
+ Ne(1),
734
+ lt(
735
+ m.bindingAlternatives.filter((u) => u._id !== r._id).map((u) => {
736
+ const i = t.skuById[u._id];
737
+ return {
738
+ label: i == null ? void 0 : i.name,
739
+ value: u.priority
740
+ };
741
+ })
742
+ )
743
+ ],
744
+ "onUpdate:modelValue": (u) => {
745
+ const i = Number(u);
746
+ isNaN(i) || (m.bindingAlternatives = m.bindingAlternatives.map((f) => f._id === d.row.original._id ? { ...f, priority: i } : f));
747
+ }
748
+ });
749
+ }
750
+ },
751
+ {
752
+ id: "default",
753
+ header: () => "",
754
+ accessorKey: "default",
755
+ cell(d) {
756
+ const r = t.skuById[d.row.original._id];
757
+ return r ? re(ye.FmCheckbox, {
758
+ modelValue: d.row.original.default ?? !1,
759
+ value: r._id,
760
+ disabled: m.disabled ?? !1,
761
+ "onUpdate:modelValue": () => {
762
+ m.bindingAlternatives = m.bindingAlternatives.map((u) => u._id === d.row.original._id ? { ...u, default: !0 } : { ...u, default: !1 });
763
+ }
764
+ }) : null;
765
+ },
766
+ enableSorting: !1,
767
+ size: 40,
768
+ meta: {
769
+ cellClass: "",
770
+ headerClass: ""
771
+ }
772
+ },
773
+ {
774
+ id: "move",
775
+ header: "",
776
+ cell(d) {
777
+ const r = d.row.original;
778
+ return re("div", { class: "w-full flex justify-end" }, [
779
+ re(ye.FmButton, {
780
+ key: r._id,
781
+ type: "button",
782
+ icon: "keyboard_arrow_up",
783
+ variant: "tertiary",
784
+ size: "md",
785
+ disabled: m.disabled ?? !1,
786
+ onClick: () => {
787
+ const u = [...m.bindingAlternatives], i = u.findIndex((f) => f._id === r._id);
788
+ if (i > 0) {
789
+ const f = u[i - 1];
790
+ u[i - 1] = r, u[i] = f;
791
+ }
792
+ m.bindingAlternatives = [...u];
793
+ }
794
+ }),
795
+ re(ye.FmButton, {
796
+ key: r._id,
797
+ type: "button",
798
+ icon: "keyboard_arrow_down",
799
+ variant: "tertiary",
800
+ size: "md",
801
+ disabled: m.disabled ?? !1,
802
+ onClick: () => {
803
+ const u = [...m.bindingAlternatives], i = u.findIndex((f) => f._id === r._id);
804
+ if (i < u.length - 1) {
805
+ const f = u[i + 1];
806
+ u[i + 1] = r, u[i] = f;
807
+ }
808
+ m.bindingAlternatives = [...u];
809
+ }
810
+ })
811
+ ]);
812
+ },
813
+ enableSorting: !1,
814
+ size: 40,
815
+ meta: {
816
+ cellClass: "",
817
+ headerClass: ""
818
+ }
819
+ }
820
+ ]);
821
+ return {
822
+ get columnDefs() {
823
+ return o.value;
824
+ },
825
+ promptAddIngredient: async ($) => {
826
+ const d = [];
827
+ for (const i of t.skus)
828
+ $.includes(i._id) || d.push({
829
+ label: i.name,
830
+ sublabel: i.code,
831
+ value: i._id,
832
+ disabled: $.includes(i._id)
833
+ });
834
+ const r = (m.bindingAlternatives ?? []).map((i) => i._id), u = await s.multiSelect(d, r, (i) => {
835
+ var v, C, w, c, k, I;
836
+ const f = (v = m.bindingAlternatives) == null ? void 0 : v.findIndex((_) => _._id === i);
837
+ return {
838
+ _id: i,
839
+ trackingMeasurement: typeof f != "number" || f == -1 ? (C = t.skuById[i]) == null ? void 0 : C.trackingMeasurement : (c = (w = m.bindingAlternatives) == null ? void 0 : w[f]) == null ? void 0 : c.trackingMeasurement,
840
+ priority: ((I = (k = m.bindingAlternatives) == null ? void 0 : k[f]) == null ? void 0 : I.priority) ?? m.bindingAlternatives.length,
841
+ default: !1
842
+ };
843
+ });
844
+ m.bindingAlternatives = u ?? m.bindingAlternatives;
845
+ },
846
+ columnVisibility: {
847
+ delete: !0,
848
+ unit: !1,
849
+ unitOption: !0,
850
+ default: !1,
851
+ // previous demo: sort priority by moving sku element in the array,
852
+ // new demo: sort priority using priority field.
853
+ // can reenable if this use case is requested to be restored
854
+ move: !1
855
+ }
856
+ };
857
+ }
858
+ const pn = { class: "flex flex-col gap-16" }, mn = { class: "flex flex-col" }, fn = { class: "flex justify-between items-center px-2" }, Se = /* @__PURE__ */ le({
859
+ __name: "InventoryBindingAlternative",
860
+ props: {
861
+ disabled: { type: Boolean },
862
+ modelValue: {},
863
+ filterIngredientIds: {}
864
+ },
865
+ emits: ["update:modelValue"],
866
+ setup(m, { emit: s }) {
867
+ const l = m, t = s, { t: o } = ie(), a = cn({
868
+ get disabled() {
869
+ return l.disabled ?? !1;
870
+ },
871
+ get bindingAlternatives() {
872
+ return l.modelValue ?? [];
873
+ },
874
+ set bindingAlternatives(r) {
875
+ t("update:modelValue", r);
876
+ }
877
+ }), $ = (r) => r && r.some((u) => l.filterIngredientIds.includes(u._id)) ? "Contains invalid ingredient" : !0, d = (r) => r && r.length > 5 ? o("inventory.binding.alternative.maximumExceeded", { max: 5 }) : !0;
878
+ return (r, u) => {
879
+ var w;
880
+ const i = G("FmLabel"), f = G("FmButton"), v = G("FmFormGroup"), C = G("FmTable");
881
+ return g(), V("div", pn, [
882
+ y("div", mn, [
883
+ y("div", fn, [
884
+ x(i, {
885
+ label: n(o)("inventory.alternatives")
886
+ }, null, 8, ["label"]),
887
+ x(f, {
888
+ disabled: r.disabled,
889
+ "prepend-icon": "link",
890
+ variant: "primary",
891
+ class: "border-1 rounded-lg border-fm-color-primary",
892
+ onClick: u[0] || (u[0] = (c) => n(a).promptAddIngredient(r.filterIngredientIds)),
893
+ size: "md"
894
+ }, null, 8, ["disabled"])
895
+ ]),
896
+ x(v, {
897
+ "model-value": r.modelValue,
898
+ rules: [$, d]
899
+ }, null, 8, ["model-value", "rules"])
900
+ ]),
901
+ x(C, {
902
+ "row-data": r.modelValue ?? [],
903
+ "column-defs": n(a).columnDefs,
904
+ "page-size": ((w = r.modelValue) == null ? void 0 : w.length) || 0,
905
+ "shrink-at": 9999,
906
+ "column-visibility": n(a).columnVisibility,
907
+ "hide-footer": ""
908
+ }, null, 8, ["row-data", "column-defs", "page-size", "column-visibility"])
909
+ ]);
910
+ };
911
+ }
912
+ }), vn = { class: "border-1 mx-3 my-1 rounded-md" }, yn = { class: "flex flex-col border-b border-fm-color-neutral-gray-100" }, bn = {
913
+ class: "flex items-center w-full",
914
+ style: { "min-height": "48px" }
915
+ }, gn = { class: "flex-1 fm-typo-en-body-md-400 py-8 px-12" }, _n = { class: "line-clamp-1 w-full" }, kn = { class: "w-[150px]" }, hn = {
916
+ key: 0,
917
+ class: "w-[52px]"
918
+ }, xn = { class: "flex flex-col px-12 pb-4" }, wn = /* @__PURE__ */ le({
919
+ __name: "InventorySkuBindingV2Field",
920
+ props: {
921
+ disabled: { type: Boolean },
922
+ readonly: { type: Boolean },
923
+ modelValue: {},
924
+ displayName: {},
925
+ unit: {},
926
+ showError: { type: Boolean },
927
+ ableToConfigureAlternative: { type: Boolean },
928
+ ableToApplyRules: { type: Boolean }
929
+ },
930
+ emits: ["update:modelValue", "delete", "settings"],
931
+ setup(m, { emit: s }) {
932
+ const l = s, { t } = ie(), o = at("modelValue");
933
+ function a(d) {
934
+ d && (o.amount = d.amount, o.measurement = d.measurement);
935
+ }
936
+ function $() {
937
+ return {
938
+ modelValue: {
939
+ amount: o.amount,
940
+ measurement: o.measurement
941
+ },
942
+ amountAsString: Ot.toFormatString({
943
+ value: o.amount
944
+ })
945
+ };
946
+ }
947
+ return (d, r) => {
948
+ const u = G("FmTooltip"), i = G("FmButton"), f = G("FmFormGroup");
949
+ return g(), V("div", vn, [
950
+ y("div", yn, [
951
+ y("div", bn, [
952
+ y("div", gn, [
953
+ x(u, {
954
+ zIndex: 51,
955
+ variant: "plain",
956
+ placement: "top",
957
+ content: d.displayName
958
+ }, {
959
+ default: J(() => [
960
+ y("span", _n, U(d.displayName), 1)
961
+ ]),
962
+ _: 1
963
+ }, 8, ["content"])
964
+ ]),
965
+ y("div", kn, [
966
+ x(Ce, {
967
+ "model-value": { amount: n(o).amount, measurement: n(o).measurement },
968
+ "onUpdate:modelValue": a,
969
+ unit: d.unit,
970
+ placement: "bottom",
971
+ "convert-amount-on-change-unit": "",
972
+ disabled: d.readonly
973
+ }, null, 8, ["model-value", "unit", "disabled"])
974
+ ]),
975
+ d.readonly ? T("", !0) : (g(), V("div", hn, [
976
+ x(i, {
977
+ disabled: d.disabled,
978
+ type: "button",
979
+ variant: "tertiary",
980
+ icon: "delete",
981
+ onClick: r[0] || (r[0] = () => l("delete", n(o).id))
982
+ }, null, 8, ["disabled"])
983
+ ]))
984
+ ]),
985
+ y("div", xn, [
986
+ x(f, {
987
+ modelValue: n(o).amount,
988
+ rules: [n(qe)(0)]
989
+ }, null, 8, ["modelValue", "rules"]),
990
+ x(f, {
991
+ modelValue: $(),
992
+ rules: [
993
+ n(Dt)(),
994
+ n(Gt)(d.unit),
995
+ () => d.showError ? n(t)("inventory.inventoryBindings.invalidWarning") : !0
996
+ ]
997
+ }, null, 8, ["modelValue", "rules"])
998
+ ]),
999
+ d.ableToApplyRules ? (g(), Y(Re, {
1000
+ key: 0,
1001
+ modelValue: n(o).rules,
1002
+ "onUpdate:modelValue": r[1] || (r[1] = (v) => n(o).rules = v),
1003
+ disabled: d.disabled
1004
+ }, null, 8, ["modelValue", "disabled"])) : T("", !0),
1005
+ d.ableToConfigureAlternative ? (g(), Y(Se, {
1006
+ key: 1,
1007
+ modelValue: n(o).alternatives,
1008
+ "onUpdate:modelValue": r[2] || (r[2] = (v) => n(o).alternatives = v),
1009
+ disabled: d.disabled,
1010
+ filterIngredientIds: [n(o).id]
1011
+ }, null, 8, ["modelValue", "disabled", "filterIngredientIds"])) : T("", !0)
1012
+ ])
1013
+ ]);
1014
+ };
1015
+ }
1016
+ });
1017
+ exports.FfCalculator;
1018
+ const $n = { class: "flex flex-col gap-24" }, In = {
1019
+ key: 0,
1020
+ class: "flex flex-col gap-16"
1021
+ }, En = { class: "flex items-center" }, Vn = { class: "flex-1 fm-typo-en-title-sm-600" }, Sn = { class: "flex flex-col" }, Cn = { class: "flex py-8 px-12 border-b border-fm-color-neutral-gray-200 bg-fm-color-neutral-gray-100 h-[44px] items-center" }, Bn = { class: "fm-typo-en-body-md-600 text-fm-color-typo-secondary" }, Rn = {
1022
+ key: 0,
1023
+ class: "w-[52px]"
1024
+ }, Fn = {
1025
+ key: 1,
1026
+ class: "w-[52px]"
1027
+ }, An = {
1028
+ key: 1,
1029
+ class: "flex flex-col gap-16"
1030
+ }, Tn = { class: "flex items-center" }, Un = { class: "flex-1 fm-typo-en-title-sm-600" }, Pn = { class: "flex flex-col" }, Mn = { class: "flex py-8 px-12 border-b border-fm-color-neutral-gray-200 bg-fm-color-neutral-gray-100 h-[44px] items-center" }, Dn = { class: "fm-typo-en-body-md-600 text-fm-color-typo-secondary" }, Gn = { class: "flex flex-col w-full border-b border-fm-color-neutral-gray-100" }, Nn = {
1031
+ key: 0,
1032
+ class: "flex gap-4 text-fm-color-system-error-400 fm-typo-en-body-sm-400"
1033
+ }, zn = {
1034
+ class: "flex items-center",
1035
+ style: { "min-height": "48px" }
1036
+ }, On = { class: "flex-1 fm-typo-en-body-md-400 py-8 px-12" }, jn = { class: "flex flex-col" }, Ln = { class: "w-[200px]" }, Kn = {
1037
+ key: 0,
1038
+ class: "w-[52px]"
1039
+ }, qn = { class: "flex flex-col gap-16" }, Wn = { class: "flex items-center" }, Yn = { class: "flex-1 fm-typo-en-title-sm-600" }, Jn = { class: "flex flex-col" }, Hn = { class: "flex py-8 px-12 border-b border-fm-color-neutral-gray-200 bg-fm-color-neutral-gray-100 h-[44px] items-center" }, Qn = { class: "flex-1 fm-typo-en-body-md-600 text-fm-color-typo-secondary" }, Xn = { class: "fm-typo-en-body-md-600 text-fm-color-typo-secondary w-[150px] px-16" }, Zn = {
1040
+ key: 0,
1041
+ class: "w-[52px]"
1042
+ }, eo = {
1043
+ key: 0,
1044
+ class: "flex flex-col border-b border-fm-color-neutral-gray-100"
1045
+ }, to = {
1046
+ class: "flex items-center w-full",
1047
+ style: { "min-height": "48px" }
1048
+ }, no = { class: "flex-1 fm-typo-en-body-md-400 py-8 px-12 text-fm-color-typo-secondary line-clamp-1" }, oo = {
1049
+ key: 0,
1050
+ class: "w-[52px]"
1051
+ }, io = { class: "flex gap-4 text-fm-color-system-error-400 fm-typo-en-body-sm-400 px-12 pb-4" }, lo = /* @__PURE__ */ le({
1052
+ __name: "InventoryBindingFormV2",
1053
+ props: {
1054
+ id: {},
1055
+ modelValue: { default: () => [] },
1056
+ excludeBindingId: {},
1057
+ rules: { default: () => [] },
1058
+ iframeMode: { type: Boolean },
1059
+ disabled: { type: Boolean },
1060
+ readonly: { type: Boolean },
1061
+ recipeBindingConfig: { default: () => ({ enabled: !0, ableToApplyRules: !1 }) },
1062
+ skuBindingConfig: { default: () => ({
1063
+ enabled: !0,
1064
+ ableToApplyRules: !1,
1065
+ ableToConfigureAlternative: !1
1066
+ }) },
1067
+ enableIngredientGroup: { type: Boolean },
1068
+ allowRecipeDecimal: { type: Boolean }
1069
+ },
1070
+ emits: ["update:modelValue", "click:pick-inventory-bindings"],
1071
+ setup(m, { emit: s }) {
1072
+ const { t: l } = ie(), t = ne(), o = F(() => t.recipeById), a = F(() => t.skuById), $ = F(() => t.skuGroupById), d = m, r = s, u = F(() => kt({
1073
+ parentId: d.id,
1074
+ bindings: d.modelValue,
1075
+ recipes: t.recipes.map((R) => R._id === d.id ? {
1076
+ ...R,
1077
+ contains: d.modelValue
1078
+ } : R),
1079
+ skus: t.skus.map((R) => R._id === d.id ? {
1080
+ ...R,
1081
+ convert: {
1082
+ inventoryBindings: d.modelValue
1083
+ }
1084
+ } : R),
1085
+ skuGroups: t.skuGroups
1086
+ }).inventoryBindings.filter((R) => "error" in R && R.error).map((R) => R).filter((R) => R.reason === ht.enum.circularDependency)), i = F(
1087
+ () => new Set(u.value.map((b) => {
1088
+ var B;
1089
+ return (B = b.bindingPaths[0]) == null ? void 0 : B.id;
1090
+ }))
1091
+ ), f = F(() => d.modelValue.filter((b) => b.type === "RECIPE")), { promptIngredientsBinding: v, promptRecipesBinding: C, promptIngredientGroupsBinding: w } = Qt();
1092
+ async function c() {
1093
+ if (d.iframeMode) {
1094
+ r("click:pick-inventory-bindings", "RECIPE");
1095
+ return;
1096
+ }
1097
+ C(
1098
+ d.modelValue,
1099
+ (b) => r("update:modelValue", b),
1100
+ d.id ? [d.id] : []
1101
+ );
1102
+ }
1103
+ const k = F(() => d.modelValue.filter((b) => b.type === "SKU_GROUP"));
1104
+ async function I() {
1105
+ w(
1106
+ d.modelValue,
1107
+ (b) => r("update:modelValue", b),
1108
+ d.id ? [d.id] : []
1109
+ );
1110
+ }
1111
+ function _(b, B, R) {
1112
+ const A = +B;
1113
+ let P = R;
1114
+ B.length > 0 && isFinite(A) ? P = R.map((K) => (K.id !== b || (K.amount = Ke(A)), K)) : P = R.map((K) => (K.id !== b || (K.amount = { amount: 0, precision: 0 }), K)), r("update:modelValue", P);
1115
+ }
1116
+ const e = F(() => d.modelValue.filter((b) => b.type === "SKU") ?? []);
1117
+ async function S() {
1118
+ if (d.iframeMode) {
1119
+ r("click:pick-inventory-bindings", "SKU");
1120
+ return;
1121
+ }
1122
+ v(
1123
+ d.modelValue,
1124
+ (b) => r("update:modelValue", b),
1125
+ d.excludeBindingId,
1126
+ d.id ? [d.id] : []
1127
+ );
1128
+ }
1129
+ function p(b) {
1130
+ const B = d.modelValue.map((R) => R.id === b.id ? b : R);
1131
+ r("update:modelValue", B);
1132
+ }
1133
+ function h(b) {
1134
+ const B = d.modelValue.filter((R) => R.id !== b);
1135
+ r("update:modelValue", B);
1136
+ }
1137
+ function N(b) {
1138
+ var R, A;
1139
+ if (b.type !== ge.enum.SKU)
1140
+ throw new Error("Non-SKU binding does not have unit");
1141
+ if (!((R = a.value[b.id]) == null ? void 0 : R.unit))
1142
+ throw new Error(`Cannot find ingredient: ${b.id}`);
1143
+ return (A = a.value[b.id]) == null ? void 0 : A.unit;
1144
+ }
1145
+ function z(b) {
1146
+ return !a.value[b.id];
1147
+ }
1148
+ return (b, B) => {
1149
+ var H, ee, O;
1150
+ const R = G("FmFormGroup"), A = G("FmButton"), P = G("FmIcon"), K = G("FmTextField");
1151
+ return g(), V("div", $n, [
1152
+ x(R, {
1153
+ disabled: b.disabled,
1154
+ "model-value": b.modelValue,
1155
+ rules: [
1156
+ ...b.rules,
1157
+ () => u.value.length ? "There is a binding error in your configuration" : !0
1158
+ ]
1159
+ }, {
1160
+ label: J(() => B[4] || (B[4] = [
1161
+ y("div", { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, " Define the inventory bindings for this recipe or ingredient. ", -1)
1162
+ ])),
1163
+ _: 1
1164
+ }, 8, ["disabled", "model-value", "rules"]),
1165
+ ((H = b.recipeBindingConfig) == null ? void 0 : H.enabled) !== !1 ? (g(), V("div", In, [
1166
+ y("div", En, [
1167
+ y("div", Vn, U(n(l)("inventory.inventoryBindings.recipe")), 1),
1168
+ b.readonly ? T("", !0) : (g(), Y(A, {
1169
+ key: 0,
1170
+ variant: "secondary",
1171
+ "text-color": "primary",
1172
+ "border-color": "primary",
1173
+ label: n(l)("inventory.inventoryBindings.linkRecipe"),
1174
+ "prepend-icon": "link",
1175
+ onClick: c
1176
+ }, null, 8, ["label"]))
1177
+ ]),
1178
+ y("div", Sn, [
1179
+ y("div", Cn, [
1180
+ y("div", Bn, U(n(l)("inventory.inventoryBindings.recipe")), 1),
1181
+ B[5] || (B[5] = y("div", { class: "w-[200px]" }, null, -1)),
1182
+ b.recipeBindingConfig.ableToApplyRules ? (g(), V("div", Rn)) : T("", !0),
1183
+ b.readonly ? T("", !0) : (g(), V("div", Fn))
1184
+ ]),
1185
+ (g(!0), V(Q, null, me(f.value, (M) => {
1186
+ var j;
1187
+ return g(), Y(un, {
1188
+ key: M.id,
1189
+ "model-value": M,
1190
+ "display-name": (j = o.value[M.id]) == null ? void 0 : j.name,
1191
+ "show-error": i.value.has(M.id),
1192
+ readonly: b.readonly,
1193
+ disabled: b.disabled,
1194
+ "allow-recipe-decimal": b.allowRecipeDecimal,
1195
+ "onUpdate:modelValue": B[0] || (B[0] = (q) => p(q)),
1196
+ onDelete: B[1] || (B[1] = (q) => h(q))
1197
+ }, null, 8, ["model-value", "display-name", "show-error", "readonly", "disabled", "allow-recipe-decimal"]);
1198
+ }), 128))
1199
+ ])
1200
+ ])) : T("", !0),
1201
+ b.enableIngredientGroup ? (g(), V("div", An, [
1202
+ y("div", Tn, [
1203
+ y("div", Un, U(n(l)("inventory.inventoryBindings.ingredientGroup")), 1),
1204
+ b.readonly ? T("", !0) : (g(), Y(A, {
1205
+ key: 0,
1206
+ variant: "secondary",
1207
+ "text-color": "primary",
1208
+ "border-color": "primary",
1209
+ label: n(l)("inventory.inventoryBindings.linkIngredientGroup"),
1210
+ "prepend-icon": "link",
1211
+ onClick: I
1212
+ }, null, 8, ["label"]))
1213
+ ]),
1214
+ y("div", Pn, [
1215
+ y("div", Mn, [
1216
+ y("div", Dn, U(n(l)("inventory.inventoryBindings.ingredientGroup")), 1),
1217
+ B[6] || (B[6] = y("div", { class: "w-[200px]" }, null, -1)),
1218
+ B[7] || (B[7] = y("div", { class: "w-[52px]" }, null, -1))
1219
+ ]),
1220
+ (g(!0), V(Q, null, me(k.value, (M) => (g(), Y(R, {
1221
+ key: M.id,
1222
+ disabled: b.disabled,
1223
+ modelValue: +n(Z)(M.amount ?? { amount: 1, precision: 0 }),
1224
+ rules: [n(it)(0), n(qe)(0)]
1225
+ }, {
1226
+ default: J(({ invalid: j }) => {
1227
+ var q;
1228
+ return [
1229
+ y("div", Gn, [
1230
+ i.value.has(M.id) ? (g(), V("div", Nn, [
1231
+ x(P, {
1232
+ name: "error",
1233
+ color: "system-error-300",
1234
+ size: "sm"
1235
+ }),
1236
+ y("div", null, U(n(l)("inventory.inventoryBindings.circularError")), 1)
1237
+ ])) : T("", !0),
1238
+ y("div", zn, [
1239
+ y("div", On, [
1240
+ y("div", jn, U((q = $.value[M.id]) == null ? void 0 : q.name), 1)
1241
+ ]),
1242
+ y("div", Ln, [
1243
+ x(K, {
1244
+ class: "w-full",
1245
+ disabled: b.disabled,
1246
+ modelValue: +n(Z)(M.amount ?? { amount: 1, precision: 0 }),
1247
+ "onUpdate:modelValue": (oe) => _(M.id, oe, b.modelValue),
1248
+ invalid: j
1249
+ }, null, 8, ["disabled", "modelValue", "onUpdate:modelValue", "invalid"])
1250
+ ]),
1251
+ b.readonly ? T("", !0) : (g(), V("div", Kn, [
1252
+ x(A, {
1253
+ disabled: b.disabled,
1254
+ type: "button",
1255
+ variant: "plain",
1256
+ icon: "delete",
1257
+ "icon-color": "#000000",
1258
+ onClick: (oe) => h(M.id)
1259
+ }, null, 8, ["disabled", "onClick"])
1260
+ ]))
1261
+ ])
1262
+ ])
1263
+ ];
1264
+ }),
1265
+ _: 2
1266
+ }, 1032, ["disabled", "modelValue", "rules"]))), 128))
1267
+ ])
1268
+ ])) : T("", !0),
1269
+ y("div", qn, [
1270
+ y("div", Wn, [
1271
+ y("div", Yn, U(n(l)("inventory.inventoryBindings.ingredient")), 1),
1272
+ b.readonly ? T("", !0) : (g(), Y(A, {
1273
+ key: 0,
1274
+ variant: "secondary",
1275
+ "text-color": "primary",
1276
+ "border-color": "primary",
1277
+ label: n(l)("inventory.inventoryBindings.linkIngredient"),
1278
+ "prepend-icon": "link",
1279
+ onClick: S
1280
+ }, null, 8, ["label"]))
1281
+ ]),
1282
+ y("div", Jn, [
1283
+ y("div", Hn, [
1284
+ y("div", Qn, U(n(l)("inventory.inventoryBindings.ingredient")), 1),
1285
+ y("div", Xn, U(n(l)("inventory.inventoryBindings.amount")), 1),
1286
+ B[8] || (B[8] = y("div", { class: "w-[52px]" }, null, -1)),
1287
+ (ee = b.skuBindingConfig) != null && ee.ableToApplyRules || (O = b.skuBindingConfig) != null && O.ableToConfigureAlternative ? (g(), V("div", Zn)) : T("", !0)
1288
+ ]),
1289
+ (g(!0), V(Q, null, me(e.value, (M) => {
1290
+ var j, q, oe;
1291
+ return g(), V(Q, {
1292
+ key: M.id
1293
+ }, [
1294
+ z(M) ? (g(), V("div", eo, [
1295
+ y("div", to, [
1296
+ y("div", no, U(M.id), 1),
1297
+ b.readonly ? T("", !0) : (g(), V("div", oo, [
1298
+ x(A, {
1299
+ disabled: b.disabled,
1300
+ type: "button",
1301
+ variant: "tertiary",
1302
+ icon: "delete",
1303
+ onClick: () => h(M.id)
1304
+ }, null, 8, ["disabled", "onClick"])
1305
+ ]))
1306
+ ]),
1307
+ y("div", io, [
1308
+ x(P, {
1309
+ name: "error",
1310
+ color: "system-error-300",
1311
+ size: "sm"
1312
+ }),
1313
+ y("div", null, U(n(l)("inventory.inventoryBindings.missingIngredient")), 1)
1314
+ ])
1315
+ ])) : (g(), Y(wn, {
1316
+ key: 1,
1317
+ "model-value": M,
1318
+ "display-name": (j = a.value[M.id]) == null ? void 0 : j.name,
1319
+ unit: N(M),
1320
+ "show-error": i.value.has(M.id),
1321
+ "able-to-apply-rules": ((q = b.skuBindingConfig) == null ? void 0 : q.ableToApplyRules) === !0,
1322
+ "able-to-configure-alternative": ((oe = b.skuBindingConfig) == null ? void 0 : oe.ableToConfigureAlternative) === !0,
1323
+ readonly: b.readonly,
1324
+ disabled: b.disabled,
1325
+ "onUpdate:modelValue": B[2] || (B[2] = (X) => p(X)),
1326
+ onDelete: B[3] || (B[3] = (X) => h(X))
1327
+ }, null, 8, ["model-value", "display-name", "unit", "show-error", "able-to-apply-rules", "able-to-configure-alternative", "readonly", "disabled"]))
1328
+ ], 64);
1329
+ }), 128))
1330
+ ])
1331
+ ])
1332
+ ]);
1333
+ };
1334
+ }
1335
+ }), ao = { class: "flex flex-col gap-40" }, ro = {
1336
+ key: 0,
1337
+ class: "flex flex-col gap-16"
1338
+ }, so = {
1339
+ key: 0,
1340
+ class: "col-span-2 mt-16 border-1 border-fm-color-neutral-gray-200 fm-corner-radius-lg flex flex-col p-16 gap-16"
1341
+ }, uo = {
1342
+ key: 0,
1343
+ class: "flex flex-col items-center w-full h-full gap-24"
1344
+ }, co = { key: 1 }, po = { class: "mt-32" }, mo = /* @__PURE__ */ le({
1345
+ __name: "RecipeForm",
1346
+ props: {
1347
+ mode: {},
1348
+ modelValue: {},
1349
+ disabled: { type: Boolean }
1350
+ },
1351
+ emits: ["update:modelValue", "click:submit"],
1352
+ setup(m, { expose: s, emit: l }) {
1353
+ const t = m, o = l, a = We(), { t: $ } = ie(), d = F({
1354
+ get() {
1355
+ var p;
1356
+ return ((p = t.modelValue) == null ? void 0 : p.name) ?? "";
1357
+ },
1358
+ set(p) {
1359
+ const h = t.modelValue ?? {};
1360
+ h.name = p, o("update:modelValue", h);
1361
+ }
1362
+ }), r = F({
1363
+ get() {
1364
+ var p;
1365
+ return ((p = t.modelValue) == null ? void 0 : p.contains) ?? [];
1366
+ },
1367
+ set(p) {
1368
+ const h = t.modelValue ?? {};
1369
+ h.contains = p, o("update:modelValue", h);
1370
+ }
1371
+ }), u = F({
1372
+ get() {
1373
+ var p;
1374
+ return ((p = t.modelValue) == null ? void 0 : p.customAttributes) ?? {};
1375
+ },
1376
+ set(p) {
1377
+ const h = t.modelValue ? {
1378
+ ...t.modelValue
1379
+ } : {};
1380
+ h.customAttributes = p, o("update:modelValue", h);
1381
+ }
1382
+ }), i = F({
1383
+ get() {
1384
+ var p;
1385
+ return ((p = t.modelValue) == null ? void 0 : p.version) ?? null;
1386
+ },
1387
+ set(p) {
1388
+ const h = t.modelValue ? { ...t.modelValue } : {};
1389
+ h.version = p, o("update:modelValue", h);
1390
+ }
1391
+ }), f = F({
1392
+ get() {
1393
+ return i.value === "v2";
1394
+ },
1395
+ set(p) {
1396
+ i.value = p ? "v2" : null;
1397
+ }
1398
+ });
1399
+ function v() {
1400
+ o("click:submit");
1401
+ }
1402
+ const C = W();
1403
+ s({
1404
+ validateInputs: () => {
1405
+ var p, h;
1406
+ (h = (p = C.value) == null ? void 0 : p.validateInputs) == null || h.call(p);
1407
+ },
1408
+ resetInputsValidation: () => {
1409
+ var p, h;
1410
+ (h = (p = C.value) == null ? void 0 : p.resetInputsValidation) == null || h.call(p);
1411
+ },
1412
+ resetInputs: () => {
1413
+ var p, h;
1414
+ (h = (p = C.value) == null ? void 0 : p.resetInputs) == null || h.call(p);
1415
+ }
1416
+ });
1417
+ const w = ne(), c = W([]), k = W(!1), I = W(!1);
1418
+ ue(k, async (p) => {
1419
+ _(p);
1420
+ });
1421
+ async function _(p) {
1422
+ var h, N;
1423
+ p && !I.value && ((h = t.modelValue) != null && h._id) && (I.value = !0, c.value = await w.getAffectedMenu((N = t.modelValue) == null ? void 0 : N._id).delayed(500), I.value = !1);
1424
+ }
1425
+ const e = F(
1426
+ () => w.recipes.map((p) => ({ label: p.name, value: p.name }))
1427
+ ), S = F(() => {
1428
+ var p;
1429
+ return ((p = t.modelValue) == null ? void 0 : p.name) ?? "";
1430
+ });
1431
+ return (p, h) => {
1432
+ const N = G("FmTextField"), z = G("FmSwitch"), b = G("FmCard"), B = G("FmSpacer"), R = G("FmCircularProgress"), A = G("FmForm");
1433
+ return g(), Y(A, {
1434
+ ref_key: "formRef",
1435
+ ref: C,
1436
+ onValidationSuccess: v
1437
+ }, {
1438
+ default: J(() => [
1439
+ y("div", ao, [
1440
+ x(N, {
1441
+ disabled: p.disabled,
1442
+ label: n($)("inventory.recipe.name"),
1443
+ "model-value": d.value,
1444
+ "onUpdate:modelValue": h[0] || (h[0] = (P) => d.value = P),
1445
+ rules: [
1446
+ n(Ft)(),
1447
+ n(lt)(e.value, S.value, (P) => `[${P.value}] already exists`)
1448
+ ],
1449
+ "label-mark": "required"
1450
+ }, null, 8, ["disabled", "label", "model-value", "rules"]),
1451
+ n(a).enableRecipeV2 ? (g(), V("div", ro, [
1452
+ x(z, {
1453
+ modelValue: f.value,
1454
+ "onUpdate:modelValue": h[1] || (h[1] = (P) => f.value = P),
1455
+ value: !0,
1456
+ label: n($)("inventory.recipe.enableRecipeV2"),
1457
+ "label-placement": "right",
1458
+ disabled: p.disabled,
1459
+ sublabel: n($)("inventory.recipe.recipeV2Warning")
1460
+ }, null, 8, ["modelValue", "label", "disabled", "sublabel"])
1461
+ ])) : T("", !0),
1462
+ x(b, {
1463
+ variant: "outlined",
1464
+ class: "p-16"
1465
+ }, {
1466
+ default: J(() => {
1467
+ var P, K;
1468
+ return [
1469
+ n(a).enableRecipeV2 ? (g(), Y(lo, {
1470
+ key: 0,
1471
+ id: (P = p.modelValue) == null ? void 0 : P._id,
1472
+ disabled: p.disabled,
1473
+ "model-value": r.value,
1474
+ "onUpdate:modelValue": h[2] || (h[2] = (H) => r.value = H),
1475
+ rules: [n(Ne)(1)],
1476
+ "enable-ingredient-group": n(a).enableIngredientGroup,
1477
+ "allow-recipe-decimal": "",
1478
+ "recipe-binding-config": { enabled: !f.value, ableToApplyRules: f.value },
1479
+ "sku-binding-config": {
1480
+ ableToConfigureAlternative: f.value
1481
+ }
1482
+ }, null, 8, ["id", "disabled", "model-value", "rules", "enable-ingredient-group", "recipe-binding-config", "sku-binding-config"])) : (g(), Y(Tt, {
1483
+ key: 1,
1484
+ id: (K = p.modelValue) == null ? void 0 : K._id,
1485
+ disabled: p.disabled,
1486
+ "model-value": r.value,
1487
+ "onUpdate:modelValue": h[3] || (h[3] = (H) => r.value = H),
1488
+ rules: [n(Ne)(1)],
1489
+ "enable-ingredient-group": n(a).enableIngredientGroup,
1490
+ "allow-recipe-decimal": ""
1491
+ }, null, 8, ["id", "disabled", "model-value", "rules", "enable-ingredient-group"]))
1492
+ ];
1493
+ }),
1494
+ _: 1
1495
+ })
1496
+ ]),
1497
+ p.mode !== n(de).CREATE ? (g(), V("div", so, [
1498
+ x(z, {
1499
+ label: "Show binded items",
1500
+ modelValue: k.value,
1501
+ "onUpdate:modelValue": h[4] || (h[4] = (P) => k.value = P),
1502
+ "label-placement": "right",
1503
+ disabled: I.value
1504
+ }, null, 8, ["modelValue", "disabled"]),
1505
+ I.value ? (g(), V("div", uo, [
1506
+ x(B),
1507
+ y("div", null, [
1508
+ x(R, { size: "xl" })
1509
+ ]),
1510
+ h[6] || (h[6] = y("div", { class: "fm-typo-en-body-lg-400 text-fm-color-typo-secondary pl-8" }, "Loading...", -1)),
1511
+ x(B)
1512
+ ])) : k.value && c.value.length ? (g(), V("div", co, [
1513
+ x(nt, {
1514
+ name: "Menu",
1515
+ bindings: c.value
1516
+ }, null, 8, ["bindings"])
1517
+ ])) : T("", !0)
1518
+ ])) : T("", !0),
1519
+ y("div", po, [
1520
+ x(jt, {
1521
+ entity: "inventoryRecipe",
1522
+ modelValue: u.value,
1523
+ "onUpdate:modelValue": h[5] || (h[5] = (P) => u.value = P)
1524
+ }, null, 8, ["modelValue"])
1525
+ ])
1526
+ ]),
1527
+ _: 1
1528
+ }, 512);
1529
+ };
1530
+ }
1531
+ }), fo = { class: "flex gap-4" }, vo = /* @__PURE__ */ le({
1532
+ __name: "RecipeDialog",
1533
+ props: {
1534
+ show: { type: Boolean },
1535
+ recipe: {},
1536
+ mode: { default: de.READ }
1537
+ },
1538
+ emits: ["update:show"],
1539
+ setup(m) {
1540
+ const s = m, l = ne(), t = Le(), { t: o } = ie(), a = Ge(s, "show"), $ = Ge(s, "recipe"), d = F(() => {
1541
+ switch (s.mode) {
1542
+ case de.READ:
1543
+ return "";
1544
+ case de.UPDATE:
1545
+ return o("inventory.recipe.update.title");
1546
+ case de.CREATE:
1547
+ return o("inventory.recipe.create.title");
1548
+ }
1549
+ return "";
1550
+ }), r = F(() => {
1551
+ switch (s.mode) {
1552
+ case de.READ:
1553
+ return "";
1554
+ case de.UPDATE:
1555
+ return o("common.save");
1556
+ case de.CREATE:
1557
+ return o("common.add");
1558
+ }
1559
+ return "";
1560
+ }), u = W(), i = W(!1);
1561
+ async function f() {
1562
+ i.value = !0;
1563
+ try {
1564
+ const c = Oe($.value);
1565
+ c.precision ?? (c.precision = 0), c.measurements ?? (c.measurements = []), await l.createRecipe(c), a.value = !1, t.open({
1566
+ title: o("inventory.common.success"),
1567
+ message: o("inventory.recipe.create.success", { name: $.value.name }),
1568
+ type: "success"
1569
+ });
1570
+ } catch (c) {
1571
+ c instanceof Je || t.open({
1572
+ title: o("inventory.recipe.create.error.title"),
1573
+ message: o("inventory.recipe.create.error.message"),
1574
+ type: "error"
1575
+ });
1576
+ } finally {
1577
+ i.value = !1;
1578
+ }
1579
+ }
1580
+ async function v() {
1581
+ i.value = !0;
1582
+ try {
1583
+ await l.updateRecipe($.value), a.value = !1, t.open({
1584
+ title: o("inventory.common.success"),
1585
+ message: o("inventory.recipe.update.success", { name: $.value.name }),
1586
+ type: "success"
1587
+ });
1588
+ } catch (c) {
1589
+ c instanceof Je || t.open({
1590
+ title: o("inventory.recipe.update.error.title"),
1591
+ message: o("inventory.recipe.update.error.message"),
1592
+ type: "error"
1593
+ });
1594
+ } finally {
1595
+ i.value = !1;
1596
+ }
1597
+ }
1598
+ function C() {
1599
+ var c, k;
1600
+ (k = (c = u.value) == null ? void 0 : c.validateInputs) == null || k.call(c);
1601
+ }
1602
+ function w() {
1603
+ switch (s.mode) {
1604
+ case de.READ:
1605
+ return;
1606
+ case de.UPDATE:
1607
+ return v();
1608
+ case de.CREATE:
1609
+ return f();
1610
+ }
1611
+ }
1612
+ return (c, k) => {
1613
+ const I = G("FmButton"), _ = G("FmSideSheet");
1614
+ return g(), Y(_, {
1615
+ "model-value": n(a),
1616
+ "onUpdate:modelValue": k[3] || (k[3] = (e) => Me(a) ? a.value = e : null),
1617
+ header: d.value,
1618
+ "close-button": "",
1619
+ "dismiss-away": "",
1620
+ "max-width": 800
1621
+ }, {
1622
+ "side-sheet-footer": J(() => [
1623
+ y("div", fo, [
1624
+ x(I, {
1625
+ loading: i.value,
1626
+ label: r.value,
1627
+ onClick: C
1628
+ }, null, 8, ["loading", "label"]),
1629
+ x(I, {
1630
+ disabled: i.value,
1631
+ label: n(o)("common.close"),
1632
+ variant: "tertiary",
1633
+ onClick: k[2] || (k[2] = (e) => a.value = !1)
1634
+ }, null, 8, ["disabled", "label"])
1635
+ ])
1636
+ ]),
1637
+ default: J(() => [
1638
+ x(mo, {
1639
+ class: "w-full",
1640
+ ref_key: "hasValidationExpose",
1641
+ ref: u,
1642
+ modelValue: n($),
1643
+ "onUpdate:modelValue": k[0] || (k[0] = (e) => Me($) ? $.value = e : null),
1644
+ mode: c.mode,
1645
+ disabled: i.value,
1646
+ "onClick:submit": k[1] || (k[1] = (e) => w())
1647
+ }, null, 8, ["modelValue", "mode", "disabled"])
1648
+ ]),
1649
+ _: 1
1650
+ }, 8, ["model-value", "header"]);
1651
+ };
1652
+ }
1653
+ });
1654
+ function ke(m, s, l) {
1655
+ const t = [];
1656
+ for (const o of m)
1657
+ if (o.type === ge.enum.SKU)
1658
+ t.push({ ...o, recipeIds: [...s] });
1659
+ else if (o.type === ge.enum.SKU_GROUP)
1660
+ t.push({ ...o, isGroup: !0, recipeIds: [...s] });
1661
+ else if (o.type === ge.enum.RECIPE) {
1662
+ const a = l[o.id];
1663
+ a && !s.has(o.id) && t.push(
1664
+ ...ke(a.contains, /* @__PURE__ */ new Set([...s, o.id]), l)
1665
+ );
1666
+ }
1667
+ return t;
1668
+ }
1669
+ function yo(m, s) {
1670
+ return he.equal(m, s);
1671
+ }
1672
+ function Fe(m) {
1673
+ if (m == null) return null;
1674
+ const s = m.$and, l = m.$or;
1675
+ return Array.isArray(s) && s.length === 0 || Array.isArray(l) && l.length === 0 || Object.keys(m).length === 0 ? null : JSON.stringify(m);
1676
+ }
1677
+ function Ae(m) {
1678
+ const s = (m ?? []).map((l) => ({
1679
+ _id: l._id,
1680
+ trackingMeasurement: l.trackingMeasurement ?? null,
1681
+ priority: l.priority ?? null,
1682
+ default: l.default ?? null
1683
+ })).sort((l, t) => l._id.localeCompare(t._id));
1684
+ return JSON.stringify(s);
1685
+ }
1686
+ function Xe(m) {
1687
+ return m.measurement ? he.multiplyDecimal(m.amount, m.measurement.conversion) : m.amount;
1688
+ }
1689
+ function Pe(m, s) {
1690
+ var o, a;
1691
+ if (m.type !== s.type || m.id !== s.id || !yo(Xe(m), Xe(s))) return !1;
1692
+ const l = ((o = m.measurement) == null ? void 0 : o.id) ?? null, t = ((a = s.measurement) == null ? void 0 : a.id) ?? null;
1693
+ return !(l !== t || Fe(m.rules) !== Fe(s.rules) || Ae(m.alternatives) !== Ae(s.alternatives));
1694
+ }
1695
+ function Ze(m, s) {
1696
+ return m.type === s.type && m.id === s.id;
1697
+ }
1698
+ function bo(m, s) {
1699
+ const l = [];
1700
+ let t = [...m.contains];
1701
+ for (const a of s)
1702
+ switch (a.type) {
1703
+ case "remove-binding": {
1704
+ const $ = t.findIndex(
1705
+ (d) => d.type === a.target.type && d.id === a.target.id
1706
+ );
1707
+ $ === -1 ? l.push({ change: a, outcome: "ignored", reason: "Source binding not found in target" }) : (t = [...t.slice(0, $), ...t.slice($ + 1)], l.push({ change: a, outcome: "applied" }));
1708
+ break;
1709
+ }
1710
+ case "add-binding": {
1711
+ if (t.find((r) => Pe(r, a.binding))) {
1712
+ l.push({ change: a, outcome: "already-satisfied", reason: "Exact binding already present" });
1713
+ break;
1714
+ }
1715
+ if (t.find((r) => Ze(r, a.binding))) {
1716
+ l.push({ change: a, outcome: "blocked", reason: "A similar but non-exact binding already exists" });
1717
+ break;
1718
+ }
1719
+ if (m.version === "v2" && a.binding.type === "RECIPE") {
1720
+ l.push({ change: a, outcome: "blocked", reason: "Cannot add RECIPE binding to a V2 recipe" });
1721
+ break;
1722
+ }
1723
+ if (m.version !== "v2" && (a.binding.alternatives ?? []).length > 0) {
1724
+ l.push({ change: a, outcome: "blocked", reason: "Cannot add a binding with alternatives to a non-V2 recipe" });
1725
+ break;
1726
+ }
1727
+ t = [...t, a.binding], l.push({ change: a, outcome: "applied" });
1728
+ break;
1729
+ }
1730
+ case "replace-binding": {
1731
+ const $ = t.findIndex(
1732
+ (u) => u.type === a.from.type && u.id === a.from.id
1733
+ ), d = t.find((u) => Pe(u, a.to)), r = t.find((u, i) => i !== $ && Ze(u, a.to) && !Pe(u, a.to));
1734
+ if ($ === -1) {
1735
+ d ? l.push({ change: a, outcome: "already-satisfied", reason: "Target already has exact replacement" }) : l.push({ change: a, outcome: "ignored", reason: "Source binding not found in target" });
1736
+ break;
1737
+ }
1738
+ if (m.version === "v2" && a.to.type === "RECIPE") {
1739
+ l.push({ change: a, outcome: "blocked", reason: "Cannot add RECIPE binding to a V2 recipe" });
1740
+ break;
1741
+ }
1742
+ if (m.version !== "v2" && (a.to.alternatives ?? []).length > 0) {
1743
+ l.push({ change: a, outcome: "blocked", reason: "Cannot apply a binding with alternatives to a non-V2 recipe" });
1744
+ break;
1745
+ }
1746
+ if (r) {
1747
+ l.push({ change: a, outcome: "blocked", reason: "A similar but non-exact replacement binding already exists" });
1748
+ break;
1749
+ }
1750
+ d ? (t = [...t.slice(0, $), ...t.slice($ + 1)], l.push({ change: a, outcome: "applied", reason: "Source removed; replacement already present" })) : (t = [
1751
+ ...t.slice(0, $),
1752
+ a.to,
1753
+ ...t.slice($ + 1)
1754
+ ], l.push({ change: a, outcome: "applied" }));
1755
+ break;
1756
+ }
1757
+ case "update-binding-rule": {
1758
+ const $ = t.findIndex(
1759
+ (i) => i.type === a.target.type && i.id === a.target.id
1760
+ );
1761
+ if ($ === -1) {
1762
+ l.push({ change: a, outcome: "ignored", reason: "Binding not found in target" });
1763
+ break;
1764
+ }
1765
+ const d = t[$], r = d.rules ?? null, u = a.rule ?? null;
1766
+ if (Fe(r) === Fe(u)) {
1767
+ l.push({ change: a, outcome: "already-satisfied", reason: "Rule already matches" });
1768
+ break;
1769
+ }
1770
+ t = [
1771
+ ...t.slice(0, $),
1772
+ { ...d, rules: u },
1773
+ ...t.slice($ + 1)
1774
+ ], l.push({ change: a, outcome: "applied" });
1775
+ break;
1776
+ }
1777
+ case "update-alternatives": {
1778
+ if (m.version !== "v2") {
1779
+ l.push({ change: a, outcome: "blocked", reason: "Cannot update alternatives on a non-V2 recipe" });
1780
+ break;
1781
+ }
1782
+ const $ = t.findIndex(
1783
+ (i) => i.type === a.target.type && i.id === a.target.id
1784
+ );
1785
+ if ($ === -1) {
1786
+ l.push({ change: a, outcome: "ignored", reason: "Binding not found in target" });
1787
+ break;
1788
+ }
1789
+ const d = t[$], r = Ae(d.alternatives), u = Ae(a.alternatives);
1790
+ if (r === u) {
1791
+ l.push({ change: a, outcome: "already-satisfied", reason: "Alternatives already match" });
1792
+ break;
1793
+ }
1794
+ t = [
1795
+ ...t.slice(0, $),
1796
+ { ...d, alternatives: a.alternatives },
1797
+ ...t.slice($ + 1)
1798
+ ], l.push({ change: a, outcome: "applied" });
1799
+ break;
1800
+ }
1801
+ }
1802
+ return { projected: { ...m, contains: t }, results: l };
1803
+ }
1804
+ function et(m) {
1805
+ switch (m.type) {
1806
+ case "add-binding":
1807
+ return m.binding.id !== "";
1808
+ case "remove-binding":
1809
+ return m.target.id !== "";
1810
+ case "replace-binding":
1811
+ return m.from.id !== "" && m.to.id !== "";
1812
+ case "update-binding-rule":
1813
+ return m.target.id !== "";
1814
+ case "update-alternatives":
1815
+ return m.target.id !== "";
1816
+ }
1817
+ }
1818
+ function go(m) {
1819
+ if (m.length === 0) return "no-applicable-changes";
1820
+ let s = 0, l = 0, t = 0, o = 0;
1821
+ for (const a of m)
1822
+ a.outcome === "applied" ? s++ : a.outcome === "blocked" ? l++ : a.outcome === "ignored" ? t++ : a.outcome === "already-satisfied" && o++;
1823
+ return l > 0 && s === 0 ? "blocked" : o === m.length ? "already-satisfied" : s > 0 && (t > 0 || l > 0) ? "partially-ignored" : s > 0 ? "will-update" : "no-applicable-changes";
1824
+ }
1825
+ let _o = 0;
1826
+ function ko(m = null) {
1827
+ return {
1828
+ id: String(++_o),
1829
+ type: m,
1830
+ itemId: null,
1831
+ amountModel: be()
1832
+ };
1833
+ }
1834
+ function ut(m, s, l, t) {
1835
+ for (const o of m)
1836
+ if (o.type === "RECIPE") {
1837
+ if (o.id === s) return !0;
1838
+ if (!l.has(o.id)) {
1839
+ const a = t[o.id];
1840
+ if (a && ut(a.contains, s, /* @__PURE__ */ new Set([...l, o.id]), t))
1841
+ return !0;
1842
+ }
1843
+ }
1844
+ return !1;
1845
+ }
1846
+ const _e = ot("recipeBulkEditor", function() {
1847
+ const s = ne(), l = Le(), { t } = ie(), o = W(!1), a = W(1), $ = W(null), d = W(/* @__PURE__ */ new Set()), r = W([]), u = W({}), i = W(!1), f = W(/* @__PURE__ */ new Map()), v = W(""), C = W([]), w = F(() => {
1848
+ let O = s.recipes;
1849
+ const M = $.value;
1850
+ if (M != null && M.nameSearch) {
1851
+ const j = M.nameSearch.trim().toLowerCase();
1852
+ j && (O = O.filter((q) => q.name.toLowerCase().includes(j)));
1853
+ }
1854
+ if (M != null && M.filters && M.filters.length > 0) {
1855
+ const j = /* @__PURE__ */ new Map();
1856
+ for (const q of O)
1857
+ j.set(
1858
+ q._id,
1859
+ ke(q.contains, /* @__PURE__ */ new Set([q._id]), s.recipeById)
1860
+ );
1861
+ for (const q of M.filters)
1862
+ if (q.type === "ingredient") {
1863
+ const { itemId: oe, amount: X, measurementId: se } = q;
1864
+ O = O.filter((fe) => (j.get(fe._id) ?? []).some((ae) => {
1865
+ var ce;
1866
+ if (ae.type !== "SKU" || ae.id !== oe) return !1;
1867
+ if (ae.recipeIds.length === 1) {
1868
+ if (X != null) {
1869
+ const Te = ae.measurement ? he.multiplyDecimal(ae.amount, ae.measurement.conversion) : ae.amount;
1870
+ if (!he.equal(Te, X)) return !1;
1871
+ }
1872
+ if (se != null && (((ce = ae.measurement) == null ? void 0 : ce.id) ?? null) !== se)
1873
+ return !1;
1874
+ }
1875
+ return !0;
1876
+ }));
1877
+ } else if (q.type === "recipe") {
1878
+ const oe = q.itemId;
1879
+ O = O.filter(
1880
+ (X) => ut(X.contains, oe, /* @__PURE__ */ new Set([X._id]), s.recipeById)
1881
+ );
1882
+ }
1883
+ }
1884
+ return O;
1885
+ }), c = F(
1886
+ () => w.value.filter((O) => !d.value.has(O._id))
1887
+ ), k = F(() => c.value.length > 0), I = F(() => {
1888
+ const O = r.value.filter(et);
1889
+ if (O.length === 0) {
1890
+ const j = {};
1891
+ for (const q of c.value)
1892
+ j[q._id] = {
1893
+ recipeId: q._id,
1894
+ recipeName: q.name,
1895
+ original: q,
1896
+ projected: null,
1897
+ status: "no-applicable-changes",
1898
+ changes: [],
1899
+ counts: { applied: 0, ignored: 0, blocked: 0, satisfied: 0 }
1900
+ };
1901
+ return j;
1902
+ }
1903
+ const M = {};
1904
+ for (const j of c.value) {
1905
+ const q = JSON.parse(JSON.stringify(j)), { projected: oe, results: X } = bo(q, O), se = go(X);
1906
+ let fe = 0, xe = 0, ae = 0, ve = 0;
1907
+ for (const ce of X)
1908
+ ce.outcome === "applied" ? fe++ : ce.outcome === "ignored" ? xe++ : ce.outcome === "blocked" ? ae++ : ce.outcome === "already-satisfied" && ve++;
1909
+ M[j._id] = {
1910
+ recipeId: j._id,
1911
+ recipeName: j.name,
1912
+ original: q,
1913
+ projected: se === "will-update" || se === "partially-ignored" ? oe : null,
1914
+ status: se,
1915
+ changes: X,
1916
+ counts: { applied: fe, ignored: xe, blocked: ae, satisfied: ve }
1917
+ };
1918
+ }
1919
+ return M;
1920
+ }), _ = F(() => r.value.some(et) ? Object.values(I.value).some(
1921
+ (O) => O.status === "will-update" || O.status === "partially-ignored"
1922
+ ) : !1);
1923
+ function e() {
1924
+ p(), o.value = !0;
1925
+ }
1926
+ function S() {
1927
+ o.value = !1;
1928
+ }
1929
+ function p() {
1930
+ a.value = 1, $.value = null, d.value = /* @__PURE__ */ new Set(), r.value = [], u.value = {}, i.value = !1, f.value = /* @__PURE__ */ new Map(), v.value = "", C.value = [];
1931
+ }
1932
+ function h(O) {
1933
+ $.value = O;
1934
+ }
1935
+ function N(O) {
1936
+ const M = new Set(d.value);
1937
+ M.add(O), d.value = M;
1938
+ }
1939
+ function z() {
1940
+ d.value = /* @__PURE__ */ new Set();
1941
+ }
1942
+ function b(O) {
1943
+ r.value = [...r.value, O];
1944
+ }
1945
+ function B(O, M) {
1946
+ const j = [...r.value];
1947
+ j[O] = M, r.value = j;
1948
+ }
1949
+ function R(O) {
1950
+ r.value = r.value.filter((M, j) => j !== O);
1951
+ }
1952
+ function A(O, M) {
1953
+ const j = [...r.value], [q] = j.splice(O, 1);
1954
+ j.splice(M, 0, q), r.value = j;
1955
+ }
1956
+ function P() {
1957
+ u.value = { ...I.value }, a.value = 3;
1958
+ }
1959
+ function K() {
1960
+ u.value = {}, a.value = 2;
1961
+ }
1962
+ function H() {
1963
+ return Object.values(u.value).filter(
1964
+ (O) => (O.status === "will-update" || O.status === "partially-ignored") && O.projected != null
1965
+ ).map((O) => O.projected);
1966
+ }
1967
+ async function ee() {
1968
+ if (!i.value) {
1969
+ i.value = !0, f.value = /* @__PURE__ */ new Map();
1970
+ try {
1971
+ const O = H(), M = await s.importRecipes({
1972
+ create: [],
1973
+ update: O
1974
+ }), j = (M == null ? void 0 : M.errors) ?? [];
1975
+ if (j.length > 0) {
1976
+ const q = /* @__PURE__ */ new Map();
1977
+ for (const { data: oe, error: X } of j) {
1978
+ const se = typeof X == "string" ? X : (X == null ? void 0 : X.message) ?? t("inventory.recipe.bulkEditor.step3.unknownError");
1979
+ q.set(oe._id, se);
1980
+ }
1981
+ f.value = q, l.open({
1982
+ title: t("inventory.recipe.bulkEditor.step3.partialErrorTitle"),
1983
+ message: t("inventory.recipe.bulkEditor.step3.partialErrorMessage", {
1984
+ count: j.length
1985
+ }),
1986
+ type: "warning"
1987
+ });
1988
+ } else
1989
+ l.open({
1990
+ title: t("inventory.recipe.bulkEditor.step3.successTitle"),
1991
+ message: t("inventory.recipe.bulkEditor.step3.successMessage", {
1992
+ count: O.length
1993
+ }),
1994
+ type: "success"
1995
+ }), o.value = !1, p();
1996
+ } catch (O) {
1997
+ l.open({
1998
+ title: t("inventory.recipe.bulkEditor.step3.errorTitle"),
1999
+ message: t("inventory.recipe.bulkEditor.step3.errorMessage"),
2000
+ type: "error"
2001
+ }), console.error("confirmAndApply failed", O);
2002
+ } finally {
2003
+ i.value = !1;
2004
+ }
2005
+ }
2006
+ }
2007
+ return {
2008
+ // state
2009
+ show: o,
2010
+ currentStep: a,
2011
+ query: $,
2012
+ excludedRecipeIds: d,
2013
+ modifications: r,
2014
+ entries: u,
2015
+ isSaving: i,
2016
+ applyErrors: f,
2017
+ nameSearch: v,
2018
+ filterRows: C,
2019
+ // computed
2020
+ matchedRecipes: w,
2021
+ selectedRecipes: c,
2022
+ livePreviewEntries: I,
2023
+ canGoToStep2: k,
2024
+ canGoToStep3: _,
2025
+ // actions
2026
+ openDialog: e,
2027
+ closeDialog: S,
2028
+ reset: p,
2029
+ updateQuery: h,
2030
+ removeRecipe: N,
2031
+ restoreAllRecipes: z,
2032
+ addModification: b,
2033
+ updateModification: B,
2034
+ removeModification: R,
2035
+ reorderModification: A,
2036
+ goToStep3: P,
2037
+ backToStep2: K,
2038
+ buildPayload: H,
2039
+ confirmAndApply: ee
2040
+ };
2041
+ }), ho = { class: "flex flex-col h-full" }, xo = { class: "px-16 pt-16 pb-8 shrink-0 flex items-center justify-between" }, wo = { class: "fm-typo-en-heading-sm-700 text-fm-color-typo-primary" }, $o = { class: "px-16 pt-12 pb-16 border-b border-fm-color-border-default bg-fm-color-surface-default flex flex-col gap-12 shrink-0" }, Io = {
2042
+ key: 0,
2043
+ class: "flex flex-wrap items-center gap-8"
2044
+ }, Eo = {
2045
+ type: "button",
2046
+ class: "inline-flex items-center gap-4 h-[30px] pl-8 pr-6 rounded-l-md border border-r-0 border-fm-color-border-default bg-fm-color-surface-secondary hover:bg-fm-color-surface-hover cursor-pointer select-none transition-colors"
2047
+ }, Vo = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-primary" }, So = { class: "flex flex-col gap-8 p-12 min-w-[260px]" }, Co = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-secondary" }, Bo = {
2048
+ key: 0,
2049
+ class: "flex flex-col gap-4"
2050
+ }, Ro = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, Fo = { class: "text-fm-color-typo-placeholder ml-4" }, Ao = ["title", "onClick"], To = { class: "flex-1 overflow-y-auto" }, Uo = {
2051
+ key: 0,
2052
+ class: "flex flex-col items-center justify-center h-full gap-8 px-24 text-center"
2053
+ }, Po = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Mo = {
2054
+ key: 1,
2055
+ class: "divide-y divide-fm-color-border-default"
2056
+ }, Do = { class: "flex-1 min-w-0" }, Go = { class: "fm-typo-en-body-md-600 text-fm-color-typo-primary truncate" }, No = {
2057
+ key: 0,
2058
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary mt-1 whitespace-normal break-words"
2059
+ }, zo = { class: "flex items-center gap-4 mt-2" }, Oo = /* @__PURE__ */ le({
2060
+ __name: "RecipeBulkEditorStep1",
2061
+ setup(m) {
2062
+ const { t: s } = ie(), l = ne(), t = _e(), o = F({
2063
+ get: () => t.nameSearch,
2064
+ set: (_) => {
2065
+ t.nameSearch = _;
2066
+ }
2067
+ }), a = F(() => t.filterRows), $ = W({});
2068
+ function d(_) {
2069
+ return $.value[_] ?? !1;
2070
+ }
2071
+ function r(_, e) {
2072
+ $.value = { ...$.value, [_]: e };
2073
+ }
2074
+ const u = F(
2075
+ () => l.skus.map((_) => ({
2076
+ label: _.name,
2077
+ sublabel: _.code,
2078
+ value: _._id
2079
+ }))
2080
+ ), i = F(
2081
+ () => l.recipes.map((_) => ({
2082
+ label: _.name,
2083
+ value: _._id
2084
+ }))
2085
+ );
2086
+ function f(_) {
2087
+ return _.type !== "ingredient" || !_.itemId ? null : l.skuById[_.itemId] ?? null;
2088
+ }
2089
+ function v(_) {
2090
+ var e;
2091
+ if (!_.type) return s("inventory.recipe.bulkEditor.step1.filter");
2092
+ if (_.type === "ingredient") {
2093
+ if (!_.itemId) return s("inventory.recipe.bulkEditor.step1.filterTypeIngredient");
2094
+ const S = l.skuById[_.itemId];
2095
+ if (!S) return s("inventory.recipe.bulkEditor.step1.filterTypeIngredient");
2096
+ const { amount: p, measurement: h } = _.amountModel;
2097
+ if (!(p != null && p.amount > 0)) return S.name;
2098
+ const z = (h == null ? void 0 : h.abbrev) ?? ((e = S.unit) == null ? void 0 : e.abbrev) ?? "", b = Z(p);
2099
+ return `${S.name} (${b}${z})`;
2100
+ }
2101
+ if (_.type === "recipe") {
2102
+ if (!_.itemId) return s("inventory.recipe.bulkEditor.step1.filterTypeRecipe");
2103
+ const S = l.recipeById[_.itemId];
2104
+ return S ? S.name : s("inventory.recipe.bulkEditor.step1.filterTypeRecipe");
2105
+ }
2106
+ return "";
2107
+ }
2108
+ function C(_) {
2109
+ const e = ko(_);
2110
+ t.filterRows.push(e), r(e.id, !0);
2111
+ }
2112
+ function w(_) {
2113
+ t.filterRows = t.filterRows.filter((S) => S.id !== _);
2114
+ const e = { ...$.value };
2115
+ delete e[_], $.value = e;
2116
+ }
2117
+ function c(_) {
2118
+ _.amountModel = be(), r(_.id, !0);
2119
+ }
2120
+ ue(
2121
+ [o, a],
2122
+ () => {
2123
+ const _ = [];
2124
+ for (const p of a.value)
2125
+ if (!(!p.type || !p.itemId))
2126
+ if (p.type === "ingredient") {
2127
+ const h = f(p), { amount: N, measurement: z } = p.amountModel, b = N != null && N.amount > 0;
2128
+ let B, R;
2129
+ h && b && (B = z ? he.multiplyDecimal(N, z.conversion) : N, R = (z == null ? void 0 : z.id) ?? null), _.push({
2130
+ id: p.id,
2131
+ type: "ingredient",
2132
+ itemId: p.itemId,
2133
+ amount: B ?? null,
2134
+ measurementId: R
2135
+ });
2136
+ } else p.type === "recipe" && _.push({
2137
+ id: p.id,
2138
+ type: "recipe",
2139
+ itemId: p.itemId
2140
+ });
2141
+ t.updateQuery({
2142
+ nameSearch: o.value,
2143
+ filters: _
2144
+ });
2145
+ const e = o.value.trim().length > 0, S = _.length > 0;
2146
+ !e && !S && t.restoreAllRecipes();
2147
+ },
2148
+ { deep: !0, immediate: !0 }
2149
+ );
2150
+ function k(_) {
2151
+ var h, N, z, b;
2152
+ if (_.isGroup) {
2153
+ const B = l.skuGroupById[_.id];
2154
+ if (!B) return null;
2155
+ const R = `x${Z(_.amount)}`;
2156
+ return _.recipeIds.slice(1).length ? `(${((h = l.recipeById[_.recipeIds.at(-1) ?? ""]) == null ? void 0 : h.name) ?? ""}) ${B.name} (${R})` : `${B.name} (${R})`;
2157
+ }
2158
+ const e = l.skuById[_.id];
2159
+ if (!e) return null;
2160
+ const S = ((N = _.measurement) == null ? void 0 : N.abbrev) ?? ((z = e.unit) == null ? void 0 : z.abbrev) ?? "", p = `${Z(_.amount)}${S}`;
2161
+ return _.recipeIds.slice(1).length ? `(${((b = l.recipeById[_.recipeIds.at(-1) ?? ""]) == null ? void 0 : b.name) ?? ""}) ${e.name} (${p})` : `${e.name} (${p})`;
2162
+ }
2163
+ function I(_) {
2164
+ return ke(_.contains, /* @__PURE__ */ new Set([_._id]), l.recipeById).map(k).filter((e) => e !== null).join(", ");
2165
+ }
2166
+ return (_, e) => {
2167
+ const S = G("FmButton"), p = G("FmSearch"), h = G("FmSelect"), N = G("FmPopover"), z = G("FmIcon"), b = G("FmMenuItem"), B = G("FmMenu"), R = G("FmChip");
2168
+ return g(), V("div", ho, [
2169
+ y("div", xo, [
2170
+ y("span", wo, U(n(s)("inventory.recipe.bulkEditor.step1.selectedCount", {
2171
+ count: n(t).selectedRecipes.length
2172
+ })), 1),
2173
+ n(t).excludedRecipeIds.size > 0 ? (g(), Y(S, {
2174
+ key: 0,
2175
+ label: n(s)("inventory.recipe.bulkEditor.step1.restoreAll"),
2176
+ variant: "tertiary",
2177
+ size: "md",
2178
+ onClick: e[0] || (e[0] = (A) => n(t).restoreAllRecipes())
2179
+ }, null, 8, ["label"])) : T("", !0)
2180
+ ]),
2181
+ y("div", $o, [
2182
+ x(p, {
2183
+ modelValue: o.value,
2184
+ "onUpdate:modelValue": e[1] || (e[1] = (A) => o.value = A),
2185
+ placeholder: n(s)("inventory.recipe.bulkEditor.query.nameSearchPlaceholder")
2186
+ }, null, 8, ["modelValue", "placeholder"]),
2187
+ a.value.length > 0 ? (g(), V("div", Io, [
2188
+ (g(!0), V(Q, null, me(a.value, (A) => (g(), V("div", {
2189
+ key: A.id,
2190
+ class: "flex items-center"
2191
+ }, [
2192
+ x(N, {
2193
+ "show-popover": d(A.id),
2194
+ "exclude-el-from-click-outside": ["fm-menu"],
2195
+ placement: "bottom-start",
2196
+ onPopoverChanged: (P) => r(A.id, P)
2197
+ }, {
2198
+ "popover-button": J(() => [
2199
+ y("button", Eo, [
2200
+ y("span", Vo, U(v(A)), 1)
2201
+ ])
2202
+ ]),
2203
+ default: J(() => [
2204
+ y("div", So, [
2205
+ y("p", Co, U(A.type === "ingredient" ? n(s)("inventory.recipe.bulkEditor.step1.filterTypeIngredient") : n(s)("inventory.recipe.bulkEditor.step1.filterTypeRecipe")), 1),
2206
+ A.type === "ingredient" ? (g(), V(Q, { key: 0 }, [
2207
+ x(h, {
2208
+ modelValue: A.itemId,
2209
+ "onUpdate:modelValue": [(P) => A.itemId = P, (P) => c(A)],
2210
+ items: u.value,
2211
+ placeholder: n(s)("inventory.recipe.bulkEditor.step1.selectIngredient"),
2212
+ clearable: ""
2213
+ }, {
2214
+ "menu-wrapper": J((P) => [
2215
+ x(Be, Ie({ ref_for: !0 }, P, {
2216
+ items: u.value,
2217
+ "model-value": A.itemId
2218
+ }), null, 16, ["items", "model-value"])
2219
+ ]),
2220
+ _: 2
2221
+ }, 1032, ["modelValue", "onUpdate:modelValue", "items", "placeholder"]),
2222
+ f(A) ? (g(), V("div", Bo, [
2223
+ y("span", Ro, [
2224
+ mt(U(n(s)("inventory.recipe.bulkEditor.step1.amountLabel")) + " ", 1),
2225
+ y("span", Fo, U(n(s)("inventory.recipe.bulkEditor.step1.amountOptional")), 1)
2226
+ ]),
2227
+ x(Ce, {
2228
+ modelValue: A.amountModel,
2229
+ "onUpdate:modelValue": (P) => A.amountModel = P,
2230
+ unit: f(A).unit,
2231
+ placeholder: n(s)("inventory.recipe.bulkEditor.step1.amountPlaceholder"),
2232
+ "convert-amount-on-change-unit": ""
2233
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "unit", "placeholder"])
2234
+ ])) : T("", !0)
2235
+ ], 64)) : A.type === "recipe" ? (g(), Y(h, {
2236
+ key: 1,
2237
+ modelValue: A.itemId,
2238
+ "onUpdate:modelValue": [(P) => A.itemId = P, (P) => c(A)],
2239
+ items: i.value,
2240
+ placeholder: n(s)("inventory.recipe.bulkEditor.step1.selectRecipe"),
2241
+ clearable: ""
2242
+ }, {
2243
+ "menu-wrapper": J((P) => [
2244
+ x(Be, Ie({ ref_for: !0 }, P, {
2245
+ items: i.value,
2246
+ "model-value": A.itemId
2247
+ }), null, 16, ["items", "model-value"])
2248
+ ]),
2249
+ _: 2
2250
+ }, 1032, ["modelValue", "onUpdate:modelValue", "items", "placeholder"])) : T("", !0)
2251
+ ])
2252
+ ]),
2253
+ _: 2
2254
+ }, 1032, ["show-popover", "onPopoverChanged"]),
2255
+ y("button", {
2256
+ type: "button",
2257
+ class: "inline-flex items-center justify-center h-[30px] w-[26px] rounded-r-md border border-l-0 border-fm-color-border-default bg-fm-color-surface-secondary hover:bg-fm-color-surface-hover text-fm-color-typo-secondary hover:text-fm-color-typo-primary cursor-pointer transition-colors",
2258
+ title: n(s)("inventory.recipe.bulkEditor.step1.removeFilter"),
2259
+ onClick: (P) => w(A.id)
2260
+ }, [
2261
+ x(z, {
2262
+ name: "close",
2263
+ size: "sm"
2264
+ })
2265
+ ], 8, Ao)
2266
+ ]))), 128))
2267
+ ])) : T("", !0),
2268
+ x(B, {
2269
+ "close-on-click": !0,
2270
+ placement: "bottom-start"
2271
+ }, {
2272
+ "menu-button": J(() => [
2273
+ x(S, {
2274
+ label: n(s)("inventory.recipe.bulkEditor.step1.filter"),
2275
+ variant: "secondary",
2276
+ size: "md",
2277
+ "prepend-icon": "add",
2278
+ class: "self-start"
2279
+ }, null, 8, ["label"])
2280
+ ]),
2281
+ default: J(() => [
2282
+ x(b, {
2283
+ label: n(s)("inventory.recipe.bulkEditor.step1.filterTypeIngredient"),
2284
+ icon: "inventory_2",
2285
+ onClick: e[2] || (e[2] = (A) => C("ingredient"))
2286
+ }, null, 8, ["label"]),
2287
+ x(b, {
2288
+ label: n(s)("inventory.recipe.bulkEditor.step1.filterTypeRecipe"),
2289
+ icon: "restaurant_menu",
2290
+ onClick: e[3] || (e[3] = (A) => C("recipe"))
2291
+ }, null, 8, ["label"])
2292
+ ]),
2293
+ _: 1
2294
+ })
2295
+ ]),
2296
+ y("div", To, [
2297
+ n(t).selectedRecipes.length === 0 ? (g(), V("div", Uo, [
2298
+ x(z, {
2299
+ name: "search_off",
2300
+ size: "lg",
2301
+ class: "text-fm-color-typo-placeholder"
2302
+ }),
2303
+ y("p", Po, U(n(s)("inventory.recipe.bulkEditor.query.noResults")), 1)
2304
+ ])) : (g(), V("div", Mo, [
2305
+ (g(!0), V(Q, null, me(n(t).selectedRecipes, (A) => (g(), V("div", {
2306
+ key: A._id,
2307
+ class: "flex items-center gap-12 px-16 py-12 hover:bg-fm-color-surface-hover transition-colors"
2308
+ }, [
2309
+ y("div", Do, [
2310
+ y("div", Go, U(A.name), 1),
2311
+ A.contains.length > 0 ? (g(), V("div", No, U(I(A)), 1)) : T("", !0),
2312
+ y("div", zo, [
2313
+ A.version === "v2" ? (g(), Y(R, {
2314
+ key: 0,
2315
+ size: "sm",
2316
+ label: "V2",
2317
+ variant: "info"
2318
+ })) : T("", !0)
2319
+ ])
2320
+ ]),
2321
+ x(S, {
2322
+ variant: "tertiary",
2323
+ icon: "do_not_disturb_on",
2324
+ title: n(s)("inventory.recipe.bulkEditor.step1.removeRecipeTooltip"),
2325
+ onClick: (P) => n(t).removeRecipe(A._id)
2326
+ }, null, 8, ["title", "onClick"])
2327
+ ]))), 128))
2328
+ ]))
2329
+ ])
2330
+ ]);
2331
+ };
2332
+ }
2333
+ }), jo = { class: "flex flex-col gap-0 rounded-lg border border-fm-color-border-default bg-fm-color-surface-default overflow-hidden" }, Lo = { class: "flex items-start gap-12 px-16 py-12" }, Ko = { class: "flex-1" }, qo = { class: "flex-1" }, Wo = {
2334
+ key: 0,
2335
+ class: "border-t border-fm-color-border-default px-16 py-10 flex items-center gap-10"
2336
+ }, Yo = {
2337
+ key: 1,
2338
+ class: "border-t border-fm-color-border-default px-16 py-10 flex items-start gap-8 bg-fm-color-surface-warning"
2339
+ }, Jo = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-warning" }, Ho = {
2340
+ key: 2,
2341
+ class: "border-t border-fm-color-border-default px-16 py-12 flex flex-col gap-12"
2342
+ }, Qo = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-secondary -mb-4" }, Xo = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, Zo = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, ei = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-warning" }, ti = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary -mt-8" }, ni = { class: "fm-typo-en-body-sm-600 text-fm-color-typo-secondary -mb-4" }, oi = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, ii = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, li = /* @__PURE__ */ le({
2343
+ __name: "ModificationCard",
2344
+ props: {
2345
+ modelValue: {},
2346
+ livePreviewEntries: {}
2347
+ },
2348
+ emits: ["update:modelValue"],
2349
+ setup(m, { emit: s }) {
2350
+ const l = m, t = s, { t: o } = ie(), a = ne(), $ = We();
2351
+ function d(E) {
2352
+ const D = E.type === "replace-binding" ? E.from.type : E.type === "remove-binding" || E.type === "update-binding-rule" || E.type === "update-alternatives" ? E.target.type : E.type === "add-binding" ? E.binding.type : null;
2353
+ return D ? D === "RECIPE" ? "recipe" : "ingredient" : null;
2354
+ }
2355
+ function r(E) {
2356
+ return E.type === "update-alternatives" ? !0 : E.type === "add-binding" ? (E.binding.alternatives ?? []).length > 0 : E.type === "replace-binding" ? (E.to.alternatives ?? []).length > 0 : !1;
2357
+ }
2358
+ function u(E) {
2359
+ switch (E.type) {
2360
+ case "add-binding":
2361
+ return "link";
2362
+ case "replace-binding":
2363
+ return E.from.id === E.to.id ? "update" : null;
2364
+ case "remove-binding":
2365
+ return "remove";
2366
+ case "update-binding-rule":
2367
+ return null;
2368
+ case "update-alternatives":
2369
+ return "alts";
2370
+ }
2371
+ }
2372
+ function i(E) {
2373
+ return E.type === "replace-binding" ? E.from.id || null : (E.type === "remove-binding" || E.type === "update-binding-rule" || E.type === "update-alternatives") && E.target.id || null;
2374
+ }
2375
+ function f(E) {
2376
+ return E.type === "add-binding" && E.binding.id || null;
2377
+ }
2378
+ function v(E) {
2379
+ const D = E.type === "replace-binding" ? E.to : E.type === "add-binding" ? E.binding : null;
2380
+ return D ? { amount: D.amount, measurement: D.measurement ?? null } : be();
2381
+ }
2382
+ function C(E) {
2383
+ return E.type === "replace-binding" ? E.to.rules ?? null : E.type === "add-binding" ? E.binding.rules ?? null : null;
2384
+ }
2385
+ function w(E) {
2386
+ return E.type === "update-alternatives" ? E.alternatives ?? [] : E.type === "add-binding" ? E.binding.alternatives ?? [] : [];
2387
+ }
2388
+ const c = W(d(l.modelValue)), k = W(u(l.modelValue)), I = W(r(l.modelValue)), _ = W(i(l.modelValue)), e = W(f(l.modelValue)), S = W(v(l.modelValue)), p = W(C(l.modelValue)), h = W(w(l.modelValue)), N = W(
2389
+ (() => {
2390
+ const E = v(l.modelValue);
2391
+ return E.amount ? Z(E.amount) : "";
2392
+ })()
2393
+ );
2394
+ let z = null;
2395
+ function b(E) {
2396
+ N.value = E, z && clearTimeout(z), z = setTimeout(() => {
2397
+ const D = +E;
2398
+ S.value = {
2399
+ amount: E.length > 0 && isFinite(D) ? Ke(D) : { amount: 0, precision: 0 },
2400
+ measurement: null
2401
+ };
2402
+ }, 300);
2403
+ }
2404
+ ue(c, () => {
2405
+ k.value = null, I.value = !1, _.value = null, e.value = null, S.value = be(), p.value = null, h.value = [], N.value = "";
2406
+ }), ue(k, () => {
2407
+ _.value = null, e.value = null, S.value = be(), p.value = null, h.value = [], N.value = "";
2408
+ }), ue(I, (E) => {
2409
+ E || (h.value = [], k.value === "alts" && (k.value = null));
2410
+ });
2411
+ const B = F(() => [
2412
+ { label: o("inventory.recipe.bulkEditor.step2.fieldIngredient"), value: "ingredient" },
2413
+ { label: o("inventory.recipe.bulkEditor.step2.fieldRecipe"), value: "recipe" }
2414
+ ]), R = F(() => {
2415
+ const E = [
2416
+ { label: o("inventory.recipe.bulkEditor.step2.actionLink"), value: "link" },
2417
+ { label: o("inventory.recipe.bulkEditor.step2.actionUpdate"), value: "update" },
2418
+ { label: o("inventory.recipe.bulkEditor.step2.actionRemove"), value: "remove" }
2419
+ ];
2420
+ return c.value === "ingredient" && I.value && $.enableRecipeV2 && E.push({ label: o("inventory.recipe.bulkEditor.step2.actionAlts"), value: "alts" }), E;
2421
+ }), A = F(() => c.value !== null && k.value !== null), P = F(
2422
+ () => k.value === "update" || k.value === "remove" || k.value === "alts"
2423
+ ), K = F(
2424
+ () => k.value === "link"
2425
+ ), H = F(
2426
+ () => k.value === "update" && _.value !== null
2427
+ ), ee = F(
2428
+ () => c.value === "ingredient" && I.value && $.enableRecipeV2
2429
+ ), O = F(
2430
+ () => a.skus.map((E) => ({ label: E.name, sublabel: E.code, value: E._id }))
2431
+ ), M = F(
2432
+ () => a.recipes.map((E) => ({ label: E.name, value: E._id }))
2433
+ ), j = F(() => c.value === "recipe" ? M.value : O.value), q = F(() => c.value === "recipe" ? M.value : O.value), oe = F(() => c.value !== "ingredient" || !e.value ? null : a.skuById[e.value] ?? null), X = F(() => c.value !== "ingredient" || !_.value ? null : a.skuById[_.value] ?? null), se = F(() => {
2434
+ const E = _.value ?? e.value;
2435
+ return E ? [E] : [];
2436
+ }), fe = F(() => ee.value ? Object.values(l.livePreviewEntries).filter(
2437
+ (E) => E.original.version !== "v2"
2438
+ ).length : 0), xe = F(() => Object.values(l.livePreviewEntries).length);
2439
+ ue(
2440
+ () => [k.value, _.value],
2441
+ ([E, D], [te, pe]) => {
2442
+ if (E !== "alts" || D === pe) return;
2443
+ if (!D) {
2444
+ h.value = [];
2445
+ return;
2446
+ }
2447
+ const we = Object.values(l.livePreviewEntries).find(
2448
+ (L) => L.original.version === "v2" && L.original.contains.some(($e) => $e.type === "SKU" && $e.id === D)
2449
+ );
2450
+ if (we) {
2451
+ const L = we.original.contains.find(($e) => $e.type === "SKU" && $e.id === D);
2452
+ h.value = L != null && L.alternatives ? [...L.alternatives] : [];
2453
+ } else
2454
+ h.value = [];
2455
+ }
2456
+ );
2457
+ const ae = F(() => k.value !== "alts" || !_.value ? 0 : Object.values(l.livePreviewEntries).filter(
2458
+ (E) => E.original.version === "v2" && E.original.contains.some((D) => D.type === "SKU" && D.id === _.value)
2459
+ ).length);
2460
+ function ve() {
2461
+ return c.value === "recipe" ? "RECIPE" : "SKU";
2462
+ }
2463
+ function ce() {
2464
+ const E = ve(), D = be().amount, te = {
2465
+ type: E,
2466
+ id: "",
2467
+ amount: D,
2468
+ measurement: null,
2469
+ rules: null,
2470
+ alternatives: []
2471
+ };
2472
+ switch (k.value) {
2473
+ case "update":
2474
+ return { type: "replace-binding", from: { type: E, id: "" }, to: te };
2475
+ case "remove":
2476
+ return { type: "remove-binding", target: { type: E, id: "" } };
2477
+ case "alts":
2478
+ return { type: "update-alternatives", target: { type: E, id: "" }, alternatives: [] };
2479
+ case "link":
2480
+ default:
2481
+ return { type: "add-binding", binding: te };
2482
+ }
2483
+ }
2484
+ function Te() {
2485
+ return _.value ? { type: ve(), id: _.value } : null;
2486
+ }
2487
+ function Ye(E = !1) {
2488
+ const D = E ? _.value : e.value;
2489
+ if (!D) return null;
2490
+ const { amount: te, measurement: pe } = S.value, Ee = pe ? he.multiplyDecimal(te, pe.conversion) : te;
2491
+ return {
2492
+ type: ve(),
2493
+ id: D,
2494
+ amount: Ee,
2495
+ measurement: pe ?? null,
2496
+ rules: c.value === "recipe" ? p.value ?? null : null,
2497
+ alternatives: ee.value ? h.value : []
2498
+ };
2499
+ }
2500
+ function ct() {
2501
+ if (!c.value) return;
2502
+ if (!k.value) {
2503
+ t("update:modelValue", ce());
2504
+ return;
2505
+ }
2506
+ const E = Te(), D = Ye(!1);
2507
+ let te = null;
2508
+ switch (k.value) {
2509
+ case "link":
2510
+ D && (te = { type: "add-binding", binding: D });
2511
+ break;
2512
+ case "update": {
2513
+ const pe = Ye(!0);
2514
+ E && pe && (te = { type: "replace-binding", from: E, to: pe });
2515
+ break;
2516
+ }
2517
+ case "remove":
2518
+ E && (te = { type: "remove-binding", target: E });
2519
+ break;
2520
+ case "alts":
2521
+ E && (te = { type: "update-alternatives", target: E, alternatives: h.value });
2522
+ break;
2523
+ }
2524
+ t("update:modelValue", te ?? ce());
2525
+ }
2526
+ return ue(
2527
+ [c, k, I, _, e, S, p, h],
2528
+ () => ct(),
2529
+ { deep: !0 }
2530
+ ), (E, D) => {
2531
+ const te = G("FmSelect"), pe = G("FmSwitch"), Ee = G("FmIcon"), we = G("FmTextField");
2532
+ return g(), V("div", jo, [
2533
+ y("div", Lo, [
2534
+ y("div", Ko, [
2535
+ x(te, {
2536
+ modelValue: c.value,
2537
+ "onUpdate:modelValue": D[0] || (D[0] = (L) => c.value = L),
2538
+ items: B.value,
2539
+ label: n(o)("inventory.recipe.bulkEditor.step2.sectionField"),
2540
+ placeholder: n(o)("inventory.recipe.bulkEditor.step2.sectionField")
2541
+ }, null, 8, ["modelValue", "items", "label", "placeholder"])
2542
+ ]),
2543
+ y("div", qo, [
2544
+ x(te, {
2545
+ modelValue: k.value,
2546
+ "onUpdate:modelValue": D[1] || (D[1] = (L) => k.value = L),
2547
+ items: R.value,
2548
+ label: n(o)("inventory.recipe.bulkEditor.step2.sectionAction"),
2549
+ placeholder: n(o)("inventory.recipe.bulkEditor.step2.sectionAction")
2550
+ }, null, 8, ["modelValue", "items", "label", "placeholder"])
2551
+ ])
2552
+ ]),
2553
+ c.value === "ingredient" && n($).enableRecipeV2 ? (g(), V("div", Wo, [
2554
+ x(pe, {
2555
+ modelValue: I.value,
2556
+ "onUpdate:modelValue": D[2] || (D[2] = (L) => I.value = L),
2557
+ label: n(o)("inventory.recipe.bulkEditor.step2.includeAlternativesToggle")
2558
+ }, null, 8, ["modelValue", "label"])
2559
+ ])) : T("", !0),
2560
+ ee.value && fe.value > 0 ? (g(), V("div", Yo, [
2561
+ x(Ee, {
2562
+ name: "warning",
2563
+ size: "sm",
2564
+ class: "text-fm-color-typo-warning mt-1 shrink-0"
2565
+ }),
2566
+ y("p", Jo, U(n(o)("inventory.recipe.bulkEditor.step2.v1AlternativesWarning", {
2567
+ v1Count: fe.value,
2568
+ total: xe.value
2569
+ })), 1)
2570
+ ])) : T("", !0),
2571
+ A.value ? (g(), V("div", Ho, [
2572
+ P.value ? (g(), V(Q, { key: 0 }, [
2573
+ y("p", Qo, U(n(o)("inventory.recipe.bulkEditor.addModification.targetLabel")), 1),
2574
+ x(te, {
2575
+ modelValue: _.value,
2576
+ "onUpdate:modelValue": D[3] || (D[3] = (L) => _.value = L),
2577
+ items: j.value,
2578
+ placeholder: c.value === "recipe" ? n(o)("inventory.recipe.bulkEditor.addModification.recipePlaceholder") : n(o)("inventory.recipe.bulkEditor.addModification.skuPlaceholder"),
2579
+ clearable: ""
2580
+ }, {
2581
+ "menu-wrapper": J((L) => [
2582
+ x(Be, Ie(L, {
2583
+ items: j.value,
2584
+ "model-value": _.value
2585
+ }), null, 16, ["items", "model-value"])
2586
+ ]),
2587
+ _: 1
2588
+ }, 8, ["modelValue", "items", "placeholder"]),
2589
+ H.value ? (g(), V(Q, { key: 0 }, [
2590
+ c.value === "ingredient" && X.value ? (g(), Y(Ce, {
2591
+ key: 0,
2592
+ modelValue: S.value,
2593
+ "onUpdate:modelValue": D[4] || (D[4] = (L) => S.value = L),
2594
+ unit: X.value.unit,
2595
+ placeholder: n(o)("inventory.recipe.bulkEditor.query.amountPlaceholder"),
2596
+ "convert-amount-on-change-unit": ""
2597
+ }, null, 8, ["modelValue", "unit", "placeholder"])) : c.value === "recipe" ? (g(), Y(we, {
2598
+ key: 1,
2599
+ "model-value": N.value,
2600
+ label: n(o)("inventory.recipe.bulkEditor.addModification.amountLabel"),
2601
+ type: "number",
2602
+ "onUpdate:modelValue": D[5] || (D[5] = (L) => b(L))
2603
+ }, null, 8, ["model-value", "label"])) : T("", !0),
2604
+ c.value === "recipe" ? (g(), V(Q, { key: 2 }, [
2605
+ y("p", Xo, U(n(o)("inventory.recipe.bulkEditor.addModification.optionalRuleLabel")), 1),
2606
+ x(Re, {
2607
+ modelValue: p.value,
2608
+ "onUpdate:modelValue": D[6] || (D[6] = (L) => p.value = L)
2609
+ }, null, 8, ["modelValue"])
2610
+ ], 64)) : T("", !0),
2611
+ ee.value ? (g(), V(Q, { key: 3 }, [
2612
+ y("p", Zo, U(n(o)("inventory.recipe.bulkEditor.addModification.optionalAlternativesLabel")), 1),
2613
+ x(Se, {
2614
+ modelValue: h.value,
2615
+ "onUpdate:modelValue": D[7] || (D[7] = (L) => h.value = L),
2616
+ "filter-ingredient-ids": se.value
2617
+ }, null, 8, ["modelValue", "filter-ingredient-ids"])
2618
+ ], 64)) : T("", !0)
2619
+ ], 64)) : T("", !0),
2620
+ k.value === "alts" && _.value ? (g(), V(Q, { key: 1 }, [
2621
+ y("p", ei, U(ae.value > 0 ? n(o)("inventory.recipe.bulkEditor.addModification.altsOverwriteWarning", { count: ae.value }) : n(o)("inventory.recipe.bulkEditor.addModification.altsNotFoundWarning")), 1),
2622
+ y("p", ti, U(n(o)("inventory.recipe.bulkEditor.addModification.altsClearNote")), 1),
2623
+ x(Se, {
2624
+ modelValue: h.value,
2625
+ "onUpdate:modelValue": D[8] || (D[8] = (L) => h.value = L),
2626
+ "filter-ingredient-ids": se.value
2627
+ }, null, 8, ["modelValue", "filter-ingredient-ids"])
2628
+ ], 64)) : T("", !0)
2629
+ ], 64)) : T("", !0),
2630
+ K.value ? (g(), V(Q, { key: 1 }, [
2631
+ y("p", ni, U(n(o)("inventory.recipe.bulkEditor.addModification.bindingLabel")), 1),
2632
+ x(te, {
2633
+ modelValue: e.value,
2634
+ "onUpdate:modelValue": D[9] || (D[9] = (L) => e.value = L),
2635
+ items: q.value,
2636
+ placeholder: c.value === "recipe" ? n(o)("inventory.recipe.bulkEditor.addModification.recipePlaceholder") : n(o)("inventory.recipe.bulkEditor.addModification.skuPlaceholder"),
2637
+ clearable: ""
2638
+ }, {
2639
+ "menu-wrapper": J((L) => [
2640
+ x(Be, Ie(L, {
2641
+ items: q.value,
2642
+ "model-value": e.value
2643
+ }), null, 16, ["items", "model-value"])
2644
+ ]),
2645
+ _: 1
2646
+ }, 8, ["modelValue", "items", "placeholder"]),
2647
+ e.value ? (g(), V(Q, { key: 0 }, [
2648
+ c.value === "ingredient" && oe.value ? (g(), Y(Ce, {
2649
+ key: 0,
2650
+ modelValue: S.value,
2651
+ "onUpdate:modelValue": D[10] || (D[10] = (L) => S.value = L),
2652
+ unit: oe.value.unit,
2653
+ placeholder: n(o)("inventory.recipe.bulkEditor.query.amountPlaceholder"),
2654
+ "convert-amount-on-change-unit": ""
2655
+ }, null, 8, ["modelValue", "unit", "placeholder"])) : c.value === "recipe" ? (g(), Y(we, {
2656
+ key: 1,
2657
+ "model-value": N.value,
2658
+ label: n(o)("inventory.recipe.bulkEditor.addModification.amountLabel"),
2659
+ type: "number",
2660
+ "onUpdate:modelValue": D[11] || (D[11] = (L) => b(L))
2661
+ }, null, 8, ["model-value", "label"])) : T("", !0),
2662
+ c.value === "recipe" ? (g(), V(Q, { key: 2 }, [
2663
+ y("p", oi, U(n(o)("inventory.recipe.bulkEditor.addModification.optionalRuleLabel")), 1),
2664
+ x(Re, {
2665
+ modelValue: p.value,
2666
+ "onUpdate:modelValue": D[12] || (D[12] = (L) => p.value = L)
2667
+ }, null, 8, ["modelValue"])
2668
+ ], 64)) : T("", !0),
2669
+ ee.value ? (g(), V(Q, { key: 3 }, [
2670
+ y("p", ii, U(n(o)("inventory.recipe.bulkEditor.addModification.optionalAlternativesLabel")), 1),
2671
+ x(Se, {
2672
+ modelValue: h.value,
2673
+ "onUpdate:modelValue": D[13] || (D[13] = (L) => h.value = L),
2674
+ "filter-ingredient-ids": se.value
2675
+ }, null, 8, ["modelValue", "filter-ingredient-ids"])
2676
+ ], 64)) : T("", !0)
2677
+ ], 64)) : T("", !0)
2678
+ ], 64)) : T("", !0)
2679
+ ])) : T("", !0)
2680
+ ]);
2681
+ };
2682
+ }
2683
+ }), ai = { class: "flex flex-col gap-8" }, ri = { class: "flex flex-wrap items-center gap-12 px-4" }, si = {
2684
+ key: 0,
2685
+ class: "flex items-center gap-6"
2686
+ }, di = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, ui = {
2687
+ key: 1,
2688
+ class: "flex items-center gap-6"
2689
+ }, ci = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, pi = {
2690
+ key: 2,
2691
+ class: "flex items-center gap-6"
2692
+ }, mi = { class: "fm-typo-en-body-sm-400 text-fm-color-typo-secondary" }, fi = { class: "rounded-lg border border-fm-color-border-default overflow-hidden" }, vi = {
2693
+ key: 0,
2694
+ class: "px-16 py-12 text-center fm-typo-en-body-sm-400 text-fm-color-typo-placeholder"
2695
+ }, yi = {
2696
+ key: 1,
2697
+ class: "divide-y divide-fm-color-border-default"
2698
+ }, bi = { class: "flex items-center gap-12" }, gi = { class: "flex-1 fm-typo-en-body-sm-600 text-fm-color-typo-primary truncate" }, _i = {
2699
+ key: 0,
2700
+ class: "flex flex-col gap-4 pl-8"
2701
+ }, ki = { class: "flex-1 fm-typo-en-body-xs-400 text-fm-color-typo-secondary font-mono truncate" }, hi = /* @__PURE__ */ le({
2702
+ __name: "LivePreviewTable",
2703
+ setup(m) {
2704
+ const { t: s } = ie(), l = _e(), t = ne(), o = {
2705
+ "will-update": 0,
2706
+ "partially-ignored": 1,
2707
+ "already-satisfied": 2,
2708
+ blocked: 3,
2709
+ "no-applicable-changes": 4
2710
+ }, a = F(
2711
+ () => Object.values(l.livePreviewEntries).sort(
2712
+ (e, S) => o[e.status] - o[S.status]
2713
+ )
2714
+ ), $ = F(
2715
+ () => a.value.filter((e) => e.status === "will-update").length
2716
+ ), d = F(
2717
+ () => a.value.filter((e) => e.status === "partially-ignored").length
2718
+ ), r = F(
2719
+ () => a.value.filter((e) => e.status === "already-satisfied").length
2720
+ ), u = F(
2721
+ () => a.value.filter((e) => e.status === "blocked").length
2722
+ );
2723
+ function i(e) {
2724
+ switch (e) {
2725
+ case "will-update":
2726
+ return s("inventory.recipe.bulkEditor.status.willUpdate");
2727
+ case "already-satisfied":
2728
+ return s("inventory.recipe.bulkEditor.status.alreadySatisfied");
2729
+ case "partially-ignored":
2730
+ return s("inventory.recipe.bulkEditor.status.partiallyIgnored");
2731
+ case "blocked":
2732
+ return s("inventory.recipe.bulkEditor.status.blocked");
2733
+ case "no-applicable-changes":
2734
+ return s("inventory.recipe.bulkEditor.status.noApplicableChanges");
2735
+ default:
2736
+ return "";
2737
+ }
2738
+ }
2739
+ function f(e) {
2740
+ switch (e) {
2741
+ case "will-update":
2742
+ return "success";
2743
+ case "already-satisfied":
2744
+ return "info";
2745
+ case "partially-ignored":
2746
+ return "warning";
2747
+ case "blocked":
2748
+ return "critical";
2749
+ case "no-applicable-changes":
2750
+ return "neutral";
2751
+ default:
2752
+ return "neutral";
2753
+ }
2754
+ }
2755
+ function v(e, S) {
2756
+ var p, h, N;
2757
+ return e === "SKU" ? ((p = t.skuById[S]) == null ? void 0 : p.name) ?? S : e === "SKU_GROUP" ? ((h = t.skuGroupById[S]) == null ? void 0 : h.name) ?? S : e === "RECIPE" ? ((N = t.recipeById[S]) == null ? void 0 : N.name) ?? S : S;
2758
+ }
2759
+ function C(e) {
2760
+ var p, h;
2761
+ const S = v(e.type, e.id);
2762
+ if (e.type === "SKU") {
2763
+ const N = t.skuById[e.id], z = ((p = e.measurement) == null ? void 0 : p.abbrev) ?? ((h = N == null ? void 0 : N.unit) == null ? void 0 : h.abbrev) ?? "";
2764
+ return `${S} (${Z(e.amount)} ${z})`.trim();
2765
+ }
2766
+ return e.type === "RECIPE" ? `${S} ×${Z(e.amount)}` : S;
2767
+ }
2768
+ function w(e) {
2769
+ return v(e.type, e.id);
2770
+ }
2771
+ function c(e, S) {
2772
+ const p = S.contains.find((h) => h.type === e.type && h.id === e.id);
2773
+ return p ? C(p) : w(e);
2774
+ }
2775
+ function k(e, S) {
2776
+ switch (e.type) {
2777
+ case "add-binding":
2778
+ return `+ ${C(e.binding)}`;
2779
+ case "remove-binding":
2780
+ return `− ${w(e.target)}`;
2781
+ case "replace-binding":
2782
+ return `${c(e.from, S)} → ${C(e.to)}`;
2783
+ case "update-binding-rule":
2784
+ return `Rule: ${w(e.target)}`;
2785
+ case "update-alternatives":
2786
+ return `Alternatives: ${w(e.target)}`;
2787
+ }
2788
+ }
2789
+ function I(e) {
2790
+ switch (e) {
2791
+ case "applied":
2792
+ return "success";
2793
+ case "already-satisfied":
2794
+ return "info";
2795
+ case "ignored":
2796
+ return "neutral";
2797
+ case "blocked":
2798
+ return "critical";
2799
+ default:
2800
+ return "neutral";
2801
+ }
2802
+ }
2803
+ function _(e) {
2804
+ switch (e) {
2805
+ case "applied":
2806
+ return s("inventory.recipe.bulkEditor.livePreview.outcomeApplied");
2807
+ case "already-satisfied":
2808
+ return s("inventory.recipe.bulkEditor.livePreview.outcomeAlreadySatisfied");
2809
+ case "ignored":
2810
+ return s("inventory.recipe.bulkEditor.livePreview.outcomeIgnored");
2811
+ case "blocked":
2812
+ return s("inventory.recipe.bulkEditor.livePreview.outcomeBlocked");
2813
+ default:
2814
+ return e;
2815
+ }
2816
+ }
2817
+ return (e, S) => {
2818
+ const p = G("FmChip");
2819
+ return g(), V("div", ai, [
2820
+ y("div", ri, [
2821
+ $.value + d.value > 0 ? (g(), V("div", si, [
2822
+ x(p, {
2823
+ size: "sm",
2824
+ label: String($.value + d.value),
2825
+ variant: "success"
2826
+ }, null, 8, ["label"]),
2827
+ y("span", di, U(n(s)("inventory.recipe.bulkEditor.livePreview.willUpdate")), 1)
2828
+ ])) : T("", !0),
2829
+ r.value > 0 ? (g(), V("div", ui, [
2830
+ x(p, {
2831
+ size: "sm",
2832
+ label: String(r.value),
2833
+ variant: "info"
2834
+ }, null, 8, ["label"]),
2835
+ y("span", ci, U(n(s)("inventory.recipe.bulkEditor.livePreview.alreadySatisfied")), 1)
2836
+ ])) : T("", !0),
2837
+ u.value > 0 ? (g(), V("div", pi, [
2838
+ x(p, {
2839
+ size: "sm",
2840
+ label: String(u.value),
2841
+ variant: "critical"
2842
+ }, null, 8, ["label"]),
2843
+ y("span", mi, U(n(s)("inventory.recipe.bulkEditor.livePreview.blocked")), 1)
2844
+ ])) : T("", !0)
2845
+ ]),
2846
+ y("div", fi, [
2847
+ a.value.length === 0 ? (g(), V("div", vi, U(n(s)("inventory.recipe.bulkEditor.livePreview.noRecipes")), 1)) : (g(), V("div", yi, [
2848
+ (g(!0), V(Q, null, me(a.value, (h) => (g(), V("div", {
2849
+ key: h.recipeId,
2850
+ class: "flex flex-col gap-6 px-16 py-10"
2851
+ }, [
2852
+ y("div", bi, [
2853
+ y("span", gi, U(h.recipeName), 1),
2854
+ x(p, {
2855
+ size: "sm",
2856
+ label: i(h.status),
2857
+ variant: f(h.status)
2858
+ }, null, 8, ["label", "variant"])
2859
+ ]),
2860
+ h.changes.length > 0 ? (g(), V("div", _i, [
2861
+ (g(!0), V(Q, null, me(h.changes, (N, z) => (g(), V("div", {
2862
+ key: z,
2863
+ class: "flex items-center gap-8"
2864
+ }, [
2865
+ y("span", ki, U(k(N.change, h.original)), 1),
2866
+ x(p, {
2867
+ size: "sm",
2868
+ label: _(N.outcome),
2869
+ variant: I(N.outcome)
2870
+ }, null, 8, ["label", "variant"])
2871
+ ]))), 128))
2872
+ ])) : T("", !0)
2873
+ ]))), 128))
2874
+ ]))
2875
+ ])
2876
+ ]);
2877
+ };
2878
+ }
2879
+ }), xi = { class: "flex flex-col h-full overflow-hidden" }, wi = { class: "flex flex-col min-h-0 shrink-0" }, $i = { class: "flex items-center gap-8 px-16 pt-12 border-b border-fm-color-border-default" }, Ii = { class: "flex-1 overflow-x-auto min-w-0" }, Ei = {
2880
+ class: "px-16 py-14 overflow-y-auto",
2881
+ style: { "max-height": "45vh" }
2882
+ }, Vi = {
2883
+ key: 0,
2884
+ class: "flex flex-col items-center justify-center py-40 gap-8 text-center rounded-lg border border-dashed border-fm-color-border-default"
2885
+ }, Si = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Ci = { class: "flex-1 overflow-y-auto px-16 py-14 flex flex-col gap-12 min-h-0" }, Bi = { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary shrink-0" }, Ri = /* @__PURE__ */ le({
2886
+ __name: "RecipeBulkEditorStep2",
2887
+ setup(m) {
2888
+ const { t: s } = ie(), l = _e(), t = W(null);
2889
+ ue(
2890
+ () => l.modifications.length,
2891
+ (r) => {
2892
+ r === 0 ? t.value = null : (t.value === null || t.value >= r) && (t.value = r - 1);
2893
+ },
2894
+ { immediate: !0 }
2895
+ );
2896
+ function o(r, u) {
2897
+ const i = r.type === "replace-binding" ? r.from.type : r.type === "remove-binding" || r.type === "update-binding-rule" || r.type === "update-alternatives" ? r.target.type : r.type === "add-binding" ? r.binding.type : null;
2898
+ return i === "RECIPE" ? s("inventory.recipe.bulkEditor.step2.fieldRecipe") : i === "SKU" || i === "SKU_GROUP" ? s("inventory.recipe.bulkEditor.step2.fieldIngredient") : s("inventory.recipe.bulkEditor.step2.tabLabel", { n: u + 1 });
2899
+ }
2900
+ const a = F(
2901
+ () => l.modifications.map((r, u) => ({
2902
+ label: o(r, u),
2903
+ value: u
2904
+ }))
2905
+ );
2906
+ function $() {
2907
+ const u = {
2908
+ type: "add-binding",
2909
+ binding: {
2910
+ type: "SKU",
2911
+ id: "",
2912
+ amount: be().amount,
2913
+ measurement: null,
2914
+ rules: null,
2915
+ alternatives: []
2916
+ }
2917
+ };
2918
+ l.addModification(u), t.value = l.modifications.length - 1;
2919
+ }
2920
+ function d(r) {
2921
+ l.removeModification(r);
2922
+ }
2923
+ return (r, u) => {
2924
+ const i = G("FmButton"), f = G("FmTab"), v = G("FmTabs"), C = G("FmIcon");
2925
+ return g(), V("div", xi, [
2926
+ y("div", wi, [
2927
+ y("div", $i, [
2928
+ y("div", Ii, [
2929
+ a.value.length > 0 ? (g(), Y(v, {
2930
+ key: 0,
2931
+ "model-value": t.value,
2932
+ items: a.value,
2933
+ "onUpdate:modelValue": u[1] || (u[1] = (w) => t.value = w)
2934
+ }, {
2935
+ default: J((w) => [
2936
+ x(f, Ie(w, {
2937
+ "model-value": t.value,
2938
+ "onUpdate:modelValue": u[0] || (u[0] = (c) => t.value = c)
2939
+ }), {
2940
+ append: J(() => [
2941
+ x(i, {
2942
+ variant: "tertiary",
2943
+ icon: "close",
2944
+ size: "md",
2945
+ onClick: ft((c) => d(w.value), ["stop"])
2946
+ }, null, 8, ["onClick"])
2947
+ ]),
2948
+ _: 2
2949
+ }, 1040, ["model-value"])
2950
+ ]),
2951
+ _: 1
2952
+ }, 8, ["model-value", "items"])) : T("", !0)
2953
+ ]),
2954
+ x(i, {
2955
+ label: n(s)("inventory.recipe.bulkEditor.step2.addModification"),
2956
+ variant: "secondary",
2957
+ size: "md",
2958
+ "prepend-icon": "add",
2959
+ class: "shrink-0",
2960
+ onClick: $
2961
+ }, null, 8, ["label"])
2962
+ ]),
2963
+ y("div", Ei, [
2964
+ n(l).modifications.length === 0 ? (g(), V("div", Vi, [
2965
+ x(C, {
2966
+ name: "edit_note",
2967
+ size: "lg",
2968
+ class: "text-fm-color-typo-placeholder"
2969
+ }),
2970
+ y("p", Si, U(n(s)("inventory.recipe.bulkEditor.step2.emptyState")), 1)
2971
+ ])) : t.value !== null && n(l).modifications[t.value] ? (g(), Y(li, {
2972
+ key: t.value,
2973
+ "model-value": n(l).modifications[t.value],
2974
+ "live-preview-entries": n(l).livePreviewEntries,
2975
+ "onUpdate:modelValue": u[2] || (u[2] = (w) => n(l).updateModification(t.value, w))
2976
+ }, null, 8, ["model-value", "live-preview-entries"])) : T("", !0)
2977
+ ])
2978
+ ]),
2979
+ u[3] || (u[3] = y("div", { class: "border-t border-fm-color-border-default shrink-0" }, null, -1)),
2980
+ y("div", Ci, [
2981
+ y("span", Bi, U(n(s)("inventory.recipe.bulkEditor.step2.livePreviewTitle")), 1),
2982
+ x(hi)
2983
+ ])
2984
+ ]);
2985
+ };
2986
+ }
2987
+ });
2988
+ function Fi(m) {
2989
+ return !m || Object.keys(m).length === 0 ? "" : Object.entries(m).map(([s, l]) => `${s}: ${l}`).join(", ");
2990
+ }
2991
+ function Ai() {
2992
+ const m = ne(), s = _e(), l = m.skuById, t = m.recipeById, o = m.skuGroupById, $ = Object.values(s.entries).filter(
2993
+ (u) => u.status === "will-update" || u.status === "partially-ignored"
2994
+ ).flatMap((u, i) => {
2995
+ var C;
2996
+ const f = u.projected ?? u.original, v = Fi(f.customAttributes);
2997
+ if ((C = f.contains) != null && C.length) {
2998
+ const w = f.contains.filter((I) => I.type === "RECIPE"), c = f.contains.filter((I) => I.type === "SKU"), k = f.contains.filter((I) => I.type === "SKU_GROUP");
2999
+ return [
3000
+ ...i === 0 ? [] : [["", "", "", "", "", "", ""]],
3001
+ ...w.map(
3002
+ (I, _) => {
3003
+ var e;
3004
+ return [
3005
+ _ === 0 ? f.name : "",
3006
+ "RECIPE",
3007
+ "",
3008
+ ((e = t[I.id]) == null ? void 0 : e.name) ?? I.id,
3009
+ Z(I.amount),
3010
+ "UNIT",
3011
+ _ === 0 ? v : ""
3012
+ ];
3013
+ }
3014
+ ),
3015
+ ...c.map(
3016
+ (I, _) => {
3017
+ var e, S, p, h;
3018
+ return [
3019
+ !w.length && _ === 0 ? f.name : "",
3020
+ "INGREDIENT",
3021
+ ((e = l[I.id]) == null ? void 0 : e.code) ?? "",
3022
+ ((S = l[I.id]) == null ? void 0 : S.name) ?? I.id,
3023
+ Z(I.amount),
3024
+ I.measurement ? I.measurement.abbrev : ((h = (p = l[I.id]) == null ? void 0 : p.unit) == null ? void 0 : h.abbrev) ?? "",
3025
+ !w.length && _ === 0 ? v : ""
3026
+ ];
3027
+ }
3028
+ ),
3029
+ ...k.map(
3030
+ (I, _) => {
3031
+ var e, S;
3032
+ return [
3033
+ w.length === 0 && c.length === 0 && _ === 0 ? f.name : "",
3034
+ "SKU_GROUP",
3035
+ ((e = o[I.id]) == null ? void 0 : e.ref) ?? "",
3036
+ ((S = o[I.id]) == null ? void 0 : S.name) ?? I.id,
3037
+ Z(I.amount),
3038
+ "UNIT",
3039
+ w.length === 0 && c.length === 0 && _ === 0 ? v : ""
3040
+ ];
3041
+ }
3042
+ )
3043
+ ];
3044
+ }
3045
+ return [
3046
+ ...i === 0 ? [] : [["", "", "", "", "", "", ""]],
3047
+ [f.name, "No bindings", "", "", "", "", v]
3048
+ ];
3049
+ }), r = rt($, ["Name", "Type", "Code", "Item", "Amount", "Unit", "Custom Attributes"]);
3050
+ st(r, `RECIPE_BULK_EDIT_${dt(/* @__PURE__ */ new Date(), "-", "-")}.xlsx`);
3051
+ }
3052
+ const Ti = { class: "flex flex-col gap-16" }, Ui = { class: "rounded-lg border border-fm-color-border-default bg-fm-color-surface-secondary p-16" }, Pi = { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary mb-8" }, Mi = { class: "flex flex-wrap gap-12" }, Di = { class: "flex items-center gap-6" }, Gi = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Ni = {
3053
+ key: 0,
3054
+ class: "flex items-center gap-6"
3055
+ }, zi = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Oi = {
3056
+ key: 1,
3057
+ class: "flex items-center gap-6"
3058
+ }, ji = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Li = {
3059
+ key: 2,
3060
+ class: "flex items-center gap-6"
3061
+ }, Ki = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, qi = {
3062
+ key: 3,
3063
+ class: "flex items-center gap-6"
3064
+ }, Wi = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Yi = { class: "mt-12" }, Ji = ["onClick"], Hi = { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary flex-1 truncate" }, Qi = {
3065
+ key: 0,
3066
+ class: "px-12 py-8 border-b border-fm-color-border-default"
3067
+ }, Xi = { class: "px-12 py-10 leading-relaxed" }, Zi = {
3068
+ key: 2,
3069
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-placeholder italic"
3070
+ }, el = { class: "flex items-center gap-12 px-12 py-8 border-t border-fm-color-border-default bg-fm-color-surface-secondary text-fm-color-typo-secondary fm-typo-en-body-xs-400" }, tl = { key: 0 }, nl = { key: 1 }, ol = {
3071
+ key: 2,
3072
+ class: "text-fm-color-warning"
3073
+ }, il = {
3074
+ key: 3,
3075
+ class: "text-fm-color-error"
3076
+ }, ll = {
3077
+ key: 4,
3078
+ class: "text-fm-color-typo-placeholder"
3079
+ }, al = /* @__PURE__ */ le({
3080
+ __name: "RecipeBulkEditorSummaryStep",
3081
+ setup(m) {
3082
+ const { t: s } = ie(), l = ne(), t = _e(), o = F(() => Object.values(t.entries)), a = F(
3083
+ () => o.value.filter((e) => e.status === "will-update").length
3084
+ ), $ = F(
3085
+ () => o.value.filter((e) => e.status === "partially-ignored").length
3086
+ ), d = F(
3087
+ () => o.value.filter((e) => e.status === "already-satisfied").length
3088
+ ), r = F(
3089
+ () => o.value.filter((e) => e.status === "blocked").length
3090
+ ), u = F(
3091
+ () => o.value.filter((e) => e.status === "no-applicable-changes").length
3092
+ ), i = W(/* @__PURE__ */ new Set());
3093
+ function f(e) {
3094
+ return i.value.has(e);
3095
+ }
3096
+ function v(e) {
3097
+ const S = new Set(i.value);
3098
+ S.has(e) ? S.delete(e) : S.add(e), i.value = S;
3099
+ }
3100
+ function C(e) {
3101
+ var h, N, z;
3102
+ const S = [], p = ke(e.contains, /* @__PURE__ */ new Set([e._id]), l.recipeById);
3103
+ for (let b = 0; b < p.length; b++) {
3104
+ const B = p[b], R = B.recipeIds.slice(1).length > 0, A = R ? ((h = l.recipeById[B.recipeIds.at(-1) ?? ""]) == null ? void 0 : h.name) ?? "" : "";
3105
+ let P;
3106
+ if (B.isGroup) {
3107
+ const K = l.skuGroupById[B.id];
3108
+ if (!K) continue;
3109
+ const H = `x${Z(B.amount)}`;
3110
+ P = R ? `(${A}) ${K.name} (${H})` : `${K.name} (${H})`;
3111
+ } else {
3112
+ const K = l.skuById[B.id];
3113
+ if (!K) continue;
3114
+ const H = ((N = B.measurement) == null ? void 0 : N.abbrev) ?? ((z = K.unit) == null ? void 0 : z.abbrev) ?? "", ee = `${Z(B.amount)}${H}`;
3115
+ P = R ? `(${A}) ${K.name} (${ee})` : `${K.name} (${ee})`;
3116
+ }
3117
+ b > 0 && S.push({ text: ", " }), S.push({ text: P });
3118
+ }
3119
+ return S;
3120
+ }
3121
+ function w(e) {
3122
+ var b, B, R, A;
3123
+ if (e.isGroup) {
3124
+ const P = l.skuGroupById[e.id];
3125
+ if (!P) return "";
3126
+ const K = e.recipeIds.slice(1).length > 0, H = K ? ((b = l.recipeById[e.recipeIds.at(-1) ?? ""]) == null ? void 0 : b.name) ?? "" : "", ee = `x${Z(e.amount)}`;
3127
+ return K ? `(${H}) ${P.name} (${ee})` : `${P.name} (${ee})`;
3128
+ }
3129
+ const S = l.skuById[e.id];
3130
+ if (!S) return "";
3131
+ const p = e.recipeIds.slice(1).length > 0, h = p ? ((B = l.recipeById[e.recipeIds.at(-1) ?? ""]) == null ? void 0 : B.name) ?? "" : "", N = ((R = e.measurement) == null ? void 0 : R.abbrev) ?? ((A = S.unit) == null ? void 0 : A.abbrev) ?? "", z = `${Z(e.amount)}${N}`;
3132
+ return p ? `(${h}) ${S.name} (${z})` : `${S.name} (${z})`;
3133
+ }
3134
+ function c(e) {
3135
+ if (!e.projected) return [];
3136
+ const S = ke(e.original.contains, /* @__PURE__ */ new Set([e.recipeId]), l.recipeById), p = ke(e.projected.contains, /* @__PURE__ */ new Set([e.recipeId]), l.recipeById), h = /* @__PURE__ */ new Map();
3137
+ for (const R of S) h.set(`${R.type}:${R.id}`, R);
3138
+ const N = /* @__PURE__ */ new Map();
3139
+ for (const R of p) N.set(`${R.type}:${R.id}`, R);
3140
+ const z = [];
3141
+ let b = !0;
3142
+ function B(R, A) {
3143
+ A && (b || z.push({ kind: "unchanged", text: ", " }), z.push({ kind: R, text: A }), b = !1);
3144
+ }
3145
+ for (const [R, A] of h) {
3146
+ const P = N.get(R);
3147
+ if (!P)
3148
+ B("removed", w(A));
3149
+ else {
3150
+ const K = w(A), H = w(P);
3151
+ K === H ? B("unchanged", K) : (B("removed", K), B("added", H));
3152
+ }
3153
+ }
3154
+ for (const [R, A] of N)
3155
+ h.has(R) || B("added", w(A));
3156
+ return z;
3157
+ }
3158
+ const k = F(() => {
3159
+ const e = /* @__PURE__ */ new Map();
3160
+ for (const S of o.value)
3161
+ e.set(S.recipeId, c(S));
3162
+ return e;
3163
+ });
3164
+ function I(e) {
3165
+ switch (e) {
3166
+ case "will-update":
3167
+ return s("inventory.recipe.bulkEditor.status.willUpdate");
3168
+ case "already-satisfied":
3169
+ return s("inventory.recipe.bulkEditor.status.alreadySatisfied");
3170
+ case "partially-ignored":
3171
+ return s("inventory.recipe.bulkEditor.status.partiallyIgnored");
3172
+ case "blocked":
3173
+ return s("inventory.recipe.bulkEditor.status.blocked");
3174
+ case "no-applicable-changes":
3175
+ return s("inventory.recipe.bulkEditor.status.noApplicableChanges");
3176
+ default:
3177
+ return "";
3178
+ }
3179
+ }
3180
+ function _(e) {
3181
+ switch (e) {
3182
+ case "will-update":
3183
+ return "success";
3184
+ case "already-satisfied":
3185
+ return "info";
3186
+ case "partially-ignored":
3187
+ return "warning";
3188
+ case "blocked":
3189
+ return "critical";
3190
+ case "no-applicable-changes":
3191
+ return "neutral";
3192
+ default:
3193
+ return "neutral";
3194
+ }
3195
+ }
3196
+ return (e, S) => {
3197
+ const p = G("FmChip"), h = G("FmButton"), N = G("FmBanner"), z = G("FmIcon");
3198
+ return g(), V("div", Ti, [
3199
+ y("div", Ui, [
3200
+ y("p", Pi, U(n(s)("inventory.recipe.bulkEditor.summary.title")), 1),
3201
+ y("div", Mi, [
3202
+ y("div", Di, [
3203
+ x(p, {
3204
+ size: "sm",
3205
+ label: String(a.value),
3206
+ variant: "success"
3207
+ }, null, 8, ["label"]),
3208
+ y("span", Gi, U(n(s)("inventory.recipe.bulkEditor.summary.countWillUpdate")), 1)
3209
+ ]),
3210
+ $.value > 0 ? (g(), V("div", Ni, [
3211
+ x(p, {
3212
+ size: "sm",
3213
+ label: String($.value),
3214
+ variant: "warning"
3215
+ }, null, 8, ["label"]),
3216
+ y("span", zi, U(n(s)("inventory.recipe.bulkEditor.summary.countPartiallyIgnored")), 1)
3217
+ ])) : T("", !0),
3218
+ d.value > 0 ? (g(), V("div", Oi, [
3219
+ x(p, {
3220
+ size: "sm",
3221
+ label: String(d.value),
3222
+ variant: "info"
3223
+ }, null, 8, ["label"]),
3224
+ y("span", ji, U(n(s)("inventory.recipe.bulkEditor.summary.countAlreadySatisfied")), 1)
3225
+ ])) : T("", !0),
3226
+ r.value > 0 ? (g(), V("div", Li, [
3227
+ x(p, {
3228
+ size: "sm",
3229
+ label: String(r.value),
3230
+ variant: "critical"
3231
+ }, null, 8, ["label"]),
3232
+ y("span", Ki, U(n(s)("inventory.recipe.bulkEditor.summary.countBlocked")), 1)
3233
+ ])) : T("", !0),
3234
+ u.value > 0 ? (g(), V("div", qi, [
3235
+ x(p, {
3236
+ size: "sm",
3237
+ label: String(u.value),
3238
+ variant: "neutral"
3239
+ }, null, 8, ["label"]),
3240
+ y("span", Wi, U(n(s)("inventory.recipe.bulkEditor.summary.countNoChanges")), 1)
3241
+ ])) : T("", !0)
3242
+ ]),
3243
+ y("div", Yi, [
3244
+ x(h, {
3245
+ label: n(s)("common.export"),
3246
+ variant: "secondary",
3247
+ size: "md",
3248
+ onClick: n(Ai)
3249
+ }, null, 8, ["label", "onClick"])
3250
+ ]),
3251
+ a.value === 0 && $.value === 0 ? (g(), Y(N, {
3252
+ key: 0,
3253
+ class: "mt-12",
3254
+ type: "warning",
3255
+ message: n(s)("inventory.recipe.bulkEditor.summary.nothingToSubmit")
3256
+ }, null, 8, ["message"])) : T("", !0)
3257
+ ]),
3258
+ (g(!0), V(Q, null, me(o.value, (b) => (g(), V("div", {
3259
+ key: b.recipeId,
3260
+ class: "rounded-lg border border-fm-color-border-default overflow-hidden"
3261
+ }, [
3262
+ y("button", {
3263
+ type: "button",
3264
+ class: De(["w-full flex items-center gap-8 px-12 py-10 bg-fm-color-surface-secondary border-b border-fm-color-border-default text-left cursor-pointer", { "border-b-0": !f(b.recipeId) }]),
3265
+ onClick: (B) => v(b.recipeId)
3266
+ }, [
3267
+ x(z, {
3268
+ name: f(b.recipeId) ? "expand_less" : "expand_more",
3269
+ size: "sm",
3270
+ class: "text-fm-color-typo-secondary flex-shrink-0"
3271
+ }, null, 8, ["name"]),
3272
+ y("span", Hi, U(b.recipeName), 1),
3273
+ b.original.version === "v2" ? (g(), Y(p, {
3274
+ key: 0,
3275
+ size: "sm",
3276
+ label: "V2",
3277
+ variant: "info"
3278
+ })) : T("", !0),
3279
+ x(p, {
3280
+ size: "sm",
3281
+ label: I(b.status),
3282
+ variant: _(b.status)
3283
+ }, null, 8, ["label", "variant"])
3284
+ ], 10, Ji),
3285
+ f(b.recipeId) ? (g(), V(Q, { key: 0 }, [
3286
+ n(t).applyErrors.has(b.recipeId) ? (g(), V("div", Qi, [
3287
+ x(N, {
3288
+ type: "error",
3289
+ message: n(t).applyErrors.get(b.recipeId)
3290
+ }, null, 8, ["message"])
3291
+ ])) : T("", !0),
3292
+ y("div", Xi, [
3293
+ b.projected ? (k.value.get(b.recipeId) ?? []).length > 0 ? (g(!0), V(Q, { key: 1 }, me(k.value.get(b.recipeId), (B, R) => (g(), V("span", {
3294
+ key: R,
3295
+ class: De(["fm-typo-en-body-sm-400", {
3296
+ "text-fm-color-typo-secondary": B.kind === "unchanged",
3297
+ "line-through text-fm-color-error font-medium": B.kind === "removed",
3298
+ "text-fm-color-success font-medium": B.kind === "added"
3299
+ }])
3300
+ }, U(B.text), 3))), 128)) : (g(), V("span", Zi, U(n(s)("inventory.recipe.bulkEditor.summary.emptyBindings")), 1)) : (g(!0), V(Q, { key: 0 }, me(C(b.original), (B, R) => (g(), V("span", {
3301
+ key: R,
3302
+ class: "fm-typo-en-body-sm-400 text-fm-color-typo-placeholder"
3303
+ }, U(B.text), 1))), 128))
3304
+ ]),
3305
+ y("div", el, [
3306
+ b.counts.applied > 0 ? (g(), V("span", tl, U(n(s)("inventory.recipe.bulkEditor.summary.footerApplied", { count: b.counts.applied })), 1)) : T("", !0),
3307
+ b.counts.satisfied > 0 ? (g(), V("span", nl, U(n(s)("inventory.recipe.bulkEditor.summary.footerSatisfied", { count: b.counts.satisfied })), 1)) : T("", !0),
3308
+ b.counts.ignored > 0 ? (g(), V("span", ol, U(n(s)("inventory.recipe.bulkEditor.summary.footerIgnored", { count: b.counts.ignored })), 1)) : T("", !0),
3309
+ b.counts.blocked > 0 ? (g(), V("span", il, U(n(s)("inventory.recipe.bulkEditor.summary.footerBlocked", { count: b.counts.blocked })), 1)) : T("", !0),
3310
+ b.counts.applied === 0 && b.counts.satisfied === 0 && b.counts.ignored === 0 && b.counts.blocked === 0 ? (g(), V("span", ll, U(n(s)("inventory.recipe.bulkEditor.summary.noChangesDetail")), 1)) : T("", !0)
3311
+ ])
3312
+ ], 64)) : T("", !0)
3313
+ ]))), 128))
3314
+ ]);
3315
+ };
3316
+ }
3317
+ }), rl = { class: "flex items-center gap-12" }, sl = { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary" }, dl = {
3318
+ key: 0,
3319
+ class: "h-[calc(98vh-120px)] overflow-hidden flex flex-col"
3320
+ }, ul = {
3321
+ key: 1,
3322
+ class: "h-[calc(98vh-120px)] overflow-hidden flex flex-col"
3323
+ }, cl = {
3324
+ key: 2,
3325
+ class: "h-[calc(98vh-120px)] overflow-y-auto px-24 py-20"
3326
+ }, pl = {
3327
+ key: 0,
3328
+ class: "flex items-center gap-8 px-4"
3329
+ }, ml = {
3330
+ key: 1,
3331
+ class: "flex items-center gap-8 px-4"
3332
+ }, fl = {
3333
+ key: 2,
3334
+ class: "flex items-center gap-8 px-4"
3335
+ }, vl = /* @__PURE__ */ le({
3336
+ __name: "RecipeBulkEditorDialog",
3337
+ props: {
3338
+ show: { type: Boolean }
3339
+ },
3340
+ emits: ["update:show"],
3341
+ setup(m, { emit: s }) {
3342
+ const l = m, { t } = ie(), o = _e(), a = Ge(l, "show"), $ = je(), d = F(() => o.currentStep === 1), r = F(() => o.currentStep === 2), u = F(() => o.currentStep === 3);
3343
+ function i() {
3344
+ o.currentStep = 2;
3345
+ }
3346
+ function f() {
3347
+ o.currentStep = 1;
3348
+ }
3349
+ function v() {
3350
+ o.goToStep3();
3351
+ }
3352
+ function C() {
3353
+ o.backToStep2();
3354
+ }
3355
+ function w() {
3356
+ $.open({
3357
+ title: t("inventory.recipe.bulkEditor.step3.confirmTitle"),
3358
+ message: t("inventory.recipe.bulkEditor.step3.confirmMessage"),
3359
+ primaryActions: {
3360
+ text: t("inventory.recipe.bulkEditor.step3.confirmButton"),
3361
+ variant: "primary",
3362
+ close: !0
3363
+ },
3364
+ secondaryActions: {
3365
+ text: t("common.cancel"),
3366
+ close: !0
3367
+ }
3368
+ }).onPrimary(async () => {
3369
+ await o.confirmAndApply();
3370
+ });
3371
+ }
3372
+ function c() {
3373
+ a.value = !1, o.reset();
3374
+ }
3375
+ return (k, I) => {
3376
+ const _ = G("FmChip"), e = G("FmButton"), S = G("FmDialog");
3377
+ return g(), Y(S, {
3378
+ modelValue: n(a),
3379
+ "onUpdate:modelValue": [
3380
+ I[0] || (I[0] = (p) => Me(a) ? a.value = p : null),
3381
+ I[1] || (I[1] = (p) => {
3382
+ p || n(o).reset();
3383
+ })
3384
+ ],
3385
+ overlay: !0,
3386
+ "close-button": "",
3387
+ "max-width": "98vw",
3388
+ "max-height": "98vh"
3389
+ }, {
3390
+ "dialog-header": J(() => [
3391
+ y("div", rl, [
3392
+ y("span", sl, U(n(t)("inventory.recipe.bulkEditor.title")), 1),
3393
+ x(_, {
3394
+ size: "sm",
3395
+ label: n(t)("inventory.recipe.bulkEditor.stepIndicator", { step: n(o).currentStep, total: 3 }),
3396
+ variant: "neutral"
3397
+ }, null, 8, ["label"])
3398
+ ])
3399
+ ]),
3400
+ "dialog-footer": J(() => [
3401
+ d.value ? (g(), V("div", pl, [
3402
+ x(e, {
3403
+ label: n(t)("common.next"),
3404
+ disabled: !n(o).canGoToStep2,
3405
+ onClick: i
3406
+ }, null, 8, ["label", "disabled"]),
3407
+ x(e, {
3408
+ label: n(t)("common.close"),
3409
+ variant: "tertiary",
3410
+ onClick: c
3411
+ }, null, 8, ["label"])
3412
+ ])) : r.value ? (g(), V("div", ml, [
3413
+ x(e, {
3414
+ label: n(t)("inventory.recipe.bulkEditor.step2.reviewButton"),
3415
+ disabled: !n(o).canGoToStep3,
3416
+ onClick: v
3417
+ }, null, 8, ["label", "disabled"]),
3418
+ x(e, {
3419
+ label: n(t)("common.back"),
3420
+ variant: "secondary",
3421
+ onClick: f
3422
+ }, null, 8, ["label"]),
3423
+ x(e, {
3424
+ label: n(t)("common.close"),
3425
+ variant: "tertiary",
3426
+ onClick: c
3427
+ }, null, 8, ["label"])
3428
+ ])) : u.value ? (g(), V("div", fl, [
3429
+ x(e, {
3430
+ label: n(t)("inventory.recipe.bulkEditor.step3.confirmButton"),
3431
+ disabled: n(o).isSaving,
3432
+ loading: n(o).isSaving,
3433
+ onClick: w
3434
+ }, null, 8, ["label", "disabled", "loading"]),
3435
+ x(e, {
3436
+ label: n(t)("common.back"),
3437
+ variant: "secondary",
3438
+ disabled: n(o).isSaving,
3439
+ onClick: C
3440
+ }, null, 8, ["label", "disabled"]),
3441
+ x(e, {
3442
+ label: n(t)("common.close"),
3443
+ variant: "tertiary",
3444
+ disabled: n(o).isSaving,
3445
+ onClick: c
3446
+ }, null, 8, ["label", "disabled"])
3447
+ ])) : T("", !0)
3448
+ ]),
3449
+ default: J(() => [
3450
+ d.value ? (g(), V("div", dl, [
3451
+ x(Oo)
3452
+ ])) : r.value ? (g(), V("div", ul, [
3453
+ x(Ri)
3454
+ ])) : u.value ? (g(), V("div", cl, [
3455
+ x(al)
3456
+ ])) : T("", !0)
3457
+ ]),
3458
+ _: 1
3459
+ }, 8, ["modelValue"]);
3460
+ };
3461
+ }
3462
+ });
3463
+ function yl(m) {
3464
+ return !m || Object.keys(m).length === 0 ? "" : Object.entries(m).map(([s, l]) => `${s}: ${l}`).join(", ");
3465
+ }
3466
+ function bl() {
3467
+ const m = ne(), s = m.recipes, l = m.recipeById, t = m.skuById, o = m.skuGroupById, a = s.flatMap((r, u) => {
3468
+ var f;
3469
+ const i = yl(r.customAttributes);
3470
+ if ((f = r.contains) != null && f.length) {
3471
+ const v = r.contains.filter((c) => c.type === "RECIPE"), C = r.contains.filter((c) => c.type === "SKU"), w = r.contains.filter((c) => c.type === "SKU_GROUP");
3472
+ return [
3473
+ ...u === 0 ? [] : [["", "", "", "", "", "", ""]],
3474
+ ...v.map(
3475
+ (c, k) => {
3476
+ var I;
3477
+ return [
3478
+ k === 0 ? r.name : "",
3479
+ "RECIPE",
3480
+ "",
3481
+ (I = l[c.id]) == null ? void 0 : I.name,
3482
+ Z(c.amount),
3483
+ "UNIT",
3484
+ k === 0 ? i : ""
3485
+ ];
3486
+ }
3487
+ ),
3488
+ ...C.map(
3489
+ (c, k) => {
3490
+ var I, _, e, S;
3491
+ return [
3492
+ !v.length && k === 0 ? r.name : "",
3493
+ "INGREDIENT",
3494
+ (I = t[c.id]) == null ? void 0 : I.code,
3495
+ (_ = t[c.id]) == null ? void 0 : _.name,
3496
+ Z(c.amount),
3497
+ c.measurement ? c.measurement.abbrev : (S = (e = t[c.id]) == null ? void 0 : e.unit) == null ? void 0 : S.abbrev,
3498
+ !v.length && k === 0 ? i : ""
3499
+ ];
3500
+ }
3501
+ ),
3502
+ ...w.map(
3503
+ (c, k) => {
3504
+ var I, _;
3505
+ return [
3506
+ v.length === 0 && C.length === 0 && k === 0 ? r.name : "",
3507
+ "SKU_GROUP",
3508
+ ((I = o[c.id]) == null ? void 0 : I.ref) || "",
3509
+ (_ = o[c.id]) == null ? void 0 : _.name,
3510
+ Z(c.amount),
3511
+ "UNIT",
3512
+ v.length === 0 && C.length === 0 && k === 0 ? i : ""
3513
+ ];
3514
+ }
3515
+ )
3516
+ ];
3517
+ }
3518
+ return [
3519
+ ...u === 0 ? [] : [["", "", "", "", "", "", ""]],
3520
+ [r.name, "No bindings", "", "", "", "", i]
3521
+ ];
3522
+ }), d = rt(a, ["Name", "Type", "Code", "Item", "Amount", "Unit", "Custom Attributes"]);
3523
+ st(d, `RECIPE_${dt(/* @__PURE__ */ new Date(), "-", "-")}.xlsx`);
3524
+ }
3525
+ const gl = { class: "flex flex-col py-8" }, _l = { class: "fm-typo-en-body-lg-600 text-fm-color-typo-primary" }, kl = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Hl = /* @__PURE__ */ le({
3526
+ __name: "RecipeView",
3527
+ setup(m) {
3528
+ const s = ne(), l = F(() => s.recipes), t = tt(), { createRecipe: o, updateRecipe: a } = ze(), { recipeDialogProps: $, recipeViewLoading: d } = Et(ze()), { columnDefs: r, formatRowData: u } = Ht(), i = F(() => u(l.value)), f = _e(), v = We();
3529
+ W(!1);
3530
+ function C(p) {
3531
+ if (p === "add")
3532
+ return o();
3533
+ if (p === "export")
3534
+ return bl();
3535
+ p === "bulk-edit" && f.openDialog();
3536
+ }
3537
+ const w = W(""), c = F(() => d.value), { breakpoints: k } = xt(), I = F(() => k.value.xs || k.value.sm), _ = F(() => I.value ? 10 : 20), e = Ct(), { t: S } = ie();
3538
+ return (p, h) => {
3539
+ const N = G("FmTable");
3540
+ return g(), Y(Bt, {
3541
+ title: n(S)("inventory.recipe.title"),
3542
+ actions: [
3543
+ {
3544
+ label: n(S)("inventory.recipe.create.title"),
3545
+ value: "add",
3546
+ isPrimary: !0,
3547
+ prependIcon: "add"
3548
+ },
3549
+ ...n(v).enableBulkEditRecipes ? [{ label: n(S)("inventory.recipe.bulkEditor.title"), value: "bulk-edit", isPrimary: !1 }] : [],
3550
+ { label: n(S)("common.export"), value: "export", isPrimary: !1 }
3551
+ ],
3552
+ "onClick:action": C
3553
+ }, {
3554
+ default: J(() => [
3555
+ y("div", {
3556
+ class: De([
3557
+ "relative flex flex-col gap-8 max-h-full",
3558
+ {
3559
+ "p-0": I.value,
3560
+ "px-24 ": !I.value
3561
+ }
3562
+ ])
3563
+ }, [
3564
+ x(Kt, {
3565
+ searchable: "",
3566
+ search: w.value,
3567
+ "onUpdate:search": h[0] || (h[0] = (z) => w.value = z)
3568
+ }, null, 8, ["search"]),
3569
+ (g(), Y(N, {
3570
+ style: vt(n(e).tableHeight),
3571
+ "column-defs": n(r),
3572
+ "row-data": i.value,
3573
+ "search-value": w.value,
3574
+ loading: !n(t)._currentLocation || c.value,
3575
+ onRowClick: h[1] || (h[1] = (z) => n(a)(z.original.original)),
3576
+ key: l.value.length,
3577
+ "page-size": _.value
3578
+ }, {
3579
+ "list-row": J((z) => [
3580
+ x(Lt, {
3581
+ row: z,
3582
+ onRowClick: (b) => n(a)(b.original)
3583
+ }, {
3584
+ default: J((b) => {
3585
+ var B, R, A, P, K, H, ee, O, M, j;
3586
+ return [
3587
+ y("div", gl, [
3588
+ y("div", _l, [
3589
+ x(n(Qe), {
3590
+ render: (A = (R = (B = b.recipe) == null ? void 0 : B.column) == null ? void 0 : R.columnDef) == null ? void 0 : A.cell,
3591
+ props: (K = (P = b.recipe) == null ? void 0 : P.getContext) == null ? void 0 : K.call(P)
3592
+ }, null, 8, ["render", "props"])
3593
+ ]),
3594
+ y("div", kl, [
3595
+ x(n(Qe), {
3596
+ render: (O = (ee = (H = b.ingredients) == null ? void 0 : H.column) == null ? void 0 : ee.columnDef) == null ? void 0 : O.cell,
3597
+ props: (j = (M = b.ingredients) == null ? void 0 : M.getContext) == null ? void 0 : j.call(M)
3598
+ }, null, 8, ["render", "props"])
3599
+ ])
3600
+ ])
3601
+ ];
3602
+ }),
3603
+ _: 2
3604
+ }, 1032, ["row", "onRowClick"])
3605
+ ]),
3606
+ _: 1
3607
+ }, 8, ["style", "column-defs", "row-data", "search-value", "loading", "page-size"]))
3608
+ ], 2),
3609
+ (g(), Y(yt, { to: "body" }, [
3610
+ x(vo, bt(gt(n($))), null, 16),
3611
+ n(v).enableBulkEditRecipes ? (g(), Y(vl, {
3612
+ key: 0,
3613
+ show: n(f).show,
3614
+ "onUpdate:show": h[2] || (h[2] = (z) => n(f).show = z)
3615
+ }, null, 8, ["show"])) : T("", !0)
3616
+ ]))
3617
+ ]),
3618
+ _: 1
3619
+ }, 8, ["title", "actions"]);
3620
+ };
3621
+ }
3622
+ });
3623
+ export {
3624
+ Hl as default
3625
+ };