@useinsider/guido 2.2.0-beta.eeefcc3 → 3.0.0-beta.118d815

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 (102) hide show
  1. package/README.md +41 -2
  2. package/dist/@types/config/schemas.js +1 -1
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +87 -78
  5. package/dist/components/organisms/base/Toaster.vue.js +4 -4
  6. package/dist/components/organisms/base/Toaster.vue2.js +12 -9
  7. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +5 -5
  8. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +2 -2
  9. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +11 -13
  10. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +54 -23
  11. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +7 -5
  12. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +34 -21
  13. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +11 -11
  14. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +48 -36
  15. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +11 -9
  16. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
  17. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
  18. package/dist/composables/useRecommendation.js +9 -9
  19. package/dist/composables/useSave.js +16 -12
  20. package/dist/composables/useStripo.js +66 -62
  21. package/dist/composables/useStripoEventHandler.js +27 -12
  22. package/dist/composables/useSyncModuleExtractor.js +45 -0
  23. package/dist/config/compiler/utils/recommendationCompilerUtils.js +1 -1
  24. package/dist/config/migrator/recommendationMigrator.js +1 -1
  25. package/dist/enums/unsubscribe.js +25 -21
  26. package/dist/extensions/Blocks/Recommendation/block.js +1 -1
  27. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +36 -33
  28. package/dist/extensions/Blocks/Recommendation/constants/layout.js +16 -14
  29. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +15 -13
  30. package/dist/extensions/Blocks/Recommendation/controls/button/index.js +9 -9
  31. package/dist/extensions/Blocks/Recommendation/controls/image/index.js +1 -1
  32. package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +41 -29
  33. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +16 -16
  34. package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +30 -32
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +194 -104
  36. package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +9 -9
  37. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +46 -38
  38. package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +16 -16
  39. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +291 -217
  40. package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +14 -14
  41. package/dist/extensions/Blocks/Recommendation/controls/name/index.js +10 -10
  42. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +5 -5
  43. package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +14 -14
  44. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +9 -9
  45. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +3 -3
  46. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +1 -1
  47. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +9 -9
  48. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +3 -3
  49. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +13 -13
  50. package/dist/extensions/Blocks/Recommendation/controls/price/index.js +3 -3
  51. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +223 -99
  52. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +172 -85
  53. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +2 -2
  54. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +1 -1
  55. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +2 -2
  56. package/dist/extensions/Blocks/Recommendation/templates/utils.js +32 -32
  57. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
  58. package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +29 -0
  59. package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
  60. package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
  61. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
  62. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
  63. package/dist/guido.css +1 -1
  64. package/dist/services/stripoApi.js +55 -19
  65. package/dist/src/@types/config/schemas.d.ts +1 -1
  66. package/dist/src/@types/events.d.ts +38 -2
  67. package/dist/src/App.vue.d.ts +3 -1
  68. package/dist/src/components/Guido.vue.d.ts +2 -2
  69. package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +1 -0
  70. package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +17 -1
  71. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  72. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  73. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  74. package/dist/src/composables/useGuidoActions.d.ts +1 -1
  75. package/dist/src/composables/useSave.d.ts +2 -2
  76. package/dist/src/composables/useStripo.d.ts +2 -2
  77. package/dist/src/composables/useSyncModuleExtractor.d.ts +4 -0
  78. package/dist/src/enums/unsubscribe.d.ts +3 -0
  79. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +6 -0
  80. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +3 -3
  81. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -2
  82. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +8 -1
  83. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +38 -10
  84. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +27 -14
  85. package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +50 -17
  86. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +19 -2
  87. package/dist/src/extensions/Blocks/Recommendation/templates/grid/migration.d.ts +1 -1
  88. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +4 -2
  89. package/dist/src/extensions/Blocks/Recommendation/templates/list/migration.d.ts +1 -1
  90. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -1
  91. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +8 -0
  92. package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +15 -0
  93. package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
  94. package/dist/src/mock/api/settings.d.ts +2 -0
  95. package/dist/src/services/stripoApi.d.ts +5 -0
  96. package/dist/src/stores/editor.d.ts +23 -0
  97. package/dist/src/utils/templatePreparation.d.ts +1 -1
  98. package/dist/static/styles/customEditorStyle.css.js +50 -23
  99. package/dist/stores/editor.js +2 -1
  100. package/dist/stores/unsubscribe.js +37 -34
  101. package/dist/utils/templatePreparation.js +1 -1
  102. package/package.json +2 -2
@@ -1,13 +1,13 @@
1
1
  var R = Object.defineProperty;
2
- var _ = (s, o, e) => o in s ? R(s, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[o] = e;
3
- var c = (s, o, e) => _(s, typeof o != "symbol" ? o + "" : o, e);
4
- import { currencyLocationMaps as l, currencyOperators as i, currencyDecimalCounts as h } from "../../../../../enums/extensions/recommendationBlock.js";
2
+ var _ = (i, o, e) => o in i ? R(i, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[o] = e;
3
+ var c = (i, o, e) => _(i, typeof o != "symbol" ? o + "" : o, e);
4
+ import { currencyLocationMaps as l, currencyOperators as a, currencyDecimalCounts as h } from "../../../../../enums/extensions/recommendationBlock.js";
5
5
  import { UEAttr as m } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
- import { CommonControl as d } from "../../../common-control.js";
7
- import { RecommendationConfigService as C } from "../../services/configService.js";
8
- import { useRecommendationExtensionStore as p } from "../../store/recommendation.js";
9
- import { setCurrencyAttributes as S, updatePricesInPlace as E, regenerateProductRowsWithStyles as N } from "./utils.js";
10
- const y = "recommendation-currency-control", t = {
6
+ import { CommonControl as p } from "../../../common-control.js";
7
+ import { RecommendationConfigService as s } from "../../services/configService.js";
8
+ import { useRecommendationExtensionStore as d } from "../../store/recommendation.js";
9
+ import { setCurrencyAttributes as S, updatePricesInPlace as N } from "./utils.js";
10
+ const E = "recommendation-currency-control", t = {
11
11
  CURRENCY: "currencyCode",
12
12
  CURRENCY_LOCATION: "currencyAlignment",
13
13
  CURRENCY_SYMBOL: "currencySymbol",
@@ -15,16 +15,16 @@ const y = "recommendation-currency-control", t = {
15
15
  CURRENCY_DECIMAL_SEPARATOR: "currencyDecimalSeparator",
16
16
  CURRENCY_DECIMAL_COUNT: "currencyDecimalCount"
17
17
  };
18
- class D extends d {
18
+ class Y extends p {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  // Store is used ONLY for API-fetched data (currency list), not for config
22
- c(this, "store", p());
22
+ c(this, "store", d());
23
23
  c(this, "storeUnsubscription", () => {
24
24
  });
25
25
  }
26
26
  getId() {
27
- return y;
27
+ return E;
28
28
  }
29
29
  getTemplate() {
30
30
  return `
@@ -52,13 +52,13 @@ class D extends d {
52
52
  this._GuSelect({
53
53
  name: t.CURRENCY_THOUSAND_SEPARATOR,
54
54
  placeholder: "Select Thousand Separator",
55
- options: i
55
+ options: a
56
56
  }),
57
57
  this._GuLabel({ text: "Decimal Separator" }),
58
58
  this._GuSelect({
59
59
  name: t.CURRENCY_DECIMAL_SEPARATOR,
60
60
  placeholder: "Select Decimal Separator",
61
- options: i
61
+ options: a
62
62
  }),
63
63
  this._GuLabel({ text: "Decimal Count" }),
64
64
  this._GuSelect({
@@ -82,7 +82,7 @@ class D extends d {
82
82
  this.storeUnsubscription();
83
83
  }
84
84
  _setFormValues() {
85
- const e = C.getConfig(this.currentNode), { currency: r } = e;
85
+ const e = s.getConfig(this.currentNode), { currency: r } = e;
86
86
  this.api.updateValues({
87
87
  [t.CURRENCY]: `price.${r.code}`,
88
88
  [t.CURRENCY_LOCATION]: r.alignment === "before" ? "0" : "1",
@@ -96,12 +96,12 @@ class D extends d {
96
96
  const { store: e } = this, r = {
97
97
  [t.CURRENCY]: e.currencyList,
98
98
  [t.CURRENCY_LOCATION]: l,
99
- [t.CURRENCY_THOUSAND_SEPARATOR]: i,
100
- [t.CURRENCY_DECIMAL_SEPARATOR]: i,
99
+ [t.CURRENCY_THOUSAND_SEPARATOR]: a,
100
+ [t.CURRENCY_DECIMAL_SEPARATOR]: a,
101
101
  [t.CURRENCY_DECIMAL_COUNT]: h
102
102
  };
103
- Object.entries(r).forEach(([u, n]) => {
104
- this.api.setUIEAttribute(u, m.SELECTPICKER.items, n);
103
+ Object.entries(r).forEach(([C, n]) => {
104
+ this.api.setUIEAttribute(C, m.SELECTPICKER.items, n);
105
105
  });
106
106
  }
107
107
  /**
@@ -114,17 +114,17 @@ class D extends d {
114
114
  _updateCurrency(e, r = !1) {
115
115
  if (!this.currentNode)
116
116
  return;
117
- const n = { ...C.getConfig(this.currentNode).currency, ...e };
118
- C.updateConfig(
117
+ const n = { ...s.getConfig(this.currentNode).currency, ...e };
118
+ s.updateConfig(
119
119
  this.api,
120
120
  this.currentNode,
121
121
  { currency: n },
122
122
  "Updated currency settings"
123
123
  );
124
- const a = this.api.getDocumentModifier();
124
+ const u = this.api.getDocumentModifier();
125
125
  S({
126
126
  currentNode: this.currentNode,
127
- documentModifier: a,
127
+ documentModifier: u,
128
128
  currency: n
129
129
  }), this.store.patchCurrentBlockConfig({
130
130
  currencySettings: {
@@ -136,22 +136,19 @@ class D extends d {
136
136
  decimalSeparator: n.decimalSeparator,
137
137
  thousandSeparator: n.thousandSeparator
138
138
  }
139
- }, { triggerRefetch: r }), E({
139
+ }, { triggerRefetch: r }), N({
140
140
  currentNode: this.currentNode,
141
- documentModifier: a
142
- }) || N({
143
- currentNode: this.currentNode,
144
- documentModifier: a
141
+ documentModifier: u
145
142
  });
146
143
  }
147
144
  _onCurrencyChange(e) {
148
145
  const [, r] = e.includes(".") ? e.split(".") : [null, e];
149
- this._updateCurrency({
146
+ s.getConfig(this.currentNode).currency.code !== r && (this._updateCurrency({
150
147
  code: r,
151
148
  symbol: r
152
149
  }, !0), this.api.updateValues({
153
150
  [t.CURRENCY_SYMBOL]: r
154
- });
151
+ }));
155
152
  }
156
153
  _onCurrencyLocationChange(e) {
157
154
  this._updateCurrency({
@@ -172,8 +169,9 @@ class D extends d {
172
169
  });
173
170
  }
174
171
  _onDecimalCountChange(e) {
172
+ const r = parseInt(e);
175
173
  this._updateCurrency({
176
- decimalCount: parseInt(e) || 2
174
+ decimalCount: Number.isNaN(r) ? 2 : r
177
175
  });
178
176
  }
179
177
  _listenToFormUpdates() {
@@ -204,6 +202,6 @@ class D extends d {
204
202
  }
205
203
  }
206
204
  export {
207
- y as CURRENCY_CONTROL_ID,
208
- D as CurrencyControl
205
+ E as CURRENCY_CONTROL_ID,
206
+ Y as CurrencyControl
209
207
  };
@@ -1,65 +1,77 @@
1
- var d = Object.defineProperty;
2
- var m = (c, s, t) => s in c ? d(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
3
- var n = (c, s, t) => m(c, typeof s != "symbol" ? s + "" : s, t);
4
- import { CommonControl as h } from "../../../common-control.js";
5
- import { RecommendationConfigService as f } from "../../services/configService.js";
6
- import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
7
- import { AlgorithmControl as p } from "./algorithm.js";
8
- import { ALGORITHM_CONTROL_ID as W } from "./algorithm.js";
9
- import { CurrencyControl as g } from "./currency.js";
10
- import { CURRENCY_CONTROL_ID as H } from "./currency.js";
11
- import { FiltersControl as R } from "./filters.js";
12
- import { FILTERS_CONTROL_ID as j } from "./filters.js";
13
- import { LocaleControl as y } from "./locale.js";
14
- import { LOCALE_CONTROL_ID as K } from "./locale.js";
15
- import { ProductLayoutControl as _ } from "./productLayout.js";
16
- import { PRODUCT_LAYOUT_CONTROL_ID as J } from "./productLayout.js";
17
- import { ShuffleControl as N } from "./shuffle.js";
18
- import { SHUFFLE_CONTROL_ID as X } from "./shuffle.js";
19
- import { regenerateProductRowsWithStyles as b, getBlockElement as P, updateProductContentInPlace as I } from "./utils.js";
20
- import { formatProductPrice as tt, getCardComposition as et, getCurrentLayout as ot, reapplySpacing as rt, regenerateMobileProductRows as nt, regenerateProductRows as it, setCurrencyAttributes as st, updatePricesInPlace as ct, updateSingleProductContent as at } from "./utils.js";
21
- import { useDebounceFn as l } from "../../../../../node_modules/@vueuse/shared/index.js";
22
- const T = "recommendation-id", S = "ui-elements-recommendation-block";
23
- class $ extends h {
1
+ var g = Object.defineProperty;
2
+ var C = (d, c, t) => c in d ? g(d, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[c] = t;
3
+ var i = (d, c, t) => C(d, typeof c != "symbol" ? c + "" : c, t);
4
+ import { CommonControl as p } from "../../../common-control.js";
5
+ import { DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
6
+ import { RecommendationConfigService as m } from "../../services/configService.js";
7
+ import { useRecommendationExtensionStore as y } from "../../store/recommendation.js";
8
+ import { AlgorithmControl as R } from "./algorithm.js";
9
+ import { ALGORITHM_CONTROL_ID as H } from "./algorithm.js";
10
+ import { CurrencyControl as N } from "./currency.js";
11
+ import { CURRENCY_CONTROL_ID as K } from "./currency.js";
12
+ import { FiltersControl as b } from "./filters.js";
13
+ import { FILTERS_CONTROL_ID as J } from "./filters.js";
14
+ import { LocaleControl as _ } from "./locale.js";
15
+ import { LOCALE_CONTROL_ID as X } from "./locale.js";
16
+ import { ProductLayoutControl as I } from "./productLayout.js";
17
+ import { PRODUCT_LAYOUT_CONTROL_ID as tt } from "./productLayout.js";
18
+ import { ShuffleControl as S } from "./shuffle.js";
19
+ import { SHUFFLE_CONTROL_ID as ot } from "./shuffle.js";
20
+ import { getBlockElement as P, updateProductContentInPlace as T, regenerateProductRowsWithStyles as L } from "./utils.js";
21
+ import { adjustProductsToSize as nt, formatProductPrice as st, getCardComposition as it, getCurrentLayout as at, reapplySpacing as ct, regenerateMobileProductRows as lt, regenerateProductRows as ut, setCurrencyAttributes as dt, updatePricesInPlace as mt, updateSingleProductContent as ht } from "./utils.js";
22
+ import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
23
+ const k = "recommendation-id", D = "ui-elements-recommendation-block";
24
+ class W extends p {
24
25
  constructor() {
25
26
  super(...arguments);
26
- n(this, "store", C());
27
- n(this, "storeUnsubscription", () => {
27
+ i(this, "store", y());
28
+ i(this, "storeUnsubscription", () => {
28
29
  });
29
30
  // Sub-control instances for lifecycle management
30
- n(this, "algorithmControl", null);
31
- n(this, "localeControl", null);
32
- n(this, "currencyControl", null);
33
- n(this, "productLayoutControl", null);
34
- n(this, "filtersControl", null);
35
- n(this, "shuffleControl", null);
31
+ i(this, "algorithmControl", null);
32
+ i(this, "localeControl", null);
33
+ i(this, "currencyControl", null);
34
+ i(this, "productLayoutControl", null);
35
+ i(this, "filtersControl", null);
36
+ i(this, "shuffleControl", null);
36
37
  /**
37
38
  * Debounced product fetch to prevent rapid API calls during config changes
38
39
  */
39
- n(this, "_debouncedFetchProducts", l(() => {
40
+ i(this, "_debouncedFetchProducts", h(() => {
40
41
  this.store.fetchRecommendationProducts();
41
42
  }, 500));
42
43
  /**
43
- * Debounced regeneration when products arrive from API
44
- * Tries in-place update first to preserve styles, falls back to full regeneration
44
+ * Debounced content update when products arrive from API.
45
+ *
46
+ * Tries in-place update first (preserves user-applied styles) — this succeeds
47
+ * when the product count matches the DOM (algorithm/locale/currency changes).
48
+ *
49
+ * Falls back to full regeneration when product count differs from DOM — this
50
+ * happens after "Number of Products" changes where the DOM still has the old
51
+ * count. The store pads products to the configured size, so in-place only
52
+ * fails when the size actually changed.
45
53
  */
46
- n(this, "_debouncedRegenerateWithProducts", l(() => {
54
+ i(this, "_debouncedRegenerateWithProducts", h(() => {
47
55
  const t = this.store.recommendationProducts;
48
56
  if (!this.currentNode || !this.api)
49
57
  return;
50
58
  const e = this.api.getDocumentModifier();
51
- I({
59
+ T({
52
60
  currentNode: this.currentNode,
53
61
  documentModifier: e,
54
62
  products: t
55
- }) || this._regenerateWithProducts(t);
63
+ }) || L({
64
+ currentNode: this.currentNode,
65
+ documentModifier: e,
66
+ products: t
67
+ });
56
68
  }, 100));
57
69
  }
58
70
  getId() {
59
- return S;
71
+ return D;
60
72
  }
61
73
  getTemplate() {
62
- return this.algorithmControl = new p(), this.localeControl = new y(), this.currencyControl = new g(), this.productLayoutControl = new _(), this.filtersControl = new R(), this.shuffleControl = new N(), `
74
+ return this.algorithmControl = new R(), this.localeControl = new _(), this.currencyControl = new N(), this.productLayoutControl = new I(), this.filtersControl = new b(), this.shuffleControl = new S(), `
63
75
  <div class="recommendation-controls-container">
64
76
  ${this.algorithmControl.getTemplate()}
65
77
  ${this.localeControl.getTemplate()}
@@ -79,35 +91,20 @@ class $ extends h {
79
91
  }
80
92
  await this._fetchBlockData(t), this._initializeSubControls();
81
93
  }
82
- /**
83
- * Immediately regenerate products with styles (no debounce)
84
- * Used for initial load after fetch completes
85
- */
86
- _regenerateWithProducts(t) {
87
- if (!this.currentNode || !this.api) {
88
- console.warn("[Recommendation] Cannot regenerate - missing currentNode or api");
89
- return;
90
- }
91
- b({
92
- currentNode: this.currentNode,
93
- documentModifier: this.api.getDocumentModifier(),
94
- products: t
95
- });
96
- }
97
94
  onTemplateNodeUpdated(t) {
98
- var i;
95
+ var r;
99
96
  super.onTemplateNodeUpdated(t);
100
97
  const e = this._getRecommendationIdFromNode(t);
101
- e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((i = this.store.blockStates[e]) != null && i.isInitialized) && this._fetchBlockData(e), [
98
+ e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e), [
102
99
  this.algorithmControl,
103
100
  this.localeControl,
104
101
  this.currencyControl,
105
102
  this.productLayoutControl,
106
103
  this.filtersControl,
107
104
  this.shuffleControl
108
- ].forEach((r) => {
109
- var a;
110
- r != null && r.api && (r.currentNode = t, (a = r.onTemplateNodeUpdated) == null || a.call(r, t));
105
+ ].forEach((n) => {
106
+ var s;
107
+ n != null && n.api && (n.currentNode = t, (s = n.onTemplateNodeUpdated) == null || s.call(n, t));
111
108
  });
112
109
  }
113
110
  onDestroy() {
@@ -152,13 +149,17 @@ class $ extends h {
152
149
  * values are being prepared for the upcoming initial fetch.
153
150
  */
154
151
  _syncNodeConfigToStore() {
155
- const t = f.getConfig(this.currentNode);
152
+ var r;
153
+ const t = m.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
156
154
  this.store.patchCurrentBlockConfig({
157
155
  strategy: t.strategy,
158
156
  language: t.language,
159
157
  size: t.size,
160
158
  productIds: t.productIds,
161
- filters: t.filters,
159
+ // Only sync filters from node config during initial load.
160
+ // After initialization, the Pinia store is the source of truth
161
+ // for filters (edited via the filter drawer).
162
+ ...o ? {} : { filters: t.filters },
162
163
  shuffleProducts: t.shuffleProducts,
163
164
  currencySettings: {
164
165
  name: t.currency.code,
@@ -172,22 +173,84 @@ class $ extends h {
172
173
  }, { triggerRefetch: !1 });
173
174
  }
174
175
  /**
175
- * Fetches initial data for a block (filters, algorithms, products).
176
+ * Fetches initial data for a block in three phases:
177
+ * 1. Shared reference data (algorithms, currencies, filters) — parallel
178
+ * 2. Smart defaults for new blocks (currency, algorithm) — sequential
179
+ * 3. Product data with correct defaults — sequential
180
+ *
176
181
  * Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
177
182
  * Marks the block as initialized to prevent redundant fetches on re-selection.
178
183
  */
179
184
  async _fetchBlockData(t) {
180
185
  t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
181
- this.store.fetchRecommendationFilters(),
182
186
  this.store.fetchRecommendationCreateData(),
183
- this.store.fetchRecommendationProducts()
184
- ])).forEach((o, i) => {
185
- o.status === "rejected" && console.warn(`Recommendation block: ${[
186
- "fetchRecommendationFilters",
187
- "fetchRecommendationCreateData",
188
- "fetchRecommendationProducts"
189
- ][i]} failed`, o.reason);
190
- });
187
+ this.store.fetchRecommendationFilters()
188
+ ])).forEach((o, r) => {
189
+ o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][r]} failed`, o.reason);
190
+ }), this._applySmartDefaults();
191
+ try {
192
+ await this.store.fetchRecommendationProducts();
193
+ } catch (o) {
194
+ console.warn("Recommendation block: fetchRecommendationProducts failed", o);
195
+ }
196
+ }
197
+ /**
198
+ * Applies smart defaults for newly dropped blocks.
199
+ *
200
+ * For new blocks (config still matches hardcoded defaults), validates that
201
+ * the default currency and algorithm are available from the API response.
202
+ * If not, falls back to the first available option.
203
+ *
204
+ * Saved templates with user-customized config are left unchanged because
205
+ * their values won't match the hardcoded defaults.
206
+ */
207
+ _applySmartDefaults() {
208
+ if (!this.currentNode || !this.api)
209
+ return;
210
+ const t = m.getConfig(this.currentNode), e = {};
211
+ let o = null, r = null, n = null;
212
+ if (t.currency.code === a.currency.code) {
213
+ const { currencyList: s } = this.store;
214
+ s.length > 0 && (s.some(
215
+ (u) => u.value === `price.${a.currency.code}`
216
+ ) || (o = s[0].value.replace("price.", ""), e.currency = {
217
+ ...a.currency,
218
+ code: o,
219
+ symbol: o
220
+ }));
221
+ }
222
+ if (t.strategy === a.strategy) {
223
+ const s = this.store.getActivePredictiveAlgorithms;
224
+ s.length > 0 && (s.some(
225
+ (u) => u.value === a.strategy
226
+ ) || (r = s[0].value, e.strategy = r));
227
+ }
228
+ if (t.language === a.language) {
229
+ const s = this.store.getLanguages;
230
+ s.length > 0 && (s.some(
231
+ (u) => u.value === a.language
232
+ ) || (n = s[0].value, e.language = n));
233
+ }
234
+ !o && !r && !n || (m.updateConfig(
235
+ this.api,
236
+ this.currentNode,
237
+ e,
238
+ "Applied smart defaults"
239
+ ), this.store.patchCurrentBlockConfig({
240
+ ...o ? {
241
+ currencySettings: {
242
+ name: o,
243
+ value: o,
244
+ symbol: o,
245
+ alignment: a.currency.alignment === "before" ? "0" : "1",
246
+ decimalCount: a.currency.decimalCount.toString(),
247
+ decimalSeparator: a.currency.decimalSeparator,
248
+ thousandSeparator: a.currency.thousandSeparator
249
+ }
250
+ } : {},
251
+ ...r ? { strategy: r } : {},
252
+ ...n ? { language: n } : {}
253
+ }, { triggerRefetch: !1 }));
191
254
  }
192
255
  /**
193
256
  * Reads the recommendation-id attribute from the block element within the node
@@ -196,11 +259,11 @@ class $ extends h {
196
259
  const e = P(t);
197
260
  if (!e || !("getAttribute" in e))
198
261
  return null;
199
- const o = e.getAttribute(T);
262
+ const o = e.getAttribute(k);
200
263
  if (!o)
201
264
  return null;
202
- const i = parseInt(o);
203
- return Number.isNaN(i) ? null : i;
265
+ const r = parseInt(o);
266
+ return Number.isNaN(r) ? null : r;
204
267
  }
205
268
  /**
206
269
  * Listen to store changes that require product refresh or regeneration.
@@ -208,43 +271,70 @@ class $ extends h {
208
271
  * Uses configVersion counter (incremented only by patchCurrentBlockConfig)
209
272
  * to distinguish user-initiated config changes from internal mutations
210
273
  * (e.g., fetchRecommendationCreateData setting preferred currency).
274
+ *
275
+ * Tracks currentRecommendationId to detect block switches. When the user
276
+ * selects a different recommendation block, the proxy getters (e.g.,
277
+ * recommendationProducts) return the new block's data — a different array
278
+ * reference that would be falsely detected as "new products arrived".
279
+ * We skip that tick and update tracking references instead.
211
280
  */
212
281
  _listenStateUpdates() {
213
282
  const { store: t } = this;
214
- let e = t.recommendationProducts, o = t.$state.configVersion;
283
+ let e = t.recommendationProducts, o = t.$state.configVersion, r = t.currentRecommendationId;
215
284
  this.storeUnsubscription = t.$subscribe(() => {
216
- const i = t.$state.configVersion;
217
- i !== o && (o = i, this._debouncedFetchProducts());
218
- const r = t.recommendationProducts, a = r !== e, u = Array.isArray(r) && r.length > 0;
219
- a && u && (e = r, this._debouncedRegenerateWithProducts());
285
+ const n = t.currentRecommendationId;
286
+ if (n !== r) {
287
+ r = n, e = t.recommendationProducts, o = t.$state.configVersion;
288
+ return;
289
+ }
290
+ const s = t.$state.configVersion;
291
+ s !== o && (o = s, this._persistFiltersToNodeConfig(), this._debouncedFetchProducts());
292
+ const l = t.recommendationProducts, u = l !== e, f = Array.isArray(l) && l.length > 0;
293
+ u && f && (e = l, this._debouncedRegenerateWithProducts());
220
294
  });
221
295
  }
296
+ /**
297
+ * Persists the current filter state from Pinia store to the Stripo node config.
298
+ * This ensures filters survive template save/reload cycles.
299
+ */
300
+ _persistFiltersToNodeConfig() {
301
+ if (!this.currentNode || !this.api)
302
+ return;
303
+ const { filters: t } = this.store.recommendationConfigs;
304
+ m.updateConfig(
305
+ this.api,
306
+ this.currentNode,
307
+ { filters: t },
308
+ "Update recommendation filters"
309
+ );
310
+ }
222
311
  }
223
312
  export {
224
- W as ALGORITHM_CONTROL_ID,
225
- p as AlgorithmControl,
226
- S as CONTROL_BLOCK_ID,
227
- H as CURRENCY_CONTROL_ID,
228
- g as CurrencyControl,
229
- j as FILTERS_CONTROL_ID,
230
- R as FiltersControl,
231
- K as LOCALE_CONTROL_ID,
232
- y as LocaleControl,
233
- J as PRODUCT_LAYOUT_CONTROL_ID,
234
- _ as ProductLayoutControl,
235
- $ as RecommendationBlockControl,
236
- X as SHUFFLE_CONTROL_ID,
237
- N as ShuffleControl,
238
- tt as formatProductPrice,
313
+ H as ALGORITHM_CONTROL_ID,
314
+ R as AlgorithmControl,
315
+ D as CONTROL_BLOCK_ID,
316
+ K as CURRENCY_CONTROL_ID,
317
+ N as CurrencyControl,
318
+ J as FILTERS_CONTROL_ID,
319
+ b as FiltersControl,
320
+ X as LOCALE_CONTROL_ID,
321
+ _ as LocaleControl,
322
+ tt as PRODUCT_LAYOUT_CONTROL_ID,
323
+ I as ProductLayoutControl,
324
+ W as RecommendationBlockControl,
325
+ ot as SHUFFLE_CONTROL_ID,
326
+ S as ShuffleControl,
327
+ nt as adjustProductsToSize,
328
+ st as formatProductPrice,
239
329
  P as getBlockElement,
240
- et as getCardComposition,
241
- ot as getCurrentLayout,
242
- rt as reapplySpacing,
243
- nt as regenerateMobileProductRows,
244
- it as regenerateProductRows,
245
- b as regenerateProductRowsWithStyles,
246
- st as setCurrencyAttributes,
247
- ct as updatePricesInPlace,
248
- I as updateProductContentInPlace,
249
- at as updateSingleProductContent
330
+ it as getCardComposition,
331
+ at as getCurrentLayout,
332
+ ct as reapplySpacing,
333
+ lt as regenerateMobileProductRows,
334
+ ut as regenerateProductRows,
335
+ L as regenerateProductRowsWithStyles,
336
+ dt as setCurrencyAttributes,
337
+ mt as updatePricesInPlace,
338
+ T as updateProductContentInPlace,
339
+ ht as updateSingleProductContent
250
340
  };
@@ -2,20 +2,20 @@ var s = Object.defineProperty;
2
2
  var r = (o, t, e) => t in o ? s(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
3
3
  var a = (o, t, e) => r(o, typeof t != "symbol" ? t + "" : t, e);
4
4
  import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
- import { CommonControl as m } from "../../../common-control.js";
5
+ import { CommonControl as c } from "../../../common-control.js";
6
6
  import { RecommendationConfigService as i } from "../../services/configService.js";
7
- import { useRecommendationExtensionStore as c } from "../../store/recommendation.js";
8
- const g = "recommendation-locale-control", n = {
7
+ import { useRecommendationExtensionStore as g } from "../../store/recommendation.js";
8
+ const m = "recommendation-locale-control", n = {
9
9
  LOCALE: "language"
10
10
  };
11
- class C extends m {
11
+ class E extends c {
12
12
  constructor() {
13
13
  super(...arguments);
14
14
  // Store is used ONLY for API-fetched data (language options), not for config
15
- a(this, "store", c());
15
+ a(this, "store", g());
16
16
  }
17
17
  getId() {
18
- return g;
18
+ return m;
19
19
  }
20
20
  getTemplate() {
21
21
  return `
@@ -51,7 +51,7 @@ class C extends m {
51
51
  );
52
52
  }
53
53
  _onLocaleChange(e) {
54
- this.currentNode && (i.updateConfig(
54
+ !this.currentNode || i.getConfig(this.currentNode).language === e || (i.updateConfig(
55
55
  this.api,
56
56
  this.currentNode,
57
57
  { language: e },
@@ -65,6 +65,6 @@ class C extends m {
65
65
  }
66
66
  }
67
67
  export {
68
- g as LOCALE_CONTROL_ID,
69
- C as LocaleControl
68
+ m as LOCALE_CONTROL_ID,
69
+ E as LocaleControl
70
70
  };