@feedmepos/mf-inventory-portal 1.7.12-dev.3 → 1.7.12-dev.5

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 (92) hide show
  1. package/dist/App-CU_QSfuv.js +1465 -0
  2. package/dist/{ApprovalView-oxEB4USR.js → ApprovalView-CnLICIVi.js} +9 -9
  3. package/dist/{BindingsDialog-jQXgkkje.js → BindingsDialog-DZqBJdn5.js} +2 -2
  4. package/dist/{BindingsPicker-y0_Vtpzl.js → BindingsPicker-Cuy5kxjs.js} +2 -2
  5. package/dist/{BindingsTable-B9HPATmM.js → BindingsTable-Dri2c-ge.js} +4 -4
  6. package/dist/{BulkReceiveRequestView-DqqEN5-b.js → BulkReceiveRequestView-osbKgXXv.js} +19 -19
  7. package/dist/{ChangeLocationComponent.vue_vue_type_script_setup_true_lang-CX_-yjEu.js → ChangeLocationComponent.vue_vue_type_script_setup_true_lang-DwtC7tA2.js} +1 -1
  8. package/dist/{ClosingDraftView-BnNaD4P3.js → ClosingDraftView-BZbNdce7.js} +19 -19
  9. package/dist/{ClosingHistoryView-D81qlQpR.js → ClosingHistoryView-D4syxOhu.js} +5 -5
  10. package/dist/{ClosingTemplateView-CNy_Sy0T.js → ClosingTemplateView-B1_lTIAQ.js} +16 -16
  11. package/dist/{CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-DFirm_5f.js → CustomPrintTemplatePreview.vue_vue_type_script_setup_true_lang-C_mZFrxZ.js} +1 -1
  12. package/dist/{DefaultView-CR265uyv.js → DefaultView-DiFtCZDc.js} +2 -2
  13. package/dist/{DeliveryOrderPrintPreview-CExp66DO.js → DeliveryOrderPrintPreview-BQRClPFv.js} +2 -2
  14. package/dist/{EmailDialog.vue_vue_type_script_setup_true_lang-CyoIPsdJ.js → EmailDialog.vue_vue_type_script_setup_true_lang-B-wf8kYi.js} +23 -23
  15. package/dist/{FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-CLEWxmbm.js → FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-CHqV8p8w.js} +1 -1
  16. package/dist/{FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-CMtXp8ii.js → FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-B_4VZKj7.js} +2 -2
  17. package/dist/{FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-rhv3Zz7c.js → FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-gX3Dc1xM.js} +2 -2
  18. package/dist/{FmMultiselectDialog-CBl4-Bxg.js → FmMultiselectDialog-CZbjW16T.js} +2 -2
  19. package/dist/{FmMultiselectDialog-UiQoj4Xz.js → FmMultiselectDialog-DogKyd9l.js} +1 -1
  20. package/dist/{FmUnitInput.vue_vue_type_script_setup_true_lang-C9Xo9zPv.js → FmUnitInput.vue_vue_type_script_setup_true_lang-BRQw6Ab1.js} +6 -6
  21. package/dist/{ImportView-CfyeYu_h.js → ImportView-KiIQZnVB.js} +6 -6
  22. package/dist/{IngredientBindedItem.vue_vue_type_script_setup_true_lang-kQb2ed-x.js → IngredientBindedItem.vue_vue_type_script_setup_true_lang-CLteHsY5.js} +1 -1
  23. package/dist/{IngredientGroupView-C-yyCXxH.js → IngredientGroupView-CvWhKB3A.js} +5 -5
  24. package/dist/{IngredientsView-DhZWcaBi.js → IngredientsView-B7iuozx0.js} +15 -15
  25. package/dist/{IntegrationExplorerView-C9DYE1IY.js → IntegrationExplorerView-BxPlIE7G.js} +4 -4
  26. package/dist/{IntegrationView-CethwJyL.js → IntegrationView-CfESNJdc.js} +2120 -2114
  27. package/dist/{InventoryBindingForm-B6nDWO5m.js → InventoryBindingForm-BGgzoXQO.js} +1 -1
  28. package/dist/{InventoryBindingForm.vue_vue_type_script_setup_true_lang-BhytMRdh.js → InventoryBindingForm.vue_vue_type_script_setup_true_lang-BR2MdQaY.js} +5 -5
  29. package/dist/{InventoryBindingSummary-NJSQ92Hv.js → InventoryBindingSummary-CBIvpR7n.js} +1 -1
  30. package/dist/{NumberPrecisionInput.vue_vue_type_script_setup_true_lang-Dfwxrtna.js → NumberPrecisionInput.vue_vue_type_script_setup_true_lang-C7kO7G5h.js} +1 -1
  31. package/dist/{PremiumBadge.vue_vue_type_script_setup_true_lang-C65NPxLw.js → PremiumBadge.vue_vue_type_script_setup_true_lang-B8XDlzoQ.js} +1 -1
  32. package/dist/{ProductionView-BsIq_A-9.js → ProductionView-BeL23GOw.js} +7 -7
  33. package/dist/{PublishView-C5YgVjR4.js → PublishView-I7GHly3b.js} +3 -3
  34. package/dist/{PurchaseOrderPrintPreview-B52LSkJv.js → PurchaseOrderPrintPreview-qrcJifVm.js} +2 -2
  35. package/dist/{ReceiveRequestView-C_76or3n.js → ReceiveRequestView-kFkfS48K.js} +14 -14
  36. package/dist/{RecipeView-53hSqpjw.js → RecipeView-CQ5Wtvba.js} +17 -17
  37. package/dist/{SettingsView-CJF-x6g5.js → SettingsView-C60DIBUW.js} +4 -4
  38. package/dist/{StockView-DD5hxJUg.js → StockView-Dtjq0Z-v.js} +21 -21
  39. package/dist/{SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-7WPGPoD7.js → SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-D4MSJHSX.js} +1 -1
  40. package/dist/{SupplierView-JkMsNCEH.js → SupplierView-BAd5T55f.js} +12 -12
  41. package/dist/{SurchargeView-CEogSF9G.js → SurchargeView-CO7D6wNP.js} +6 -6
  42. package/dist/{SystemTrailDialog.vue_vue_type_script_setup_true_lang-DNwkpBFs.js → SystemTrailDialog.vue_vue_type_script_setup_true_lang-CzUUgFx3.js} +2 -2
  43. package/dist/{TemplatePublishDialog.vue_vue_type_script_setup_true_lang-BWldDQWX.js → TemplatePublishDialog.vue_vue_type_script_setup_true_lang-B71-e7oL.js} +1 -1
  44. package/dist/{TransferDetails.vue_vue_type_script_setup_true_lang-Ce111sJ2.js → TransferDetails.vue_vue_type_script_setup_true_lang-BvSutVIA.js} +20 -20
  45. package/dist/{TransferTemplateView-gqp2SM2X.js → TransferTemplateView-olmpzj8z.js} +20 -20
  46. package/dist/{UnitCostHistoryView-DIqhobwc.js → UnitCostHistoryView-BRghmXgu.js} +4 -4
  47. package/dist/{UnitDisplayControl.vue_vue_type_script_setup_true_lang-DterFkEz.js → UnitDisplayControl.vue_vue_type_script_setup_true_lang-DUtZ7Y45.js} +4 -4
  48. package/dist/{UnitView-BJNQoSp7.js → UnitView-DjAWnHJv.js} +7 -7
  49. package/dist/{WarehouseView-Bog3ej-P.js → WarehouseView-svAKmyGx.js} +6 -6
  50. package/dist/{WastageTemplateView-BediHhzD.js → WastageTemplateView-BZ0PZ2Pu.js} +14 -14
  51. package/dist/{app-B21lv_1b.js → app-C_rLd-TD.js} +23 -15
  52. package/dist/app.d.ts +8 -0
  53. package/dist/app.js +1 -1
  54. package/dist/{closing-template-_kUPCBsQ.js → closing-template-9aNJ81NN.js} +1 -1
  55. package/dist/{date2-BDwZlML3.js → date2-CcxGrCsx.js} +1 -1
  56. package/dist/{dayjs.min-Brno9n-D.js → dayjs.min-CXxGGCFk.js} +1 -1
  57. package/dist/{decimal-ApeU8j4E.js → decimal-DJubI-mF.js} +2 -2
  58. package/dist/{defineDeepModel-7Wnt7J2f.js → defineDeepModel-Dj5kiddM.js} +1 -1
  59. package/dist/{duplicate-template-D2MRCQyw.js → duplicate-template-BZveR-NS.js} +1 -1
  60. package/dist/{feature-DpKd7lle.js → feature-BQvEyCHQ.js} +2 -2
  61. package/dist/{format-time-from-id-B8X8RLUx.js → format-time-from-id-UYQ1CBgS.js} +1 -1
  62. package/dist/{format-unit-display-CHZJt3KC.js → format-unit-display-CQ1_GfD7.js} +12 -12
  63. package/dist/{import-export.helper-B43FydJj.js → import-export.helper-BQzX05Uz.js} +6 -6
  64. package/dist/{index-BJ4vDncB.js → index-BR7TbMo3.js} +1 -1
  65. package/dist/{index-B0oIHF1c.js → index-Cl8hmTng.js} +1 -1
  66. package/dist/{index-Czp03huB.js → index-_01D0wMu.js} +3 -3
  67. package/dist/{inventory-core-dart.default-BSPBfipS.js → inventory-core-dart.default-CI6QYxwh.js} +1 -1
  68. package/dist/{lz-string-DMNv3eY9.js → lz-string-Cgus1m9r.js} +1 -1
  69. package/dist/{netsuite-CcDbi65Q.js → netsuite-B_4mKgIX.js} +2 -2
  70. package/dist/{number-B_MTr0vc.js → number-4BKQ5rh-.js} +3 -3
  71. package/dist/{predefined-templates-Pc4yGHjM.js → predefined-templates-D7WKkFLd.js} +1 -1
  72. package/dist/{purchase-order-template-JSO0KS3Y.js → purchase-order-template-DUBoUweW.js} +1 -1
  73. package/dist/{recalculationUtils-BcLT8Tni.js → recalculationUtils-BH84mZ4R.js} +1 -1
  74. package/dist/{rules-Bx4N50Hy.js → rules-B6dk9lIh.js} +2 -2
  75. package/dist/{stock-Cg7he-jQ.js → stock-C0gv2Jjj.js} +3 -3
  76. package/dist/{stock-BChSnRaw.js → stock-Ftff4rfo.js} +1 -1
  77. package/dist/style.css +1 -1
  78. package/dist/{supplier-DN4GB57K.js → supplier-vofSOPpI.js} +2 -2
  79. package/dist/{surcharge-D2VwZOKf.js → surcharge-BvfJ9o6h.js} +1 -1
  80. package/dist/tsconfig.app.tsbuildinfo +1 -1
  81. package/dist/{uom-rules-gY5GpNIC.js → uom-rules-C6vZoubJ.js} +1 -1
  82. package/dist/{use-ingredient-select-dialog-CZskL7N_.js → use-ingredient-select-dialog-uPfWvBHv.js} +2 -2
  83. package/dist/{use-inventory-binding-dialog-Bfis6BtZ.js → use-inventory-binding-dialog-CTnFGlqD.js} +2 -2
  84. package/dist/{use-template-enabled-locations-CXOwBN9i.js → use-template-enabled-locations-CBVBx989.js} +2 -2
  85. package/dist/{use-transfer-locations-6j-TEBDb.js → use-transfer-locations-DkOE-gfp.js} +2 -2
  86. package/dist/{useHrmPermission-DRvXw4vK.js → useHrmPermission-BnM2nXtN.js} +1 -1
  87. package/dist/{useNavigationMenu-ELSabLvQ.js → useNavigationMenu-By43qVcm.js} +2 -2
  88. package/dist/{useSseClient-DQE-swBN.js → useSseClient-Bc-S6x2L.js} +1 -1
  89. package/dist/{vue-i18n-BjJAVxRm.js → vue-i18n-BWC7Z-GW.js} +375 -375
  90. package/dist/{xlsx.util-CJkboyFg.js → xlsx.util-BQtSWQ_K.js} +2 -2
  91. package/package.json +5 -5
  92. package/dist/App-Dh5a34El.js +0 -1434
@@ -0,0 +1,1465 @@
1
+ import { ref as $, onUnmounted as dt, computed as R, defineComponent as ce, watch as q, onMounted as Fe, resolveComponent as H, createElementBlock as c, openBlock as i, createBlock as pe, createCommentVNode as E, unref as L, createVNode as D, createElementVNode as g, toDisplayString as _, Fragment as z, renderList as ne, withKeys as Me, normalizeClass as se, withModifiers as ft, withCtx as te, createTextVNode as le, h as mt, onBeforeUnmount as pt, nextTick as vt, Teleport as gt, normalizeStyle as yt, withDirectives as ht, vModelText as _t } from "vue";
2
+ import { _ as xt } from "./empty-placeholder-B0QU467o.js";
3
+ import { u as Ke, a as He, R as ue, d as bt, S as wt, b as kt } from "./app-C_rLd-TD.js";
4
+ import { useCoreStore as ge, useI18n as he } from "@feedmepos/mf-common";
5
+ import { useRouter as Ee, useRoute as St } from "vue-router";
6
+ import { u as $t, a as Lt, I as Ct } from "./feature-BQvEyCHQ.js";
7
+ import { u as Rt } from "./netsuite-B_4mKgIX.js";
8
+ import { u as Je } from "./useNavigationMenu-By43qVcm.js";
9
+ import { useBreakpoints as Dt } from "@feedmepos/ui-library";
10
+ import { F as Ne } from "./FmAdminBadge-DlplQOHb.js";
11
+ import { i as It, _ as Ft } from "./FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-CHqV8p8w.js";
12
+ import { F as Et } from "./decimal-DJubI-mF.js";
13
+ import { t as Nt, a as Pt } from "./date2-CcxGrCsx.js";
14
+ import { _ as Tt } from "./_plugin-vue_export-helper-CHgC5LLL.js";
15
+ import { u as Vt } from "./useTabStorage-BkIVScW_.js";
16
+ import { u as Bt } from "./googlemap-D9vA7GsS.js";
17
+ function Ut() {
18
+ return {
19
+ loadingHookInstalled: !1,
20
+ isLoading: !1
21
+ };
22
+ }
23
+ const me = $(Ut());
24
+ function At() {
25
+ const a = Ee();
26
+ if (!me.value.loadingHookInstalled) {
27
+ me.value.loadingHookInstalled = !0;
28
+ const e = a.beforeEach(() => {
29
+ me.value.isLoading = !0;
30
+ }), t = a.afterEach(() => {
31
+ me.value.isLoading = !1;
32
+ });
33
+ dt(() => {
34
+ me.value.loadingHookInstalled = !1, e(), t();
35
+ });
36
+ }
37
+ return {
38
+ get isLoading() {
39
+ return me.value.isLoading;
40
+ }
41
+ };
42
+ }
43
+ function Mt() {
44
+ const { firstAccessibleRouteName: a } = Je();
45
+ return { hasAnyAccessibleInventoryRoute: R(() => a.value !== null) };
46
+ }
47
+ const Ot = {
48
+ key: 0,
49
+ class: "flex flex-col items-center w-full h-full gap-24"
50
+ }, zt = {
51
+ key: 1,
52
+ class: "flex flex-col pt-[200px] gap-32 items-center"
53
+ }, Gt = { class: "flex flex-col gap-12 items-center text-center px-24 max-w-[600px]" }, jt = { class: "fm-typo-en-title-lg-600" }, Kt = { class: "text-fm-color-typo-secondary fm-typo-en-body-md-400" }, Ht = {
54
+ key: 2,
55
+ class: "flex flex-col pt-[200px] gap-32 items-center"
56
+ }, Jt = { class: "flex flex-col gap-12 items-center text-center px-24 max-w-[1000px]" }, Yt = { class: "fm-typo-en-title-lg-600" }, Wt = { class: "text-fm-color-typo-secondary fm-typo-en-body-md-400" }, Xt = { class: "flex gap-16" }, qt = { href: "https://feedme.ai/product/inventory/features?tab=plans_%26_prices" }, Zt = { href: "https://feedme.ai/form" }, Qt = /* @__PURE__ */ ce({
57
+ __name: "InventoryView",
58
+ setup(a) {
59
+ const e = Ke(), t = He(), l = Rt(), s = ge(), o = Ee(), u = At(), r = $t(), { t: v } = he(), { hasAnyAccessibleInventoryRoute: m } = Mt();
60
+ q(
61
+ [() => s.sessionUser.value, () => s.currentBusiness.value],
62
+ ([O, I]) => {
63
+ h(O, I);
64
+ }
65
+ ), Fe(async () => {
66
+ await r.init(), await s.readBusinesses();
67
+ const O = s.sessionUser.value, I = s.currentBusiness.value;
68
+ h(O, I);
69
+ });
70
+ function h(O, I) {
71
+ !O || !I || k();
72
+ }
73
+ async function k() {
74
+ return await e.init(), await l.readSetting().catch((O) => {
75
+ console.error("[all] error on reading netsuite store", O);
76
+ }), await t.init();
77
+ }
78
+ const P = R(() => o.currentRoute.value.name === ue.TRANSFER_TEMPLATE ? r.enablePoTemplate : o.currentRoute.value.name === ue.INGREDIENT_GROUP ? r.enableIngredientGroup : !0), U = R(
79
+ () => o.currentRoute.value.matched.some((O) => {
80
+ var S;
81
+ const I = O.meta, Y = I == null ? void 0 : I.validationManifest;
82
+ return (((S = Y == null ? void 0 : Y.requiredCaslPermissions) == null ? void 0 : S.length) ?? 0) > 0;
83
+ })
84
+ ), oe = R(() => {
85
+ if (!s.sessionUser.value) return !1;
86
+ if (e._locations !== null && e.locations.length === 0) return !0;
87
+ if (!r.isLoaded) return !1;
88
+ const Y = o.currentRoute.value.name === ue.LOADING;
89
+ return !m.value && (Y || U.value);
90
+ });
91
+ return (O, I) => {
92
+ const Y = H("FmSpacer"), S = H("FmCircularProgress"), T = H("FmButton"), G = H("RouterView");
93
+ return i(), c("div", null, [
94
+ L(u).isLoading ? (i(), c("div", Ot, [
95
+ D(Y),
96
+ g("div", null, [
97
+ D(S, { size: "xl" })
98
+ ]),
99
+ I[0] || (I[0] = g("div", { class: "fm-typo-en-body-lg-400 text-fm-color-typo-secondary pl-8" }, "Loading page...", -1)),
100
+ D(Y)
101
+ ])) : oe.value ? (i(), c("div", zt, [
102
+ I[1] || (I[1] = g("img", {
103
+ src: xt,
104
+ alt: "No permission",
105
+ class: "w-[200px] h-[200px]"
106
+ }, null, -1)),
107
+ g("div", Gt, [
108
+ g("div", jt, _(L(v)("inventory.common.noPermission.title")), 1),
109
+ g("div", Kt, _(L(v)("inventory.common.noPermission.description")), 1)
110
+ ])
111
+ ])) : P.value ? L(s).sessionUser.value ? (i(), pe(G, { key: 3 })) : E("", !0) : (i(), c("div", Ht, [
112
+ g("div", Jt, [
113
+ g("div", Yt, _(L(v)("inventory.common.proPlan.title")), 1),
114
+ g("div", Wt, _(L(v)("inventory.common.proPlan.subtitle")), 1)
115
+ ]),
116
+ g("div", Xt, [
117
+ g("a", qt, [
118
+ D(T, {
119
+ label: L(v)("inventory.common.proPlan.comparePlans"),
120
+ variant: "secondary"
121
+ }, null, 8, ["label"])
122
+ ]),
123
+ g("a", Zt, [
124
+ D(T, {
125
+ label: L(v)("inventory.common.proPlan.callUs"),
126
+ "prepend-icon": "call"
127
+ }, null, 8, ["label"])
128
+ ])
129
+ ])
130
+ ]))
131
+ ]);
132
+ };
133
+ }
134
+ }), Ce = {
135
+ // Template/PO item rows carry no id of their own — the embedded sku's _id is
136
+ // the element identity, and kit names the element from that object's name
137
+ // field, so an item change reads "Items › <sku name> › …" instead of a bare
138
+ // index. Arrays where the key isn't usable (an element without sku._id, or
139
+ // duplicates) fall back to identity_fields, then positional — unchanged.
140
+ array_keys: { items: "sku._id" },
141
+ identity_fields: ["_id", "id"],
142
+ name_fields: ["name", "code"],
143
+ ignored_fields: [
144
+ "_id",
145
+ "_rev",
146
+ "_deleted",
147
+ "__v",
148
+ "updatedAt",
149
+ "createdAt",
150
+ "updatedBy",
151
+ "createdBy"
152
+ ],
153
+ label_keys: {
154
+ prefix: "inventory.changelog.label.",
155
+ fields: [
156
+ "abbrev",
157
+ "alternatives",
158
+ "amount",
159
+ "code",
160
+ "contains",
161
+ "conversion",
162
+ "convert",
163
+ "costPerUnit",
164
+ "customAttributes",
165
+ "default",
166
+ "defaultCost",
167
+ "inventoryBindings",
168
+ "isInactive",
169
+ "low",
170
+ "measurement",
171
+ "measurements",
172
+ "mid",
173
+ "name",
174
+ "operationalGroup",
175
+ "precision",
176
+ "priority",
177
+ "recipe",
178
+ "rules",
179
+ "sku",
180
+ "thresholds",
181
+ "trackingMeasurement",
182
+ "type",
183
+ "unit",
184
+ "valuation",
185
+ "version"
186
+ ]
187
+ }
188
+ }, Re = {
189
+ ...Ce,
190
+ array_keys: {
191
+ measurements: "id",
192
+ "unit.measurements": "id",
193
+ "convert.inventoryBindings": "id",
194
+ "convert.inventoryBindings.alternatives": "_id",
195
+ contains: "id",
196
+ "contains.alternatives": "_id"
197
+ }
198
+ };
199
+ function en(a) {
200
+ return a instanceof wt && a.errorResponse.statusCode === 409;
201
+ }
202
+ const _e = bt((a, e) => ({
203
+ /**
204
+ * Commits for one record. recordId is the changelog docId, `${dbName}/${id}`.
205
+ * The dbName scopes the (access-checked) backend route; only the bare id is
206
+ * sent — the backend rebuilds the docId server-side.
207
+ */
208
+ async getRecordChangelog(t, l, s, o) {
209
+ const u = t.indexOf("/");
210
+ if (u < 0) return [];
211
+ const r = t.slice(0, u), v = t.slice(u + 1), m = new URLSearchParams({ id: v });
212
+ l != null && m.set("limit", String(l)), o && m.set("before", o), s && (m.set("explain", "1"), m.set("schema", JSON.stringify(s)));
213
+ const h = `${a.inventoryBackendUrl}/${r}/changelog?${m.toString()}`;
214
+ return await e.get(h);
215
+ },
216
+ /**
217
+ * Purchase orders in a date range, each with when it last changed. The
218
+ * backend joins the orders to their newest commit, so no ids travel and the
219
+ * browser makes one request instead of list-then-ask-for-timestamps.
220
+ */
221
+ async listPurchaseOrders(t, l, s) {
222
+ if (!t) return [];
223
+ const o = new URLSearchParams({ start: l, end: s }), u = `${a.inventoryBackendUrl}/${t}/changelog/purchase-order?${o}`;
224
+ return await e.get(u);
225
+ },
226
+ /**
227
+ * Closing drafts created in a date range, each with when it last changed.
228
+ * Closing groups come back as rows of their own — their submit/approve/
229
+ * reject is recorded against the group document, not its parent.
230
+ */
231
+ async listClosingDrafts(t, l, s) {
232
+ if (!t) return [];
233
+ const o = new URLSearchParams({ start: l, end: s }), u = `${a.inventoryBackendUrl}/${t}/changelog/closing-draft?${o}`;
234
+ return await e.get(u);
235
+ },
236
+ /**
237
+ * A kit-dialect record's whole document, at HEAD or as of (and including)
238
+ * commit `at`. Same dbName/id split as getRecordChangelog. Rejects with a
239
+ * 409 (see isStateConflict) when the record's history predates the kit
240
+ * write path — the backend passthrough for kit httpapi's GET /api/state.
241
+ */
242
+ async getState(t, l, s) {
243
+ const o = new URLSearchParams({ id: l });
244
+ s && o.set("at", s);
245
+ const u = `${a.inventoryBackendUrl}/${t}/changelog/state?${o.toString()}`;
246
+ return await e.get(u);
247
+ },
248
+ /**
249
+ * The domains the browser lists generically, declared in
250
+ * changelog-domains-pkg and served by the backend — a new browsable domain
251
+ * becomes a tab without a portal change. Backends predating the route
252
+ * yield an error the caller treats as "no extra domains".
253
+ */
254
+ async listDomains(t) {
255
+ if (!t) return [];
256
+ const l = `${a.inventoryBackendUrl}/business_${t}/changelog/domains`;
257
+ return await e.get(l);
258
+ },
259
+ /**
260
+ * One generic domain's records, each with when it last changed. Business-
261
+ * scoped: the generic domains are configuration documents of the business
262
+ * db, not of a location.
263
+ */
264
+ async listDomainRecords(t, l) {
265
+ if (!t) return [];
266
+ const s = `${a.inventoryBackendUrl}/business_${t}/changelog/domain/${encodeURIComponent(l)}`;
267
+ return await e.get(s);
268
+ },
269
+ /**
270
+ * One inventory module's records, each with when it last changed. Business-
271
+ * scoped, so the db is `business_<id>` — the same prefixed name the record's
272
+ * own changelog docId carries.
273
+ */
274
+ async listInventory(t, l) {
275
+ if (!t) return [];
276
+ const s = `${a.inventoryBackendUrl}/business_${t}/changelog/inventory?module=${l}`;
277
+ return await e.get(s);
278
+ }
279
+ })), Se = 50;
280
+ function tn() {
281
+ const a = _e(), e = $([]), t = $(!1), l = $(!1);
282
+ let s = null, o = 0;
283
+ async function u(v, m, h) {
284
+ const k = ++o;
285
+ if (s = null, l.value = !1, !v) {
286
+ e.value = [];
287
+ return;
288
+ }
289
+ t.value = !0;
290
+ try {
291
+ const P = m ?? Se, U = await a.getRecordChangelog(v, P, h);
292
+ if (k !== o) return;
293
+ e.value = U, m == null && (s = { recordId: v, explain: h }, l.value = U.length === P);
294
+ } catch (P) {
295
+ throw k === o && (e.value = []), P;
296
+ } finally {
297
+ k === o && (t.value = !1);
298
+ }
299
+ }
300
+ async function r() {
301
+ const v = e.value[e.value.length - 1];
302
+ if (!s || !v || t.value || !l.value) return;
303
+ const m = o;
304
+ t.value = !0;
305
+ try {
306
+ const h = await a.getRecordChangelog(s.recordId, Se, s.explain, v.id);
307
+ if (m !== o) return;
308
+ e.value = [...e.value, ...h], l.value = h.length === Se;
309
+ } finally {
310
+ m === o && (t.value = !1);
311
+ }
312
+ }
313
+ return { commits: e, isLoading: t, hasMore: l, load: u, loadMore: r };
314
+ }
315
+ const Ye = 1e3;
316
+ function nn(a, e) {
317
+ return [...a, ...e].sort((t, l) => l.at.localeCompare(t.at));
318
+ }
319
+ function on() {
320
+ const a = _e(), e = $([]);
321
+ async function t(l) {
322
+ if (e.value = [], !!l)
323
+ try {
324
+ e.value = await a.getRecordChangelog(
325
+ l,
326
+ Ye,
327
+ Re
328
+ );
329
+ } catch (s) {
330
+ console.error("changelog per-entity load failed", s);
331
+ }
332
+ }
333
+ return { commits: e, load: t };
334
+ }
335
+ function We(a) {
336
+ if (!a) return null;
337
+ try {
338
+ const e = JSON.parse(a);
339
+ return typeof (e == null ? void 0 : e.changelogLabelKey) == "string" && typeof (e == null ? void 0 : e.verb) == "string" ? {
340
+ labelKey: e.changelogLabelKey,
341
+ verb: e.verb,
342
+ ...typeof e.name == "string" ? { name: e.name } : {}
343
+ } : null;
344
+ } catch {
345
+ return null;
346
+ }
347
+ }
348
+ function Xe(a) {
349
+ return a.startsWith("inventory.changelog.");
350
+ }
351
+ const qe = "";
352
+ function De(a) {
353
+ const e = a.indexOf(qe);
354
+ return e === -1 ? { raw: a, human: a } : { raw: a.slice(0, e), human: a.slice(e + 1) };
355
+ }
356
+ const an = [
357
+ "inventory.changelog.label.recipe",
358
+ "inventory.changelog.label.sku",
359
+ "inventory.changelog.label.unit"
360
+ ], sn = [...an, "Recipe", "Ingredient", "Unit"];
361
+ function ln(a) {
362
+ const { human: e } = De(a);
363
+ if (!e) return { type: "Document", name: "", field: [] };
364
+ const t = e.split(" › ");
365
+ return t.length >= 2 && sn.includes(t[0]) ? { type: t[0], name: t[1], field: t.slice(2) } : { type: "Document", name: "", field: t };
366
+ }
367
+ const Oe = 800;
368
+ function Ze(a, e, t = 2) {
369
+ const l = ze(a), s = ze(e);
370
+ if (!l || !s) return null;
371
+ let o = 0;
372
+ for (; o < l.length && o < s.length && l[o] === s[o]; ) o++;
373
+ let u = 0;
374
+ for (; u < l.length - o && u < s.length - o && l[l.length - 1 - u] === s[s.length - 1 - u]; )
375
+ u++;
376
+ const r = l.slice(o, l.length - u), v = s.slice(o, s.length - u);
377
+ if (r.length > Oe || v.length > Oe) return null;
378
+ const m = (h) => ({ type: "same", text: h });
379
+ return un(
380
+ [...l.slice(0, o).map(m), ...rn(r, v), ...l.slice(l.length - u).map(m)],
381
+ t
382
+ );
383
+ }
384
+ function ze(a) {
385
+ try {
386
+ const e = JSON.parse(a);
387
+ return e === null || typeof e != "object" ? null : JSON.stringify(e, null, 2).split(`
388
+ `);
389
+ } catch {
390
+ return null;
391
+ }
392
+ }
393
+ function rn(a, e) {
394
+ const t = a.length, l = e.length, s = Array.from({ length: t + 1 }, () => new Uint32Array(l + 1));
395
+ for (let v = t - 1; v >= 0; v--)
396
+ for (let m = l - 1; m >= 0; m--)
397
+ s[v][m] = a[v] === e[m] ? s[v + 1][m + 1] + 1 : Math.max(s[v + 1][m], s[v][m + 1]);
398
+ const o = [];
399
+ let u = 0, r = 0;
400
+ for (; u < t && r < l; )
401
+ a[u] === e[r] ? (o.push({ type: "same", text: a[u] }), u++, r++) : s[u + 1][r] >= s[u][r + 1] ? (o.push({ type: "del", text: a[u] }), u++) : (o.push({ type: "add", text: e[r] }), r++);
402
+ for (; u < t; ) o.push({ type: "del", text: a[u++] });
403
+ for (; r < l; ) o.push({ type: "add", text: e[r++] });
404
+ return o;
405
+ }
406
+ function un(a, e) {
407
+ const t = a.map(() => !1);
408
+ a.forEach((o, u) => {
409
+ if (o.type !== "same")
410
+ for (let r = Math.max(0, u - e); r <= Math.min(a.length - 1, u + e); r++)
411
+ t[r] = !0;
412
+ });
413
+ const l = [];
414
+ let s = !1;
415
+ return a.forEach((o, u) => {
416
+ t[u] ? (l.push(o), s = !1) : s || (l.push({ type: "skip", text: "⋯" }), s = !0);
417
+ }), l;
418
+ }
419
+ function cn(a, e) {
420
+ let t;
421
+ try {
422
+ t = JSON.parse(a);
423
+ } catch {
424
+ return a;
425
+ }
426
+ return t === null ? "—" : typeof t == "number" ? t.toLocaleString() : typeof t == "boolean" ? e(t ? "inventory.changelog.yes" : "inventory.changelog.no") : String(t);
427
+ }
428
+ function Ie(a, e, t = 0, l) {
429
+ var m;
430
+ const s = a.label == null ? void 0 : Xe(a.label) ? e(a.label) : a.label, o = s != null || a.value != null || a.display != null, u = !((m = a.kids) != null && m.length), r = [];
431
+ o && r.push({
432
+ depth: t,
433
+ // A bare array index says nothing a reader needs — a leaf list entry
434
+ // shows just its value. Branch nodes keep the index as their header.
435
+ label: s != null && u && /^\d+$/.test(s) ? void 0 : s,
436
+ text: u ? dn(a, e, l) : void 0,
437
+ bookkeeping: !!a.bookkeeping
438
+ });
439
+ const v = o ? t + 1 : t;
440
+ for (const h of a.kids ?? [])
441
+ r.push(...Ie(h, e, v, l));
442
+ return r;
443
+ }
444
+ function dn(a, e, t) {
445
+ if (a.value == null) return a.display || void 0;
446
+ const l = cn(a.value, e);
447
+ return (t == null ? void 0 : t(l)) ?? a.display ?? l;
448
+ }
449
+ function $e(a, e) {
450
+ return JSON.stringify(a, null, 2).split(`
451
+ `).map((t) => ({ type: e, text: t }));
452
+ }
453
+ function fn() {
454
+ const a = _e(), e = /* @__PURE__ */ new Map(), t = $(!1), l = $(null);
455
+ async function s(o) {
456
+ const u = e.get(o.id);
457
+ if (u) {
458
+ l.value = u;
459
+ return;
460
+ }
461
+ t.value = !0;
462
+ try {
463
+ const r = o.doc_id.indexOf("/"), v = o.doc_id.slice(0, r), m = o.doc_id.slice(r + 1), [h, k] = await Promise.all([
464
+ o.parent ? a.getState(v, m, o.parent) : Promise.resolve({}),
465
+ a.getState(v, m, o.id)
466
+ ]), U = { diff: o.parent ? Ze(JSON.stringify(h), JSON.stringify(k)) ?? [
467
+ ...$e(h, "del"),
468
+ ...$e(k, "add")
469
+ ] : $e(k, "add"), conflict: !1 };
470
+ e.set(o.id, U), l.value = U;
471
+ } catch (r) {
472
+ if (!en(r))
473
+ throw l.value = null, r;
474
+ const v = { diff: null, conflict: !0 };
475
+ e.set(o.id, v), l.value = v;
476
+ } finally {
477
+ t.value = !1;
478
+ }
479
+ }
480
+ return { isLoading: t, result: l, load: s };
481
+ }
482
+ const mn = {
483
+ key: 0,
484
+ class: "flex justify-center p-16"
485
+ }, pn = {
486
+ key: 1,
487
+ class: "p-16 text-center text-gray-500"
488
+ }, vn = {
489
+ key: 2,
490
+ class: "flex h-full min-h-0 gap-8"
491
+ }, gn = { class: "w-1/3 shrink-0 overflow-y-auto border-r border-gray-200 pr-4" }, yn = ["onClick", "onKeydown"], hn = { class: "fm-typo-en-body-md-600" }, _n = { class: "text-xs text-gray-500" }, xn = {
492
+ key: 0,
493
+ class: "flex-1 overflow-y-auto pl-4"
494
+ }, bn = { class: "mb-12 flex flex-col gap-2 border-b border-gray-200 pb-8" }, wn = { class: "flex flex-wrap items-center gap-8" }, kn = { class: "fm-typo-en-body-lg-600" }, Sn = {
495
+ key: 0,
496
+ class: "rounded-full bg-gray-100 px-8 text-xs text-gray-500"
497
+ }, $n = { class: "text-xs text-gray-500" }, Ln = { class: "mb-12" }, Cn = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary pl-8" }, Rn = {
498
+ key: 0,
499
+ class: "mb-12"
500
+ }, Dn = {
501
+ key: 1,
502
+ class: "text-sm text-gray-400"
503
+ }, In = {
504
+ key: 2,
505
+ class: "w-full overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
506
+ }, Fn = {
507
+ key: 0,
508
+ class: "text-xs text-gray-400"
509
+ }, En = { class: "fm-typo-en-body-md-600" }, Nn = { class: "flex flex-col gap-6" }, Pn = {
510
+ key: 0,
511
+ class: "text-gray-700"
512
+ }, Tn = { class: "min-w-[120px] shrink-0 text-gray-500" }, Vn = {
513
+ key: 0,
514
+ class: "flex w-full flex-col gap-4"
515
+ }, Bn = {
516
+ key: 0,
517
+ class: "w-full overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
518
+ }, Un = { key: 0 }, An = { key: 1 }, Mn = {
519
+ key: 1,
520
+ class: "w-full overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
521
+ }, On = { key: 0 }, zn = { key: 1 }, Gn = {
522
+ key: 1,
523
+ class: "w-full overflow-x-auto rounded border border-gray-200 py-4 font-mono text-xs"
524
+ }, jn = {
525
+ key: 2,
526
+ class: "flex w-full flex-wrap items-baseline gap-4"
527
+ }, Kn = {
528
+ key: 0,
529
+ class: "rounded bg-red-50 px-4 text-red-700"
530
+ }, Hn = {
531
+ key: 1,
532
+ class: "text-gray-400"
533
+ }, Jn = {
534
+ key: 2,
535
+ class: "rounded bg-green-50 px-4 text-green-700"
536
+ }, Yn = {
537
+ key: 1,
538
+ class: "text-sm text-gray-500"
539
+ }, Wn = {
540
+ key: 2,
541
+ class: "mt-16 break-all border-t border-gray-200 pt-8 font-mono text-xs text-gray-400"
542
+ }, Xn = { key: 0 }, qn = "capture baseline", Zn = /* @__PURE__ */ ce({
543
+ __name: "ChangelogPanel",
544
+ props: {
545
+ commits: {},
546
+ isLoading: { type: Boolean },
547
+ resolveName: { type: Function }
548
+ },
549
+ setup(a) {
550
+ const e = a, { t } = he(), l = $(null), s = R(
551
+ () => e.commits.find((p) => p.id === l.value)
552
+ ), o = /* @__PURE__ */ new Set(["updatedAt", "createdAt", "updatedBy", "createdBy", "_rev"]), u = R(() => {
553
+ var b;
554
+ return (((b = s.value) == null ? void 0 : b.changes) ?? []).filter((B) => {
555
+ const { raw: V } = De(B.path);
556
+ return V === "@payload" || B.from == null && B.to == null ? !1 : !V.split(".").some((W) => o.has(W));
557
+ });
558
+ });
559
+ q(
560
+ () => e.commits,
561
+ (p) => {
562
+ var b;
563
+ p.find((B) => B.id === l.value) || (l.value = ((b = p[0]) == null ? void 0 : b.id) ?? null);
564
+ },
565
+ { immediate: !0 }
566
+ );
567
+ const r = $(!1), { isLoading: v, result: m, load: h } = fn();
568
+ q([r, s], ([p, b]) => {
569
+ m.value = null, !(!p || !b) && h(b).catch((B) => {
570
+ console.error("changelog snapshot load failed", B), r.value = !1;
571
+ });
572
+ });
573
+ function k(p) {
574
+ return p ? p.slice(0, 8) : "";
575
+ }
576
+ function P(p) {
577
+ return p ? new Date(p).toLocaleString() : "";
578
+ }
579
+ function U(p) {
580
+ if (p == null) return "";
581
+ let b;
582
+ try {
583
+ b = JSON.parse(p);
584
+ } catch {
585
+ return p;
586
+ }
587
+ return b === null ? "—" : typeof b == "string" ? b : typeof b == "number" ? b.toLocaleString() : typeof b == "boolean" ? t(b ? "inventory.changelog.yes" : "inventory.changelog.no") : JSON.stringify(b, null, 2);
588
+ }
589
+ function oe(p) {
590
+ return (p.authors || []).join(", ") || t("inventory.changelog.unknownActor");
591
+ }
592
+ function O(p) {
593
+ if (p.message === qn) return t("inventory.changelog.captureBaseline");
594
+ const b = We(p.message);
595
+ if (!b) return p.message || t("inventory.changelog.noMessage");
596
+ const B = I(b.labelKey);
597
+ return b.name ? t(`inventory.changelog.message.${b.verb}`, { module: B, name: b.name }) : t(`inventory.changelog.message.${b.verb}NoName`, { module: B });
598
+ }
599
+ function I(p) {
600
+ return Xe(p) ? t(p) : p;
601
+ }
602
+ const Y = (p) => /[^a-zA-Z]/.test(p);
603
+ function S(p, b) {
604
+ return p == null || b == null ? null : Ze(p, b);
605
+ }
606
+ function T(p) {
607
+ if (!(!p.to_value && !p.from_value))
608
+ return {
609
+ toTree: p.to_value ? Ie(p.to_value, t, 0, e.resolveName) : void 0,
610
+ fromTree: p.from_value ? Ie(p.from_value, t, 0, e.resolveName) : void 0
611
+ };
612
+ }
613
+ function G(p) {
614
+ return p === "add" ? "bg-green-50 text-green-700" : p === "del" ? "bg-red-50 text-red-700" : p === "skip" ? "text-gray-400" : "text-gray-600";
615
+ }
616
+ function j(p) {
617
+ return p.type === "skip" ? p.text : (p.type === "add" ? "+ " : p.type === "del" ? "- " : " ") + p.text;
618
+ }
619
+ const Q = R(() => {
620
+ const p = /* @__PURE__ */ new Map(), b = [], B = (y, f) => {
621
+ let F = p.get(y);
622
+ return F || (F = f(), p.set(y, F), b.push(F)), F;
623
+ }, V = () => B("@doc", () => ({ header: "", lines: [] })), W = (y, f) => {
624
+ var N;
625
+ if (y == null) return f;
626
+ let F;
627
+ try {
628
+ F = JSON.parse(y);
629
+ } catch {
630
+ F = y;
631
+ }
632
+ return (typeof F == "string" ? (N = e.resolveName) == null ? void 0 : N.call(e, F) : void 0) ?? f;
633
+ }, K = (y, f, F) => {
634
+ var N, J, Z, ee;
635
+ const x = T(f);
636
+ x ? y.lines.push({ label: F, ...x }) : f.from != null && f.to != null ? y.lines.push({
637
+ label: F,
638
+ from: f.from,
639
+ to: f.to,
640
+ diff: S(f.from, f.to),
641
+ fromDisplay: W(f.from, (N = f.display) == null ? void 0 : N.from),
642
+ toDisplay: W(f.to, (J = f.display) == null ? void 0 : J.to)
643
+ }) : f.to != null ? y.lines.push({ label: F, to: f.to, toDisplay: W(f.to, (Z = f.display) == null ? void 0 : Z.to) }) : y.lines.push({ label: F, from: f.from, fromDisplay: W(f.from, (ee = f.display) == null ? void 0 : ee.from) });
644
+ }, C = (y) => {
645
+ var F;
646
+ const f = y.element;
647
+ if (f) {
648
+ const x = B(`kit:${(f.trail ?? []).join(".")}:${f.id ?? ""}`, () => ({
649
+ kind: (f.trail ?? []).map(I).join(" › "),
650
+ header: f.name || f.id || "",
651
+ lines: []
652
+ }));
653
+ if ((F = y.field) != null && F.length)
654
+ K(x, y, y.field.map(I).join(" › "));
655
+ else {
656
+ x.badge = y.to != null ? "added" : "removed";
657
+ const N = T(y);
658
+ N && x.lines.push(N);
659
+ }
660
+ return;
661
+ }
662
+ K(V(), y, (y.field ?? []).map(I).join(" › "));
663
+ };
664
+ for (const y of u.value) {
665
+ const { raw: f, human: F } = De(y.path);
666
+ if (y.kind === "create" && !f) {
667
+ const Z = T(y);
668
+ V().lines.push(
669
+ Z ? { label: t("inventory.changelog.kind.created"), ...Z } : { text: t("inventory.changelog.kind.created") }
670
+ );
671
+ continue;
672
+ }
673
+ if (!y.path.includes(qe) && (y.field || y.element)) {
674
+ C(y);
675
+ continue;
676
+ }
677
+ const x = f ? f.split(".") : [], N = F ? F.split(" › ") : [], J = x.findIndex((Z, ee) => ee > 0 && Y(Z));
678
+ if (J > 0 && N.length === x.length) {
679
+ const Z = N[J], ee = B(x.slice(0, J + 1).join("."), () => ({
680
+ kind: N.slice(0, J).map(I).join(" › "),
681
+ header: Z,
682
+ lines: []
683
+ })), re = N.slice(J + 1).map(I).join(" › ");
684
+ if (re) K(ee, y, re);
685
+ else if (y.from != null && y.to != null) K(ee, y, Z);
686
+ else {
687
+ ee.badge = y.to != null ? "added" : "removed";
688
+ const de = T(y);
689
+ de && ee.lines.push(de);
690
+ }
691
+ continue;
692
+ }
693
+ K(V(), y, N.map(I).join(" › "));
694
+ }
695
+ return b;
696
+ });
697
+ return (p, b) => {
698
+ var W, K;
699
+ const B = H("FmCircularProgress"), V = H("FmSwitch");
700
+ return p.isLoading ? (i(), c("div", mn, [
701
+ D(B)
702
+ ])) : p.commits.length ? (i(), c("div", vn, [
703
+ g("ol", gn, [
704
+ (i(!0), c(z, null, ne(p.commits, (C) => (i(), c("li", {
705
+ key: C.id,
706
+ role: "button",
707
+ tabindex: "0",
708
+ class: se([
709
+ "cursor-pointer border-l-2 py-8 pl-12",
710
+ C.id === l.value ? "border-fm-color-primary bg-fm-color-primary-50" : "border-gray-200 hover:bg-gray-50"
711
+ ]),
712
+ onClick: (y) => l.value = C.id,
713
+ onKeydown: [
714
+ Me((y) => l.value = C.id, ["enter"]),
715
+ Me(ft((y) => l.value = C.id, ["prevent"]), ["space"])
716
+ ]
717
+ }, [
718
+ g("div", hn, _(O(C)), 1),
719
+ g("div", _n, _(oe(C)) + " · " + _(P(C.at)) + " · " + _(k(C.id)), 1)
720
+ ], 42, yn))), 128))
721
+ ]),
722
+ s.value ? (i(), c("div", xn, [
723
+ g("div", bn, [
724
+ g("div", wn, [
725
+ g("div", kn, _(O(s.value)), 1),
726
+ s.value.parent ? E("", !0) : (i(), c("span", Sn, _(L(t)("inventory.changelog.rootCommit")), 1))
727
+ ]),
728
+ g("div", $n, _(oe(s.value)) + " · " + _(P(s.value.at)), 1)
729
+ ]),
730
+ g("div", Ln, [
731
+ D(Ne, null, {
732
+ default: te(() => [
733
+ g("span", Cn, _(L(t)("inventory.changelog.dataDiff")), 1),
734
+ D(V, {
735
+ modelValue: r.value,
736
+ "onUpdate:modelValue": b[0] || (b[0] = (C) => r.value = C)
737
+ }, null, 8, ["modelValue"])
738
+ ]),
739
+ _: 1
740
+ })
741
+ ]),
742
+ r.value ? (i(), c("div", Rn, [
743
+ L(v) ? (i(), pe(B, { key: 0 })) : (W = L(m)) != null && W.conflict ? (i(), c("div", Dn, _(L(t)("inventory.changelog.snapshotUnavailable")), 1)) : (K = L(m)) != null && K.diff ? (i(), c("div", In, [
744
+ (i(!0), c(z, null, ne(L(m).diff, (C, y) => (i(), c("div", {
745
+ key: y,
746
+ class: se(["whitespace-pre px-4", G(C.type)])
747
+ }, _(j(C)), 3))), 128))
748
+ ])) : E("", !0)
749
+ ])) : E("", !0),
750
+ (i(!0), c(z, null, ne(Q.value, (C, y) => (i(), c("div", {
751
+ key: y,
752
+ class: "mb-12 rounded-lg border border-gray-200 p-12"
753
+ }, [
754
+ C.kind || C.header || C.badge ? (i(), c("div", {
755
+ key: 0,
756
+ class: se(["flex flex-wrap items-baseline gap-8", C.lines.length ? "mb-8" : ""])
757
+ }, [
758
+ C.kind ? (i(), c("span", Fn, _(C.kind), 1)) : E("", !0),
759
+ g("span", En, _(C.header), 1),
760
+ C.badge ? (i(), c("span", {
761
+ key: 1,
762
+ class: se(["rounded-full px-8 text-xs", C.badge === "added" ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"])
763
+ }, _(C.badge === "added" ? L(t)("inventory.changelog.added") : L(t)("inventory.changelog.kind.removed")), 3)) : E("", !0)
764
+ ], 2)) : E("", !0),
765
+ g("ul", Nn, [
766
+ (i(!0), c(z, null, ne(C.lines, (f, F) => (i(), c("li", {
767
+ key: F,
768
+ class: "flex flex-wrap items-baseline gap-8 text-sm"
769
+ }, [
770
+ f.text ? (i(), c("span", Pn, _(f.text), 1)) : (i(), c(z, { key: 1 }, [
771
+ g("span", Tn, _(f.label), 1),
772
+ f.toTree || f.fromTree ? (i(), c("div", Vn, [
773
+ f.fromTree ? (i(), c("div", Bn, [
774
+ (i(!0), c(z, null, ne(f.fromTree, (x, N) => (i(), c("div", {
775
+ key: N,
776
+ class: se(["flex items-baseline gap-4 px-4", x.bookkeeping ? "text-gray-400" : "text-red-700"])
777
+ }, [
778
+ (i(!0), c(z, null, ne(x.depth, (J) => (i(), c("span", {
779
+ key: J,
780
+ class: "inline-block w-16"
781
+ }))), 128)),
782
+ x.label ? (i(), c("span", Un, [
783
+ le(_(x.label), 1),
784
+ x.text ? (i(), c(z, { key: 0 }, [
785
+ le(":")
786
+ ], 64)) : E("", !0)
787
+ ])) : E("", !0),
788
+ x.text ? (i(), c("span", An, _(x.text), 1)) : E("", !0)
789
+ ], 2))), 128))
790
+ ])) : E("", !0),
791
+ f.toTree ? (i(), c("div", Mn, [
792
+ (i(!0), c(z, null, ne(f.toTree, (x, N) => (i(), c("div", {
793
+ key: N,
794
+ class: se(["flex items-baseline gap-4 px-4", x.bookkeeping ? "text-gray-400" : "text-green-700"])
795
+ }, [
796
+ (i(!0), c(z, null, ne(x.depth, (J) => (i(), c("span", {
797
+ key: J,
798
+ class: "inline-block w-16"
799
+ }))), 128)),
800
+ x.label ? (i(), c("span", On, [
801
+ le(_(x.label), 1),
802
+ x.text ? (i(), c(z, { key: 0 }, [
803
+ le(":")
804
+ ], 64)) : E("", !0)
805
+ ])) : E("", !0),
806
+ x.text ? (i(), c("span", zn, _(x.text), 1)) : E("", !0)
807
+ ], 2))), 128))
808
+ ])) : E("", !0)
809
+ ])) : f.diff ? (i(), c("div", Gn, [
810
+ (i(!0), c(z, null, ne(f.diff, (x, N) => (i(), c("div", {
811
+ key: N,
812
+ class: se(["whitespace-pre px-4", G(x.type)])
813
+ }, _(j(x)), 3))), 128))
814
+ ])) : (i(), c("span", jn, [
815
+ f.from != null ? (i(), c("span", Kn, _(f.fromDisplay ?? U(f.from)), 1)) : E("", !0),
816
+ f.from != null && f.to != null ? (i(), c("span", Hn, "→")) : E("", !0),
817
+ f.to != null ? (i(), c("span", Jn, _(f.toDisplay ?? U(f.to)), 1)) : E("", !0)
818
+ ]))
819
+ ], 64))
820
+ ]))), 128))
821
+ ])
822
+ ]))), 128)),
823
+ Q.value.length ? E("", !0) : (i(), c("div", Yn, _(L(t)("inventory.changelog.empty")), 1)),
824
+ r.value ? (i(), c("div", Wn, [
825
+ le(_(s.value.id) + " ", 1),
826
+ s.value.parent ? (i(), c("span", Xn, "← " + _(s.value.parent), 1)) : E("", !0)
827
+ ])) : E("", !0)
828
+ ])) : E("", !0)
829
+ ])) : (i(), c("div", pn, _(L(t)("inventory.changelog.empty")), 1));
830
+ };
831
+ }
832
+ }), Qn = { class: "flex flex-col gap-8" }, eo = { class: "flex flex-wrap items-center gap-16" }, to = { class: "fm-typo-en-heading-lg-600" }, no = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, oo = { class: "flex h-full min-h-0 flex-col gap-12 p-16" }, ao = { class: "flex flex-wrap items-center gap-12" }, so = { class: "flex shrink-0 items-center gap-8" }, lo = { class: "fm-typo-en-body-md-400 text-fm-color-typo-secondary" }, ro = { class: "flex flex-wrap items-center gap-12" }, io = {
833
+ key: 0,
834
+ class: "fm-typo-en-body-md-600"
835
+ }, uo = { class: "fm-typo-en-heading-md-600" }, co = {
836
+ key: 0,
837
+ class: "flex justify-center py-8"
838
+ }, Le = "inventory.changelog.label.", fo = /* @__PURE__ */ ce({
839
+ __name: "ChangelogDialog",
840
+ props: {
841
+ modelValue: { type: Boolean }
842
+ },
843
+ emits: ["update:modelValue"],
844
+ setup(a, { emit: e }) {
845
+ const t = a, l = e, s = R({
846
+ get: () => t.modelValue,
847
+ set: (n) => l("update:modelValue", n)
848
+ }), { t: o } = he(), u = ge(), r = He(), v = Ke(), m = _e(), { breakpoints: h } = Dt(), k = R(() => h.value.xs || h.value.sm), P = R(() => k.value ? "98vw" : "72vw"), { commits: U, isLoading: oe, hasMore: O, load: I, loadMore: Y } = tn();
849
+ function S() {
850
+ Y().catch((n) => console.error("changelog load more failed", n));
851
+ }
852
+ function T(n) {
853
+ return n ? new Date(n).toLocaleString() : "—";
854
+ }
855
+ function G(n) {
856
+ return [...n].sort((d, w) => (w.lastUpdate ?? "").localeCompare(d.lastUpdate ?? ""));
857
+ }
858
+ function j(n, d, w) {
859
+ I(n, d, w).catch((A) => console.error("changelog load failed", A));
860
+ }
861
+ const Q = $([]);
862
+ async function p() {
863
+ var d;
864
+ const n = (d = u.currentBusiness.value) == null ? void 0 : d._id;
865
+ if (n)
866
+ try {
867
+ Q.value = await m.listDomains(n);
868
+ } catch (w) {
869
+ console.error("changelog domain list load failed", w), Q.value = [];
870
+ }
871
+ }
872
+ const b = R(() => [
873
+ { label: o("inventory.changelog.label.purchaseOrder"), value: "purchaseOrder" },
874
+ { label: o("inventory.changelog.label.closingDraft"), value: "closingDraft" },
875
+ { label: o("inventory.changelog.domainInventory"), value: "inventory" },
876
+ ...Q.value.map((n) => ({ label: o(n.labelKey), value: n.domain }))
877
+ ]), B = $(b.value[0]), V = R(() => {
878
+ var n;
879
+ return ((n = B.value) == null ? void 0 : n.value) ?? "purchaseOrder";
880
+ }), W = R(
881
+ () => Q.value.some((n) => n.domain === V.value)
882
+ ), K = $(!1), C = R(
883
+ () => ["sku", "recipe", "unit"].map((n) => ({
884
+ label: o(Le + n),
885
+ value: n
886
+ }))
887
+ ), y = $(C.value[0]), f = R(() => {
888
+ var n;
889
+ return ((n = y.value) == null ? void 0 : n.value) ?? "sku";
890
+ }), F = $(""), x = $(null), N = $(!1), J = R(() => {
891
+ var w;
892
+ const n = (w = u.currentBusiness.value) == null ? void 0 : w._id, d = r.inventory._id;
893
+ return n && d ? `business_${n}/${d}` : "";
894
+ }), Z = R(() => {
895
+ const n = /* @__PURE__ */ new Map(), d = r.inventory;
896
+ for (const w of [d.sku, d.recipe, d.unit, d.skuGroup])
897
+ for (const A of w ?? [])
898
+ A._id && A.name && n.set(A._id, A.name);
899
+ for (const w of d.unit ?? [])
900
+ for (const A of w.measurements ?? []) {
901
+ if (!A.id) continue;
902
+ const X = A.abbrev || A.name;
903
+ if (!X) continue;
904
+ const ae = Et.toDouble(A.conversion);
905
+ n.set(A.id, ae ? `${X} (1 ${X} = ${ae} ${w.abbrev})` : X);
906
+ }
907
+ return n;
908
+ }), ee = (n) => Z.value.get(n), re = $([]), de = $(!1);
909
+ async function Pe() {
910
+ var d;
911
+ const n = (d = u.currentBusiness.value) == null ? void 0 : d._id;
912
+ if (n) {
913
+ de.value = !0;
914
+ try {
915
+ re.value = G(
916
+ await m.listInventory(n, f.value)
917
+ );
918
+ } catch (w) {
919
+ console.error("changelog inventory list load failed", w), re.value = [];
920
+ } finally {
921
+ de.value = !1;
922
+ }
923
+ }
924
+ }
925
+ const Qe = R(
926
+ () => N.value ? re.value : re.value.filter((n) => !n.deleted)
927
+ ), et = R(() => [
928
+ { accessorKey: "id", header: () => o("inventory.closing.draft.table.id"), size: 320 },
929
+ {
930
+ id: "name",
931
+ header: () => o("inventory.common.name"),
932
+ accessorFn: (n) => n.name,
933
+ // Deleted records sit in the same list as live ones, so the row says which
934
+ // it is; nothing else distinguishes them.
935
+ cell: ({ row: n }) => n.original.deleted ? mt(
936
+ "span",
937
+ { "data-deleted": "" },
938
+ `${n.original.name} (${o("inventory.changelog.deleted")})`
939
+ ) : n.original.name
940
+ },
941
+ {
942
+ id: "lastUpdate",
943
+ header: () => o("inventory.changelog.column.lastUpdate"),
944
+ size: 200,
945
+ // Raw ISO is the sort key — clicking the header on formatted dates would
946
+ // order them lexicographically by locale string. Formatted only to display.
947
+ accessorFn: (n) => n.lastUpdate ?? "",
948
+ cell: ({ getValue: n }) => T(n() || void 0)
949
+ }
950
+ ]), { commits: tt, load: nt } = on();
951
+ function ot(n) {
952
+ x.value = n, K.value = !0, j(J.value, Ye, Re), n.id && nt(`${J.value}/${f.value}/${n.id}`).catch(
953
+ (d) => console.error("changelog per-entity load failed", d)
954
+ );
955
+ }
956
+ function at(n, d) {
957
+ const w = We(n.message);
958
+ return w && w.labelKey === Le + f.value && w.name === d.name ? !0 : (n.changes ?? []).some((A) => {
959
+ const X = ln(A.path);
960
+ return X.type === Le + f.value && X.name === d.name;
961
+ });
962
+ }
963
+ const st = R(() => {
964
+ const n = x.value;
965
+ if (!n) return [];
966
+ const d = U.value.filter((w) => at(w, n));
967
+ return nn(d, tt.value);
968
+ }), xe = $([]), be = $(!1), we = $(null);
969
+ async function lt() {
970
+ var d;
971
+ const n = (d = u.currentBusiness.value) == null ? void 0 : d._id;
972
+ if (n) {
973
+ be.value = !0;
974
+ try {
975
+ xe.value = G(
976
+ await m.listDomainRecords(n, V.value)
977
+ );
978
+ } catch (w) {
979
+ console.error("changelog domain records load failed", w), xe.value = [];
980
+ } finally {
981
+ be.value = !1;
982
+ }
983
+ }
984
+ }
985
+ function rt(n) {
986
+ var w;
987
+ const d = (w = u.currentBusiness.value) == null ? void 0 : w._id;
988
+ d && (we.value = n, K.value = !0, j(`business_${d}/${n.id}`, void 0, Ce));
989
+ }
990
+ const ve = $(It()), ye = $([]), ke = $(!1), fe = $(null), Te = R(() => {
991
+ const n = v._currentLocation;
992
+ return n ? `${n.name} (${n.doc.profile.code ?? "--"})` : "";
993
+ }), Ve = R(() => [
994
+ { accessorKey: "id", header: () => o("inventory.closing.draft.table.id"), size: 320 },
995
+ {
996
+ accessorKey: "name",
997
+ header: () => V.value === "purchaseOrder" ? o("inventory.changelog.column.seq") : o("inventory.common.name"),
998
+ size: 240
999
+ },
1000
+ {
1001
+ id: "lastUpdate",
1002
+ header: () => o("inventory.changelog.column.lastUpdate"),
1003
+ size: 200,
1004
+ // Raw ISO is the sort key; see the note on the inventory table.
1005
+ accessorFn: (n) => n.lastUpdate ?? "",
1006
+ cell: ({ getValue: n }) => T(n() || void 0)
1007
+ }
1008
+ ]);
1009
+ async function Be() {
1010
+ var A;
1011
+ const n = (A = v._currentLocation) == null ? void 0 : A.dbName;
1012
+ if (!n) return;
1013
+ const d = Nt(new Date(ve.value.startDate)).toISOString(), w = Pt(new Date(ve.value.endDate)).toISOString();
1014
+ ke.value = !0;
1015
+ try {
1016
+ ye.value = G(
1017
+ V.value === "purchaseOrder" ? await m.listPurchaseOrders(n, d, w) : await m.listClosingDrafts(n, d, w)
1018
+ );
1019
+ } catch (X) {
1020
+ console.error("changelog location list load failed", X), ye.value = [];
1021
+ } finally {
1022
+ ke.value = !1;
1023
+ }
1024
+ fe.value && !ye.value.find((X) => {
1025
+ var ae;
1026
+ return X.id === ((ae = fe.value) == null ? void 0 : ae.id);
1027
+ }) && (fe.value = null, j(""));
1028
+ }
1029
+ function it(n) {
1030
+ fe.value = n, K.value = !0, j(`${v.currentLocationDBName}/${n.id}`, void 0, Ce);
1031
+ }
1032
+ const ut = R(() => {
1033
+ var n, d, w;
1034
+ return V.value === "inventory" ? ((n = x.value) == null ? void 0 : n.name) ?? "" : W.value ? ((d = we.value) == null ? void 0 : d.name) ?? "" : ((w = fe.value) == null ? void 0 : w.name) ?? "";
1035
+ });
1036
+ function Ue() {
1037
+ K.value = !1, V.value === "inventory" ? (x.value = null, N.value = !1, j(""), Pe().catch(
1038
+ (n) => console.error("changelog inventory list failed", n)
1039
+ )) : W.value ? (we.value = null, j(""), lt().catch(
1040
+ (n) => console.error("changelog domain records failed", n)
1041
+ )) : (fe.value = null, j(""), Be().catch((n) => console.error("changelog location list failed", n)));
1042
+ }
1043
+ return q(s, (n) => {
1044
+ n && (p().catch((d) => console.error("changelog domain list failed", d)), Ue());
1045
+ }), q(V, () => {
1046
+ s.value && Ue();
1047
+ }), q(ve, () => {
1048
+ s.value && V.value !== "inventory" && !W.value && Be().catch((n) => console.error("changelog location list failed", n));
1049
+ }), q(N, (n) => {
1050
+ var d;
1051
+ !n && ((d = x.value) != null && d.deleted) && (x.value = null, K.value = !1);
1052
+ }), q(f, () => {
1053
+ x.value = null, K.value = !1, s.value && V.value === "inventory" && Pe().catch(
1054
+ (n) => console.error("changelog inventory list failed", n)
1055
+ );
1056
+ }), q(J, (n) => {
1057
+ x.value = null, s.value && V.value === "inventory" && j(n, void 0, Re);
1058
+ }), (n, d) => {
1059
+ const w = H("FmButtonGroup"), A = H("FmSearch"), X = H("FmSwitch"), ae = H("FmTable"), Ae = H("FmDialog"), ct = H("FmButton");
1060
+ return i(), c(z, null, [
1061
+ D(Ae, {
1062
+ modelValue: s.value,
1063
+ "onUpdate:modelValue": d[8] || (d[8] = (M) => s.value = M),
1064
+ "close-button": "",
1065
+ "dismiss-away": "",
1066
+ "min-width": "98vw",
1067
+ "max-width": "98vw",
1068
+ "max-height": "94vh",
1069
+ "content-class": "!p-0 h-[86vh]"
1070
+ }, {
1071
+ "dialog-header": te(() => [
1072
+ g("div", Qn, [
1073
+ g("div", eo, [
1074
+ g("div", to, _(L(o)("inventory.changelog.title")), 1),
1075
+ D(w, {
1076
+ modelValue: B.value,
1077
+ "onUpdate:modelValue": d[0] || (d[0] = (M) => B.value = M),
1078
+ items: b.value
1079
+ }, null, 8, ["modelValue", "items"])
1080
+ ]),
1081
+ g("div", no, _(L(o)("inventory.changelog.scopeDescription")), 1)
1082
+ ])
1083
+ ]),
1084
+ default: te(() => [
1085
+ g("div", oo, [
1086
+ V.value === "inventory" ? (i(), c(z, { key: 0 }, [
1087
+ g("div", ao, [
1088
+ D(w, {
1089
+ modelValue: y.value,
1090
+ "onUpdate:modelValue": d[1] || (d[1] = (M) => y.value = M),
1091
+ items: C.value
1092
+ }, null, 8, ["modelValue", "items"]),
1093
+ D(A, {
1094
+ modelValue: F.value,
1095
+ "onUpdate:modelValue": d[2] || (d[2] = (M) => F.value = M),
1096
+ class: "flex-1",
1097
+ placeholder: L(o)("inventory.changelog.searchInventory")
1098
+ }, null, 8, ["modelValue", "placeholder"]),
1099
+ g("div", so, [
1100
+ g("span", lo, _(L(o)("inventory.changelog.includeDeleted")), 1),
1101
+ D(X, {
1102
+ modelValue: N.value,
1103
+ "onUpdate:modelValue": d[3] || (d[3] = (M) => N.value = M)
1104
+ }, null, 8, ["modelValue"])
1105
+ ])
1106
+ ]),
1107
+ D(ae, {
1108
+ class: "min-h-0 flex-1",
1109
+ "row-data": Qe.value,
1110
+ "column-defs": et.value,
1111
+ "search-value": F.value,
1112
+ loading: de.value,
1113
+ "page-size": 20,
1114
+ onRowClick: d[4] || (d[4] = (M) => ot(M.original))
1115
+ }, null, 8, ["row-data", "column-defs", "search-value", "loading"])
1116
+ ], 64)) : W.value ? (i(), pe(ae, {
1117
+ key: 1,
1118
+ class: "min-h-0 flex-1",
1119
+ "row-data": xe.value,
1120
+ "column-defs": Ve.value,
1121
+ loading: be.value,
1122
+ "page-size": 20,
1123
+ onRowClick: d[5] || (d[5] = (M) => rt(M.original))
1124
+ }, null, 8, ["row-data", "column-defs", "loading"])) : (i(), c(z, { key: 2 }, [
1125
+ g("div", ro, [
1126
+ D(Ft, {
1127
+ modelValue: ve.value,
1128
+ "onUpdate:modelValue": d[6] || (d[6] = (M) => ve.value = M)
1129
+ }, null, 8, ["modelValue"]),
1130
+ Te.value ? (i(), c("span", io, _(Te.value), 1)) : E("", !0)
1131
+ ]),
1132
+ D(ae, {
1133
+ class: "min-h-0 flex-1",
1134
+ "row-data": ye.value,
1135
+ "column-defs": Ve.value,
1136
+ loading: ke.value,
1137
+ "page-size": 20,
1138
+ onRowClick: d[7] || (d[7] = (M) => it(M.original))
1139
+ }, null, 8, ["row-data", "column-defs", "loading"])
1140
+ ], 64))
1141
+ ])
1142
+ ]),
1143
+ _: 1
1144
+ }, 8, ["modelValue"]),
1145
+ D(Ae, {
1146
+ modelValue: K.value,
1147
+ "onUpdate:modelValue": d[9] || (d[9] = (M) => K.value = M),
1148
+ "close-button": "",
1149
+ "dismiss-away": "",
1150
+ "min-width": P.value,
1151
+ "max-width": P.value,
1152
+ "max-height": "86vh"
1153
+ }, {
1154
+ "dialog-header": te(() => [
1155
+ g("div", uo, _(ut.value), 1)
1156
+ ]),
1157
+ default: te(() => [
1158
+ D(Zn, {
1159
+ commits: V.value === "inventory" ? st.value : L(U),
1160
+ "is-loading": L(oe),
1161
+ "resolve-name": ee
1162
+ }, null, 8, ["commits", "is-loading"]),
1163
+ V.value !== "inventory" && L(O) ? (i(), c("div", co, [
1164
+ D(ct, {
1165
+ label: L(o)("inventory.changelog.loadMore"),
1166
+ variant: "secondary",
1167
+ disabled: L(oe),
1168
+ onClick: S
1169
+ }, null, 8, ["label", "disabled"])
1170
+ ])) : E("", !0)
1171
+ ]),
1172
+ _: 1
1173
+ }, 8, ["modelValue", "min-width", "max-width"])
1174
+ ], 64);
1175
+ };
1176
+ }
1177
+ }), mo = /* @__PURE__ */ Tt(fo, [["__scopeId", "data-v-ae9bd171"]]), po = ["title"], Ge = 48, ie = 8, je = 8, vo = /* @__PURE__ */ ce({
1178
+ __name: "ChangelogFloatingButton",
1179
+ setup(a) {
1180
+ const { t: e } = he(), t = ge(), l = R(() => {
1181
+ var S;
1182
+ return !!((S = t.sessionUser.value) != null && S.role.isAdmin);
1183
+ }), s = $(!1), o = $(null);
1184
+ function u() {
1185
+ var S, T;
1186
+ return {
1187
+ width: ((S = o.value) == null ? void 0 : S.offsetWidth) ?? Ge,
1188
+ height: ((T = o.value) == null ? void 0 : T.offsetHeight) ?? Ge
1189
+ };
1190
+ }
1191
+ const r = $({ x: 0, y: 0 });
1192
+ function v(S, T, G) {
1193
+ return Math.min(Math.max(S, T), G);
1194
+ }
1195
+ function m() {
1196
+ const { width: S, height: T } = u(), G = Math.max(ie, window.innerWidth - S - ie - je), j = Math.max(ie, window.innerHeight - T - ie), Q = r.value.x + S / 2;
1197
+ r.value = {
1198
+ x: Q < window.innerWidth / 2 ? ie : G,
1199
+ y: v(r.value.y, ie, j)
1200
+ };
1201
+ }
1202
+ function h() {
1203
+ const { width: S } = u();
1204
+ r.value = {
1205
+ x: window.innerWidth - S - ie - je,
1206
+ y: Math.round(window.innerHeight / 2)
1207
+ };
1208
+ }
1209
+ Fe(() => {
1210
+ h(), window.addEventListener("resize", m), window.addEventListener("orientationchange", m);
1211
+ }), pt(() => {
1212
+ window.removeEventListener("resize", m), window.removeEventListener("orientationchange", m);
1213
+ }), q(l, async (S) => {
1214
+ S && (await vt(), h());
1215
+ });
1216
+ const k = $(!1);
1217
+ let P = null, U = !1;
1218
+ function oe(S) {
1219
+ P = { x: S.clientX, y: S.clientY, px: r.value.x, py: r.value.y }, k.value = !0, U = !1, S.currentTarget.setPointerCapture(S.pointerId);
1220
+ }
1221
+ function O(S) {
1222
+ if (!P) return;
1223
+ const T = S.clientX - P.x, G = S.clientY - P.y;
1224
+ Math.abs(T) + Math.abs(G) > 3 && (U = !0);
1225
+ const { width: j, height: Q } = u();
1226
+ r.value = {
1227
+ x: v(P.px + T, 0, window.innerWidth - j),
1228
+ y: v(P.py + G, 0, window.innerHeight - Q)
1229
+ };
1230
+ }
1231
+ function I() {
1232
+ P = null, k.value = !1, m();
1233
+ }
1234
+ function Y() {
1235
+ P && (I(), U || (s.value = !0));
1236
+ }
1237
+ return (S, T) => {
1238
+ const G = H("FmIcon");
1239
+ return i(), pe(gt, { to: "body" }, [
1240
+ l.value ? (i(), c(z, { key: 0 }, [
1241
+ g("div", {
1242
+ ref_key: "wrapperRef",
1243
+ ref: o,
1244
+ class: se([
1245
+ "fixed z-50 touch-none",
1246
+ k.value ? "cursor-grabbing" : "cursor-grab transition-[left,top] duration-200 ease-out"
1247
+ ]),
1248
+ style: yt({ left: `${r.value.x}px`, top: `${r.value.y}px` })
1249
+ }, [
1250
+ D(Ne, null, {
1251
+ default: te(() => [
1252
+ g("button", {
1253
+ type: "button",
1254
+ title: L(e)("inventory.changelog.title"),
1255
+ class: "fm-typo-en-body-sm-600 flex h-48 items-center gap-8 whitespace-nowrap rounded-full border border-gray-200 bg-white px-16 shadow-lg hover:bg-gray-50",
1256
+ onPointerdown: oe,
1257
+ onPointermove: O,
1258
+ onPointerup: Y,
1259
+ onPointercancel: I
1260
+ }, [
1261
+ D(G, {
1262
+ name: "history",
1263
+ size: "md",
1264
+ outline: ""
1265
+ }),
1266
+ g("span", null, _(L(e)("inventory.changelog.fabLabel")), 1)
1267
+ ], 40, po)
1268
+ ]),
1269
+ _: 1
1270
+ })
1271
+ ], 6),
1272
+ D(mo, {
1273
+ modelValue: s.value,
1274
+ "onUpdate:modelValue": T[0] || (T[0] = (j) => s.value = j)
1275
+ }, null, 8, ["modelValue"])
1276
+ ], 64)) : E("", !0)
1277
+ ]);
1278
+ };
1279
+ }
1280
+ }), go = { class: "flex items-center gap-2" }, yo = { class: "text-xs text-gray-400 font-normal" }, ho = { class: "flex flex-col gap-3" }, _o = { class: "max-h-[480px] flex flex-col gap-1" }, xo = { class: "font-mono text-xs text-gray-700 break-all min-w-0" }, bo = {
1281
+ key: 0,
1282
+ class: "inline-flex items-center gap-1 text-xs font-medium text-green-700 bg-green-50 px-2 py-0.5 rounded-full"
1283
+ }, wo = {
1284
+ key: 1,
1285
+ class: "inline-flex items-center gap-1 text-xs font-medium text-red-700 bg-red-50 px-2 py-0.5 rounded-full"
1286
+ }, ko = {
1287
+ key: 2,
1288
+ class: "inline-flex items-center gap-1 text-xs font-medium text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full"
1289
+ }, So = {
1290
+ key: 0,
1291
+ class: "text-center text-sm text-gray-400 py-4"
1292
+ }, $o = /* @__PURE__ */ ce({
1293
+ __name: "FmFeatureFlagDialog",
1294
+ setup(a) {
1295
+ const e = $(!1), t = $(""), l = R(() => {
1296
+ const { getFlagValue: u } = Lt();
1297
+ return Object.values(Ct).map((r) => {
1298
+ const v = u(r, (m) => m === "true");
1299
+ return {
1300
+ name: r,
1301
+ enabled: v
1302
+ };
1303
+ });
1304
+ }), s = R(() => {
1305
+ const u = t.value.toLowerCase();
1306
+ return u ? l.value.filter((r) => r.name.toLowerCase().includes(u)) : l.value;
1307
+ }), o = R(() => {
1308
+ const u = l.value.filter((m) => m.enabled === !0).length, r = l.value.filter((m) => m.enabled === !1).length, v = l.value.filter((m) => m.enabled === null).length;
1309
+ return { enabled: u, disabled: r, unknown: v, total: l.value.length };
1310
+ });
1311
+ return (u, r) => {
1312
+ const v = H("FmButton"), m = H("FmSpacer"), h = H("FmDialog");
1313
+ return i(), pe(h, {
1314
+ modelValue: e.value,
1315
+ "onUpdate:modelValue": r[2] || (r[2] = (k) => e.value = k),
1316
+ overlay: !0
1317
+ }, {
1318
+ "dialog-button": te(() => [
1319
+ D(Ne, null, {
1320
+ default: te(() => [
1321
+ D(v, {
1322
+ variant: "secondary",
1323
+ label: "Feature flags"
1324
+ })
1325
+ ]),
1326
+ _: 1
1327
+ })
1328
+ ]),
1329
+ "dialog-header": te(() => [
1330
+ g("div", go, [
1331
+ r[3] || (r[3] = g("span", null, "Feature Flags", -1)),
1332
+ g("span", yo, _(o.value.enabled) + " enabled · " + _(o.value.disabled) + " disabled · " + _(o.value.unknown) + " unknown ", 1)
1333
+ ])
1334
+ ]),
1335
+ "dialog-footer": te(() => [
1336
+ D(m, { class: "sm:hidden xs:hidden" }),
1337
+ D(v, {
1338
+ class: "sm:w-full xs:w-full",
1339
+ label: "Close",
1340
+ size: "md",
1341
+ variant: "primary",
1342
+ onClick: r[1] || (r[1] = (k) => e.value = !1)
1343
+ })
1344
+ ]),
1345
+ default: te(() => [
1346
+ g("div", ho, [
1347
+ ht(g("input", {
1348
+ "onUpdate:modelValue": r[0] || (r[0] = (k) => t.value = k),
1349
+ type: "text",
1350
+ placeholder: "Search flags...",
1351
+ 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"
1352
+ }, null, 512), [
1353
+ [_t, t.value]
1354
+ ]),
1355
+ g("div", _o, [
1356
+ (i(!0), c(z, null, ne(s.value, (k) => (i(), c("div", {
1357
+ key: k.name,
1358
+ class: "flex items-start justify-between gap-2 px-3 py-2 rounded-md hover:bg-gray-50 text-sm"
1359
+ }, [
1360
+ g("span", xo, _(k.name), 1),
1361
+ k.enabled === !0 ? (i(), c("span", bo, r[4] || (r[4] = [
1362
+ g("span", { class: "w-1.5 h-1.5 rounded-full bg-green-500" }, null, -1),
1363
+ le(" Enabled ")
1364
+ ]))) : k.enabled === !1 ? (i(), c("span", wo, r[5] || (r[5] = [
1365
+ g("span", { class: "w-1.5 h-1.5 rounded-full bg-red-500" }, null, -1),
1366
+ le(" Disabled ")
1367
+ ]))) : (i(), c("span", ko, r[6] || (r[6] = [
1368
+ g("span", { class: "w-1.5 h-1.5 rounded-full bg-gray-400" }, null, -1),
1369
+ le(" Unknown ")
1370
+ ])))
1371
+ ]))), 128)),
1372
+ s.value.length === 0 ? (i(), c("div", So, ' No flags matching "' + _(t.value) + '" ', 1)) : E("", !0)
1373
+ ])
1374
+ ])
1375
+ ]),
1376
+ _: 1
1377
+ }, 8, ["modelValue"]);
1378
+ };
1379
+ }
1380
+ }), Lo = { class: "h-full flex flex-col overflow-auto py-16 gap-2" }, Co = /* @__PURE__ */ ce({
1381
+ __name: "NavigationTab",
1382
+ setup(a) {
1383
+ const e = St(), t = Ee(), l = ge(), s = Vt(), { menuItems: o } = Je();
1384
+ q([() => l.currentBusiness.value, () => e.name], ([h, k]) => {
1385
+ (h == null ? void 0 : h.menuVersion) === "v3" && (k === ue.INGREDIENTS || k === ue.RECIPE || k === ue.UNIT) && t.push({ name: ue.STOCK });
1386
+ });
1387
+ const u = R({
1388
+ get() {
1389
+ if (e.name)
1390
+ return String(e.name);
1391
+ },
1392
+ set(h) {
1393
+ h && t.push({ name: h });
1394
+ }
1395
+ }), r = R(
1396
+ () => {
1397
+ var h;
1398
+ return `NavigationTab.${(h = l.currentBusiness.value) == null ? void 0 : h._id}`;
1399
+ }
1400
+ ), v = $(!1), m = R({
1401
+ get() {
1402
+ return v.value;
1403
+ },
1404
+ set(h) {
1405
+ v.value = h, h || s.setItem(r.value, "true");
1406
+ }
1407
+ });
1408
+ return q([() => r.value], () => {
1409
+ v.value = !1, setTimeout(() => {
1410
+ m.value = !s.getItem(r.value);
1411
+ }, 2e3);
1412
+ }), (h, k) => {
1413
+ const P = H("FmCollapsibleTabs");
1414
+ return i(), c("div", Lo, [
1415
+ D($o),
1416
+ D(P, {
1417
+ modelValue: u.value,
1418
+ "onUpdate:modelValue": k[0] || (k[0] = (U) => u.value = U),
1419
+ items: L(o)
1420
+ }, null, 8, ["modelValue", "items"])
1421
+ ]);
1422
+ };
1423
+ }
1424
+ });
1425
+ typeof Promise.withResolvers > "u" && (Promise.withResolvers = () => {
1426
+ let a, e;
1427
+ return { promise: new Promise((l, s) => {
1428
+ a = l, e = s;
1429
+ }), resolve: a, reject: e };
1430
+ });
1431
+ typeof Promise.prototype.delayed > "u" && (Promise.prototype.delayed = async function(a) {
1432
+ return await new Promise((e) => setTimeout(e, a)), Promise.resolve(this);
1433
+ });
1434
+ const jo = /* @__PURE__ */ ce({
1435
+ __name: "App",
1436
+ setup(a) {
1437
+ const e = ge(), t = Bt(), l = kt(), s = window.location.href.includes("print-preview");
1438
+ Fe(() => {
1439
+ if (window.location.href.includes("print-preview")) {
1440
+ e.setEmbedded(!0), document.body.classList.add("print-mode");
1441
+ return;
1442
+ }
1443
+ e.registerSidebarComponent(Co), t.initGoogleMap(l.appApi.googleMap).catch(() => {
1444
+ console.error("Google map cannot be loaded");
1445
+ });
1446
+ }), q([() => e.currentCountry.value], () => {
1447
+ o();
1448
+ });
1449
+ async function o() {
1450
+ var u;
1451
+ try {
1452
+ await e.readBusinesses(), e.currentBusiness.value = (u = e.businesses.value) == null ? void 0 : u.find((r) => r);
1453
+ } catch (r) {
1454
+ console.error("error when trying to reset businesses:", r);
1455
+ }
1456
+ }
1457
+ return (u, r) => (i(), c(z, null, [
1458
+ D(Qt),
1459
+ L(s) ? E("", !0) : (i(), pe(vo, { key: 0 }))
1460
+ ], 64));
1461
+ }
1462
+ });
1463
+ export {
1464
+ jo as default
1465
+ };