@useinsider/guido 2.1.0-beta.a873eb7 → 2.1.0-beta.ab9a598

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 (68) hide show
  1. package/dist/@types/config/schemas.js +1 -1
  2. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +13 -11
  3. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +23 -54
  4. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +3 -3
  5. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +21 -34
  6. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +11 -11
  7. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +34 -44
  8. package/dist/components/organisms/header/EditorActions.vue.js +10 -8
  9. package/dist/components/organisms/header/EditorActions.vue2.js +40 -30
  10. package/dist/components/organisms/header/MigrationConfirmModal.vue.js +17 -0
  11. package/dist/components/organisms/header/MigrationConfirmModal.vue2.js +39 -0
  12. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
  13. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
  14. package/dist/composables/useStripo.js +25 -23
  15. package/dist/composables/useVersionHistoryApi.js +1 -1
  16. package/dist/config/i18n/en/index.js +11 -0
  17. package/dist/config/i18n/en/labels.json.js +12 -0
  18. package/dist/config/i18n/en/toasters.json.js +56 -0
  19. package/dist/config/i18n/en/tooltips.json.js +82 -0
  20. package/dist/config/i18n/index.js +7 -0
  21. package/dist/config/migrator/itemsBlockMigrator.js +136 -131
  22. package/dist/config/migrator/recommendationMigrator.js +58 -54
  23. package/dist/enums/block.js +4 -0
  24. package/dist/extensions/Blocks/Items/block.js +30 -21
  25. package/dist/extensions/Blocks/Items/iconsRegistry.js +7 -6
  26. package/dist/extensions/Blocks/Items/items.css.js +48 -0
  27. package/dist/extensions/Blocks/Recommendation/block.js +22 -13
  28. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +39 -58
  29. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +5 -4
  30. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +48 -0
  31. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +57 -93
  32. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
  33. package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
  34. package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
  35. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
  36. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
  37. package/dist/extensions/Blocks/common-control.js +12 -4
  38. package/dist/guido.css +1 -1
  39. package/dist/src/@types/extensions/block.d.ts +2 -0
  40. package/dist/src/components/Guido.vue.d.ts +1 -1
  41. package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +0 -1
  42. package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +1 -15
  43. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  44. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  45. package/dist/src/components/organisms/header/MigrationConfirmModal.vue.d.ts +6 -0
  46. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  47. package/dist/src/components/wrappers/WpModal.vue.d.ts +2 -2
  48. package/dist/src/config/i18n/en/index.d.ts +1 -0
  49. package/dist/src/config/i18n/index.d.ts +16 -0
  50. package/dist/src/enums/block.d.ts +4 -0
  51. package/dist/src/extensions/Blocks/Items/block.d.ts +3 -1
  52. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +3 -1
  53. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -5
  54. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -18
  55. package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
  56. package/dist/src/extensions/Blocks/common-control.d.ts +5 -0
  57. package/dist/src/stores/template.d.ts +29 -0
  58. package/dist/src/utils/migrationBannerHtml.d.ts +2 -0
  59. package/dist/static/assets/info.svg.js +5 -0
  60. package/dist/static/styles/components/notification.css.js +18 -0
  61. package/dist/static/styles/components/tools.css.js +6 -2
  62. package/dist/static/styles/variables.css.js +2 -0
  63. package/dist/stores/template.js +15 -0
  64. package/dist/stores/unsubscribe.js +37 -34
  65. package/dist/utils/migrationBannerHtml.js +21 -0
  66. package/package.json +1 -1
  67. package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +0 -29
  68. package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +0 -15
@@ -1,18 +1,20 @@
1
- import { useOnboardingStore as d } from "../../../stores/onboarding.js";
2
- import { Block as g, BlockCompositionType as f, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
3
- import { SETTINGS_ENUMS as c, DefaultConfigValues as i } from "./enums/settingsEnums.js";
4
- import { getDefaultTemplate as p } from "./template.js";
5
- import { getItemsBlockContainer as u, getItemsBlockConfig as C, getDefaultItemsBlockConfig as I } from "./utils/nodeConfigUtils.js";
6
- const y = "items-block";
7
- class B extends g {
1
+ import { BlockId as g } from "../../../enums/block.js";
2
+ import { useOnboardingStore as p } from "../../../stores/onboarding.js";
3
+ import { getMigrationBannerHtml as f } from "../../../utils/migrationBannerHtml.js";
4
+ import { Block as u, BlockCompositionType as I, ModificationDescription as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
+ import { SETTINGS_ENUMS as a, DefaultConfigValues as i } from "./enums/settingsEnums.js";
6
+ import { getDefaultTemplate as C } from "./template.js";
7
+ import { getItemsBlockContainer as y, getItemsBlockConfig as b, getDefaultItemsBlockConfig as h } from "./utils/nodeConfigUtils.js";
8
+ const c = g.Items;
9
+ class E extends u {
8
10
  getId() {
9
- return y;
11
+ return c;
10
12
  }
11
13
  getIcon() {
12
14
  return "items-icon";
13
15
  }
14
16
  getBlockCompositionType() {
15
- return f.CONTAINER;
17
+ return I.CONTAINER;
16
18
  }
17
19
  getName() {
18
20
  return this.api.translate("Items");
@@ -20,10 +22,17 @@ class B extends g {
20
22
  getDescription() {
21
23
  return this.api.translate("Items lets you display personalized products based on user behavior.");
22
24
  }
25
+ getSettingsPanelTitleHtml() {
26
+ return f(
27
+ c,
28
+ this.api.translate("Items"),
29
+ this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
30
+ );
31
+ }
23
32
  getTemplate() {
24
- return p({
25
- orientation: c.ORIENTATION.VERTICAL,
26
- itemsType: c.ITEMS_TYPE.CART_ITEMS,
33
+ return C({
34
+ orientation: a.ORIENTATION.VERTICAL,
35
+ itemsType: a.ITEMS_TYPE.CART_ITEMS,
27
36
  itemId: "{{Abandoned Cart Item (1) Url}}",
28
37
  currencySymbol: i.productPriceCurrencySymbolControlValue,
29
38
  currencyLocation: i.productPriceCurrencyLocationControlValue,
@@ -34,21 +43,21 @@ class B extends g {
34
43
  return !1;
35
44
  }
36
45
  onCreated(n) {
37
- const s = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
38
- r.querySelector('[product-attr="imageSrc"] img') || s.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
39
- const e = u(n);
46
+ const l = this.api.getDocumentModifier(), r = this.api.getDocumentRootCssNode();
47
+ r.querySelector('[product-attr="imageSrc"] img') || l.modifyCss(r).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
48
+ const e = y(n);
40
49
  if (!e)
41
50
  return;
42
- const a = e.getNodeConfig(), l = a && Object.keys(a).length > 0, t = C(n);
51
+ const s = e.getNodeConfig(), m = s && Object.keys(s).length > 0, t = b(n);
43
52
  if (t != null && t.initialized)
44
- l ? t.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...t, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(t).apply(new o("Migrate legacy config to nodeConfig"));
53
+ m ? t.blockInstanceId || this.api.getDocumentModifier().modifyHtml(e).setNodeConfig({ ...t, blockInstanceId: String(Date.now()) }).apply(new o("Assign block instance ID to block")) : this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(t).apply(new o("Migrate legacy config to nodeConfig"));
45
54
  else {
46
- const m = I();
47
- this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(m).apply(new o("Initialize Items block with default configuration")), d().startOnboarding("itemsOnboarding");
55
+ const d = h();
56
+ this.api.getDocumentModifier().modifyHtml(e).setNodeConfig(d).apply(new o("Initialize Items block with default configuration")), p().startOnboarding("itemsOnboarding");
48
57
  }
49
58
  }
50
59
  }
51
60
  export {
52
- y as BLOCK_ID,
53
- B as ItemsBlock
61
+ c as BLOCK_ID,
62
+ E as ItemsBlock
54
63
  };
@@ -1,5 +1,6 @@
1
- import { IconsRegistry as o } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- class i extends o {
1
+ import o from "../../../static/assets/info.svg.js";
2
+ import { IconsRegistry as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
3
+ class s extends r {
3
4
  registerIconsSvg(t) {
4
5
  t["items-icon"] = `
5
6
  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -19,14 +20,14 @@ class i extends o {
19
20
  </svg>
20
21
  `, t["horizontal-orientation"] = `
21
22
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
22
- <path d="M10 19H4C3.44772 19 3 18.5523 3 18V2C3 1.44772 3.44772 1 4 1H10V19Z" stroke="currentColor"
23
+ <path d="M10 19H4C3.44772 19 3 18.5523 3 18V2C3 1.44772 3.44772 1 4 1H10V19Z" stroke="currentColor"
23
24
  stroke-width="2" fill="none"/>
24
- <path d="M17 2V18C17 18.5523 16.5523 19 16 19H10V1H16C16.5523 1 17 1.44772 17 2Z" stroke="currentColor"
25
+ <path d="M17 2V18C17 18.5523 16.5523 19 16 19H10V1H16C16.5523 1 17 1.44772 17 2Z" stroke="currentColor"
25
26
  stroke-width="2" fill="none"/>
26
27
  </svg>
27
- `;
28
+ `, t["migration-info-icon"] = o;
28
29
  }
29
30
  }
30
31
  export {
31
- i as ItemsIconsRegistry
32
+ s as ItemsIconsRegistry
32
33
  };
@@ -17,6 +17,54 @@ const n = `/* Utils */
17
17
  .container:has(.items-controls-container) {
18
18
  padding: 0
19
19
  }
20
+
21
+ /* ─── Migration Info Box ─────────────────────────────────────────────── */
22
+ /* Shown in the settings panel title when a block was migrated from legacy */
23
+
24
+ /* Layout variables for positioning the absolutely-placed info box */
25
+ :host {
26
+ --items-migration-padding: 16px;
27
+ --items-migration-title-height: 61px;
28
+ --items-migration-box-height: 98px;
29
+ }
30
+
31
+ /* Push tabs down when info box is present inside the control panel header */
32
+ .control-panel-header:has(.items-block-migration-info) {
33
+ position: relative;
34
+ margin-bottom: calc(2 * var(--items-migration-padding) + var(--items-migration-box-height));
35
+ }
36
+
37
+ /* Info box container */
38
+ .items-block-migration-info {
39
+ display: flex;
40
+ align-items: flex-start;
41
+ gap: 8px;
42
+ padding: 12px;
43
+ background: var(--guido-color-background-onpage-message-info);
44
+ border: 1px solid var(--guido-color-border-onpage-message-info);
45
+ border-radius: 4px;
46
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
47
+ position: absolute;
48
+ left: var(--items-migration-padding);
49
+ right: var(--items-migration-padding);
50
+ top: calc(var(--items-migration-padding) + var(--items-migration-title-height));
51
+ }
52
+
53
+ /* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
54
+ .items-block-migration-info__icon {
55
+ flex-shrink: 0;
56
+ width: 24px;
57
+ height: 24px;
58
+ }
59
+
60
+ /* Text content */
61
+ .items-block-migration-info__text {
62
+ margin: 4px 0;
63
+ white-space: normal;
64
+ font-size: 13px;
65
+ font-weight: 400;
66
+ line-height: 16px;
67
+ }
20
68
  `;
21
69
  export {
22
70
  n as default
@@ -1,13 +1,15 @@
1
- var p = Object.defineProperty;
2
- var f = (r, o, t) => o in r ? p(r, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[o] = t;
3
- var g = (r, o, t) => f(r, typeof o != "symbol" ? o + "" : o, t);
4
- import { Block as h, BlockCompositionType as I, ModificationDescription as _ } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ var f = Object.defineProperty;
2
+ var h = (r, o, t) => o in r ? f(r, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[o] = t;
3
+ var g = (r, o, t) => h(r, typeof o != "symbol" ? o + "" : o, t);
4
+ import { BlockId as I } from "../../../enums/block.js";
5
+ import { getMigrationBannerHtml as k } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as B, BlockCompositionType as _, ModificationDescription as R } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
7
  import { ensureMobileCssRulesExist as d } from "./controls/mobileLayout/cssRules.js";
6
8
  import { RecommendationConfigService as s } from "./services/configService.js";
7
9
  import { useRecommendationExtensionStore as u } from "./store/recommendation.js";
8
- import { getDefaultTemplate as k } from "./templates/grid/template.js";
9
- const B = "recommendation-block", c = "ins-recommendation-v3-block-v2", a = "recommendation-id";
10
- class y extends h {
10
+ import { getDefaultTemplate as A } from "./templates/grid/template.js";
11
+ const p = I.Recommendation, c = "ins-recommendation-v3-block-v2", a = "recommendation-id";
12
+ class T extends B {
11
13
  constructor() {
12
14
  super();
13
15
  /**
@@ -17,13 +19,13 @@ class y extends h {
17
19
  g(this, "_pendingBlockId", null);
18
20
  }
19
21
  getId() {
20
- return B;
22
+ return p;
21
23
  }
22
24
  getIcon() {
23
25
  return "recommendation-icon";
24
26
  }
25
27
  getBlockCompositionType() {
26
- return I.CONTAINER;
28
+ return _.CONTAINER;
27
29
  }
28
30
  getName() {
29
31
  return this.api.translate("Recommendation Block");
@@ -31,6 +33,13 @@ class y extends h {
31
33
  getDescription() {
32
34
  return this.api.translate("Recommendation Block Title Description");
33
35
  }
36
+ getSettingsPanelTitleHtml() {
37
+ return k(
38
+ p,
39
+ this.api.translate("Recommendation Block"),
40
+ this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
41
+ );
42
+ }
34
43
  /**
35
44
  * Returns the template HTML for a new recommendation block.
36
45
  * Generates a unique recommendation ID and embeds the instance class
@@ -40,7 +49,7 @@ class y extends h {
40
49
  */
41
50
  getTemplate() {
42
51
  const t = this._generateNextId();
43
- return this._pendingBlockId = t, k(t);
52
+ return this._pendingBlockId = t, A(t);
44
53
  }
45
54
  /**
46
55
  * Called when a new block is dropped into the template
@@ -115,7 +124,7 @@ class y extends h {
115
124
  if (!n)
116
125
  return;
117
126
  const i = this.api.getDocumentModifier();
118
- i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new _(`Assign recommendation ID ${e}`));
127
+ i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new R(`Assign recommendation ID ${e}`));
119
128
  }
120
129
  /**
121
130
  * Gets the recommendation-id from a block node
@@ -149,6 +158,6 @@ class y extends h {
149
158
  }
150
159
  }
151
160
  export {
152
- B as BLOCK_ID,
153
- y as RecommendationBlock
161
+ p as BLOCK_ID,
162
+ T as RecommendationBlock
154
163
  };
@@ -1,8 +1,8 @@
1
- var m = Object.defineProperty;
2
- var h = (c, s, t) => s in c ? m(c, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[s] = t;
3
- var n = (c, s, t) => h(c, typeof s != "symbol" ? s + "" : s, t);
4
- import { CommonControl as f } from "../../../common-control.js";
5
- import { RecommendationConfigService as l } from "../../services/configService.js";
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
6
  import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
7
7
  import { AlgorithmControl as p } from "./algorithm.js";
8
8
  import { ALGORITHM_CONTROL_ID as W } from "./algorithm.js";
@@ -10,17 +10,17 @@ import { CurrencyControl as g } from "./currency.js";
10
10
  import { CURRENCY_CONTROL_ID as H } from "./currency.js";
11
11
  import { FiltersControl as R } from "./filters.js";
12
12
  import { FILTERS_CONTROL_ID as j } from "./filters.js";
13
- import { LocaleControl as N } from "./locale.js";
13
+ import { LocaleControl as y } from "./locale.js";
14
14
  import { LOCALE_CONTROL_ID as K } from "./locale.js";
15
- import { ProductLayoutControl as y } from "./productLayout.js";
15
+ import { ProductLayoutControl as _ } from "./productLayout.js";
16
16
  import { PRODUCT_LAYOUT_CONTROL_ID as J } from "./productLayout.js";
17
- import { ShuffleControl as _ } from "./shuffle.js";
17
+ import { ShuffleControl as N } from "./shuffle.js";
18
18
  import { SHUFFLE_CONTROL_ID as X } from "./shuffle.js";
19
- import { regenerateProductRowsWithStyles as b, getBlockElement as I, updateProductContentInPlace as P } from "./utils.js";
20
- import { formatProductPrice as tt, getCardComposition as et, getCurrentLayout as ot, reapplySpacing as rt, regenerateMobileProductRows as it, regenerateProductRows as nt, setCurrencyAttributes as st, updatePricesInPlace as ct, updateSingleProductContent as at } from "./utils.js";
21
- import { useDebounceFn as u } from "../../../../../node_modules/@vueuse/shared/index.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
22
  const T = "recommendation-id", S = "ui-elements-recommendation-block";
23
- class z extends f {
23
+ class $ extends h {
24
24
  constructor() {
25
25
  super(...arguments);
26
26
  n(this, "store", C());
@@ -36,19 +36,19 @@ class z extends f {
36
36
  /**
37
37
  * Debounced product fetch to prevent rapid API calls during config changes
38
38
  */
39
- n(this, "_debouncedFetchProducts", u(() => {
39
+ n(this, "_debouncedFetchProducts", l(() => {
40
40
  this.store.fetchRecommendationProducts();
41
41
  }, 500));
42
42
  /**
43
43
  * Debounced regeneration when products arrive from API
44
44
  * Tries in-place update first to preserve styles, falls back to full regeneration
45
45
  */
46
- n(this, "_debouncedRegenerateWithProducts", u(() => {
46
+ n(this, "_debouncedRegenerateWithProducts", l(() => {
47
47
  const t = this.store.recommendationProducts;
48
48
  if (!this.currentNode || !this.api)
49
49
  return;
50
50
  const e = this.api.getDocumentModifier();
51
- P({
51
+ I({
52
52
  currentNode: this.currentNode,
53
53
  documentModifier: e,
54
54
  products: t
@@ -59,7 +59,7 @@ class z extends f {
59
59
  return S;
60
60
  }
61
61
  getTemplate() {
62
- return this.algorithmControl = new p(), this.localeControl = new N(), this.currencyControl = new g(), this.productLayoutControl = new y(), this.filtersControl = new R(), this.shuffleControl = new _(), `
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(), `
63
63
  <div class="recommendation-controls-container">
64
64
  ${this.algorithmControl.getTemplate()}
65
65
  ${this.localeControl.getTemplate()}
@@ -95,19 +95,19 @@ class z extends f {
95
95
  });
96
96
  }
97
97
  onTemplateNodeUpdated(t) {
98
- var r;
98
+ var i;
99
99
  super.onTemplateNodeUpdated(t);
100
100
  const e = this._getRecommendationIdFromNode(t);
101
- 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), [
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), [
102
102
  this.algorithmControl,
103
103
  this.localeControl,
104
104
  this.currencyControl,
105
105
  this.productLayoutControl,
106
106
  this.filtersControl,
107
107
  this.shuffleControl
108
- ].forEach((i) => {
108
+ ].forEach((r) => {
109
109
  var a;
110
- i != null && i.api && (i.currentNode = t, (a = i.onTemplateNodeUpdated) == null || a.call(i, t));
110
+ r != null && r.api && (r.currentNode = t, (a = r.onTemplateNodeUpdated) == null || a.call(r, t));
111
111
  });
112
112
  }
113
113
  onDestroy() {
@@ -152,17 +152,13 @@ class z extends f {
152
152
  * values are being prepared for the upcoming initial fetch.
153
153
  */
154
154
  _syncNodeConfigToStore() {
155
- var r;
156
- const t = l.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
155
+ const t = f.getConfig(this.currentNode);
157
156
  this.store.patchCurrentBlockConfig({
158
157
  strategy: t.strategy,
159
158
  language: t.language,
160
159
  size: t.size,
161
160
  productIds: t.productIds,
162
- // Only sync filters from node config during initial load.
163
- // After initialization, the Pinia store is the source of truth
164
- // for filters (edited via the filter drawer).
165
- ...o ? {} : { filters: t.filters },
161
+ filters: t.filters,
166
162
  shuffleProducts: t.shuffleProducts,
167
163
  currencySettings: {
168
164
  name: t.currency.code,
@@ -185,26 +181,26 @@ class z extends f {
185
181
  this.store.fetchRecommendationFilters(),
186
182
  this.store.fetchRecommendationCreateData(),
187
183
  this.store.fetchRecommendationProducts()
188
- ])).forEach((o, r) => {
184
+ ])).forEach((o, i) => {
189
185
  o.status === "rejected" && console.warn(`Recommendation block: ${[
190
186
  "fetchRecommendationFilters",
191
187
  "fetchRecommendationCreateData",
192
188
  "fetchRecommendationProducts"
193
- ][r]} failed`, o.reason);
189
+ ][i]} failed`, o.reason);
194
190
  });
195
191
  }
196
192
  /**
197
193
  * Reads the recommendation-id attribute from the block element within the node
198
194
  */
199
195
  _getRecommendationIdFromNode(t) {
200
- const e = I(t);
196
+ const e = P(t);
201
197
  if (!e || !("getAttribute" in e))
202
198
  return null;
203
199
  const o = e.getAttribute(T);
204
200
  if (!o)
205
201
  return null;
206
- const r = parseInt(o);
207
- return Number.isNaN(r) ? null : r;
202
+ const i = parseInt(o);
203
+ return Number.isNaN(i) ? null : i;
208
204
  }
209
205
  /**
210
206
  * Listen to store changes that require product refresh or regeneration.
@@ -217,27 +213,12 @@ class z extends f {
217
213
  const { store: t } = this;
218
214
  let e = t.recommendationProducts, o = t.$state.configVersion;
219
215
  this.storeUnsubscription = t.$subscribe(() => {
220
- const r = t.$state.configVersion;
221
- r !== o && (o = r, this._persistFiltersToNodeConfig(), this._debouncedFetchProducts());
222
- const i = t.recommendationProducts, a = i !== e, d = Array.isArray(i) && i.length > 0;
223
- a && d && (e = i, this._debouncedRegenerateWithProducts());
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());
224
220
  });
225
221
  }
226
- /**
227
- * Persists the current filter state from Pinia store to the Stripo node config.
228
- * This ensures filters survive template save/reload cycles.
229
- */
230
- _persistFiltersToNodeConfig() {
231
- if (!this.currentNode || !this.api)
232
- return;
233
- const { filters: t } = this.store.recommendationConfigs;
234
- l.updateConfig(
235
- this.api,
236
- this.currentNode,
237
- { filters: t },
238
- "Update recommendation filters"
239
- );
240
- }
241
222
  }
242
223
  export {
243
224
  W as ALGORITHM_CONTROL_ID,
@@ -248,22 +229,22 @@ export {
248
229
  j as FILTERS_CONTROL_ID,
249
230
  R as FiltersControl,
250
231
  K as LOCALE_CONTROL_ID,
251
- N as LocaleControl,
232
+ y as LocaleControl,
252
233
  J as PRODUCT_LAYOUT_CONTROL_ID,
253
- y as ProductLayoutControl,
254
- z as RecommendationBlockControl,
234
+ _ as ProductLayoutControl,
235
+ $ as RecommendationBlockControl,
255
236
  X as SHUFFLE_CONTROL_ID,
256
- _ as ShuffleControl,
237
+ N as ShuffleControl,
257
238
  tt as formatProductPrice,
258
- I as getBlockElement,
239
+ P as getBlockElement,
259
240
  et as getCardComposition,
260
241
  ot as getCurrentLayout,
261
242
  rt as reapplySpacing,
262
- it as regenerateMobileProductRows,
263
- nt as regenerateProductRows,
243
+ nt as regenerateMobileProductRows,
244
+ it as regenerateProductRows,
264
245
  b as regenerateProductRowsWithStyles,
265
246
  st as setCurrencyAttributes,
266
247
  ct as updatePricesInPlace,
267
- P as updateProductContentInPlace,
248
+ I as updateProductContentInPlace,
268
249
  at as updateSingleProductContent
269
250
  };
@@ -1,5 +1,6 @@
1
- import { IconsRegistry as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- class o extends r {
1
+ import r from "../../../static/assets/info.svg.js";
2
+ import { IconsRegistry as t } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
3
+ class h extends t {
3
4
  registerIconsSvg(C) {
4
5
  C["recommendation-icon"] = `
5
6
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
@@ -59,9 +60,9 @@ class o extends r {
59
60
  <circle cx="3" cy="16" r="1" stroke="currentColor" stroke-width="1"/>
60
61
  <rect x="7" y="15" width="11" height="2" rx="1"/>
61
62
  </svg>
62
- `;
63
+ `, C["migration-info-icon"] = r;
63
64
  }
64
65
  }
65
66
  export {
66
- o as RecommendationIconsRegistry
67
+ h as RecommendationIconsRegistry
67
68
  };
@@ -22,6 +22,54 @@ const n = `/* Utils */
22
22
  ue-orderable.orderable-disabled .droppable-icon {
23
23
  display: none;
24
24
  }
25
+
26
+ /* ─── Migration Info Box ─────────────────────────────────────────────── */
27
+ /* Shown in the settings panel title when a block was migrated from legacy */
28
+
29
+ /* Layout variables for positioning the absolutely-placed info box */
30
+ :host {
31
+ --rec-migration-padding: 16px;
32
+ --rec-migration-title-height: 61px;
33
+ --rec-migration-box-height: 98px;
34
+ }
35
+
36
+ /* Push tabs down when info box is present inside the control panel header */
37
+ .control-panel-header:has(.recommendation-block-migration-info) {
38
+ position: relative;
39
+ margin-bottom: calc(2 * var(--rec-migration-padding) + var(--rec-migration-box-height));
40
+ }
41
+
42
+ /* Info box container */
43
+ .recommendation-block-migration-info {
44
+ display: flex;
45
+ align-items: flex-start;
46
+ gap: 8px;
47
+ padding: 12px;
48
+ background: var(--guido-color-background-onpage-message-info);
49
+ border: 1px solid var(--guido-color-border-onpage-message-info);
50
+ border-radius: 4px;
51
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
52
+ position: absolute;
53
+ left: var(--rec-migration-padding);
54
+ right: var(--rec-migration-padding);
55
+ top: calc(var(--rec-migration-padding) + var(--rec-migration-title-height));
56
+ }
57
+
58
+ /* Icon — 18x19 icon inside a 24x24 bounding box (matches Figma) */
59
+ .recommendation-block-migration-info__icon {
60
+ flex-shrink: 0;
61
+ width: 24px;
62
+ height: 24px;
63
+ }
64
+
65
+ /* Text content */
66
+ .recommendation-block-migration-info__text {
67
+ margin: 4px 0;
68
+ white-space: normal;
69
+ font-size: 13px;
70
+ font-weight: 400;
71
+ line-height: 16px;
72
+ }
25
73
  `;
26
74
  export {
27
75
  n as default