@feedmepos/mf-inventory-portal 1.7.8 → 1.7.9-dev.1

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 (117) hide show
  1. package/dist/App-DEdkuDaS.js +1155 -0
  2. package/dist/{ApprovalView-Ba0gWkVa.js → ApprovalView-DpkYimTU.js} +9 -9
  3. package/dist/{BindingsDialog-CZXoBZ1d.js → BindingsDialog-9MteMW5_.js} +2 -2
  4. package/dist/{BindingsPicker-CMV6iPjw.js → BindingsPicker-C3R1Iaci.js} +2 -2
  5. package/dist/{BindingsTable-U-ZlTLYU.js → BindingsTable-yWS4vjmz.js} +6 -5
  6. package/dist/BulkReceiveRequestView-MYLE3mXl.js +2646 -0
  7. package/dist/{ChangeLocationComponent.vue_vue_type_script_setup_true_lang-CQF4cvgH.js → ChangeLocationComponent.vue_vue_type_script_setup_true_lang-DrehE0r3.js} +1 -1
  8. package/dist/{ClosingDraftView-DO9gdBiD.js → ClosingDraftView-BO0eUpk7.js} +19 -19
  9. package/dist/{ClosingHistoryView-BXB64J_7.js → ClosingHistoryView-1Gu4B0qB.js} +5 -5
  10. package/dist/{ClosingTemplateView-sXjGpGuz.js → ClosingTemplateView-CvAn5afN.js} +16 -16
  11. package/dist/{CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-BWgnavaG.js → CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-CwWbC1oH.js} +1 -1
  12. package/dist/{DefaultView-B1CVRi4r.js → DefaultView-DeXxhLsq.js} +2 -2
  13. package/dist/{DeliveryOrderPrintPreview-D_aGDrVG.js → DeliveryOrderPrintPreview-Bilzn1WS.js} +2 -2
  14. package/dist/{EmailDialog.vue_vue_type_script_setup_true_lang-47JMPt7A.js → EmailDialog.vue_vue_type_script_setup_true_lang-C5xp1ceO.js} +6332 -6331
  15. package/dist/{FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-D5aKq-2y.js → FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-DL5i2-tq.js} +6 -6
  16. package/dist/{FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-nEdSBuz9.js → FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-Bq36-nnH.js} +2 -2
  17. package/dist/{FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-CZ93MtX7.js → FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-D2l0nTi_.js} +2 -2
  18. package/dist/{FmMultiselectDialog-924d0E8e.js → FmMultiselectDialog-CKQ1eFVZ.js} +2 -2
  19. package/dist/{FmMultiselectDialog-CTp_ZmWc.js → FmMultiselectDialog-COp24wS3.js} +1 -1
  20. package/dist/{FmUnitInput.vue_vue_type_script_setup_true_lang-BRxkMafg.js → FmUnitInput.vue_vue_type_script_setup_true_lang-CN4ENCPZ.js} +152 -139
  21. package/dist/{ImportView-BwuAAHuI.js → ImportView-CB3qjhvy.js} +6 -6
  22. package/dist/{IngredientBindedItem.vue_vue_type_script_setup_true_lang-D9ZUAHHY.js → IngredientBindedItem.vue_vue_type_script_setup_true_lang-CBxUyjH8.js} +1 -1
  23. package/dist/{IngredientGroupView-YpSzpMv_.js → IngredientGroupView-DuY6Gw5V.js} +5 -5
  24. package/dist/{IngredientsView-Bz8qVoFv.js → IngredientsView-DxzyJE_h.js} +18 -17
  25. package/dist/{IntegrationExplorerView-B_-ymgN1.js → IntegrationExplorerView-Ma59NTHM.js} +4 -4
  26. package/dist/{IntegrationView-xnoC9QlN.js → IntegrationView-SBMEO_e9.js} +14 -14
  27. package/dist/{InventoryBindingForm-BTWQUPsI.js → InventoryBindingForm-CBFJRVNH.js} +1 -1
  28. package/dist/InventoryBindingForm.vue_vue_type_script_setup_true_lang-B-nEFGKA.js +563 -0
  29. package/dist/{InventoryBindingSummary-CooEEtKf.js → InventoryBindingSummary-c5g-35nq.js} +1 -1
  30. package/dist/{NumberPrecisionInput.vue_vue_type_script_setup_true_lang-C8SiLZRg.js → NumberPrecisionInput.vue_vue_type_script_setup_true_lang-DEtNW2wJ.js} +1 -1
  31. package/dist/{PremiumBadge.vue_vue_type_script_setup_true_lang-B__FAGnr.js → PremiumBadge.vue_vue_type_script_setup_true_lang-BInLhmxe.js} +1 -1
  32. package/dist/{ProductionView-D3JiyMzC.js → ProductionView-BlhsrkXW.js} +7 -7
  33. package/dist/{PublishView-CYhEJUmO.js → PublishView-bMEZSiVN.js} +3 -3
  34. package/dist/{PurchaseOrderPrintPreview-BwshL0T9.js → PurchaseOrderPrintPreview-HvIFszQX.js} +2 -2
  35. package/dist/{ReceiveRequestView-5ysfk9Qw.js → ReceiveRequestView-jwXYj2Wy.js} +14 -14
  36. package/dist/RecipeView-DKd5h85n.js +3625 -0
  37. package/dist/{SettingsView-FXvsU3GV.js → SettingsView-BqELMK6p.js} +4 -4
  38. package/dist/{StockView-hVzDJxiT.js → StockView-6xDfuSnV.js} +21 -21
  39. package/dist/{SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-BtE8xrKp.js → SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-CBUZIEA5.js} +1 -1
  40. package/dist/{SupplierView-yrlxEXgg.js → SupplierView-BwMl9JFO.js} +12 -12
  41. package/dist/{SurchargeView-Dbr__oJX.js → SurchargeView-AGXGqhxy.js} +6 -6
  42. package/dist/{SystemTrailDialog.vue_vue_type_script_setup_true_lang-DAgh0GuY.js → SystemTrailDialog.vue_vue_type_script_setup_true_lang-DQSq3UGp.js} +2 -2
  43. package/dist/{TemplatePublishDialog.vue_vue_type_script_setup_true_lang-DhHV4yRp.js → TemplatePublishDialog.vue_vue_type_script_setup_true_lang-BBUG8N2w.js} +1 -1
  44. package/dist/{TransferDetails.vue_vue_type_script_setup_true_lang-DM9eodXF.js → TransferDetails.vue_vue_type_script_setup_true_lang-BMrGsD-f.js} +20 -20
  45. package/dist/{TransferTemplateView-CaBy-6XK.js → TransferTemplateView-DJYXlxpw.js} +20 -20
  46. package/dist/{UnitCostHistoryView-BaRe2psg.js → UnitCostHistoryView-DRgWgXhB.js} +4 -4
  47. package/dist/{UnitDisplayControl.vue_vue_type_script_setup_true_lang-DGnnhrzA.js → UnitDisplayControl.vue_vue_type_script_setup_true_lang-CR8a6DkX.js} +4 -4
  48. package/dist/{UnitView-Cs_PMZJ1.js → UnitView-mWUCF13E.js} +8 -8
  49. package/dist/{WarehouseView-pjHowuWl.js → WarehouseView-DY4_bxzS.js} +5 -5
  50. package/dist/{WastageTemplateView-DIobOhxN.js → WastageTemplateView-D4YFC_zj.js} +14 -14
  51. package/dist/api/changelog.d.ts +64 -0
  52. package/dist/api/purchase-order.d.ts +2 -0
  53. package/dist/{app-DaNzSOfE.js → app-DCSH6Br7.js} +19659 -18887
  54. package/dist/app.d.ts +894 -15
  55. package/dist/app.js +1 -1
  56. package/dist/{closing-template-CDgEFOg1.js → closing-template-knrmn7Jq.js} +1 -1
  57. package/dist/components/FmUnitInputRules.d.ts +7 -0
  58. package/dist/{date2-DhrEiF43.js → date2-m9Qq52B4.js} +5 -5
  59. package/dist/{dayjs.min-TVnsxFg6.js → dayjs.min-BX2fRC46.js} +1 -1
  60. package/dist/{decimal-BWDv8ol1.js → decimal-pgdYbjfw.js} +2 -2
  61. package/dist/{defineDeepModel-DbsM6gfc.js → defineDeepModel-C5kt7Waa.js} +1 -1
  62. package/dist/{duplicate-template-PkTtWam_.js → duplicate-template-B74iiBzz.js} +1 -1
  63. package/dist/{feature-BHgYy3ah.js → feature-CfkazbcV.js} +2 -2
  64. package/dist/{format-time-from-id-D352xZ82.js → format-time-from-id-C1AIz8rq.js} +1 -1
  65. package/dist/{format-unit-display-CVHKzXuh.js → format-unit-display-A-G-IaSa.js} +27 -27
  66. package/dist/{import-export.helper-BRfb6211.js → import-export.helper-Dx6UODpr.js} +6 -6
  67. package/dist/{index-FtpqwqiH.js → index-CiQiwzTH.js} +3306 -3232
  68. package/dist/{index-DnohPynu.js → index-DjKTLy_K.js} +1 -1
  69. package/dist/{index-DdCqL1tq.js → index-uk9CA-G3.js} +3 -3
  70. package/dist/{inventory-core-dart.default-Byo1HZGy.js → inventory-core-dart.default-CMAgxo1z.js} +3728 -3685
  71. package/dist/{lz-string-DRHK_x08.js → lz-string-DZI7eVks.js} +1 -1
  72. package/dist/{netsuite-v_z3aTzd.js → netsuite-CoajVOCj.js} +2 -2
  73. package/dist/{number-gmV3FUZE.js → number-qzibfxtV.js} +3 -3
  74. package/dist/{predefined-templates-rCKSqYYr.js → predefined-templates-Bi2KN0S0.js} +1 -1
  75. package/dist/{purchase-order-template-GnAQ7vbn.js → purchase-order-template-q60hgvfd.js} +1 -1
  76. package/dist/{recalculationUtils-DTlZlorm.js → recalculationUtils-ThdsSQXA.js} +1 -1
  77. package/dist/{rules-DPVlkE_B.js → rules-DkRl1mdI.js} +2 -2
  78. package/dist/{stock-D3fUW9qa.js → stock-CDBl371n.js} +3 -3
  79. package/dist/{stock-BibsfxiT.js → stock-CfGnNgNm.js} +1 -1
  80. package/dist/stores/bulk-job.d.ts +13 -0
  81. package/dist/style.css +1 -1
  82. package/dist/{supplier-C5FZ6JiE.js → supplier-m95t74cw.js} +2 -2
  83. package/dist/{surcharge-B2RJmnfQ.js → surcharge-D0KNDUtM.js} +8 -8
  84. package/dist/tsconfig.app.tsbuildinfo +1 -1
  85. package/dist/{uom-rules-Bvgpk8MW.js → uom-rules-DoC_viYg.js} +1 -1
  86. package/dist/{use-ingredient-select-dialog-sSIVFrjN.js → use-ingredient-select-dialog-DUDA6jkc.js} +2 -2
  87. package/dist/{use-inventory-binding-dialog-Bj4xYOqT.js → use-inventory-binding-dialog-DyZVwYRw.js} +2 -2
  88. package/dist/{use-template-enabled-locations-CDcXjJ9e.js → use-template-enabled-locations-DU6ebPLW.js} +2 -2
  89. package/dist/{use-transfer-locations-Cjubo6cI.js → use-transfer-locations-i4WVdQfZ.js} +2 -2
  90. package/dist/{useHrmPermission-CmAWvTZK.js → useHrmPermission-D4dofQF9.js} +1 -1
  91. package/dist/{useNavigationMenu-CMuz1qRT.js → useNavigationMenu-BwZoEiX3.js} +2 -2
  92. package/dist/{useSseClient-Bq84vjXH.js → useSseClient-vOXEoq_d.js} +1 -1
  93. package/dist/views/changelog/components/ChangelogDialog.vue.d.ts +19 -0
  94. package/dist/views/changelog/components/ChangelogFloatingButton.vue.d.ts +2 -0
  95. package/dist/views/changelog/components/ChangelogPanel.vue.d.ts +18 -0
  96. package/dist/views/changelog/composables/change-path.d.ts +10 -0
  97. package/dist/views/changelog/composables/commit-message.d.ts +9 -0
  98. package/dist/views/changelog/composables/commit-message.spec.d.ts +1 -0
  99. package/dist/views/changelog/composables/json-line-diff.d.ts +10 -0
  100. package/dist/views/changelog/composables/json-line-diff.spec.d.ts +1 -0
  101. package/dist/views/changelog/composables/use-changelog.d.ts +36 -0
  102. package/dist/views/ingredients/components/inventory-binding/InventoryBindingForm.vue.d.ts +2 -0
  103. package/dist/views/ingredients/components/inventory-binding/RecipeBindingBreakdown.vue.d.ts +25 -0
  104. package/dist/views/ingredients/components/inventory-binding/composables/recipe-breakdown.d.ts +34 -0
  105. package/dist/views/ingredients/components/inventory-binding/composables/recipe-breakdown.spec.d.ts +1 -0
  106. package/dist/views/ingredients/components/inventory-binding/v2/InventoryBindingFormV2.vue.d.ts +2 -0
  107. package/dist/views/ingredients/components/inventory-binding/v2/components/InventoryRecipeBindingV2Field.vue.d.ts +4 -0
  108. package/dist/views/receive-request/components/email-dialog/EmailDialog.spec.d.ts +1 -0
  109. package/dist/views/receive-request/components/email-dialog/EmailDialogProps.d.ts +23 -9
  110. package/dist/views/recipe/composables/use-recipe-table.d.ts +11 -0
  111. package/dist/{vue-i18n-Cbgnu2bw.js → vue-i18n-CV9ieqUG.js} +491 -491
  112. package/dist/{xlsx.util-DbTorswP.js → xlsx.util-CfgV0r9W.js} +2 -2
  113. package/package.json +4 -4
  114. package/dist/App-DI9Gew7u.js +0 -311
  115. package/dist/BulkReceiveRequestView-C7x81WZj.js +0 -2584
  116. package/dist/InventoryBindingForm.vue_vue_type_script_setup_true_lang-BZKc-zmn.js +0 -441
  117. package/dist/RecipeView-DOwdWmwx.js +0 -3584
@@ -0,0 +1,1155 @@
1
+ import { ref as I, onUnmounted as Ye, computed as k, defineComponent as ee, watch as K, onMounted as ke, resolveComponent as T, createElementBlock as m, openBlock as u, createBlock as de, createCommentVNode as N, unref as V, createVNode as R, createElementVNode as f, toDisplayString as y, Fragment as E, renderList as q, withKeys as Ce, normalizeClass as ie, withModifiers as Je, withCtx as j, createTextVNode as ve, h as We, onBeforeUnmount as Xe, Teleport as qe, normalizeStyle as Ze, withDirectives as Qe, vModelText as et } from "vue";
2
+ import { _ as tt } from "./empty-placeholder-B0QU467o.js";
3
+ import { u as Pe, a as Ue, R as Q, d as nt, b as ot } from "./app-DCSH6Br7.js";
4
+ import { useCoreStore as me, useI18n as ye } from "@feedmepos/mf-common";
5
+ import { useRouter as Se, useRoute as at } from "vue-router";
6
+ import { u as lt, a as st, I as rt } from "./feature-CfkazbcV.js";
7
+ import { u as it } from "./netsuite-CoajVOCj.js";
8
+ import { u as Te } from "./useNavigationMenu-BwZoEiX3.js";
9
+ import { useBreakpoints as ut } from "@feedmepos/ui-library";
10
+ import { F as Be } from "./FmAdminBadge-DlplQOHb.js";
11
+ import { i as ct, _ as dt } from "./FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-DL5i2-tq.js";
12
+ import { t as mt, a as ft } from "./date2-m9Qq52B4.js";
13
+ import { _ as pt } from "./_plugin-vue_export-helper-CHgC5LLL.js";
14
+ import { u as vt } from "./useTabStorage-BkIVScW_.js";
15
+ import { u as gt } from "./googlemap-D9vA7GsS.js";
16
+ function yt() {
17
+ return {
18
+ loadingHookInstalled: !1,
19
+ isLoading: !1
20
+ };
21
+ }
22
+ const se = I(yt());
23
+ function ht() {
24
+ const c = Se();
25
+ if (!se.value.loadingHookInstalled) {
26
+ se.value.loadingHookInstalled = !0;
27
+ const t = c.beforeEach(() => {
28
+ se.value.isLoading = !0;
29
+ }), o = c.afterEach(() => {
30
+ se.value.isLoading = !1;
31
+ });
32
+ Ye(() => {
33
+ se.value.loadingHookInstalled = !1, t(), o();
34
+ });
35
+ }
36
+ return {
37
+ get isLoading() {
38
+ return se.value.isLoading;
39
+ }
40
+ };
41
+ }
42
+ function _t() {
43
+ const { firstAccessibleRouteName: c } = Te();
44
+ return { hasAnyAccessibleInventoryRoute: k(() => c.value !== null) };
45
+ }
46
+ const xt = {
47
+ key: 0,
48
+ class: "flex flex-col items-center w-full h-full gap-24"
49
+ }, bt = {
50
+ key: 1,
51
+ class: "flex flex-col pt-[200px] gap-32 items-center"
52
+ }, wt = { class: "flex flex-col gap-12 items-center text-center px-24 max-w-[600px]" }, kt = { class: "fm-typo-en-title-lg-600" }, St = { class: "text-fm-color-typo-secondary fm-typo-en-body-md-400" }, $t = {
53
+ key: 2,
54
+ class: "flex flex-col pt-[200px] gap-32 items-center"
55
+ }, Rt = { class: "flex flex-col gap-12 items-center text-center px-24 max-w-[1000px]" }, Lt = { class: "fm-typo-en-title-lg-600" }, It = { class: "text-fm-color-typo-secondary fm-typo-en-body-md-400" }, Ft = { class: "flex gap-16" }, Ct = { href: "https://feedme.ai/product/inventory/features?tab=plans_%26_prices" }, Vt = { href: "https://feedme.ai/form" }, Dt = /* @__PURE__ */ ee({
56
+ __name: "InventoryView",
57
+ setup(c) {
58
+ const t = Pe(), o = Ue(), i = it(), l = me(), n = Se(), s = ht(), r = lt(), { t: g } = ye(), { hasAnyAccessibleInventoryRoute: _ } = _t();
59
+ K(
60
+ [() => l.sessionUser.value, () => l.currentBusiness.value],
61
+ ([P, h]) => {
62
+ x(P, h);
63
+ }
64
+ ), ke(async () => {
65
+ await r.init(), await l.readBusinesses();
66
+ const P = l.sessionUser.value, h = l.currentBusiness.value;
67
+ x(P, h);
68
+ });
69
+ function x(P, h) {
70
+ !P || !h || S();
71
+ }
72
+ async function S() {
73
+ return await t.init(), await i.readSetting().catch((P) => {
74
+ console.error("[all] error on reading netsuite store", P);
75
+ }), await o.init();
76
+ }
77
+ const G = k(() => n.currentRoute.value.name === Q.TRANSFER_TEMPLATE ? r.enablePoTemplate : n.currentRoute.value.name === Q.INGREDIENT_GROUP ? r.enableIngredientGroup : !0), Y = k(
78
+ () => n.currentRoute.value.matched.some((P) => {
79
+ var C;
80
+ const h = P.meta, L = h == null ? void 0 : h.validationManifest;
81
+ return (((C = L == null ? void 0 : L.requiredCaslPermissions) == null ? void 0 : C.length) ?? 0) > 0;
82
+ })
83
+ ), O = k(() => {
84
+ if (!l.sessionUser.value) return !1;
85
+ if (t._locations !== null && t.locations.length === 0) return !0;
86
+ if (!r.isLoaded) return !1;
87
+ const L = n.currentRoute.value.name === Q.LOADING;
88
+ return !_.value && (L || Y.value);
89
+ });
90
+ return (P, h) => {
91
+ const L = T("FmSpacer"), C = T("FmCircularProgress"), A = T("FmButton"), te = T("RouterView");
92
+ return u(), m("div", null, [
93
+ V(s).isLoading ? (u(), m("div", xt, [
94
+ R(L),
95
+ f("div", null, [
96
+ R(C, { size: "xl" })
97
+ ]),
98
+ h[0] || (h[0] = f("div", { class: "fm-typo-en-body-lg-400 text-fm-color-typo-secondary pl-8" }, "Loading page...", -1)),
99
+ R(L)
100
+ ])) : O.value ? (u(), m("div", bt, [
101
+ h[1] || (h[1] = f("img", {
102
+ src: tt,
103
+ alt: "No permission",
104
+ class: "w-[200px] h-[200px]"
105
+ }, null, -1)),
106
+ f("div", wt, [
107
+ f("div", kt, y(V(g)("inventory.common.noPermission.title")), 1),
108
+ f("div", St, y(V(g)("inventory.common.noPermission.description")), 1)
109
+ ])
110
+ ])) : G.value ? V(l).sessionUser.value ? (u(), de(te, { key: 3 })) : N("", !0) : (u(), m("div", $t, [
111
+ f("div", Rt, [
112
+ f("div", Lt, y(V(g)("inventory.common.proPlan.title")), 1),
113
+ f("div", It, y(V(g)("inventory.common.proPlan.subtitle")), 1)
114
+ ]),
115
+ f("div", Ft, [
116
+ f("a", Ct, [
117
+ R(A, {
118
+ label: V(g)("inventory.common.proPlan.comparePlans"),
119
+ variant: "secondary"
120
+ }, null, 8, ["label"])
121
+ ]),
122
+ f("a", Vt, [
123
+ R(A, {
124
+ label: V(g)("inventory.common.proPlan.callUs"),
125
+ "prepend-icon": "call"
126
+ }, null, 8, ["label"])
127
+ ])
128
+ ])
129
+ ]))
130
+ ]);
131
+ };
132
+ }
133
+ }), Ne = nt((c, t) => ({
134
+ /**
135
+ * Commits for one record. recordId is the changelog docId, `${dbName}/${id}`.
136
+ * The dbName scopes the (access-checked) backend route; only the bare id is
137
+ * sent — the backend rebuilds the docId server-side.
138
+ */
139
+ async getRecordChangelog(o, i) {
140
+ const l = o.indexOf("/");
141
+ if (l < 0) return [];
142
+ const n = o.slice(0, l), s = o.slice(l + 1), r = new URLSearchParams({ id: s });
143
+ i != null && r.set("limit", String(i));
144
+ const g = `${c.inventoryBackendUrl}/${n}/changelog?${r.toString()}`;
145
+ return await t.get(g);
146
+ },
147
+ /**
148
+ * Purchase orders in a date range, each with when it last changed. The
149
+ * backend joins the orders to their newest commit, so no ids travel and the
150
+ * browser makes one request instead of list-then-ask-for-timestamps.
151
+ */
152
+ async listPurchaseOrders(o, i, l) {
153
+ if (!o) return [];
154
+ const n = new URLSearchParams({ start: i, end: l }), s = `${c.inventoryBackendUrl}/${o}/changelog/purchase-order?${n}`;
155
+ return await t.get(s);
156
+ },
157
+ /**
158
+ * Closing drafts created in a date range, each with when it last changed.
159
+ * Closing groups come back as rows of their own — their submit/approve/
160
+ * reject is recorded against the group document, not its parent.
161
+ */
162
+ async listClosingDrafts(o, i, l) {
163
+ if (!o) return [];
164
+ const n = new URLSearchParams({ start: i, end: l }), s = `${c.inventoryBackendUrl}/${o}/changelog/closing-draft?${n}`;
165
+ return await t.get(s);
166
+ },
167
+ /**
168
+ * The domains the browser lists generically, declared in
169
+ * changelog-domains-pkg and served by the backend — a new browsable domain
170
+ * becomes a tab without a portal change. Backends predating the route
171
+ * yield an error the caller treats as "no extra domains".
172
+ */
173
+ async listDomains(o) {
174
+ if (!o) return [];
175
+ const i = `${c.inventoryBackendUrl}/business_${o}/changelog/domains`;
176
+ return await t.get(i);
177
+ },
178
+ /**
179
+ * One generic domain's records, each with when it last changed. Business-
180
+ * scoped: the generic domains are configuration documents of the business
181
+ * db, not of a location.
182
+ */
183
+ async listDomainRecords(o, i) {
184
+ if (!o) return [];
185
+ const l = `${c.inventoryBackendUrl}/business_${o}/changelog/domain/${encodeURIComponent(i)}`;
186
+ return await t.get(l);
187
+ },
188
+ /**
189
+ * One inventory module's records, each with when it last changed. Business-
190
+ * scoped, so the db is `business_<id>` — the same prefixed name the record's
191
+ * own changelog docId carries.
192
+ */
193
+ async listInventory(o, i) {
194
+ if (!o) return [];
195
+ const l = `${c.inventoryBackendUrl}/business_${o}/changelog/inventory?module=${i}`;
196
+ return await t.get(l);
197
+ }
198
+ }));
199
+ function Pt() {
200
+ const c = Ne(), t = I([]), o = I(!1);
201
+ async function i(l, n) {
202
+ if (!l) {
203
+ t.value = [];
204
+ return;
205
+ }
206
+ o.value = !0;
207
+ try {
208
+ t.value = await c.getRecordChangelog(l, n);
209
+ } catch (s) {
210
+ throw t.value = [], s;
211
+ } finally {
212
+ o.value = !1;
213
+ }
214
+ }
215
+ return { commits: t, isLoading: o, load: i };
216
+ }
217
+ function Ee(c) {
218
+ if (!c) return null;
219
+ try {
220
+ const t = JSON.parse(c);
221
+ return typeof (t == null ? void 0 : t.changelogLabelKey) == "string" && typeof (t == null ? void 0 : t.verb) == "string" ? {
222
+ labelKey: t.changelogLabelKey,
223
+ verb: t.verb,
224
+ ...typeof t.name == "string" ? { name: t.name } : {}
225
+ } : null;
226
+ } catch {
227
+ return null;
228
+ }
229
+ }
230
+ function Ut(c) {
231
+ return c.startsWith("inventory.changelog.");
232
+ }
233
+ const Tt = "";
234
+ function ge(c) {
235
+ const t = c.indexOf(Tt);
236
+ return t === -1 ? { raw: c, human: c } : { raw: c.slice(0, t), human: c.slice(t + 1) };
237
+ }
238
+ const Bt = [
239
+ "inventory.changelog.label.recipe",
240
+ "inventory.changelog.label.sku",
241
+ "inventory.changelog.label.unit"
242
+ ], Nt = [...Bt, "Recipe", "Ingredient", "Unit"];
243
+ function Et(c) {
244
+ const { human: t } = ge(c);
245
+ if (!t) return { type: "Document", name: "", field: [] };
246
+ const o = t.split(" › ");
247
+ return o.length >= 2 && Nt.includes(o[0]) ? { type: o[0], name: o[1], field: o.slice(2) } : { type: "Document", name: "", field: o };
248
+ }
249
+ const Ve = 800;
250
+ function At(c, t, o = 2) {
251
+ const i = De(c), l = De(t);
252
+ if (!i || !l) return null;
253
+ let n = 0;
254
+ for (; n < i.length && n < l.length && i[n] === l[n]; ) n++;
255
+ let s = 0;
256
+ for (; s < i.length - n && s < l.length - n && i[i.length - 1 - s] === l[l.length - 1 - s]; )
257
+ s++;
258
+ const r = i.slice(n, i.length - s), g = l.slice(n, l.length - s);
259
+ if (r.length > Ve || g.length > Ve) return null;
260
+ const _ = (x) => ({ type: "same", text: x });
261
+ return Ot(
262
+ [...i.slice(0, n).map(_), ...Mt(r, g), ...i.slice(i.length - s).map(_)],
263
+ o
264
+ );
265
+ }
266
+ function De(c) {
267
+ try {
268
+ const t = JSON.parse(c);
269
+ return t === null || typeof t != "object" ? null : JSON.stringify(t, null, 2).split(`
270
+ `);
271
+ } catch {
272
+ return null;
273
+ }
274
+ }
275
+ function Mt(c, t) {
276
+ const o = c.length, i = t.length, l = Array.from({ length: o + 1 }, () => new Uint32Array(i + 1));
277
+ for (let g = o - 1; g >= 0; g--)
278
+ for (let _ = i - 1; _ >= 0; _--)
279
+ l[g][_] = c[g] === t[_] ? l[g + 1][_ + 1] + 1 : Math.max(l[g + 1][_], l[g][_ + 1]);
280
+ const n = [];
281
+ let s = 0, r = 0;
282
+ for (; s < o && r < i; )
283
+ c[s] === t[r] ? (n.push({ type: "same", text: c[s] }), s++, r++) : l[s + 1][r] >= l[s][r + 1] ? (n.push({ type: "del", text: c[s] }), s++) : (n.push({ type: "add", text: t[r] }), r++);
284
+ for (; s < o; ) n.push({ type: "del", text: c[s++] });
285
+ for (; r < i; ) n.push({ type: "add", text: t[r++] });
286
+ return n;
287
+ }
288
+ function Ot(c, t) {
289
+ const o = c.map(() => !1);
290
+ c.forEach((n, s) => {
291
+ if (n.type !== "same")
292
+ for (let r = Math.max(0, s - t); r <= Math.min(c.length - 1, s + t); r++)
293
+ o[r] = !0;
294
+ });
295
+ const i = [];
296
+ let l = !1;
297
+ return c.forEach((n, s) => {
298
+ o[s] ? (i.push(n), l = !1) : l || (i.push({ type: "skip", text: "⋯" }), l = !0);
299
+ }), i;
300
+ }
301
+ const zt = {
302
+ key: 0,
303
+ class: "flex justify-center p-16"
304
+ }, Kt = {
305
+ key: 1,
306
+ class: "p-16 text-center text-gray-500"
307
+ }, jt = {
308
+ key: 2,
309
+ class: "flex h-full min-h-0 gap-8"
310
+ }, Gt = { class: "w-1/3 shrink-0 overflow-y-auto border-r border-gray-200 pr-4" }, Ht = ["onClick", "onKeydown"], Yt = { class: "fm-typo-en-body-md-600" }, Jt = { class: "text-xs text-gray-500" }, Wt = {
311
+ key: 0,
312
+ class: "flex-1 overflow-y-auto pl-4"
313
+ }, Xt = { class: "mb-12 flex flex-col gap-2 border-b border-gray-200 pb-8" }, qt = { class: "fm-typo-en-body-lg-600" }, Zt = { class: "text-xs text-gray-500" }, Qt = { class: "mb-12" }, en = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary pl-8" }, tn = {
314
+ key: 0,
315
+ class: "text-xs text-gray-400"
316
+ }, nn = { class: "fm-typo-en-body-md-600" }, on = { class: "flex flex-col gap-6" }, an = {
317
+ key: 0,
318
+ class: "text-gray-700"
319
+ }, ln = { class: "min-w-[120px] shrink-0 text-gray-500" }, sn = {
320
+ key: 0,
321
+ class: "w-full overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
322
+ }, rn = {
323
+ key: 1,
324
+ class: "flex flex-wrap items-baseline gap-4"
325
+ }, un = {
326
+ key: 0,
327
+ class: "rounded bg-red-50 px-4 text-red-700"
328
+ }, cn = {
329
+ key: 1,
330
+ class: "text-gray-400"
331
+ }, dn = {
332
+ key: 2,
333
+ class: "rounded bg-green-50 px-4 text-green-700"
334
+ }, mn = {
335
+ key: 0,
336
+ class: "text-sm text-gray-500"
337
+ }, fn = {
338
+ key: 1,
339
+ class: "flex flex-col gap-16"
340
+ }, pn = { class: "flex items-center gap-4" }, vn = { class: "rounded bg-gray-100 px-2 py-1 text-xs" }, gn = { class: "flex min-w-0 flex-wrap items-center gap-1 font-mono text-xs text-gray-600" }, yn = {
341
+ key: 0,
342
+ class: "text-gray-400"
343
+ }, hn = { class: "cursor-default" }, _n = {
344
+ key: 0,
345
+ class: "ml-auto shrink-0 text-xs text-gray-400"
346
+ }, xn = {
347
+ key: 0,
348
+ class: "overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
349
+ }, bn = {
350
+ key: 1,
351
+ class: "grid grid-cols-2 gap-2 font-mono text-xs"
352
+ }, wn = { class: "m-0 min-h-[1.5em] overflow-x-auto whitespace-pre-wrap break-all rounded bg-red-50 p-4 text-red-700" }, kn = { class: "m-0 min-h-[1.5em] overflow-x-auto whitespace-pre-wrap break-all rounded bg-green-50 p-4 text-green-700" }, Sn = {
353
+ key: 2,
354
+ class: "mt-16 break-all border-t border-gray-200 pt-8 font-mono text-xs text-gray-400"
355
+ }, $n = { key: 0 }, Rn = /* @__PURE__ */ ee({
356
+ __name: "ChangelogPanel",
357
+ props: {
358
+ commits: {},
359
+ isLoading: { type: Boolean }
360
+ },
361
+ setup(c) {
362
+ const t = c, { t: o } = ye(), i = I(null), l = I(!1), n = k(() => l.value ? "raw" : "friendly"), s = k(
363
+ () => t.commits.find((a) => a.id === i.value)
364
+ ), r = /* @__PURE__ */ new Set(["updatedAt", "createdAt", "updatedBy", "createdBy", "_rev"]), g = k(() => {
365
+ var v;
366
+ const a = ((v = s.value) == null ? void 0 : v.changes) ?? [];
367
+ return n.value === "raw" ? a : a.filter((w) => {
368
+ const { raw: H } = ge(w.path);
369
+ return H === "@payload" || w.from == null && w.to == null ? !1 : !H.split(".").some((z) => r.has(z));
370
+ });
371
+ }), _ = k(
372
+ () => n.value === "raw" ? g.value.map((a) => ({ ch: a, diff: A(a.from, a.to) })) : []
373
+ );
374
+ K(
375
+ () => t.commits,
376
+ (a) => {
377
+ var v;
378
+ a.find((w) => w.id === i.value) || (i.value = ((v = a[0]) == null ? void 0 : v.id) ?? null);
379
+ },
380
+ { immediate: !0 }
381
+ );
382
+ function x(a) {
383
+ return a ? a.slice(0, 8) : "";
384
+ }
385
+ function S(a) {
386
+ return a ? new Date(a).toLocaleString() : "";
387
+ }
388
+ function G(a) {
389
+ const { raw: v } = ge(a);
390
+ if (!v) {
391
+ const w = o("inventory.changelog.documentRoot");
392
+ return [{ display: w, full: w }];
393
+ }
394
+ return v.split(".").map((w) => ({
395
+ full: w,
396
+ display: w.length > 28 ? `${w.slice(0, 14)}…${w.slice(-8)}` : w
397
+ }));
398
+ }
399
+ function Y(a) {
400
+ return a;
401
+ }
402
+ function O(a) {
403
+ if (a == null) return "";
404
+ let v;
405
+ try {
406
+ v = JSON.parse(a);
407
+ } catch {
408
+ return a;
409
+ }
410
+ return n.value === "raw" ? JSON.stringify(v, null, 2) : v === null ? "—" : typeof v == "string" ? v : typeof v == "number" ? v.toLocaleString() : typeof v == "boolean" ? o(v ? "inventory.changelog.yes" : "inventory.changelog.no") : JSON.stringify(v, null, 2);
411
+ }
412
+ function P(a) {
413
+ return (a.authors || []).join(", ") || o("inventory.changelog.unknownActor");
414
+ }
415
+ function h(a) {
416
+ const v = Ee(a.message);
417
+ if (!v) return a.message || o("inventory.changelog.noMessage");
418
+ const w = L(v.labelKey);
419
+ return v.name ? o(`inventory.changelog.message.${v.verb}`, { module: w, name: v.name }) : o(`inventory.changelog.message.${v.verb}NoName`, { module: w });
420
+ }
421
+ function L(a) {
422
+ return Ut(a) ? o(a) : a;
423
+ }
424
+ const C = (a) => /[^a-zA-Z]/.test(a);
425
+ function A(a, v) {
426
+ return a == null || v == null ? null : At(a, v);
427
+ }
428
+ function te(a) {
429
+ return a === "add" ? "bg-green-50 text-green-700" : a === "del" ? "bg-red-50 text-red-700" : a === "skip" ? "text-gray-400" : "text-gray-600";
430
+ }
431
+ function ue(a) {
432
+ return a.type === "skip" ? a.text : (a.type === "add" ? "+ " : a.type === "del" ? "- " : " ") + a.text;
433
+ }
434
+ const ne = k(() => {
435
+ const a = /* @__PURE__ */ new Map(), v = [], w = (p, F) => {
436
+ let b = a.get(p);
437
+ return b || (b = F(), a.set(p, b), v.push(b)), b;
438
+ }, H = () => w("@doc", () => ({ header: o("inventory.changelog.documentRoot"), lines: [] })), z = (p, F, b) => {
439
+ F.from != null && F.to != null ? p.lines.push({ label: b, from: F.from, to: F.to, diff: A(F.from, F.to) }) : F.to != null ? p.lines.push({ label: b, to: F.to }) : p.lines.push({ label: b, from: F.from });
440
+ };
441
+ for (const p of g.value) {
442
+ const { raw: F, human: b } = ge(p.path);
443
+ if (p.kind === "create") {
444
+ H().lines.push({ text: o("inventory.changelog.kind.created") });
445
+ continue;
446
+ }
447
+ const U = F ? F.split(".") : [], B = b ? b.split(" › ") : [], M = U.findIndex((J, W) => W > 0 && C(J));
448
+ if (M > 0 && B.length === U.length) {
449
+ const J = B[M], W = w(U.slice(0, M + 1).join("."), () => ({
450
+ kind: B.slice(0, M).map(L).join(" › "),
451
+ header: J,
452
+ lines: []
453
+ })), fe = B.slice(M + 1).map(L).join(" › ");
454
+ fe ? z(W, p, fe) : p.from != null && p.to != null ? z(W, p, J) : W.badge = p.to != null ? "added" : "removed";
455
+ continue;
456
+ }
457
+ z(H(), p, B.map(L).join(" › "));
458
+ }
459
+ return v;
460
+ });
461
+ return (a, v) => {
462
+ const w = T("FmCircularProgress"), H = T("FmSwitch"), z = T("FmTooltip");
463
+ return a.isLoading ? (u(), m("div", zt, [
464
+ R(w)
465
+ ])) : a.commits.length ? (u(), m("div", jt, [
466
+ f("ol", Gt, [
467
+ (u(!0), m(E, null, q(a.commits, (p) => (u(), m("li", {
468
+ key: p.id,
469
+ role: "button",
470
+ tabindex: "0",
471
+ class: ie([
472
+ "cursor-pointer border-l-2 py-8 pl-12",
473
+ p.id === i.value ? "border-fm-color-primary bg-fm-color-primary-50" : "border-gray-200 hover:bg-gray-50"
474
+ ]),
475
+ onClick: (F) => i.value = p.id,
476
+ onKeydown: [
477
+ Ce((F) => i.value = p.id, ["enter"]),
478
+ Ce(Je((F) => i.value = p.id, ["prevent"]), ["space"])
479
+ ]
480
+ }, [
481
+ f("div", Yt, y(h(p)), 1),
482
+ f("div", Jt, y(P(p)) + " · " + y(S(p.at)) + " · " + y(x(p.id)), 1)
483
+ ], 42, Ht))), 128))
484
+ ]),
485
+ s.value ? (u(), m("div", Wt, [
486
+ f("div", Xt, [
487
+ f("div", qt, y(h(s.value)), 1),
488
+ f("div", Zt, y(P(s.value)) + " · " + y(S(s.value.at)), 1)
489
+ ]),
490
+ f("div", Qt, [
491
+ R(Be, null, {
492
+ default: j(() => [
493
+ f("span", en, y(V(o)("inventory.changelog.tabRaw")), 1),
494
+ R(H, {
495
+ modelValue: l.value,
496
+ "onUpdate:modelValue": v[0] || (v[0] = (p) => l.value = p)
497
+ }, null, 8, ["modelValue"])
498
+ ]),
499
+ _: 1
500
+ })
501
+ ]),
502
+ n.value === "friendly" ? (u(), m(E, { key: 0 }, [
503
+ (u(!0), m(E, null, q(ne.value, (p, F) => (u(), m("div", {
504
+ key: F,
505
+ class: "mb-12 rounded-lg border border-gray-200 p-12"
506
+ }, [
507
+ f("div", {
508
+ class: ie(["flex flex-wrap items-baseline gap-8", p.lines.length ? "mb-8" : ""])
509
+ }, [
510
+ p.kind ? (u(), m("span", tn, y(p.kind), 1)) : N("", !0),
511
+ f("span", nn, y(p.header), 1),
512
+ p.badge ? (u(), m("span", {
513
+ key: 1,
514
+ class: ie(["rounded-full px-8 text-xs", p.badge === "added" ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"])
515
+ }, y(p.badge === "added" ? V(o)("inventory.changelog.added") : V(o)("inventory.changelog.kind.removed")), 3)) : N("", !0)
516
+ ], 2),
517
+ f("ul", on, [
518
+ (u(!0), m(E, null, q(p.lines, (b, U) => (u(), m("li", {
519
+ key: U,
520
+ class: "flex flex-wrap items-baseline gap-8 text-sm"
521
+ }, [
522
+ b.text ? (u(), m("span", an, y(b.text), 1)) : (u(), m(E, { key: 1 }, [
523
+ f("span", ln, y(b.label), 1),
524
+ b.diff ? (u(), m("div", sn, [
525
+ (u(!0), m(E, null, q(b.diff, (B, M) => (u(), m("div", {
526
+ key: M,
527
+ class: ie(["whitespace-pre px-4", te(B.type)])
528
+ }, y(ue(B)), 3))), 128))
529
+ ])) : (u(), m("span", rn, [
530
+ b.from != null ? (u(), m("span", un, y(O(b.from)), 1)) : N("", !0),
531
+ b.from != null && b.to != null ? (u(), m("span", cn, "→")) : N("", !0),
532
+ b.to != null ? (u(), m("span", dn, y(O(b.to)), 1)) : N("", !0)
533
+ ]))
534
+ ], 64))
535
+ ]))), 128))
536
+ ])
537
+ ]))), 128)),
538
+ ne.value.length ? N("", !0) : (u(), m("div", mn, y(V(o)("inventory.changelog.empty")), 1))
539
+ ], 64)) : (u(), m("ul", fn, [
540
+ (u(!0), m(E, null, q(_.value, ({ ch: p, diff: F }, b) => (u(), m("li", {
541
+ key: b,
542
+ class: "flex flex-col gap-2"
543
+ }, [
544
+ f("div", pn, [
545
+ f("span", vn, y(p.kind), 1),
546
+ f("div", gn, [
547
+ (u(!0), m(E, null, q(G(p.path), (U, B) => (u(), m(E, { key: B }, [
548
+ B > 0 ? (u(), m("span", yn, "›")) : N("", !0),
549
+ R(z, {
550
+ placement: "top",
551
+ content: U.full,
552
+ "z-index": 9999
553
+ }, {
554
+ default: j(() => [
555
+ f("span", hn, y(U.display), 1)
556
+ ]),
557
+ _: 2
558
+ }, 1032, ["content"])
559
+ ], 64))), 128))
560
+ ]),
561
+ p.at ? (u(), m("span", _n, y(S(p.at)), 1)) : N("", !0)
562
+ ]),
563
+ F ? (u(), m("div", xn, [
564
+ (u(!0), m(E, null, q(F, (U, B) => (u(), m("div", {
565
+ key: B,
566
+ class: ie(["whitespace-pre px-4", te(U.type)])
567
+ }, y(ue(U)), 3))), 128))
568
+ ])) : (u(), m("div", bn, [
569
+ f("pre", wn, y(O(p.from)), 1),
570
+ f("pre", kn, y(O(p.to)), 1)
571
+ ]))
572
+ ]))), 128))
573
+ ])),
574
+ n.value === "raw" ? (u(), m("div", Sn, [
575
+ ve(y(s.value.id) + " ", 1),
576
+ s.value.parent ? (u(), m("span", $n, "← " + y(s.value.parent), 1)) : N("", !0)
577
+ ])) : N("", !0)
578
+ ])) : N("", !0)
579
+ ])) : (u(), m("div", Kt, y(V(o)("inventory.changelog.empty")), 1));
580
+ };
581
+ }
582
+ }), Ln = { class: "flex flex-wrap items-center gap-16" }, In = { class: "fm-typo-en-heading-lg-600" }, Fn = { class: "flex h-full min-h-0 flex-col gap-12 p-16" }, Cn = { class: "flex flex-wrap items-center gap-12" }, Vn = { class: "flex shrink-0 items-center gap-8" }, Dn = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, Pn = { class: "flex flex-wrap items-center gap-12" }, Un = {
583
+ key: 0,
584
+ class: "fm-typo-en-body-md-600"
585
+ }, Tn = { class: "fm-typo-en-heading-md-600" }, we = "inventory.changelog.label.", Bn = 1e3, Nn = /* @__PURE__ */ ee({
586
+ __name: "ChangelogDialog",
587
+ props: {
588
+ modelValue: { type: Boolean }
589
+ },
590
+ emits: ["update:modelValue"],
591
+ setup(c, { emit: t }) {
592
+ const o = c, i = t, l = k({
593
+ get: () => o.modelValue,
594
+ set: (e) => i("update:modelValue", e)
595
+ }), { t: n } = ye(), s = me(), r = Ue(), g = Pe(), _ = Ne(), { breakpoints: x } = ut(), S = k(() => x.value.xs || x.value.sm), G = k(() => S.value ? "98vw" : "72vw"), { commits: Y, isLoading: O, load: P } = Pt();
596
+ function h(e) {
597
+ return e ? new Date(e).toLocaleString() : "—";
598
+ }
599
+ function L(e) {
600
+ return [...e].sort((d, $) => ($.lastUpdate ?? "").localeCompare(d.lastUpdate ?? ""));
601
+ }
602
+ function C(e, d) {
603
+ P(e, d).catch(($) => console.error("changelog load failed", $));
604
+ }
605
+ const A = I([]);
606
+ async function te() {
607
+ var d;
608
+ const e = (d = s.currentBusiness.value) == null ? void 0 : d._id;
609
+ if (e)
610
+ try {
611
+ A.value = await _.listDomains(e);
612
+ } catch ($) {
613
+ console.error("changelog domain list load failed", $), A.value = [];
614
+ }
615
+ }
616
+ const ue = k(() => [
617
+ { label: n("inventory.changelog.label.purchaseOrder"), value: "purchaseOrder" },
618
+ { label: n("inventory.changelog.label.closingDraft"), value: "closingDraft" },
619
+ { label: n("inventory.changelog.domainInventory"), value: "inventory" },
620
+ ...A.value.map((e) => ({ label: n(e.labelKey), value: e.domain }))
621
+ ]), ne = I(ue.value[0]), a = k(() => {
622
+ var e;
623
+ return ((e = ne.value) == null ? void 0 : e.value) ?? "purchaseOrder";
624
+ }), v = k(
625
+ () => A.value.some((e) => e.domain === a.value)
626
+ ), w = I(!1), H = k(
627
+ () => ["sku", "recipe", "unit"].map((e) => ({
628
+ label: n(we + e),
629
+ value: e
630
+ }))
631
+ ), z = I(H.value[0]), p = k(() => {
632
+ var e;
633
+ return ((e = z.value) == null ? void 0 : e.value) ?? "sku";
634
+ }), F = I(""), b = I(null), U = I(!1), B = k(() => {
635
+ var $;
636
+ const e = ($ = s.currentBusiness.value) == null ? void 0 : $._id, d = r.inventory._id;
637
+ return e && d ? `business_${e}/${d}` : "";
638
+ }), M = I([]), J = I(!1);
639
+ async function W() {
640
+ var d;
641
+ const e = (d = s.currentBusiness.value) == null ? void 0 : d._id;
642
+ if (e) {
643
+ J.value = !0;
644
+ try {
645
+ M.value = L(await _.listInventory(e, p.value));
646
+ } catch ($) {
647
+ console.error("changelog inventory list load failed", $), M.value = [];
648
+ } finally {
649
+ J.value = !1;
650
+ }
651
+ }
652
+ }
653
+ const fe = k(
654
+ () => U.value ? M.value : M.value.filter((e) => !e.deleted)
655
+ ), Ae = k(() => [
656
+ { accessorKey: "id", header: () => n("inventory.closing.draft.table.id"), size: 320 },
657
+ {
658
+ id: "name",
659
+ header: () => n("inventory.common.name"),
660
+ accessorFn: (e) => e.name,
661
+ // Deleted records sit in the same list as live ones, so the row says which
662
+ // it is; nothing else distinguishes them.
663
+ cell: ({ row: e }) => e.original.deleted ? We(
664
+ "span",
665
+ { "data-deleted": "" },
666
+ `${e.original.name} (${n("inventory.changelog.deleted")})`
667
+ ) : e.original.name
668
+ },
669
+ {
670
+ id: "lastUpdate",
671
+ header: () => n("inventory.changelog.column.lastUpdate"),
672
+ size: 200,
673
+ // Raw ISO is the sort key — clicking the header on formatted dates would
674
+ // order them lexicographically by locale string. Formatted only to display.
675
+ accessorFn: (e) => e.lastUpdate ?? "",
676
+ cell: ({ getValue: e }) => h(e() || void 0)
677
+ }
678
+ ]);
679
+ function Me(e) {
680
+ b.value = e, w.value = !0, C(B.value, Bn);
681
+ }
682
+ function Oe(e, d) {
683
+ const $ = Ee(e.message);
684
+ return $ && $.labelKey === we + p.value && $.name === d.name ? !0 : (e.changes ?? []).some((ae) => {
685
+ const X = Et(ae.path);
686
+ return X.type === we + p.value && X.name === d.name;
687
+ });
688
+ }
689
+ const ze = k(() => {
690
+ const e = b.value;
691
+ return e ? Y.value.filter((d) => Oe(d, e)) : [];
692
+ }), he = I([]), _e = I(!1), xe = I(null);
693
+ async function Ke() {
694
+ var d;
695
+ const e = (d = s.currentBusiness.value) == null ? void 0 : d._id;
696
+ if (e) {
697
+ _e.value = !0;
698
+ try {
699
+ he.value = L(
700
+ await _.listDomainRecords(e, a.value)
701
+ );
702
+ } catch ($) {
703
+ console.error("changelog domain records load failed", $), he.value = [];
704
+ } finally {
705
+ _e.value = !1;
706
+ }
707
+ }
708
+ }
709
+ function je(e) {
710
+ var $;
711
+ const d = ($ = s.currentBusiness.value) == null ? void 0 : $._id;
712
+ d && (xe.value = e, w.value = !0, C(`business_${d}/${e.id}`));
713
+ }
714
+ const ce = I(ct()), pe = I([]), be = I(!1), oe = I(null), $e = k(() => {
715
+ const e = g._currentLocation;
716
+ return e ? `${e.name} (${e.doc.profile.code ?? "--"})` : "";
717
+ }), Re = k(() => [
718
+ { accessorKey: "id", header: () => n("inventory.closing.draft.table.id"), size: 320 },
719
+ {
720
+ accessorKey: "name",
721
+ header: () => a.value === "purchaseOrder" ? n("inventory.changelog.column.seq") : n("inventory.common.name"),
722
+ size: 240
723
+ },
724
+ {
725
+ id: "lastUpdate",
726
+ header: () => n("inventory.changelog.column.lastUpdate"),
727
+ size: 200,
728
+ // Raw ISO is the sort key; see the note on the inventory table.
729
+ accessorFn: (e) => e.lastUpdate ?? "",
730
+ cell: ({ getValue: e }) => h(e() || void 0)
731
+ }
732
+ ]);
733
+ async function Le() {
734
+ var ae;
735
+ const e = (ae = g._currentLocation) == null ? void 0 : ae.dbName;
736
+ if (!e) return;
737
+ const d = mt(new Date(ce.value.startDate)).toISOString(), $ = ft(new Date(ce.value.endDate)).toISOString();
738
+ be.value = !0;
739
+ try {
740
+ pe.value = L(
741
+ a.value === "purchaseOrder" ? await _.listPurchaseOrders(e, d, $) : await _.listClosingDrafts(e, d, $)
742
+ );
743
+ } catch (X) {
744
+ console.error("changelog location list load failed", X), pe.value = [];
745
+ } finally {
746
+ be.value = !1;
747
+ }
748
+ oe.value && !pe.value.find((X) => {
749
+ var le;
750
+ return X.id === ((le = oe.value) == null ? void 0 : le.id);
751
+ }) && (oe.value = null, C(""));
752
+ }
753
+ function Ge(e) {
754
+ oe.value = e, w.value = !0, C(`${g.currentLocationDBName}/${e.id}`);
755
+ }
756
+ const He = k(() => {
757
+ var e, d, $;
758
+ return a.value === "inventory" ? ((e = b.value) == null ? void 0 : e.name) ?? "" : v.value ? ((d = xe.value) == null ? void 0 : d.name) ?? "" : (($ = oe.value) == null ? void 0 : $.name) ?? "";
759
+ });
760
+ function Ie() {
761
+ w.value = !1, a.value === "inventory" ? (b.value = null, U.value = !1, C(""), W().catch(
762
+ (e) => console.error("changelog inventory list failed", e)
763
+ )) : v.value ? (xe.value = null, C(""), Ke().catch(
764
+ (e) => console.error("changelog domain records failed", e)
765
+ )) : (oe.value = null, C(""), Le().catch(
766
+ (e) => console.error("changelog location list failed", e)
767
+ ));
768
+ }
769
+ return K(l, (e) => {
770
+ e && (te().catch(
771
+ (d) => console.error("changelog domain list failed", d)
772
+ ), Ie());
773
+ }), K(a, () => {
774
+ l.value && Ie();
775
+ }), K(ce, () => {
776
+ l.value && a.value !== "inventory" && !v.value && Le().catch(
777
+ (e) => console.error("changelog location list failed", e)
778
+ );
779
+ }), K(U, (e) => {
780
+ var d;
781
+ !e && ((d = b.value) != null && d.deleted) && (b.value = null, w.value = !1);
782
+ }), K(p, () => {
783
+ b.value = null, w.value = !1, l.value && a.value === "inventory" && W().catch(
784
+ (e) => console.error("changelog inventory list failed", e)
785
+ );
786
+ }), K(B, (e) => {
787
+ b.value = null, l.value && a.value === "inventory" && C(e);
788
+ }), (e, d) => {
789
+ const $ = T("FmButtonGroup"), ae = T("FmSearch"), X = T("FmSwitch"), le = T("FmTable"), Fe = T("FmDialog");
790
+ return u(), m(E, null, [
791
+ R(Fe, {
792
+ modelValue: l.value,
793
+ "onUpdate:modelValue": d[8] || (d[8] = (D) => l.value = D),
794
+ "close-button": "",
795
+ "dismiss-away": "",
796
+ "min-width": "98vw",
797
+ "max-width": "98vw",
798
+ "max-height": "94vh",
799
+ "content-class": "!p-0 h-[86vh]"
800
+ }, {
801
+ "dialog-header": j(() => [
802
+ f("div", Ln, [
803
+ f("div", In, y(V(n)("inventory.changelog.title")), 1),
804
+ R($, {
805
+ modelValue: ne.value,
806
+ "onUpdate:modelValue": d[0] || (d[0] = (D) => ne.value = D),
807
+ items: ue.value
808
+ }, null, 8, ["modelValue", "items"])
809
+ ])
810
+ ]),
811
+ default: j(() => [
812
+ f("div", Fn, [
813
+ a.value === "inventory" ? (u(), m(E, { key: 0 }, [
814
+ f("div", Cn, [
815
+ R($, {
816
+ modelValue: z.value,
817
+ "onUpdate:modelValue": d[1] || (d[1] = (D) => z.value = D),
818
+ items: H.value
819
+ }, null, 8, ["modelValue", "items"]),
820
+ R(ae, {
821
+ modelValue: F.value,
822
+ "onUpdate:modelValue": d[2] || (d[2] = (D) => F.value = D),
823
+ class: "flex-1",
824
+ placeholder: V(n)("inventory.changelog.searchInventory")
825
+ }, null, 8, ["modelValue", "placeholder"]),
826
+ f("div", Vn, [
827
+ f("span", Dn, y(V(n)("inventory.changelog.includeDeleted")), 1),
828
+ R(X, {
829
+ modelValue: U.value,
830
+ "onUpdate:modelValue": d[3] || (d[3] = (D) => U.value = D)
831
+ }, null, 8, ["modelValue"])
832
+ ])
833
+ ]),
834
+ R(le, {
835
+ class: "min-h-0 flex-1",
836
+ "row-data": fe.value,
837
+ "column-defs": Ae.value,
838
+ "search-value": F.value,
839
+ loading: J.value,
840
+ "page-size": 20,
841
+ onRowClick: d[4] || (d[4] = (D) => Me(D.original))
842
+ }, null, 8, ["row-data", "column-defs", "search-value", "loading"])
843
+ ], 64)) : v.value ? (u(), de(le, {
844
+ key: 1,
845
+ class: "min-h-0 flex-1",
846
+ "row-data": he.value,
847
+ "column-defs": Re.value,
848
+ loading: _e.value,
849
+ "page-size": 20,
850
+ onRowClick: d[5] || (d[5] = (D) => je(D.original))
851
+ }, null, 8, ["row-data", "column-defs", "loading"])) : (u(), m(E, { key: 2 }, [
852
+ f("div", Pn, [
853
+ R(dt, {
854
+ modelValue: ce.value,
855
+ "onUpdate:modelValue": d[6] || (d[6] = (D) => ce.value = D)
856
+ }, null, 8, ["modelValue"]),
857
+ $e.value ? (u(), m("span", Un, y($e.value), 1)) : N("", !0)
858
+ ]),
859
+ R(le, {
860
+ class: "min-h-0 flex-1",
861
+ "row-data": pe.value,
862
+ "column-defs": Re.value,
863
+ loading: be.value,
864
+ "page-size": 20,
865
+ onRowClick: d[7] || (d[7] = (D) => Ge(D.original))
866
+ }, null, 8, ["row-data", "column-defs", "loading"])
867
+ ], 64))
868
+ ])
869
+ ]),
870
+ _: 1
871
+ }, 8, ["modelValue"]),
872
+ R(Fe, {
873
+ modelValue: w.value,
874
+ "onUpdate:modelValue": d[9] || (d[9] = (D) => w.value = D),
875
+ "close-button": "",
876
+ "dismiss-away": "",
877
+ "min-width": G.value,
878
+ "max-width": G.value,
879
+ "max-height": "86vh"
880
+ }, {
881
+ "dialog-header": j(() => [
882
+ f("div", Tn, y(He.value), 1)
883
+ ]),
884
+ default: j(() => [
885
+ R(Rn, {
886
+ commits: a.value === "inventory" ? ze.value : V(Y),
887
+ "is-loading": V(O)
888
+ }, null, 8, ["commits", "is-loading"])
889
+ ]),
890
+ _: 1
891
+ }, 8, ["modelValue", "min-width", "max-width"])
892
+ ], 64);
893
+ };
894
+ }
895
+ }), En = /* @__PURE__ */ pt(Nn, [["__scopeId", "data-v-3fc1e3f3"]]), An = ["title"], re = 48, Z = 8, Mn = /* @__PURE__ */ ee({
896
+ __name: "ChangelogFloatingButton",
897
+ setup(c) {
898
+ const { t } = ye(), o = me(), i = k(() => {
899
+ var h;
900
+ return !!((h = o.sessionUser.value) != null && h.role.isAdmin);
901
+ }), l = I(!1), n = I({ x: 0, y: 0 });
902
+ function s(h, L, C) {
903
+ return Math.min(Math.max(h, L), C);
904
+ }
905
+ function r() {
906
+ const h = Math.max(Z, window.innerWidth - re - Z), L = Math.max(Z, window.innerHeight - re - Z), C = n.value.x + re / 2;
907
+ n.value = {
908
+ x: C < window.innerWidth / 2 ? Z : h,
909
+ y: s(n.value.y, Z, L)
910
+ };
911
+ }
912
+ function g() {
913
+ n.value = { x: window.innerWidth - re - Z, y: Math.round(window.innerHeight / 2) };
914
+ }
915
+ ke(() => {
916
+ g(), window.addEventListener("resize", r), window.addEventListener("orientationchange", r);
917
+ }), Xe(() => {
918
+ window.removeEventListener("resize", r), window.removeEventListener("orientationchange", r);
919
+ });
920
+ const _ = I(!1);
921
+ let x = null, S = !1;
922
+ function G(h) {
923
+ x = { x: h.clientX, y: h.clientY, px: n.value.x, py: n.value.y }, _.value = !0, S = !1, h.currentTarget.setPointerCapture(h.pointerId);
924
+ }
925
+ function Y(h) {
926
+ if (!x) return;
927
+ const L = h.clientX - x.x, C = h.clientY - x.y;
928
+ Math.abs(L) + Math.abs(C) > 3 && (S = !0), n.value = {
929
+ x: s(x.px + L, 0, window.innerWidth - re),
930
+ y: s(x.py + C, 0, window.innerHeight - re)
931
+ };
932
+ }
933
+ function O() {
934
+ x = null, _.value = !1, r();
935
+ }
936
+ function P() {
937
+ x && (O(), S || (l.value = !0));
938
+ }
939
+ return (h, L) => {
940
+ const C = T("FmIcon");
941
+ return u(), de(qe, { to: "body" }, [
942
+ i.value ? (u(), m(E, { key: 0 }, [
943
+ f("button", {
944
+ type: "button",
945
+ title: V(t)("inventory.changelog.title"),
946
+ class: ie([
947
+ "fixed z-50 flex h-48 w-48 touch-none items-center justify-center rounded-full border border-gray-200 bg-white shadow-lg hover:bg-gray-50",
948
+ _.value ? "cursor-grabbing" : "cursor-grab transition-[left,top] duration-200 ease-out"
949
+ ]),
950
+ style: Ze({ left: `${n.value.x}px`, top: `${n.value.y}px` }),
951
+ onPointerdown: G,
952
+ onPointermove: Y,
953
+ onPointerup: P,
954
+ onPointercancel: O
955
+ }, [
956
+ R(C, {
957
+ name: "history",
958
+ size: "md",
959
+ outline: ""
960
+ })
961
+ ], 46, An),
962
+ R(En, {
963
+ modelValue: l.value,
964
+ "onUpdate:modelValue": L[0] || (L[0] = (A) => l.value = A)
965
+ }, null, 8, ["modelValue"])
966
+ ], 64)) : N("", !0)
967
+ ]);
968
+ };
969
+ }
970
+ }), On = { class: "flex items-center gap-2" }, zn = { class: "text-xs text-gray-400 font-normal" }, Kn = { class: "flex flex-col gap-3" }, jn = { class: "max-h-[480px] flex flex-col gap-1" }, Gn = { class: "font-mono text-xs text-gray-700 break-all min-w-0" }, Hn = {
971
+ key: 0,
972
+ class: "inline-flex items-center gap-1 text-xs font-medium text-green-700 bg-green-50 px-2 py-0.5 rounded-full"
973
+ }, Yn = {
974
+ key: 1,
975
+ class: "inline-flex items-center gap-1 text-xs font-medium text-red-700 bg-red-50 px-2 py-0.5 rounded-full"
976
+ }, Jn = {
977
+ key: 2,
978
+ class: "inline-flex items-center gap-1 text-xs font-medium text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full"
979
+ }, Wn = {
980
+ key: 0,
981
+ class: "text-center text-sm text-gray-400 py-4"
982
+ }, Xn = /* @__PURE__ */ ee({
983
+ __name: "FmFeatureFlagDialog",
984
+ setup(c) {
985
+ const t = I(!1), o = I(""), i = k(() => {
986
+ const { getFlagValue: s } = st();
987
+ return Object.values(rt).map((r) => {
988
+ const g = s(r, (_) => _ === "true");
989
+ return {
990
+ name: r,
991
+ enabled: g
992
+ };
993
+ });
994
+ }), l = k(() => {
995
+ const s = o.value.toLowerCase();
996
+ return s ? i.value.filter((r) => r.name.toLowerCase().includes(s)) : i.value;
997
+ }), n = k(() => {
998
+ const s = i.value.filter((_) => _.enabled === !0).length, r = i.value.filter((_) => _.enabled === !1).length, g = i.value.filter((_) => _.enabled === null).length;
999
+ return { enabled: s, disabled: r, unknown: g, total: i.value.length };
1000
+ });
1001
+ return (s, r) => {
1002
+ const g = T("FmButton"), _ = T("FmSpacer"), x = T("FmDialog");
1003
+ return u(), de(x, {
1004
+ modelValue: t.value,
1005
+ "onUpdate:modelValue": r[2] || (r[2] = (S) => t.value = S),
1006
+ overlay: !0
1007
+ }, {
1008
+ "dialog-button": j(() => [
1009
+ R(Be, null, {
1010
+ default: j(() => [
1011
+ R(g, {
1012
+ variant: "secondary",
1013
+ label: "Feature flags"
1014
+ })
1015
+ ]),
1016
+ _: 1
1017
+ })
1018
+ ]),
1019
+ "dialog-header": j(() => [
1020
+ f("div", On, [
1021
+ r[3] || (r[3] = f("span", null, "Feature Flags", -1)),
1022
+ f("span", zn, y(n.value.enabled) + " enabled · " + y(n.value.disabled) + " disabled · " + y(n.value.unknown) + " unknown ", 1)
1023
+ ])
1024
+ ]),
1025
+ "dialog-footer": j(() => [
1026
+ R(_, { class: "sm:hidden xs:hidden" }),
1027
+ R(g, {
1028
+ class: "sm:w-full xs:w-full",
1029
+ label: "Close",
1030
+ size: "md",
1031
+ variant: "primary",
1032
+ onClick: r[1] || (r[1] = (S) => t.value = !1)
1033
+ })
1034
+ ]),
1035
+ default: j(() => [
1036
+ f("div", Kn, [
1037
+ Qe(f("input", {
1038
+ "onUpdate:modelValue": r[0] || (r[0] = (S) => o.value = S),
1039
+ type: "text",
1040
+ placeholder: "Search flags...",
1041
+ class: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-blue-500"
1042
+ }, null, 512), [
1043
+ [et, o.value]
1044
+ ]),
1045
+ f("div", jn, [
1046
+ (u(!0), m(E, null, q(l.value, (S) => (u(), m("div", {
1047
+ key: S.name,
1048
+ class: "flex items-start justify-between gap-2 px-3 py-2 rounded-md hover:bg-gray-50 text-sm"
1049
+ }, [
1050
+ f("span", Gn, y(S.name), 1),
1051
+ S.enabled === !0 ? (u(), m("span", Hn, r[4] || (r[4] = [
1052
+ f("span", { class: "w-1.5 h-1.5 rounded-full bg-green-500" }, null, -1),
1053
+ ve(" Enabled ")
1054
+ ]))) : S.enabled === !1 ? (u(), m("span", Yn, r[5] || (r[5] = [
1055
+ f("span", { class: "w-1.5 h-1.5 rounded-full bg-red-500" }, null, -1),
1056
+ ve(" Disabled ")
1057
+ ]))) : (u(), m("span", Jn, r[6] || (r[6] = [
1058
+ f("span", { class: "w-1.5 h-1.5 rounded-full bg-gray-400" }, null, -1),
1059
+ ve(" Unknown ")
1060
+ ])))
1061
+ ]))), 128)),
1062
+ l.value.length === 0 ? (u(), m("div", Wn, ' No flags matching "' + y(o.value) + '" ', 1)) : N("", !0)
1063
+ ])
1064
+ ])
1065
+ ]),
1066
+ _: 1
1067
+ }, 8, ["modelValue"]);
1068
+ };
1069
+ }
1070
+ }), qn = { class: "h-full flex flex-col overflow-auto py-16 gap-2" }, Zn = /* @__PURE__ */ ee({
1071
+ __name: "NavigationTab",
1072
+ setup(c) {
1073
+ const t = at(), o = Se(), i = me(), l = vt(), { menuItems: n } = Te();
1074
+ K([() => i.currentBusiness.value, () => t.name], ([x, S]) => {
1075
+ (x == null ? void 0 : x.menuVersion) === "v3" && (S === Q.INGREDIENTS || S === Q.RECIPE || S === Q.UNIT) && o.push({ name: Q.STOCK });
1076
+ });
1077
+ const s = k({
1078
+ get() {
1079
+ if (t.name)
1080
+ return String(t.name);
1081
+ },
1082
+ set(x) {
1083
+ x && o.push({ name: x });
1084
+ }
1085
+ }), r = k(
1086
+ () => {
1087
+ var x;
1088
+ return `NavigationTab.${(x = i.currentBusiness.value) == null ? void 0 : x._id}`;
1089
+ }
1090
+ ), g = I(!1), _ = k({
1091
+ get() {
1092
+ return g.value;
1093
+ },
1094
+ set(x) {
1095
+ g.value = x, x || l.setItem(r.value, "true");
1096
+ }
1097
+ });
1098
+ return K([() => r.value], () => {
1099
+ g.value = !1, setTimeout(() => {
1100
+ _.value = !l.getItem(r.value);
1101
+ }, 2e3);
1102
+ }), (x, S) => {
1103
+ const G = T("FmCollapsibleTabs");
1104
+ return u(), m("div", qn, [
1105
+ R(Xn),
1106
+ R(G, {
1107
+ modelValue: s.value,
1108
+ "onUpdate:modelValue": S[0] || (S[0] = (Y) => s.value = Y),
1109
+ items: V(n)
1110
+ }, null, 8, ["modelValue", "items"])
1111
+ ]);
1112
+ };
1113
+ }
1114
+ });
1115
+ typeof Promise.withResolvers > "u" && (Promise.withResolvers = () => {
1116
+ let c, t;
1117
+ return { promise: new Promise((i, l) => {
1118
+ c = i, t = l;
1119
+ }), resolve: c, reject: t };
1120
+ });
1121
+ typeof Promise.prototype.delayed > "u" && (Promise.prototype.delayed = async function(c) {
1122
+ return await new Promise((t) => setTimeout(t, c)), Promise.resolve(this);
1123
+ });
1124
+ const vo = /* @__PURE__ */ ee({
1125
+ __name: "App",
1126
+ setup(c) {
1127
+ const t = me(), o = gt(), i = ot(), l = window.location.href.includes("print-preview");
1128
+ ke(() => {
1129
+ if (window.location.href.includes("print-preview")) {
1130
+ t.setEmbedded(!0), document.body.classList.add("print-mode");
1131
+ return;
1132
+ }
1133
+ t.registerSidebarComponent(Zn), o.initGoogleMap(i.appApi.googleMap).catch(() => {
1134
+ console.error("Google map cannot be loaded");
1135
+ });
1136
+ }), K([() => t.currentCountry.value], () => {
1137
+ n();
1138
+ });
1139
+ async function n() {
1140
+ var s;
1141
+ try {
1142
+ await t.readBusinesses(), t.currentBusiness.value = (s = t.businesses.value) == null ? void 0 : s.find((r) => r);
1143
+ } catch (r) {
1144
+ console.error("error when trying to reset businesses:", r);
1145
+ }
1146
+ }
1147
+ return (s, r) => (u(), m(E, null, [
1148
+ R(Dt),
1149
+ V(l) ? N("", !0) : (u(), de(Mn, { key: 0 }))
1150
+ ], 64));
1151
+ }
1152
+ });
1153
+ export {
1154
+ vo as default
1155
+ };