@useinsider/guido 3.12.0-beta.cfe6433 → 3.12.0-beta.d77b0d2

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 (92) hide show
  1. package/dist/@types/config/schemas.js +9 -4
  2. package/dist/components/Guido.vue.js +6 -6
  3. package/dist/components/Guido.vue2.js +50 -49
  4. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  5. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  6. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  7. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  8. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +38 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +271 -0
  10. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +18 -0
  11. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +42 -0
  12. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +20 -0
  13. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +18 -0
  14. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +20 -0
  15. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +60 -0
  16. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +19 -0
  17. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +19 -0
  18. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +22 -0
  19. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +29 -0
  20. package/dist/composables/useHtmlValidator.js +68 -60
  21. package/dist/composables/useHttp.js +61 -52
  22. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  23. package/dist/composables/useRecommendation.js +56 -40
  24. package/dist/composables/useRecommendationPreview.js +61 -60
  25. package/dist/composables/useSave.js +22 -22
  26. package/dist/composables/useStrategyFilters.js +16 -0
  27. package/dist/config/migrator/recommendationMigrator.js +7 -4
  28. package/dist/enums/date.js +4 -3
  29. package/dist/enums/extensions/filteringV2.js +1024 -0
  30. package/dist/enums/extensions/recommendationBlock.js +45 -24
  31. package/dist/enums/extensions/strategyDetail.js +149 -0
  32. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  33. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
  34. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +141 -123
  36. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +297 -0
  37. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  38. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +16 -2
  39. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +137 -0
  40. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  41. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +549 -165
  42. package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
  43. package/dist/extensions/Blocks/Recommendation/utils/strategyNavigation.js +8 -0
  44. package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +95 -0
  45. package/dist/extensions/Blocks/Recommendation/utils/strategyUrl.js +43 -0
  46. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -10
  47. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  48. package/dist/extensions/Blocks/common-control.js +37 -35
  49. package/dist/extensions/Blocks/controlFactories.js +125 -75
  50. package/dist/guido.css +1 -1
  51. package/dist/services/recommendationApi.js +127 -33
  52. package/dist/services/stripoApi.js +18 -18
  53. package/dist/src/@types/config/schemas.d.ts +10 -0
  54. package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +2 -0
  55. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +43 -0
  56. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +29 -0
  57. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +40 -0
  58. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +38 -0
  59. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +51 -0
  60. package/dist/src/composables/useConfig.d.ts +2 -0
  61. package/dist/src/composables/useHtmlValidator.d.ts +2 -0
  62. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  63. package/dist/src/composables/useRecommendation.d.ts +2 -0
  64. package/dist/src/composables/useStrategyFilters.d.ts +24 -0
  65. package/dist/src/enums/extensions/filteringV2.d.ts +72 -0
  66. package/dist/src/enums/extensions/recommendationBlock.d.ts +33 -0
  67. package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
  68. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  69. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  70. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  71. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +10 -4
  72. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +118 -0
  73. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +958 -1
  74. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  75. package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +50 -0
  76. package/dist/src/extensions/Blocks/Recommendation/utils/strategyNavigation.d.ts +10 -0
  77. package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
  78. package/dist/src/extensions/Blocks/Recommendation/utils/strategyUrl.d.ts +51 -0
  79. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +8 -1
  80. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  81. package/dist/src/extensions/Blocks/common-control.d.ts +5 -2
  82. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  83. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  84. package/dist/src/services/recommendationApi.d.ts +9 -1
  85. package/dist/src/stores/config.d.ts +18 -0
  86. package/dist/src/utils/genericUtil.d.ts +9 -0
  87. package/dist/src/utils/urlSchemes.d.ts +6 -0
  88. package/dist/utils/dateUtil.js +23 -10
  89. package/dist/utils/genericUtil.js +10 -1
  90. package/dist/utils/templatePreparation.js +70 -57
  91. package/dist/utils/urlSchemes.js +4 -0
  92. package/package.json +1 -1
@@ -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, RecommendationProduct, RrsCampaign, RrsStrategy } from '@@/Types/recommendation';
2
2
  export interface PerBlockConfigs {
3
3
  cardsInRow: number;
4
4
  currencySettings: {
@@ -21,6 +21,8 @@ export interface PerBlockConfigs {
21
21
  sendProductRequestFlag: boolean;
22
22
  shuffleProducts: boolean;
23
23
  strategy: string;
24
+ /** RRS strategy id; empty string when no strategy is assigned */
25
+ strategyId: string;
24
26
  textTrimming: boolean;
25
27
  unresponsive: boolean;
26
28
  size: string;
@@ -33,6 +35,16 @@ interface PerBlockState {
33
35
  recommendationProducts: RecommendationProduct[];
34
36
  filterStatus: boolean;
35
37
  filterSelectionDrawerStatus: boolean;
38
+ /** Whether the RRS detail drawer is open for this block */
39
+ strategyDetailDrawerStatus: boolean;
40
+ /**
41
+ * Which strategy the drawer is describing, when that is not the assigned one.
42
+ *
43
+ * View More opens the drawer straight off a hovered option, and reading the
44
+ * details of a strategy must not assign it — the marketer is still choosing.
45
+ * Empty means "whatever this block has assigned", which is the gear's case.
46
+ */
47
+ strategyDetailId: string;
36
48
  filterGroup: number;
37
49
  /** Whether initial API data (filters, algorithms, products) has been fetched for this block */
38
50
  isInitialized: boolean;
@@ -47,6 +59,8 @@ interface PerBlockState {
47
59
  */
48
60
  export interface PerBlockUrlConfig {
49
61
  strategy: string;
62
+ /** RRS strategy id; empty string when the block still uses an algorithm. */
63
+ strategyId: string;
50
64
  language: string;
51
65
  size: string;
52
66
  productIds: string[];
@@ -64,6 +78,40 @@ interface StoreState {
64
78
  languages: Languages;
65
79
  currencyList: Currency[];
66
80
  filterList: FiltersResponse;
81
+ /** Reusable Recommendation Strategies available to the EMAIL channel */
82
+ strategies: RrsStrategy[];
83
+ /** True while the strategy listing is in flight, so the panel can show a loading state */
84
+ strategiesLoading: boolean;
85
+ /** Campaigns using the strategy currently shown in the detail drawer */
86
+ strategyCampaigns: RrsCampaign[];
87
+ /** True while the campaign list is in flight */
88
+ strategyCampaignsLoading: boolean;
89
+ /** Strategy id `strategyCampaigns` was loaded for; null when nothing is loaded */
90
+ strategyCampaignsFetchedFor: string | null;
91
+ /**
92
+ * Resolved recommendation-URL template per strategy id, with placeholders still
93
+ * unsubstituted. `buildCampaignUrl` is synchronous, so the template has to be
94
+ * cached here before it runs — an empty string records "asked, but the strategy
95
+ * has no usable URL", which stops a broken id being retried on every compile.
96
+ */
97
+ strategyUrlTemplates: Record<string, string>;
98
+ /**
99
+ * Whether the last listing fetch failed.
100
+ *
101
+ * Without it a transport failure is indistinguishable from "this partner has
102
+ * no strategies", and the feed-URL resolver would cache that as a settled
103
+ * "strategy has no URL" for the whole session.
104
+ */
105
+ strategiesLoadFailed: boolean;
106
+ /**
107
+ * Whether a listing fetch has ever settled.
108
+ *
109
+ * Distinguishes "not asked yet" from "asked, and the answer was empty" — the
110
+ * deleted-strategy gate must stay silent for the first and fire for the second.
111
+ */
112
+ strategiesLoaded: boolean;
113
+ /** True while a Duplicate-and-Assign round trip is in flight. */
114
+ strategyDuplicating: boolean;
67
115
  blockStates: Record<number, PerBlockState>;
68
116
  currentRecommendationId: number | null;
69
117
  configVersion: number;
@@ -82,6 +130,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
82
130
  value: string;
83
131
  }[];
84
132
  filterList: FiltersResponse;
133
+ strategies: {
134
+ strategy_id: number;
135
+ name: string;
136
+ algorithm: string;
137
+ status: string;
138
+ size: number;
139
+ suitable_channels: string;
140
+ updated_at: string;
141
+ algorithm_used?: string | undefined;
142
+ exclude_view?: (boolean | number) | undefined;
143
+ exclude_purchase?: (boolean | number) | undefined;
144
+ exclude_cart?: (boolean | number) | undefined;
145
+ filters?: string | undefined;
146
+ manual_merchandising_products?: string | undefined;
147
+ mixed_strategies?: string | undefined;
148
+ suitable_page_types?: (string | string[]) | undefined;
149
+ base_product?: string | undefined;
150
+ checkout_recommendation_cart_value?: (number | string) | undefined;
151
+ shuffle?: (boolean | number) | undefined;
152
+ attribute_affinity?: (boolean | number) | undefined;
153
+ is_user_context_filter_optional?: (boolean | number) | undefined;
154
+ last_updated_by?: string | undefined;
155
+ created_at?: string | undefined;
156
+ exclude_view_option?: string | undefined;
157
+ exclude_view_duration?: number | undefined;
158
+ exclude_view_duration_type?: string | undefined;
159
+ exclude_view_item_count?: number | undefined;
160
+ exclude_purchase_option?: string | undefined;
161
+ exclude_purchase_duration?: number | undefined;
162
+ exclude_purchase_duration_type?: string | undefined;
163
+ exclude_purchase_item_count?: number | undefined;
164
+ campaignCount?: {
165
+ active?: number | undefined;
166
+ passive?: number | undefined;
167
+ test?: number | undefined;
168
+ } | undefined;
169
+ }[];
170
+ strategiesLoading: boolean;
171
+ strategyCampaigns: {
172
+ id: string | number;
173
+ name: string;
174
+ status: string;
175
+ variants: {
176
+ id?: (number | string) | undefined;
177
+ name: string;
178
+ }[];
179
+ channel: string;
180
+ productAlias?: string | undefined;
181
+ isPreventing?: boolean | undefined;
182
+ }[];
183
+ strategyCampaignsLoading: boolean;
184
+ strategyCampaignsFetchedFor: string | null;
185
+ strategyUrlTemplates: Record<string, string>;
186
+ strategiesLoadFailed: boolean;
187
+ strategiesLoaded: boolean;
188
+ strategyDuplicating: boolean;
85
189
  blockStates: Record<number, PerBlockState>;
86
190
  currentRecommendationId: number | null;
87
191
  configVersion: number;
@@ -98,6 +202,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
98
202
  value: string;
99
203
  }[];
100
204
  filterList: FiltersResponse;
205
+ strategies: {
206
+ strategy_id: number;
207
+ name: string;
208
+ algorithm: string;
209
+ status: string;
210
+ size: number;
211
+ suitable_channels: string;
212
+ updated_at: string;
213
+ algorithm_used?: string | undefined;
214
+ exclude_view?: (boolean | number) | undefined;
215
+ exclude_purchase?: (boolean | number) | undefined;
216
+ exclude_cart?: (boolean | number) | undefined;
217
+ filters?: string | undefined;
218
+ manual_merchandising_products?: string | undefined;
219
+ mixed_strategies?: string | undefined;
220
+ suitable_page_types?: (string | string[]) | undefined;
221
+ base_product?: string | undefined;
222
+ checkout_recommendation_cart_value?: (number | string) | undefined;
223
+ shuffle?: (boolean | number) | undefined;
224
+ attribute_affinity?: (boolean | number) | undefined;
225
+ is_user_context_filter_optional?: (boolean | number) | undefined;
226
+ last_updated_by?: string | undefined;
227
+ created_at?: string | undefined;
228
+ exclude_view_option?: string | undefined;
229
+ exclude_view_duration?: number | undefined;
230
+ exclude_view_duration_type?: string | undefined;
231
+ exclude_view_item_count?: number | undefined;
232
+ exclude_purchase_option?: string | undefined;
233
+ exclude_purchase_duration?: number | undefined;
234
+ exclude_purchase_duration_type?: string | undefined;
235
+ exclude_purchase_item_count?: number | undefined;
236
+ campaignCount?: {
237
+ active?: number | undefined;
238
+ passive?: number | undefined;
239
+ test?: number | undefined;
240
+ } | undefined;
241
+ }[];
242
+ strategiesLoading: boolean;
243
+ strategyCampaigns: {
244
+ id: string | number;
245
+ name: string;
246
+ status: string;
247
+ variants: {
248
+ id?: (number | string) | undefined;
249
+ name: string;
250
+ }[];
251
+ channel: string;
252
+ productAlias?: string | undefined;
253
+ isPreventing?: boolean | undefined;
254
+ }[];
255
+ strategyCampaignsLoading: boolean;
256
+ strategyCampaignsFetchedFor: string | null;
257
+ strategyUrlTemplates: Record<string, string>;
258
+ strategiesLoadFailed: boolean;
259
+ strategiesLoaded: boolean;
260
+ strategyDuplicating: boolean;
101
261
  blockStates: Record<number, PerBlockState>;
102
262
  currentRecommendationId: number | null;
103
263
  configVersion: number;
@@ -114,10 +274,147 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
114
274
  value: string;
115
275
  }[];
116
276
  filterList: FiltersResponse;
277
+ strategies: {
278
+ strategy_id: number;
279
+ name: string;
280
+ algorithm: string;
281
+ status: string;
282
+ size: number;
283
+ suitable_channels: string;
284
+ updated_at: string;
285
+ algorithm_used?: string | undefined;
286
+ exclude_view?: (boolean | number) | undefined;
287
+ exclude_purchase?: (boolean | number) | undefined;
288
+ exclude_cart?: (boolean | number) | undefined;
289
+ filters?: string | undefined;
290
+ manual_merchandising_products?: string | undefined;
291
+ mixed_strategies?: string | undefined;
292
+ suitable_page_types?: (string | string[]) | undefined;
293
+ base_product?: string | undefined;
294
+ checkout_recommendation_cart_value?: (number | string) | undefined;
295
+ shuffle?: (boolean | number) | undefined;
296
+ attribute_affinity?: (boolean | number) | undefined;
297
+ is_user_context_filter_optional?: (boolean | number) | undefined;
298
+ last_updated_by?: string | undefined;
299
+ created_at?: string | undefined;
300
+ exclude_view_option?: string | undefined;
301
+ exclude_view_duration?: number | undefined;
302
+ exclude_view_duration_type?: string | undefined;
303
+ exclude_view_item_count?: number | undefined;
304
+ exclude_purchase_option?: string | undefined;
305
+ exclude_purchase_duration?: number | undefined;
306
+ exclude_purchase_duration_type?: string | undefined;
307
+ exclude_purchase_item_count?: number | undefined;
308
+ campaignCount?: {
309
+ active?: number | undefined;
310
+ passive?: number | undefined;
311
+ test?: number | undefined;
312
+ } | undefined;
313
+ }[];
314
+ strategiesLoading: boolean;
315
+ strategyCampaigns: {
316
+ id: string | number;
317
+ name: string;
318
+ status: string;
319
+ variants: {
320
+ id?: (number | string) | undefined;
321
+ name: string;
322
+ }[];
323
+ channel: string;
324
+ productAlias?: string | undefined;
325
+ isPreventing?: boolean | undefined;
326
+ }[];
327
+ strategyCampaignsLoading: boolean;
328
+ strategyCampaignsFetchedFor: string | null;
329
+ strategyUrlTemplates: Record<string, string>;
330
+ strategiesLoadFailed: boolean;
331
+ strategiesLoaded: boolean;
332
+ strategyDuplicating: boolean;
333
+ blockStates: Record<number, PerBlockState>;
334
+ currentRecommendationId: number | null;
335
+ configVersion: number;
336
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
337
+ /**
338
+ * Proxy getter: delegates to blockStates[currentRecommendationId].strategyDetailDrawerStatus
339
+ */
340
+ strategyDetailDrawerStatus(state: {
341
+ recommendationCampaignUrls: Record<string, string>;
342
+ activePredictiveAlgorithms: number[];
343
+ languages: Languages;
344
+ currencyList: {
345
+ text: string;
346
+ value: string;
347
+ }[];
348
+ filterList: FiltersResponse;
349
+ strategies: {
350
+ strategy_id: number;
351
+ name: string;
352
+ algorithm: string;
353
+ status: string;
354
+ size: number;
355
+ suitable_channels: string;
356
+ updated_at: string;
357
+ algorithm_used?: string | undefined;
358
+ exclude_view?: (boolean | number) | undefined;
359
+ exclude_purchase?: (boolean | number) | undefined;
360
+ exclude_cart?: (boolean | number) | undefined;
361
+ filters?: string | undefined;
362
+ manual_merchandising_products?: string | undefined;
363
+ mixed_strategies?: string | undefined;
364
+ suitable_page_types?: (string | string[]) | undefined;
365
+ base_product?: string | undefined;
366
+ checkout_recommendation_cart_value?: (number | string) | undefined;
367
+ shuffle?: (boolean | number) | undefined;
368
+ attribute_affinity?: (boolean | number) | undefined;
369
+ is_user_context_filter_optional?: (boolean | number) | undefined;
370
+ last_updated_by?: string | undefined;
371
+ created_at?: string | undefined;
372
+ exclude_view_option?: string | undefined;
373
+ exclude_view_duration?: number | undefined;
374
+ exclude_view_duration_type?: string | undefined;
375
+ exclude_view_item_count?: number | undefined;
376
+ exclude_purchase_option?: string | undefined;
377
+ exclude_purchase_duration?: number | undefined;
378
+ exclude_purchase_duration_type?: string | undefined;
379
+ exclude_purchase_item_count?: number | undefined;
380
+ campaignCount?: {
381
+ active?: number | undefined;
382
+ passive?: number | undefined;
383
+ test?: number | undefined;
384
+ } | undefined;
385
+ }[];
386
+ strategiesLoading: boolean;
387
+ strategyCampaigns: {
388
+ id: string | number;
389
+ name: string;
390
+ status: string;
391
+ variants: {
392
+ id?: (number | string) | undefined;
393
+ name: string;
394
+ }[];
395
+ channel: string;
396
+ productAlias?: string | undefined;
397
+ isPreventing?: boolean | undefined;
398
+ }[];
399
+ strategyCampaignsLoading: boolean;
400
+ strategyCampaignsFetchedFor: string | null;
401
+ strategyUrlTemplates: Record<string, string>;
402
+ strategiesLoadFailed: boolean;
403
+ strategiesLoaded: boolean;
404
+ strategyDuplicating: boolean;
117
405
  blockStates: Record<number, PerBlockState>;
118
406
  currentRecommendationId: number | null;
119
407
  configVersion: number;
120
408
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
409
+ /**
410
+ * The strategy the detail drawer is describing.
411
+ *
412
+ * Usually the assigned one (the gear opens the drawer for the block), but
413
+ * View More opens it for a strategy the marketer is only inspecting — so an
414
+ * explicit id wins. An id that is no longer in the listing falls back to the
415
+ * assigned strategy rather than showing an empty drawer.
416
+ */
417
+ getDrawerStrategy(): RrsStrategy | null;
121
418
  /**
122
419
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
123
420
  */
@@ -130,6 +427,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
130
427
  value: string;
131
428
  }[];
132
429
  filterList: FiltersResponse;
430
+ strategies: {
431
+ strategy_id: number;
432
+ name: string;
433
+ algorithm: string;
434
+ status: string;
435
+ size: number;
436
+ suitable_channels: string;
437
+ updated_at: string;
438
+ algorithm_used?: string | undefined;
439
+ exclude_view?: (boolean | number) | undefined;
440
+ exclude_purchase?: (boolean | number) | undefined;
441
+ exclude_cart?: (boolean | number) | undefined;
442
+ filters?: string | undefined;
443
+ manual_merchandising_products?: string | undefined;
444
+ mixed_strategies?: string | undefined;
445
+ suitable_page_types?: (string | string[]) | undefined;
446
+ base_product?: string | undefined;
447
+ checkout_recommendation_cart_value?: (number | string) | undefined;
448
+ shuffle?: (boolean | number) | undefined;
449
+ attribute_affinity?: (boolean | number) | undefined;
450
+ is_user_context_filter_optional?: (boolean | number) | undefined;
451
+ last_updated_by?: string | undefined;
452
+ created_at?: string | undefined;
453
+ exclude_view_option?: string | undefined;
454
+ exclude_view_duration?: number | undefined;
455
+ exclude_view_duration_type?: string | undefined;
456
+ exclude_view_item_count?: number | undefined;
457
+ exclude_purchase_option?: string | undefined;
458
+ exclude_purchase_duration?: number | undefined;
459
+ exclude_purchase_duration_type?: string | undefined;
460
+ exclude_purchase_item_count?: number | undefined;
461
+ campaignCount?: {
462
+ active?: number | undefined;
463
+ passive?: number | undefined;
464
+ test?: number | undefined;
465
+ } | undefined;
466
+ }[];
467
+ strategiesLoading: boolean;
468
+ strategyCampaigns: {
469
+ id: string | number;
470
+ name: string;
471
+ status: string;
472
+ variants: {
473
+ id?: (number | string) | undefined;
474
+ name: string;
475
+ }[];
476
+ channel: string;
477
+ productAlias?: string | undefined;
478
+ isPreventing?: boolean | undefined;
479
+ }[];
480
+ strategyCampaignsLoading: boolean;
481
+ strategyCampaignsFetchedFor: string | null;
482
+ strategyUrlTemplates: Record<string, string>;
483
+ strategiesLoadFailed: boolean;
484
+ strategiesLoaded: boolean;
485
+ strategyDuplicating: boolean;
133
486
  blockStates: Record<number, PerBlockState>;
134
487
  currentRecommendationId: number | null;
135
488
  configVersion: number;
@@ -146,6 +499,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
146
499
  value: string;
147
500
  }[];
148
501
  filterList: FiltersResponse;
502
+ strategies: {
503
+ strategy_id: number;
504
+ name: string;
505
+ algorithm: string;
506
+ status: string;
507
+ size: number;
508
+ suitable_channels: string;
509
+ updated_at: string;
510
+ algorithm_used?: string | undefined;
511
+ exclude_view?: (boolean | number) | undefined;
512
+ exclude_purchase?: (boolean | number) | undefined;
513
+ exclude_cart?: (boolean | number) | undefined;
514
+ filters?: string | undefined;
515
+ manual_merchandising_products?: string | undefined;
516
+ mixed_strategies?: string | undefined;
517
+ suitable_page_types?: (string | string[]) | undefined;
518
+ base_product?: string | undefined;
519
+ checkout_recommendation_cart_value?: (number | string) | undefined;
520
+ shuffle?: (boolean | number) | undefined;
521
+ attribute_affinity?: (boolean | number) | undefined;
522
+ is_user_context_filter_optional?: (boolean | number) | undefined;
523
+ last_updated_by?: string | undefined;
524
+ created_at?: string | undefined;
525
+ exclude_view_option?: string | undefined;
526
+ exclude_view_duration?: number | undefined;
527
+ exclude_view_duration_type?: string | undefined;
528
+ exclude_view_item_count?: number | undefined;
529
+ exclude_purchase_option?: string | undefined;
530
+ exclude_purchase_duration?: number | undefined;
531
+ exclude_purchase_duration_type?: string | undefined;
532
+ exclude_purchase_item_count?: number | undefined;
533
+ campaignCount?: {
534
+ active?: number | undefined;
535
+ passive?: number | undefined;
536
+ test?: number | undefined;
537
+ } | undefined;
538
+ }[];
539
+ strategiesLoading: boolean;
540
+ strategyCampaigns: {
541
+ id: string | number;
542
+ name: string;
543
+ status: string;
544
+ variants: {
545
+ id?: (number | string) | undefined;
546
+ name: string;
547
+ }[];
548
+ channel: string;
549
+ productAlias?: string | undefined;
550
+ isPreventing?: boolean | undefined;
551
+ }[];
552
+ strategyCampaignsLoading: boolean;
553
+ strategyCampaignsFetchedFor: string | null;
554
+ strategyUrlTemplates: Record<string, string>;
555
+ strategiesLoadFailed: boolean;
556
+ strategiesLoaded: boolean;
557
+ strategyDuplicating: boolean;
149
558
  blockStates: Record<number, PerBlockState>;
150
559
  currentRecommendationId: number | null;
151
560
  configVersion: number;
@@ -163,6 +572,149 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
163
572
  value: string;
164
573
  }[];
165
574
  filterList: FiltersResponse;
575
+ strategies: {
576
+ strategy_id: number;
577
+ name: string;
578
+ algorithm: string;
579
+ status: string;
580
+ size: number;
581
+ suitable_channels: string;
582
+ updated_at: string;
583
+ algorithm_used?: string | undefined;
584
+ exclude_view?: (boolean | number) | undefined;
585
+ exclude_purchase?: (boolean | number) | undefined;
586
+ exclude_cart?: (boolean | number) | undefined;
587
+ filters?: string | undefined;
588
+ manual_merchandising_products?: string | undefined;
589
+ mixed_strategies?: string | undefined;
590
+ suitable_page_types?: (string | string[]) | undefined;
591
+ base_product?: string | undefined;
592
+ checkout_recommendation_cart_value?: (number | string) | undefined;
593
+ shuffle?: (boolean | number) | undefined;
594
+ attribute_affinity?: (boolean | number) | undefined;
595
+ is_user_context_filter_optional?: (boolean | number) | undefined;
596
+ last_updated_by?: string | undefined;
597
+ created_at?: string | undefined;
598
+ exclude_view_option?: string | undefined;
599
+ exclude_view_duration?: number | undefined;
600
+ exclude_view_duration_type?: string | undefined;
601
+ exclude_view_item_count?: number | undefined;
602
+ exclude_purchase_option?: string | undefined;
603
+ exclude_purchase_duration?: number | undefined;
604
+ exclude_purchase_duration_type?: string | undefined;
605
+ exclude_purchase_item_count?: number | undefined;
606
+ campaignCount?: {
607
+ active?: number | undefined;
608
+ passive?: number | undefined;
609
+ test?: number | undefined;
610
+ } | undefined;
611
+ }[];
612
+ strategiesLoading: boolean;
613
+ strategyCampaigns: {
614
+ id: string | number;
615
+ name: string;
616
+ status: string;
617
+ variants: {
618
+ id?: (number | string) | undefined;
619
+ name: string;
620
+ }[];
621
+ channel: string;
622
+ productAlias?: string | undefined;
623
+ isPreventing?: boolean | undefined;
624
+ }[];
625
+ strategyCampaignsLoading: boolean;
626
+ strategyCampaignsFetchedFor: string | null;
627
+ strategyUrlTemplates: Record<string, string>;
628
+ strategiesLoadFailed: boolean;
629
+ strategiesLoaded: boolean;
630
+ strategyDuplicating: boolean;
631
+ blockStates: Record<number, PerBlockState>;
632
+ currentRecommendationId: number | null;
633
+ configVersion: number;
634
+ } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
635
+ text: string;
636
+ value: string;
637
+ }[];
638
+ /**
639
+ * Reusable Recommendation Strategies as dropdown options.
640
+ *
641
+ * Unlike algorithms, strategy ids come straight from Smart Recommender —
642
+ * there is no local id→key table to join against.
643
+ */
644
+ /**
645
+ * Options for the picker.
646
+ *
647
+ * A name shared by two strategies is disambiguated with its id. Smart
648
+ * Recommender does not enforce unique names, and an ambiguous label is a
649
+ * problem twice over: the marketer cannot tell the rows apart, and the hover
650
+ * card resolves a row back to a strategy by that very text — so it would
651
+ * describe the wrong one. Fixing the label fixes both.
652
+ */
653
+ getStrategyOptions: (state: {
654
+ recommendationCampaignUrls: Record<string, string>;
655
+ activePredictiveAlgorithms: number[];
656
+ languages: Languages;
657
+ currencyList: {
658
+ text: string;
659
+ value: string;
660
+ }[];
661
+ filterList: FiltersResponse;
662
+ strategies: {
663
+ strategy_id: number;
664
+ name: string;
665
+ algorithm: string;
666
+ status: string;
667
+ size: number;
668
+ suitable_channels: string;
669
+ updated_at: string;
670
+ algorithm_used?: string | undefined;
671
+ exclude_view?: (boolean | number) | undefined;
672
+ exclude_purchase?: (boolean | number) | undefined;
673
+ exclude_cart?: (boolean | number) | undefined;
674
+ filters?: string | undefined;
675
+ manual_merchandising_products?: string | undefined;
676
+ mixed_strategies?: string | undefined;
677
+ suitable_page_types?: (string | string[]) | undefined;
678
+ base_product?: string | undefined;
679
+ checkout_recommendation_cart_value?: (number | string) | undefined;
680
+ shuffle?: (boolean | number) | undefined;
681
+ attribute_affinity?: (boolean | number) | undefined;
682
+ is_user_context_filter_optional?: (boolean | number) | undefined;
683
+ last_updated_by?: string | undefined;
684
+ created_at?: string | undefined;
685
+ exclude_view_option?: string | undefined;
686
+ exclude_view_duration?: number | undefined;
687
+ exclude_view_duration_type?: string | undefined;
688
+ exclude_view_item_count?: number | undefined;
689
+ exclude_purchase_option?: string | undefined;
690
+ exclude_purchase_duration?: number | undefined;
691
+ exclude_purchase_duration_type?: string | undefined;
692
+ exclude_purchase_item_count?: number | undefined;
693
+ campaignCount?: {
694
+ active?: number | undefined;
695
+ passive?: number | undefined;
696
+ test?: number | undefined;
697
+ } | undefined;
698
+ }[];
699
+ strategiesLoading: boolean;
700
+ strategyCampaigns: {
701
+ id: string | number;
702
+ name: string;
703
+ status: string;
704
+ variants: {
705
+ id?: (number | string) | undefined;
706
+ name: string;
707
+ }[];
708
+ channel: string;
709
+ productAlias?: string | undefined;
710
+ isPreventing?: boolean | undefined;
711
+ }[];
712
+ strategyCampaignsLoading: boolean;
713
+ strategyCampaignsFetchedFor: string | null;
714
+ strategyUrlTemplates: Record<string, string>;
715
+ strategiesLoadFailed: boolean;
716
+ strategiesLoaded: boolean;
717
+ strategyDuplicating: boolean;
166
718
  blockStates: Record<number, PerBlockState>;
167
719
  currentRecommendationId: number | null;
168
720
  configVersion: number;
@@ -170,6 +722,178 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
170
722
  text: string;
171
723
  value: string;
172
724
  }[];
725
+ /**
726
+ * The current block's selected strategy, or null when none is selected
727
+ * or the selected id is no longer in the listing.
728
+ *
729
+ * A null return with a non-empty `strategyId` means the strategy was
730
+ * deleted in Smart Recommender after this block was configured — the
731
+ * panel flags that rather than silently clearing the selection.
732
+ */
733
+ getSelectedStrategy(): RrsStrategy | null;
734
+ /**
735
+ * Whether the RRS feature is enabled for this editor.
736
+ *
737
+ * Read through a getter so `hasInvalidBlock` can pass the store straight to
738
+ * the required-field descriptors, which need the flag to decide whether a
739
+ * missing strategy blocks the save.
740
+ */
741
+ isRrsEnabled(): boolean;
742
+ /** Strategy ids currently offered for email, for the save-time deleted-strategy check. */
743
+ strategyIds: (state: {
744
+ recommendationCampaignUrls: Record<string, string>;
745
+ activePredictiveAlgorithms: number[];
746
+ languages: Languages;
747
+ currencyList: {
748
+ text: string;
749
+ value: string;
750
+ }[];
751
+ filterList: FiltersResponse;
752
+ strategies: {
753
+ strategy_id: number;
754
+ name: string;
755
+ algorithm: string;
756
+ status: string;
757
+ size: number;
758
+ suitable_channels: string;
759
+ updated_at: string;
760
+ algorithm_used?: string | undefined;
761
+ exclude_view?: (boolean | number) | undefined;
762
+ exclude_purchase?: (boolean | number) | undefined;
763
+ exclude_cart?: (boolean | number) | undefined;
764
+ filters?: string | undefined;
765
+ manual_merchandising_products?: string | undefined;
766
+ mixed_strategies?: string | undefined;
767
+ suitable_page_types?: (string | string[]) | undefined;
768
+ base_product?: string | undefined;
769
+ checkout_recommendation_cart_value?: (number | string) | undefined;
770
+ shuffle?: (boolean | number) | undefined;
771
+ attribute_affinity?: (boolean | number) | undefined;
772
+ is_user_context_filter_optional?: (boolean | number) | undefined;
773
+ last_updated_by?: string | undefined;
774
+ created_at?: string | undefined;
775
+ exclude_view_option?: string | undefined;
776
+ exclude_view_duration?: number | undefined;
777
+ exclude_view_duration_type?: string | undefined;
778
+ exclude_view_item_count?: number | undefined;
779
+ exclude_purchase_option?: string | undefined;
780
+ exclude_purchase_duration?: number | undefined;
781
+ exclude_purchase_duration_type?: string | undefined;
782
+ exclude_purchase_item_count?: number | undefined;
783
+ campaignCount?: {
784
+ active?: number | undefined;
785
+ passive?: number | undefined;
786
+ test?: number | undefined;
787
+ } | undefined;
788
+ }[];
789
+ strategiesLoading: boolean;
790
+ strategyCampaigns: {
791
+ id: string | number;
792
+ name: string;
793
+ status: string;
794
+ variants: {
795
+ id?: (number | string) | undefined;
796
+ name: string;
797
+ }[];
798
+ channel: string;
799
+ productAlias?: string | undefined;
800
+ isPreventing?: boolean | undefined;
801
+ }[];
802
+ strategyCampaignsLoading: boolean;
803
+ strategyCampaignsFetchedFor: string | null;
804
+ strategyUrlTemplates: Record<string, string>;
805
+ strategiesLoadFailed: boolean;
806
+ strategiesLoaded: boolean;
807
+ strategyDuplicating: boolean;
808
+ blockStates: Record<number, PerBlockState>;
809
+ currentRecommendationId: number | null;
810
+ configVersion: number;
811
+ } & import("pinia").PiniaCustomStateProperties<StoreState>) => string[];
812
+ /**
813
+ * Whether the listing is trustworthy enough to judge an assigned id against.
814
+ *
815
+ * The bar is a settled, successful fetch — NOT a non-empty result. A partner
816
+ * whose EMAIL listing legitimately comes back empty (every strategy paused,
817
+ * none suitable for the channel) still makes an assigned id deleted, and
818
+ * keying on `strategies.length` silently disabled the save gate for exactly
819
+ * those partners.
820
+ */
821
+ canValidateStrategy: (state: {
822
+ recommendationCampaignUrls: Record<string, string>;
823
+ activePredictiveAlgorithms: number[];
824
+ languages: Languages;
825
+ currencyList: {
826
+ text: string;
827
+ value: string;
828
+ }[];
829
+ filterList: FiltersResponse;
830
+ strategies: {
831
+ strategy_id: number;
832
+ name: string;
833
+ algorithm: string;
834
+ status: string;
835
+ size: number;
836
+ suitable_channels: string;
837
+ updated_at: string;
838
+ algorithm_used?: string | undefined;
839
+ exclude_view?: (boolean | number) | undefined;
840
+ exclude_purchase?: (boolean | number) | undefined;
841
+ exclude_cart?: (boolean | number) | undefined;
842
+ filters?: string | undefined;
843
+ manual_merchandising_products?: string | undefined;
844
+ mixed_strategies?: string | undefined;
845
+ suitable_page_types?: (string | string[]) | undefined;
846
+ base_product?: string | undefined;
847
+ checkout_recommendation_cart_value?: (number | string) | undefined;
848
+ shuffle?: (boolean | number) | undefined;
849
+ attribute_affinity?: (boolean | number) | undefined;
850
+ is_user_context_filter_optional?: (boolean | number) | undefined;
851
+ last_updated_by?: string | undefined;
852
+ created_at?: string | undefined;
853
+ exclude_view_option?: string | undefined;
854
+ exclude_view_duration?: number | undefined;
855
+ exclude_view_duration_type?: string | undefined;
856
+ exclude_view_item_count?: number | undefined;
857
+ exclude_purchase_option?: string | undefined;
858
+ exclude_purchase_duration?: number | undefined;
859
+ exclude_purchase_duration_type?: string | undefined;
860
+ exclude_purchase_item_count?: number | undefined;
861
+ campaignCount?: {
862
+ active?: number | undefined;
863
+ passive?: number | undefined;
864
+ test?: number | undefined;
865
+ } | undefined;
866
+ }[];
867
+ strategiesLoading: boolean;
868
+ strategyCampaigns: {
869
+ id: string | number;
870
+ name: string;
871
+ status: string;
872
+ variants: {
873
+ id?: (number | string) | undefined;
874
+ name: string;
875
+ }[];
876
+ channel: string;
877
+ productAlias?: string | undefined;
878
+ isPreventing?: boolean | undefined;
879
+ }[];
880
+ strategyCampaignsLoading: boolean;
881
+ strategyCampaignsFetchedFor: string | null;
882
+ strategyUrlTemplates: Record<string, string>;
883
+ strategiesLoadFailed: boolean;
884
+ strategiesLoaded: boolean;
885
+ strategyDuplicating: boolean;
886
+ blockStates: Record<number, PerBlockState>;
887
+ currentRecommendationId: number | null;
888
+ configVersion: number;
889
+ } & import("pinia").PiniaCustomStateProperties<StoreState>) => boolean;
890
+ /**
891
+ * True when a strategy id is set but absent from the fetched listing.
892
+ *
893
+ * Shares `canValidateStrategy` so the panel warning and the save gate can
894
+ * never disagree about whether the listing can be judged.
895
+ */
896
+ hasMissingStrategy(): boolean;
173
897
  getLanguages: (state: {
174
898
  recommendationCampaignUrls: Record<string, string>;
175
899
  activePredictiveAlgorithms: number[];
@@ -179,6 +903,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
179
903
  value: string;
180
904
  }[];
181
905
  filterList: FiltersResponse;
906
+ strategies: {
907
+ strategy_id: number;
908
+ name: string;
909
+ algorithm: string;
910
+ status: string;
911
+ size: number;
912
+ suitable_channels: string;
913
+ updated_at: string;
914
+ algorithm_used?: string | undefined;
915
+ exclude_view?: (boolean | number) | undefined;
916
+ exclude_purchase?: (boolean | number) | undefined;
917
+ exclude_cart?: (boolean | number) | undefined;
918
+ filters?: string | undefined;
919
+ manual_merchandising_products?: string | undefined;
920
+ mixed_strategies?: string | undefined;
921
+ suitable_page_types?: (string | string[]) | undefined;
922
+ base_product?: string | undefined;
923
+ checkout_recommendation_cart_value?: (number | string) | undefined;
924
+ shuffle?: (boolean | number) | undefined;
925
+ attribute_affinity?: (boolean | number) | undefined;
926
+ is_user_context_filter_optional?: (boolean | number) | undefined;
927
+ last_updated_by?: string | undefined;
928
+ created_at?: string | undefined;
929
+ exclude_view_option?: string | undefined;
930
+ exclude_view_duration?: number | undefined;
931
+ exclude_view_duration_type?: string | undefined;
932
+ exclude_view_item_count?: number | undefined;
933
+ exclude_purchase_option?: string | undefined;
934
+ exclude_purchase_duration?: number | undefined;
935
+ exclude_purchase_duration_type?: string | undefined;
936
+ exclude_purchase_item_count?: number | undefined;
937
+ campaignCount?: {
938
+ active?: number | undefined;
939
+ passive?: number | undefined;
940
+ test?: number | undefined;
941
+ } | undefined;
942
+ }[];
943
+ strategiesLoading: boolean;
944
+ strategyCampaigns: {
945
+ id: string | number;
946
+ name: string;
947
+ status: string;
948
+ variants: {
949
+ id?: (number | string) | undefined;
950
+ name: string;
951
+ }[];
952
+ channel: string;
953
+ productAlias?: string | undefined;
954
+ isPreventing?: boolean | undefined;
955
+ }[];
956
+ strategyCampaignsLoading: boolean;
957
+ strategyCampaignsFetchedFor: string | null;
958
+ strategyUrlTemplates: Record<string, string>;
959
+ strategiesLoadFailed: boolean;
960
+ strategiesLoaded: boolean;
961
+ strategyDuplicating: boolean;
182
962
  blockStates: Record<number, PerBlockState>;
183
963
  currentRecommendationId: number | null;
184
964
  configVersion: number;
@@ -195,6 +975,62 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
195
975
  value: string;
196
976
  }[];
197
977
  filterList: FiltersResponse;
978
+ strategies: {
979
+ strategy_id: number;
980
+ name: string;
981
+ algorithm: string;
982
+ status: string;
983
+ size: number;
984
+ suitable_channels: string;
985
+ updated_at: string;
986
+ algorithm_used?: string | undefined;
987
+ exclude_view?: (boolean | number) | undefined;
988
+ exclude_purchase?: (boolean | number) | undefined;
989
+ exclude_cart?: (boolean | number) | undefined;
990
+ filters?: string | undefined;
991
+ manual_merchandising_products?: string | undefined;
992
+ mixed_strategies?: string | undefined;
993
+ suitable_page_types?: (string | string[]) | undefined;
994
+ base_product?: string | undefined;
995
+ checkout_recommendation_cart_value?: (number | string) | undefined;
996
+ shuffle?: (boolean | number) | undefined;
997
+ attribute_affinity?: (boolean | number) | undefined;
998
+ is_user_context_filter_optional?: (boolean | number) | undefined;
999
+ last_updated_by?: string | undefined;
1000
+ created_at?: string | undefined;
1001
+ exclude_view_option?: string | undefined;
1002
+ exclude_view_duration?: number | undefined;
1003
+ exclude_view_duration_type?: string | undefined;
1004
+ exclude_view_item_count?: number | undefined;
1005
+ exclude_purchase_option?: string | undefined;
1006
+ exclude_purchase_duration?: number | undefined;
1007
+ exclude_purchase_duration_type?: string | undefined;
1008
+ exclude_purchase_item_count?: number | undefined;
1009
+ campaignCount?: {
1010
+ active?: number | undefined;
1011
+ passive?: number | undefined;
1012
+ test?: number | undefined;
1013
+ } | undefined;
1014
+ }[];
1015
+ strategiesLoading: boolean;
1016
+ strategyCampaigns: {
1017
+ id: string | number;
1018
+ name: string;
1019
+ status: string;
1020
+ variants: {
1021
+ id?: (number | string) | undefined;
1022
+ name: string;
1023
+ }[];
1024
+ channel: string;
1025
+ productAlias?: string | undefined;
1026
+ isPreventing?: boolean | undefined;
1027
+ }[];
1028
+ strategyCampaignsLoading: boolean;
1029
+ strategyCampaignsFetchedFor: string | null;
1030
+ strategyUrlTemplates: Record<string, string>;
1031
+ strategiesLoadFailed: boolean;
1032
+ strategiesLoaded: boolean;
1033
+ strategyDuplicating: boolean;
198
1034
  blockStates: Record<number, PerBlockState>;
199
1035
  currentRecommendationId: number | null;
200
1036
  configVersion: number;
@@ -267,12 +1103,125 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
267
1103
  * Called after successful apply — discards the snapshot.
268
1104
  */
269
1105
  closeFilterDrawer(): void;
1106
+ /**
1107
+ * Find a strategy record by id, fetching the listing once if it is not loaded.
1108
+ *
1109
+ * The endpoint-generate call needs the record, and the save/hydrate path can
1110
+ * reach it on a template the marketer never clicked into — where no panel has
1111
+ * ever triggered the listing fetch.
1112
+ *
1113
+ * THROWS when the listing could not be loaded, rather than reporting "not
1114
+ * found". The caller caches a not-found as a settled "this strategy has no
1115
+ * URL"; doing that for a network blip would strand the block on its old
1116
+ * algorithm feed for the rest of the session while the panel still showed
1117
+ * the strategy as assigned. A throw leaves the cache key unset, so the next
1118
+ * selection or save tries again.
1119
+ */
1120
+ _resolveStrategyRecord(strategyId: string): Promise<RrsStrategy | null>;
1121
+ /**
1122
+ * Assign a strategy to the current block.
1123
+ *
1124
+ * Only patches Pinia: the `configVersion` bump makes the main control persist
1125
+ * `strategyId` into the block's node config (see `_persistStoreConfigToNode`),
1126
+ * which is the same route filters take. Resolving the URL template here rather
1127
+ * than at compile time matters — `buildCampaignUrl` is synchronous and would
1128
+ * otherwise silently fall back to the algorithm URL.
1129
+ */
1130
+ selectStrategy(strategyId: string): Promise<void>;
1131
+ /**
1132
+ * Duplicate the selected strategy and assign the copy to this block.
1133
+ *
1134
+ * Runs inline — the marketer never leaves the editor. Two things the web flow
1135
+ * does that we deliberately skip: its follow-up `POST /{id}/assign` (that binds
1136
+ * a strategy to a campaign *variation*, a concept email blocks do not have —
1137
+ * here the assignment is the block's own config), and displaying the copy's
1138
+ * name from the response, which only carries the new id. Hence the refetch.
1139
+ */
1140
+ duplicateAndAssignStrategy(): Promise<void>;
1141
+ /**
1142
+ * Opens the RRS detail drawer for the current block.
1143
+ *
1144
+ * `strategyId` describes a strategy without assigning it — View More reads
1145
+ * the details of an option the marketer is still only considering. Omitted,
1146
+ * the drawer describes whatever the block already has.
1147
+ *
1148
+ * Unlike the filter drawer this takes no snapshot — the drawer is
1149
+ * read-only, so there is nothing to revert on close.
1150
+ */
1151
+ openStrategyDrawer(strategyId?: string): void;
1152
+ /**
1153
+ * Closes the RRS detail drawer for the current block and drops the campaign
1154
+ * list, so reopening on a different strategy never flashes stale rows.
1155
+ */
1156
+ closeStrategyDrawer(): void;
1157
+ /** Drops the campaign list and lets the next open refetch. */
1158
+ clearStrategyCampaigns(): void;
1159
+ /**
1160
+ * Resolve and cache a strategy's recommendation-URL template.
1161
+ *
1162
+ * Keyed by id for caching, but the request itself carries the whole strategy
1163
+ * record — the algorithm inside it decides the feed's path and params, so an
1164
+ * id alone cannot describe the URL. The listing is therefore a prerequisite;
1165
+ * it is fetched on demand for callers (template hydrate) that may run before
1166
+ * the panel ever opened.
1167
+ *
1168
+ * Must be awaited before `buildCampaignUrl` runs for a strategy-driven block,
1169
+ * because that builder is synchronous and can only read what is already
1170
+ * cached. Safe to call repeatedly: a resolved id short-circuits, and
1171
+ * concurrent callers for the same id share one request.
1172
+ *
1173
+ * Only a *settled* answer is cached. An id the server rejects caches as '',
1174
+ * so the block falls back instead of retrying on every compile. A request
1175
+ * that merely failed to complete leaves the key unset and resolves to false,
1176
+ * so the next selection or save tries again — caching a network blip as "no
1177
+ * URL" would strand the block on its old algorithm feed for the session while
1178
+ * the panel still showed the strategy as assigned.
1179
+ * @returns whether the strategy now has a USABLE url — not merely a cache
1180
+ * entry. A rejected id caches as '' to stop the retry storm, but reporting
1181
+ * that as success would let the caller confirm an assignment the compiled
1182
+ * email cannot honour.
1183
+ */
1184
+ fetchStrategyUrlTemplate(strategyId: string): Promise<boolean>;
1185
+ /**
1186
+ * Wait for every strategy-URL request still in flight.
1187
+ *
1188
+ * The compiler is synchronous: whatever is not cached by the time it runs
1189
+ * compiles as the block's old algorithm URL. Selection and template hydrate
1190
+ * both await their own request, but a save fired inside that round trip would
1191
+ * still race — so the save path drains the queue first.
1192
+ */
1193
+ awaitPendingStrategyUrls(): Promise<void>;
1194
+ /**
1195
+ * Fetch the campaigns a strategy is used in, for the drawer's second tab.
1196
+ *
1197
+ * Lazy and once-per-strategy: the caller invokes this only while the drawer is
1198
+ * open on that tab, and a repeat call for the same id is a no-op. A version
1199
+ * counter discards a response that arrives after the user switched strategies,
1200
+ * which would otherwise show one strategy's campaigns under another's name.
1201
+ */
1202
+ fetchStrategyCampaigns(strategyId: string): Promise<void>;
270
1203
  /**
271
1204
  * Cancels the filter selection drawer and reverts filters
272
1205
  * to the snapshot taken when the drawer was opened.
273
1206
  */
274
1207
  cancelFilterDrawer(): void;
275
1208
  fetchRecommendationCreateData(): Promise<void>;
1209
+ /**
1210
+ * Fetch the partner's Reusable Recommendation Strategies for the EMAIL channel.
1211
+ *
1212
+ * Same cache-guard + in-flight dedupe shape as fetchRecommendationCreateData.
1213
+ * A failure leaves `strategies` empty so the dropdown renders empty rather
1214
+ * than blocking the panel — the block keeps working on its algorithm.
1215
+ */
1216
+ fetchRecommendationStrategies(): Promise<void>;
1217
+ /**
1218
+ * Refetch the listing, ignoring the once-per-session cache.
1219
+ *
1220
+ * Needed after Duplicate and Assign: the copy exists server-side but not in
1221
+ * `strategies`, so without this the panel would read the freshly assigned id
1222
+ * back as a deleted strategy.
1223
+ */
1224
+ refreshRecommendationStrategies(): Promise<void>;
276
1225
  fetchRecommendationFilters(): Promise<void>;
277
1226
  addFilterGroup(filterGroup: number): void;
278
1227
  deleteFilterGroup(groupId: number): void;
@@ -288,5 +1237,13 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
288
1237
  hasInvalidBlock(): boolean;
289
1238
  fetchRecommendationProducts(): Promise<void>;
290
1239
  _doFetchProducts(): Promise<void>;
1240
+ /**
1241
+ * Runs a product fetch and writes the result to `blockId`.
1242
+ *
1243
+ * Shared by the strategy and algorithm paths so the size padding/clipping —
1244
+ * which the in-place card renderer depends on for its element-count match —
1245
+ * cannot drift between them.
1246
+ */
1247
+ _applyFetchedProducts(blockId: number, fetchProducts: () => Promise<RecommendationProduct[]>): Promise<void>;
291
1248
  }>;
292
1249
  export {};