@useinsider/guido 3.17.0 → 3.18.0-beta.a0b94e0

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 (119) hide show
  1. package/README.md +6 -5
  2. package/dist/@types/config/schemas.js +7 -6
  3. package/dist/components/Guido.vue.js +10 -10
  4. package/dist/components/Guido.vue2.js +82 -76
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +21 -0
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +106 -0
  7. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.js +17 -0
  8. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +57 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.js +19 -0
  10. package/dist/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue2.js +63 -0
  11. package/dist/composables/useCustomInterfaceAppearance.js +52 -38
  12. package/dist/composables/useModuleRepair.js +33 -0
  13. package/dist/composables/useRecommendation.js +41 -34
  14. package/dist/composables/useSave.js +30 -29
  15. package/dist/composables/useStripo.js +15 -15
  16. package/dist/composables/useSyncModuleExtractor.js +15 -13
  17. package/dist/composables/validators/useSyncModuleBlockValidator.js +24 -0
  18. package/dist/config/i18n/en/labels.json.js +1 -1
  19. package/dist/config/migrator/index.js +9 -8
  20. package/dist/config/migrator/itemsBlockMigrator.js +197 -137
  21. package/dist/config/migrator/recommendation/compositionMapper.js +20 -20
  22. package/dist/config/migrator/recommendation/extractors.js +29 -24
  23. package/dist/config/migrator/recommendation/htmlBuilder.js +116 -130
  24. package/dist/config/migrator/recommendation/settingsMapper.js +17 -17
  25. package/dist/config/migrator/recommendationMigrator.js +31 -25
  26. package/dist/config/migrator/recommendationTitleMigrator.js +119 -0
  27. package/dist/enums/academy.js +2 -1
  28. package/dist/enums/date.js +5 -3
  29. package/dist/enums/extensions/recommendationBlock.js +3 -1
  30. package/dist/extensions/Blocks/Items/block.js +118 -49
  31. package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
  32. package/dist/extensions/Blocks/Items/constants/currency.js +25 -0
  33. package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
  34. package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
  35. package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
  36. package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
  37. package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
  38. package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
  39. package/dist/extensions/Blocks/Items/template.js +189 -179
  40. package/dist/extensions/Blocks/Items/utils/constants.js +4 -0
  41. package/dist/extensions/Blocks/Recommendation/block.js +35 -29
  42. package/dist/extensions/Blocks/Recommendation/constants/blockIds.js +1 -1
  43. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  44. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +29 -27
  45. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +35 -28
  46. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +309 -236
  47. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +241 -180
  48. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +124 -0
  49. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +1 -0
  50. package/dist/extensions/Blocks/Recommendation/controls/title/index.js +44 -0
  51. package/dist/extensions/Blocks/Recommendation/extension.js +31 -29
  52. package/dist/extensions/Blocks/Recommendation/services/configService.js +54 -36
  53. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +23 -4
  54. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +175 -79
  55. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -3
  56. package/dist/extensions/Blocks/Recommendation/templates/titleRows.js +33 -0
  57. package/dist/extensions/Blocks/Recommendation/templates/utils.js +85 -107
  58. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +22 -0
  59. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +10 -6
  60. package/dist/extensions/Blocks/common-control.js +22 -19
  61. package/dist/guido.css +1 -1
  62. package/dist/services/recommendationApi.js +69 -30
  63. package/dist/src/@types/config/schemas.d.ts +2 -0
  64. package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
  65. package/dist/src/components/organisms/extensions/recommendation/RemoveStrategyModal.vue.d.ts +2 -0
  66. package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBoxContent.vue.d.ts +15 -0
  67. package/dist/src/composables/useConfig.d.ts +2 -0
  68. package/dist/src/composables/useModuleRepair.d.ts +18 -0
  69. package/dist/src/composables/useRecommendation.d.ts +1 -0
  70. package/dist/src/composables/useSyncModuleExtractor.d.ts +2 -0
  71. package/dist/src/composables/validators/useSyncModuleBlockValidator.d.ts +3 -0
  72. package/dist/src/config/migrator/recommendation/extractors.d.ts +8 -0
  73. package/dist/src/config/migrator/recommendationTitleMigrator.d.ts +5 -0
  74. package/dist/src/enums/academy.d.ts +1 -0
  75. package/dist/src/enums/date.d.ts +1 -0
  76. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  77. package/dist/src/extensions/Blocks/Items/block.d.ts +35 -0
  78. package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
  79. package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +43 -0
  80. package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
  81. package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
  82. package/dist/src/extensions/Blocks/Items/utils/constants.d.ts +6 -0
  83. package/dist/src/extensions/Blocks/Recommendation/constants/blockIds.d.ts +2 -1
  84. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +7 -0
  85. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +3 -6
  86. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +2 -2
  87. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +12 -0
  88. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +11 -0
  89. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  90. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +44 -8
  91. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +16 -0
  92. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +1 -0
  93. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +86 -0
  94. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +12 -1
  95. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +176 -10
  96. package/dist/src/extensions/Blocks/Recommendation/templates/titleRows.d.ts +13 -0
  97. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  98. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +31 -0
  99. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +6 -2
  100. package/dist/src/extensions/Blocks/common-control.d.ts +4 -1
  101. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  102. package/dist/src/services/recommendationApi.d.ts +4 -1
  103. package/dist/src/stores/config.d.ts +18 -0
  104. package/dist/src/stores/save-as-template.d.ts +4 -3
  105. package/dist/src/utils/genericUtil.d.ts +5 -0
  106. package/dist/src/utils/itemsCurrencyRepair.d.ts +17 -0
  107. package/dist/static/assets/icons/line-change.svg.js +5 -0
  108. package/dist/static/assets/icons/line-delete.svg.js +5 -0
  109. package/dist/static/assets/icons/line-plus.svg.js +5 -0
  110. package/dist/static/styles/components/recommendation-strategy.css.js +155 -0
  111. package/dist/static/styles/customEditorStyle.css.js +3 -1
  112. package/dist/utils/dateUtil.js +23 -10
  113. package/dist/utils/genericUtil.js +28 -27
  114. package/dist/utils/itemsCurrencyRepair.js +39 -0
  115. package/dist/utils/pairProductVariables.js +77 -77
  116. package/dist/utils/templatePreparation.js +35 -34
  117. package/package.json +3 -2
  118. package/dist/composables/useModuleDynamicContentRepair.js +0 -37
  119. package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -13
@@ -0,0 +1,86 @@
1
+ export declare const TitleControls: {
2
+ readonly align: {
3
+ new (): {
4
+ getId(): string;
5
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
6
+ getParentControlId(): string;
7
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
8
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
9
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
10
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
11
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
12
+ };
13
+ };
14
+ readonly color: {
15
+ new (): {
16
+ getId(): string;
17
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
18
+ getParentControlId(): string;
19
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
20
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
21
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
22
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
23
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
24
+ };
25
+ };
26
+ readonly size: {
27
+ new (): {
28
+ getId(): string;
29
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
30
+ getParentControlId(): string;
31
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
32
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
33
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
34
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
35
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
36
+ };
37
+ };
38
+ readonly style: {
39
+ new (): {
40
+ getId(): string;
41
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
42
+ getParentControlId(): string;
43
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
44
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
45
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
46
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
47
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
48
+ };
49
+ };
50
+ readonly fontFamily: {
51
+ new (): {
52
+ getId(): string;
53
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
54
+ getParentControlId(): string;
55
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
56
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
57
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
58
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
59
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
60
+ };
61
+ };
62
+ readonly background: {
63
+ new (): {
64
+ getId(): string;
65
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
66
+ getAdditionalModifications(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
67
+ getParentControlId(): string;
68
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
69
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
70
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
71
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
72
+ };
73
+ };
74
+ readonly paddings: {
75
+ new (): {
76
+ getId(): string;
77
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
78
+ getParentControlId(): string;
79
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
80
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
81
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
82
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
83
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
84
+ };
85
+ };
86
+ };
@@ -25,7 +25,7 @@ import { ModificationDescription } from '@stripoinc/ui-editor-extensions';
25
25
  * Stripo Extension API interface for document modifications
26
26
  * Extracted to allow type-safe usage without importing full Stripo types
27
27
  */
28
- interface DocumentModifier {
28
+ export interface DocumentModifier {
29
29
  modifyHtml: (node: ImmutableHtmlNode) => {
30
30
  setNodeConfig: (config: Record<string, unknown>) => DocumentModifier;
31
31
  setAttribute: (name: string, value: string) => DocumentModifier;
@@ -90,6 +90,17 @@ export declare class RecommendationConfigService {
90
90
  * @returns The new complete configuration
91
91
  */
92
92
  static updateConfig(api: DocumentModifierApi, node: ImmutableHtmlNode, updates: PartialNodeConfig, description: string): RecommendationNodeConfig;
93
+ /**
94
+ * Accumulate a config update into an existing modifier batch, WITHOUT applying.
95
+ *
96
+ * The caller owns the apply(), so the write shares one undo entry with the rest
97
+ * of that batch — a change whose visible result only lands after an async product
98
+ * fetch would otherwise cost the user two undo presses (SD-149105).
99
+ * @param documentModifier - The batch to accumulate into (caller applies)
100
+ * @param node - The immutable HTML node to write to
101
+ * @param updates - Partial config with values to update
102
+ */
103
+ static stageConfig(documentModifier: DocumentModifier, node: ImmutableHtmlNode, updates: PartialNodeConfig): void;
93
104
  /**
94
105
  * Initialize configuration for a new block
95
106
  *
@@ -1,4 +1,4 @@
1
- import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationProduct } from '@@/Types/recommendation';
1
+ import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsStrategy } from '@@/Types/recommendation';
2
2
  export interface PerBlockConfigs {
3
3
  cardsInRow: number;
4
4
  currencySettings: {
@@ -21,6 +21,7 @@ export interface PerBlockConfigs {
21
21
  sendProductRequestFlag: boolean;
22
22
  shuffleProducts: boolean;
23
23
  strategy: string;
24
+ strategyId: string;
24
25
  textTrimming: boolean;
25
26
  unresponsive: boolean;
26
27
  size: string;
@@ -33,6 +34,8 @@ interface PerBlockState {
33
34
  recommendationProducts: RecommendationProduct[];
34
35
  filterStatus: boolean;
35
36
  filterSelectionDrawerStatus: boolean;
37
+ assignStrategyDrawerStatus: boolean;
38
+ removeStrategyModalStatus: boolean;
36
39
  filterGroup: number;
37
40
  /** Whether initial API data (filters, algorithms, products) has been fetched for this block */
38
41
  isInitialized: boolean;
@@ -47,6 +50,7 @@ interface PerBlockState {
47
50
  */
48
51
  export interface PerBlockUrlConfig {
49
52
  strategy: string;
53
+ strategyId: string;
50
54
  language: string;
51
55
  size: string;
52
56
  productIds: string[];
@@ -59,11 +63,14 @@ export interface PerBlockUrlConfig {
59
63
  currencyThousandSeparator: string;
60
64
  }
61
65
  interface StoreState {
62
- recommendationCampaignUrls: Record<string, string>;
66
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
63
67
  activePredictiveAlgorithms: number[];
64
68
  languages: Languages;
65
69
  currencyList: Currency[];
66
70
  filterList: FiltersResponse;
71
+ strategies: RrsStrategy[];
72
+ strategiesLoading: boolean;
73
+ strategyUrlTemplates: Record<string, string>;
67
74
  blockStates: Record<number, PerBlockState>;
68
75
  currentRecommendationId: number | null;
69
76
  configVersion: number;
@@ -74,7 +81,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
74
81
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
75
82
  */
76
83
  recommendationConfigs(state: {
77
- recommendationCampaignUrls: Record<string, string>;
84
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
78
85
  activePredictiveAlgorithms: number[];
79
86
  languages: Languages;
80
87
  currencyList: {
@@ -82,6 +89,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
82
89
  value: string;
83
90
  }[];
84
91
  filterList: FiltersResponse;
92
+ strategies: {
93
+ [x: string]: unknown;
94
+ strategy_id: number;
95
+ name: string;
96
+ status: string;
97
+ suitable_channels: string;
98
+ size?: (number | string) | undefined;
99
+ }[];
100
+ strategiesLoading: boolean;
101
+ strategyUrlTemplates: Record<string, string>;
85
102
  blockStates: Record<number, PerBlockState>;
86
103
  currentRecommendationId: number | null;
87
104
  configVersion: number;
@@ -90,7 +107,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
90
107
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
91
108
  */
92
109
  recommendationProducts(state: {
93
- recommendationCampaignUrls: Record<string, string>;
110
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
94
111
  activePredictiveAlgorithms: number[];
95
112
  languages: Languages;
96
113
  currencyList: {
@@ -98,6 +115,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
98
115
  value: string;
99
116
  }[];
100
117
  filterList: FiltersResponse;
118
+ strategies: {
119
+ [x: string]: unknown;
120
+ strategy_id: number;
121
+ name: string;
122
+ status: string;
123
+ suitable_channels: string;
124
+ size?: (number | string) | undefined;
125
+ }[];
126
+ strategiesLoading: boolean;
127
+ strategyUrlTemplates: Record<string, string>;
101
128
  blockStates: Record<number, PerBlockState>;
102
129
  currentRecommendationId: number | null;
103
130
  configVersion: number;
@@ -106,7 +133,30 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
106
133
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterSelectionDrawerStatus
107
134
  */
108
135
  filterSelectionDrawerStatus(state: {
109
- recommendationCampaignUrls: Record<string, string>;
136
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
137
+ activePredictiveAlgorithms: number[];
138
+ languages: Languages;
139
+ currencyList: {
140
+ text: string;
141
+ value: string;
142
+ }[];
143
+ filterList: FiltersResponse;
144
+ strategies: {
145
+ [x: string]: unknown;
146
+ strategy_id: number;
147
+ name: string;
148
+ status: string;
149
+ suitable_channels: string;
150
+ size?: (number | string) | undefined;
151
+ }[];
152
+ strategiesLoading: boolean;
153
+ strategyUrlTemplates: Record<string, string>;
154
+ blockStates: Record<number, PerBlockState>;
155
+ currentRecommendationId: number | null;
156
+ configVersion: number;
157
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
158
+ assignStrategyDrawerStatus(state: {
159
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
110
160
  activePredictiveAlgorithms: number[];
111
161
  languages: Languages;
112
162
  currencyList: {
@@ -114,15 +164,71 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
114
164
  value: string;
115
165
  }[];
116
166
  filterList: FiltersResponse;
167
+ strategies: {
168
+ [x: string]: unknown;
169
+ strategy_id: number;
170
+ name: string;
171
+ status: string;
172
+ suitable_channels: string;
173
+ size?: (number | string) | undefined;
174
+ }[];
175
+ strategiesLoading: boolean;
176
+ strategyUrlTemplates: Record<string, string>;
117
177
  blockStates: Record<number, PerBlockState>;
118
178
  currentRecommendationId: number | null;
119
179
  configVersion: number;
120
180
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
181
+ removeStrategyModalStatus(state: {
182
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
183
+ activePredictiveAlgorithms: number[];
184
+ languages: Languages;
185
+ currencyList: {
186
+ text: string;
187
+ value: string;
188
+ }[];
189
+ filterList: FiltersResponse;
190
+ strategies: {
191
+ [x: string]: unknown;
192
+ strategy_id: number;
193
+ name: string;
194
+ status: string;
195
+ suitable_channels: string;
196
+ size?: (number | string) | undefined;
197
+ }[];
198
+ strategiesLoading: boolean;
199
+ strategyUrlTemplates: Record<string, string>;
200
+ blockStates: Record<number, PerBlockState>;
201
+ currentRecommendationId: number | null;
202
+ configVersion: number;
203
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
204
+ assignedStrategy(state: {
205
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
206
+ activePredictiveAlgorithms: number[];
207
+ languages: Languages;
208
+ currencyList: {
209
+ text: string;
210
+ value: string;
211
+ }[];
212
+ filterList: FiltersResponse;
213
+ strategies: {
214
+ [x: string]: unknown;
215
+ strategy_id: number;
216
+ name: string;
217
+ status: string;
218
+ suitable_channels: string;
219
+ size?: (number | string) | undefined;
220
+ }[];
221
+ strategiesLoading: boolean;
222
+ strategyUrlTemplates: Record<string, string>;
223
+ blockStates: Record<number, PerBlockState>;
224
+ currentRecommendationId: number | null;
225
+ configVersion: number;
226
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
121
227
  /**
122
228
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
123
229
  */
124
230
  filterStatus(state: {
125
- recommendationCampaignUrls: Record<string, string>;
231
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
126
232
  activePredictiveAlgorithms: number[];
127
233
  languages: Languages;
128
234
  currencyList: {
@@ -130,6 +236,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
130
236
  value: string;
131
237
  }[];
132
238
  filterList: FiltersResponse;
239
+ strategies: {
240
+ [x: string]: unknown;
241
+ strategy_id: number;
242
+ name: string;
243
+ status: string;
244
+ suitable_channels: string;
245
+ size?: (number | string) | undefined;
246
+ }[];
247
+ strategiesLoading: boolean;
248
+ strategyUrlTemplates: Record<string, string>;
133
249
  blockStates: Record<number, PerBlockState>;
134
250
  currentRecommendationId: number | null;
135
251
  configVersion: number;
@@ -138,7 +254,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
138
254
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterGroup
139
255
  */
140
256
  filterGroup(state: {
141
- recommendationCampaignUrls: Record<string, string>;
257
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
142
258
  activePredictiveAlgorithms: number[];
143
259
  languages: Languages;
144
260
  currencyList: {
@@ -146,6 +262,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
146
262
  value: string;
147
263
  }[];
148
264
  filterList: FiltersResponse;
265
+ strategies: {
266
+ [x: string]: unknown;
267
+ strategy_id: number;
268
+ name: string;
269
+ status: string;
270
+ suitable_channels: string;
271
+ size?: (number | string) | undefined;
272
+ }[];
273
+ strategiesLoading: boolean;
274
+ strategyUrlTemplates: Record<string, string>;
149
275
  blockStates: Record<number, PerBlockState>;
150
276
  currentRecommendationId: number | null;
151
277
  configVersion: number;
@@ -155,7 +281,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
155
281
  getFilterGroupCount(): number;
156
282
  getUniqueFilterGroups(): number[];
157
283
  getActivePredictiveAlgorithms: (state: {
158
- recommendationCampaignUrls: Record<string, string>;
284
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
159
285
  activePredictiveAlgorithms: number[];
160
286
  languages: Languages;
161
287
  currencyList: {
@@ -163,6 +289,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
163
289
  value: string;
164
290
  }[];
165
291
  filterList: FiltersResponse;
292
+ strategies: {
293
+ [x: string]: unknown;
294
+ strategy_id: number;
295
+ name: string;
296
+ status: string;
297
+ suitable_channels: string;
298
+ size?: (number | string) | undefined;
299
+ }[];
300
+ strategiesLoading: boolean;
301
+ strategyUrlTemplates: Record<string, string>;
166
302
  blockStates: Record<number, PerBlockState>;
167
303
  currentRecommendationId: number | null;
168
304
  configVersion: number;
@@ -171,7 +307,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
171
307
  value: string;
172
308
  }[];
173
309
  getLanguages: (state: {
174
- recommendationCampaignUrls: Record<string, string>;
310
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
175
311
  activePredictiveAlgorithms: number[];
176
312
  languages: Languages;
177
313
  currencyList: {
@@ -179,6 +315,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
179
315
  value: string;
180
316
  }[];
181
317
  filterList: FiltersResponse;
318
+ strategies: {
319
+ [x: string]: unknown;
320
+ strategy_id: number;
321
+ name: string;
322
+ status: string;
323
+ suitable_channels: string;
324
+ size?: (number | string) | undefined;
325
+ }[];
326
+ strategiesLoading: boolean;
327
+ strategyUrlTemplates: Record<string, string>;
182
328
  blockStates: Record<number, PerBlockState>;
183
329
  currentRecommendationId: number | null;
184
330
  configVersion: number;
@@ -187,7 +333,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
187
333
  value: string;
188
334
  }[];
189
335
  getCurrencySymbolList: (state: {
190
- recommendationCampaignUrls: Record<string, string>;
336
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
191
337
  activePredictiveAlgorithms: number[];
192
338
  languages: Languages;
193
339
  currencyList: {
@@ -195,6 +341,16 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
195
341
  value: string;
196
342
  }[];
197
343
  filterList: FiltersResponse;
344
+ strategies: {
345
+ [x: string]: unknown;
346
+ strategy_id: number;
347
+ name: string;
348
+ status: string;
349
+ suitable_channels: string;
350
+ size?: (number | string) | undefined;
351
+ }[];
352
+ strategiesLoading: boolean;
353
+ strategyUrlTemplates: Record<string, string>;
198
354
  blockStates: Record<number, PerBlockState>;
199
355
  currentRecommendationId: number | null;
200
356
  configVersion: number;
@@ -272,6 +428,14 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
272
428
  * to the snapshot taken when the drawer was opened.
273
429
  */
274
430
  cancelFilterDrawer(): void;
431
+ openAssignStrategyDrawer(): void;
432
+ closeAssignStrategyDrawer(): void;
433
+ openRemoveStrategyModal(): void;
434
+ closeRemoveStrategyModal(): void;
435
+ fetchStrategies(): Promise<void>;
436
+ resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
437
+ assignStrategy(strategy: RrsStrategy): void;
438
+ removeStrategy(): void;
275
439
  fetchRecommendationCreateData(): Promise<void>;
276
440
  fetchRecommendationFilters(): Promise<void>;
277
441
  addFilterGroup(filterGroup: number): void;
@@ -288,5 +452,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
288
452
  hasInvalidBlock(): boolean;
289
453
  fetchRecommendationProducts(): Promise<void>;
290
454
  _doFetchProducts(): Promise<void>;
455
+ _doFetchStrategyProducts(blockId: number): Promise<void>;
456
+ _setBlockProducts(blockId: number, products: RecommendationProduct[], size: number): void;
291
457
  }>;
292
458
  export {};
@@ -0,0 +1,13 @@
1
+ export declare const DEFAULT_TITLE_TEXT = "You May Also Like!";
2
+ export declare const DEFAULT_TITLE_PARAGRAPH: string;
3
+ /**
4
+ * Builds the two block-level title rows: the title itself and the spacer below it.
5
+ * Both carry the same `recommendation-attribute-row` tagging a card attribute row has,
6
+ * so the Card Composition toggle hides the pair together and the compiler's
7
+ * `[data-visibility="0"]` sweep drops both — no leading gap when the title is off.
8
+ * @param paragraphHtml - Full `<p>` markup rendered inside the title cell
9
+ * @param visible - Whether the title starts visible
10
+ * @param spacerHeightPx - Height of the spacer row below the title
11
+ * @returns HTML string with the title row followed by its spacer row
12
+ */
13
+ export declare function buildTitleRows(paragraphHtml?: string, visible?: boolean, spacerHeightPx?: number): string;
@@ -82,6 +82,7 @@ export interface RecommendationNodeConfig {
82
82
  * Uses existing Filter interface from recommendation types
83
83
  */
84
84
  filters: Filter[];
85
+ strategyId: string;
85
86
  /**
86
87
  * Layout orientation
87
88
  * - 'grid': Products in a grid, attributes aligned across products
@@ -138,6 +139,12 @@ export interface RecommendationNodeConfig {
138
139
  * Keys are ATTR_PRODUCT_* constants
139
140
  */
140
141
  visibility: Record<string, boolean>;
142
+ /**
143
+ * Snapshot of the block title's row markup before it's removed.
144
+ * Restored verbatim when the title is re-enabled.
145
+ * @default ''
146
+ */
147
+ previousTitleHtml: string;
141
148
  /**
142
149
  * Omnibus price text configuration
143
150
  * For EU Omnibus Directive compliance
@@ -0,0 +1,31 @@
1
+ import type { DocumentModifier } from '../services/configService';
2
+ import type { PartialNodeConfig } from '../types/nodeConfig';
3
+ import type { RecommendationProduct } from '@@/Types/recommendation';
4
+ import { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
5
+ interface ConfigWriterApi {
6
+ getDocumentModifier: () => DocumentModifier;
7
+ getDocumentRootHtmlNode: () => ImmutableHtmlNode;
8
+ }
9
+ /**
10
+ * Keeps a document handle alive for writes the settings panel can no longer make.
11
+ * Deliberately not cleared on deselect — that is the exact moment the handle is
12
+ * needed. It is replaced on the next render, and goes stale only if the editor
13
+ * itself is torn down.
14
+ */
15
+ export declare function registerNodeConfigWriter(api: ConfigWriterApi): void;
16
+ /**
17
+ * Commits a config change and its product re-render straight to the document,
18
+ * bypassing the settings panel.
19
+ *
20
+ * Host-rendered UI (the remove-strategy modal) lives outside `ui-editor`, and
21
+ * Stripo deselects the block on the first click that lands there — destroying the
22
+ * control that normally does both, before the store change even happens.
23
+ *
24
+ * Mirrors the control's regenerate routine so config and cards land in ONE undo
25
+ * entry, and so partner-managed blocks keep their hand-authored cells.
26
+ * @param description - labels the undo entry only when there are no cards to
27
+ * re-render; the product helpers label their own batch.
28
+ * @returns whether the write reached a node
29
+ */
30
+ export declare function commitBlockChangeOutsidePanel(blockId: number, updates: PartialNodeConfig, products: RecommendationProduct[], description: string): boolean;
31
+ export {};
@@ -13,16 +13,20 @@
13
13
  */
14
14
  export declare const RECOMMENDATION_BLOCK_SELECTOR = ".recommendation-block-v2";
15
15
  export declare const RECOMMENDATION_PRODUCT_ROW_SELECTOR = ".recommendation-product-row";
16
- interface QueryableNode {
16
+ export interface QueryableNode {
17
17
  querySelector(selector: string): unknown;
18
18
  }
19
19
  export interface QueryableRoot {
20
20
  querySelectorAll(selector: string): Iterable<QueryableNode>;
21
21
  }
22
+ /**
23
+ * Live-vs-ghost discriminator for a single `.recommendation-block-v2` node.
24
+ * Single home for the (provisional) heuristic described above.
25
+ */
26
+ export declare function isLiveRecommendationBlock(block: QueryableNode): boolean;
22
27
  /**
23
28
  * Counts the live recommendation blocks reachable from `root`. Works on the
24
29
  * editor's `ImmutableHtmlNode` document root (the `onCreated` drop / duplicate
25
30
  * paths) and on any DOM-like root exposing `querySelectorAll`.
26
31
  */
27
32
  export declare function countLiveRecommendationBlocks(root: QueryableRoot): number;
28
- export {};
@@ -56,6 +56,9 @@ interface ButtonProps {
56
56
  name: string;
57
57
  label: string;
58
58
  id?: string;
59
+ className?: string;
60
+ icon?: string;
61
+ disabled?: boolean;
59
62
  }
60
63
  /**
61
64
  * Common control for all blocks which includes common UI Elements.
@@ -116,7 +119,7 @@ export declare abstract class CommonControl extends Control {
116
119
  icon?: string;
117
120
  }): string;
118
121
  _GuRadioButton({ name, buttons, id }: RadioButtonProps): string;
119
- _GuButton({ name, label, id }: ButtonProps): string;
122
+ _GuButton({ name, label, id, className, icon, disabled }: ButtonProps): string;
120
123
  _GuIcon({ src, className }: IconProps): string;
121
124
  /**
122
125
  *
@@ -0,0 +1,2 @@
1
+ declare const _default: import("msw").HttpHandler[];
2
+ export default _default;
@@ -1,6 +1,9 @@
1
- import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams } from '@@/Types/recommendation';
1
+ import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsStrategy } from '@@/Types/recommendation';
2
2
  export declare const useRecommendationApi: () => {
3
3
  fetchRecommendationCreateData: () => Promise<InitialResponse>;
4
4
  fetchRecommendationFilters: () => Promise<FiltersResponse>;
5
5
  fetchRecommendationProducts: (strategy: string, params: RecommendationProductsParams) => Promise<RecommendationProduct[]>;
6
+ fetchRecommendationProductsByUrl: (url: string) => Promise<RecommendationProduct[]>;
7
+ fetchRecommendationStrategies: () => Promise<RrsStrategy[]>;
8
+ generateStrategyEndpoint: (strategy: RrsStrategy, currency: string) => Promise<RrsEndpointGenerateResponse | null>;
6
9
  };