@useinsider/guido 3.17.0 → 3.18.0

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 (110) hide show
  1. package/README.md +6 -5
  2. package/dist/@types/config/schemas.js +7 -6
  3. package/dist/components/Guido.vue.js +10 -10
  4. package/dist/components/Guido.vue2.js +82 -76
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +21 -0
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +106 -0
  7. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
  8. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
  10. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
  11. package/dist/composables/useCustomInterfaceAppearance.js +52 -38
  12. package/dist/composables/useModuleRepair.js +33 -0
  13. package/dist/composables/useRecommendation.js +41 -34
  14. package/dist/composables/useSave.js +30 -29
  15. package/dist/composables/useStripo.js +15 -15
  16. package/dist/composables/useSyncModuleExtractor.js +15 -13
  17. package/dist/composables/validators/useSyncModuleBlockValidator.js +24 -0
  18. package/dist/config/i18n/en/labels.json.js +1 -1
  19. package/dist/config/migrator/index.js +9 -8
  20. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  21. package/dist/config/migrator/recommendation/extractors.js +29 -24
  22. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  23. package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
  24. package/dist/config/migrator/recommendationMigrator.js +31 -25
  25. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  26. package/dist/enums/academy.js +2 -1
  27. package/dist/enums/date.js +5 -3
  28. package/dist/enums/extensions/recommendationBlock.js +3 -1
  29. package/dist/extensions/Blocks/Items/block.js +118 -49
  30. package/dist/extensions/Blocks/Items/constants/currency.js +25 -0
  31. package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
  32. package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
  33. package/dist/extensions/Blocks/Items/template.js +153 -152
  34. package/dist/extensions/Blocks/Items/utils/constants.js +4 -0
  35. package/dist/extensions/Blocks/Recommendation/block.js +35 -29
  36. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  37. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  38. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +29 -27
  39. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
  40. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +309 -236
  41. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +241 -180
  42. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +124 -0
  43. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  44. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  45. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  46. package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
  47. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  48. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +175 -79
  49. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  50. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  51. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  52. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
  53. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +10 -6
  54. package/dist/extensions/Blocks/common-control.js +22 -19
  55. package/dist/guido.css +1 -1
  56. package/dist/services/recommendationApi.js +69 -30
  57. package/dist/src/@types/config/schemas.d.ts +2 -0
  58. package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
  59. package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
  60. package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
  61. package/dist/src/composables/useConfig.d.ts +2 -0
  62. package/dist/src/composables/useModuleRepair.d.ts +18 -0
  63. package/dist/src/composables/useRecommendation.d.ts +1 -0
  64. package/dist/src/composables/useSyncModuleExtractor.d.ts +2 -0
  65. package/dist/src/composables/validators/useSyncModuleBlockValidator.d.ts +3 -0
  66. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  67. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
  68. package/dist/src/enums/academy.d.ts +1 -0
  69. package/dist/src/enums/date.d.ts +1 -0
  70. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  71. package/dist/src/extensions/Blocks/Items/block.d.ts +35 -0
  72. package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +43 -0
  73. package/dist/src/extensions/Blocks/Items/utils/constants.d.ts +6 -0
  74. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  75. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  76. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +3 -6
  77. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
  78. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
  79. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
  80. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  81. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
  82. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +16 -0
  83. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  84. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  85. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
  86. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +176 -10
  87. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  88. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  89. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
  90. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +6 -2
  91. package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
  92. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  93. package/dist/src/services/recommendationApi.d.ts +4 -1
  94. package/dist/src/stores/config.d.ts +18 -0
  95. package/dist/src/stores/save-as-template.d.ts +4 -3
  96. package/dist/src/utils/genericUtil.d.ts +5 -0
  97. package/dist/src/utils/itemsCurrencyRepair.d.ts +17 -0
  98. package/dist/static/assets/icons/line-change.svg.js +5 -0
  99. package/dist/static/assets/icons/line-delete.svg.js +5 -0
  100. package/dist/static/assets/icons/line-plus.svg.js +5 -0
  101. package/dist/static/styles/components/recommendation-strategy.css.js +155 -0
  102. package/dist/static/styles/customEditorStyle.css.js +3 -1
  103. package/dist/utils/dateUtil.js +23 -10
  104. package/dist/utils/genericUtil.js +28 -27
  105. package/dist/utils/itemsCurrencyRepair.js +39 -0
  106. package/dist/utils/pairProductVariables.js +58 -58
  107. package/dist/utils/templatePreparation.js +35 -34
  108. package/package.json +3 -2
  109. package/dist/composables/useModuleDynamicContentRepair.js +0 -37
  110. package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -13
@@ -1,21 +1,22 @@
1
- import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as G } from "../../../../stores/config.js";
4
- import { defineStore as P } 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 P } from "../../../../stores/config.js";
4
+ import { defineStore as F } from "pinia";
5
5
  import "../constants/selectors.js";
6
- import { DEFAULT_MOBILE_CARDS_IN_ROW as F, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
7
- import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
8
- import { getDefaultProducts as S } from "../templates/utils.js";
9
- import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
10
- import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
11
- import { sanitizeProductIds as N } from "../utils/productIds.js";
12
- import { isFilterValid as x } from "../validation/filterSchema.js";
13
- import { isConfigValid as L } from "../validation/requiredFields.js";
14
- const h = y();
15
- let m = null, u = null, d = null;
16
- function k() {
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, h = null, g = null, S = null;
16
+ const p = /* @__PURE__ */ new Map();
17
+ function w() {
17
18
  return {
18
- cardsInRow: D,
19
+ cardsInRow: U,
19
20
  currencySettings: {
20
21
  name: "USD",
21
22
  value: "USD",
@@ -29,13 +30,14 @@ function k() {
29
30
  productIds: [],
30
31
  id: 1,
31
32
  language: "en_US",
32
- mobileCardsInRow: F,
33
+ mobileCardsInRow: _,
33
34
  mobileLayoutEnabled: !1,
34
35
  orientation: "grid",
35
36
  recommendedProducts: [],
36
37
  sendProductRequestFlag: !1,
37
38
  shuffleProducts: !1,
38
39
  strategy: "mostPopular",
40
+ strategyId: "",
39
41
  textTrimming: !0,
40
42
  unresponsive: !1,
41
43
  size: "6",
@@ -44,28 +46,33 @@ function k() {
44
46
  priceHideIfSameAsDiscounted: !1
45
47
  };
46
48
  }
47
- function I() {
49
+ function C() {
48
50
  return {
49
- recommendationConfigs: k(),
51
+ recommendationConfigs: w(),
50
52
  recommendationProducts: [],
51
53
  filterStatus: !1,
52
54
  filterSelectionDrawerStatus: !1,
55
+ assignStrategyDrawerStatus: !1,
56
+ removeStrategyModalStatus: !1,
53
57
  filterGroup: 1,
54
58
  isInitialized: !1,
55
59
  filterSnapshot: null
56
60
  };
57
61
  }
58
- const U = () => ({
62
+ const z = () => ({
59
63
  recommendationCampaignUrls: {},
60
64
  activePredictiveAlgorithms: [],
61
65
  languages: {},
62
66
  currencyList: [],
63
67
  filterList: {},
68
+ strategies: [],
69
+ strategiesLoading: !1,
70
+ strategyUrlTemplates: {},
64
71
  blockStates: {},
65
72
  currentRecommendationId: null,
66
73
  configVersion: 0
67
- }), H = P("guidoRecommendationExtension", {
68
- state: () => U(),
74
+ }), Y = F("guidoRecommendationExtension", {
75
+ state: () => z(),
69
76
  getters: {
70
77
  // ====================================================================
71
78
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -75,7 +82,7 @@ const U = () => ({
75
82
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
76
83
  */
77
84
  recommendationConfigs(t) {
78
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
85
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
79
86
  },
80
87
  /**
81
88
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -89,6 +96,16 @@ const U = () => ({
89
96
  filterSelectionDrawerStatus(t) {
90
97
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
91
98
  },
99
+ assignStrategyDrawerStatus(t) {
100
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
101
+ },
102
+ removeStrategyModalStatus(t) {
103
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
104
+ },
105
+ assignedStrategy(t) {
106
+ const { strategyId: e } = this.recommendationConfigs;
107
+ return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
108
+ },
92
109
  /**
93
110
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
94
111
  */
@@ -120,9 +137,9 @@ const U = () => ({
120
137
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
121
138
  },
122
139
  getActivePredictiveAlgorithms: (t) => {
123
- const e = g(), r = [];
124
- return t.activePredictiveAlgorithms.filter((n) => !w.includes(n)).forEach((n) => {
125
- r.push(...e.filter((c) => c.id === n));
140
+ const e = b(), r = [];
141
+ return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
142
+ r.push(...e.filter((s) => s.id === n));
126
143
  }), r.map((n) => ({
127
144
  text: n.name,
128
145
  value: n.key
@@ -139,7 +156,7 @@ const U = () => ({
139
156
  getFilterList() {
140
157
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
141
158
  let e;
142
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
159
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : v.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
143
160
  text: t.displayName,
144
161
  value: e,
145
162
  type: t.attributeType
@@ -161,7 +178,7 @@ const U = () => ({
161
178
  setCurrentBlock(t) {
162
179
  this.blockStates[t] || (this.blockStates = {
163
180
  ...this.blockStates,
164
- [t]: I()
181
+ [t]: C()
165
182
  }), this.currentRecommendationId = t;
166
183
  },
167
184
  /**
@@ -193,10 +210,10 @@ const U = () => ({
193
210
  [e]: o
194
211
  };
195
212
  }
196
- const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
213
+ const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
197
214
  i && (this.recommendationCampaignUrls = {
198
215
  ...this.recommendationCampaignUrls,
199
- [c]: i
216
+ [s]: i
200
217
  });
201
218
  },
202
219
  /**
@@ -221,7 +238,7 @@ const U = () => ({
221
238
  * `isInitialized`) alone.
222
239
  */
223
240
  seedBlockUrlConfig(t, e) {
224
- const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
241
+ const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
225
242
  name: e.currencyCode,
226
243
  value: e.currencyCode,
227
244
  symbol: e.currencyCode,
@@ -229,17 +246,18 @@ const U = () => ({
229
246
  decimalCount: String(e.currencyDecimalCount),
230
247
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
231
248
  thousandSeparator: r(e.currencyThousandSeparator, ".")
232
- }, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
249
+ }, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
233
250
  i.recommendationConfigs = {
234
251
  ...i.recommendationConfigs,
235
252
  strategy: e.strategy,
253
+ strategyId: e.strategyId,
236
254
  language: e.language,
237
255
  size: e.size,
238
256
  productIds: e.productIds,
239
257
  filters: e.filters,
240
258
  shuffleProducts: e.shuffleProducts,
241
259
  currencySettings: n
242
- }, c && (this.blockStates = {
260
+ }, s && (this.blockStates = {
243
261
  ...this.blockStates,
244
262
  [t]: i
245
263
  });
@@ -267,7 +285,7 @@ const U = () => ({
267
285
  * Creates a filter with the first available attribute and operator pre-selected.
268
286
  */
269
287
  createDefaultFilter(t, e) {
270
- const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
288
+ const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
271
289
  return {
272
290
  type: "standardFilter",
273
291
  attribute: (r == null ? void 0 : r.value) ?? "",
@@ -314,21 +332,71 @@ const U = () => ({
314
332
  const t = this.blockStates[this.currentRecommendationId];
315
333
  t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
316
334
  },
335
+ openAssignStrategyDrawer() {
336
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !0);
337
+ },
338
+ closeAssignStrategyDrawer() {
339
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
340
+ },
341
+ openRemoveStrategyModal() {
342
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !0);
343
+ },
344
+ closeRemoveStrategyModal() {
345
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
346
+ },
347
+ async fetchStrategies() {
348
+ if (S) {
349
+ await S;
350
+ return;
351
+ }
352
+ S = (async () => {
353
+ this.strategiesLoading = !0;
354
+ try {
355
+ this.strategies = await u.fetchRecommendationStrategies();
356
+ } finally {
357
+ this.strategiesLoading = !1;
358
+ }
359
+ })();
360
+ try {
361
+ await S;
362
+ } finally {
363
+ S = null;
364
+ }
365
+ },
366
+ async resolveStrategyUrlTemplate(t, e) {
367
+ const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
368
+ if (s)
369
+ return s;
370
+ const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
371
+ return n && i && (this.strategyUrlTemplates = {
372
+ ...this.strategyUrlTemplates,
373
+ [n]: i
374
+ }), i;
375
+ },
376
+ assignStrategy(t) {
377
+ this.patchCurrentBlockConfig({
378
+ strategyId: String(t.strategy_id),
379
+ ...t.size !== void 0 ? { size: String(t.size) } : {}
380
+ });
381
+ },
382
+ removeStrategy() {
383
+ this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
384
+ },
317
385
  // ====================================================================
318
386
  // Shared Data Fetching (fetched once, used by all blocks)
319
387
  // ====================================================================
320
388
  async fetchRecommendationCreateData() {
321
389
  if (!this.activePredictiveAlgorithms.length) {
322
- if (m) {
323
- await m;
390
+ if (f) {
391
+ await f;
324
392
  return;
325
393
  }
326
- m = (async () => {
394
+ f = (async () => {
327
395
  const {
328
396
  activePredictiveAlgorithms: t,
329
397
  languages: e,
330
398
  currencies: r
331
- } = await h.fetchRecommendationCreateData();
399
+ } = await u.fetchRecommendationCreateData();
332
400
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
333
401
  const n = this.blockStates[this.currentRecommendationId];
334
402
  n.filterStatus = !!n.recommendationConfigs.filters.length;
@@ -336,26 +404,26 @@ const U = () => ({
336
404
  this.currencyList = r;
337
405
  })();
338
406
  try {
339
- await m;
407
+ await f;
340
408
  } finally {
341
- m = null;
409
+ f = null;
342
410
  }
343
411
  }
344
412
  },
345
413
  async fetchRecommendationFilters() {
346
414
  if (!Object.keys(this.filterList).length) {
347
- if (u) {
348
- await u;
415
+ if (h) {
416
+ await h;
349
417
  return;
350
418
  }
351
- u = (async () => {
352
- const t = await h.fetchRecommendationFilters();
419
+ h = (async () => {
420
+ const t = await u.fetchRecommendationFilters();
353
421
  this.filterList = t;
354
422
  })();
355
423
  try {
356
- await u;
424
+ await h;
357
425
  } finally {
358
- u = null;
426
+ h = null;
359
427
  }
360
428
  }
361
429
  },
@@ -370,10 +438,10 @@ const U = () => ({
370
438
  deleteFilterGroup(t) {
371
439
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
372
440
  return;
373
- 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), c = new Map(n.map((i, o) => [i, o + 1]));
441
+ 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]));
374
442
  e.recommendationConfigs.filters = r.map((i) => ({
375
443
  ...i,
376
- filterGroup: c.get(i.filterGroup) ?? i.filterGroup
444
+ filterGroup: s.get(i.filterGroup) ?? i.filterGroup
377
445
  }));
378
446
  },
379
447
  updateFilter(t) {
@@ -384,7 +452,7 @@ const U = () => ({
384
452
  const n = [...e.recommendationConfigs.filters];
385
453
  n[r] = {
386
454
  ...t,
387
- isValid: x(t)
455
+ isValid: B(t)
388
456
  }, e.recommendationConfigs.filters = n;
389
457
  }
390
458
  },
@@ -398,10 +466,10 @@ const U = () => ({
398
466
  let i = 1;
399
467
  n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
400
468
  } else {
401
- const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
402
- n = n.map((s) => ({
403
- ...s,
404
- filterGroup: o.get(s.filterGroup) ?? s.filterGroup
469
+ const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
470
+ n = n.map((c) => ({
471
+ ...c,
472
+ filterGroup: o.get(c.filterGroup) ?? c.filterGroup
405
473
  }));
406
474
  }
407
475
  e.recommendationConfigs.filters = n;
@@ -410,19 +478,19 @@ const U = () => ({
410
478
  addFilter(t) {
411
479
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
412
480
  return;
413
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
481
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
414
482
  (o) => o.filterGroup === t.filterGroup
415
483
  ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
416
484
  i !== -1 ? r.splice(i + 1, 0, {
417
485
  ...t,
418
- filterNumber: c
486
+ filterNumber: s
419
487
  }) : r.push({
420
488
  ...t,
421
- filterNumber: c
489
+ filterNumber: s
422
490
  }), e.recommendationConfigs.filters = r;
423
491
  },
424
492
  generateFilterQuery() {
425
- return b(this.recommendationConfigs.filters);
493
+ return k(this.recommendationConfigs.filters);
426
494
  },
427
495
  /**
428
496
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -430,55 +498,83 @@ const U = () => ({
430
498
  * every block's recommendationConfigs across user edits.
431
499
  */
432
500
  hasInvalidBlock() {
433
- return Object.values(this.blockStates).some((t) => !L(t.recommendationConfigs, this));
501
+ return Object.values(this.blockStates).some((t) => !M(t.recommendationConfigs, this));
434
502
  },
435
503
  // ====================================================================
436
504
  // Per-Block Product Fetching
437
505
  // ====================================================================
438
506
  async fetchRecommendationProducts() {
439
507
  if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
440
- if (d) {
441
- await d;
508
+ if (g) {
509
+ await g;
442
510
  return;
443
511
  }
444
- d = this._doFetchProducts();
512
+ g = this._doFetchProducts();
445
513
  try {
446
- await d;
514
+ await g;
447
515
  } finally {
448
- d = null;
516
+ g = null;
449
517
  }
450
518
  }
451
519
  },
452
520
  async _doFetchProducts() {
453
- var p;
454
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
521
+ var d;
522
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = P();
523
+ if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
524
+ await this._doFetchStrategyProducts(t);
525
+ return;
526
+ }
527
+ 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 = {
455
528
  locale: r.language,
456
529
  currency: r.currencySettings.value,
457
- partnerName: o.partnerName,
530
+ partnerName: n.partnerName,
458
531
  size: r.size,
459
532
  details: !0,
460
- campaignId: o.variationId
533
+ campaignId: n.variationId
461
534
  };
462
- r.strategy === "manualMerchandising" ? a.productId = N(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
535
+ 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(
463
536
  a,
464
- v(o.partnerName, r.strategy)
537
+ x(n.partnerName, r.strategy)
465
538
  );
466
- let f;
539
+ let l;
467
540
  try {
468
- f = await h.fetchRecommendationProducts(i, a);
541
+ l = await u.fetchRecommendationProducts(o, a);
469
542
  } catch {
470
- f = [];
543
+ l = [];
471
544
  }
472
- if (this.blockStates[t]) {
473
- const l = f.length > 0 ? f : S(s);
474
- l.length < s ? this.blockStates[t].recommendationProducts = [
475
- ...l,
476
- ...S(s - l.length)
477
- ] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
545
+ this._setBlockProducts(t, l, c);
546
+ },
547
+ async _doFetchStrategyProducts(t) {
548
+ const e = (p.get(t) ?? 0) + 1;
549
+ p.set(t, e);
550
+ const { recommendationConfigs: r } = this.blockStates[t];
551
+ let n = [], s = parseInt(r.size) || 6;
552
+ try {
553
+ await this.fetchStrategies();
554
+ const i = this.strategies.find(
555
+ (o) => String(o.strategy_id) === r.strategyId
556
+ );
557
+ if (i) {
558
+ s = parseInt(String(i.size ?? "")) || s;
559
+ 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;
560
+ y && (n = await u.fetchRecommendationProductsByUrl(y));
561
+ }
562
+ } catch {
563
+ n = [];
478
564
  }
565
+ p.get(t) === e && this._setBlockProducts(t, n, s);
566
+ },
567
+ _setBlockProducts(t, e, r) {
568
+ if (!this.blockStates[t])
569
+ return;
570
+ const n = e.length > 0 ? e : R(r);
571
+ this.blockStates[t].recommendationProducts = [
572
+ ...n.slice(0, r),
573
+ ...R(Math.max(0, r - n.length))
574
+ ];
479
575
  }
480
576
  }
481
577
  });
482
578
  export {
483
- H as useRecommendationExtensionStore
579
+ Y as useRecommendationExtensionStore
484
580
  };
@@ -1,6 +1,6 @@
1
1
  import { ATTR_PRODUCT_PRICE as f, ATTR_PRODUCT_OLD_PRICE as O } from "../../constants/selectors.js";
2
2
  import { DEFAULT_PRODUCTS_PER_ROW as w } from "../../constants/layout.js";
3
- import { getDefaultProducts as A, DEFAULTS as g, createBlockTemplate as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
3
+ import { createBlockTemplate as A, getDefaultProducts as g, DEFAULTS as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
4
4
  import { DEFAULT_CELL_PADDING as k, renderInlineGridPriceCell as H, buildFillerCell as x, gridElementRenderer as y } from "./elementRenderer.js";
5
5
  const G = `
6
6
  <tr class="recommendation-product-row">
@@ -69,8 +69,8 @@ function M(t, r, o, e = {}, c = {}) {
69
69
  );
70
70
  }
71
71
  function Q(t) {
72
- const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = U("grid", r), e = A(), c = M(e, w);
73
- return o.replace("{-{-TITLE-}-}", g.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
72
+ const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = A("grid", r), e = g(), c = M(e, w);
73
+ return o.replace("{-{-TITLE-}-}", U.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
74
74
  }
75
75
  export {
76
76
  Q as getDefaultTemplate,
@@ -0,0 +1,33 @@
1
+ import { RecommendationBlockId as r } from "../constants/blockIds.js";
2
+ import { DEFAULT_ROW_SPACING as l } from "../constants/layout.js";
3
+ import { CSS_CLASS_ATTRIBUTE_ROW as d, ATTR_RECOMMENDATION_TITLE as n, ATTR_DATA_VISIBILITY as A, CSS_CLASS_TITLE_CELL as _, CSS_CLASS_SPACER as c } from "../constants/selectors.js";
4
+ const a = "You May Also Like!", i = '<p style="font-size: 28px; color: #333333;"><strong>{-{-TITLE-}-}</strong></p>';
5
+ function E(s = i, t = !0, T = l) {
6
+ const e = `class="${d}" data-attribute-type="${n}" ${A}="${t ? "1" : "0"}"`, o = t ? "" : ' style="display: none;"';
7
+ return `
8
+ <tr ${e}${o}>
9
+ <td>
10
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
11
+ <tbody>
12
+ <tr>
13
+ <td
14
+ class="esd-block-text ${_} es-p10t es-p10b es-p20l es-p20r"
15
+ align="center"
16
+ esd-extension-block-id="${r.TITLE}">
17
+ ${s}
18
+ </td>
19
+ </tr>
20
+ </tbody>
21
+ </table>
22
+ </td>
23
+ </tr>
24
+ <tr ${e}${o}>
25
+ <td class="${c}" style="height: ${T}px;"></td>
26
+ </tr>
27
+ `;
28
+ }
29
+ export {
30
+ i as DEFAULT_TITLE_PARAGRAPH,
31
+ a as DEFAULT_TITLE_TEXT,
32
+ E as buildTitleRows
33
+ };