@feedmepos/mf-menu 0.32.70 → 0.32.72-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 (75) hide show
  1. package/dist/{App-D2qKBNOI.js → App-DpBAxq_x.js} +6 -6
  2. package/dist/{ApplyProduct.vue_vue_type_script_setup_true_lang-DpuE1Txi.js → ApplyProduct.vue_vue_type_script_setup_true_lang-BE34SL6B.js} +12 -12
  3. package/dist/{ApplyProductDialog.vue_vue_type_script_setup_true_lang-CuhfoI6u.js → ApplyProductDialog.vue_vue_type_script_setup_true_lang-Cg4oaBql.js} +3 -3
  4. package/dist/{Catalog-B8DQ8HuW.js → Catalog-BCKu3av3.js} +20 -20
  5. package/dist/{Category-BlfQyXMP.js → Category-D8fstrW5.js} +4 -4
  6. package/dist/{Category-DXRKc5oR.js → Category-DRyJ8Y9S.js} +4 -4
  7. package/dist/{CookingGuide-jNeTimU7.js → CookingGuide-BKTlBPm-.js} +46 -46
  8. package/dist/{CustomAttributeChip.vue_vue_type_script_setup_true_lang-BMKqOTc3.js → CustomAttributeChip.vue_vue_type_script_setup_true_lang-BHqJGqLf.js} +1 -1
  9. package/dist/{Group-BDS80Kj0.js → Group-DMLdJAIA.js} +1 -1
  10. package/dist/{Group-BmU0_HFA.js → Group-_vEUeyva.js} +3 -3
  11. package/dist/{Group.vue_vue_type_script_setup_true_lang-hSxGRxop.js → Group.vue_vue_type_script_setup_true_lang-BEONKZuB.js} +7 -7
  12. package/dist/{GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-CUNcxRnJ.js → GroupMarkupPriceDialog.vue_vue_type_script_setup_true_lang-B2pS71Xq.js} +24 -24
  13. package/dist/{ImportProductDialog.vue_vue_type_script_setup_true_lang-DjLnCfC5.js → ImportProductDialog.vue_vue_type_script_setup_true_lang-BHNmNXw0.js} +7 -7
  14. package/dist/{Ingredient-Czl2K5rQ.js → Ingredient-DeGrqMqN.js} +4 -4
  15. package/dist/{InventoryBinding.vue_vue_type_script_setup_true_lang-M8HxDzxj.js → InventoryBinding.vue_vue_type_script_setup_true_lang-DFOcD2mw.js} +2 -2
  16. package/dist/{LinkProductSideSheet-iwH-Ft7_.js → LinkProductSideSheet-BZNe2r8t.js} +4 -4
  17. package/dist/{MenuSetting-D-PtnHh_.js → MenuSetting-yb8w_Nwc.js} +7 -7
  18. package/dist/{OrderPacing-DpajUDfR.js → OrderPacing-DRApEr9x.js} +5 -5
  19. package/dist/{PrintRoute-CWzUI3D1.js → PrintRoute-DK3ZMajo.js} +10 -10
  20. package/dist/{Product-C341g4w7.js → Product-CBhhhicD.js} +1 -1
  21. package/dist/{Product.vue_vue_type_script_setup_true_lang-BRLo39YE.js → Product.vue_vue_type_script_setup_true_lang-CPgECJwS.js} +14 -14
  22. package/dist/ProductInternalTools-D8j9hMuA.js +439 -0
  23. package/dist/{Products-Dco1XgQd.js → Products-Db0Ihn6p.js} +55 -55
  24. package/dist/{Publish-sDveejeh.js → Publish-BFBUjUWu.js} +4 -4
  25. package/dist/{Recipe-MfXgmqtt.js → Recipe-B0r5vJz6.js} +5 -5
  26. package/dist/{RestaurantAttributesSelector.vue_vue_type_script_setup_true_lang-vtJwWImA.js → RestaurantAttributesSelector.vue_vue_type_script_setup_true_lang-C8Jk7KEh.js} +1 -1
  27. package/dist/{RuleView.vue_vue_type_script_setup_true_lang-ZnrzCXu3.js → RuleView.vue_vue_type_script_setup_true_lang-DPCcNBrm.js} +340 -340
  28. package/dist/{Scheduler-DKyhr6p8.js → Scheduler-yOdnbwyV.js} +17 -17
  29. package/dist/{ServingSequence-nEoPok72.js → ServingSequence-CEcYzZKq.js} +3 -3
  30. package/dist/{Setting-RWyx1jq2.js → Setting-CEwxLrwm.js} +5 -5
  31. package/dist/{Subcategory-B0smFoMD.js → Subcategory-b1NEH4Rt.js} +6 -6
  32. package/dist/{Takeaway-BVMZewQ0.js → Takeaway-BwGq2ti3.js} +4 -4
  33. package/dist/{Takeaway-BpwBR54Y.js → Takeaway-C4X3hjz2.js} +1 -1
  34. package/dist/{Takeaway.vue_vue_type_script_setup_true_lang-BTnFR11p.js → Takeaway.vue_vue_type_script_setup_true_lang-Da28Vzx1.js} +5 -5
  35. package/dist/{TranslationFieldSection.vue_vue_type_script_setup_true_lang-KNIxHJsf.js → TranslationFieldSection.vue_vue_type_script_setup_true_lang-DIP7cNpd.js} +1 -1
  36. package/dist/{TranslationSideSheet.vue_vue_type_script_setup_true_lang-Dznh3-H8.js → TranslationSideSheet.vue_vue_type_script_setup_true_lang-CCYzllV_.js} +2 -2
  37. package/dist/{TreeEditorOpenner.vue_vue_type_script_setup_true_lang-k3m88FlR.js → TreeEditorOpenner.vue_vue_type_script_setup_true_lang-e_pAe_Ob.js} +15 -15
  38. package/dist/{Unit-BzbHDW_L.js → Unit-DWGvi3C5.js} +2 -2
  39. package/dist/{Variant-BF_zXLDM.js → Variant-2YYwBJmZ.js} +3 -3
  40. package/dist/{_id_-BjGIzI2V.js → _id_-3pf3YlPS.js} +10 -10
  41. package/dist/{app-DDrm4hOt.js → app-D1p44Rbf.js} +37 -37
  42. package/dist/{app-qoGPYaSq.js → app-D6CmNX90.js} +1 -1
  43. package/dist/app.js +1 -1
  44. package/dist/apps/mf-menu/src/app.d.ts +20 -0
  45. package/dist/apps/mf-menu/src/components/feature/TreeEditor/composable/productImages.d.ts +80 -19
  46. package/dist/apps/mf-menu/tsconfig.app.tsbuildinfo +1 -1
  47. package/dist/assets/{override-menu-D1btUpWP.js → linked-status-B_5fbldk.js} +4 -4
  48. package/dist/assets/{menu-export-rYnoju7h.js → menu-export-Dje2CzXB.js} +3 -3
  49. package/dist/assets/{linked-status-CXL9skR7.js → override-menu-CpJc9-6f.js} +4 -4
  50. package/dist/assets/{validate-menu-R6zi6RGb.js → validate-menu-CpDDVAwU.js} +3 -3
  51. package/dist/{catalog-ByfbV1WF.js → catalog-Ds7c8bSK.js} +1 -1
  52. package/dist/{catalogSetting-qvKbsi8t.js → catalogSetting-qbnlvX9R.js} +1 -1
  53. package/dist/{currency-C5kmu6Ku.js → currency-BQjK22_U.js} +1 -1
  54. package/dist/dayjs.min-BjENDBB5.js +7 -0
  55. package/dist/{discardConfirm-rDbUqsKj.js → discardConfirm-DhbS0wLN.js} +1 -1
  56. package/dist/{index-B2Hnb8WK.js → index-BqB1Vagh.js} +6 -6
  57. package/dist/{index-COu9fsyr.js → index-C2rMjg4b.js} +1 -1
  58. package/dist/{index-BoVuN9fk.js → index-YU-FPKch.js} +5 -5
  59. package/dist/{index.vue_vue_type_script_setup_true_lang-Wm3L_CDm.js → index.vue_vue_type_script_setup_true_lang-DILo07iQ.js} +16618 -16607
  60. package/dist/{item-CcaqdD88.js → item-CN-mYmn-.js} +1627 -1626
  61. package/dist/{jszip.min-B-GfzNS3.js → jszip.min-DdiexxWX.js} +384 -384
  62. package/dist/{linkProducts-DXSk9ntt.js → linkProducts-DSa1bP0Z.js} +4 -4
  63. package/dist/{memberPricing-Bmv0qRtK.js → memberPricing-BLIgqSgU.js} +1 -1
  64. package/dist/{menu-BLbZDh7_.js → menu-kYSa55lO.js} +1 -1
  65. package/dist/{menuV2-BSGYEEJI.js → menuV2-BJ-6TZDX.js} +23 -23
  66. package/dist/mf-menu.css +1 -1
  67. package/dist/{order_pacing-DLrwnijs.js → order_pacing-CeCi-pP3.js} +5 -5
  68. package/dist/{priceTier-Bw0-wJJ0.js → priceTier-CsF1g5ie.js} +1 -1
  69. package/dist/{rules-Ciu45JMO.js → rules-C3jtb0rM.js} +3 -3
  70. package/dist/{scheduler-DYZ2PnDh.js → scheduler-DZpjPLLc.js} +5 -5
  71. package/dist/{toExcel-D6Rp5oOB.js → toExcel-DI9BOlMc.js} +2 -2
  72. package/dist/{unit-BR60ZgDQ.js → unit-DeNymCWc.js} +17 -17
  73. package/package.json +1 -1
  74. package/dist/ProductInternalTools-BUku68VS.js +0 -416
  75. package/dist/dayjs.min-D3WVCWf8.js +0 -7
@@ -0,0 +1,439 @@
1
+ import { defineComponent as q, ref as v, computed as z, resolveComponent as G, createElementBlock as c, openBlock as i, createElementVNode as s, createVNode as k, unref as h, createCommentVNode as B, normalizeClass as R, toDisplayString as $, createStaticVNode as A, Fragment as T, renderList as O, createBlock as re, withCtx as D } from "vue";
2
+ import { J as V, F as ie } from "./jszip.min-DdiexxWX.js";
3
+ import { l as Z } from "./discardConfirm-DhbS0wLN.js";
4
+ import { useI18n as ce } from "@feedmepos/mf-common";
5
+ import { FmButtonVariant as P, useSnackbar as W, useDialog as de, FmButtonColorThemeVariant as M } from "@feedmepos/ui-library";
6
+ import { b as me, u as ue, p as pe, x as ge, y as fe } from "./index.vue_vue_type_script_setup_true_lang-DILo07iQ.js";
7
+ import { _ as he } from "./PageLayout.vue_vue_type_script_setup_true_lang-BVmHMvKD.js";
8
+ import { u as be, a as ye } from "./menu-kYSa55lO.js";
9
+ import { a as ve } from "./Product.vue_vue_type_script_setup_true_lang-CPgECJwS.js";
10
+ import { af as _e, ag as we, ah as xe, ai as Ie, aj as ke } from "./item-CN-mYmn-.js";
11
+ const Ce = { class: "h-full flex flex-col" }, Ue = { class: "flex items-center justify-between p-16 border-b border-gray-200" }, je = { class: "flex gap-8" }, $e = { class: "border-b border-gray-200" }, Fe = { class: "flex" }, Se = { class: "flex-1 overflow-hidden" }, Me = {
12
+ key: 0,
13
+ class: "h-full flex flex-col"
14
+ }, ze = {
15
+ key: 0,
16
+ class: "flex-1 flex items-center justify-center"
17
+ }, Pe = {
18
+ key: 1,
19
+ class: "flex-1 overflow-y-auto p-16"
20
+ }, Le = { class: "space-y-12" }, Te = { class: "fm-typo-en-body-sm font-medium" }, Ne = { class: "flex" }, Ee = { class: "w-64 h-64 bg-gray-100 rounded-md overflow-hidden flex items-center justify-center" }, Be = ["src", "alt"], Re = {
21
+ key: 1,
22
+ class: "text-gray-400 text-xs"
23
+ }, Ae = { class: "flex" }, Oe = { class: "w-64 h-64 bg-gray-100 rounded-md overflow-hidden" }, De = ["src", "alt"], Ve = {
24
+ key: 1,
25
+ class: "h-full flex flex-col"
26
+ }, Ze = {
27
+ key: 0,
28
+ class: "flex-1 flex items-center justify-center"
29
+ }, We = {
30
+ key: 1,
31
+ class: "flex-1 overflow-y-auto p-16"
32
+ }, qe = { class: "space-y-12" }, Ge = { class: "fm-typo-en-body-sm font-medium break-all" }, Je = { class: "flex" }, He = { class: "w-64 h-64 bg-gray-100 rounded-md overflow-hidden" }, Xe = ["src", "alt"], Ke = /* @__PURE__ */ q({
33
+ __name: "ImageUpdatePreview",
34
+ props: {
35
+ matchedImages: {},
36
+ unmatchedImages: {}
37
+ },
38
+ emits: ["cancel", "update"],
39
+ setup(N, { emit: _ }) {
40
+ const p = N, C = _, b = v("matched"), y = z(() => p.matchedImages.length), U = z(() => p.unmatchedImages.length);
41
+ function w() {
42
+ C("cancel");
43
+ }
44
+ function F() {
45
+ C("update", p.matchedImages);
46
+ }
47
+ return (x, r) => {
48
+ const I = G("fm-button");
49
+ return i(), c("div", Ce, [
50
+ s("div", Ue, [
51
+ r[2] || (r[2] = s("h2", { class: "fm-typo-en-headline-sm font-semibold" }, "Update Product Images", -1)),
52
+ s("div", je, [
53
+ k(I, {
54
+ variant: h(P).Secondary,
55
+ label: "Cancel",
56
+ onClick: w
57
+ }, null, 8, ["variant"]),
58
+ k(I, {
59
+ variant: h(P).Primary,
60
+ label: "Update",
61
+ disabled: y.value === 0,
62
+ onClick: F
63
+ }, null, 8, ["variant", "disabled"])
64
+ ])
65
+ ]),
66
+ s("div", $e, [
67
+ s("div", Fe, [
68
+ s("button", {
69
+ class: R([
70
+ "px-16 py-12 font-medium text-sm border-b-2 transition-colors",
71
+ b.value === "matched" ? "border-blue-500 text-blue-600 bg-blue-50" : "border-transparent text-gray-500 hover:text-gray-700"
72
+ ]),
73
+ onClick: r[0] || (r[0] = (m) => b.value = "matched")
74
+ }, " Matched Images (" + $(y.value) + ") ", 3),
75
+ U.value > 0 ? (i(), c("button", {
76
+ key: 0,
77
+ class: R([
78
+ "px-16 py-12 font-medium text-sm border-b-2 transition-colors",
79
+ b.value === "unmatched" ? "border-blue-500 text-blue-600 bg-blue-50" : "border-transparent text-gray-500 hover:text-gray-700"
80
+ ]),
81
+ onClick: r[1] || (r[1] = (m) => b.value = "unmatched")
82
+ }, " Unmatched Images (" + $(U.value) + ") ", 3)) : B("", !0)
83
+ ])
84
+ ]),
85
+ s("div", Se, [
86
+ b.value === "matched" ? (i(), c("div", Me, [
87
+ y.value === 0 ? (i(), c("div", ze, r[3] || (r[3] = [
88
+ A('<div class="text-center text-gray-500"><svg class="mx-auto h-48 w-48 text-gray-400 mb-16" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg><p class="fm-typo-en-body-lg text-gray-500">No matched images found</p><p class="fm-typo-en-body-sm text-gray-400 mt-4"> Make sure your image filenames match product names </p></div>', 1)
89
+ ]))) : (i(), c("div", Pe, [
90
+ r[4] || (r[4] = s("div", { class: "grid grid-cols-3 gap-16 pb-12 border-b border-gray-200 mb-16" }, [
91
+ s("div", { class: "fm-typo-en-body-sm-600 font-semibold text-gray-700" }, "Product Name"),
92
+ s("div", { class: "fm-typo-en-body-sm-600 font-semibold text-gray-700" }, "Current Image"),
93
+ s("div", { class: "fm-typo-en-body-sm-600 font-semibold text-gray-700" }, "New Image")
94
+ ], -1)),
95
+ s("div", Le, [
96
+ (i(!0), c(T, null, O(p.matchedImages, (m, j) => (i(), c("div", {
97
+ key: j,
98
+ class: "grid grid-cols-3 gap-16 py-12 border-b border-gray-100 items-center"
99
+ }, [
100
+ s("div", Te, $(m.productName), 1),
101
+ s("div", Ne, [
102
+ s("div", Ee, [
103
+ m.originalThumbnail ? (i(), c("img", {
104
+ key: 0,
105
+ src: m.originalThumbnail,
106
+ alt: m.productName,
107
+ class: "w-full h-full object-cover"
108
+ }, null, 8, Be)) : (i(), c("span", Re, "No image"))
109
+ ])
110
+ ]),
111
+ s("div", Ae, [
112
+ s("div", Oe, [
113
+ s("img", {
114
+ src: m.newImageUrl,
115
+ alt: m.newImage.name,
116
+ class: "w-full h-full object-cover"
117
+ }, null, 8, De)
118
+ ])
119
+ ])
120
+ ]))), 128))
121
+ ])
122
+ ]))
123
+ ])) : b.value === "unmatched" ? (i(), c("div", Ve, [
124
+ U.value === 0 ? (i(), c("div", Ze, r[5] || (r[5] = [
125
+ A('<div class="text-center text-gray-500"><svg class="mx-auto h-48 w-48 text-gray-400 mb-16" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><p class="fm-typo-en-body-lg text-gray-500">All images matched!</p><p class="fm-typo-en-body-sm text-gray-400 mt-4">No unmatched images found</p></div>', 1)
126
+ ]))) : (i(), c("div", We, [
127
+ r[6] || (r[6] = s("div", { class: "grid grid-cols-2 gap-16 pb-12 border-b border-gray-200 mb-16" }, [
128
+ s("div", { class: "fm-typo-en-body-sm-600 font-semibold text-gray-700" }, "Filename"),
129
+ s("div", { class: "fm-typo-en-body-sm-600 font-semibold text-gray-700" }, "Image")
130
+ ], -1)),
131
+ s("div", qe, [
132
+ (i(!0), c(T, null, O(p.unmatchedImages, (m, j) => (i(), c("div", {
133
+ key: j,
134
+ class: "grid grid-cols-2 gap-16 py-12 border-b border-gray-100 items-center"
135
+ }, [
136
+ s("div", Ge, $(m.filename), 1),
137
+ s("div", Je, [
138
+ s("div", He, [
139
+ s("img", {
140
+ src: m.imageUrl,
141
+ alt: m.filename,
142
+ class: "w-full h-full object-cover"
143
+ }, null, 8, Xe)
144
+ ])
145
+ ])
146
+ ]))), 128))
147
+ ])
148
+ ]))
149
+ ])) : B("", !0)
150
+ ])
151
+ ]);
152
+ };
153
+ }
154
+ });
155
+ var Qe = { firebase: { storageBucket: "image.feedmedev.cc" } };
156
+ const Ye = {
157
+ key: 0,
158
+ class: "h-screen"
159
+ }, et = { class: "flex-1 flex justify-between gap-8 pl-8" }, tt = { class: "flex items-center" }, at = { class: "bg-fm-color-neutral-gray-100 rounded-md px-8 py-4" }, st = { class: "fm-typo-en-body-md-600 font-semibold" }, ot = { class: "flex gap-8" }, ft = /* @__PURE__ */ q({
160
+ __name: "ProductInternalTools",
161
+ setup(N) {
162
+ const { t: _ } = ce(), p = me(W()), C = W(), b = de(), y = ue(), { selectedCategories: U } = be(), w = v(!1), F = v(), x = v([]), r = v([]), I = z(() => {
163
+ const e = Z.flatten(U.value.map((t) => t.items));
164
+ return Z.uniqBy(e, (t) => t._id);
165
+ }), m = z(() => I.value.length);
166
+ async function j(e, t) {
167
+ return await xe(e, {
168
+ withTimestamp: !0,
169
+ filename: t
170
+ });
171
+ }
172
+ async function J(e, t = "images.zip") {
173
+ const n = new V();
174
+ e.forEach(({ blob: d, filename: l }) => {
175
+ d && n.file(l, d);
176
+ });
177
+ const g = await n.generateAsync({ type: "blob" });
178
+ ie.saveAs(g, t);
179
+ }
180
+ async function H() {
181
+ const e = I.value.filter((t) => t.thumbnail);
182
+ if (e.length === 0) {
183
+ C.open({ type: "error", title: "No downloadable images found" });
184
+ return;
185
+ }
186
+ b.open({
187
+ title: "Download Images",
188
+ message: `Found ${e.length} images, download as ZIP file?`,
189
+ primaryActions: {
190
+ text: "Download",
191
+ close: !0
192
+ },
193
+ secondaryActions: {
194
+ text: _("common.cancel"),
195
+ close: !0
196
+ }
197
+ }).onPrimary(async () => {
198
+ const t = v("Preparing download...");
199
+ await p.minor(
200
+ async () => {
201
+ const n = e.filter((l) => l.thumbnail).map((l, f) => {
202
+ let o = l.name || `image_${Date.now()}_${f}`;
203
+ return o += ".jpg", {
204
+ url: l.thumbnail,
205
+ filename: o,
206
+ index: f + 1
207
+ };
208
+ });
209
+ t.value = `Starting download of ${n.length} images...`;
210
+ const d = (await _e(n, j, {
211
+ batchSize: 5,
212
+ // Download 5 images at a time
213
+ batchDelay: 200,
214
+ // 200ms delay between batches
215
+ progressMessage: t
216
+ })).filter((l) => l !== null);
217
+ if (t.value = "Creating ZIP file...", d.length > 0) {
218
+ const l = `images_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.zip`;
219
+ await J(d, l);
220
+ } else
221
+ throw new Error("Failed to fetch any images");
222
+ },
223
+ {
224
+ message: t,
225
+ successMessage: `Successfully downloaded ${e.length} images`,
226
+ customId: "download-images"
227
+ }
228
+ );
229
+ });
230
+ }
231
+ async function X(e) {
232
+ const n = await new V().loadAsync(e), g = [];
233
+ for (const [d, l] of Object.entries(n.files)) {
234
+ if (l.dir || d.includes("__MACOSX/") || !E(d))
235
+ continue;
236
+ const f = await l.async("blob"), o = d.split("/").pop() || d, a = new File([f], o, { type: K(o) });
237
+ g.push(a);
238
+ }
239
+ return g;
240
+ }
241
+ function E(e) {
242
+ const t = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"], n = e.toLowerCase().substring(e.lastIndexOf("."));
243
+ return t.includes(n);
244
+ }
245
+ function K(e) {
246
+ const t = e.toLowerCase().substring(e.lastIndexOf("."));
247
+ return {
248
+ ".jpg": "image/jpeg",
249
+ ".jpeg": "image/jpeg",
250
+ ".png": "image/png",
251
+ ".gif": "image/gif",
252
+ ".webp": "image/webp",
253
+ ".bmp": "image/bmp"
254
+ }[t] || "image/jpeg";
255
+ }
256
+ function Q(e) {
257
+ return (e.substring(0, e.lastIndexOf(".")) || e).toLowerCase().trim().replace(/[_\-\s]+/g, " ");
258
+ }
259
+ function Y(e) {
260
+ return e.toLowerCase().trim().replace(/[_\-\s]+/g, " ");
261
+ }
262
+ async function ee(e) {
263
+ const t = [];
264
+ for (const a of e)
265
+ if (a.type === "application/zip" || a.name.toLowerCase().endsWith(".zip")) {
266
+ const u = await X(a);
267
+ t.push(...u);
268
+ } else E(a.name) && t.push(a);
269
+ const n = /* @__PURE__ */ new Map();
270
+ t.forEach((a) => {
271
+ const u = a.name.toLowerCase();
272
+ n.has(u) || n.set(u, a);
273
+ });
274
+ const g = Array.from(n.values()), d = [], l = [], f = /* @__PURE__ */ new Map();
275
+ I.value.forEach((a) => {
276
+ const u = Y(a.name);
277
+ f.set(u, a);
278
+ });
279
+ const o = [];
280
+ for (const a of g) {
281
+ const u = Q(a.name), S = f.get(u);
282
+ if (!S) {
283
+ l.push({
284
+ filename: a.name,
285
+ file: a,
286
+ imageUrl: URL.createObjectURL(a)
287
+ });
288
+ continue;
289
+ }
290
+ let L;
291
+ try {
292
+ L = await ge(a);
293
+ } catch (le) {
294
+ console.error(`Unable to compress ${a.name}`, le), o.push(a.name);
295
+ continue;
296
+ }
297
+ d.push({
298
+ productId: S._id,
299
+ productName: S.name,
300
+ originalThumbnail: S.thumbnail,
301
+ newImage: L,
302
+ newImageUrl: URL.createObjectURL(L)
303
+ });
304
+ }
305
+ if (o.length) {
306
+ const a = o.slice(0, 5).join(", ");
307
+ C.open({
308
+ type: "error",
309
+ title: _("menu.productInternalTools.unreadable_images.title"),
310
+ message: _("menu.productInternalTools.unreadable_images.message", {
311
+ count: o.length,
312
+ names: `${a}${o.length > 5 ? ", ..." : ""}`
313
+ })
314
+ });
315
+ }
316
+ return { matched: d, unmatched: l };
317
+ }
318
+ async function te(e) {
319
+ await p.minor(
320
+ async () => {
321
+ const { matched: t, unmatched: n } = await ee(e);
322
+ x.value = t, r.value = n, w.value = !0;
323
+ },
324
+ {
325
+ message: "Processing uploaded images...",
326
+ customId: "process-images"
327
+ }
328
+ );
329
+ }
330
+ async function ae(e) {
331
+ const t = v("Preparing image updates...");
332
+ await p.minor(
333
+ async () => {
334
+ const n = async (o) => {
335
+ const a = Ie(o.productId);
336
+ let u = "";
337
+ return o.newImage && (await ke.update(a, o.newImage, Qe.firebase.storageBucket), u = fe(a)), { productId: o.productId, newImageUrl: u };
338
+ };
339
+ t.value = `Starting upload of ${e.length} product images...`;
340
+ const g = await we({
341
+ items: e,
342
+ processor: n,
343
+ batchSize: 5,
344
+ // Upload 5 images at a time
345
+ batchDelay: 200,
346
+ // 200ms delay between batches
347
+ onProgress: ({ batchStart: o, batchEnd: a, total: u }) => {
348
+ t.value = `Uploading images ${o}-${a}/${u}...`;
349
+ }
350
+ });
351
+ t.value = "Updating product data...";
352
+ const d = y.state.menu, l = pe(d), f = new Map(g.map((o) => [o == null ? void 0 : o.productId, o]));
353
+ l.modules.item = l.modules.item.map((o) => {
354
+ const a = f.get(o._id);
355
+ return a && a.newImageUrl ? { ...o, thumbnail: a.newImageUrl } : o;
356
+ }), await y.updateMenuSetting(l), await y.importMenu(l);
357
+ },
358
+ {
359
+ message: t,
360
+ successMessage: `Successfully updated ${e.length} product images`,
361
+ customId: "update-product-images"
362
+ }
363
+ ), w.value = !1, x.value = [], r.value = [];
364
+ }
365
+ function se() {
366
+ x.value.forEach((e) => URL.revokeObjectURL(e.newImageUrl)), r.value.forEach((e) => URL.revokeObjectURL(e.imageUrl)), w.value = !1, x.value = [], r.value = [];
367
+ }
368
+ function oe() {
369
+ var e;
370
+ (e = F.value) == null || e.click();
371
+ }
372
+ function ne(e) {
373
+ const t = e.target;
374
+ if (t.files && t.files.length > 0) {
375
+ const n = Array.from(t.files);
376
+ te(n);
377
+ }
378
+ t.value = "";
379
+ }
380
+ return ye().resetOnMount(), (e, t) => {
381
+ const n = G("fm-button");
382
+ return i(), c(T, null, [
383
+ w.value ? (i(), c("div", Ye, [
384
+ k(Ke, {
385
+ "matched-images": x.value,
386
+ "unmatched-images": r.value,
387
+ onCancel: se,
388
+ onUpdate: ae
389
+ }, null, 8, ["matched-images", "unmatched-images"])
390
+ ])) : (i(), re(he, {
391
+ key: 1,
392
+ heading: h(_)("menu.productInternalTools.title")
393
+ }, {
394
+ default: D(() => [
395
+ k(ve)
396
+ ]),
397
+ "append-heading": D(() => [
398
+ s("div", et, [
399
+ s("div", tt, [
400
+ s("div", at, [
401
+ s("p", st, $(m.value), 1)
402
+ ])
403
+ ]),
404
+ s("div", ot, [
405
+ k(n, {
406
+ "bg-color": h(M).NeutralGray100,
407
+ "text-color": h(M).TypoSecondary,
408
+ variant: h(P).Primary,
409
+ label: "Download Images",
410
+ onClick: H
411
+ }, null, 8, ["bg-color", "text-color", "variant"]),
412
+ k(n, {
413
+ "bg-color": h(M).NeutralGray100,
414
+ "text-color": h(M).TypoSecondary,
415
+ variant: h(P).Primary,
416
+ label: "Update Images",
417
+ onClick: oe
418
+ }, null, 8, ["bg-color", "text-color", "variant"])
419
+ ])
420
+ ])
421
+ ]),
422
+ _: 1
423
+ }, 8, ["heading"])),
424
+ s("input", {
425
+ ref_key: "fileInput",
426
+ ref: F,
427
+ type: "file",
428
+ multiple: "",
429
+ accept: "image/*,.zip",
430
+ style: { display: "none" },
431
+ onChange: ne
432
+ }, null, 544)
433
+ ], 64);
434
+ };
435
+ }
436
+ });
437
+ export {
438
+ ft as default
439
+ };