@useinsider/guido 3.17.0-beta.668ca65 → 3.17.0-beta.6b602e7

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 (73) hide show
  1. package/README.md +5 -5
  2. package/dist/components/Guido.vue.js +7 -7
  3. package/dist/components/Guido.vue2.js +65 -61
  4. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +3 -3
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +78 -52
  6. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
  7. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
  8. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
  9. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
  10. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +36 -35
  11. package/dist/composables/useCustomInterfaceAppearance.js +46 -42
  12. package/dist/composables/useLegacyStrategyConversion.js +52 -0
  13. package/dist/composables/useStripo.js +14 -14
  14. package/dist/config/i18n/en/labels.json.js +1 -1
  15. package/dist/config/migrator/index.js +9 -8
  16. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  17. package/dist/config/migrator/recommendation/extractors.js +29 -24
  18. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  19. package/dist/config/migrator/recommendationMigrator.js +30 -25
  20. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  21. package/dist/enums/extensions/recommendationBlock.js +2 -1
  22. package/dist/extensions/Blocks/Recommendation/block.js +12 -11
  23. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  24. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  25. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +24 -22
  26. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
  27. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +329 -257
  28. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +211 -145
  29. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +66 -31
  30. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  31. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  32. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  33. package/dist/extensions/Blocks/Recommendation/services/configService.js +34 -16
  34. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  35. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +93 -42
  36. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  37. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  38. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  39. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +58 -0
  40. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
  41. package/dist/guido.css +1 -1
  42. package/dist/services/recommendationApi.js +61 -52
  43. package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
  44. package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
  45. package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
  46. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  47. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
  48. package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -0
  49. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  50. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  51. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  52. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  53. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
  54. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
  55. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  56. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +38 -8
  57. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +1 -0
  58. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  59. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  60. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
  61. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +80 -1
  62. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  63. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
  64. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +39 -0
  65. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
  66. package/dist/src/services/recommendationApi.d.ts +2 -1
  67. package/dist/src/utils/genericUtil.d.ts +5 -0
  68. package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
  69. package/dist/static/assets/icons/line-info.svg.js +5 -0
  70. package/dist/static/styles/components/recommendation-strategy.css.js +70 -5
  71. package/dist/static/styles/customEditorStyle.css.js +3 -1
  72. package/dist/utils/genericUtil.js +28 -27
  73. package/package.json +2 -2
@@ -0,0 +1,44 @@
1
+ import { createPaddingsControl as r, createTextBackgroundColorControl as T, createTextFontFamilyControl as e, createTextStyleControl as l, createTextSizeControl as C, createTextColorControl as c, createTextAlignControl as I } from "../../../controlFactories.js";
2
+ import { RecommendationBlockId as o } from "../../constants/blockIds.js";
3
+ import { RecommendationControlId as t } from "../../constants/controlIds.js";
4
+ import { BLOCK_ROOT_SELECTOR as n } from "../../constants/selectors.js";
5
+ const L = I(
6
+ t.TITLE_ALIGN,
7
+ o.TITLE,
8
+ n
9
+ ), a = c(
10
+ t.TITLE_COLOR,
11
+ o.TITLE,
12
+ n
13
+ ), i = C(
14
+ t.TITLE_SIZE,
15
+ o.TITLE,
16
+ n
17
+ ), E = l(
18
+ t.TITLE_STYLE,
19
+ o.TITLE,
20
+ n
21
+ ), m = e(
22
+ t.TITLE_FONT_FAMILY,
23
+ o.TITLE,
24
+ n
25
+ ), s = T(
26
+ t.TITLE_BACKGROUND,
27
+ o.TITLE,
28
+ n
29
+ ), d = r(
30
+ t.TITLE_PADDINGS,
31
+ o.TITLE,
32
+ n
33
+ ), x = {
34
+ align: L,
35
+ color: a,
36
+ size: i,
37
+ style: E,
38
+ fontFamily: m,
39
+ background: s,
40
+ paddings: d
41
+ };
42
+ export {
43
+ x as TitleControls
44
+ };
@@ -5,23 +5,24 @@ import { RecommendationBlockControl as i } from "./controls/main/index.js";
5
5
  import "./constants/selectors.js";
6
6
  import "./store/recommendation.js";
7
7
  import "./utils/captureStyleTemplates.js";
8
- import { NameControls as e } from "./controls/name/index.js";
9
- import { PriceControls as l } from "./controls/price/index.js";
10
- import { OldPriceControls as s } from "./controls/oldPrice/index.js";
11
- import { OmnibusPriceControls as p } from "./controls/omnibusPrice/index.js";
12
- import { OmnibusDiscountControls as a } from "./controls/omnibusDiscount/index.js";
13
- import { ButtonControls as c } from "./controls/button/index.js";
14
- import { ImageControls as C } from "./controls/image/index.js";
15
- import { CustomAttributeControls as f } from "./controls/customAttribute/index.js";
16
- import { SpacingControl as d } from "./controls/spacing/index.js";
17
- import { BlockBackgroundColorControl as u } from "./controls/blockBackground/index.js";
18
- import { CardBackgroundColorControl as g } from "./controls/cardBackground/index.js";
19
- import { RecommendationCardCompositionControl as y } from "./controls/cardComposition/index.js";
20
- import { SyncInfoMessageControl as B } from "./controls/syncInfoMessage.js";
21
- import { RecommendationIconsRegistry as P } from "./iconsRegistry.js";
22
- import R from "./recommendation.css.js";
23
- import { SettingsPanel as S } from "./settingsPanel.js";
24
- const k = [
8
+ import { TitleControls as e } from "./controls/title/index.js";
9
+ import { NameControls as l } from "./controls/name/index.js";
10
+ import { PriceControls as s } from "./controls/price/index.js";
11
+ import { OldPriceControls as p } from "./controls/oldPrice/index.js";
12
+ import { OmnibusPriceControls as a } from "./controls/omnibusPrice/index.js";
13
+ import { OmnibusDiscountControls as c } from "./controls/omnibusDiscount/index.js";
14
+ import { ButtonControls as C } from "./controls/button/index.js";
15
+ import { ImageControls as f } from "./controls/image/index.js";
16
+ import { CustomAttributeControls as d } from "./controls/customAttribute/index.js";
17
+ import { SpacingControl as u } from "./controls/spacing/index.js";
18
+ import { BlockBackgroundColorControl as g } from "./controls/blockBackground/index.js";
19
+ import { CardBackgroundColorControl as y } from "./controls/cardBackground/index.js";
20
+ import { RecommendationCardCompositionControl as B } from "./controls/cardComposition/index.js";
21
+ import { SyncInfoMessageControl as P } from "./controls/syncInfoMessage.js";
22
+ import { RecommendationIconsRegistry as R } from "./iconsRegistry.js";
23
+ import S from "./recommendation.css.js";
24
+ import { SettingsPanel as k } from "./settingsPanel.js";
25
+ const w = [
25
26
  e,
26
27
  l,
27
28
  s,
@@ -29,21 +30,22 @@ const k = [
29
30
  a,
30
31
  c,
31
32
  C,
32
- f
33
- ], w = [
33
+ f,
34
+ d
35
+ ], b = [
34
36
  i,
35
- u,
36
37
  g,
37
- d,
38
38
  y,
39
- B
40
- ], b = [
41
- ...w,
42
- ...k.flatMap((o) => Object.values(o))
43
- ], W = b.reduce(
39
+ u,
40
+ B,
41
+ P
42
+ ], v = [
43
+ ...b,
44
+ ...w.flatMap((o) => Object.values(o))
45
+ ], Y = v.reduce(
44
46
  (o, r) => o.addControl(r),
45
- new t().addBlock(m).withSettingsPanelRegistry(S)
46
- ).addStyles(R).withPreviewStyles(n).withIconsRegistry(P).build();
47
+ new t().addBlock(m).withSettingsPanelRegistry(k)
48
+ ).addStyles(S).withPreviewStyles(n).withIconsRegistry(R).build();
47
49
  export {
48
- W as default
50
+ Y as default
49
51
  };
@@ -2,13 +2,13 @@ import { ModificationDescription as h } from "../../../../node_modules/@stripoin
2
2
  import { PRE_RRS_CONFIG_VERSION as C, DEFAULT_NODE_CONFIG as c } from "../constants/defaultConfig.js";
3
3
  import { setCurrencyAttributes as D } from "../controls/main/utils.js";
4
4
  import { hasMinimalConfig as S } from "../types/nodeConfig.js";
5
- function A(n) {
6
- return n === "." || n === "," || n === " ";
5
+ function A(r) {
6
+ return r === "." || r === "," || r === " ";
7
7
  }
8
- function N(n) {
9
- return n === "." || n === "," || n === " " || n === "";
8
+ function N(r) {
9
+ return r === "." || r === "," || r === " " || r === "";
10
10
  }
11
- class F {
11
+ class M {
12
12
  // ========================================================================
13
13
  // Read Operations
14
14
  // ========================================================================
@@ -83,9 +83,27 @@ class F {
83
83
  * @returns The new complete configuration
84
84
  */
85
85
  static updateConfig(i, t, o, e) {
86
- const r = this.getConfig(t), u = this.deepMerge(r, o);
86
+ const n = this.getConfig(t), u = this.deepMerge(n, o);
87
87
  return this.saveConfig(i, t, u, e), u;
88
88
  }
89
+ /**
90
+ * Accumulate a config update into an existing modifier batch, WITHOUT applying.
91
+ *
92
+ * The caller owns the apply(), so the write shares one undo entry with the rest
93
+ * of that batch — a change whose visible result only lands after an async product
94
+ * fetch would otherwise cost the user two undo presses (SD-149105).
95
+ * @param documentModifier - The batch to accumulate into (caller applies)
96
+ * @param node - The immutable HTML node to write to
97
+ * @param updates - Partial config with values to update
98
+ */
99
+ static stageConfig(i, t, o) {
100
+ const e = this.deepMerge(this.getConfig(t), o);
101
+ try {
102
+ i.modifyHtml(t).setNodeConfig(e);
103
+ } catch (n) {
104
+ console.warn("[RecommendationConfigService] Failed to stage config:", n);
105
+ }
106
+ }
89
107
  /**
90
108
  * Initialize configuration for a new block
91
109
  *
@@ -126,8 +144,8 @@ class F {
126
144
  static saveConfig(i, t, o, e) {
127
145
  try {
128
146
  i.getDocumentModifier().modifyHtml(t).setNodeConfig(o).apply(new h(e));
129
- } catch (r) {
130
- console.warn("[RecommendationConfigService] Failed to save config:", r);
147
+ } catch (n) {
148
+ console.warn("[RecommendationConfigService] Failed to save config:", n);
131
149
  }
132
150
  }
133
151
  // ========================================================================
@@ -164,20 +182,20 @@ class F {
164
182
  s && typeof s == "object" && Object.assign(o, s);
165
183
  } catch {
166
184
  }
167
- const r = t.getAttribute("data-layout");
168
- r === "list" || r === "horizontal" ? o.layout = "list" : (r === "grid" || r === "vertical") && (o.layout = "grid");
185
+ const n = t.getAttribute("data-layout");
186
+ n === "list" || n === "horizontal" ? o.layout = "list" : (n === "grid" || n === "vertical") && (o.layout = "grid");
169
187
  const u = t.getAttribute("data-card-composition");
170
188
  u && (o.composition = u.split(",").filter(Boolean));
171
189
  const l = t.getAttribute("data-column-spacing");
172
190
  l && (o.columnSpacing = parseInt(l) || c.columnSpacing);
173
- const b = t.getAttribute("data-row-spacing");
174
- if (b && (o.rowSpacing = parseInt(b) || c.rowSpacing), !o.currency) {
175
- const s = t.getAttribute("currency"), p = t.getAttribute("currency-symbol"), y = t.getAttribute("currency-alignment"), f = t.getAttribute("currency-thousand-separator"), g = t.getAttribute("currency-decimal-separator"), m = t.getAttribute("currency-decimal-count");
176
- if (s || p || y || f || g || m) {
191
+ const p = t.getAttribute("data-row-spacing");
192
+ if (p && (o.rowSpacing = parseInt(p) || c.rowSpacing), !o.currency) {
193
+ const s = t.getAttribute("currency"), b = t.getAttribute("currency-symbol"), y = t.getAttribute("currency-alignment"), f = t.getAttribute("currency-thousand-separator"), g = t.getAttribute("currency-decimal-separator"), m = t.getAttribute("currency-decimal-count");
194
+ if (s || b || y || f || g || m) {
177
195
  const a = c.currency, d = m ? parseInt(m) : NaN;
178
196
  o.currency = {
179
197
  code: s ?? a.code,
180
- symbol: p ?? a.symbol,
198
+ symbol: b ?? a.symbol,
181
199
  alignment: y === "0" ? "before" : "after",
182
200
  decimalCount: Number.isFinite(d) ? d : a.decimalCount,
183
201
  decimalSeparator: A(g) ? g : a.decimalSeparator,
@@ -279,5 +297,5 @@ class F {
279
297
  }
280
298
  }
281
299
  export {
282
- F as RecommendationConfigService
300
+ M as RecommendationConfigService
283
301
  };
@@ -3,9 +3,10 @@ import { BLOCK_ID as R } from "./block.js";
3
3
  import { RecommendationBlockId as S } from "./constants/blockIds.js";
4
4
  import { RecommendationControlId as T } from "./constants/controlIds.js";
5
5
  import "./constants/selectors.js";
6
- import { CONTROL_BLOCK_ID as U } from "./controls/main/index.js";
6
+ import { CONTROL_BLOCK_ID as L } from "./controls/main/index.js";
7
7
  import "./store/recommendation.js";
8
8
  import "./utils/captureStyleTemplates.js";
9
+ import "./controls/title/index.js";
9
10
  import "./controls/name/index.js";
10
11
  import "./controls/price/index.js";
11
12
  import "./controls/oldPrice/index.js";
@@ -15,7 +16,7 @@ import "./controls/button/index.js";
15
16
  import "./controls/image/index.js";
16
17
  import { SPACING_CONTROL_ID as A } from "./controls/spacing/index.js";
17
18
  import "./controls/blockBackground/index.js";
18
- import { CARD_BACKGROUND_COLOR_CONTROL_ID as L } from "./controls/cardBackground/index.js";
19
+ import { CARD_BACKGROUND_COLOR_CONTROL_ID as U } from "./controls/cardBackground/index.js";
19
20
  import { COMPOSITION_CONTROL_BLOCK_ID as D } from "./controls/cardComposition/index.js";
20
21
  import { SYNC_INFO_MESSAGE_CONTROL_ID as N } from "./controls/syncInfoMessage.js";
21
22
  class s extends E {
@@ -24,7 +25,7 @@ class s extends E {
24
25
  new _(
25
26
  I.SETTINGS,
26
27
  [
27
- U,
28
+ L,
28
29
  C.EXTERNAL_INDENTS
29
30
  ]
30
31
  ),
@@ -32,7 +33,7 @@ class s extends E {
32
33
  I.STYLES,
33
34
  [
34
35
  T.BLOCK_BACKGROUND,
35
- L,
36
+ U,
36
37
  A
37
38
  ]
38
39
  ),
@@ -42,6 +43,24 @@ class s extends E {
42
43
  D
43
44
  ]
44
45
  ).withLabel(this.api.translate("Card Composition"))
46
+ ], O[S.TITLE] = [
47
+ new _(
48
+ I.SETTINGS,
49
+ [
50
+ T.TITLE_STYLE,
51
+ T.TITLE_ALIGN,
52
+ T.TITLE_PADDINGS
53
+ ]
54
+ ),
55
+ new _(
56
+ I.STYLES,
57
+ [
58
+ T.TITLE_BACKGROUND,
59
+ T.TITLE_FONT_FAMILY,
60
+ T.TITLE_SIZE,
61
+ T.TITLE_COLOR
62
+ ]
63
+ )
45
64
  ], O[S.NAME] = [
46
65
  new _(
47
66
  I.SETTINGS,
@@ -1,22 +1,23 @@
1
- import { getRecommendationFeedSourceMaps as I, getOperatorOptions as G, PriceAttributes as D } from "../../../../enums/extensions/recommendationBlock.js";
1
+ import { getRecommendationFeedSourceMaps as b, getOperatorOptions as D, PriceAttributes as F } from "../../../../enums/extensions/recommendationBlock.js";
2
2
  import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as F } from "../../../../stores/config.js";
4
- import { defineStore as v } from "pinia";
3
+ import { useConfigStore as R } from "../../../../stores/config.js";
4
+ import { defineStore as L } from "pinia";
5
5
  import "../constants/selectors.js";
6
- import { DEFAULT_MOBILE_CARDS_IN_ROW as _, DEFAULT_CARDS_IN_ROW as U } from "../constants/layout.js";
7
- import { DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as L } from "../constants/defaultConfig.js";
6
+ import { DEFAULT_MOBILE_CARDS_IN_ROW as U, DEFAULT_CARDS_IN_ROW as _ } from "../constants/layout.js";
7
+ import { DEFAULT_NODE_CONFIG as N, CURRENT_CONFIG_VERSION as w, EXCLUDED_ALGORITHM_IDS as M } from "../constants/defaultConfig.js";
8
8
  import { getDefaultProducts as k } from "../templates/utils.js";
9
- import { generateCompleteFilterQuery as R } from "../utils/filterUtil.js";
10
- import { getPartnerRecommendationParams as x } from "../utils/partnerCustomizations.js";
11
- import { sanitizeProductIds as A } from "../utils/productIds.js";
12
- import { isFilterValid as B } from "../validation/filterSchema.js";
13
- import { isConfigValid as z } from "../validation/requiredFields.js";
14
- const m = P();
9
+ import { generateCompleteFilterQuery as C } from "../utils/filterUtil.js";
10
+ import { isLegacyStrategyConfig as x } from "../utils/legacyStrategyMigration.js";
11
+ import { getPartnerRecommendationParams as B } from "../utils/partnerCustomizations.js";
12
+ import { sanitizeProductIds as z } from "../utils/productIds.js";
13
+ import { isFilterValid as A } from "../validation/filterSchema.js";
14
+ import { isConfigValid as O } from "../validation/requiredFields.js";
15
+ const u = P();
15
16
  let f = null, g = null, h = null, S = null;
16
17
  const p = /* @__PURE__ */ new Map();
17
- function w() {
18
+ function G() {
18
19
  return {
19
- cardsInRow: U,
20
+ cardsInRow: _,
20
21
  currencySettings: {
21
22
  name: "USD",
22
23
  value: "USD",
@@ -30,7 +31,7 @@ function w() {
30
31
  productIds: [],
31
32
  id: 1,
32
33
  language: "en_US",
33
- mobileCardsInRow: _,
34
+ mobileCardsInRow: U,
34
35
  mobileLayoutEnabled: !1,
35
36
  orientation: "grid",
36
37
  recommendedProducts: [],
@@ -38,6 +39,7 @@ function w() {
38
39
  shuffleProducts: !1,
39
40
  strategy: "mostPopular",
40
41
  strategyId: "",
42
+ nodeConfigVersion: w,
41
43
  textTrimming: !0,
42
44
  unresponsive: !1,
43
45
  size: "6",
@@ -46,19 +48,22 @@ function w() {
46
48
  priceHideIfSameAsDiscounted: !1
47
49
  };
48
50
  }
49
- function C() {
51
+ function v() {
50
52
  return {
51
- recommendationConfigs: w(),
53
+ recommendationConfigs: G(),
52
54
  recommendationProducts: [],
53
55
  filterStatus: !1,
54
56
  filterSelectionDrawerStatus: !1,
55
57
  assignStrategyDrawerStatus: !1,
58
+ removeStrategyModalStatus: !1,
59
+ legacyStrategyUpdatedModalStatus: !1,
56
60
  filterGroup: 1,
57
61
  isInitialized: !1,
58
- filterSnapshot: null
62
+ filterSnapshot: null,
63
+ legacyConversionLoading: !1
59
64
  };
60
65
  }
61
- const O = () => ({
66
+ const E = () => ({
62
67
  recommendationCampaignUrls: {},
63
68
  activePredictiveAlgorithms: [],
64
69
  languages: {},
@@ -70,8 +75,8 @@ const O = () => ({
70
75
  blockStates: {},
71
76
  currentRecommendationId: null,
72
77
  configVersion: 0
73
- }), Y = v("guidoRecommendationExtension", {
74
- state: () => O(),
78
+ }), et = L("guidoRecommendationExtension", {
79
+ state: () => E(),
75
80
  getters: {
76
81
  // ====================================================================
77
82
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -81,7 +86,7 @@ const O = () => ({
81
86
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
82
87
  */
83
88
  recommendationConfigs(t) {
84
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : w();
89
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : G();
85
90
  },
86
91
  /**
87
92
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -98,6 +103,18 @@ const O = () => ({
98
103
  assignStrategyDrawerStatus(t) {
99
104
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].assignStrategyDrawerStatus : !1;
100
105
  },
106
+ removeStrategyModalStatus(t) {
107
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
108
+ },
109
+ isLegacyStrategyBlock() {
110
+ return R().isFeatureEnabled("reusableRecommendationStrategy") && x(this.recommendationConfigs);
111
+ },
112
+ legacyConversionLoading(t) {
113
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyConversionLoading : !1;
114
+ },
115
+ legacyStrategyUpdatedModalStatus(t) {
116
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyStrategyUpdatedModalStatus : !1;
117
+ },
101
118
  assignedStrategy(t) {
102
119
  const { strategyId: e } = this.recommendationConfigs;
103
120
  return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
@@ -133,8 +150,8 @@ const O = () => ({
133
150
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
134
151
  },
135
152
  getActivePredictiveAlgorithms: (t) => {
136
- const e = I(), r = [];
137
- return t.activePredictiveAlgorithms.filter((n) => !L.includes(n)).forEach((n) => {
153
+ const e = b(), r = [];
154
+ return t.activePredictiveAlgorithms.filter((n) => !M.includes(n)).forEach((n) => {
138
155
  r.push(...e.filter((s) => s.id === n));
139
156
  }), r.map((n) => ({
140
157
  text: n.name,
@@ -152,7 +169,7 @@ const O = () => ({
152
169
  getFilterList() {
153
170
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
154
171
  let e;
155
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : D.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
172
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : F.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
156
173
  text: t.displayName,
157
174
  value: e,
158
175
  type: t.attributeType
@@ -174,7 +191,7 @@ const O = () => ({
174
191
  setCurrentBlock(t) {
175
192
  this.blockStates[t] || (this.blockStates = {
176
193
  ...this.blockStates,
177
- [t]: C()
194
+ [t]: v()
178
195
  }), this.currentRecommendationId = t;
179
196
  },
180
197
  /**
@@ -242,7 +259,7 @@ const O = () => ({
242
259
  decimalCount: String(e.currencyDecimalCount),
243
260
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
244
261
  thousandSeparator: r(e.currencyThousandSeparator, ".")
245
- }, s = !this.blockStates[t], i = s ? C() : this.blockStates[t];
262
+ }, s = !this.blockStates[t], i = s ? v() : this.blockStates[t];
246
263
  i.recommendationConfigs = {
247
264
  ...i.recommendationConfigs,
248
265
  strategy: e.strategy,
@@ -281,7 +298,7 @@ const O = () => ({
281
298
  * Creates a filter with the first available attribute and operator pre-selected.
282
299
  */
283
300
  createDefaultFilter(t, e) {
284
- const [r] = this.getFilterList, [n] = G(r == null ? void 0 : r.type);
301
+ const [r] = this.getFilterList, [n] = D(r == null ? void 0 : r.type);
285
302
  return {
286
303
  type: "standardFilter",
287
304
  attribute: (r == null ? void 0 : r.value) ?? "",
@@ -334,6 +351,18 @@ const O = () => ({
334
351
  closeAssignStrategyDrawer() {
335
352
  this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].assignStrategyDrawerStatus = !1);
336
353
  },
354
+ openLegacyStrategyUpdatedModal() {
355
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].legacyStrategyUpdatedModalStatus = !0);
356
+ },
357
+ closeLegacyStrategyUpdatedModal() {
358
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].legacyStrategyUpdatedModalStatus = !1);
359
+ },
360
+ openRemoveStrategyModal() {
361
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !0);
362
+ },
363
+ closeRemoveStrategyModal() {
364
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].removeStrategyModalStatus = !1);
365
+ },
337
366
  async fetchStrategies() {
338
367
  if (S) {
339
368
  await S;
@@ -342,7 +371,7 @@ const O = () => ({
342
371
  S = (async () => {
343
372
  this.strategiesLoading = !0;
344
373
  try {
345
- this.strategies = await m.fetchRecommendationStrategies();
374
+ this.strategies = await u.fetchRecommendationStrategies();
346
375
  } finally {
347
376
  this.strategiesLoading = !1;
348
377
  }
@@ -357,7 +386,7 @@ const O = () => ({
357
386
  const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
358
387
  if (s)
359
388
  return s;
360
- const { full_path: i = "" } = await m.generateStrategyEndpoint(t, e) ?? {};
389
+ const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
361
390
  return n && i && (this.strategyUrlTemplates = {
362
391
  ...this.strategyUrlTemplates,
363
392
  [n]: i
@@ -369,6 +398,28 @@ const O = () => ({
369
398
  ...t.size !== void 0 ? { size: String(t.size) } : {}
370
399
  });
371
400
  },
401
+ async convertLegacyStrategy(t) {
402
+ const e = this.currentRecommendationId;
403
+ if (e === null || !this.blockStates[e])
404
+ throw new Error("[Guido] convertLegacyStrategy called without an active block");
405
+ this.blockStates[e].legacyConversionLoading = !0;
406
+ try {
407
+ const r = await u.migrateLegacyStrategy(t);
408
+ try {
409
+ await this.fetchStrategies();
410
+ } catch (s) {
411
+ console.error("[Guido] strategy listing refresh after conversion failed", s);
412
+ }
413
+ const n = this.strategies.find((s) => String(s.strategy_id) === r);
414
+ return this.patchCurrentBlockConfig({
415
+ strategyId: r,
416
+ nodeConfigVersion: w,
417
+ ...(n == null ? void 0 : n.size) !== void 0 ? { size: String(n.size) } : {}
418
+ }), r;
419
+ } finally {
420
+ this.blockStates[e].legacyConversionLoading = !1;
421
+ }
422
+ },
372
423
  removeStrategy() {
373
424
  this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
374
425
  },
@@ -386,7 +437,7 @@ const O = () => ({
386
437
  activePredictiveAlgorithms: t,
387
438
  languages: e,
388
439
  currencies: r
389
- } = await m.fetchRecommendationCreateData();
440
+ } = await u.fetchRecommendationCreateData();
390
441
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
391
442
  const n = this.blockStates[this.currentRecommendationId];
392
443
  n.filterStatus = !!n.recommendationConfigs.filters.length;
@@ -407,7 +458,7 @@ const O = () => ({
407
458
  return;
408
459
  }
409
460
  g = (async () => {
410
- const t = await m.fetchRecommendationFilters();
461
+ const t = await u.fetchRecommendationFilters();
411
462
  this.filterList = t;
412
463
  })();
413
464
  try {
@@ -442,7 +493,7 @@ const O = () => ({
442
493
  const n = [...e.recommendationConfigs.filters];
443
494
  n[r] = {
444
495
  ...t,
445
- isValid: B(t)
496
+ isValid: A(t)
446
497
  }, e.recommendationConfigs.filters = n;
447
498
  }
448
499
  },
@@ -480,7 +531,7 @@ const O = () => ({
480
531
  }), e.recommendationConfigs.filters = r;
481
532
  },
482
533
  generateFilterQuery() {
483
- return R(this.recommendationConfigs.filters);
534
+ return C(this.recommendationConfigs.filters);
484
535
  },
485
536
  /**
486
537
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -488,7 +539,7 @@ const O = () => ({
488
539
  * every block's recommendationConfigs across user edits.
489
540
  */
490
541
  hasInvalidBlock() {
491
- return Object.values(this.blockStates).some((t) => !z(t.recommendationConfigs, this));
542
+ return Object.values(this.blockStates).some((t) => !O(t.recommendationConfigs, this));
492
543
  },
493
544
  // ====================================================================
494
545
  // Per-Block Product Fetching
@@ -509,12 +560,12 @@ const O = () => ({
509
560
  },
510
561
  async _doFetchProducts() {
511
562
  var d;
512
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = F();
563
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = R();
513
564
  if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
514
565
  await this._doFetchStrategyProducts(t);
515
566
  return;
516
567
  }
517
- const s = r.filters.filter((u) => u.isValid), i = R(s), o = ((d = I().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
568
+ const s = r.filters.filter((m) => m.isValid), i = C(s), o = ((d = b().find((m) => m.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
518
569
  locale: r.language,
519
570
  currency: r.currencySettings.value,
520
571
  partnerName: n.partnerName,
@@ -522,13 +573,13 @@ const O = () => ({
522
573
  details: !0,
523
574
  campaignId: n.variationId
524
575
  };
525
- r.strategy === "manualMerchandising" ? a.productId = A(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
576
+ r.strategy === "manualMerchandising" ? a.productId = z(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), i && (a.filter = i), r.shuffleProducts && (a.shuffle = !0), Object.assign(
526
577
  a,
527
- x(n.partnerName, r.strategy)
578
+ B(n.partnerName, r.strategy)
528
579
  );
529
580
  let l;
530
581
  try {
531
- l = await m.fetchRecommendationProducts(o, a);
582
+ l = await u.fetchRecommendationProducts(o, a);
532
583
  } catch {
533
584
  l = [];
534
585
  }
@@ -546,8 +597,8 @@ const O = () => ({
546
597
  );
547
598
  if (i) {
548
599
  s = parseInt(String(i.size ?? "")) || s;
549
- const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((b) => b && !b.startsWith("user_id=")), y = u.length ? `${d}?${u.join("&")}` : d;
550
- y && (n = await m.fetchRecommendationProductsByUrl(y));
600
+ const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), m = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = m.length ? `${d}?${m.join("&")}` : d;
601
+ y && (n = await u.fetchRecommendationProductsByUrl(y));
551
602
  }
552
603
  } catch {
553
604
  n = [];
@@ -566,5 +617,5 @@ const O = () => ({
566
617
  }
567
618
  });
568
619
  export {
569
- Y as useRecommendationExtensionStore
620
+ et as useRecommendationExtensionStore
570
621
  };
@@ -1,6 +1,6 @@
1
1
  import { ATTR_PRODUCT_PRICE as f, ATTR_PRODUCT_OLD_PRICE as O } from "../../constants/selectors.js";
2
2
  import { DEFAULT_PRODUCTS_PER_ROW as w } from "../../constants/layout.js";
3
- import { getDefaultProducts as A, DEFAULTS as g, createBlockTemplate as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
3
+ import { createBlockTemplate as A, getDefaultProducts as g, DEFAULTS as U, buildSpacer as h, DEFAULT_CARD_COMPOSITION as Y, buildElementRenderer as B, resolveInlinePriceOrder as F, buildCellOptions as I, DEFAULT_CARD_VISIBILITY as W } from "../utils.js";
4
4
  import { DEFAULT_CELL_PADDING as k, renderInlineGridPriceCell as H, buildFillerCell as x, gridElementRenderer as y } from "./elementRenderer.js";
5
5
  const G = `
6
6
  <tr class="recommendation-product-row">
@@ -69,8 +69,8 @@ function M(t, r, o, e = {}, c = {}) {
69
69
  );
70
70
  }
71
71
  function Q(t) {
72
- const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = U("grid", r), e = A(), c = M(e, w);
73
- return o.replace("{-{-TITLE-}-}", g.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
72
+ const r = t ? `ins-recommendation-v3-block-${t}` : void 0, o = A("grid", r), e = g(), c = M(e, w);
73
+ return o.replace("{-{-TITLE-}-}", U.TITLE).replace("{-{-PRODUCT_ROWS-}-}", c).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
74
74
  }
75
75
  export {
76
76
  Q as getDefaultTemplate,
@@ -0,0 +1,33 @@
1
+ import { RecommendationBlockId as r } from "../constants/blockIds.js";
2
+ import { DEFAULT_ROW_SPACING as l } from "../constants/layout.js";
3
+ import { CSS_CLASS_ATTRIBUTE_ROW as d, ATTR_RECOMMENDATION_TITLE as n, ATTR_DATA_VISIBILITY as A, CSS_CLASS_TITLE_CELL as _, CSS_CLASS_SPACER as c } from "../constants/selectors.js";
4
+ const a = "You May Also Like!", i = '<p style="font-size: 28px; color: #333333;"><strong>{-{-TITLE-}-}</strong></p>';
5
+ function E(s = i, t = !0, T = l) {
6
+ const e = `class="${d}" data-attribute-type="${n}" ${A}="${t ? "1" : "0"}"`, o = t ? "" : ' style="display: none;"';
7
+ return `
8
+ <tr ${e}${o}>
9
+ <td>
10
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
11
+ <tbody>
12
+ <tr>
13
+ <td
14
+ class="esd-block-text ${_} es-p10t es-p10b es-p20l es-p20r"
15
+ align="center"
16
+ esd-extension-block-id="${r.TITLE}">
17
+ ${s}
18
+ </td>
19
+ </tr>
20
+ </tbody>
21
+ </table>
22
+ </td>
23
+ </tr>
24
+ <tr ${e}${o}>
25
+ <td class="${c}" style="height: ${T}px;"></td>
26
+ </tr>
27
+ `;
28
+ }
29
+ export {
30
+ i as DEFAULT_TITLE_PARAGRAPH,
31
+ a as DEFAULT_TITLE_TEXT,
32
+ E as buildTitleRows
33
+ };