@useinsider/guido 3.17.0 → 3.18.0-beta.41e529d

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 (120) hide show
  1. package/README.md +6 -5
  2. package/dist/@types/config/schemas.js +10 -7
  3. package/dist/components/Guido.vue.js +10 -10
  4. package/dist/components/Guido.vue2.js +86 -78
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +21 -0
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +131 -0
  7. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
  8. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
  9. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
  10. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
  11. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
  12. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
  13. package/dist/composables/useCustomInterfaceAppearance.js +56 -38
  14. package/dist/composables/useLegacyStrategyConversion.js +52 -0
  15. package/dist/composables/useModuleRepair.js +33 -0
  16. package/dist/composables/useRecommendation.js +41 -34
  17. package/dist/composables/useSave.js +30 -29
  18. package/dist/composables/useStripo.js +15 -15
  19. package/dist/composables/useSyncModuleExtractor.js +15 -13
  20. package/dist/composables/validators/useSyncModuleBlockValidator.js +24 -0
  21. package/dist/config/i18n/en/labels.json.js +1 -1
  22. package/dist/config/migrator/index.js +9 -8
  23. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  24. package/dist/config/migrator/recommendation/extractors.js +29 -24
  25. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  26. package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
  27. package/dist/config/migrator/recommendationMigrator.js +31 -25
  28. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  29. package/dist/enums/academy.js +2 -1
  30. package/dist/enums/date.js +5 -3
  31. package/dist/enums/extensions/recommendationBlock.js +4 -1
  32. package/dist/extensions/Blocks/Items/block.js +118 -49
  33. package/dist/extensions/Blocks/Items/constants/currency.js +25 -0
  34. package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
  35. package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
  36. package/dist/extensions/Blocks/Items/template.js +153 -152
  37. package/dist/extensions/Blocks/Items/utils/constants.js +4 -0
  38. package/dist/extensions/Blocks/Recommendation/block.js +35 -29
  39. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  40. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  41. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +29 -27
  42. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
  43. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +309 -236
  44. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +242 -180
  45. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +159 -0
  46. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  47. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  48. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  49. package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
  50. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  51. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +217 -80
  52. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  53. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  54. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  55. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +58 -0
  56. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
  57. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +10 -6
  58. package/dist/extensions/Blocks/common-control.js +22 -19
  59. package/dist/guido.css +1 -1
  60. package/dist/services/recommendationApi.js +81 -33
  61. package/dist/src/@types/config/schemas.d.ts +6 -0
  62. package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
  63. package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
  64. package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
  65. package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
  66. package/dist/src/composables/useConfig.d.ts +4 -0
  67. package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
  68. package/dist/src/composables/useModuleRepair.d.ts +18 -0
  69. package/dist/src/composables/useRecommendation.d.ts +1 -0
  70. package/dist/src/composables/useSyncModuleExtractor.d.ts +2 -0
  71. package/dist/src/composables/validators/useSyncModuleBlockValidator.d.ts +3 -0
  72. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  73. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
  74. package/dist/src/enums/academy.d.ts +1 -0
  75. package/dist/src/enums/date.d.ts +1 -0
  76. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  77. package/dist/src/extensions/Blocks/Items/block.d.ts +35 -0
  78. package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +43 -0
  79. package/dist/src/extensions/Blocks/Items/utils/constants.d.ts +6 -0
  80. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  81. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  82. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +3 -6
  83. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
  84. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
  85. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
  86. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  87. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
  88. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +17 -0
  89. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  90. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  91. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
  92. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +229 -10
  93. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  94. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  95. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +39 -0
  96. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
  97. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +6 -2
  98. package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
  99. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  100. package/dist/src/services/recommendationApi.d.ts +5 -1
  101. package/dist/src/stores/config.d.ts +178 -0
  102. package/dist/src/stores/save-as-template.d.ts +4 -3
  103. package/dist/src/utils/genericUtil.d.ts +5 -0
  104. package/dist/src/utils/itemsCurrencyRepair.d.ts +17 -0
  105. package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
  106. package/dist/static/assets/icons/line-change.svg.js +5 -0
  107. package/dist/static/assets/icons/line-delete.svg.js +5 -0
  108. package/dist/static/assets/icons/line-info.svg.js +5 -0
  109. package/dist/static/assets/icons/line-plus.svg.js +5 -0
  110. package/dist/static/styles/components/recommendation-strategy.css.js +220 -0
  111. package/dist/static/styles/customEditorStyle.css.js +3 -1
  112. package/dist/stores/config.js +66 -59
  113. package/dist/utils/dateUtil.js +23 -10
  114. package/dist/utils/genericUtil.js +28 -27
  115. package/dist/utils/itemsCurrencyRepair.js +39 -0
  116. package/dist/utils/pairProductVariables.js +58 -58
  117. package/dist/utils/templatePreparation.js +35 -34
  118. package/package.json +3 -2
  119. package/dist/composables/useModuleDynamicContentRepair.js +0 -37
  120. package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -13
@@ -1,21 +1,23 @@
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 D, PriceAttributes as F } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as R } from "../../../../stores/config.js";
4
+ import { defineStore as L } 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 U, DEFAULT_CARDS_IN_ROW as _ } from "../constants/layout.js";
7
+ import { DEFAULT_NODE_CONFIG as N, CURRENT_CONFIG_VERSION as w, EXCLUDED_ALGORITHM_IDS as M } from "../constants/defaultConfig.js";
8
+ import { getDefaultProducts as k } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as C } from "../utils/filterUtil.js";
10
+ import { isLegacyStrategyConfig as x } from "../utils/legacyStrategyMigration.js";
11
+ import { getPartnerRecommendationParams as B } from "../utils/partnerCustomizations.js";
12
+ import { sanitizeProductIds as z } from "../utils/productIds.js";
13
+ import { isFilterValid as A } from "../validation/filterSchema.js";
14
+ import { isConfigValid as O } from "../validation/requiredFields.js";
15
+ const u = P();
16
+ let f = null, g = null, h = null, S = null;
17
+ const p = /* @__PURE__ */ new Map();
18
+ function G() {
17
19
  return {
18
- cardsInRow: D,
20
+ cardsInRow: _,
19
21
  currencySettings: {
20
22
  name: "USD",
21
23
  value: "USD",
@@ -29,13 +31,15 @@ function k() {
29
31
  productIds: [],
30
32
  id: 1,
31
33
  language: "en_US",
32
- mobileCardsInRow: F,
34
+ mobileCardsInRow: U,
33
35
  mobileLayoutEnabled: !1,
34
36
  orientation: "grid",
35
37
  recommendedProducts: [],
36
38
  sendProductRequestFlag: !1,
37
39
  shuffleProducts: !1,
38
40
  strategy: "mostPopular",
41
+ strategyId: "",
42
+ nodeConfigVersion: w,
39
43
  textTrimming: !0,
40
44
  unresponsive: !1,
41
45
  size: "6",
@@ -44,28 +48,35 @@ function k() {
44
48
  priceHideIfSameAsDiscounted: !1
45
49
  };
46
50
  }
47
- function I() {
51
+ function v() {
48
52
  return {
49
- recommendationConfigs: k(),
53
+ recommendationConfigs: G(),
50
54
  recommendationProducts: [],
51
55
  filterStatus: !1,
52
56
  filterSelectionDrawerStatus: !1,
57
+ assignStrategyDrawerStatus: !1,
58
+ removeStrategyModalStatus: !1,
59
+ legacyStrategyUpdatedModalStatus: !1,
53
60
  filterGroup: 1,
54
61
  isInitialized: !1,
55
- filterSnapshot: null
62
+ filterSnapshot: null,
63
+ legacyConversionLoading: !1
56
64
  };
57
65
  }
58
- const U = () => ({
66
+ const E = () => ({
59
67
  recommendationCampaignUrls: {},
60
68
  activePredictiveAlgorithms: [],
61
69
  languages: {},
62
70
  currencyList: [],
63
71
  filterList: {},
72
+ strategies: [],
73
+ strategiesLoading: !1,
74
+ strategyUrlTemplates: {},
64
75
  blockStates: {},
65
76
  currentRecommendationId: null,
66
77
  configVersion: 0
67
- }), H = P("guidoRecommendationExtension", {
68
- state: () => U(),
78
+ }), et = L("guidoRecommendationExtension", {
79
+ state: () => E(),
69
80
  getters: {
70
81
  // ====================================================================
71
82
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -75,7 +86,7 @@ const U = () => ({
75
86
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
76
87
  */
77
88
  recommendationConfigs(t) {
78
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
89
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : G();
79
90
  },
80
91
  /**
81
92
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -89,6 +100,25 @@ const U = () => ({
89
100
  filterSelectionDrawerStatus(t) {
90
101
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
91
102
  },
103
+ assignStrategyDrawerStatus(t) {
104
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
105
+ },
106
+ removeStrategyModalStatus(t) {
107
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
108
+ },
109
+ isLegacyStrategyBlock() {
110
+ return R().isFeatureEnabled("reusableRecommendationStrategy") && x(this.recommendationConfigs);
111
+ },
112
+ legacyConversionLoading(t) {
113
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyConversionLoading : !1;
114
+ },
115
+ legacyStrategyUpdatedModalStatus(t) {
116
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyStrategyUpdatedModalStatus : !1;
117
+ },
118
+ assignedStrategy(t) {
119
+ const { strategyId: e } = this.recommendationConfigs;
120
+ return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
121
+ },
92
122
  /**
93
123
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
94
124
  */
@@ -120,9 +150,9 @@ const U = () => ({
120
150
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
121
151
  },
122
152
  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));
153
+ const e = b(), r = [];
154
+ return t.activePredictiveAlgorithms.filter((n) => !M.includes(n)).forEach((n) => {
155
+ r.push(...e.filter((s) => s.id === n));
126
156
  }), r.map((n) => ({
127
157
  text: n.name,
128
158
  value: n.key
@@ -139,7 +169,7 @@ const U = () => ({
139
169
  getFilterList() {
140
170
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
141
171
  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, {
172
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : F.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
143
173
  text: t.displayName,
144
174
  value: e,
145
175
  type: t.attributeType
@@ -161,7 +191,7 @@ const U = () => ({
161
191
  setCurrentBlock(t) {
162
192
  this.blockStates[t] || (this.blockStates = {
163
193
  ...this.blockStates,
164
- [t]: I()
194
+ [t]: v()
165
195
  }), this.currentRecommendationId = t;
166
196
  },
167
197
  /**
@@ -193,10 +223,10 @@ const U = () => ({
193
223
  [e]: o
194
224
  };
195
225
  }
196
- const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
226
+ const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
197
227
  i && (this.recommendationCampaignUrls = {
198
228
  ...this.recommendationCampaignUrls,
199
- [c]: i
229
+ [s]: i
200
230
  });
201
231
  },
202
232
  /**
@@ -221,7 +251,7 @@ const U = () => ({
221
251
  * `isInitialized`) alone.
222
252
  */
223
253
  seedBlockUrlConfig(t, e) {
224
- const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
254
+ const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
225
255
  name: e.currencyCode,
226
256
  value: e.currencyCode,
227
257
  symbol: e.currencyCode,
@@ -229,17 +259,18 @@ const U = () => ({
229
259
  decimalCount: String(e.currencyDecimalCount),
230
260
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
231
261
  thousandSeparator: r(e.currencyThousandSeparator, ".")
232
- }, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
262
+ }, s = !this.blockStates[t], i = s ? v() : this.blockStates[t];
233
263
  i.recommendationConfigs = {
234
264
  ...i.recommendationConfigs,
235
265
  strategy: e.strategy,
266
+ strategyId: e.strategyId,
236
267
  language: e.language,
237
268
  size: e.size,
238
269
  productIds: e.productIds,
239
270
  filters: e.filters,
240
271
  shuffleProducts: e.shuffleProducts,
241
272
  currencySettings: n
242
- }, c && (this.blockStates = {
273
+ }, s && (this.blockStates = {
243
274
  ...this.blockStates,
244
275
  [t]: i
245
276
  });
@@ -267,7 +298,7 @@ const U = () => ({
267
298
  * Creates a filter with the first available attribute and operator pre-selected.
268
299
  */
269
300
  createDefaultFilter(t, e) {
270
- const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
301
+ const [r] = this.getFilterList, [n] = D(r == null ? void 0 : r.type);
271
302
  return {
272
303
  type: "standardFilter",
273
304
  attribute: (r == null ? void 0 : r.value) ?? "",
@@ -314,21 +345,99 @@ const U = () => ({
314
345
  const t = this.blockStates[this.currentRecommendationId];
315
346
  t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
316
347
  },
348
+ openAssignStrategyDrawer() {
349
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !0);
350
+ },
351
+ closeAssignStrategyDrawer() {
352
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
353
+ },
354
+ openLegacyStrategyUpdatedModal() {
355
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].legacyStrategyUpdatedModalStatus = !0);
356
+ },
357
+ closeLegacyStrategyUpdatedModal() {
358
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].legacyStrategyUpdatedModalStatus = !1);
359
+ },
360
+ openRemoveStrategyModal() {
361
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !0);
362
+ },
363
+ closeRemoveStrategyModal() {
364
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
365
+ },
366
+ async fetchStrategies() {
367
+ if (S) {
368
+ await S;
369
+ return;
370
+ }
371
+ S = (async () => {
372
+ this.strategiesLoading = !0;
373
+ try {
374
+ this.strategies = await u.fetchRecommendationStrategies();
375
+ } finally {
376
+ this.strategiesLoading = !1;
377
+ }
378
+ })();
379
+ try {
380
+ await S;
381
+ } finally {
382
+ S = null;
383
+ }
384
+ },
385
+ async resolveStrategyUrlTemplate(t, e) {
386
+ const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
387
+ if (s)
388
+ return s;
389
+ const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
390
+ return n && i && (this.strategyUrlTemplates = {
391
+ ...this.strategyUrlTemplates,
392
+ [n]: i
393
+ }), i;
394
+ },
395
+ assignStrategy(t) {
396
+ this.patchCurrentBlockConfig({
397
+ strategyId: String(t.strategy_id),
398
+ ...t.size !== void 0 ? { size: String(t.size) } : {}
399
+ });
400
+ },
401
+ async convertLegacyStrategy(t) {
402
+ const e = this.currentRecommendationId;
403
+ if (e === null || !this.blockStates[e])
404
+ throw new Error("[Guido] convertLegacyStrategy called without an active block");
405
+ this.blockStates[e].legacyConversionLoading = !0;
406
+ try {
407
+ const r = await u.migrateLegacyStrategy(t);
408
+ try {
409
+ await this.fetchStrategies();
410
+ } catch (s) {
411
+ console.error("[Guido] strategy listing refresh after conversion failed", s);
412
+ }
413
+ const n = this.strategies.find((s) => String(s.strategy_id) === r);
414
+ return this.patchCurrentBlockConfig({
415
+ strategyId: r,
416
+ nodeConfigVersion: w,
417
+ ...(n == null ? void 0 : n.size) !== void 0 ? { size: String(n.size) } : {}
418
+ }), r;
419
+ } finally {
420
+ this.blockStates[e].legacyConversionLoading = !1;
421
+ }
422
+ },
423
+ removeStrategy() {
424
+ this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
425
+ },
317
426
  // ====================================================================
318
427
  // Shared Data Fetching (fetched once, used by all blocks)
319
428
  // ====================================================================
320
429
  async fetchRecommendationCreateData() {
321
430
  if (!this.activePredictiveAlgorithms.length) {
322
- if (m) {
323
- await m;
431
+ if (f) {
432
+ await f;
324
433
  return;
325
434
  }
326
- m = (async () => {
435
+ f = (async () => {
327
436
  const {
328
437
  activePredictiveAlgorithms: t,
329
438
  languages: e,
330
439
  currencies: r
331
- } = await h.fetchRecommendationCreateData();
440
+ } = await u.fetchRecommendationCreateData();
332
441
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
333
442
  const n = this.blockStates[this.currentRecommendationId];
334
443
  n.filterStatus = !!n.recommendationConfigs.filters.length;
@@ -336,26 +445,26 @@ const U = () => ({
336
445
  this.currencyList = r;
337
446
  })();
338
447
  try {
339
- await m;
448
+ await f;
340
449
  } finally {
341
- m = null;
450
+ f = null;
342
451
  }
343
452
  }
344
453
  },
345
454
  async fetchRecommendationFilters() {
346
455
  if (!Object.keys(this.filterList).length) {
347
- if (u) {
348
- await u;
456
+ if (g) {
457
+ await g;
349
458
  return;
350
459
  }
351
- u = (async () => {
352
- const t = await h.fetchRecommendationFilters();
460
+ g = (async () => {
461
+ const t = await u.fetchRecommendationFilters();
353
462
  this.filterList = t;
354
463
  })();
355
464
  try {
356
- await u;
465
+ await g;
357
466
  } finally {
358
- u = null;
467
+ g = null;
359
468
  }
360
469
  }
361
470
  },
@@ -370,10 +479,10 @@ const U = () => ({
370
479
  deleteFilterGroup(t) {
371
480
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
372
481
  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]));
482
+ 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
483
  e.recommendationConfigs.filters = r.map((i) => ({
375
484
  ...i,
376
- filterGroup: c.get(i.filterGroup) ?? i.filterGroup
485
+ filterGroup: s.get(i.filterGroup) ?? i.filterGroup
377
486
  }));
378
487
  },
379
488
  updateFilter(t) {
@@ -384,7 +493,7 @@ const U = () => ({
384
493
  const n = [...e.recommendationConfigs.filters];
385
494
  n[r] = {
386
495
  ...t,
387
- isValid: x(t)
496
+ isValid: A(t)
388
497
  }, e.recommendationConfigs.filters = n;
389
498
  }
390
499
  },
@@ -398,10 +507,10 @@ const U = () => ({
398
507
  let i = 1;
399
508
  n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
400
509
  } 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
510
+ const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
511
+ n = n.map((c) => ({
512
+ ...c,
513
+ filterGroup: o.get(c.filterGroup) ?? c.filterGroup
405
514
  }));
406
515
  }
407
516
  e.recommendationConfigs.filters = n;
@@ -410,19 +519,19 @@ const U = () => ({
410
519
  addFilter(t) {
411
520
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
412
521
  return;
413
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
522
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
414
523
  (o) => o.filterGroup === t.filterGroup
415
524
  ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
416
525
  i !== -1 ? r.splice(i + 1, 0, {
417
526
  ...t,
418
- filterNumber: c
527
+ filterNumber: s
419
528
  }) : r.push({
420
529
  ...t,
421
- filterNumber: c
530
+ filterNumber: s
422
531
  }), e.recommendationConfigs.filters = r;
423
532
  },
424
533
  generateFilterQuery() {
425
- return b(this.recommendationConfigs.filters);
534
+ return C(this.recommendationConfigs.filters);
426
535
  },
427
536
  /**
428
537
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -430,55 +539,83 @@ const U = () => ({
430
539
  * every block's recommendationConfigs across user edits.
431
540
  */
432
541
  hasInvalidBlock() {
433
- return Object.values(this.blockStates).some((t) => !L(t.recommendationConfigs, this));
542
+ return Object.values(this.blockStates).some((t) => !O(t.recommendationConfigs, this));
434
543
  },
435
544
  // ====================================================================
436
545
  // Per-Block Product Fetching
437
546
  // ====================================================================
438
547
  async fetchRecommendationProducts() {
439
548
  if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
440
- if (d) {
441
- await d;
549
+ if (h) {
550
+ await h;
442
551
  return;
443
552
  }
444
- d = this._doFetchProducts();
553
+ h = this._doFetchProducts();
445
554
  try {
446
- await d;
555
+ await h;
447
556
  } finally {
448
- d = null;
557
+ h = null;
449
558
  }
450
559
  }
451
560
  },
452
561
  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 = {
562
+ var d;
563
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = R();
564
+ if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
565
+ await this._doFetchStrategyProducts(t);
566
+ return;
567
+ }
568
+ const s = r.filters.filter((m) => m.isValid), i = C(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
455
569
  locale: r.language,
456
570
  currency: r.currencySettings.value,
457
- partnerName: o.partnerName,
571
+ partnerName: n.partnerName,
458
572
  size: r.size,
459
573
  details: !0,
460
- campaignId: o.variationId
574
+ campaignId: n.variationId
461
575
  };
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(
576
+ r.strategy === "manualMerchandising" ? a.productId = z(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
577
  a,
464
- v(o.partnerName, r.strategy)
578
+ B(n.partnerName, r.strategy)
465
579
  );
466
- let f;
580
+ let l;
467
581
  try {
468
- f = await h.fetchRecommendationProducts(i, a);
582
+ l = await u.fetchRecommendationProducts(o, a);
469
583
  } catch {
470
- f = [];
584
+ l = [];
471
585
  }
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;
586
+ this._setBlockProducts(t, l, c);
587
+ },
588
+ async _doFetchStrategyProducts(t) {
589
+ const e = (p.get(t) ?? 0) + 1;
590
+ p.set(t, e);
591
+ const { recommendationConfigs: r } = this.blockStates[t];
592
+ let n = [], s = parseInt(r.size) || 6;
593
+ try {
594
+ await this.fetchStrategies();
595
+ const i = this.strategies.find(
596
+ (o) => String(o.strategy_id) === r.strategyId
597
+ );
598
+ if (i) {
599
+ s = parseInt(String(i.size ?? "")) || s;
600
+ 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;
601
+ y && (n = await u.fetchRecommendationProductsByUrl(y));
602
+ }
603
+ } catch {
604
+ n = [];
478
605
  }
606
+ p.get(t) === e && this._setBlockProducts(t, n, s);
607
+ },
608
+ _setBlockProducts(t, e, r) {
609
+ if (!this.blockStates[t])
610
+ return;
611
+ const n = e.length > 0 ? e : k(r);
612
+ this.blockStates[t].recommendationProducts = [
613
+ ...n.slice(0, r),
614
+ ...k(Math.max(0, r - n.length))
615
+ ];
479
616
  }
480
617
  }
481
618
  });
482
619
  export {
483
- H as useRecommendationExtensionStore
620
+ et as useRecommendationExtensionStore
484
621
  };
@@ -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
+ };