@useinsider/guido 3.18.2-beta.45f708c → 3.18.2-beta.4d2b065

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 (58) hide show
  1. package/README.md +21 -3
  2. package/dist/@types/config/schemas.js +59 -51
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +72 -70
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +7 -9
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +51 -66
  7. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
  8. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
  9. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +40 -24
  10. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +28 -26
  11. package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.js +21 -0
  12. package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue2.js +46 -0
  13. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +3 -3
  14. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +20 -21
  15. package/dist/composables/useCustomInterfaceAppearance.js +47 -53
  16. package/dist/composables/useHtmlValidator.js +79 -84
  17. package/dist/composables/useLegacyStrategyConversion.js +61 -0
  18. package/dist/composables/useRecommendation.js +35 -40
  19. package/dist/composables/useStripo.js +30 -30
  20. package/dist/enums/extensions/recommendationBlock.js +41 -39
  21. package/dist/extensions/Blocks/Recommendation/block.js +39 -43
  22. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
  23. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +80 -84
  24. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +94 -82
  25. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +97 -96
  26. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +144 -179
  27. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +42 -0
  28. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +16 -26
  29. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
  30. package/dist/guido.css +1 -1
  31. package/dist/services/recommendationApi.js +46 -37
  32. package/dist/src/@types/config/schemas.d.ts +16 -0
  33. package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
  34. package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts +2 -0
  35. package/dist/src/composables/useConfig.d.ts +4 -0
  36. package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
  37. package/dist/src/enums/extensions/recommendationBlock.d.ts +5 -3
  38. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
  39. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  40. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
  41. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +1 -8
  42. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +6 -7
  43. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +70 -76
  44. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +32 -0
  45. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
  46. package/dist/src/services/recommendationApi.d.ts +2 -1
  47. package/dist/src/stores/config.d.ts +322 -0
  48. package/dist/src/stores/onboarding.d.ts +421 -0
  49. package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
  50. package/dist/static/assets/icons/line-info.svg.js +5 -0
  51. package/dist/static/styles/components/recommendation-strategy.css.js +74 -39
  52. package/dist/stores/config.js +74 -60
  53. package/dist/stores/onboarding.js +6 -1
  54. package/dist/utils/templatePreparation.js +55 -55
  55. package/package.json +5 -5
  56. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +0 -24
  57. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -14
  58. package/dist/static/styles/components/skeleton.css.js +0 -23
@@ -1,4 +1,4 @@
1
- import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsStrategy } from '@@/Types/recommendation';
1
+ import type { Orientation, Languages, Currency, NumericSeparator, FiltersResponse, Filter, RecommendationCampaignUrlValue, RecommendationProduct, RrsMigrationPayload, RrsMigrationTarget, RrsStrategy } from '@@/Types/recommendation';
2
2
  export interface PerBlockConfigs {
3
3
  cardsInRow: number;
4
4
  currencySettings: {
@@ -22,6 +22,7 @@ export interface PerBlockConfigs {
22
22
  shuffleProducts: boolean;
23
23
  strategy: string;
24
24
  strategyId: string;
25
+ nodeConfigVersion: number;
25
26
  textTrimming: boolean;
26
27
  unresponsive: boolean;
27
28
  size: string;
@@ -36,6 +37,7 @@ interface PerBlockState {
36
37
  filterSelectionDrawerStatus: boolean;
37
38
  assignStrategyDrawerStatus: boolean;
38
39
  removeStrategyModalStatus: boolean;
40
+ legacyStrategyUpdatedModalStatus: boolean;
39
41
  filterGroup: number;
40
42
  /** Whether initial API data (filters, algorithms, products) has been fetched for this block */
41
43
  isInitialized: boolean;
@@ -51,6 +53,7 @@ interface PerBlockState {
51
53
  * same id skipped the re-sync and kept the defaults (SD-150347).
52
54
  */
53
55
  syncedConfigFingerprint: string | null;
56
+ legacyConversionLoading: boolean;
54
57
  }
55
58
  /**
56
59
  * Persisted-config subset used by `seedBlockUrlConfig` to reconstruct
@@ -83,11 +86,8 @@ interface StoreState {
83
86
  strategies: RrsStrategy[];
84
87
  strategiesLoading: boolean;
85
88
  strategyUrlTemplates: Record<string, string>;
86
- strategiesFetched: boolean;
87
- strategiesSettled: boolean;
88
89
  blockStates: Record<number, PerBlockState>;
89
90
  currentRecommendationId: number | null;
90
- strategyPanelOpen: boolean;
91
91
  configVersion: number;
92
92
  }
93
93
  export declare const useRecommendationExtensionStore: import("pinia").StoreDefinition<"guidoRecommendationExtension", StoreState, {
@@ -114,11 +114,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
114
114
  }[];
115
115
  strategiesLoading: boolean;
116
116
  strategyUrlTemplates: Record<string, string>;
117
- strategiesFetched: boolean;
118
- strategiesSettled: boolean;
119
117
  blockStates: Record<number, PerBlockState>;
120
118
  currentRecommendationId: number | null;
121
- strategyPanelOpen: boolean;
122
119
  configVersion: number;
123
120
  } & import("pinia").PiniaCustomStateProperties<StoreState>): PerBlockConfigs;
124
121
  /**
@@ -143,11 +140,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
143
140
  }[];
144
141
  strategiesLoading: boolean;
145
142
  strategyUrlTemplates: Record<string, string>;
146
- strategiesFetched: boolean;
147
- strategiesSettled: boolean;
148
143
  blockStates: Record<number, PerBlockState>;
149
144
  currentRecommendationId: number | null;
150
- strategyPanelOpen: boolean;
151
145
  configVersion: number;
152
146
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RecommendationProduct[];
153
147
  /**
@@ -172,11 +166,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
172
166
  }[];
173
167
  strategiesLoading: boolean;
174
168
  strategyUrlTemplates: Record<string, string>;
175
- strategiesFetched: boolean;
176
- strategiesSettled: boolean;
177
169
  blockStates: Record<number, PerBlockState>;
178
170
  currentRecommendationId: number | null;
179
- strategyPanelOpen: boolean;
180
171
  configVersion: number;
181
172
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
182
173
  assignStrategyDrawerStatus(state: {
@@ -198,11 +189,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
198
189
  }[];
199
190
  strategiesLoading: boolean;
200
191
  strategyUrlTemplates: Record<string, string>;
201
- strategiesFetched: boolean;
202
- strategiesSettled: boolean;
203
192
  blockStates: Record<number, PerBlockState>;
204
193
  currentRecommendationId: number | null;
205
- strategyPanelOpen: boolean;
206
194
  configVersion: number;
207
195
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
208
196
  removeStrategyModalStatus(state: {
@@ -224,11 +212,55 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
224
212
  }[];
225
213
  strategiesLoading: boolean;
226
214
  strategyUrlTemplates: Record<string, string>;
227
- strategiesFetched: boolean;
228
- strategiesSettled: boolean;
229
215
  blockStates: Record<number, PerBlockState>;
230
216
  currentRecommendationId: number | null;
231
- strategyPanelOpen: boolean;
217
+ configVersion: number;
218
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
219
+ isLegacyStrategyBlock(): boolean;
220
+ legacyConversionLoading(state: {
221
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
222
+ activePredictiveAlgorithms: number[];
223
+ languages: Languages;
224
+ currencyList: {
225
+ text: string;
226
+ value: string;
227
+ }[];
228
+ filterList: FiltersResponse;
229
+ strategies: {
230
+ [x: string]: unknown;
231
+ strategy_id: number;
232
+ name: string;
233
+ status: string;
234
+ suitable_channels: string;
235
+ size?: (number | string) | undefined;
236
+ }[];
237
+ strategiesLoading: boolean;
238
+ strategyUrlTemplates: Record<string, string>;
239
+ blockStates: Record<number, PerBlockState>;
240
+ currentRecommendationId: number | null;
241
+ configVersion: number;
242
+ } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
243
+ legacyStrategyUpdatedModalStatus(state: {
244
+ recommendationCampaignUrls: Record<string, RecommendationCampaignUrlValue>;
245
+ activePredictiveAlgorithms: number[];
246
+ languages: Languages;
247
+ currencyList: {
248
+ text: string;
249
+ value: string;
250
+ }[];
251
+ filterList: FiltersResponse;
252
+ strategies: {
253
+ [x: string]: unknown;
254
+ strategy_id: number;
255
+ name: string;
256
+ status: string;
257
+ suitable_channels: string;
258
+ size?: (number | string) | undefined;
259
+ }[];
260
+ strategiesLoading: boolean;
261
+ strategyUrlTemplates: Record<string, string>;
262
+ blockStates: Record<number, PerBlockState>;
263
+ currentRecommendationId: number | null;
232
264
  configVersion: number;
233
265
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
234
266
  assignedStrategy(state: {
@@ -250,11 +282,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
250
282
  }[];
251
283
  strategiesLoading: boolean;
252
284
  strategyUrlTemplates: Record<string, string>;
253
- strategiesFetched: boolean;
254
- strategiesSettled: boolean;
255
285
  blockStates: Record<number, PerBlockState>;
256
286
  currentRecommendationId: number | null;
257
- strategyPanelOpen: boolean;
258
287
  configVersion: number;
259
288
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
260
289
  /**
@@ -279,11 +308,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
279
308
  }[];
280
309
  strategiesLoading: boolean;
281
310
  strategyUrlTemplates: Record<string, string>;
282
- strategiesFetched: boolean;
283
- strategiesSettled: boolean;
284
311
  blockStates: Record<number, PerBlockState>;
285
312
  currentRecommendationId: number | null;
286
- strategyPanelOpen: boolean;
287
313
  configVersion: number;
288
314
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
289
315
  /**
@@ -308,11 +334,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
308
334
  }[];
309
335
  strategiesLoading: boolean;
310
336
  strategyUrlTemplates: Record<string, string>;
311
- strategiesFetched: boolean;
312
- strategiesSettled: boolean;
313
337
  blockStates: Record<number, PerBlockState>;
314
338
  currentRecommendationId: number | null;
315
- strategyPanelOpen: boolean;
316
339
  configVersion: number;
317
340
  } & import("pinia").PiniaCustomStateProperties<StoreState>): number;
318
341
  hasFilters(): boolean;
@@ -338,11 +361,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
338
361
  }[];
339
362
  strategiesLoading: boolean;
340
363
  strategyUrlTemplates: Record<string, string>;
341
- strategiesFetched: boolean;
342
- strategiesSettled: boolean;
343
364
  blockStates: Record<number, PerBlockState>;
344
365
  currentRecommendationId: number | null;
345
- strategyPanelOpen: boolean;
346
366
  configVersion: number;
347
367
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
348
368
  text: string;
@@ -367,11 +387,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
367
387
  }[];
368
388
  strategiesLoading: boolean;
369
389
  strategyUrlTemplates: Record<string, string>;
370
- strategiesFetched: boolean;
371
- strategiesSettled: boolean;
372
390
  blockStates: Record<number, PerBlockState>;
373
391
  currentRecommendationId: number | null;
374
- strategyPanelOpen: boolean;
375
392
  configVersion: number;
376
393
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
377
394
  text: string;
@@ -396,11 +413,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
396
413
  }[];
397
414
  strategiesLoading: boolean;
398
415
  strategyUrlTemplates: Record<string, string>;
399
- strategiesFetched: boolean;
400
- strategiesSettled: boolean;
401
416
  blockStates: Record<number, PerBlockState>;
402
417
  currentRecommendationId: number | null;
403
- strategyPanelOpen: boolean;
404
418
  configVersion: number;
405
419
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
406
420
  text: string;
@@ -478,45 +492,24 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
478
492
  cancelFilterDrawer(): void;
479
493
  openAssignStrategyDrawer(): void;
480
494
  closeAssignStrategyDrawer(): void;
495
+ openLegacyStrategyUpdatedModal(): void;
496
+ closeLegacyStrategyUpdatedModal(): void;
481
497
  openRemoveStrategyModal(): void;
482
498
  closeRemoveStrategyModal(): void;
483
499
  fetchStrategies(): Promise<void>;
484
- invalidateStrategies(): void;
485
- /**
486
- * Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
487
- * the user comes back. `visibilitychange` only: a `focus` listener would also fire when
488
- * focus merely returns from the Stripo canvas iframe to the panel, refetching and
489
- * regenerating the canvas while the user never left the editor (SD-149916).
490
- *
491
- * Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
492
- * strategy in it and come back again — a listener that disarmed on the first return would
493
- * leave that one missing from the list. It disarms on the first return AFTER that tab is
494
- * closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
495
- * once the user actually opens a strategy page, so anyone who never does pays nothing.
496
- */
497
- _armStrategyPageReturn(url: string): void;
498
- /**
499
- * Reloads the products of the block the user is on, so an edit made in the strategy tab
500
- * lands on the canvas instead of waiting for the assign drawer to be reopened.
501
- *
502
- * Only the selected block: the canvas regeneration is driven off the active block's
503
- * product array, so refreshing an unselected block would fetch without redrawing it.
504
- */
505
- _refreshAssignedStrategyProducts(): Promise<void>;
506
- /** Lets the editor tear the return listeners down when it unmounts. */
507
- disposeStrategyPageReturn(): void;
508
- /**
509
- * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
510
- * new strategy is offered; the user picks it themselves.
511
- */
512
- openStrategyCreation(): void;
513
- /**
514
- * Opens the strategy's edit page. Every return refreshes the list so the block reflects the
515
- * edited configuration.
516
- */
517
- openStrategyEdit(strategyId: string | number): void;
518
500
  resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
519
501
  assignStrategy(strategy: RrsStrategy): void;
502
+ convertLegacyStrategy(payload: RrsMigrationPayload, target?: RrsMigrationTarget): Promise<string>;
503
+ /**
504
+ * Undoes the config half of a conversion whose document write never landed, so the
505
+ * panel and the drawer fall back to "Legacy Strategy" instead of showing an assignment
506
+ * the document never received.
507
+ */
508
+ revertLegacyConversion(blockId: number, previous: {
509
+ strategyId: string;
510
+ size: string;
511
+ nodeConfigVersion: number;
512
+ }): void;
520
513
  removeStrategy(): void;
521
514
  fetchRecommendationCreateData(): Promise<void>;
522
515
  fetchRecommendationFilters(): Promise<void>;
@@ -532,13 +525,14 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
532
525
  * every block's recommendationConfigs across user edits.
533
526
  */
534
527
  hasInvalidBlock(): boolean;
535
- /**
536
- * Which required fields are missing across the design's blocks, so the save
537
- * toaster can name the cause instead of always showing the generic message.
538
- */
539
- invalidBlockFields(): string[];
540
528
  fetchRecommendationProducts(): Promise<void>;
541
529
  _doFetchProducts(): Promise<void>;
530
+ /**
531
+ * Block-scoped counterpart of `fetchRecommendationProducts`, which only ever serves the
532
+ * selected block. The legacy conversion must refresh the products of the block that
533
+ * started it even after the user selected another one.
534
+ */
535
+ fetchStrategyProductsForBlock(blockId: number): Promise<void>;
542
536
  _doFetchStrategyProducts(blockId: number): Promise<void>;
543
537
  _setBlockProducts(blockId: number, products: RecommendationProduct[], size: number): void;
544
538
  }>;
@@ -0,0 +1,32 @@
1
+ import type { RrsMigrationPayload, RrsMigrationTarget } from '@@/Types/recommendation';
2
+ /**
3
+ * A block authored before reusable strategies: it still carries a plain feed
4
+ * configuration (compiled into a feed URL string) instead of a strategy id.
5
+ * Blocks created under RRS stamp `CURRENT_CONFIG_VERSION`, so the version is
6
+ * what separates "never converted" from "not assigned yet".
7
+ */
8
+ export declare function isLegacyStrategyConfig({ strategyId, nodeConfigVersion }: {
9
+ strategyId: string;
10
+ nodeConfigVersion: number;
11
+ }): boolean;
12
+ export declare function resolveMigrationTarget({ campaignId, templateLibraryId }: {
13
+ campaignId?: string;
14
+ templateLibraryId?: string;
15
+ }): RrsMigrationTarget;
16
+ interface MigrationInputs {
17
+ blockId: number;
18
+ url: string;
19
+ campaignId: string;
20
+ variationId: string;
21
+ strategy: string;
22
+ productIds: string[];
23
+ target: RrsMigrationTarget;
24
+ }
25
+ /**
26
+ * The server names and de-duplicates the strategy, so nothing here derives a name, and the
27
+ * filters travel inside `url` — the endpoint parses the feed URL's filter DSL itself. The two
28
+ * routes take different identity fields — the campaign one names from `campaignId`/`variationId`
29
+ * (0 for modules, which carry no numeric campaign), the template one from `templateId`.
30
+ */
31
+ export declare function buildLegacyMigrationPayload({ blockId, url, campaignId, variationId, strategy, productIds, target, }: MigrationInputs): RrsMigrationPayload;
32
+ export {};
@@ -15,11 +15,7 @@ export interface RequiredField {
15
15
  getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
16
16
  condition?: (config: PerBlockConfigs) => boolean;
17
17
  }
18
- /** Field key of the strategy/algorithm descriptor, used to pick the toaster message. */
19
- export declare const STRATEGY_FIELD_KEY = "strategy";
20
18
  export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
21
19
  export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
22
- /** Shown instead of the generic message when the only thing missing is the strategy. */
23
- export declare const RecommendationAssignStrategyKey = "newsletter.recommendation-assign-strategy";
24
20
  export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
25
21
  export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;
@@ -1,4 +1,4 @@
1
- import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsStrategy } from '@@/Types/recommendation';
1
+ import type { InitialResponse, FiltersResponse, RecommendationProduct, RecommendationProductsParams, RrsEndpointGenerateResponse, RrsMigrationPayload, RrsMigrationTarget, RrsStrategy } from '@@/Types/recommendation';
2
2
  export declare const useRecommendationApi: () => {
3
3
  fetchRecommendationCreateData: () => Promise<InitialResponse>;
4
4
  fetchRecommendationFilters: () => Promise<FiltersResponse>;
@@ -6,4 +6,5 @@ export declare const useRecommendationApi: () => {
6
6
  fetchRecommendationProductsByUrl: (url: string) => Promise<RecommendationProduct[]>;
7
7
  fetchRecommendationStrategies: () => Promise<RrsStrategy[]>;
8
8
  generateStrategyEndpoint: (strategy: RrsStrategy, currency: string) => Promise<RrsEndpointGenerateResponse | null>;
9
+ migrateLegacyStrategy: (payload: RrsMigrationPayload, target?: RrsMigrationTarget) => Promise<string>;
9
10
  };