@useinsider/guido 2.1.0-beta.e13d291 → 2.1.0-beta.e2153c2

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 (138) hide show
  1. package/README.md +36 -0
  2. package/dist/@types/config/schemas.js +70 -65
  3. package/dist/components/Guido.vue.js +1 -1
  4. package/dist/components/Guido.vue2.js +69 -58
  5. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +15 -14
  6. package/dist/components/organisms/header/HeaderWrapper.vue.js +9 -9
  7. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
  8. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
  9. package/dist/composables/useActionsApi.js +15 -13
  10. package/dist/composables/useBlocksConfig.js +26 -16
  11. package/dist/composables/useHtmlValidator.js +114 -104
  12. package/dist/composables/useRecommendation.js +54 -21
  13. package/dist/composables/useStripo.js +25 -23
  14. package/dist/composables/useVersionHistoryApi.js +1 -1
  15. package/dist/config/compiler/recommendationCompilerRules.js +45 -39
  16. package/dist/config/compiler/utils/recommendationCompilerUtils.js +121 -0
  17. package/dist/config/i18n/en/index.js +11 -0
  18. package/dist/config/i18n/en/labels.json.js +7 -0
  19. package/dist/config/i18n/en/toasters.json.js +56 -0
  20. package/dist/config/i18n/en/tooltips.json.js +82 -0
  21. package/dist/config/i18n/index.js +7 -0
  22. package/dist/config/migrator/itemsBlockMigrator.js +142 -120
  23. package/dist/enums/defaults.js +8 -4
  24. package/dist/enums/extensions/recommendationBlock.js +1 -1
  25. package/dist/enums/recommendation.js +16 -15
  26. package/dist/extensions/Blocks/Items/block.js +19 -28
  27. package/dist/extensions/Blocks/Items/controls/button/link.js +19 -31
  28. package/dist/extensions/Blocks/Items/controls/cardComposition.js +124 -85
  29. package/dist/extensions/Blocks/Items/controls/image/link.js +19 -31
  30. package/dist/extensions/Blocks/Items/controls/name/trimming.js +28 -40
  31. package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +35 -47
  32. package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +49 -54
  33. package/dist/extensions/Blocks/Items/controls/price/formattedPrice.js +42 -51
  34. package/dist/extensions/Blocks/Items/controls/price/hideDiscount.js +23 -36
  35. package/dist/extensions/Blocks/Items/controls/price/priceOrientation.js +45 -57
  36. package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +42 -60
  37. package/dist/extensions/Blocks/Items/controls/settingsControl.js +189 -196
  38. package/dist/extensions/Blocks/Items/enums/settingsEnums.js +0 -2
  39. package/dist/extensions/Blocks/Items/extension.js +8 -9
  40. package/dist/extensions/Blocks/Items/settingsPanel.js +10 -15
  41. package/dist/extensions/Blocks/Items/template.js +181 -175
  42. package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +65 -65
  43. package/dist/extensions/Blocks/Recommendation/block.js +117 -27
  44. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +33 -31
  45. package/dist/extensions/Blocks/Recommendation/constants/layout.js +6 -4
  46. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +12 -10
  47. package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +10 -14
  48. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +19 -27
  49. package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +49 -44
  50. package/dist/extensions/Blocks/Recommendation/controls/main/filters.js +1 -3
  51. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +147 -102
  52. package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +1 -5
  53. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +85 -43
  54. package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +9 -13
  55. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +138 -117
  56. package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +21 -0
  57. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +66 -34
  58. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +2 -2
  59. package/dist/extensions/Blocks/Recommendation/services/configService.js +2 -1
  60. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +248 -206
  61. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +26 -31
  62. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +1 -1
  63. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +31 -34
  64. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +20 -25
  65. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +22 -22
  66. package/dist/extensions/Blocks/Recommendation/templates/utils.js +52 -39
  67. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +10 -10
  68. package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
  69. package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
  70. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
  71. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
  72. package/dist/extensions/Blocks/common-control.js +91 -92
  73. package/dist/extensions/ModulesTabIcons/extension.js +17 -0
  74. package/dist/guido.css +1 -1
  75. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +257 -187
  76. package/dist/package.json.js +1 -1
  77. package/dist/services/recommendationApi.js +11 -9
  78. package/dist/services/stripoApi.js +20 -17
  79. package/dist/services/templateLibraryApi.js +16 -13
  80. package/dist/src/@types/config/schemas.d.ts +8 -0
  81. package/dist/src/composables/useConfig.d.ts +4 -0
  82. package/dist/src/composables/useRecommendation.d.ts +1 -0
  83. package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +17 -0
  84. package/dist/src/config/i18n/en/index.d.ts +1 -0
  85. package/dist/src/config/i18n/index.d.ts +16 -0
  86. package/dist/src/enums/defaults.d.ts +4 -0
  87. package/dist/src/extensions/Blocks/Items/block.d.ts +0 -1
  88. package/dist/src/extensions/Blocks/Items/controls/button/link.d.ts +0 -1
  89. package/dist/src/extensions/Blocks/Items/controls/cardComposition.d.ts +5 -5
  90. package/dist/src/extensions/Blocks/Items/controls/image/link.d.ts +0 -1
  91. package/dist/src/extensions/Blocks/Items/controls/name/trimming.d.ts +0 -1
  92. package/dist/src/extensions/Blocks/Items/controls/price/currencyLocation.d.ts +0 -1
  93. package/dist/src/extensions/Blocks/Items/controls/price/currencySymbol.d.ts +0 -1
  94. package/dist/src/extensions/Blocks/Items/controls/price/formattedPrice.d.ts +0 -1
  95. package/dist/src/extensions/Blocks/Items/controls/price/hideDiscount.d.ts +0 -1
  96. package/dist/src/extensions/Blocks/Items/controls/price/priceOrientation.d.ts +0 -1
  97. package/dist/src/extensions/Blocks/Items/controls/price/singlePrice.d.ts +0 -5
  98. package/dist/src/extensions/Blocks/Items/controls/settingsControl.d.ts +10 -12
  99. package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +2 -1
  100. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +44 -11
  101. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
  102. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -0
  103. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +4 -0
  104. package/dist/src/extensions/Blocks/Recommendation/controls/main/currency.d.ts +8 -1
  105. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +27 -5
  106. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +22 -4
  107. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -2
  108. package/dist/src/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.d.ts +29 -0
  109. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +19 -1
  110. package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +2 -2
  111. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +138 -469
  112. package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +2 -2
  113. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  114. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +2 -0
  115. package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +2 -2
  116. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +2 -2
  117. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +16 -4
  118. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +14 -2
  119. package/dist/src/extensions/Blocks/Recommendation/utils/stylePreserver.d.ts +1 -1
  120. package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
  121. package/dist/src/extensions/Blocks/common-control.d.ts +4 -5
  122. package/dist/src/extensions/ModulesTabIcons/extension.d.ts +2 -0
  123. package/dist/src/stores/config.d.ts +36 -0
  124. package/dist/static/styles/components/notification.css.js +19 -0
  125. package/dist/static/styles/components/tools.css.js +6 -2
  126. package/dist/static/styles/components/version-history.css.js +10 -2
  127. package/dist/static/styles/components/wide-panel.css.js +18 -2
  128. package/dist/static/styles/customEditorStyle.css.js +10 -9
  129. package/dist/static/styles/variables.css.js +2 -0
  130. package/dist/static/templates/empty/index.html.js +74 -0
  131. package/dist/static/templates/empty/style.css.js +779 -0
  132. package/dist/stores/unsubscribe.js +37 -34
  133. package/dist/utils/pairProductVariables.js +57 -56
  134. package/dist/utils/templatePreparation.js +15 -14
  135. package/package.json +2 -2
  136. package/dist/extensions/Blocks/Items/store/items-block.js +0 -79
  137. package/dist/src/extensions/Blocks/Items/store/items-block.d.ts +0 -45
  138. package/dist/src/extensions/Blocks/Recommendation/controls/nameTextTrimControl.d.ts +0 -16
@@ -1,46 +1,46 @@
1
1
  import { ModificationDescription as b } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { DefaultConfigValues as i, SETTINGS_ENUMS as n, ItemInCartOptions as g } from "../enums/settingsEnums.js";
3
- function d() {
2
+ import { DefaultConfigValues as o, SETTINGS_ENUMS as n, ItemInCartOptions as g } from "../enums/settingsEnums.js";
3
+ function _() {
4
4
  return String(Date.now() + Math.floor(Math.random() * 1e3));
5
5
  }
6
- const E = (o) => o.replace(/\$/g, "$$$$");
6
+ const E = (r) => r.replace(/\$/g, "$$$$");
7
7
  function S() {
8
8
  return {
9
9
  initialized: !0,
10
- blockInstanceId: d(),
10
+ blockInstanceId: _(),
11
11
  source: n.ITEMS_TYPE.CART_ITEMS,
12
12
  type: n.ITEMS_TYPE.CART_ITEMS,
13
- itemsSelectValue: i.cartItemsSelectControlValue,
13
+ itemsSelectValue: o.cartItemsSelectControlValue,
14
14
  orientation: n.ORIENTATION.VERTICAL,
15
- nameTrimming: i.productNameTrimmingControlValue === "1",
16
- priceHideDiscount: i.productPriceHideDiscountControlValue === "1",
17
- priceFormatted: i.productPriceFormattedControlValue === "1",
15
+ nameTrimming: o.productNameTrimmingControlValue === "1",
16
+ priceHideDiscount: o.productPriceHideDiscountControlValue === "1",
17
+ priceFormatted: o.productPriceFormattedControlValue === "1",
18
18
  priceSinglePrice: !1,
19
- priceCurrencySymbol: i.productPriceCurrencySymbolControlValue,
20
- priceCurrencyLocation: i.productPriceCurrencyLocationControlValue,
19
+ priceCurrencySymbol: o.productPriceCurrencySymbolControlValue,
20
+ priceCurrencyLocation: o.productPriceCurrencyLocationControlValue,
21
21
  priceOrientation: "horizontal",
22
- quantityControlEnabled: i.productQuantityControlEnabled === "1",
23
- buttonLink: i.productButtonLinkControlValue,
24
- imageLink: i.productImageLinkControlValue,
22
+ quantityControlEnabled: o.productQuantityControlEnabled === "1",
23
+ buttonLink: o.productButtonLinkControlValue,
24
+ imageLink: o.productImageLinkControlValue,
25
25
  buttonLabel: "Buy",
26
26
  buttonFullWidth: !0,
27
27
  // Default to full width (es-fw class)
28
- imageVisible: i.productImageVisible === "1",
29
- nameVisible: i.productNameVisible === "1",
30
- quantityVisible: i.productQuantityVisible === "1",
31
- priceVisible: i.productPriceVisible === "1",
32
- originalPriceVisible: i.productOriginalPriceVisible === "1",
33
- buttonVisible: i.productButtonVisible === "1"
28
+ imageVisible: o.productImageVisible === "1",
29
+ nameVisible: o.productNameVisible === "1",
30
+ quantityVisible: o.productQuantityVisible === "1",
31
+ priceVisible: o.productPriceVisible === "1",
32
+ originalPriceVisible: o.productOriginalPriceVisible === "1",
33
+ buttonVisible: o.productButtonVisible === "1"
34
34
  };
35
35
  }
36
- function s(o) {
37
- if (!o)
36
+ function p(r) {
37
+ if (!r)
38
38
  return null;
39
- const t = o.closest(".items-block-v2");
40
- return t || o.closest(".esd-cart-items-block");
39
+ const t = r.closest(".items-block-v2");
40
+ return t || r.closest(".esd-cart-items-block");
41
41
  }
42
- function m(o) {
43
- return o ? {
42
+ function m(r) {
43
+ return r ? {
44
44
  CartItems: n.ITEMS_TYPE.CART_ITEMS,
45
45
  BrowsedItems: n.ITEMS_TYPE.BROWSED_ITEMS,
46
46
  PurchasedItems: n.ITEMS_TYPE.PURCHASED_ITEMS,
@@ -48,34 +48,34 @@ function m(o) {
48
48
  CART_ITEMS: n.ITEMS_TYPE.CART_ITEMS,
49
49
  BROWSED_ITEMS: n.ITEMS_TYPE.BROWSED_ITEMS,
50
50
  PURCHASED_ITEMS: n.ITEMS_TYPE.PURCHASED_ITEMS
51
- }[o] || n.ITEMS_TYPE.CART_ITEMS : n.ITEMS_TYPE.CART_ITEMS;
51
+ }[r] || n.ITEMS_TYPE.CART_ITEMS : n.ITEMS_TYPE.CART_ITEMS;
52
52
  }
53
- function I(o, t) {
54
- if (!o)
55
- return i.cartItemsSelectControlValue;
56
- if (o.includes("{{"))
57
- return o;
58
- if (/^\d+$/.test(o)) {
59
- const e = parseInt(o) - 1, r = g[t];
60
- if (r && r[e])
61
- return r[e].value;
53
+ function I(r, t) {
54
+ if (!r)
55
+ return o.cartItemsSelectControlValue;
56
+ if (r.includes("{{"))
57
+ return r;
58
+ if (/^\d+$/.test(r)) {
59
+ const e = parseInt(r) - 1, i = g[t];
60
+ if (i && i[e])
61
+ return i[e].value;
62
62
  }
63
- return i.cartItemsSelectControlValue;
63
+ return o.cartItemsSelectControlValue;
64
64
  }
65
- function C(o) {
66
- const t = o.querySelector("esd-config-block");
65
+ function C(r) {
66
+ const t = r.querySelector("esd-config-block");
67
67
  if (!t)
68
68
  return null;
69
- const e = (c, a) => c == null ? a : c === "1" || c === "true", r = (c, a) => c || a, l = t.getAttribute("data-type"), u = m(l), _ = t.getAttribute("data-cart_items_select_control_value"), p = I(_, u);
69
+ const e = (c, s) => c == null ? s : c === "1" || c === "true", i = (c, s) => c || s, u = t.getAttribute("data-type"), a = m(u), d = t.getAttribute("data-cart_items_select_control_value"), l = I(d, a);
70
70
  return {
71
71
  initialized: e(t.getAttribute("data-initialized"), !1),
72
- blockInstanceId: r(
72
+ blockInstanceId: i(
73
73
  t.getAttribute("data-block-instance-id"),
74
- d()
74
+ _()
75
75
  ),
76
- source: u,
77
- type: u,
78
- itemsSelectValue: p,
76
+ source: a,
77
+ type: a,
78
+ itemsSelectValue: l,
79
79
  orientation: t.getAttribute("data-card_orientation_control_value") || n.ORIENTATION.VERTICAL,
80
80
  nameTrimming: e(
81
81
  t.getAttribute("data-product_name_control_trim"),
@@ -93,28 +93,28 @@ function C(o) {
93
93
  t.getAttribute("data-product_price_control_single_price"),
94
94
  !1
95
95
  ),
96
- priceCurrencySymbol: r(
97
- t.getAttribute("data-product_price_currency_symbol"),
98
- i.productPriceCurrencySymbolControlValue
96
+ priceCurrencySymbol: i(
97
+ t.getAttribute("data-product_price_control_currency_symbol"),
98
+ o.productPriceCurrencySymbolControlValue
99
99
  ),
100
- priceCurrencyLocation: r(
100
+ priceCurrencyLocation: i(
101
101
  t.getAttribute("data-product_price_currency_location"),
102
- i.productPriceCurrencyLocationControlValue
102
+ o.productPriceCurrencyLocationControlValue
103
103
  ),
104
104
  priceOrientation: t.getAttribute("data-product_original_price_control_orientation") || "horizontal",
105
105
  quantityControlEnabled: e(
106
106
  t.getAttribute("data-product_quantity_control_enabled"),
107
107
  !0
108
108
  ),
109
- buttonLink: r(
109
+ buttonLink: i(
110
110
  t.getAttribute("data-product_button_link"),
111
- i.productButtonLinkControlValue
111
+ o.productButtonLinkControlValue
112
112
  ),
113
- imageLink: r(
113
+ imageLink: i(
114
114
  t.getAttribute("data-product_image_link"),
115
- i.productImageLinkControlValue
115
+ o.productImageLinkControlValue
116
116
  ),
117
- buttonLabel: r(
117
+ buttonLabel: i(
118
118
  t.getAttribute("data-product_button_control_label"),
119
119
  "Buy"
120
120
  ),
@@ -149,28 +149,28 @@ function C(o) {
149
149
  )
150
150
  };
151
151
  }
152
- function y(o) {
153
- const t = s(o);
152
+ function y(r) {
153
+ const t = p(r);
154
154
  if (!t)
155
155
  return null;
156
156
  const e = t.getNodeConfig();
157
157
  if (e && e.initialized)
158
158
  return e;
159
- const r = C(t);
160
- return r || null;
159
+ const i = C(t);
160
+ return i || null;
161
161
  }
162
- function A(o, t, e) {
163
- const r = s(o);
164
- if (!r)
162
+ function A(r, t, e, i) {
163
+ const u = p(r);
164
+ if (!u)
165
165
  return;
166
- const u = { ...r.getNodeConfig() || {}, ...e };
167
- t.getDocumentModifier().modifyHtml(r).setNodeConfig(u).apply(new b("Update Items block configuration"));
166
+ const d = { ...u.getNodeConfig() || {}, ...e }, l = i ?? t.getDocumentModifier();
167
+ l.modifyHtml(u).setNodeConfig(d), i || l.apply(new b("Update Items block configuration"));
168
168
  }
169
169
  export {
170
170
  E as escapeReplacement,
171
- d as generateBlockInstanceId,
171
+ _ as generateBlockInstanceId,
172
172
  S as getDefaultItemsBlockConfig,
173
173
  y as getItemsBlockConfig,
174
- s as getItemsBlockContainer,
174
+ p as getItemsBlockContainer,
175
175
  A as setItemsBlockConfig
176
176
  };
@@ -1,19 +1,29 @@
1
- import { Block as o, BlockCompositionType as i } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { RecommendationConfigService as t } from "./services/configService.js";
3
- import { getDefaultTemplate as r } from "./templates/grid/template.js";
4
- const n = "recommendation-block";
5
- class g extends o {
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";
5
+ import { ensureMobileCssRulesExist as d } from "./controls/mobileLayout/cssRules.js";
6
+ import { RecommendationConfigService as s } from "./services/configService.js";
7
+ 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 {
6
11
  constructor() {
7
12
  super();
13
+ /**
14
+ * Stores the ID generated in getTemplate() so onCreated() can reuse it.
15
+ * This avoids generating a new (different) ID in onCreated().
16
+ */
17
+ g(this, "_pendingBlockId", null);
8
18
  }
9
19
  getId() {
10
- return n;
20
+ return B;
11
21
  }
12
22
  getIcon() {
13
23
  return "recommendation-icon";
14
24
  }
15
25
  getBlockCompositionType() {
16
- return i.CONTAINER;
26
+ return I.CONTAINER;
17
27
  }
18
28
  getName() {
19
29
  return this.api.translate("Recommendation Block");
@@ -21,44 +31,124 @@ class g extends o {
21
31
  getDescription() {
22
32
  return this.api.translate("Recommendation Block Title Description");
23
33
  }
34
+ /**
35
+ * Returns the template HTML for a new recommendation block.
36
+ * Generates a unique recommendation ID and embeds the instance class
37
+ * (ins-recommendation-v3-block-{id}) directly in the template HTML.
38
+ * This is necessary because Stripo's Angular rendering manages the class
39
+ * attribute and overwrites dynamically added classes via setAttribute.
40
+ */
24
41
  getTemplate() {
25
- return r();
42
+ const t = this._generateNextId();
43
+ return this._pendingBlockId = t, k(t);
26
44
  }
27
45
  /**
28
46
  * Called when a new block is dropped into the template
29
47
  *
30
- * Initializes the block with default configuration stored via node config.
31
- * This ensures the configuration persists with the template.
48
+ * Uses the ID from getTemplate() (which already embedded the instance class)
49
+ * and assigns the recommendation-id attribute + initializes configuration.
32
50
  * @param node - The newly created block node
33
51
  */
34
- onCreated(e) {
35
- t.initializeConfig(this.api, e);
52
+ onCreated(t) {
53
+ const e = this._pendingBlockId ?? this._generateNextId();
54
+ this._pendingBlockId = null, this._assignRecommendationId(t, e);
55
+ const n = s.initializeConfig(this.api, t, { recommendationId: e }), i = u();
56
+ i.setCurrentBlock(e), d(this.api), i.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
36
57
  }
37
58
  /**
38
59
  * Called when the document changes or template is loaded
39
60
  *
40
- * Handles migration from legacy templates that don't have node config.
41
- * Also handles config version upgrades for future migrations.
61
+ * Handles migration from legacy templates that don't have node config
62
+ * and assigns recommendation-id to legacy blocks that lack one.
42
63
  * @param node - The block node that may need migration
43
64
  */
44
- onDocumentChanged(e) {
45
- !e || !("getNodeConfig" in e) || t.needsMigration(e) && this._migrateFromLegacy(e);
65
+ onDocumentChanged(t) {
66
+ if (!(!t || !("getNodeConfig" in t))) {
67
+ if (!this._getRecommendationId(t)) {
68
+ const e = this._generateNextId();
69
+ this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
70
+ this.api,
71
+ t,
72
+ { recommendationId: e },
73
+ "Assign recommendation ID to legacy block"
74
+ );
75
+ }
76
+ s.needsMigration(t) && this._migrateFromLegacy(t), d(this.api);
77
+ }
46
78
  }
47
79
  /**
48
- * Migrate configuration from legacy format
80
+ * Called when a block is deleted from the template
49
81
  *
50
- * Legacy templates may store configuration in:
51
- * - data-attributes (data-layout, data-card-composition, etc.)
52
- * - Pinia store (lost on reload - this is what we're fixing)
53
- *
54
- * This method reads what we can from the DOM and initializes proper node config.
55
- * @param node - The block node to migrate
82
+ * Cleans up the per-block state from the Pinia store.
83
+ * @param node - The block node being deleted
84
+ */
85
+ onDelete(t) {
86
+ const e = this._getRecommendationId(t);
87
+ e && u().removeBlockState(e);
88
+ }
89
+ /**
90
+ * Generates the next unique recommendation ID by scanning all existing blocks
91
+ * in the document and finding the maximum existing ID + 1.
92
+ */
93
+ _generateNextId() {
94
+ let t = 0;
95
+ try {
96
+ const e = this.api.getDocumentRoot();
97
+ e && "querySelectorAll" in e && e.querySelectorAll(`.${c}`).forEach((i) => {
98
+ if ("getAttribute" in i) {
99
+ const m = i.getAttribute(a), l = m ? parseInt(m) : 0;
100
+ l > t && (t = l);
101
+ }
102
+ });
103
+ } catch {
104
+ }
105
+ return t + 1;
106
+ }
107
+ /**
108
+ * Assigns a recommendation-id attribute to the block element.
109
+ * The instance class (ins-recommendation-v3-block-{id}) is embedded in the template
110
+ * HTML by getTemplate(), since Stripo's Angular rendering overwrites dynamically
111
+ * added classes via setAttribute.
112
+ */
113
+ _assignRecommendationId(t, e) {
114
+ const n = this._getBlockElement(t);
115
+ if (!n)
116
+ return;
117
+ const i = this.api.getDocumentModifier();
118
+ i.modifyHtml(n).setAttribute(a, e.toString()), i.apply(new _(`Assign recommendation ID ${e}`));
119
+ }
120
+ /**
121
+ * Gets the recommendation-id from a block node
122
+ */
123
+ _getRecommendationId(t) {
124
+ const e = this._getBlockElement(t);
125
+ if (!e || !("getAttribute" in e))
126
+ return null;
127
+ const n = e.getAttribute(a);
128
+ if (!n)
129
+ return null;
130
+ const i = parseInt(n);
131
+ return Number.isNaN(i) ? null : i;
132
+ }
133
+ /**
134
+ * Gets the block element (the element with BLOCK_CLASS)
135
+ */
136
+ _getBlockElement(t) {
137
+ if ("getAttribute" in t) {
138
+ const e = t.getAttribute("class");
139
+ if (e && e.includes(c))
140
+ return t;
141
+ }
142
+ return "querySelector" in t ? t.querySelector(`.${c}`) : null;
143
+ }
144
+ /**
145
+ * Migrate configuration from legacy format
56
146
  */
57
- _migrateFromLegacy(e) {
58
- t.migrateFromDataAttributes(this.api, e);
147
+ _migrateFromLegacy(t) {
148
+ s.migrateFromDataAttributes(this.api, t);
59
149
  }
60
150
  }
61
151
  export {
62
- n as BLOCK_ID,
63
- g as RecommendationBlock
152
+ B as BLOCK_ID,
153
+ y as RecommendationBlock
64
154
  };
@@ -1,64 +1,66 @@
1
- import { DEFAULT_ROW_SPACING as s, DEFAULT_COLUMN_SPACING as R, DEFAULT_CARDS_IN_ROW as n } from "./layout.js";
2
- import { ATTR_PRODUCT_IMAGE as t, ATTR_PRODUCT_NAME as T, ATTR_PRODUCT_OLD_PRICE as e, ATTR_PRODUCT_PRICE as o, ATTR_PRODUCT_OMNIBUS_PRICE as _, ATTR_PRODUCT_OMNIBUS_DISCOUNT as r, ATTR_PRODUCT_BUTTON as U } from "./selectors.js";
3
- const I = {
1
+ import { DEFAULT_ROW_SPACING as U, DEFAULT_COLUMN_SPACING as I, DEFAULT_MOBILE_CARDS_IN_ROW as n, DEFAULT_CARDS_IN_ROW as s } from "./layout.js";
2
+ import { ATTR_PRODUCT_IMAGE as t, ATTR_PRODUCT_NAME as e, ATTR_PRODUCT_OLD_PRICE as o, ATTR_PRODUCT_PRICE as _, ATTR_PRODUCT_OMNIBUS_PRICE as T, ATTR_PRODUCT_OMNIBUS_DISCOUNT as r, ATTR_PRODUCT_BUTTON as R } from "./selectors.js";
3
+ const O = {
4
4
  code: "USD",
5
5
  symbol: "USD",
6
6
  alignment: "after",
7
7
  decimalCount: 2,
8
8
  decimalSeparator: ".",
9
9
  thousandSeparator: ","
10
- }, O = {
10
+ }, i = {
11
11
  textBefore: "",
12
12
  textAfter: ""
13
- }, i = {
13
+ }, C = {
14
14
  textBefore: "",
15
15
  textAfter: ""
16
- }, C = [
16
+ }, D = [
17
17
  t,
18
- T,
19
18
  e,
20
19
  o,
21
20
  _,
21
+ T,
22
22
  r,
23
- U
24
- ], D = {
23
+ R
24
+ ], A = {
25
25
  [t]: !0,
26
- [T]: !0,
27
- [o]: !0,
28
26
  [e]: !0,
29
- [_]: !1,
27
+ [_]: !0,
28
+ [o]: !0,
29
+ [T]: !1,
30
30
  [r]: !1,
31
- [U]: !0
32
- }, a = {
31
+ [R]: !0
32
+ }, E = {
33
33
  // Settings
34
34
  strategy: "mostPopular",
35
35
  productIds: [],
36
36
  size: "6",
37
37
  shuffleProducts: !1,
38
38
  language: "en_US",
39
- currency: I,
39
+ currency: O,
40
40
  filters: [],
41
41
  // Layout
42
42
  layout: "grid",
43
- cardsInRow: n,
44
- columnSpacing: R,
45
- rowSpacing: s,
43
+ cardsInRow: s,
44
+ mobileCardsInRow: n,
45
+ columnSpacing: I,
46
+ rowSpacing: U,
46
47
  // Composition
47
- composition: C,
48
- visibility: D,
48
+ composition: D,
49
+ visibility: A,
49
50
  // Element settings
50
- omnibusPrice: O,
51
- omnibusDiscount: i,
51
+ omnibusPrice: i,
52
+ omnibusDiscount: C,
52
53
  textTrimming: !1,
53
54
  // Meta
54
- configVersion: 1
55
- }, E = 1;
55
+ configVersion: 1,
56
+ recommendationId: 0
57
+ }, N = 1;
56
58
  export {
57
- E as CURRENT_CONFIG_VERSION,
58
- C as DEFAULT_COMPOSITION,
59
- I as DEFAULT_CURRENCY,
60
- a as DEFAULT_NODE_CONFIG,
61
- i as DEFAULT_OMNIBUS_DISCOUNT,
62
- O as DEFAULT_OMNIBUS_PRICE,
63
- D as DEFAULT_VISIBILITY
59
+ N as CURRENT_CONFIG_VERSION,
60
+ D as DEFAULT_COMPOSITION,
61
+ O as DEFAULT_CURRENCY,
62
+ E as DEFAULT_NODE_CONFIG,
63
+ C as DEFAULT_OMNIBUS_DISCOUNT,
64
+ i as DEFAULT_OMNIBUS_PRICE,
65
+ A as DEFAULT_VISIBILITY
64
66
  };
@@ -4,17 +4,19 @@ const _ = {
4
4
  }, o = [
5
5
  { icon: "grid-orientation", value: _.GRID },
6
6
  { icon: "list-orientation", value: _.LIST }
7
- ], t = 3, n = 3, A = 9, T = 4, c = 10, s = 20, O = 0, S = 50, I = 5;
7
+ ], t = 3, n = 3, A = 9, O = 4, R = 1, T = 2, c = 10, s = 20, I = 0, S = 50, P = 5;
8
8
  export {
9
9
  n as DEFAULT_CARDS_IN_ROW,
10
10
  c as DEFAULT_COLUMN_SPACING,
11
+ R as DEFAULT_MOBILE_CARDS_IN_ROW,
11
12
  t as DEFAULT_PRODUCTS_PER_ROW,
12
13
  s as DEFAULT_ROW_SPACING,
13
14
  o as LAYOUT_OPTIONS,
14
15
  _ as LAYOUT_VALUES,
15
- T as MAX_PRODUCTS_PER_ROW,
16
+ T as MAX_MOBILE_PRODUCTS_PER_ROW,
17
+ O as MAX_PRODUCTS_PER_ROW,
16
18
  A as MAX_PRODUCT_COUNT,
17
19
  S as MAX_SPACING,
18
- O as MIN_SPACING,
19
- I as SPACING_STEP
20
+ I as MIN_SPACING,
21
+ P as SPACING_STEP
20
22
  };
@@ -1,19 +1,21 @@
1
- const c = ".ins-recommendation-product-container", T = {
1
+ const c = ".ins-recommendation-product-container", n = ".ins-recommendation-desktop-container", o = ".ins-recommendation-mobile-container", T = {
2
2
  CURRENCY: "currency",
3
3
  SYMBOL: "currency-symbol",
4
4
  ALIGNMENT: "currency-alignment",
5
5
  THOUSAND_SEPARATOR: "currency-thousand-separator",
6
6
  DECIMAL_SEPARATOR: "currency-decimal-separator",
7
7
  DECIMAL_COUNT: "currency-decimal-count"
8
- }, r = "productImage", n = "productName", o = "productPrice", t = "productOldPrice", R = "productOmnibusPrice", O = "productOmnibusDiscount", _ = "productButton";
8
+ }, t = "productImage", r = "productName", R = "productPrice", e = "productOldPrice", O = "productOmnibusPrice", _ = "productOmnibusDiscount", C = "productButton";
9
9
  export {
10
- _ as ATTR_PRODUCT_BUTTON,
11
- r as ATTR_PRODUCT_IMAGE,
12
- n as ATTR_PRODUCT_NAME,
13
- t as ATTR_PRODUCT_OLD_PRICE,
14
- O as ATTR_PRODUCT_OMNIBUS_DISCOUNT,
15
- R as ATTR_PRODUCT_OMNIBUS_PRICE,
16
- o as ATTR_PRODUCT_PRICE,
10
+ C as ATTR_PRODUCT_BUTTON,
11
+ t as ATTR_PRODUCT_IMAGE,
12
+ r as ATTR_PRODUCT_NAME,
13
+ e as ATTR_PRODUCT_OLD_PRICE,
14
+ _ as ATTR_PRODUCT_OMNIBUS_DISCOUNT,
15
+ O as ATTR_PRODUCT_OMNIBUS_PRICE,
16
+ R as ATTR_PRODUCT_PRICE,
17
17
  c as CONTAINER_SELECTOR,
18
- T as CURRENCY_ATTR
18
+ T as CURRENCY_ATTR,
19
+ n as DESKTOP_CONTAINER_SELECTOR,
20
+ o as MOBILE_CONTAINER_SELECTOR
19
21
  };
@@ -4,12 +4,12 @@ var n = (o, e, t) => d(o, typeof e != "symbol" ? e + "" : e, t);
4
4
  import { ModificationDescription as m } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
5
  import { CommonControl as h } from "../../../common-control.js";
6
6
  import { LAYOUT_OPTIONS as g } from "../../constants/layout.js";
7
- import { RecommendationConfigService as i } from "../../services/configService.js";
7
+ import { RecommendationConfigService as r } from "../../services/configService.js";
8
8
  import { useRecommendationExtensionStore as l } from "../../store/recommendation.js";
9
9
  import { getCurrentLayout as u, getBlockElement as f, regenerateProductRowsWithStyles as p } from "../main/utils.js";
10
- const L = "recommendation-layout-control", r = {
10
+ const L = "recommendation-layout-control", i = {
11
11
  LAYOUT: "layout"
12
- }, T = {
12
+ }, C = {
13
13
  LAYOUT: "data-layout"
14
14
  };
15
15
  class Y extends h {
@@ -27,7 +27,7 @@ class Y extends h {
27
27
  ${this._GuTwoColumns([
28
28
  this._GuLabel({ text: "Layout Orientation" }),
29
29
  this._GuRadioButton({
30
- name: r.LAYOUT,
30
+ name: i.LAYOUT,
31
31
  buttons: g
32
32
  })
33
33
  ])}
@@ -41,9 +41,9 @@ class Y extends h {
41
41
  super.onTemplateNodeUpdated(t), this._setFormValues();
42
42
  }
43
43
  _setFormValues() {
44
- const s = i.getConfig(this.currentNode).layout || u(this.currentNode);
44
+ const s = r.getConfig(this.currentNode).layout || u(this.currentNode);
45
45
  this.api.updateValues({
46
- [r.LAYOUT]: s
46
+ [i.LAYOUT]: s
47
47
  });
48
48
  }
49
49
  /**
@@ -51,22 +51,18 @@ class Y extends h {
51
51
  * Updates node config, data attribute and regenerates product rows
52
52
  */
53
53
  _onLayoutChange(t) {
54
- if (this.isChangingLayout || !this.currentNode || (i.getConfig(this.currentNode).layout || u(this.currentNode)) === t)
54
+ if (this.isChangingLayout || !this.currentNode || (r.getConfig(this.currentNode).layout || u(this.currentNode)) === t)
55
55
  return;
56
56
  const a = f(this.currentNode);
57
57
  if (a) {
58
58
  this.isChangingLayout = !0;
59
59
  try {
60
- i.updateConfig(
60
+ r.updateConfig(
61
61
  this.api,
62
62
  this.currentNode,
63
63
  { layout: t },
64
64
  `Changed layout to ${t}`
65
- ), this.store.$patch({
66
- recommendationConfigs: {
67
- orientation: t
68
- }
69
- }), this.api.getDocumentModifier().modifyHtml(a).setAttribute(T.LAYOUT, t).apply(new m(`Update layout to ${t}`)), this._regenerateProductRows(t);
65
+ ), this.store.patchCurrentBlockConfig({ orientation: t }), this.api.getDocumentModifier().modifyHtml(a).setAttribute(C.LAYOUT, t).apply(new m(`Update layout to ${t}`)), this._regenerateProductRows(t);
70
66
  } finally {
71
67
  this.isChangingLayout = !1;
72
68
  }
@@ -85,7 +81,7 @@ class Y extends h {
85
81
  });
86
82
  }
87
83
  _listenToFormUpdates() {
88
- this.api.onValueChanged(r.LAYOUT, (t) => {
84
+ this.api.onValueChanged(i.LAYOUT, (t) => {
89
85
  this._onLayoutChange(t);
90
86
  });
91
87
  }