@useinsider/guido 3.12.0-beta.841bb6a → 3.12.0-beta.86e34da

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