@useinsider/guido 3.17.0-beta.dc7f4d2 → 3.17.0-beta.e23d5cd

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 (88) hide show
  1. package/README.md +6 -5
  2. package/dist/@types/config/schemas.js +7 -6
  3. package/dist/components/Guido.vue.js +6 -6
  4. package/dist/components/Guido.vue2.js +96 -94
  5. package/dist/components/organisms/AutoSaveController.vue2.js +8 -9
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +21 -0
  7. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +106 -0
  8. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
  10. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  11. package/dist/components/organisms/header/EditorActions.vue2.js +43 -74
  12. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  13. package/dist/components/organisms/header/LeftSlot.vue2.js +23 -46
  14. package/dist/components/wrappers/WpDrawer.vue.js +7 -9
  15. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  16. package/dist/composables/useCustomInterfaceAppearance.js +52 -38
  17. package/dist/composables/useHtmlCompiler.js +26 -37
  18. package/dist/composables/useHtmlValidator.js +0 -2
  19. package/dist/composables/useRecommendation.js +41 -34
  20. package/dist/composables/useSave.js +41 -84
  21. package/dist/composables/validators/useCouponBlockValidator.js +21 -24
  22. package/dist/composables/validators/useUnsubscribeBlockValidator.js +27 -34
  23. package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
  24. package/dist/config/migrator/recommendationMigrator.js +5 -4
  25. package/dist/enums/academy.js +2 -1
  26. package/dist/enums/date.js +5 -3
  27. package/dist/enums/extensions/recommendationBlock.js +3 -1
  28. package/dist/extensions/Blocks/Recommendation/block.js +26 -21
  29. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +34 -34
  30. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +96 -95
  31. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +238 -185
  32. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +124 -0
  33. package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
  34. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +165 -86
  35. package/dist/extensions/Blocks/common-control.js +22 -19
  36. package/dist/guido.css +1 -1
  37. package/dist/services/recommendationApi.js +69 -30
  38. package/dist/src/@types/config/schemas.d.ts +2 -0
  39. package/dist/src/components/Guido.vue.d.ts +1 -17
  40. package/dist/src/components/organisms/{validation/ValidationErrorDrawer.vue.d.ts → extensions/recommendation/AssignStrategyDrawer.vue.d.ts} +1 -0
  41. package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
  42. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -17
  43. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -17
  44. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -17
  45. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +3 -4
  46. package/dist/src/composables/useConfig.d.ts +2 -0
  47. package/dist/src/composables/useHtmlValidator.d.ts +0 -21
  48. package/dist/src/composables/useRecommendation.d.ts +1 -0
  49. package/dist/src/composables/useSave.d.ts +1 -6
  50. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +0 -3
  51. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +0 -10
  52. package/dist/src/enums/academy.d.ts +1 -0
  53. package/dist/src/enums/date.d.ts +1 -0
  54. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  55. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +2 -6
  56. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  57. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
  58. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +16 -0
  59. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
  60. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +150 -15
  61. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -0
  62. package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
  63. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  64. package/dist/src/services/recommendationApi.d.ts +4 -1
  65. package/dist/src/stores/config.d.ts +18 -5
  66. package/dist/src/stores/save-as-template.d.ts +4 -3
  67. package/dist/src/utils/genericUtil.d.ts +5 -0
  68. package/dist/src/utils/templatePreparation.d.ts +0 -30
  69. package/dist/static/assets/icons/line-change.svg.js +5 -0
  70. package/dist/static/assets/icons/line-delete.svg.js +5 -0
  71. package/dist/static/assets/icons/line-plus.svg.js +5 -0
  72. package/dist/static/styles/components/recommendation-strategy.css.js +155 -0
  73. package/dist/stores/config.js +6 -13
  74. package/dist/utils/dateUtil.js +23 -10
  75. package/dist/utils/genericUtil.js +28 -27
  76. package/dist/utils/templatePreparation.js +48 -50
  77. package/package.json +3 -2
  78. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +0 -20
  79. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +0 -48
  80. package/dist/composables/useSaveValidation.js +0 -279
  81. package/dist/composables/useSaveValidationRollout.js +0 -9
  82. package/dist/enums/save-validation.js +0 -4
  83. package/dist/src/@types/save-validation.d.ts +0 -19
  84. package/dist/src/composables/useSaveValidation.d.ts +0 -6
  85. package/dist/src/composables/useSaveValidationRollout.d.ts +0 -3
  86. package/dist/src/enums/save-validation.d.ts +0 -27
  87. package/dist/src/stores/save-validation.d.ts +0 -22
  88. package/dist/stores/save-validation.js +0 -30
@@ -1,21 +1,22 @@
1
- import { getRecommendationFeedSourceMaps as g, getOperatorOptions as C, PriceAttributes as y } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as G } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as P } from "../../../../stores/config.js";
4
- import { defineStore as F } from "pinia";
1
+ import { getRecommendationFeedSourceMaps as I, getOperatorOptions as G, PriceAttributes as D } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as F } from "../../../../stores/config.js";
4
+ import { defineStore as v } from "pinia";
5
5
  import "../constants/selectors.js";
6
- import { DEFAULT_MOBILE_CARDS_IN_ROW as D, DEFAULT_CARDS_IN_ROW as v } 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 N } from "../utils/partnerCustomizations.js";
11
- import { sanitizeProductIds as x } from "../utils/productIds.js";
12
- import { isFilterValid as L } from "../validation/filterSchema.js";
13
- import { isConfigValid as I } from "../validation/requiredFields.js";
14
- const h = G();
15
- let m = null, u = null, d = null;
16
- function R() {
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 k } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as R } 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 z } from "../validation/requiredFields.js";
14
+ const m = P();
15
+ let f = null, g = null, h = null, S = null;
16
+ const p = /* @__PURE__ */ new Map();
17
+ function w() {
17
18
  return {
18
- cardsInRow: v,
19
+ cardsInRow: U,
19
20
  currencySettings: {
20
21
  name: "USD",
21
22
  value: "USD",
@@ -29,13 +30,14 @@ function R() {
29
30
  productIds: [],
30
31
  id: 1,
31
32
  language: "en_US",
32
- mobileCardsInRow: D,
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,32 @@ function R() {
44
46
  priceHideIfSameAsDiscounted: !1
45
47
  };
46
48
  }
47
- function k() {
49
+ function C() {
48
50
  return {
49
- recommendationConfigs: R(),
51
+ recommendationConfigs: w(),
50
52
  recommendationProducts: [],
51
53
  filterStatus: !1,
52
54
  filterSelectionDrawerStatus: !1,
55
+ assignStrategyDrawerStatus: !1,
53
56
  filterGroup: 1,
54
57
  isInitialized: !1,
55
58
  filterSnapshot: null
56
59
  };
57
60
  }
58
- const U = () => ({
61
+ const O = () => ({
59
62
  recommendationCampaignUrls: {},
60
63
  activePredictiveAlgorithms: [],
61
64
  languages: {},
62
65
  currencyList: [],
63
66
  filterList: {},
67
+ strategies: [],
68
+ strategiesLoading: !1,
69
+ strategyUrlTemplates: {},
64
70
  blockStates: {},
65
71
  currentRecommendationId: null,
66
72
  configVersion: 0
67
- }), H = F("guidoRecommendationExtension", {
68
- state: () => U(),
73
+ }), Y = v("guidoRecommendationExtension", {
74
+ state: () => O(),
69
75
  getters: {
70
76
  // ====================================================================
71
77
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -75,7 +81,7 @@ const U = () => ({
75
81
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
76
82
  */
77
83
  recommendationConfigs(t) {
78
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : R();
84
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
79
85
  },
80
86
  /**
81
87
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -89,6 +95,13 @@ const U = () => ({
89
95
  filterSelectionDrawerStatus(t) {
90
96
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
91
97
  },
98
+ assignStrategyDrawerStatus(t) {
99
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
100
+ },
101
+ assignedStrategy(t) {
102
+ const { strategyId: e } = this.recommendationConfigs;
103
+ return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
104
+ },
92
105
  /**
93
106
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
94
107
  */
@@ -120,9 +133,9 @@ const U = () => ({
120
133
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
121
134
  },
122
135
  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));
136
+ const e = I(), r = [];
137
+ return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
138
+ r.push(...e.filter((s) => s.id === n));
126
139
  }), r.map((n) => ({
127
140
  text: n.name,
128
141
  value: n.key
@@ -139,7 +152,7 @@ const U = () => ({
139
152
  getFilterList() {
140
153
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
141
154
  let e;
142
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : y.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
155
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : D.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
143
156
  text: t.displayName,
144
157
  value: e,
145
158
  type: t.attributeType
@@ -161,7 +174,7 @@ const U = () => ({
161
174
  setCurrentBlock(t) {
162
175
  this.blockStates[t] || (this.blockStates = {
163
176
  ...this.blockStates,
164
- [t]: k()
177
+ [t]: C()
165
178
  }), this.currentRecommendationId = t;
166
179
  },
167
180
  /**
@@ -193,10 +206,10 @@ const U = () => ({
193
206
  [e]: o
194
207
  };
195
208
  }
196
- const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
209
+ const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
197
210
  i && (this.recommendationCampaignUrls = {
198
211
  ...this.recommendationCampaignUrls,
199
- [c]: i
212
+ [s]: i
200
213
  });
201
214
  },
202
215
  /**
@@ -221,7 +234,7 @@ const U = () => ({
221
234
  * `isInitialized`) alone.
222
235
  */
223
236
  seedBlockUrlConfig(t, e) {
224
- const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
237
+ const r = (o, c) => o === "." || o === "," || o === " " ? o : c, n = {
225
238
  name: e.currencyCode,
226
239
  value: e.currencyCode,
227
240
  symbol: e.currencyCode,
@@ -229,17 +242,18 @@ const U = () => ({
229
242
  decimalCount: String(e.currencyDecimalCount),
230
243
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
231
244
  thousandSeparator: r(e.currencyThousandSeparator, ".")
232
- }, c = !this.blockStates[t], i = c ? k() : this.blockStates[t];
245
+ }, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
233
246
  i.recommendationConfigs = {
234
247
  ...i.recommendationConfigs,
235
248
  strategy: e.strategy,
249
+ strategyId: e.strategyId,
236
250
  language: e.language,
237
251
  size: e.size,
238
252
  productIds: e.productIds,
239
253
  filters: e.filters,
240
254
  shuffleProducts: e.shuffleProducts,
241
255
  currencySettings: n
242
- }, c && (this.blockStates = {
256
+ }, s && (this.blockStates = {
243
257
  ...this.blockStates,
244
258
  [t]: i
245
259
  });
@@ -267,7 +281,7 @@ const U = () => ({
267
281
  * Creates a filter with the first available attribute and operator pre-selected.
268
282
  */
269
283
  createDefaultFilter(t, e) {
270
- const [r] = this.getFilterList, [n] = C(r == null ? void 0 : r.type);
284
+ const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
271
285
  return {
272
286
  type: "standardFilter",
273
287
  attribute: (r == null ? void 0 : r.value) ?? "",
@@ -314,21 +328,65 @@ const U = () => ({
314
328
  const t = this.blockStates[this.currentRecommendationId];
315
329
  t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
316
330
  },
331
+ openAssignStrategyDrawer() {
332
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !0);
333
+ },
334
+ closeAssignStrategyDrawer() {
335
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
336
+ },
337
+ async fetchStrategies() {
338
+ if (S) {
339
+ await S;
340
+ return;
341
+ }
342
+ S = (async () => {
343
+ this.strategiesLoading = !0;
344
+ try {
345
+ this.strategies = await m.fetchRecommendationStrategies();
346
+ } finally {
347
+ this.strategiesLoading = !1;
348
+ }
349
+ })();
350
+ try {
351
+ await S;
352
+ } finally {
353
+ S = null;
354
+ }
355
+ },
356
+ async resolveStrategyUrlTemplate(t, e) {
357
+ const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
358
+ if (s)
359
+ return s;
360
+ const { full_path: i = "" } = await m.generateStrategyEndpoint(t, e) ?? {};
361
+ return n && i && (this.strategyUrlTemplates = {
362
+ ...this.strategyUrlTemplates,
363
+ [n]: i
364
+ }), i;
365
+ },
366
+ assignStrategy(t) {
367
+ this.patchCurrentBlockConfig({
368
+ strategyId: String(t.strategy_id),
369
+ ...t.size !== void 0 ? { size: String(t.size) } : {}
370
+ });
371
+ },
372
+ removeStrategy() {
373
+ this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
374
+ },
317
375
  // ====================================================================
318
376
  // Shared Data Fetching (fetched once, used by all blocks)
319
377
  // ====================================================================
320
378
  async fetchRecommendationCreateData() {
321
379
  if (!this.activePredictiveAlgorithms.length) {
322
- if (m) {
323
- await m;
380
+ if (f) {
381
+ await f;
324
382
  return;
325
383
  }
326
- m = (async () => {
384
+ f = (async () => {
327
385
  const {
328
386
  activePredictiveAlgorithms: t,
329
387
  languages: e,
330
388
  currencies: r
331
- } = await h.fetchRecommendationCreateData();
389
+ } = await m.fetchRecommendationCreateData();
332
390
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
333
391
  const n = this.blockStates[this.currentRecommendationId];
334
392
  n.filterStatus = !!n.recommendationConfigs.filters.length;
@@ -336,26 +394,26 @@ const U = () => ({
336
394
  this.currencyList = r;
337
395
  })();
338
396
  try {
339
- await m;
397
+ await f;
340
398
  } finally {
341
- m = null;
399
+ f = null;
342
400
  }
343
401
  }
344
402
  },
345
403
  async fetchRecommendationFilters() {
346
404
  if (!Object.keys(this.filterList).length) {
347
- if (u) {
348
- await u;
405
+ if (g) {
406
+ await g;
349
407
  return;
350
408
  }
351
- u = (async () => {
352
- const t = await h.fetchRecommendationFilters();
409
+ g = (async () => {
410
+ const t = await m.fetchRecommendationFilters();
353
411
  this.filterList = t;
354
412
  })();
355
413
  try {
356
- await u;
414
+ await g;
357
415
  } finally {
358
- u = null;
416
+ g = null;
359
417
  }
360
418
  }
361
419
  },
@@ -370,10 +428,10 @@ const U = () => ({
370
428
  deleteFilterGroup(t) {
371
429
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
372
430
  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]));
431
+ 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
432
  e.recommendationConfigs.filters = r.map((i) => ({
375
433
  ...i,
376
- filterGroup: c.get(i.filterGroup) ?? i.filterGroup
434
+ filterGroup: s.get(i.filterGroup) ?? i.filterGroup
377
435
  }));
378
436
  },
379
437
  updateFilter(t) {
@@ -384,7 +442,7 @@ const U = () => ({
384
442
  const n = [...e.recommendationConfigs.filters];
385
443
  n[r] = {
386
444
  ...t,
387
- isValid: L(t)
445
+ isValid: B(t)
388
446
  }, e.recommendationConfigs.filters = n;
389
447
  }
390
448
  },
@@ -398,10 +456,10 @@ const U = () => ({
398
456
  let i = 1;
399
457
  n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
400
458
  } 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
459
+ const i = [...new Set(n.map((c) => c.filterGroup))].sort((c, a) => c - a), o = new Map(i.map((c, a) => [c, a + 1]));
460
+ n = n.map((c) => ({
461
+ ...c,
462
+ filterGroup: o.get(c.filterGroup) ?? c.filterGroup
405
463
  }));
406
464
  }
407
465
  e.recommendationConfigs.filters = n;
@@ -410,19 +468,19 @@ const U = () => ({
410
468
  addFilter(t) {
411
469
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
412
470
  return;
413
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
471
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
414
472
  (o) => o.filterGroup === t.filterGroup
415
473
  ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
416
474
  i !== -1 ? r.splice(i + 1, 0, {
417
475
  ...t,
418
- filterNumber: c
476
+ filterNumber: s
419
477
  }) : r.push({
420
478
  ...t,
421
- filterNumber: c
479
+ filterNumber: s
422
480
  }), e.recommendationConfigs.filters = r;
423
481
  },
424
482
  generateFilterQuery() {
425
- return b(this.recommendationConfigs.filters);
483
+ return R(this.recommendationConfigs.filters);
426
484
  },
427
485
  /**
428
486
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -430,62 +488,83 @@ const U = () => ({
430
488
  * every block's recommendationConfigs across user edits.
431
489
  */
432
490
  hasInvalidBlock() {
433
- return Object.values(this.blockStates).some((t) => !I(t.recommendationConfigs, this));
434
- },
435
- /**
436
- * Per-instance counterpart to `hasInvalidBlock`: the ids of every block
437
- * that fails required-field validation, one drawer row each (SD-147430).
438
- */
439
- invalidBlockIds() {
440
- return Object.entries(this.blockStates).filter(([, t]) => !I(t.recommendationConfigs, this)).map(([t]) => t);
491
+ return Object.values(this.blockStates).some((t) => !z(t.recommendationConfigs, this));
441
492
  },
442
493
  // ====================================================================
443
494
  // Per-Block Product Fetching
444
495
  // ====================================================================
445
496
  async fetchRecommendationProducts() {
446
497
  if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
447
- if (d) {
448
- await d;
498
+ if (h) {
499
+ await h;
449
500
  return;
450
501
  }
451
- d = this._doFetchProducts();
502
+ h = this._doFetchProducts();
452
503
  try {
453
- await d;
504
+ await h;
454
505
  } finally {
455
- d = null;
506
+ h = null;
456
507
  }
457
508
  }
458
509
  },
459
510
  async _doFetchProducts() {
460
- var p;
461
- 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 = P(), s = parseInt(r.size) || 6, a = {
511
+ var d;
512
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
513
+ if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
514
+ await this._doFetchStrategyProducts(t);
515
+ return;
516
+ }
517
+ const s = r.filters.filter((u) => u.isValid), i = R(s), o = ((d = I().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
462
518
  locale: r.language,
463
519
  currency: r.currencySettings.value,
464
- partnerName: o.partnerName,
520
+ partnerName: n.partnerName,
465
521
  size: r.size,
466
522
  details: !0,
467
- campaignId: o.variationId
523
+ campaignId: n.variationId
468
524
  };
469
- r.strategy === "manualMerchandising" ? a.productId = x(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(
525
+ 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(
470
526
  a,
471
- N(o.partnerName, r.strategy)
527
+ x(n.partnerName, r.strategy)
472
528
  );
473
- let f;
529
+ let l;
474
530
  try {
475
- f = await h.fetchRecommendationProducts(i, a);
531
+ l = await m.fetchRecommendationProducts(o, a);
476
532
  } catch {
477
- f = [];
533
+ l = [];
478
534
  }
479
- if (this.blockStates[t]) {
480
- const l = f.length > 0 ? f : S(s);
481
- l.length < s ? this.blockStates[t].recommendationProducts = [
482
- ...l,
483
- ...S(s - l.length)
484
- ] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
535
+ this._setBlockProducts(t, l, c);
536
+ },
537
+ async _doFetchStrategyProducts(t) {
538
+ const e = (p.get(t) ?? 0) + 1;
539
+ p.set(t, e);
540
+ const { recommendationConfigs: r } = this.blockStates[t];
541
+ let n = [], s = parseInt(r.size) || 6;
542
+ try {
543
+ await this.fetchStrategies();
544
+ const i = this.strategies.find(
545
+ (o) => String(o.strategy_id) === r.strategyId
546
+ );
547
+ if (i) {
548
+ s = parseInt(String(i.size ?? "")) || s;
549
+ 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), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((b) => b && !b.startsWith("user_id=")), y = u.length ? `${d}?${u.join("&")}` : d;
550
+ y && (n = await m.fetchRecommendationProductsByUrl(y));
551
+ }
552
+ } catch {
553
+ n = [];
485
554
  }
555
+ p.get(t) === e && this._setBlockProducts(t, n, s);
556
+ },
557
+ _setBlockProducts(t, e, r) {
558
+ if (!this.blockStates[t])
559
+ return;
560
+ const n = e.length > 0 ? e : k(r);
561
+ this.blockStates[t].recommendationProducts = [
562
+ ...n.slice(0, r),
563
+ ...k(Math.max(0, r - n.length))
564
+ ];
486
565
  }
487
566
  }
488
567
  });
489
568
  export {
490
- H as useRecommendationExtensionStore
569
+ Y as useRecommendationExtensionStore
491
570
  };
@@ -1,12 +1,12 @@
1
1
  var c = Object.defineProperty;
2
- var i = (s, r, e) => r in s ? c(s, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[r] = e;
3
- var u = (s, r, e) => i(s, typeof r != "symbol" ? r + "" : r, e);
2
+ var i = (l, a, e) => a in l ? c(l, a, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[a] = e;
3
+ var T = (l, a, e) => i(l, typeof a != "symbol" ? a + "" : a, e);
4
4
  import { Control as I, UIElementType as n, UEAttr as $ } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- class d extends I {
5
+ class _ extends I {
6
6
  constructor() {
7
7
  super(...arguments);
8
- u(this, "currentNode");
9
- u(this, "lastBlockInstanceId", null);
8
+ T(this, "currentNode");
9
+ T(this, "lastBlockInstanceId", null);
10
10
  }
11
11
  getContainer() {
12
12
  var e;
@@ -91,21 +91,21 @@ class d extends I {
91
91
  * and combines it with the text in Stripo's alert-message layout.
92
92
  */
93
93
  _setInfoMessageValue(e, t) {
94
- const E = this.getContainer(), o = E.querySelector(`[data-icon-key="${e}"]`), a = o == null ? void 0 : o.querySelector("ue-icon-component"), l = (a == null ? void 0 : a.outerHTML) ?? "";
94
+ const E = this.getContainer(), o = E.querySelector(`[data-icon-key="${e}"]`), r = o == null ? void 0 : o.querySelector("ue-icon-component"), s = (r == null ? void 0 : r.outerHTML) ?? "";
95
95
  this.api.setUIEAttribute(
96
96
  e,
97
97
  "value",
98
98
  `
99
99
  <div class="service-element alert-message-main" style="align-items: start;">
100
- ${l}
100
+ ${s}
101
101
  <div class="service-element alert-message-text">
102
102
  ${t}
103
103
  </div>
104
104
  </div>
105
105
  `
106
106
  );
107
- const T = E.querySelector(`[data-info-message="${e}"]`);
108
- T && (T.style.display = "");
107
+ const u = E.querySelector(`[data-info-message="${e}"]`);
108
+ u && (u.style.display = "");
109
109
  }
110
110
  _GuToggle(e) {
111
111
  return `
@@ -126,15 +126,15 @@ class d extends I {
126
126
  placeholder: t,
127
127
  options: E,
128
128
  className: o = "es-180w",
129
- searchable: a = !1
129
+ searchable: r = !1
130
130
  }) {
131
131
  return `
132
132
  <${n.SELECTPICKER}
133
133
  class="${o}"
134
134
  ${$.SELECTPICKER.name}="${e}"
135
- ${a ? `${$.SELECTPICKER.searchable}="true"` : ""}
135
+ ${r ? `${$.SELECTPICKER.searchable}="true"` : ""}
136
136
  ${$.SELECTPICKER.placeholder}="${t}">
137
- ${E.map((l) => this._GuSelectItem(l)).join("")}
137
+ ${E.map((s) => this._GuSelectItem(s)).join("")}
138
138
  </${n.SELECTPICKER}>
139
139
  `;
140
140
  }
@@ -176,12 +176,15 @@ class d extends I {
176
176
  </${n.RADIO_BUTTONS}>
177
177
  `;
178
178
  }
179
- _GuButton({ name: e, label: t, id: E = "" }) {
179
+ _GuButton({ name: e, label: t, id: E = "", className: o = "", icon: r = "", disabled: s = !1 }) {
180
180
  return `
181
181
  <${n.BUTTON}
182
182
  ${$.BUTTON.name}="${e}"
183
183
  ${E ? `id="${E}"` : ""}
184
- ${$.BUTTON.caption}="${t}"}>
184
+ ${o ? `class="${o}"` : ""}
185
+ ${r ? `${$.BUTTON.icon}="${r}"` : ""}
186
+ ${s ? `${$.BUTTON.disabled}="true"` : ""}
187
+ ${$.BUTTON.caption}="${t}">
185
188
  </${n.BUTTON}>
186
189
  `;
187
190
  }
@@ -230,11 +233,11 @@ class d extends I {
230
233
  */
231
234
  _GuOrderable(e, t) {
232
235
  let E = "";
233
- t.forEach((a) => {
234
- const l = $.ORDERABLE_ITEM && "name" in $.ORDERABLE_ITEM ? $.ORDERABLE_ITEM.name : "name";
236
+ t.forEach((r) => {
237
+ const s = $.ORDERABLE_ITEM && "name" in $.ORDERABLE_ITEM ? $.ORDERABLE_ITEM.name : "name";
235
238
  E += `
236
- <${n.ORDERABLE_ITEM} ${l}="${a.key}">
237
- ${a.content}
239
+ <${n.ORDERABLE_ITEM} ${s}="${r.key}">
240
+ ${r.content}
238
241
  </${n.ORDERABLE_ITEM}>
239
242
  `;
240
243
  });
@@ -305,5 +308,5 @@ class d extends I {
305
308
  }
306
309
  }
307
310
  export {
308
- d as CommonControl
311
+ _ as CommonControl
309
312
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-74d455fc] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-44d8e7c8]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-856367aa]{gap:16px}.validation-error-row[data-v-856367aa]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-856367aa]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-856367aa]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-f02fdde0]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-f02fdde0]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-f02fdde0]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}
1
+ @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-e6f99d29]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-e6f99d29]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-e6f99d29]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}