@feedmepos/mf-inventory-portal 1.8.0-dev.19 → 1.8.0-dev.20

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