@useinsider/guido 3.18.2-beta.dfce34a → 3.18.2-beta.ec1fd57

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