@useinsider/guido 3.17.0-beta.ddd4dde → 3.17.0-beta.e324492

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