@useinsider/guido 3.17.0-beta.e6704da → 3.17.0-beta.ea65303

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 (75) hide show
  1. package/README.md +1 -1
  2. package/dist/@types/config/schemas.js +31 -35
  3. package/dist/components/Guido.vue.js +5 -5
  4. package/dist/components/Guido.vue2.js +77 -77
  5. package/dist/components/organisms/AutoSaveController.vue2.js +9 -8
  6. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  7. package/dist/components/organisms/header/EditorActions.vue2.js +74 -43
  8. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  9. package/dist/components/organisms/header/LeftSlot.vue2.js +16 -12
  10. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +20 -0
  11. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +48 -0
  12. package/dist/components/wrappers/WpDrawer.vue.js +9 -7
  13. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  14. package/dist/composables/useCustomInterfaceAppearance.js +16 -19
  15. package/dist/composables/useHtmlCompiler.js +37 -26
  16. package/dist/composables/useHtmlValidator.js +2 -0
  17. package/dist/composables/useRecommendation.js +34 -41
  18. package/dist/composables/useSave.js +84 -41
  19. package/dist/composables/useSaveValidation.js +279 -0
  20. package/dist/composables/useSaveValidationRollout.js +9 -0
  21. package/dist/composables/validators/useCouponBlockValidator.js +24 -21
  22. package/dist/composables/validators/useUnsubscribeBlockValidator.js +34 -27
  23. package/dist/config/migrator/recommendationMigrator.js +4 -6
  24. package/dist/enums/academy.js +1 -2
  25. package/dist/enums/date.js +3 -4
  26. package/dist/enums/extensions/recommendationBlock.js +23 -25
  27. package/dist/enums/save-validation.js +4 -0
  28. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +11 -13
  29. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +95 -96
  30. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +154 -156
  31. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +82 -223
  32. package/dist/extensions/Blocks/common-control.js +19 -22
  33. package/dist/guido.css +1 -1
  34. package/dist/services/recommendationApi.js +29 -78
  35. package/dist/src/@types/config/schemas.d.ts +4 -12
  36. package/dist/src/@types/save-validation.d.ts +19 -0
  37. package/dist/src/components/Guido.vue.d.ts +17 -1
  38. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +17 -1
  39. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +17 -1
  40. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +17 -1
  41. package/dist/src/components/organisms/{extensions/recommendation/AssignStrategyDrawer.vue.d.ts → validation/ValidationErrorDrawer.vue.d.ts} +0 -1
  42. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +4 -3
  43. package/dist/src/composables/useConfig.d.ts +2 -2
  44. package/dist/src/composables/useHtmlValidator.d.ts +21 -0
  45. package/dist/src/composables/useRecommendation.d.ts +0 -1
  46. package/dist/src/composables/useSave.d.ts +6 -1
  47. package/dist/src/composables/useSaveValidation.d.ts +6 -0
  48. package/dist/src/composables/useSaveValidationRollout.d.ts +3 -0
  49. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  50. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +10 -0
  51. package/dist/src/enums/academy.d.ts +0 -1
  52. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
  53. package/dist/src/enums/save-validation.d.ts +27 -0
  54. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -14
  55. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +15 -214
  56. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -6
  57. package/dist/src/extensions/Blocks/common-control.d.ts +1 -4
  58. package/dist/src/services/recommendationApi.d.ts +1 -4
  59. package/dist/src/stores/config.d.ts +30 -18
  60. package/dist/src/stores/save-validation.d.ts +22 -0
  61. package/dist/src/utils/templatePreparation.d.ts +30 -0
  62. package/dist/stores/config.js +39 -22
  63. package/dist/stores/save-validation.js +30 -0
  64. package/dist/utils/dateUtil.js +10 -23
  65. package/dist/utils/templatePreparation.js +50 -50
  66. package/package.json +1 -2
  67. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +0 -18
  68. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +0 -70
  69. package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue.js +0 -20
  70. package/dist/components/organisms/extensions/recommendation/StrategyInfoBox.vue2.js +0 -55
  71. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -141
  72. package/dist/src/components/organisms/extensions/recommendation/StrategyInfoBox.vue.d.ts +0 -24
  73. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -29
  74. package/dist/src/mock/api/recommendation-strategies.d.ts +0 -43
  75. package/dist/static/styles/components/recommendation-strategy.css.js +0 -171
@@ -1,4 +1,4 @@
1
- import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsStrategy } from '@@/Types/recommendation';
1
+ import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationProduct } from '@@/Types/recommendation';
2
2
  export interface PerBlockConfigs {
3
3
  cardsInRow: number;
4
4
  currencySettings: {
@@ -21,8 +21,6 @@ export interface PerBlockConfigs {
21
21
  sendProductRequestFlag: boolean;
22
22
  shuffleProducts: boolean;
23
23
  strategy: string;
24
- /** Assigned RRS id ('' = none) — mirrors RecommendationNodeConfig.strategyId (SD-149105) */
25
- strategyId: string;
26
24
  textTrimming: boolean;
27
25
  unresponsive: boolean;
28
26
  size: string;
@@ -35,8 +33,6 @@ interface PerBlockState {
35
33
  recommendationProducts: RecommendationProduct[];
36
34
  filterStatus: boolean;
37
35
  filterSelectionDrawerStatus: boolean;
38
- /** Assign Recommendation Strategy drawer visibility (SD-149105) */
39
- assignStrategyDrawerStatus: boolean;
40
36
  filterGroup: number;
41
37
  /** Whether initial API data (filters, algorithms, products) has been fetched for this block */
42
38
  isInitialized: boolean;
@@ -51,7 +47,6 @@ interface PerBlockState {
51
47
  */
52
48
  export interface PerBlockUrlConfig {
53
49
  strategy: string;
54
- strategyId: string;
55
50
  language: string;
56
51
  size: string;
57
52
  productIds: string[];
@@ -64,14 +59,11 @@ export interface PerBlockUrlConfig {
64
59
  currencyThousandSeparator: string;
65
60
  }
66
61
  interface StoreState {
67
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
62
+ recommendationCampaignUrls: Record<string, string>;
68
63
  activePredictiveAlgorithms: number[];
69
64
  languages: Languages;
70
65
  currencyList: Currency[];
71
66
  filterList: FiltersResponse;
72
- strategies: RrsStrategy[];
73
- strategiesLoading: boolean;
74
- strategyUrlTemplates: Record<string, string>;
75
67
  blockStates: Record<number, PerBlockState>;
76
68
  currentRecommendationId: number | null;
77
69
  configVersion: number;
@@ -82,7 +74,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
82
74
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
83
75
  */
84
76
  recommendationConfigs(state: {
85
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
77
+ recommendationCampaignUrls: Record<string, string>;
86
78
  activePredictiveAlgorithms: number[];
87
79
  languages: Languages;
88
80
  currencyList: {
@@ -90,16 +82,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
90
82
  value: string;
91
83
  }[];
92
84
  filterList: FiltersResponse;
93
- strategies: {
94
- [x: string]: unknown;
95
- strategy_id: number;
96
- name: string;
97
- status: string;
98
- suitable_channels: string;
99
- size?: (number | string) | undefined;
100
- }[];
101
- strategiesLoading: boolean;
102
- strategyUrlTemplates: Record<string, string>;
103
85
  blockStates: Record<number, PerBlockState>;
104
86
  currentRecommendationId: number | null;
105
87
  configVersion: number;
@@ -108,7 +90,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
108
90
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
109
91
  */
110
92
  recommendationProducts(state: {
111
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
93
+ recommendationCampaignUrls: Record<string, string>;
112
94
  activePredictiveAlgorithms: number[];
113
95
  languages: Languages;
114
96
  currencyList: {
@@ -116,16 +98,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
116
98
  value: string;
117
99
  }[];
118
100
  filterList: FiltersResponse;
119
- strategies: {
120
- [x: string]: unknown;
121
- strategy_id: number;
122
- name: string;
123
- status: string;
124
- suitable_channels: string;
125
- size?: (number | string) | undefined;
126
- }[];
127
- strategiesLoading: boolean;
128
- strategyUrlTemplates: Record<string, string>;
129
101
  blockStates: Record<number, PerBlockState>;
130
102
  currentRecommendationId: number | null;
131
103
  configVersion: number;
@@ -134,7 +106,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
134
106
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterSelectionDrawerStatus
135
107
  */
136
108
  filterSelectionDrawerStatus(state: {
137
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
109
+ recommendationCampaignUrls: Record<string, string>;
138
110
  activePredictiveAlgorithms: number[];
139
111
  languages: Languages;
140
112
  currencyList: {
@@ -142,78 +114,15 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
142
114
  value: string;
143
115
  }[];
144
116
  filterList: FiltersResponse;
145
- strategies: {
146
- [x: string]: unknown;
147
- strategy_id: number;
148
- name: string;
149
- status: string;
150
- suitable_channels: string;
151
- size?: (number | string) | undefined;
152
- }[];
153
- strategiesLoading: boolean;
154
- strategyUrlTemplates: Record<string, string>;
155
117
  blockStates: Record<number, PerBlockState>;
156
118
  currentRecommendationId: number | null;
157
119
  configVersion: number;
158
120
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
159
- /**
160
- * Proxy getter: delegates to blockStates[currentRecommendationId].assignStrategyDrawerStatus
161
- */
162
- assignStrategyDrawerStatus(state: {
163
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
164
- activePredictiveAlgorithms: number[];
165
- languages: Languages;
166
- currencyList: {
167
- text: string;
168
- value: string;
169
- }[];
170
- filterList: FiltersResponse;
171
- strategies: {
172
- [x: string]: unknown;
173
- strategy_id: number;
174
- name: string;
175
- status: string;
176
- suitable_channels: string;
177
- size?: (number | string) | undefined;
178
- }[];
179
- strategiesLoading: boolean;
180
- strategyUrlTemplates: Record<string, string>;
181
- blockStates: Record<number, PerBlockState>;
182
- currentRecommendationId: number | null;
183
- configVersion: number;
184
- } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
185
- /**
186
- * The current block's assigned strategy record from the listing,
187
- * or null when nothing is assigned / the strategy is no longer listed.
188
- */
189
- assignedStrategy(state: {
190
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
191
- activePredictiveAlgorithms: number[];
192
- languages: Languages;
193
- currencyList: {
194
- text: string;
195
- value: string;
196
- }[];
197
- filterList: FiltersResponse;
198
- strategies: {
199
- [x: string]: unknown;
200
- strategy_id: number;
201
- name: string;
202
- status: string;
203
- suitable_channels: string;
204
- size?: (number | string) | undefined;
205
- }[];
206
- strategiesLoading: boolean;
207
- strategyUrlTemplates: Record<string, string>;
208
- blockStates: Record<number, PerBlockState>;
209
- currentRecommendationId: number | null;
210
- configVersion: number;
211
- } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
212
121
  /**
213
122
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
214
123
  */
215
124
  filterStatus(state: {
216
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
125
+ recommendationCampaignUrls: Record<string, string>;
217
126
  activePredictiveAlgorithms: number[];
218
127
  languages: Languages;
219
128
  currencyList: {
@@ -221,16 +130,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
221
130
  value: string;
222
131
  }[];
223
132
  filterList: FiltersResponse;
224
- strategies: {
225
- [x: string]: unknown;
226
- strategy_id: number;
227
- name: string;
228
- status: string;
229
- suitable_channels: string;
230
- size?: (number | string) | undefined;
231
- }[];
232
- strategiesLoading: boolean;
233
- strategyUrlTemplates: Record<string, string>;
234
133
  blockStates: Record<number, PerBlockState>;
235
134
  currentRecommendationId: number | null;
236
135
  configVersion: number;
@@ -239,7 +138,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
239
138
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterGroup
240
139
  */
241
140
  filterGroup(state: {
242
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
141
+ recommendationCampaignUrls: Record<string, string>;
243
142
  activePredictiveAlgorithms: number[];
244
143
  languages: Languages;
245
144
  currencyList: {
@@ -247,16 +146,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
247
146
  value: string;
248
147
  }[];
249
148
  filterList: FiltersResponse;
250
- strategies: {
251
- [x: string]: unknown;
252
- strategy_id: number;
253
- name: string;
254
- status: string;
255
- suitable_channels: string;
256
- size?: (number | string) | undefined;
257
- }[];
258
- strategiesLoading: boolean;
259
- strategyUrlTemplates: Record<string, string>;
260
149
  blockStates: Record<number, PerBlockState>;
261
150
  currentRecommendationId: number | null;
262
151
  configVersion: number;
@@ -266,7 +155,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
266
155
  getFilterGroupCount(): number;
267
156
  getUniqueFilterGroups(): number[];
268
157
  getActivePredictiveAlgorithms: (state: {
269
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
158
+ recommendationCampaignUrls: Record<string, string>;
270
159
  activePredictiveAlgorithms: number[];
271
160
  languages: Languages;
272
161
  currencyList: {
@@ -274,16 +163,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
274
163
  value: string;
275
164
  }[];
276
165
  filterList: FiltersResponse;
277
- strategies: {
278
- [x: string]: unknown;
279
- strategy_id: number;
280
- name: string;
281
- status: string;
282
- suitable_channels: string;
283
- size?: (number | string) | undefined;
284
- }[];
285
- strategiesLoading: boolean;
286
- strategyUrlTemplates: Record<string, string>;
287
166
  blockStates: Record<number, PerBlockState>;
288
167
  currentRecommendationId: number | null;
289
168
  configVersion: number;
@@ -292,7 +171,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
292
171
  value: string;
293
172
  }[];
294
173
  getLanguages: (state: {
295
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
174
+ recommendationCampaignUrls: Record<string, string>;
296
175
  activePredictiveAlgorithms: number[];
297
176
  languages: Languages;
298
177
  currencyList: {
@@ -300,16 +179,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
300
179
  value: string;
301
180
  }[];
302
181
  filterList: FiltersResponse;
303
- strategies: {
304
- [x: string]: unknown;
305
- strategy_id: number;
306
- name: string;
307
- status: string;
308
- suitable_channels: string;
309
- size?: (number | string) | undefined;
310
- }[];
311
- strategiesLoading: boolean;
312
- strategyUrlTemplates: Record<string, string>;
313
182
  blockStates: Record<number, PerBlockState>;
314
183
  currentRecommendationId: number | null;
315
184
  configVersion: number;
@@ -318,7 +187,7 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
318
187
  value: string;
319
188
  }[];
320
189
  getCurrencySymbolList: (state: {
321
- recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
190
+ recommendationCampaignUrls: Record<string, string>;
322
191
  activePredictiveAlgorithms: number[];
323
192
  languages: Languages;
324
193
  currencyList: {
@@ -326,16 +195,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
326
195
  value: string;
327
196
  }[];
328
197
  filterList: FiltersResponse;
329
- strategies: {
330
- [x: string]: unknown;
331
- strategy_id: number;
332
- name: string;
333
- status: string;
334
- suitable_channels: string;
335
- size?: (number | string) | undefined;
336
- }[];
337
- strategiesLoading: boolean;
338
- strategyUrlTemplates: Record<string, string>;
339
198
  blockStates: Record<number, PerBlockState>;
340
199
  currentRecommendationId: number | null;
341
200
  configVersion: number;
@@ -413,52 +272,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
413
272
  * to the snapshot taken when the drawer was opened.
414
273
  */
415
274
  cancelFilterDrawer(): void;
416
- /**
417
- * Opens the Assign Strategy drawer for the current block.
418
- * Selection state lives in the drawer component until Assign is
419
- * pressed, so closing without assigning needs no snapshot/revert.
420
- */
421
- openAssignStrategyDrawer(): void;
422
- closeAssignStrategyDrawer(): void;
423
- /**
424
- * Fetches the active + EMAIL strategy listing. Always fetches fresh
425
- * (dead-strategy detection and post-create refresh need freshness);
426
- * only concurrent in-flight calls share one request.
427
- */
428
- fetchStrategies(): Promise<void>;
429
- /**
430
- * Resolves a strategy's recommendation endpoint template via
431
- * endpoint-generate, cached per strategy id + revision. Failures throw
432
- * and are NOT cached, so the next attempt retries.
433
- *
434
- * The revision is part of the key because `full_path` bakes in the
435
- * algorithm path and `size=` as they were when it was generated, while
436
- * the listing is deliberately never cached — editing a strategy in the
437
- * panel and re-assigning it here would otherwise call a stale endpoint.
438
- *
439
- * A record with no revision is not cached at all: a `<id>:` key can
440
- * never change, so it would serve the stale template forever — exactly
441
- * what the revision is here to prevent.
442
- */
443
- resolveStrategyUrlTemplate(strategy: RrsStrategy): Promise<string>;
444
- /**
445
- * Assigns a strategy to the current block. The config write is
446
- * synchronous (before any await) so a block switch cannot misdirect
447
- * it; the configVersion bump persists it to node config and triggers
448
- * the product refetch via the coordinator control's subscription.
449
- */
450
- assignStrategy(strategy: RrsStrategy): void;
451
- /**
452
- * Clears the current block's strategy; it falls back to the per-block
453
- * algorithm settings.
454
- *
455
- * `size` goes back to the default rather than staying on the removed
456
- * strategy's count: the Number of Products control is hidden in RRS
457
- * mode (D2), so a block left on the strategy's count would have no UI
458
- * to correct it. The pre-assign count is not restored — that would
459
- * need a persisted snapshot field; tracked for a later phase.
460
- */
461
- removeStrategy(): void;
462
275
  fetchRecommendationCreateData(): Promise<void>;
463
276
  fetchRecommendationFilters(): Promise<void>;
464
277
  addFilterGroup(filterGroup: number): void;
@@ -473,24 +286,12 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
473
286
  * every block's recommendationConfigs across user edits.
474
287
  */
475
288
  hasInvalidBlock(): boolean;
476
- fetchRecommendationProducts(): Promise<void>;
477
- _doFetchProducts(): Promise<void>;
478
- /**
479
- * Fetches products for a strategy-backed block: listing lookup →
480
- * endpoint-generate template → fill {locale}/{currency}, drop
481
- * {user_id} (resolved at send time) → fetch. Any failure (dead
482
- * strategy, resolution error) falls back to placeholder products.
483
- */
484
- _doFetchStrategyProducts(blockId: number): Promise<void>;
485
289
  /**
486
- * Writes products to a block's state, padded/clipped to `size` so
487
- * in-place content updates (which compare DOM element count vs
488
- * products.length) succeed:
489
- * - API returned nothing → fill entirely with defaults
490
- * - fewer than requested → pad with dummies
491
- * - more than requested → clip, preventing the renderer from extending
492
- * its slot grid (which would reset migrator-applied styles).
290
+ * Per-instance counterpart to `hasInvalidBlock`: the ids of every block
291
+ * that fails required-field validation, one drawer row each (SD-147430).
493
292
  */
494
- _setBlockProducts(blockId: number, products: RecommendationProduct[], size: number): void;
293
+ invalidBlockIds(): string[];
294
+ fetchRecommendationProducts(): Promise<void>;
295
+ _doFetchProducts(): Promise<void>;
495
296
  }>;
496
297
  export {};
@@ -82,12 +82,6 @@ export interface RecommendationNodeConfig {
82
82
  * Uses existing Filter interface from recommendation types
83
83
  */
84
84
  filters: Filter[];
85
- /**
86
- * Assigned Reusable Recommendation Strategy id (SD-149105).
87
- * '' = no strategy assigned; block uses the per-block settings above.
88
- * When set, algorithm/size/filters/shuffle come from the strategy record.
89
- */
90
- strategyId: string;
91
85
  /**
92
86
  * Layout orientation
93
87
  * - 'grid': Products in a grid, attributes aligned across products
@@ -56,9 +56,6 @@ interface ButtonProps {
56
56
  name: string;
57
57
  label: string;
58
58
  id?: string;
59
- className?: string;
60
- icon?: string;
61
- disabled?: boolean;
62
59
  }
63
60
  /**
64
61
  * Common control for all blocks which includes common UI Elements.
@@ -119,7 +116,7 @@ export declare abstract class CommonControl extends Control {
119
116
  icon?: string;
120
117
  }): string;
121
118
  _GuRadioButton({ name, buttons, id }: RadioButtonProps): string;
122
- _GuButton({ name, label, id, className, icon, disabled }: ButtonProps): string;
119
+ _GuButton({ name, label, id }: ButtonProps): string;
123
120
  _GuIcon({ src, className }: IconProps): string;
124
121
  /**
125
122
  *
@@ -1,9 +1,6 @@
1
- import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsStrategy } from '@@/Types/recommendation';
1
+ import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams } 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) => Promise<RrsEndpointGenerateResponse>;
9
6
  };
@@ -104,7 +104,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
104
104
  autosave: boolean;
105
105
  allowlistEnabled: boolean;
106
106
  linkTrackingIds: boolean;
107
- reusableRecommendationStrategy: boolean;
107
+ allowSaveWithErrors: boolean;
108
108
  };
109
109
  blocks: {
110
110
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -245,7 +245,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
245
245
  autosave: boolean;
246
246
  allowlistEnabled: boolean;
247
247
  linkTrackingIds: boolean;
248
- reusableRecommendationStrategy: boolean;
248
+ allowSaveWithErrors: boolean;
249
249
  };
250
250
  blocks: {
251
251
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -386,7 +386,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
386
386
  autosave: boolean;
387
387
  allowlistEnabled: boolean;
388
388
  linkTrackingIds: boolean;
389
- reusableRecommendationStrategy: boolean;
389
+ allowSaveWithErrors: boolean;
390
390
  };
391
391
  blocks: {
392
392
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -527,7 +527,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
527
527
  autosave: boolean;
528
528
  allowlistEnabled: boolean;
529
529
  linkTrackingIds: boolean;
530
- reusableRecommendationStrategy: boolean;
530
+ allowSaveWithErrors: boolean;
531
531
  };
532
532
  blocks: {
533
533
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -668,7 +668,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
668
668
  autosave: boolean;
669
669
  allowlistEnabled: boolean;
670
670
  linkTrackingIds: boolean;
671
- reusableRecommendationStrategy: boolean;
671
+ allowSaveWithErrors: boolean;
672
672
  };
673
673
  blocks: {
674
674
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -809,7 +809,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
809
809
  autosave: boolean;
810
810
  allowlistEnabled: boolean;
811
811
  linkTrackingIds: boolean;
812
- reusableRecommendationStrategy: boolean;
812
+ allowSaveWithErrors: boolean;
813
813
  };
814
814
  blocks: {
815
815
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -950,7 +950,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
950
950
  autosave: boolean;
951
951
  allowlistEnabled: boolean;
952
952
  linkTrackingIds: boolean;
953
- reusableRecommendationStrategy: boolean;
953
+ allowSaveWithErrors: boolean;
954
954
  };
955
955
  blocks: {
956
956
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1091,7 +1091,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1091
1091
  autosave: boolean;
1092
1092
  allowlistEnabled: boolean;
1093
1093
  linkTrackingIds: boolean;
1094
- reusableRecommendationStrategy: boolean;
1094
+ allowSaveWithErrors: boolean;
1095
1095
  };
1096
1096
  blocks: {
1097
1097
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1232,7 +1232,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1232
1232
  autosave: boolean;
1233
1233
  allowlistEnabled: boolean;
1234
1234
  linkTrackingIds: boolean;
1235
- reusableRecommendationStrategy: boolean;
1235
+ allowSaveWithErrors: boolean;
1236
1236
  };
1237
1237
  blocks: {
1238
1238
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1373,7 +1373,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1373
1373
  autosave: boolean;
1374
1374
  allowlistEnabled: boolean;
1375
1375
  linkTrackingIds: boolean;
1376
- reusableRecommendationStrategy: boolean;
1376
+ allowSaveWithErrors: boolean;
1377
1377
  };
1378
1378
  blocks: {
1379
1379
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1514,7 +1514,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1514
1514
  autosave: boolean;
1515
1515
  allowlistEnabled: boolean;
1516
1516
  linkTrackingIds: boolean;
1517
- reusableRecommendationStrategy: boolean;
1517
+ allowSaveWithErrors: boolean;
1518
1518
  };
1519
1519
  blocks: {
1520
1520
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1655,7 +1655,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1655
1655
  autosave: boolean;
1656
1656
  allowlistEnabled: boolean;
1657
1657
  linkTrackingIds: boolean;
1658
- reusableRecommendationStrategy: boolean;
1658
+ allowSaveWithErrors: boolean;
1659
1659
  };
1660
1660
  blocks: {
1661
1661
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1796,7 +1796,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1796
1796
  autosave: boolean;
1797
1797
  allowlistEnabled: boolean;
1798
1798
  linkTrackingIds: boolean;
1799
- reusableRecommendationStrategy: boolean;
1799
+ allowSaveWithErrors: boolean;
1800
1800
  };
1801
1801
  blocks: {
1802
1802
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1937,7 +1937,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1937
1937
  autosave: boolean;
1938
1938
  allowlistEnabled: boolean;
1939
1939
  linkTrackingIds: boolean;
1940
- reusableRecommendationStrategy: boolean;
1940
+ allowSaveWithErrors: boolean;
1941
1941
  };
1942
1942
  blocks: {
1943
1943
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2078,7 +2078,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2078
2078
  autosave: boolean;
2079
2079
  allowlistEnabled: boolean;
2080
2080
  linkTrackingIds: boolean;
2081
- reusableRecommendationStrategy: boolean;
2081
+ allowSaveWithErrors: boolean;
2082
2082
  };
2083
2083
  blocks: {
2084
2084
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2121,6 +2121,18 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2121
2121
  };
2122
2122
  } | null;
2123
2123
  } & import("pinia").PiniaCustomStateProperties<ConfigStoreState>) => number;
2124
+ /**
2125
+ * Transactional campaigns keep the hard save block. Reactive getter, so
2126
+ * consumers stay safe in setup where a raw config read snapshots null (SD-147945).
2127
+ */
2128
+ isTransactional(): boolean;
2129
+ /**
2130
+ * Soft-save policy: may the editor persist a template with validation errors?
2131
+ * Default true (host sets features.allowSaveWithErrors=false for transactional +
2132
+ * unsub). Reactive getter defaulting true — reading via isFeatureEnabled would
2133
+ * floor to false pre-init and momentarily hide the soft-save option (SD-147430).
2134
+ */
2135
+ allowSaveWithErrors(): boolean;
2124
2136
  /**
2125
2137
  * Get the username
2126
2138
  */
@@ -2219,7 +2231,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2219
2231
  autosave: boolean;
2220
2232
  allowlistEnabled: boolean;
2221
2233
  linkTrackingIds: boolean;
2222
- reusableRecommendationStrategy: boolean;
2234
+ allowSaveWithErrors: boolean;
2223
2235
  };
2224
2236
  blocks: {
2225
2237
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2360,7 +2372,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2360
2372
  autosave: boolean;
2361
2373
  allowlistEnabled: boolean;
2362
2374
  linkTrackingIds: boolean;
2363
- reusableRecommendationStrategy: boolean;
2375
+ allowSaveWithErrors: boolean;
2364
2376
  };
2365
2377
  blocks: {
2366
2378
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2503,7 +2515,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2503
2515
  autosave: boolean;
2504
2516
  allowlistEnabled: boolean;
2505
2517
  linkTrackingIds: boolean;
2506
- reusableRecommendationStrategy: boolean;
2518
+ allowSaveWithErrors: boolean;
2507
2519
  };
2508
2520
  blocks: {
2509
2521
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -0,0 +1,22 @@
1
+ import type { SaveValidationError, SaveValidationIntent } from '@@/Types/save-validation';
2
+ interface SaveValidationState {
3
+ errors: SaveValidationError[];
4
+ isDrawerOpen: boolean;
5
+ intent: SaveValidationIntent | null;
6
+ }
7
+ export declare const useSaveValidationStore: import("pinia").StoreDefinition<"guidoSaveValidation", SaveValidationState, {
8
+ errorCount: (state: {
9
+ errors: {
10
+ rule: import("../enums/save-validation").SaveValidationRule;
11
+ message: string;
12
+ detail?: string | undefined;
13
+ type: import("../enums/toaster").ToasterTypeOptions;
14
+ }[];
15
+ isDrawerOpen: boolean;
16
+ intent: SaveValidationIntent | null;
17
+ } & import("pinia").PiniaCustomStateProperties<SaveValidationState>) => number;
18
+ }, {
19
+ open(errors: SaveValidationError[], intent: SaveValidationIntent): void;
20
+ close(): void;
21
+ }>;
22
+ export {};