@useinsider/guido 3.12.0-beta.841bb6a → 3.12.0-beta.86e34da

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 (90) hide show
  1. package/dist/@types/config/schemas.js +9 -4
  2. package/dist/components/Guido.vue.js +6 -6
  3. package/dist/components/Guido.vue2.js +50 -49
  4. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  5. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  6. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  7. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  8. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +38 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +271 -0
  10. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +18 -0
  11. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +42 -0
  12. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +20 -0
  13. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +18 -0
  14. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +20 -0
  15. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +60 -0
  16. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +19 -0
  17. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +19 -0
  18. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +22 -0
  19. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +29 -0
  20. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  21. package/dist/composables/useRecommendation.js +56 -40
  22. package/dist/composables/useRecommendationPreview.js +61 -60
  23. package/dist/composables/useStrategyFilters.js +16 -0
  24. package/dist/config/migrator/recommendationMigrator.js +7 -4
  25. package/dist/enums/date.js +4 -3
  26. package/dist/enums/extensions/filteringV2.js +1024 -0
  27. package/dist/enums/extensions/recommendationBlock.js +45 -24
  28. package/dist/enums/extensions/strategyDetail.js +148 -0
  29. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  30. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
  31. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  32. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +141 -123
  33. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +285 -0
  34. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  35. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +16 -2
  36. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +257 -0
  37. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  38. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +460 -113
  39. package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
  40. package/dist/extensions/Blocks/Recommendation/utils/strategyNavigation.js +8 -0
  41. package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +95 -0
  42. package/dist/extensions/Blocks/Recommendation/utils/strategyUrl.js +43 -0
  43. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -10
  44. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  45. package/dist/extensions/Blocks/common-control.js +2 -1
  46. package/dist/extensions/Blocks/controlFactories.js +125 -75
  47. package/dist/guido.css +1 -1
  48. package/dist/services/recommendationApi.js +120 -32
  49. package/dist/services/stripoApi.js +18 -18
  50. package/dist/src/@types/config/schemas.d.ts +10 -0
  51. package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +2 -0
  52. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +43 -0
  53. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +29 -0
  54. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +40 -0
  55. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +38 -0
  56. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +51 -0
  57. package/dist/src/composables/useConfig.d.ts +2 -0
  58. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  59. package/dist/src/composables/useRecommendation.d.ts +2 -0
  60. package/dist/src/composables/useStrategyFilters.d.ts +24 -0
  61. package/dist/src/enums/extensions/filteringV2.d.ts +72 -0
  62. package/dist/src/enums/extensions/recommendationBlock.d.ts +33 -0
  63. package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
  64. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  65. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  66. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  67. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +10 -4
  68. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +75 -0
  69. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +903 -1
  70. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  71. package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +50 -0
  72. package/dist/src/extensions/Blocks/Recommendation/utils/strategyNavigation.d.ts +10 -0
  73. package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
  74. package/dist/src/extensions/Blocks/Recommendation/utils/strategyUrl.d.ts +51 -0
  75. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +8 -1
  76. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  77. package/dist/src/extensions/Blocks/common-control.d.ts +2 -1
  78. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  79. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  80. package/dist/src/services/recommendationApi.d.ts +9 -1
  81. package/dist/src/stores/config.d.ts +18 -0
  82. package/dist/src/utils/genericUtil.d.ts +9 -0
  83. package/dist/src/utils/urlSchemes.d.ts +6 -0
  84. package/dist/static/styles/components/base-input.css.js +6 -7
  85. package/dist/utils/dateUtil.js +23 -10
  86. package/dist/utils/genericUtil.js +10 -1
  87. package/dist/utils/pairProductVariables.js +43 -44
  88. package/dist/utils/templatePreparation.js +70 -57
  89. package/dist/utils/urlSchemes.js +4 -0
  90. package/package.json +1 -1
@@ -1,41 +1,45 @@
1
- var f = Object.defineProperty;
2
- var p = (d, l, t) => l in d ? f(d, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[l] = t;
1
+ var g = Object.defineProperty;
2
+ var p = (d, l, t) => l in d ? g(d, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[l] = t;
3
3
  var s = (d, l, t) => p(d, typeof l != "symbol" ? l + "" : l, t);
4
- import { CommonControl as g } from "../../../common-control.js";
5
- import { DEFAULT_NODE_CONFIG as c } from "../../constants/defaultConfig.js";
4
+ import { useConfig as h } from "../../../../../composables/useConfig.js";
5
+ import { CommonControl as y } from "../../../common-control.js";
6
+ import { DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
6
7
  import { RecommendationConfigService as m } from "../../services/configService.js";
7
- import { useRecommendationExtensionStore as y } from "../../store/recommendation.js";
8
- import { AlgorithmControl as N } from "./algorithm.js";
9
- import { ALGORITHM_CONTROL_ID as tt } from "./algorithm.js";
10
- import { CurrencyControl as R } from "./currency.js";
11
- import { CURRENCY_CONTROL_ID as ot } from "./currency.js";
12
- import { FiltersControl as I } from "./filters.js";
13
- import { FILTERS_CONTROL_ID as nt } from "./filters.js";
8
+ import { useRecommendationExtensionStore as R } from "../../store/recommendation.js";
9
+ import { AlgorithmControl as b } from "./algorithm.js";
10
+ import { ALGORITHM_CONTROL_ID as nt } from "./algorithm.js";
11
+ import { CurrencyControl as I } from "./currency.js";
12
+ import { CURRENCY_CONTROL_ID as st } from "./currency.js";
13
+ import { FiltersControl as N } from "./filters.js";
14
+ import { FILTERS_CONTROL_ID as lt } from "./filters.js";
14
15
  import { LayoutOrientationControl as _ } from "./layoutOrientation.js";
15
- import { LAYOUT_ORIENTATION_CONTROL_ID as st } from "./layoutOrientation.js";
16
- import { LocaleControl as b } from "./locale.js";
17
- import { LOCALE_CONTROL_ID as lt } from "./locale.js";
18
- import { PricePlacementControl as T } from "./pricePlacement.js";
19
- import { PRICE_PLACEMENT_CONTROL_ID as ut } from "./pricePlacement.js";
20
- import { ProductCountControl as P } from "./productCount.js";
21
- import { PRODUCT_COUNT_CONTROL_ID as mt } from "./productCount.js";
22
- import { ProductLayoutControl as O } from "./productLayout.js";
23
- import { PRODUCT_LAYOUT_CONTROL_ID as Ct } from "./productLayout.js";
16
+ import { LAYOUT_ORIENTATION_CONTROL_ID as ut } from "./layoutOrientation.js";
17
+ import { LocaleControl as T } from "./locale.js";
18
+ import { LOCALE_CONTROL_ID as mt } from "./locale.js";
19
+ import { PricePlacementControl as S } from "./pricePlacement.js";
20
+ import { PRICE_PLACEMENT_CONTROL_ID as Ct } from "./pricePlacement.js";
21
+ import { ProductCountControl as O } from "./productCount.js";
22
+ import { PRODUCT_COUNT_CONTROL_ID as gt } from "./productCount.js";
23
+ import { ProductLayoutControl as P } from "./productLayout.js";
24
+ import { PRODUCT_LAYOUT_CONTROL_ID as yt } from "./productLayout.js";
24
25
  import { ShuffleControl as L } from "./shuffle.js";
25
- import { SHUFFLE_CONTROL_ID as pt } from "./shuffle.js";
26
- import { setCurrencyAttributes as S, getBlockElement as k, isPartnerManagedBlock as D, updateProductContentInPlace as E, regenerateProductRowsWithStyles as A } from "./utils.js";
27
- import { adjustProductsToSize as yt, formatProductPrice as Nt, getCardComposition as Rt, getCurrentLayout as It, regenerateMobileProductRows as _t, updatePricesInPlace as bt, updateSingleProductContent as Tt } from "./utils.js";
28
- import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
29
- const v = "recommendation-id", w = "ui-elements-recommendation-block";
30
- class Q extends g {
26
+ import { SHUFFLE_CONTROL_ID as bt } from "./shuffle.js";
27
+ import { StrategyControl as E } from "./strategy.js";
28
+ import { STRATEGY_CONTROL_ID as Nt } from "./strategy.js";
29
+ import { setCurrencyAttributes as k, getBlockElement as D, isPartnerManagedBlock as A, updateProductContentInPlace as w, regenerateProductRowsWithStyles as v } from "./utils.js";
30
+ import { adjustProductsToSize as Tt, formatProductPrice as St, getCardComposition as Ot, getCurrentLayout as Pt, regenerateMobileProductRows as Lt, updatePricesInPlace as Et, updateSingleProductContent as kt } from "./utils.js";
31
+ import { useDebounceFn as C } from "../../../../../node_modules/@vueuse/shared/index.js";
32
+ const x = "recommendation-id", B = "ui-elements-recommendation-block";
33
+ class et extends y {
31
34
  constructor() {
32
35
  super(...arguments);
33
- s(this, "store", y());
36
+ s(this, "store", R());
34
37
  s(this, "storeUnsubscription", () => {
35
38
  });
36
39
  s(this, "syncedBlockIds", /* @__PURE__ */ new Set());
37
40
  // Sub-control instances for lifecycle management
38
41
  s(this, "algorithmControl", null);
42
+ s(this, "strategyControl", null);
39
43
  s(this, "localeControl", null);
40
44
  s(this, "currencyControl", null);
41
45
  s(this, "productCountControl", null);
@@ -47,7 +51,7 @@ class Q extends g {
47
51
  /**
48
52
  * Debounced product fetch to prevent rapid API calls during config changes
49
53
  */
50
- s(this, "_debouncedFetchProducts", h(() => {
54
+ s(this, "_debouncedFetchProducts", C(() => {
51
55
  this.store.fetchRecommendationProducts();
52
56
  }, 500));
53
57
  /**
@@ -61,16 +65,16 @@ class Q extends g {
61
65
  * count. The store pads products to the configured size, so in-place only
62
66
  * fails when the size actually changed.
63
67
  */
64
- s(this, "_debouncedRegenerateWithProducts", h(() => {
68
+ s(this, "_debouncedRegenerateWithProducts", C(() => {
65
69
  const t = this.store.recommendationProducts;
66
- if (!this.currentNode || !this.api || D(this.currentNode))
70
+ if (!this.currentNode || !this.api || A(this.currentNode))
67
71
  return;
68
72
  const e = this.api.getDocumentModifier();
69
- E({
73
+ w({
70
74
  currentNode: this.currentNode,
71
75
  documentModifier: e,
72
76
  products: t
73
- }) || A({
77
+ }) || v({
74
78
  currentNode: this.currentNode,
75
79
  documentModifier: e,
76
80
  products: t
@@ -78,11 +82,13 @@ class Q extends g {
78
82
  }, 100));
79
83
  }
80
84
  getId() {
81
- return w;
85
+ return B;
82
86
  }
83
87
  getTemplate() {
84
- return this.algorithmControl = new N(), this.localeControl = new b(), this.currencyControl = new R(), this.productCountControl = new P(), this.productLayoutControl = new O(), this.filtersControl = new I(), this.shuffleControl = new L(), this.pricePlacementControl = new T(), this.layoutOrientationControl = new _(), [
88
+ var o;
89
+ return h().isFeatureEnabled("reusableRecommendationStrategy") ? this.strategyControl = new E() : this.algorithmControl = new b(), this.localeControl = new T(), this.currencyControl = new I(), this.productCountControl = new O(), this.productLayoutControl = new P(), this.filtersControl = new N(), this.shuffleControl = new L(), this.pricePlacementControl = new S(), this.layoutOrientationControl = new _(), [
85
90
  this.algorithmControl,
91
+ this.strategyControl,
86
92
  this.localeControl,
87
93
  this.currencyControl,
88
94
  this.productCountControl,
@@ -91,18 +97,18 @@ class Q extends g {
91
97
  this.shuffleControl,
92
98
  this.pricePlacementControl,
93
99
  this.layoutOrientationControl
94
- ].forEach((e) => {
95
- e.api = this.api;
100
+ ].filter(Boolean).forEach((n) => {
101
+ n.api = this.api;
96
102
  }), `
97
103
  <div class="recommendation-controls-container">
98
- ${this.layoutOrientationControl.getTemplate()}
99
- ${this.productCountControl.getTemplate()}
100
- ${this.productLayoutControl.getTemplate()}
101
- ${this.algorithmControl.getTemplate()}
104
+ ${((o = this.strategyControl ?? this.algorithmControl) == null ? void 0 : o.getTemplate()) ?? ""}
102
105
  ${this.localeControl.getTemplate()}
103
- ${this.pricePlacementControl.getTemplate()}
104
106
  ${this.currencyControl.getTemplate()}
105
107
  ${this.filtersControl.getTemplate()}
108
+ ${this.productCountControl.getTemplate()}
109
+ ${this.productLayoutControl.getTemplate()}
110
+ ${this.layoutOrientationControl.getTemplate()}
111
+ ${this.pricePlacementControl.getTemplate()}
106
112
  ${this.shuffleControl.getTemplate()}
107
113
  </div>
108
114
  `;
@@ -117,24 +123,25 @@ class Q extends g {
117
123
  await this._fetchBlockData(e), this._initializeSubControls();
118
124
  }
119
125
  onTemplateNodeUpdated(t) {
120
- var r;
126
+ var n;
121
127
  super.onTemplateNodeUpdated(t);
122
128
  const e = this._getRecommendationIdFromNode(t);
123
- e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.syncedBlockIds.has(e) && (this.syncedBlockIds.add(e), this._syncNodeConfigToStore()), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e).then(() => {
129
+ e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && !this.syncedBlockIds.has(e) && (this.syncedBlockIds.add(e), this._syncNodeConfigToStore()), e !== null && !((n = this.store.blockStates[e]) != null && n.isInitialized) && this._fetchBlockData(e).then(() => {
124
130
  this._initializeSubControls();
125
131
  }), [
126
132
  this.layoutOrientationControl,
127
133
  this.productCountControl,
128
134
  this.algorithmControl,
135
+ this.strategyControl,
129
136
  this.localeControl,
130
137
  this.currencyControl,
131
138
  this.productLayoutControl,
132
139
  this.filtersControl,
133
140
  this.shuffleControl,
134
141
  this.pricePlacementControl
135
- ].forEach((n) => {
142
+ ].forEach((r) => {
136
143
  var i;
137
- n != null && n.api && (n.currentNode = t, (i = n.onTemplateNodeUpdated) == null || i.call(n, t));
144
+ r != null && r.api && (r.currentNode = t, (i = r.onTemplateNodeUpdated) == null || i.call(r, t));
138
145
  });
139
146
  }
140
147
  onDestroy() {
@@ -142,6 +149,7 @@ class Q extends g {
142
149
  this.layoutOrientationControl,
143
150
  this.productCountControl,
144
151
  this.algorithmControl,
152
+ this.strategyControl,
145
153
  this.localeControl,
146
154
  this.currencyControl,
147
155
  this.productLayoutControl,
@@ -162,6 +170,7 @@ class Q extends g {
162
170
  this.layoutOrientationControl,
163
171
  this.productCountControl,
164
172
  this.algorithmControl,
173
+ this.strategyControl,
165
174
  this.localeControl,
166
175
  this.currencyControl,
167
176
  this.productLayoutControl,
@@ -185,8 +194,8 @@ class Q extends g {
185
194
  * values are being prepared for the upcoming initial fetch.
186
195
  */
187
196
  _syncNodeConfigToStore() {
188
- var r;
189
- const t = m.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
197
+ var n;
198
+ const t = m.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
190
199
  this.store.patchCurrentBlockConfig({
191
200
  strategy: t.strategy,
192
201
  language: t.language,
@@ -196,10 +205,10 @@ class Q extends g {
196
205
  mobileCardsInRow: t.mobileCardsInRow,
197
206
  mobileLayoutEnabled: t.mobileLayoutEnabled,
198
207
  orientation: t.layout,
199
- // Only sync filters from node config during initial load.
200
- // After initialization, the Pinia store is the source of truth
201
- // for filters (edited via the filter drawer).
202
- ...o ? {} : { filters: t.filters },
208
+ // Only sync filters and strategy from node config during initial load.
209
+ // After initialization, the Pinia store is the source of truth for both
210
+ // (edited via the filter drawer and the strategy picker respectively).
211
+ ...o ? {} : { filters: t.filters, strategyId: t.strategyId },
203
212
  shuffleProducts: t.shuffleProducts,
204
213
  priceMovedToNextLine: t.priceMovedToNextLine,
205
214
  priceHideIfSameAsDiscounted: t.priceHideIfSameAsDiscounted,
@@ -224,16 +233,19 @@ class Q extends g {
224
233
  * Marks the block as initialized to prevent redundant fetches on re-selection.
225
234
  */
226
235
  async _fetchBlockData(t) {
227
- t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
228
- this.store.fetchRecommendationCreateData(),
229
- this.store.fetchRecommendationFilters()
230
- ])).forEach((o, r) => {
231
- o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][r]} failed`, o.reason);
236
+ t !== null && this.store.markBlockInitialized(t);
237
+ const e = h().isFeatureEnabled("reusableRecommendationStrategy"), o = [
238
+ { name: "fetchRecommendationCreateData", run: () => this.store.fetchRecommendationCreateData() },
239
+ { name: "fetchRecommendationFilters", run: () => this.store.fetchRecommendationFilters() },
240
+ ...e ? [{ name: "fetchRecommendationStrategies", run: () => this.store.fetchRecommendationStrategies() }] : []
241
+ ];
242
+ (await Promise.allSettled(o.map((r) => r.run()))).forEach((r, i) => {
243
+ r.status === "rejected" && console.warn(`Recommendation block: ${o[i].name} failed`, r.reason);
232
244
  }), this._applySmartDefaults();
233
245
  try {
234
246
  await this.store.fetchRecommendationProducts();
235
- } catch (o) {
236
- console.warn("Recommendation block: fetchRecommendationProducts failed", o);
247
+ } catch (r) {
248
+ console.warn("Recommendation block: fetchRecommendationProducts failed", r);
237
249
  }
238
250
  }
239
251
  /**
@@ -250,35 +262,35 @@ class Q extends g {
250
262
  if (!this.currentNode || !this.api)
251
263
  return;
252
264
  const t = m.getConfig(this.currentNode), e = {};
253
- let o = null, r = null, n = null;
254
- if (t.currency.code === c.currency.code) {
265
+ let o = null, n = null, r = null;
266
+ if (t.currency.code === a.currency.code) {
255
267
  const { currencyList: i } = this.store;
256
268
  i.length > 0 && (i.some(
257
- (u) => u.value === `price.${c.currency.code}`
269
+ (u) => u.value === `price.${a.currency.code}`
258
270
  ) || (o = i[0].value.replace("price.", ""), e.currency = {
259
- ...c.currency,
271
+ ...a.currency,
260
272
  code: o,
261
273
  symbol: o
262
274
  }));
263
275
  }
264
- if (t.strategy === c.strategy) {
276
+ if (t.strategy === a.strategy) {
265
277
  const i = this.store.getActivePredictiveAlgorithms;
266
278
  i.length > 0 && (i.some(
267
- (u) => u.value === c.strategy
268
- ) || (r = i[0].value, e.strategy = r));
279
+ (u) => u.value === a.strategy
280
+ ) || (n = i[0].value, e.strategy = n));
269
281
  }
270
- if (t.language === c.language) {
282
+ if (t.language === a.language) {
271
283
  const i = this.store.getLanguages;
272
284
  i.length > 0 && (i.some(
273
- (u) => u.value === c.language
274
- ) || (n = i[0].value, e.language = n));
285
+ (u) => u.value === a.language
286
+ ) || (r = i[0].value, e.language = r));
275
287
  }
276
- !o && !r && !n || (m.updateConfig(
288
+ !o && !n && !r || (m.updateConfig(
277
289
  this.api,
278
290
  this.currentNode,
279
291
  e,
280
292
  "Applied smart defaults"
281
- ), o && e.currency && S({
293
+ ), o && e.currency && k({
282
294
  currentNode: this.currentNode,
283
295
  documentModifier: this.api.getDocumentModifier(),
284
296
  currency: e.currency
@@ -288,28 +300,28 @@ class Q extends g {
288
300
  name: o,
289
301
  value: o,
290
302
  symbol: o,
291
- alignment: c.currency.alignment === "before" ? "0" : "1",
292
- decimalCount: c.currency.decimalCount.toString(),
293
- decimalSeparator: c.currency.decimalSeparator,
294
- thousandSeparator: c.currency.thousandSeparator
303
+ alignment: a.currency.alignment === "before" ? "0" : "1",
304
+ decimalCount: a.currency.decimalCount.toString(),
305
+ decimalSeparator: a.currency.decimalSeparator,
306
+ thousandSeparator: a.currency.thousandSeparator
295
307
  }
296
308
  } : {},
297
- ...r ? { strategy: r } : {},
298
- ...n ? { language: n } : {}
309
+ ...n ? { strategy: n } : {},
310
+ ...r ? { language: r } : {}
299
311
  }, { triggerRefetch: !1 }));
300
312
  }
301
313
  /**
302
314
  * Reads the recommendation-id attribute from the block element within the node
303
315
  */
304
316
  _getRecommendationIdFromNode(t) {
305
- const e = k(t);
317
+ const e = D(t);
306
318
  if (!e || !("getAttribute" in e))
307
319
  return null;
308
- const o = e.getAttribute(v);
320
+ const o = e.getAttribute(x);
309
321
  if (!o)
310
322
  return null;
311
- const r = parseInt(o);
312
- return Number.isNaN(r) ? null : r;
323
+ const n = parseInt(o);
324
+ return Number.isNaN(n) ? null : n;
313
325
  }
314
326
  /**
315
327
  * Listen to store changes that require product refresh or regeneration.
@@ -326,66 +338,72 @@ class Q extends g {
326
338
  */
327
339
  _listenStateUpdates() {
328
340
  const { store: t } = this;
329
- let e = t.recommendationProducts, o = t.$state.configVersion, r = t.currentRecommendationId;
341
+ let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
330
342
  this.storeUnsubscription = t.$subscribe(() => {
331
- const n = t.currentRecommendationId;
332
- if (n !== r) {
333
- r = n, e = t.recommendationProducts, o = t.$state.configVersion;
343
+ const r = t.currentRecommendationId;
344
+ if (r !== n) {
345
+ n = r, e = t.recommendationProducts, o = t.$state.configVersion;
334
346
  return;
335
347
  }
336
348
  const i = t.$state.configVersion;
337
- i !== o && (o = i, this._persistFiltersToNodeConfig(), this._debouncedFetchProducts());
338
- const a = t.recommendationProducts, u = a !== e, C = Array.isArray(a) && a.length > 0;
339
- u && C && (e = a, this._debouncedRegenerateWithProducts());
349
+ i !== o && (o = i, this._persistStoreConfigToNode(), this._debouncedFetchProducts());
350
+ const c = t.recommendationProducts, u = c !== e, f = Array.isArray(c) && c.length > 0;
351
+ u && f && (e = c, this._debouncedRegenerateWithProducts());
340
352
  });
341
353
  }
342
354
  /**
343
- * Persists the current filter state from Pinia store to the Stripo node config.
344
- * This ensures filters survive template save/reload cycles.
355
+ * Persists the Pinia-owned parts of the block config to the Stripo node config,
356
+ * so they survive template save/reload cycles.
357
+ *
358
+ * Filters are edited in a drawer and the strategy in an overlaid picker — neither
359
+ * is a Stripo form element, so neither can write to the node itself. Both ride
360
+ * this one update to keep the undo history to a single entry per change.
345
361
  */
346
- _persistFiltersToNodeConfig() {
362
+ _persistStoreConfigToNode() {
347
363
  if (!this.currentNode || !this.api)
348
364
  return;
349
- const { filters: t } = this.store.recommendationConfigs;
365
+ const { filters: t, strategyId: e } = this.store.recommendationConfigs;
350
366
  m.updateConfig(
351
367
  this.api,
352
368
  this.currentNode,
353
- { filters: t },
354
- "Update recommendation filters"
369
+ { filters: t, strategyId: e },
370
+ "Update recommendation settings"
355
371
  );
356
372
  }
357
373
  }
358
374
  export {
359
- tt as ALGORITHM_CONTROL_ID,
360
- N as AlgorithmControl,
361
- w as CONTROL_BLOCK_ID,
362
- ot as CURRENCY_CONTROL_ID,
363
- R as CurrencyControl,
364
- nt as FILTERS_CONTROL_ID,
365
- I as FiltersControl,
366
- st as LAYOUT_ORIENTATION_CONTROL_ID,
367
- lt as LOCALE_CONTROL_ID,
375
+ nt as ALGORITHM_CONTROL_ID,
376
+ b as AlgorithmControl,
377
+ B as CONTROL_BLOCK_ID,
378
+ st as CURRENCY_CONTROL_ID,
379
+ I as CurrencyControl,
380
+ lt as FILTERS_CONTROL_ID,
381
+ N as FiltersControl,
382
+ ut as LAYOUT_ORIENTATION_CONTROL_ID,
383
+ mt as LOCALE_CONTROL_ID,
368
384
  _ as LayoutOrientationControl,
369
- b as LocaleControl,
370
- ut as PRICE_PLACEMENT_CONTROL_ID,
371
- mt as PRODUCT_COUNT_CONTROL_ID,
372
- Ct as PRODUCT_LAYOUT_CONTROL_ID,
373
- T as PricePlacementControl,
374
- P as ProductCountControl,
375
- O as ProductLayoutControl,
376
- Q as RecommendationBlockControl,
377
- pt as SHUFFLE_CONTROL_ID,
385
+ T as LocaleControl,
386
+ Ct as PRICE_PLACEMENT_CONTROL_ID,
387
+ gt as PRODUCT_COUNT_CONTROL_ID,
388
+ yt as PRODUCT_LAYOUT_CONTROL_ID,
389
+ S as PricePlacementControl,
390
+ O as ProductCountControl,
391
+ P as ProductLayoutControl,
392
+ et as RecommendationBlockControl,
393
+ bt as SHUFFLE_CONTROL_ID,
394
+ Nt as STRATEGY_CONTROL_ID,
378
395
  L as ShuffleControl,
379
- yt as adjustProductsToSize,
380
- Nt as formatProductPrice,
381
- k as getBlockElement,
382
- Rt as getCardComposition,
383
- It as getCurrentLayout,
384
- D as isPartnerManagedBlock,
385
- _t as regenerateMobileProductRows,
386
- A as regenerateProductRowsWithStyles,
387
- S as setCurrencyAttributes,
388
- bt as updatePricesInPlace,
389
- E as updateProductContentInPlace,
390
- Tt as updateSingleProductContent
396
+ E as StrategyControl,
397
+ Tt as adjustProductsToSize,
398
+ St as formatProductPrice,
399
+ D as getBlockElement,
400
+ Ot as getCardComposition,
401
+ Pt as getCurrentLayout,
402
+ A as isPartnerManagedBlock,
403
+ Lt as regenerateMobileProductRows,
404
+ v as regenerateProductRowsWithStyles,
405
+ k as setCurrencyAttributes,
406
+ Et as updatePricesInPlace,
407
+ w as updateProductContentInPlace,
408
+ kt as updateSingleProductContent
391
409
  };