@useinsider/guido 3.1.1 → 3.2.0-beta.080341b

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 (189) hide show
  1. package/README.md +117 -0
  2. package/dist/@types/config/schemas.js +166 -96
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +92 -80
  5. package/dist/components/organisms/AutoSaveController.vue.js +17 -0
  6. package/dist/components/organisms/AutoSaveController.vue2.js +13 -0
  7. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +7 -7
  8. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +12 -20
  9. package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
  10. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
  11. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  12. package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
  13. package/dist/components/organisms/header/RightSlot.vue.js +11 -11
  14. package/dist/components/organisms/header/RightSlot.vue2.js +17 -13
  15. package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
  16. package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
  17. package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
  18. package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
  19. package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
  20. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
  21. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
  22. package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
  23. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
  24. package/dist/composables/useActionsApi.js +4 -4
  25. package/dist/composables/useAutoSave.js +71 -0
  26. package/dist/composables/useFullStoryBridge.js +14 -0
  27. package/dist/composables/useHtmlCompiler.js +23 -21
  28. package/dist/composables/useHtmlValidator.js +40 -38
  29. package/dist/composables/usePreviewMode.js +20 -16
  30. package/dist/composables/useRecommendation.js +46 -26
  31. package/dist/composables/useRibbonOffset.js +21 -0
  32. package/dist/composables/useSave.js +26 -15
  33. package/dist/composables/useStripo.js +48 -45
  34. package/dist/composables/validators/useCouponBlockValidator.js +24 -0
  35. package/dist/composables/validators/useLiquidValidator.js +42 -0
  36. package/dist/config/compiler/liquidCompilerRules.js +15 -0
  37. package/dist/config/compiler/recommendationCompilerRules.js +162 -43
  38. package/dist/config/compiler/unsubscribeCompilerRules.js +48 -45
  39. package/dist/config/compiler/utils/recommendationCompilerUtils.js +110 -71
  40. package/dist/config/i18n/en/tooltips.json.js +2 -1
  41. package/dist/config/migrator/checkboxMigrator.js +5 -3
  42. package/dist/config/migrator/index.js +9 -9
  43. package/dist/config/migrator/radioButtonMigrator.js +66 -44
  44. package/dist/config/migrator/recommendation/compositionMapper.js +98 -0
  45. package/dist/config/migrator/recommendation/extractors.js +27 -0
  46. package/dist/config/migrator/recommendation/htmlBuilder.js +496 -0
  47. package/dist/config/migrator/recommendation/parseLegacyConfig.js +33 -0
  48. package/dist/config/migrator/recommendation/settingsMapper.js +70 -0
  49. package/dist/config/migrator/recommendation/themeMapper.js +93 -0
  50. package/dist/config/migrator/recommendationMigrator.js +74 -290
  51. package/dist/enums/extensions/recommendationBlock.js +16 -12
  52. package/dist/enums/onboarding.js +7 -2
  53. package/dist/enums/recommendation.js +2 -2
  54. package/dist/enums/unsubscribe.js +34 -27
  55. package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
  56. package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +38 -38
  57. package/dist/extensions/Blocks/Items/enums/productEnums.js +19 -7
  58. package/dist/extensions/Blocks/RadioButton/template.js +1 -1
  59. package/dist/extensions/Blocks/Recommendation/block.js +60 -50
  60. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  61. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +5 -5
  62. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +27 -11
  63. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +185 -172
  64. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
  65. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
  66. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +27 -26
  67. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
  68. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +211 -162
  69. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
  70. package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
  71. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +75 -73
  72. package/dist/extensions/Blocks/Recommendation/services/configService.js +76 -33
  73. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
  74. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +123 -79
  75. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +24 -13
  76. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -29
  77. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -7
  78. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +27 -15
  79. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
  80. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -50
  81. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
  82. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +21 -0
  83. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +13 -22
  84. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +6 -6
  85. package/dist/extensions/Blocks/Unsubscribe/block.js +11 -11
  86. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +16 -17
  87. package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
  88. package/dist/guido.css +1 -1
  89. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
  90. package/dist/node_modules/valibot/dist/index.js +450 -235
  91. package/dist/package.json.js +1 -1
  92. package/dist/services/recommendationApi.js +15 -15
  93. package/dist/services/stripoApi.js +9 -9
  94. package/dist/services/templateLibraryApi.js +49 -46
  95. package/dist/src/@types/config/defaults.d.ts +5 -1
  96. package/dist/src/@types/config/index.d.ts +3 -3
  97. package/dist/src/@types/config/schemas.d.ts +245 -0
  98. package/dist/src/@types/config/types.d.ts +11 -1
  99. package/dist/src/@types/generic.d.ts +0 -1
  100. package/dist/src/@types/save-as-template.d.ts +1 -0
  101. package/dist/src/components/Guido.vue.d.ts +1 -1
  102. package/dist/src/components/organisms/AutoSaveController.vue.d.ts +2 -0
  103. package/dist/src/components/organisms/header/AutoSaveToggle.vue.d.ts +2 -0
  104. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  105. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  106. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  107. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  108. package/dist/src/composables/useActionsApi.d.ts +1 -1
  109. package/dist/src/composables/useAutoSave.d.ts +3 -0
  110. package/dist/src/composables/useConfig.d.ts +70 -0
  111. package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
  112. package/dist/src/composables/useRecommendation.d.ts +10 -1
  113. package/dist/src/composables/useRecommendation.test.d.ts +1 -0
  114. package/dist/src/composables/useRibbonOffset.d.ts +4 -0
  115. package/dist/src/composables/useSave.d.ts +1 -1
  116. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  117. package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
  118. package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
  119. package/dist/src/config/compiler/utils/recommendationCompilerUtils.d.ts +1 -1
  120. package/dist/src/config/migrator/index.d.ts +2 -1
  121. package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +2 -0
  122. package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +1 -0
  123. package/dist/src/config/migrator/recommendation/extractors.d.ts +7 -0
  124. package/dist/src/config/migrator/recommendation/extractors.test.d.ts +1 -0
  125. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +11 -0
  126. package/dist/src/config/migrator/recommendation/parseLegacyConfig.d.ts +15 -0
  127. package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +1 -0
  128. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +7 -0
  129. package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +1 -0
  130. package/dist/src/config/migrator/recommendation/themeMapper.d.ts +5 -0
  131. package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +1 -0
  132. package/dist/src/config/migrator/recommendation/types.d.ts +205 -0
  133. package/dist/src/config/migrator/recommendationMigrator.d.ts +13 -1
  134. package/dist/src/config/migrator/recommendationMigrator.test.d.ts +1 -0
  135. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  136. package/dist/src/enums/onboarding.d.ts +6 -0
  137. package/dist/src/enums/unsubscribe.d.ts +5 -0
  138. package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
  139. package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
  140. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  141. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  142. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +5 -0
  143. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +5 -0
  144. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
  145. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
  146. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +1 -0
  147. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
  148. package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
  149. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +21 -3
  150. package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +1 -0
  151. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +34 -0
  152. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  153. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  154. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +20 -3
  155. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -1
  156. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +21 -0
  157. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +1 -0
  158. package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -3
  159. package/dist/src/library.d.ts +1 -1
  160. package/dist/src/services/templateLibraryApi.d.ts +1 -1
  161. package/dist/src/stores/autosave.d.ts +12 -0
  162. package/dist/src/stores/config.d.ts +630 -0
  163. package/dist/src/stores/editor.d.ts +23 -0
  164. package/dist/src/stores/onboarding.d.ts +4 -0
  165. package/dist/src/stores/preview.d.ts +3 -0
  166. package/dist/src/utils/genericUtil.d.ts +1 -1
  167. package/dist/src/utils/htmlCompiler.d.ts +2 -1
  168. package/dist/src/utils/htmlEscape.d.ts +5 -0
  169. package/dist/src/utils/htmlEscape.test.d.ts +1 -0
  170. package/dist/src/utils/timeUtil.d.ts +8 -0
  171. package/dist/static/styles/base.css.js +7 -2
  172. package/dist/static/styles/components/button.css.js +16 -9
  173. package/dist/static/styles/components/loader.css.js +4 -0
  174. package/dist/static/styles/components/narrow-panel.css.js +52 -0
  175. package/dist/stores/autosave.js +17 -0
  176. package/dist/stores/editor.js +3 -1
  177. package/dist/stores/onboarding.js +4 -0
  178. package/dist/stores/preview.js +4 -3
  179. package/dist/utils/genericUtil.js +42 -20
  180. package/dist/utils/htmlCompiler.js +48 -41
  181. package/dist/utils/htmlEscape.js +13 -0
  182. package/dist/utils/pairProductVariables.js +89 -88
  183. package/dist/utils/templatePreparation.js +75 -24
  184. package/dist/utils/timeUtil.js +19 -0
  185. package/dist/utils/tooltipUtils.js +4 -5
  186. package/package.json +8 -4
  187. package/dist/enums/displayConditions.js +0 -80
  188. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +0 -251
  189. package/dist/src/enums/displayConditions.d.ts +0 -2
@@ -1,6 +1,6 @@
1
1
  import { SettingsPanelRegistry as E, SettingsPanelTab as _, SettingsTab as O, ContainerControls as C, TextControls as R } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { BLOCK_ID as U } from "./block.js";
3
- import { RecommendationBlockId as N } from "./constants/blockIds.js";
3
+ import { RecommendationBlockId as S } from "./constants/blockIds.js";
4
4
  import { RecommendationControlId as T } from "./constants/controlIds.js";
5
5
  import { CONTROL_BLOCK_ID as A } from "./controls/main/index.js";
6
6
  import "./store/recommendation.js";
@@ -14,7 +14,7 @@ import "./controls/image/index.js";
14
14
  import { SPACING_CONTROL_ID as L } from "./controls/spacing/index.js";
15
15
  import { CARD_BACKGROUND_COLOR_CONTROL_ID as D } from "./controls/cardBackground/index.js";
16
16
  import { COMPOSITION_CONTROL_BLOCK_ID as B } from "./controls/cardComposition/index.js";
17
- import { SYNC_INFO_MESSAGE_CONTROL_ID as S } from "./controls/syncInfoMessage.js";
17
+ import { SYNC_INFO_MESSAGE_CONTROL_ID as N } from "./controls/syncInfoMessage.js";
18
18
  class Z extends E {
19
19
  registerBlockControls(I) {
20
20
  I[U] = [
@@ -39,11 +39,11 @@ class Z extends E {
39
39
  B
40
40
  ]
41
41
  ).withLabel(this.api.translate("Card Composition"))
42
- ], I[N.NAME] = [
42
+ ], I[S.NAME] = [
43
43
  new _(
44
44
  O.SETTINGS,
45
45
  [
46
- S,
46
+ N,
47
47
  T.NAME_STYLE,
48
48
  T.NAME_ALIGN,
49
49
  T.NAME_TEXT_TRIM,
@@ -59,11 +59,11 @@ class Z extends E {
59
59
  T.NAME_COLOR
60
60
  ]
61
61
  )
62
- ], I[N.PRICE] = [
62
+ ], I[S.PRICE] = [
63
63
  new _(
64
64
  O.SETTINGS,
65
65
  [
66
- S,
66
+ N,
67
67
  T.PRICE_STYLE,
68
68
  T.PRICE_ALIGN,
69
69
  T.PRICE_PADDINGS
@@ -78,11 +78,11 @@ class Z extends E {
78
78
  T.PRICE_COLOR
79
79
  ]
80
80
  )
81
- ], I[N.OLD_PRICE] = [
81
+ ], I[S.OLD_PRICE] = [
82
82
  new _(
83
83
  O.SETTINGS,
84
84
  [
85
- S,
85
+ N,
86
86
  T.OLD_PRICE_STYLE,
87
87
  T.OLD_PRICE_ALIGN,
88
88
  T.OLD_PRICE_PADDINGS
@@ -97,11 +97,11 @@ class Z extends E {
97
97
  T.OLD_PRICE_COLOR
98
98
  ]
99
99
  )
100
- ], I[N.OMNIBUS_PRICE] = [
100
+ ], I[S.OMNIBUS_PRICE] = [
101
101
  new _(
102
102
  O.SETTINGS,
103
103
  [
104
- S,
104
+ N,
105
105
  T.OMNIBUS_PRICE_TEXT_BEFORE,
106
106
  T.OMNIBUS_PRICE_TEXT_AFTER,
107
107
  T.OMNIBUS_PRICE_STYLE,
@@ -118,11 +118,11 @@ class Z extends E {
118
118
  T.OMNIBUS_PRICE_COLOR
119
119
  ]
120
120
  )
121
- ], I[N.OMNIBUS_DISCOUNT] = [
121
+ ], I[S.OMNIBUS_DISCOUNT] = [
122
122
  new _(
123
123
  O.SETTINGS,
124
124
  [
125
- S,
125
+ N,
126
126
  T.OMNIBUS_DISCOUNT_TEXT_BEFORE,
127
127
  T.OMNIBUS_DISCOUNT_TEXT_AFTER,
128
128
  T.OMNIBUS_DISCOUNT_STYLE,
@@ -139,11 +139,11 @@ class Z extends E {
139
139
  T.OMNIBUS_DISCOUNT_COLOR
140
140
  ]
141
141
  )
142
- ], I[N.BUTTON] = [
142
+ ], I[S.BUTTON] = [
143
143
  new _(
144
144
  O.SETTINGS,
145
145
  [
146
- S,
146
+ N,
147
147
  T.BUTTON_TEXT,
148
148
  T.BUTTON_ALIGN,
149
149
  T.BUTTON_PADDINGS,
@@ -162,12 +162,13 @@ class Z extends E {
162
162
  T.BUTTON_BORDER
163
163
  ]
164
164
  )
165
- ], I[N.CUSTOM_ATTRIBUTE] = [
165
+ ], I[S.CUSTOM_ATTRIBUTE] = [
166
166
  new _(
167
167
  O.SETTINGS,
168
168
  [
169
169
  T.CUSTOM_ATTR_STYLE,
170
170
  T.CUSTOM_ATTR_ALIGN,
171
+ T.CUSTOM_ATTR_TEXT_TRIM,
171
172
  T.CUSTOM_ATTR_PADDINGS
172
173
  ]
173
174
  ),
@@ -180,11 +181,11 @@ class Z extends E {
180
181
  T.CUSTOM_ATTR_COLOR
181
182
  ]
182
183
  )
183
- ], I[N.IMAGE] = [
184
+ ], I[S.IMAGE] = [
184
185
  new _(
185
186
  O.SETTINGS,
186
187
  [
187
- S,
188
+ N,
188
189
  T.IMAGE_SIZE,
189
190
  T.IMAGE_MARGINS
190
191
  ]
@@ -1,15 +1,15 @@
1
- import { RecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as k } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as C } from "../../../../stores/config.js";
4
- import { defineStore as G } from "pinia";
1
+ import { RecommendationFeedSourceMaps as S, getOperatorOptions as R, PriceAttributes as y } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as C } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as G } from "../../../../stores/config.js";
4
+ import { defineStore as P } from "pinia";
5
5
  import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
- import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
7
- import { getDefaultProducts as S } from "../templates/utils.js";
6
+ import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
7
+ import { getDefaultProducts as g } from "../templates/utils.js";
8
8
  import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
9
- import { isFilterValid as D } from "../validation/filterSchema.js";
10
- const h = y();
9
+ import { isFilterValid as w } from "../validation/filterSchema.js";
10
+ const h = C();
11
11
  let u = null, m = null, d = null;
12
- function I() {
12
+ function k() {
13
13
  return {
14
14
  cardsInRow: F,
15
15
  currencySettings: {
@@ -37,9 +37,9 @@ function I() {
37
37
  customAttributes: []
38
38
  };
39
39
  }
40
- function P() {
40
+ function I() {
41
41
  return {
42
- recommendationConfigs: I(),
42
+ recommendationConfigs: k(),
43
43
  recommendationProducts: [],
44
44
  filterStatus: !1,
45
45
  filterSelectionDrawerStatus: !1,
@@ -57,7 +57,7 @@ const v = () => ({
57
57
  blockStates: {},
58
58
  currentRecommendationId: null,
59
59
  configVersion: 0
60
- }), E = G("guidoRecommendationExtension", {
60
+ }), _ = P("guidoRecommendationExtension", {
61
61
  state: () => v(),
62
62
  getters: {
63
63
  // ====================================================================
@@ -68,7 +68,7 @@ const v = () => ({
68
68
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
69
69
  */
70
70
  recommendationConfigs(t) {
71
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : I();
71
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
72
72
  },
73
73
  /**
74
74
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -102,46 +102,45 @@ const v = () => ({
102
102
  },
103
103
  hasValidFilters() {
104
104
  const { filters: t } = this.recommendationConfigs;
105
- return t.length ? t.every((r) => r.isValid) : !1;
105
+ return t.length ? t.every((e) => e.isValid) : !1;
106
106
  },
107
107
  getFilterGroupCount() {
108
108
  const { filters: t } = this.recommendationConfigs;
109
- return t.length ? new Set(t.map((r) => r.filterGroup)).size : 0;
109
+ return t.length ? new Set(t.map((e) => e.filterGroup)).size : 0;
110
110
  },
111
111
  getUniqueFilterGroups() {
112
112
  const { filters: t } = this.recommendationConfigs;
113
- return [...new Set(t.map((r) => r.filterGroup))].sort((r, e) => r - e);
113
+ return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
114
114
  },
115
115
  getActivePredictiveAlgorithms: (t) => {
116
- const r = [];
117
- return t.activePredictiveAlgorithms.filter((e) => !w.includes(e)).forEach((e) => {
118
- r.push(...g.filter((n) => n.id === e));
119
- }), r.map((e) => ({
120
- text: e.name,
121
- value: e.key
116
+ const e = [];
117
+ return t.activePredictiveAlgorithms.filter((r) => !D.includes(r)).forEach((r) => {
118
+ e.push(...S.filter((n) => n.id === r));
119
+ }), e.map((r) => ({
120
+ text: r.name,
121
+ value: r.key
122
122
  }));
123
123
  },
124
- getLanguages: (t) => Object.entries(t.languages).map(([r, e]) => ({
125
- text: e,
126
- value: r
124
+ getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
125
+ text: r,
126
+ value: e
127
127
  })),
128
- getCurrencySymbolList: (t) => t.currencyList.map((r) => ({
129
- text: r.text,
130
- value: r.text
128
+ getCurrencySymbolList: (t) => t.currencyList.map((e) => ({
129
+ text: e.text,
130
+ value: e.text
131
131
  })),
132
132
  getFilterList() {
133
133
  return Object.values(this.filterList).map((t) => {
134
- const r = t.type === "defaultAttribute", e = k.includes(t.attributeName);
135
- let n = r ? t.attributeName : `product_attributes.${t.attributeName}`;
136
- return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
134
+ let e;
135
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : y.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
137
136
  text: t.displayName,
138
- value: n,
137
+ value: e,
139
138
  type: t.attributeType
140
139
  };
141
140
  });
142
141
  },
143
142
  getSelectedFilterGroup() {
144
- return (t) => [...this.recommendationConfigs.filters].filter((r) => r.filterGroup === t);
143
+ return (t) => [...this.recommendationConfigs.filters].filter((e) => e.filterGroup === t);
145
144
  }
146
145
  },
147
146
  actions: {
@@ -155,7 +154,7 @@ const v = () => ({
155
154
  setCurrentBlock(t) {
156
155
  this.blockStates[t] || (this.blockStates = {
157
156
  ...this.blockStates,
158
- [t]: P()
157
+ [t]: I()
159
158
  }), this.currentRecommendationId = t;
160
159
  },
161
160
  /**
@@ -163,10 +162,15 @@ const v = () => ({
163
162
  * Resets currentRecommendationId if it was the deleted block.
164
163
  */
165
164
  removeBlockState(t) {
165
+ const e = t.toString();
166
+ if (this.recommendationCampaignUrls[e]) {
167
+ const n = { ...this.recommendationCampaignUrls };
168
+ delete n[e], this.recommendationCampaignUrls = n;
169
+ }
166
170
  const r = { ...this.blockStates };
167
171
  if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
168
- const e = Object.keys(this.blockStates).map(Number);
169
- this.currentRecommendationId = e.length > 0 ? e[0] : null;
172
+ const n = Object.keys(this.blockStates).map(Number);
173
+ this.currentRecommendationId = n.length > 0 ? n[0] : null;
170
174
  }
171
175
  },
172
176
  /**
@@ -176,37 +180,75 @@ const v = () => ({
176
180
  markBlockInitialized(t) {
177
181
  this.blockStates[t] && (this.blockStates[t].isInitialized = !0);
178
182
  },
183
+ /**
184
+ * Seeds the URL-relevant fields of a block from a persisted node config.
185
+ *
186
+ * Used at save-time to ensure the campaign URL is built from the
187
+ * persisted truth (the `esd-ext-config` blob in the raw HTML) even when
188
+ * the user never selected the block in this editor session — without
189
+ * this seed, `_syncNodeConfigToStore` would never have run for that
190
+ * block and the store would hold default values (USD/en_US/mostPopular)
191
+ * instead of the real config.
192
+ *
193
+ * Creates the block entry if missing; otherwise patches only the URL-
194
+ * relevant subset and leaves runtime fields (e.g., `recommendedProducts`,
195
+ * `isInitialized`) alone.
196
+ */
197
+ seedBlockUrlConfig(t, e) {
198
+ const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
199
+ name: e.currencyCode,
200
+ value: e.currencyCode,
201
+ symbol: e.currencyCode,
202
+ alignment: e.currencyAlignment === "before" ? "0" : "1",
203
+ decimalCount: String(e.currencyDecimalCount),
204
+ decimalSeparator: r(e.currencyDecimalSeparator, ","),
205
+ thousandSeparator: r(e.currencyThousandSeparator, ".")
206
+ }, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
207
+ i.recommendationConfigs = {
208
+ ...i.recommendationConfigs,
209
+ strategy: e.strategy,
210
+ language: e.language,
211
+ size: e.size,
212
+ productIds: e.productIds,
213
+ filters: e.filters,
214
+ shuffleProducts: e.shuffleProducts,
215
+ currencySettings: n
216
+ }, c && (this.blockStates = {
217
+ ...this.blockStates,
218
+ [t]: i
219
+ });
220
+ },
179
221
  /**
180
222
  * Patches the current block's recommendationConfigs.
181
223
  * Replaces `store.$patch({ recommendationConfigs: { ... } })` pattern.
182
224
  */
183
- patchCurrentBlockConfig(t, r = {}) {
225
+ patchCurrentBlockConfig(t, e = {}) {
184
226
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
185
227
  return;
186
- const e = this.blockStates[this.currentRecommendationId];
187
- e.recommendationConfigs = {
188
- ...e.recommendationConfigs,
228
+ const r = this.blockStates[this.currentRecommendationId];
229
+ r.recommendationConfigs = {
230
+ ...r.recommendationConfigs,
189
231
  ...t,
190
232
  currencySettings: {
191
- ...e.recommendationConfigs.currencySettings,
233
+ ...r.recommendationConfigs.currencySettings,
192
234
  ...t.currencySettings || {}
193
235
  }
194
236
  };
195
- const { triggerRefetch: n = !0 } = r;
237
+ const { triggerRefetch: n = !0 } = e;
196
238
  n && this.configVersion++;
197
239
  },
198
240
  /**
199
241
  * Creates a filter with the first available attribute and operator pre-selected.
200
242
  */
201
- createDefaultFilter(t, r) {
202
- const [e] = this.getFilterList, [n] = R(e == null ? void 0 : e.type);
243
+ createDefaultFilter(t, e) {
244
+ const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
203
245
  return {
204
246
  type: "standardFilter",
205
- attribute: (e == null ? void 0 : e.value) ?? "",
247
+ attribute: (r == null ? void 0 : r.value) ?? "",
206
248
  operator: (n == null ? void 0 : n.value) ?? "",
207
249
  innerGroupOperator: "*",
208
250
  outerGroupOperator: "*",
209
- filterNumber: r,
251
+ filterNumber: e,
210
252
  filterGroup: t,
211
253
  isValid: !1,
212
254
  value: ""
@@ -258,14 +300,14 @@ const v = () => ({
258
300
  u = (async () => {
259
301
  const {
260
302
  activePredictiveAlgorithms: t,
261
- languages: r,
262
- currencies: e
303
+ languages: e,
304
+ currencies: r
263
305
  } = await h.fetchRecommendationCreateData();
264
- if (this.activePredictiveAlgorithms = t, this.languages = r, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
306
+ if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
265
307
  const n = this.blockStates[this.currentRecommendationId];
266
308
  n.filterStatus = !!n.recommendationConfigs.filters.length;
267
309
  }
268
- this.currencyList = e;
310
+ this.currencyList = r;
269
311
  })();
270
312
  try {
271
313
  await u;
@@ -302,8 +344,8 @@ const v = () => ({
302
344
  deleteFilterGroup(t) {
303
345
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
304
346
  return;
305
- const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(e.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
306
- r.recommendationConfigs.filters = e.map((i) => ({
347
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
348
+ e.recommendationConfigs.filters = r.map((i) => ({
307
349
  ...i,
308
350
  filterGroup: c.get(i.filterGroup) ?? i.filterGroup
309
351
  }));
@@ -311,47 +353,47 @@ const v = () => ({
311
353
  updateFilter(t) {
312
354
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
313
355
  return;
314
- const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
315
- if (e !== -1) {
316
- const n = [...r.recommendationConfigs.filters];
317
- n[e] = {
356
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
357
+ if (r !== -1) {
358
+ const n = [...e.recommendationConfigs.filters];
359
+ n[r] = {
318
360
  ...t,
319
- isValid: D(t)
320
- }, r.recommendationConfigs.filters = n;
361
+ isValid: w(t)
362
+ }, e.recommendationConfigs.filters = n;
321
363
  }
322
364
  },
323
365
  deleteFilter(t) {
324
366
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
325
367
  return;
326
- const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
327
- if (e !== -1) {
328
- let n = [...r.recommendationConfigs.filters];
329
- if (n.splice(e, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
368
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
369
+ if (r !== -1) {
370
+ let n = [...e.recommendationConfigs.filters];
371
+ if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
330
372
  let i = 1;
331
373
  n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
332
374
  } else {
333
- const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, l) => s - l), o = new Map(i.map((s, l) => [s, l + 1]));
375
+ const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
334
376
  n = n.map((s) => ({
335
377
  ...s,
336
378
  filterGroup: o.get(s.filterGroup) ?? s.filterGroup
337
379
  }));
338
380
  }
339
- r.recommendationConfigs.filters = n;
381
+ e.recommendationConfigs.filters = n;
340
382
  }
341
383
  },
342
384
  addFilter(t) {
343
385
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
344
386
  return;
345
- const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters], c = e.filter(
387
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
346
388
  (o) => o.filterGroup === t.filterGroup
347
- ).length + 1, i = e.findLastIndex((o) => o.filterGroup === t.filterGroup);
348
- i !== -1 ? e.splice(i + 1, 0, {
389
+ ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
390
+ i !== -1 ? r.splice(i + 1, 0, {
349
391
  ...t,
350
392
  filterNumber: c
351
- }) : e.push({
393
+ }) : r.push({
352
394
  ...t,
353
395
  filterNumber: c
354
- }), r.recommendationConfigs.filters = e;
396
+ }), e.recommendationConfigs.filters = r;
355
397
  },
356
398
  generateFilterQuery() {
357
399
  return b(this.recommendationConfigs.filters);
@@ -375,29 +417,31 @@ const v = () => ({
375
417
  },
376
418
  async _doFetchProducts() {
377
419
  var p;
378
- const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((a) => a.isValid), c = b(n), i = ((p = g.find((a) => a.key === e.strategy)) == null ? void 0 : p.path) || "", o = C(), s = {
379
- locale: e.language,
380
- currency: e.currencySettings.value,
420
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = S.find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
421
+ locale: r.language,
422
+ currency: r.currencySettings.value,
381
423
  partnerName: o.partnerName,
382
- size: e.size,
424
+ size: r.size,
383
425
  details: !0,
384
426
  campaignId: o.variationId
385
427
  };
386
- e.strategy === "manualMerchandising" ? s.productId = e.productIds.join(",") : e.strategy === "similarViewed" && (s.productId = "{itemId}"), e.strategy === "userBased" && (s.userId = "{user_id}"), c && (s.filter = c), e.shuffleProducts && (s.shuffle = !0);
387
- const l = parseInt(e.size) || 6;
428
+ r.strategy === "manualMerchandising" ? a.productId = r.productIds.slice(0, s).join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0);
388
429
  let f;
389
430
  try {
390
- f = await h.fetchRecommendationProducts(i, s);
431
+ f = await h.fetchRecommendationProducts(i, a);
391
432
  } catch {
392
433
  f = [];
393
434
  }
394
435
  if (this.blockStates[t]) {
395
- const a = f.length > 0 ? f : S(l);
396
- this.blockStates[t].recommendationProducts = a.length < l ? [...a, ...S(l - a.length)] : a;
436
+ const l = f.length > 0 ? f : g(s);
437
+ l.length < s ? this.blockStates[t].recommendationProducts = [
438
+ ...l,
439
+ ...g(s - l.length)
440
+ ] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
397
441
  }
398
442
  }
399
443
  }
400
444
  });
401
445
  export {
402
- E as useRecommendationExtensionStore
446
+ _ as useRecommendationExtensionStore
403
447
  };
@@ -1,11 +1,11 @@
1
1
  import { RecommendationBlockId as s } from "../../constants/blockIds.js";
2
- import { ATTR_PRODUCT_ATTR as g, ATTR_PRODUCT_BUTTON as u, ATTR_PRODUCT_OMNIBUS_DISCOUNT as m, ATTR_PRODUCT_OMNIBUS_PRICE as h, ATTR_PRODUCT_OLD_PRICE as y, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_NAME as f, ATTR_PRODUCT_IMAGE as _ } from "../../constants/selectors.js";
3
- import { useRecommendationExtensionStore as x } from "../../store/recommendation.js";
2
+ import { ATTR_PRODUCT_ATTR as b, ATTR_PRODUCT_BUTTON as u, ATTR_PRODUCT_OMNIBUS_DISCOUNT as m, ATTR_PRODUCT_OMNIBUS_PRICE as h, ATTR_PRODUCT_OLD_PRICE as y, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_NAME as f, ATTR_PRODUCT_IMAGE as x } from "../../constants/selectors.js";
3
+ import { useRecommendationExtensionStore as _ } from "../../store/recommendation.js";
4
4
  import { formatPrice as $ } from "../../utils/priceFormatter.js";
5
5
  import { sanitizeImageUrl as C, CUSTOM_CELL_HTML as R } from "../utils.js";
6
6
  const a = "0 5px", l = "attribute-cell";
7
7
  function p() {
8
- const t = x(), { currencySettings: e } = t.recommendationConfigs;
8
+ const t = _(), { currencySettings: e } = t.recommendationConfigs;
9
9
  return {
10
10
  code: e.value,
11
11
  symbol: e.symbol,
@@ -15,7 +15,7 @@ function p() {
15
15
  thousandSeparator: e.thousandSeparator
16
16
  };
17
17
  }
18
- function r(t, e = "price") {
18
+ function i(t, e = "price") {
19
19
  const o = p(), n = t[e], d = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
20
20
  return $({
21
21
  price: d,
@@ -23,7 +23,7 @@ function r(t, e = "price") {
23
23
  });
24
24
  }
25
25
  const I = {
26
- [_]: (t) => `
26
+ [x]: (t) => `
27
27
  <td class="${l}" style="padding: ${a}; height: 100%;" valign="top">
28
28
  <table
29
29
  class="product-card-segment"
@@ -92,7 +92,7 @@ const I = {
92
92
  align="center"
93
93
  esd-extension-block-id="${s.PRICE}">
94
94
  <p contenteditable="false" style="font-size: 16px; color: #333333;">
95
- <strong>${r(t, "price")}</strong>
95
+ <strong>${i(t, "price")}</strong>
96
96
  </p>
97
97
  </td>
98
98
  </tr>
@@ -116,7 +116,7 @@ const I = {
116
116
  align="center"
117
117
  esd-extension-block-id="${s.OLD_PRICE}">
118
118
  <p contenteditable="false" style="font-size: 14px; color: #999999;">
119
- <strong>${r(t, "original_price")}</strong>
119
+ <strong>${i(t, "original_price")}</strong>
120
120
  </p>
121
121
  </td>
122
122
  </tr>
@@ -143,7 +143,7 @@ const I = {
143
143
  esd-extension-block-id="${s.OMNIBUS_PRICE}">
144
144
  <p contenteditable="false" style="font-size: 12px; color: #666666;">
145
145
  <span class="omnibus-text-before">Lowest 30-day price: </span>
146
- <span class="omnibus-price-value">${r(t, "original_price")}</span>
146
+ <span class="omnibus-price-value">${i(t, "original_price")}</span>
147
147
  <span class="omnibus-text-after"></span>
148
148
  </p>
149
149
  </td>
@@ -153,8 +153,8 @@ const I = {
153
153
  </td>
154
154
  `,
155
155
  [m]: (t) => {
156
- var c, i;
157
- const e = p(), o = ((c = t.original_price) == null ? void 0 : c[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((i = t.price) == null ? void 0 : i[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, d = o > 0 ? Math.round((o - n) / o * 100) : 0, b = d > 0 ? `-${d}%` : "0%";
156
+ var r, c;
157
+ const e = p(), o = ((r = t.original_price) == null ? void 0 : r[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((c = t.price) == null ? void 0 : c[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, d = o > 0 ? Math.round((o - n) / o * 100) : 0, g = d > 0 ? `-${d}%` : "0%";
158
158
  return `
159
159
  <td class="${l}" style="padding: ${a}; height: 100%;" valign="top">
160
160
  <table
@@ -174,7 +174,7 @@ const I = {
174
174
  esd-extension-block-id="${s.OMNIBUS_DISCOUNT}">
175
175
  <p contenteditable="false" style="font-size: 12px; color: #666666;">
176
176
  <span class="omnibus-text-before"></span>
177
- <span class="omnibus-discount-value">${b}</span>
177
+ <span class="omnibus-discount-value">${g}</span>
178
178
  <span class="omnibus-text-after"></span>
179
179
  </p>
180
180
  </td>
@@ -210,7 +210,16 @@ const I = {
210
210
  href="#"
211
211
  class="es-button buy-button"
212
212
  target="_blank"
213
- style="color: rgb(56, 118, 29); background: rgb(217, 234, 211);">
213
+ style="
214
+ color: rgb(56, 118, 29);
215
+ background: rgb(217, 234, 211);
216
+ font-family: arial, 'helvetica neue', helvetica, sans-serif;
217
+ font-size: 16px;
218
+ font-weight: normal;
219
+ line-height: 120%;
220
+ mso-border-alt: 10px solid rgb(217, 234, 211);
221
+ mso-padding-alt: 0;
222
+ ">
214
223
  Buy
215
224
  </a>
216
225
  </span>
@@ -224,6 +233,8 @@ const I = {
224
233
  * Custom attribute cell template — same structure as built-in entries
225
234
  * (outer td → inner product-card-segment table).
226
235
  * Used by `buildElementRenderer` for `customAttr:*` composition entries.
236
+ * @param productAttrValue - Resolved product-attr value (e.g., "brand" for default, "product_attribute.rating_star" for custom)
237
+ * @param content - Display content for the cell
227
238
  */
228
239
  [R]: (t, e) => `
229
240
  <td class="${l}" style="padding: ${a}; height: 100%;" valign="middle">
@@ -238,7 +249,7 @@ const I = {
238
249
  <tbody>
239
250
  <tr valign="top">
240
251
  <td
241
- ${g}="product_attribute.${t}"
252
+ ${b}="${t}"
242
253
  class="esd-block-text product-custom-attribute es-p0t es-p0b es-p15l es-p15r"
243
254
  align="center"
244
255
  esd-extension-block-id="${s.CUSTOM_ATTRIBUTE}">