@useinsider/guido 3.18.2-beta.a5a0a11 → 3.18.2-beta.ac0d92e

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 (49) hide show
  1. package/dist/components/Guido.vue.js +1 -1
  2. package/dist/components/Guido.vue2.js +60 -54
  3. package/dist/components/organisms/base/Toaster.vue2.js +12 -13
  4. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +11 -13
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +57 -74
  6. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +37 -23
  7. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
  8. package/dist/composables/useActionsApi.js +24 -20
  9. package/dist/composables/useCortexBlueprintBridge.js +115 -54
  10. package/dist/composables/useCustomInterfaceAppearance.js +46 -56
  11. package/dist/composables/useEmailTemplateApplier.js +93 -50
  12. package/dist/composables/useHtmlValidator.js +82 -87
  13. package/dist/composables/useRecommendation.js +35 -40
  14. package/dist/composables/useStripo.js +30 -30
  15. package/dist/composables/useToaster.js +20 -14
  16. package/dist/enums/extensions/recommendationBlock.js +31 -38
  17. package/dist/extensions/Blocks/Recommendation/block.js +42 -61
  18. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
  19. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +35 -40
  20. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -84
  21. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
  22. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +140 -260
  23. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +16 -26
  24. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
  25. package/dist/guido.css +1 -1
  26. package/dist/src/composables/useCortexBlueprintBridge.d.ts +4 -3
  27. package/dist/src/composables/useEmailTemplateApplier.d.ts +22 -2
  28. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
  29. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
  30. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
  31. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  32. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
  33. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -9
  34. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +2 -7
  35. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -86
  36. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
  37. package/dist/src/stores/guido-email-editor.d.ts +29 -7
  38. package/dist/src/stores/onboarding.d.ts +0 -377
  39. package/dist/static/styles/components/recommendation-strategy.css.js +4 -34
  40. package/dist/stores/guido-email-editor.js +5 -1
  41. package/dist/stores/onboarding.js +36 -41
  42. package/dist/utils/templatePreparation.js +55 -55
  43. package/package.json +1 -1
  44. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +0 -21
  45. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +0 -47
  46. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +0 -24
  47. package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +0 -2
  48. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -14
  49. package/dist/static/styles/components/skeleton.css.js +0 -23
@@ -1,26 +1,22 @@
1
- import { useToaster as D } from "../../../../composables/useToaster.js";
2
- import { useTranslations as _ } from "../../../../composables/useTranslations.js";
3
- import { getRecommendationFeedSourceMaps as v, strategyEditPath as A, URLS as E, getOperatorOptions as N, PriceAttributes as U } from "../../../../enums/extensions/recommendationBlock.js";
4
- import { ToasterTypeOptions as L } from "../../../../enums/toaster.js";
5
- import { useRecommendationApi as T } from "../../../../services/recommendationApi.js";
6
- import { useConfigStore as k } from "../../../../stores/config.js";
7
- import { defineStore as B } from "pinia";
1
+ import { getRecommendationFeedSourceMaps as b, getOperatorOptions as G, PriceAttributes as v } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as D } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as F } from "../../../../stores/config.js";
4
+ import { defineStore as P } from "pinia";
8
5
  import "../constants/selectors.js";
9
- import { DEFAULT_MOBILE_CARDS_IN_ROW as O, DEFAULT_CARDS_IN_ROW as x } from "../constants/layout.js";
10
- import { DEFAULT_NODE_CONFIG as M, EXCLUDED_ALGORITHM_IDS as z } from "../constants/defaultConfig.js";
11
- import { getDefaultProducts as F } from "../templates/utils.js";
12
- import { generateCompleteFilterQuery as w } from "../utils/filterUtil.js";
13
- import { getPartnerRecommendationParams as V } from "../utils/partnerCustomizations.js";
14
- import { sanitizeProductIds as j } from "../utils/productIds.js";
15
- import { isFilterValid as $ } from "../validation/filterSchema.js";
16
- import { getInvalidFields as q, isConfigValid as K } from "../validation/requiredFields.js";
17
- const f = T();
18
- let S = null, p = null, y = null, I = "", R = null, b = 0;
19
- const g = /* @__PURE__ */ new Map();
20
- let l = null;
21
- function G() {
6
+ import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
7
+ import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
8
+ import { getDefaultProducts as R } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as k } from "../utils/filterUtil.js";
10
+ import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
11
+ import { sanitizeProductIds as A } from "../utils/productIds.js";
12
+ import { isFilterValid as B } from "../validation/filterSchema.js";
13
+ import { isConfigValid as M } from "../validation/requiredFields.js";
14
+ const u = D();
15
+ let f = null, g = null, h = null, S = null;
16
+ const p = /* @__PURE__ */ new Map();
17
+ function w() {
22
18
  return {
23
- cardsInRow: x,
19
+ cardsInRow: U,
24
20
  currencySettings: {
25
21
  name: "USD",
26
22
  value: "USD",
@@ -34,17 +30,13 @@ function G() {
34
30
  productIds: [],
35
31
  id: 1,
36
32
  language: "en_US",
37
- mobileCardsInRow: O,
33
+ mobileCardsInRow: _,
38
34
  mobileLayoutEnabled: !1,
39
35
  orientation: "grid",
40
36
  recommendedProducts: [],
41
37
  sendProductRequestFlag: !1,
42
38
  shuffleProducts: !1,
43
- // With RRS on, a block that has not been synced yet must not claim an algorithm:
44
- // that default is what reached buildCampaignUrl and baked a most-popular feed URL
45
- // for a block the user never configured (SD-149916). Legacy blocks still get their real
46
- // algorithm from the node-config sync or the save-time seed.
47
- strategy: k().isFeatureEnabled("reusableRecommendationStrategy") ? "" : "mostPopular",
39
+ strategy: "mostPopular",
48
40
  strategyId: "",
49
41
  textTrimming: !0,
50
42
  unresponsive: !1,
@@ -54,9 +46,9 @@ function G() {
54
46
  priceHideIfSameAsDiscounted: !1
55
47
  };
56
48
  }
57
- function P() {
49
+ function C() {
58
50
  return {
59
- recommendationConfigs: G(),
51
+ recommendationConfigs: w(),
60
52
  recommendationProducts: [],
61
53
  filterStatus: !1,
62
54
  filterSelectionDrawerStatus: !1,
@@ -68,7 +60,7 @@ function P() {
68
60
  syncedConfigFingerprint: null
69
61
  };
70
62
  }
71
- const H = () => ({
63
+ const z = () => ({
72
64
  recommendationCampaignUrls: {},
73
65
  activePredictiveAlgorithms: [],
74
66
  languages: {},
@@ -77,14 +69,11 @@ const H = () => ({
77
69
  strategies: [],
78
70
  strategiesLoading: !1,
79
71
  strategyUrlTemplates: {},
80
- strategiesFetched: !1,
81
- strategiesSettled: !1,
82
72
  blockStates: {},
83
73
  currentRecommendationId: null,
84
- strategyPanelOpen: !1,
85
74
  configVersion: 0
86
- }), mt = B("guidoRecommendationExtension", {
87
- state: () => H(),
75
+ }), Y = P("guidoRecommendationExtension", {
76
+ state: () => z(),
88
77
  getters: {
89
78
  // ====================================================================
90
79
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -94,7 +83,7 @@ const H = () => ({
94
83
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
95
84
  */
96
85
  recommendationConfigs(t) {
97
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : G();
86
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
98
87
  },
99
88
  /**
100
89
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -149,12 +138,12 @@ const H = () => ({
149
138
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
150
139
  },
151
140
  getActivePredictiveAlgorithms: (t) => {
152
- const e = v(), r = [];
153
- return t.activePredictiveAlgorithms.filter((i) => !z.includes(i)).forEach((i) => {
154
- r.push(...e.filter((s) => s.id === i));
155
- }), r.map((i) => ({
156
- text: i.name,
157
- value: i.key
141
+ const e = b(), r = [];
142
+ return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
143
+ r.push(...e.filter((s) => s.id === n));
144
+ }), r.map((n) => ({
145
+ text: n.name,
146
+ value: n.key
158
147
  }));
159
148
  },
160
149
  getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
@@ -168,7 +157,7 @@ const H = () => ({
168
157
  getFilterList() {
169
158
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
170
159
  let e;
171
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : U.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
160
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
172
161
  text: t.displayName,
173
162
  value: e,
174
163
  type: t.attributeType
@@ -190,7 +179,7 @@ const H = () => ({
190
179
  setCurrentBlock(t) {
191
180
  this.blockStates[t] || (this.blockStates = {
192
181
  ...this.blockStates,
193
- [t]: P()
182
+ [t]: C()
194
183
  }), this.currentRecommendationId = t;
195
184
  },
196
185
  /**
@@ -200,36 +189,32 @@ const H = () => ({
200
189
  removeBlockState(t) {
201
190
  const e = t.toString();
202
191
  if (this.recommendationCampaignUrls[e]) {
203
- const i = { ...this.recommendationCampaignUrls };
204
- delete i[e], this.recommendationCampaignUrls = i;
192
+ const n = { ...this.recommendationCampaignUrls };
193
+ delete n[e], this.recommendationCampaignUrls = n;
205
194
  }
206
195
  const r = { ...this.blockStates };
207
196
  if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
208
- const i = Object.keys(this.blockStates).map(Number);
209
- this.currentRecommendationId = i.length > 0 ? i[0] : null;
197
+ const n = Object.keys(this.blockStates).map(Number);
198
+ this.currentRecommendationId = n.length > 0 ? n[0] : null;
210
199
  }
211
200
  },
212
201
  /**
213
202
  * Deep-clones a block's state and mirrors its campaign URL under a new id.
214
203
  * Invoked from `onCreated` when a duplicate is detected (SD-142352).
215
- *
216
- * The clone keeps the source's data but drops its "already fetched / already
217
- * synced" claims for strategy blocks, so it fetches again like a fresh drop
218
- * (SD-149916).
219
204
  */
220
205
  cloneBlockState(t, e) {
221
206
  const r = this.blockStates[t];
222
207
  if (r) {
223
208
  const o = structuredClone(r);
224
- o.recommendationConfigs.id = e, o.recommendationConfigs.strategyId && k().isFeatureEnabled("reusableRecommendationStrategy") && (o.isInitialized = !1, o.syncedConfigFingerprint = null), this.blockStates = {
209
+ o.recommendationConfigs.id = e, this.blockStates = {
225
210
  ...this.blockStates,
226
211
  [e]: o
227
212
  };
228
213
  }
229
- const i = t.toString(), s = e.toString(), n = this.recommendationCampaignUrls[i];
230
- n && (this.recommendationCampaignUrls = {
214
+ const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
215
+ i && (this.recommendationCampaignUrls = {
231
216
  ...this.recommendationCampaignUrls,
232
- [s]: n
217
+ [s]: i
233
218
  });
234
219
  },
235
220
  /**
@@ -254,7 +239,7 @@ const H = () => ({
254
239
  * `isInitialized`) alone.
255
240
  */
256
241
  seedBlockUrlConfig(t, e) {
257
- const r = (o, a) => o === "." || o === "," || o === " " ? o : a, i = {
242
+ const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
258
243
  name: e.currencyCode,
259
244
  value: e.currencyCode,
260
245
  symbol: e.currencySymbol,
@@ -262,9 +247,9 @@ const H = () => ({
262
247
  decimalCount: String(e.currencyDecimalCount),
263
248
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
264
249
  thousandSeparator: r(e.currencyThousandSeparator, ".")
265
- }, s = !this.blockStates[t], n = s ? P() : this.blockStates[t];
266
- n.recommendationConfigs = {
267
- ...n.recommendationConfigs,
250
+ }, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
251
+ i.recommendationConfigs = {
252
+ ...i.recommendationConfigs,
268
253
  strategy: e.strategy,
269
254
  strategyId: e.strategyId,
270
255
  language: e.language,
@@ -272,10 +257,10 @@ const H = () => ({
272
257
  productIds: e.productIds,
273
258
  filters: e.filters,
274
259
  shuffleProducts: e.shuffleProducts,
275
- currencySettings: i
260
+ currencySettings: n
276
261
  }, s && (this.blockStates = {
277
262
  ...this.blockStates,
278
- [t]: n
263
+ [t]: i
279
264
  });
280
265
  },
281
266
  /**
@@ -294,18 +279,18 @@ const H = () => ({
294
279
  ...t.currencySettings || {}
295
280
  }
296
281
  };
297
- const { triggerRefetch: i = !0 } = e;
298
- i && this.configVersion++;
282
+ const { triggerRefetch: n = !0 } = e;
283
+ n && this.configVersion++;
299
284
  },
300
285
  /**
301
286
  * Creates a filter with the first available attribute and operator pre-selected.
302
287
  */
303
288
  createDefaultFilter(t, e) {
304
- const [r] = this.getFilterList, [i] = N(r == null ? void 0 : r.type);
289
+ const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
305
290
  return {
306
291
  type: "standardFilter",
307
292
  attribute: (r == null ? void 0 : r.value) ?? "",
308
- operator: (i == null ? void 0 : i.value) ?? "",
293
+ operator: (n == null ? void 0 : n.value) ?? "",
309
294
  innerGroupOperator: "*",
310
295
  outerGroupOperator: "*",
311
296
  filterNumber: e,
@@ -361,115 +346,33 @@ const H = () => ({
361
346
  this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
362
347
  },
363
348
  async fetchStrategies() {
364
- for (; R; )
365
- try {
366
- await R;
367
- } catch {
368
- }
369
- if (this.strategiesFetched)
349
+ if (S) {
350
+ await S;
370
351
  return;
371
- const t = b, e = (async () => {
352
+ }
353
+ S = (async () => {
372
354
  this.strategiesLoading = !0;
373
355
  try {
374
- const r = await f.fetchRecommendationStrategies();
375
- if (t !== b)
376
- return;
377
- this.strategies = r, this.strategiesFetched = !0;
356
+ this.strategies = await u.fetchRecommendationStrategies();
378
357
  } finally {
379
- this.strategiesLoading = !1, t === b && (this.strategiesSettled = !0);
358
+ this.strategiesLoading = !1;
380
359
  }
381
360
  })();
382
- R = e;
383
361
  try {
384
- await e;
362
+ await S;
385
363
  } finally {
386
- R = null;
364
+ S = null;
387
365
  }
388
366
  },
389
- /**
390
- * Clears what a block inherited from the id it arrived holding, so the panel fetches for it.
391
- * A re-dropped saved module can keep the source's id — and its "already fetched" entry —
392
- * while the strategy's product count has moved on (SD-149916).
393
- */
394
- resetArrivedBlock(t) {
395
- const e = this.blockStates[t];
396
- e != null && e.recommendationConfigs.strategyId && (e.isInitialized = !1, e.syncedConfigFingerprint = null, this.invalidateStrategies(), this.fetchStrategies().catch(() => {
397
- }));
398
- },
399
- invalidateStrategies() {
400
- this.strategiesFetched = !1, this.strategiesSettled = !1, b += 1;
401
- },
402
- /**
403
- * Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
404
- * the user comes back. `visibilitychange` only: a `focus` listener would also fire when
405
- * focus merely returns from the Stripo canvas iframe to the panel, refetching and
406
- * regenerating the canvas while the user never left the editor (SD-149916).
407
- *
408
- * Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
409
- * strategy in it and come back again — a listener that disarmed on the first return would
410
- * leave that one missing from the list. It disarms on the first return AFTER that tab is
411
- * closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
412
- * once the user actually opens a strategy page, so anyone who never does pays nothing.
413
- * @returns whether a tab actually opened, so callers can skip work that assumes one did
414
- */
415
- _armStrategyPageReturn(t) {
416
- const e = window.open(t, "_blank");
417
- if (!e)
418
- return D().showToaster({
419
- type: L.Error,
420
- message: _()("discovery-strategy.error-description")
421
- }), !1;
422
- e.opener = null, l == null || l();
423
- let r = !1;
424
- const i = () => {
425
- document.hidden || r || (e != null && e.closed && (l == null || l()), r = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
426
- }).finally(() => {
427
- r = !1;
428
- }));
429
- };
430
- return document.addEventListener("visibilitychange", i), l = () => {
431
- document.removeEventListener("visibilitychange", i), l = null;
432
- }, !0;
433
- },
434
- /**
435
- * Reloads the products of the block the user is on, so an edit made in the strategy tab
436
- * lands on the canvas instead of waiting for the assign drawer to be reopened.
437
- *
438
- * Only the selected block: the canvas regeneration is driven off the active block's
439
- * product array, so refreshing an unselected block would fetch without redrawing it.
440
- */
441
- async _refreshAssignedStrategyProducts() {
442
- var e;
443
- const t = this.currentRecommendationId;
444
- t === null || !((e = this.blockStates[t]) != null && e.recommendationConfigs.strategyId) || await this.fetchRecommendationProducts();
445
- },
446
- /** Lets the editor tear the return listeners down when it unmounts. */
447
- disposeStrategyPageReturn() {
448
- l == null || l();
449
- },
450
- /**
451
- * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
452
- * new strategy is offered; the user picks it themselves.
453
- */
454
- openStrategyCreation() {
455
- return this._armStrategyPageReturn(E.RECOMMENDATION_STRATEGY_CREATE_PATH);
456
- },
457
- /**
458
- * Opens the strategy's edit page. Every return refreshes the list so the block reflects the
459
- * edited configuration.
460
- */
461
- openStrategyEdit(t) {
462
- return this._armStrategyPageReturn(A(t));
463
- },
464
367
  async resolveStrategyUrlTemplate(t, e) {
465
- const r = typeof t.updated_at == "string" ? t.updated_at : "", i = r ? `${t.strategy_id}:${r}:${e}` : "", s = i ? this.strategyUrlTemplates[i] : void 0;
368
+ const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
466
369
  if (s)
467
370
  return s;
468
- const { full_path: n = "" } = await f.generateStrategyEndpoint(t, e) ?? {};
469
- return i && n && (this.strategyUrlTemplates = {
371
+ const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
372
+ return n && i && (this.strategyUrlTemplates = {
470
373
  ...this.strategyUrlTemplates,
471
- [i]: n
472
- }), n;
374
+ [n]: i
375
+ }), i;
473
376
  },
474
377
  assignStrategy(t) {
475
378
  this.patchCurrentBlockConfig({
@@ -478,54 +381,50 @@ const H = () => ({
478
381
  });
479
382
  },
480
383
  removeStrategy() {
481
- this.patchCurrentBlockConfig({
482
- strategyId: "",
483
- strategy: "",
484
- size: M.size
485
- });
384
+ this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
486
385
  },
487
386
  // ====================================================================
488
387
  // Shared Data Fetching (fetched once, used by all blocks)
489
388
  // ====================================================================
490
389
  async fetchRecommendationCreateData() {
491
390
  if (!this.activePredictiveAlgorithms.length) {
492
- if (S) {
493
- await S;
391
+ if (f) {
392
+ await f;
494
393
  return;
495
394
  }
496
- S = (async () => {
395
+ f = (async () => {
497
396
  const {
498
397
  activePredictiveAlgorithms: t,
499
398
  languages: e,
500
399
  currencies: r
501
- } = await f.fetchRecommendationCreateData();
400
+ } = await u.fetchRecommendationCreateData();
502
401
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
503
- const i = this.blockStates[this.currentRecommendationId];
504
- i.filterStatus = !!i.recommendationConfigs.filters.length;
402
+ const n = this.blockStates[this.currentRecommendationId];
403
+ n.filterStatus = !!n.recommendationConfigs.filters.length;
505
404
  }
506
405
  this.currencyList = r;
507
406
  })();
508
407
  try {
509
- await S;
408
+ await f;
510
409
  } finally {
511
- S = null;
410
+ f = null;
512
411
  }
513
412
  }
514
413
  },
515
414
  async fetchRecommendationFilters() {
516
415
  if (!Object.keys(this.filterList).length) {
517
- if (p) {
518
- await p;
416
+ if (g) {
417
+ await g;
519
418
  return;
520
419
  }
521
- p = (async () => {
522
- const t = await f.fetchRecommendationFilters();
420
+ g = (async () => {
421
+ const t = await u.fetchRecommendationFilters();
523
422
  this.filterList = t;
524
423
  })();
525
424
  try {
526
- await p;
425
+ await g;
527
426
  } finally {
528
- p = null;
427
+ g = null;
529
428
  }
530
429
  }
531
430
  },
@@ -540,41 +439,41 @@ const H = () => ({
540
439
  deleteFilterGroup(t) {
541
440
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
542
441
  return;
543
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((n) => n.filterGroup !== t), i = [...new Set(r.map((n) => n.filterGroup))].sort((n, o) => n - o), s = new Map(i.map((n, o) => [n, o + 1]));
544
- e.recommendationConfigs.filters = r.map((n) => ({
545
- ...n,
546
- filterGroup: s.get(n.filterGroup) ?? n.filterGroup
442
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), s = new Map(n.map((i, o) => [i, o + 1]));
443
+ e.recommendationConfigs.filters = r.map((i) => ({
444
+ ...i,
445
+ filterGroup: s.get(i.filterGroup) ?? i.filterGroup
547
446
  }));
548
447
  },
549
448
  updateFilter(t) {
550
449
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
551
450
  return;
552
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
451
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
553
452
  if (r !== -1) {
554
- const i = [...e.recommendationConfigs.filters];
555
- i[r] = {
453
+ const n = [...e.recommendationConfigs.filters];
454
+ n[r] = {
556
455
  ...t,
557
- isValid: $(t)
558
- }, e.recommendationConfigs.filters = i;
456
+ isValid: B(t)
457
+ }, e.recommendationConfigs.filters = n;
559
458
  }
560
459
  },
561
460
  deleteFilter(t) {
562
461
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
563
462
  return;
564
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
463
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
565
464
  if (r !== -1) {
566
- let i = [...e.recommendationConfigs.filters];
567
- if (i.splice(r, 1), i.some((n) => n.filterGroup === t.filterGroup)) {
568
- let n = 1;
569
- i = i.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: n++ } : o);
465
+ let n = [...e.recommendationConfigs.filters];
466
+ if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
467
+ let i = 1;
468
+ n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
570
469
  } else {
571
- const n = [...new Set(i.map((a) => a.filterGroup))].sort((a, m) => a - m), o = new Map(n.map((a, m) => [a, m + 1]));
572
- i = i.map((a) => ({
573
- ...a,
574
- filterGroup: o.get(a.filterGroup) ?? a.filterGroup
470
+ const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
471
+ n = n.map((c) => ({
472
+ ...c,
473
+ filterGroup: o.get(c.filterGroup) ?? c.filterGroup
575
474
  }));
576
475
  }
577
- e.recommendationConfigs.filters = i;
476
+ e.recommendationConfigs.filters = n;
578
477
  }
579
478
  },
580
479
  addFilter(t) {
@@ -582,8 +481,8 @@ const H = () => ({
582
481
  return;
583
482
  const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
584
483
  (o) => o.filterGroup === t.filterGroup
585
- ).length + 1, n = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
586
- n !== -1 ? r.splice(n + 1, 0, {
484
+ ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
485
+ i !== -1 ? r.splice(i + 1, 0, {
587
486
  ...t,
588
487
  filterNumber: s
589
488
  }) : r.push({
@@ -592,7 +491,7 @@ const H = () => ({
592
491
  }), e.recommendationConfigs.filters = r;
593
492
  },
594
493
  generateFilterQuery() {
595
- return w(this.recommendationConfigs.filters);
494
+ return k(this.recommendationConfigs.filters);
596
495
  },
597
496
  /**
598
497
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -600,102 +499,83 @@ const H = () => ({
600
499
  * every block's recommendationConfigs across user edits.
601
500
  */
602
501
  hasInvalidBlock() {
603
- return Object.values(this.blockStates).some((t) => !K(t.recommendationConfigs, this));
604
- },
605
- /**
606
- * Which required fields are missing across the design's blocks, so the save
607
- * toaster can name the cause instead of always showing the generic message.
608
- */
609
- invalidBlockFields() {
610
- return Object.values(this.blockStates).flatMap((t) => q(t.recommendationConfigs, this));
502
+ return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
611
503
  },
612
504
  // ====================================================================
613
505
  // Per-Block Product Fetching
614
506
  // ====================================================================
615
507
  async fetchRecommendationProducts() {
616
- if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
617
- return;
618
- const t = [
619
- this.currentRecommendationId,
620
- this.configVersion,
621
- b
622
- ].join(":");
623
- if (y && I === t) {
624
- await y;
625
- return;
626
- }
627
- I = t, y = this._doFetchProducts();
628
- try {
629
- await y;
630
- } finally {
631
- I === t && (y = null, I = "");
508
+ if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
509
+ if (h) {
510
+ await h;
511
+ return;
512
+ }
513
+ h = this._doFetchProducts();
514
+ try {
515
+ await h;
516
+ } finally {
517
+ h = null;
518
+ }
632
519
  }
633
520
  },
634
521
  async _doFetchProducts() {
635
- var h;
636
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, i = k();
637
- if (r.strategyId && i.isFeatureEnabled("reusableRecommendationStrategy")) {
522
+ var d;
523
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
524
+ if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
638
525
  await this._doFetchStrategyProducts(t);
639
526
  return;
640
527
  }
641
- const s = (g.get(t) ?? 0) + 1;
642
- g.set(t, s);
643
- const n = parseInt(r.size) || 6;
644
- if (!r.strategy) {
645
- this._setBlockProducts(t, [], n);
646
- return;
647
- }
648
- const o = r.filters.filter((d) => d.isValid), a = w(o), m = ((h = v().find((d) => d.key === r.strategy)) == null ? void 0 : h.path) || "", c = {
528
+ const s = r.filters.filter((m) => m.isValid), i = k(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
649
529
  locale: r.language,
650
530
  currency: r.currencySettings.value,
651
- partnerName: i.partnerName,
531
+ partnerName: n.partnerName,
652
532
  size: r.size,
653
533
  details: !0,
654
- campaignId: i.variationId
534
+ campaignId: n.variationId
655
535
  };
656
- r.strategy === "manualMerchandising" ? c.productId = j(r.productIds) : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), a && (c.filter = a), r.shuffleProducts && (c.shuffle = !0), Object.assign(
657
- c,
658
- V(i.partnerName, r.strategy)
536
+ r.strategy === "manualMerchandising" ? a.productId = A(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
537
+ a,
538
+ x(n.partnerName, r.strategy)
659
539
  );
660
- let u;
540
+ let l;
661
541
  try {
662
- u = await f.fetchRecommendationProducts(m, c);
542
+ l = await u.fetchRecommendationProducts(o, a);
663
543
  } catch {
664
- u = [];
544
+ l = [];
665
545
  }
666
- g.get(t) === s && this._setBlockProducts(t, u, n);
546
+ this._setBlockProducts(t, l, c);
667
547
  },
668
548
  async _doFetchStrategyProducts(t) {
669
- const e = (g.get(t) ?? 0) + 1;
670
- g.set(t, e);
549
+ const e = (p.get(t) ?? 0) + 1;
550
+ p.set(t, e);
671
551
  const { recommendationConfigs: r } = this.blockStates[t];
672
- let i = [], s = parseInt(r.size) || 6;
552
+ let n = [], s = parseInt(r.size) || 6;
673
553
  try {
674
554
  await this.fetchStrategies();
675
- const n = this.strategies.find(
555
+ const i = this.strategies.find(
676
556
  (o) => String(o.strategy_id) === r.strategyId
677
557
  );
678
- if (n) {
679
- s = parseInt(String(n.size ?? "")) || s;
680
- const o = r.currencySettings.value, m = (await this.resolveStrategyUrlTemplate(n, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), c = m.indexOf("?"), u = c === -1 ? m : m.slice(0, c), h = (c === -1 ? "" : m.slice(c + 1)).split("&").filter((C) => C && !C.startsWith("user_id=")), d = h.length ? `${u}?${h.join("&")}` : u;
681
- d && (i = await f.fetchRecommendationProductsByUrl(d));
558
+ if (i) {
559
+ s = parseInt(String(i.size ?? "")) || s;
560
+ const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = m.length ? `${d}?${m.join("&")}` : d;
561
+ y && (n = await u.fetchRecommendationProductsByUrl(y));
682
562
  }
683
563
  } catch {
684
- i = [];
564
+ n = [];
685
565
  }
686
- g.get(t) === e && this._setBlockProducts(t, i, s);
566
+ p.get(t) === e && this._setBlockProducts(t, n, s);
687
567
  },
688
568
  _setBlockProducts(t, e, r) {
689
569
  if (!this.blockStates[t])
690
570
  return;
691
- const i = e.length > 0 ? e : F(r);
571
+ const n = e.length > 0 ? e : R(r);
692
572
  this.blockStates[t].recommendationProducts = [
693
- ...i.slice(0, r),
694
- ...F(Math.max(0, r - i.length))
573
+ ...n.slice(0, r),
574
+ ...R(Math.max(0, r - n.length))
695
575
  ];
696
576
  }
697
577
  }
698
578
  });
699
579
  export {
700
- mt as useRecommendationExtensionStore
580
+ Y as useRecommendationExtensionStore
701
581
  };