@useinsider/guido 3.12.0-beta.b73c720 → 3.12.0-beta.bec0e55

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 (80) hide show
  1. package/dist/@types/config/schemas.js +8 -13
  2. package/dist/components/Guido.vue.js +6 -6
  3. package/dist/components/Guido.vue2.js +49 -50
  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/composables/usePreviewInteractionGuard.js +36 -11
  9. package/dist/composables/useRecommendation.js +51 -82
  10. package/dist/composables/useRecommendationPreview.js +61 -60
  11. package/dist/config/migrator/recommendationMigrator.js +4 -7
  12. package/dist/enums/date.js +3 -4
  13. package/dist/enums/extensions/recommendationBlock.js +22 -28
  14. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  15. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +11 -12
  16. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  17. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +109 -123
  18. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  19. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +1 -1
  20. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  21. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +102 -256
  22. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -24
  23. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  24. package/dist/extensions/Blocks/controlFactories.js +125 -75
  25. package/dist/guido.css +1 -1
  26. package/dist/services/recommendationApi.js +27 -65
  27. package/dist/src/@types/config/schemas.d.ts +0 -10
  28. package/dist/src/composables/useConfig.d.ts +0 -2
  29. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  30. package/dist/src/composables/useRecommendation.d.ts +0 -2
  31. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -10
  32. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  33. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  34. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  35. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -3
  36. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -606
  37. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +0 -7
  38. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +1 -3
  39. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  40. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  41. package/dist/src/services/recommendationApi.d.ts +1 -7
  42. package/dist/src/stores/config.d.ts +0 -18
  43. package/dist/src/utils/genericUtil.d.ts +0 -9
  44. package/dist/src/utils/urlSchemes.d.ts +6 -0
  45. package/dist/static/styles/base.css.js +0 -15
  46. package/dist/utils/dateUtil.js +10 -23
  47. package/dist/utils/genericUtil.js +1 -10
  48. package/dist/utils/templatePreparation.js +58 -62
  49. package/dist/utils/urlSchemes.js +4 -0
  50. package/package.json +1 -1
  51. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +0 -36
  52. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +0 -244
  53. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +0 -18
  54. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +0 -42
  55. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +0 -20
  56. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +0 -18
  57. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +0 -20
  58. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +0 -60
  59. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +0 -19
  60. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +0 -19
  61. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +0 -22
  62. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +0 -29
  63. package/dist/composables/useStrategyFilters.js +0 -16
  64. package/dist/enums/extensions/filteringV2.js +0 -8
  65. package/dist/enums/extensions/strategyDetail.js +0 -148
  66. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +0 -146
  67. package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +0 -97
  68. package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +0 -10
  69. package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +0 -2
  70. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +0 -43
  71. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +0 -29
  72. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +0 -40
  73. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +0 -38
  74. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +0 -51
  75. package/dist/src/composables/useStrategyFilters.d.ts +0 -24
  76. package/dist/src/enums/extensions/filteringV2.d.ts +0 -72
  77. package/dist/src/enums/extensions/strategyDetail.d.ts +0 -90
  78. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -61
  79. package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +0 -50
  80. package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +0 -34
@@ -1,23 +1,20 @@
1
- import { useConfig as D } from "../../../../composables/useConfig.js";
2
- import { useTranslations as F } from "../../../../composables/useTranslations.js";
3
- import { getRecommendationFeedSourceMaps as y, getOperatorOptions as w, PriceAttributes as G } from "../../../../enums/extensions/recommendationBlock.js";
4
- import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
5
- import { useConfigStore as v } from "../../../../stores/config.js";
6
- import { defineStore as L } from "pinia";
1
+ import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as G } from "../../../../stores/config.js";
4
+ import { defineStore as F } from "pinia";
7
5
  import "../constants/selectors.js";
8
- import { DEFAULT_MOBILE_CARDS_IN_ROW as U, DEFAULT_CARDS_IN_ROW as N } from "../constants/layout.js";
9
- import { EXCLUDED_ALGORITHM_IDS as x } from "../constants/defaultConfig.js";
10
- import { getDefaultProducts as I } from "../templates/utils.js";
11
- import { generateCompleteFilterQuery as R } from "../utils/filterUtil.js";
12
- import { getPartnerRecommendationParams as _ } from "../utils/partnerCustomizations.js";
13
- import { isFilterValid as O } from "../validation/filterSchema.js";
14
- import { isConfigValid as A } from "../validation/requiredFields.js";
15
- const m = P();
16
- let u = null, d = null, f = null, g = null, S = 0;
17
- const p = {};
18
- function C() {
6
+ import { DEFAULT_MOBILE_CARDS_IN_ROW as P, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
7
+ import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
8
+ import { getDefaultProducts as S } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
10
+ import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
11
+ import { isFilterValid as N } from "../validation/filterSchema.js";
12
+ import { isConfigValid as x } from "../validation/requiredFields.js";
13
+ const h = y();
14
+ let m = null, u = null, d = null;
15
+ function k() {
19
16
  return {
20
- cardsInRow: N,
17
+ cardsInRow: D,
21
18
  currencySettings: {
22
19
  name: "USD",
23
20
  value: "USD",
@@ -31,14 +28,13 @@ function C() {
31
28
  productIds: [],
32
29
  id: 1,
33
30
  language: "en_US",
34
- mobileCardsInRow: U,
31
+ mobileCardsInRow: P,
35
32
  mobileLayoutEnabled: !1,
36
33
  orientation: "grid",
37
34
  recommendedProducts: [],
38
35
  sendProductRequestFlag: !1,
39
36
  shuffleProducts: !1,
40
37
  strategy: "mostPopular",
41
- strategyId: "",
42
38
  textTrimming: !0,
43
39
  unresponsive: !1,
44
40
  size: "6",
@@ -47,35 +43,28 @@ function C() {
47
43
  priceHideIfSameAsDiscounted: !1
48
44
  };
49
45
  }
50
- function k() {
46
+ function I() {
51
47
  return {
52
- recommendationConfigs: C(),
48
+ recommendationConfigs: k(),
53
49
  recommendationProducts: [],
54
50
  filterStatus: !1,
55
51
  filterSelectionDrawerStatus: !1,
56
- strategyDetailDrawerStatus: !1,
57
52
  filterGroup: 1,
58
53
  isInitialized: !1,
59
54
  filterSnapshot: null
60
55
  };
61
56
  }
62
- const B = () => ({
57
+ const L = () => ({
63
58
  recommendationCampaignUrls: {},
64
59
  activePredictiveAlgorithms: [],
65
60
  languages: {},
66
61
  currencyList: [],
67
62
  filterList: {},
68
- strategies: [],
69
- strategiesLoading: !1,
70
- strategyCampaigns: [],
71
- strategyCampaignsLoading: !1,
72
- strategyCampaignsFetchedFor: null,
73
- strategyUrlTemplates: {},
74
63
  blockStates: {},
75
64
  currentRecommendationId: null,
76
65
  configVersion: 0
77
- }), Y = L("guidoRecommendationExtension", {
78
- state: () => B(),
66
+ }), $ = F("guidoRecommendationExtension", {
67
+ state: () => L(),
79
68
  getters: {
80
69
  // ====================================================================
81
70
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -85,7 +74,7 @@ const B = () => ({
85
74
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
86
75
  */
87
76
  recommendationConfigs(t) {
88
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : C();
77
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
89
78
  },
90
79
  /**
91
80
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -99,12 +88,6 @@ const B = () => ({
99
88
  filterSelectionDrawerStatus(t) {
100
89
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].filterSelectionDrawerStatus : !1;
101
90
  },
102
- /**
103
- * Proxy getter: delegates to blockStates[currentRecommendationId].strategyDetailDrawerStatus
104
- */
105
- strategyDetailDrawerStatus(t) {
106
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].strategyDetailDrawerStatus : !1;
107
- },
108
91
  /**
109
92
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
110
93
  */
@@ -136,55 +119,14 @@ const B = () => ({
136
119
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
137
120
  },
138
121
  getActivePredictiveAlgorithms: (t) => {
139
- const e = y(), r = [];
140
- return t.activePredictiveAlgorithms.filter((i) => !x.includes(i)).forEach((i) => {
141
- r.push(...e.filter((a) => a.id === i));
142
- }), r.map((i) => ({
143
- text: i.name,
144
- value: i.key
122
+ const e = g(), r = [];
123
+ return t.activePredictiveAlgorithms.filter((n) => !w.includes(n)).forEach((n) => {
124
+ r.push(...e.filter((c) => c.id === n));
125
+ }), r.map((n) => ({
126
+ text: n.name,
127
+ value: n.key
145
128
  }));
146
129
  },
147
- /**
148
- * Reusable Recommendation Strategies as dropdown options.
149
- *
150
- * Unlike algorithms, strategy ids come straight from Smart Recommender —
151
- * there is no local id→key table to join against.
152
- */
153
- getStrategyOptions: (t) => t.strategies.map((e) => ({
154
- text: e.name,
155
- value: String(e.strategy_id)
156
- })),
157
- /**
158
- * The current block's selected strategy, or null when none is selected
159
- * or the selected id is no longer in the listing.
160
- *
161
- * A null return with a non-empty `strategyId` means the strategy was
162
- * deleted in Smart Recommender after this block was configured — the
163
- * panel flags that rather than silently clearing the selection.
164
- */
165
- getSelectedStrategy() {
166
- const { strategyId: t } = this.recommendationConfigs;
167
- return t ? this.strategies.find((e) => String(e.strategy_id) === t) ?? null : null;
168
- },
169
- /**
170
- * Whether the RRS feature is enabled for this editor.
171
- *
172
- * Read through a getter so `hasInvalidBlock` can pass the store straight to
173
- * the required-field descriptors, which need the flag to decide whether a
174
- * missing strategy blocks the save.
175
- */
176
- isRrsEnabled() {
177
- return D().isFeatureEnabled("reusableRecommendationStrategy");
178
- },
179
- /**
180
- * True when a strategy id is set but absent from the fetched listing.
181
- *
182
- * Guarded on the listing having loaded — mid-fetch every id looks missing.
183
- */
184
- hasMissingStrategy() {
185
- const { strategyId: t } = this.recommendationConfigs;
186
- return !t || this.strategiesLoading || !this.strategies.length ? !1 : this.getSelectedStrategy === null;
187
- },
188
130
  getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
189
131
  text: r,
190
132
  value: e
@@ -196,7 +138,7 @@ const B = () => ({
196
138
  getFilterList() {
197
139
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
198
140
  let e;
199
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : G.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
141
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
200
142
  text: t.displayName,
201
143
  value: e,
202
144
  type: t.attributeType
@@ -218,7 +160,7 @@ const B = () => ({
218
160
  setCurrentBlock(t) {
219
161
  this.blockStates[t] || (this.blockStates = {
220
162
  ...this.blockStates,
221
- [t]: k()
163
+ [t]: I()
222
164
  }), this.currentRecommendationId = t;
223
165
  },
224
166
  /**
@@ -228,13 +170,13 @@ const B = () => ({
228
170
  removeBlockState(t) {
229
171
  const e = t.toString();
230
172
  if (this.recommendationCampaignUrls[e]) {
231
- const i = { ...this.recommendationCampaignUrls };
232
- delete i[e], this.recommendationCampaignUrls = i;
173
+ const n = { ...this.recommendationCampaignUrls };
174
+ delete n[e], this.recommendationCampaignUrls = n;
233
175
  }
234
176
  const r = { ...this.blockStates };
235
177
  if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
236
- const i = Object.keys(this.blockStates).map(Number);
237
- this.currentRecommendationId = i.length > 0 ? i[0] : null;
178
+ const n = Object.keys(this.blockStates).map(Number);
179
+ this.currentRecommendationId = n.length > 0 ? n[0] : null;
238
180
  }
239
181
  },
240
182
  /**
@@ -250,10 +192,10 @@ const B = () => ({
250
192
  [e]: o
251
193
  };
252
194
  }
253
- const i = t.toString(), a = e.toString(), n = this.recommendationCampaignUrls[i];
254
- n && (this.recommendationCampaignUrls = {
195
+ const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
196
+ i && (this.recommendationCampaignUrls = {
255
197
  ...this.recommendationCampaignUrls,
256
- [a]: n
198
+ [c]: i
257
199
  });
258
200
  },
259
201
  /**
@@ -278,7 +220,7 @@ const B = () => ({
278
220
  * `isInitialized`) alone.
279
221
  */
280
222
  seedBlockUrlConfig(t, e) {
281
- const r = (o, s) => o === "." || o === "," || o === " " ? o : s, i = {
223
+ const r = (o, s) => o === "." || o === "," || o === " " ? o : s, n = {
282
224
  name: e.currencyCode,
283
225
  value: e.currencyCode,
284
226
  symbol: e.currencyCode,
@@ -286,20 +228,19 @@ const B = () => ({
286
228
  decimalCount: String(e.currencyDecimalCount),
287
229
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
288
230
  thousandSeparator: r(e.currencyThousandSeparator, ".")
289
- }, a = !this.blockStates[t], n = a ? k() : this.blockStates[t];
290
- n.recommendationConfigs = {
291
- ...n.recommendationConfigs,
231
+ }, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
232
+ i.recommendationConfigs = {
233
+ ...i.recommendationConfigs,
292
234
  strategy: e.strategy,
293
- strategyId: e.strategyId,
294
235
  language: e.language,
295
236
  size: e.size,
296
237
  productIds: e.productIds,
297
238
  filters: e.filters,
298
239
  shuffleProducts: e.shuffleProducts,
299
- currencySettings: i
300
- }, a && (this.blockStates = {
240
+ currencySettings: n
241
+ }, c && (this.blockStates = {
301
242
  ...this.blockStates,
302
- [t]: n
243
+ [t]: i
303
244
  });
304
245
  },
305
246
  /**
@@ -318,18 +259,18 @@ const B = () => ({
318
259
  ...t.currencySettings || {}
319
260
  }
320
261
  };
321
- const { triggerRefetch: i = !0 } = e;
322
- i && this.configVersion++;
262
+ const { triggerRefetch: n = !0 } = e;
263
+ n && this.configVersion++;
323
264
  },
324
265
  /**
325
266
  * Creates a filter with the first available attribute and operator pre-selected.
326
267
  */
327
268
  createDefaultFilter(t, e) {
328
- const [r] = this.getFilterList, [i] = w(r == null ? void 0 : r.type);
269
+ const [r] = this.getFilterList, [n] = R(r == null ? void 0 : r.type);
329
270
  return {
330
271
  type: "standardFilter",
331
272
  attribute: (r == null ? void 0 : r.value) ?? "",
332
- operator: (i == null ? void 0 : i.value) ?? "",
273
+ operator: (n == null ? void 0 : n.value) ?? "",
333
274
  innerGroupOperator: "*",
334
275
  outerGroupOperator: "*",
335
276
  filterNumber: e,
@@ -362,72 +303,6 @@ const B = () => ({
362
303
  const t = this.blockStates[this.currentRecommendationId];
363
304
  t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
364
305
  },
365
- /**
366
- * Opens the RRS detail drawer for the current block.
367
- *
368
- * Unlike the filter drawer this takes no snapshot — the drawer is
369
- * read-only, so there is nothing to revert on close.
370
- */
371
- openStrategyDrawer() {
372
- this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !0);
373
- },
374
- /**
375
- * Closes the RRS detail drawer for the current block and drops the campaign
376
- * list, so reopening on a different strategy never flashes stale rows.
377
- */
378
- closeStrategyDrawer() {
379
- this.clearStrategyCampaigns(), !(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId]) && (this.blockStates[this.currentRecommendationId].strategyDetailDrawerStatus = !1);
380
- },
381
- /** Drops the campaign list and lets the next open refetch. */
382
- clearStrategyCampaigns() {
383
- this.strategyCampaigns = [], this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = null, S += 1;
384
- },
385
- /**
386
- * Resolve and cache a strategy's recommendation-URL template.
387
- *
388
- * Must be awaited before `buildCampaignUrl` runs for a strategy-driven block,
389
- * because that builder is synchronous and can only read what is already
390
- * cached. Safe to call repeatedly: a cached id (including one cached as the
391
- * empty string after a failure) short-circuits, and concurrent callers for
392
- * the same id share one request.
393
- */
394
- async fetchStrategyUrlTemplate(t) {
395
- if (!t || t in this.strategyUrlTemplates)
396
- return;
397
- const e = p[t];
398
- if (e) {
399
- await e;
400
- return;
401
- }
402
- p[t] = (async () => {
403
- const r = await m.fetchStrategyRecommendationUrl(t);
404
- this.strategyUrlTemplates = {
405
- ...this.strategyUrlTemplates,
406
- [t]: (r == null ? void 0 : r.full_path) ?? ""
407
- };
408
- })();
409
- try {
410
- await p[t];
411
- } finally {
412
- delete p[t];
413
- }
414
- },
415
- /**
416
- * Fetch the campaigns a strategy is used in, for the drawer's second tab.
417
- *
418
- * Lazy and once-per-strategy: the caller invokes this only while the drawer is
419
- * open on that tab, and a repeat call for the same id is a no-op. A version
420
- * counter discards a response that arrives after the user switched strategies,
421
- * which would otherwise show one strategy's campaigns under another's name.
422
- */
423
- async fetchStrategyCampaigns(t) {
424
- if (!t || this.strategyCampaignsFetchedFor === t)
425
- return;
426
- const e = ++S;
427
- this.strategyCampaignsLoading = !0;
428
- const r = await m.fetchStrategyCampaigns(t, F());
429
- e === S && (this.strategyCampaigns = r, this.strategyCampaignsLoading = !1, this.strategyCampaignsFetchedFor = t);
430
- },
431
306
  /**
432
307
  * Cancels the filter selection drawer and reverts filters
433
308
  * to the snapshot taken when the drawer was opened.
@@ -443,72 +318,43 @@ const B = () => ({
443
318
  // ====================================================================
444
319
  async fetchRecommendationCreateData() {
445
320
  if (!this.activePredictiveAlgorithms.length) {
446
- if (u) {
447
- await u;
321
+ if (m) {
322
+ await m;
448
323
  return;
449
324
  }
450
- u = (async () => {
325
+ m = (async () => {
451
326
  const {
452
327
  activePredictiveAlgorithms: t,
453
328
  languages: e,
454
329
  currencies: r
455
- } = await m.fetchRecommendationCreateData();
330
+ } = await h.fetchRecommendationCreateData();
456
331
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
457
- const i = this.blockStates[this.currentRecommendationId];
458
- i.filterStatus = !!i.recommendationConfigs.filters.length;
332
+ const n = this.blockStates[this.currentRecommendationId];
333
+ n.filterStatus = !!n.recommendationConfigs.filters.length;
459
334
  }
460
335
  this.currencyList = r;
461
336
  })();
462
337
  try {
463
- await u;
338
+ await m;
464
339
  } finally {
465
- u = null;
466
- }
467
- }
468
- },
469
- /**
470
- * Fetch the partner's Reusable Recommendation Strategies for the EMAIL channel.
471
- *
472
- * Same cache-guard + in-flight dedupe shape as fetchRecommendationCreateData.
473
- * A failure leaves `strategies` empty so the dropdown renders empty rather
474
- * than blocking the panel — the block keeps working on its algorithm.
475
- */
476
- async fetchRecommendationStrategies() {
477
- if (!this.strategies.length) {
478
- if (g) {
479
- await g;
480
- return;
481
- }
482
- this.strategiesLoading = !0, g = (async () => {
483
- try {
484
- this.strategies = await m.fetchRecommendationStrategies();
485
- } catch {
486
- this.strategies = [];
487
- } finally {
488
- this.strategiesLoading = !1;
489
- }
490
- })();
491
- try {
492
- await g;
493
- } finally {
494
- g = null;
340
+ m = null;
495
341
  }
496
342
  }
497
343
  },
498
344
  async fetchRecommendationFilters() {
499
345
  if (!Object.keys(this.filterList).length) {
500
- if (d) {
501
- await d;
346
+ if (u) {
347
+ await u;
502
348
  return;
503
349
  }
504
- d = (async () => {
505
- const t = await m.fetchRecommendationFilters();
350
+ u = (async () => {
351
+ const t = await h.fetchRecommendationFilters();
506
352
  this.filterList = t;
507
353
  })();
508
354
  try {
509
- await d;
355
+ await u;
510
356
  } finally {
511
- d = null;
357
+ u = null;
512
358
  }
513
359
  }
514
360
  },
@@ -523,59 +369,59 @@ const B = () => ({
523
369
  deleteFilterGroup(t) {
524
370
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
525
371
  return;
526
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((n) => n.filterGroup !== t), i = [...new Set(r.map((n) => n.filterGroup))].sort((n, o) => n - o), a = new Map(i.map((n, o) => [n, o + 1]));
527
- e.recommendationConfigs.filters = r.map((n) => ({
528
- ...n,
529
- filterGroup: a.get(n.filterGroup) ?? n.filterGroup
372
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
373
+ e.recommendationConfigs.filters = r.map((i) => ({
374
+ ...i,
375
+ filterGroup: c.get(i.filterGroup) ?? i.filterGroup
530
376
  }));
531
377
  },
532
378
  updateFilter(t) {
533
379
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
534
380
  return;
535
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
381
+ const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
536
382
  if (r !== -1) {
537
- const i = [...e.recommendationConfigs.filters];
538
- i[r] = {
383
+ const n = [...e.recommendationConfigs.filters];
384
+ n[r] = {
539
385
  ...t,
540
- isValid: O(t)
541
- }, e.recommendationConfigs.filters = i;
386
+ isValid: N(t)
387
+ }, e.recommendationConfigs.filters = n;
542
388
  }
543
389
  },
544
390
  deleteFilter(t) {
545
391
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
546
392
  return;
547
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((i) => i.filterNumber === t.filterNumber && i.filterGroup === t.filterGroup);
393
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
548
394
  if (r !== -1) {
549
- let i = [...e.recommendationConfigs.filters];
550
- if (i.splice(r, 1), i.some((n) => n.filterGroup === t.filterGroup)) {
551
- let n = 1;
552
- i = i.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: n++ } : o);
395
+ let n = [...e.recommendationConfigs.filters];
396
+ if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
397
+ let i = 1;
398
+ n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
553
399
  } else {
554
- const n = [...new Set(i.map((s) => s.filterGroup))].sort((s, c) => s - c), o = new Map(n.map((s, c) => [s, c + 1]));
555
- i = i.map((s) => ({
400
+ const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, a) => s - a), o = new Map(i.map((s, a) => [s, a + 1]));
401
+ n = n.map((s) => ({
556
402
  ...s,
557
403
  filterGroup: o.get(s.filterGroup) ?? s.filterGroup
558
404
  }));
559
405
  }
560
- e.recommendationConfigs.filters = i;
406
+ e.recommendationConfigs.filters = n;
561
407
  }
562
408
  },
563
409
  addFilter(t) {
564
410
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
565
411
  return;
566
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], a = r.filter(
412
+ const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], c = r.filter(
567
413
  (o) => o.filterGroup === t.filterGroup
568
- ).length + 1, n = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
569
- n !== -1 ? r.splice(n + 1, 0, {
414
+ ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
415
+ i !== -1 ? r.splice(i + 1, 0, {
570
416
  ...t,
571
- filterNumber: a
417
+ filterNumber: c
572
418
  }) : r.push({
573
419
  ...t,
574
- filterNumber: a
420
+ filterNumber: c
575
421
  }), e.recommendationConfigs.filters = r;
576
422
  },
577
423
  generateFilterQuery() {
578
- return R(this.recommendationConfigs.filters);
424
+ return b(this.recommendationConfigs.filters);
579
425
  },
580
426
  /**
581
427
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -583,28 +429,28 @@ const B = () => ({
583
429
  * every block's recommendationConfigs across user edits.
584
430
  */
585
431
  hasInvalidBlock() {
586
- return Object.values(this.blockStates).some((t) => !A(t.recommendationConfigs, this));
432
+ return Object.values(this.blockStates).some((t) => !x(t.recommendationConfigs, this));
587
433
  },
588
434
  // ====================================================================
589
435
  // Per-Block Product Fetching
590
436
  // ====================================================================
591
437
  async fetchRecommendationProducts() {
592
438
  if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
593
- if (f) {
594
- await f;
439
+ if (d) {
440
+ await d;
595
441
  return;
596
442
  }
597
- f = this._doFetchProducts();
443
+ d = this._doFetchProducts();
598
444
  try {
599
- await f;
445
+ await d;
600
446
  } finally {
601
- f = null;
447
+ d = null;
602
448
  }
603
449
  }
604
450
  },
605
451
  async _doFetchProducts() {
606
- var b;
607
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, i = r.filters.filter((l) => l.isValid), a = R(i), n = ((b = y().find((l) => l.key === r.strategy)) == null ? void 0 : b.path) || "", o = v(), s = parseInt(r.size) || 6, c = {
452
+ var p;
453
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
608
454
  locale: r.language,
609
455
  currency: r.currencySettings.value,
610
456
  partnerName: o.partnerName,
@@ -612,26 +458,26 @@ const B = () => ({
612
458
  details: !0,
613
459
  campaignId: o.variationId
614
460
  };
615
- r.strategy === "manualMerchandising" ? c.productId = r.productIds.join(",") : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), a && (c.filter = a), r.shuffleProducts && (c.shuffle = !0), Object.assign(
616
- c,
617
- _(o.partnerName, r.strategy)
461
+ r.strategy === "manualMerchandising" ? a.productId = r.productIds.join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
462
+ a,
463
+ v(o.partnerName, r.strategy)
618
464
  );
619
- let h;
465
+ let f;
620
466
  try {
621
- h = await m.fetchRecommendationProducts(n, c);
467
+ f = await h.fetchRecommendationProducts(i, a);
622
468
  } catch {
623
- h = [];
469
+ f = [];
624
470
  }
625
471
  if (this.blockStates[t]) {
626
- const l = h.length > 0 ? h : I(s);
472
+ const l = f.length > 0 ? f : S(s);
627
473
  l.length < s ? this.blockStates[t].recommendationProducts = [
628
474
  ...l,
629
- ...I(s - l.length)
475
+ ...S(s - l.length)
630
476
  ] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
631
477
  }
632
478
  }
633
479
  }
634
480
  });
635
481
  export {
636
- Y as useRecommendationExtensionStore
482
+ $ as useRecommendationExtensionStore
637
483
  };
@@ -9,38 +9,26 @@ const l = [
9
9
  getValue: (e) => e.currencySettings.value,
10
10
  getAvailableOptions: (e) => e.currencyList.map((n) => n.text),
11
11
  canBeEmpty: !0
12
- },
13
- {
14
- // Required only behind the feature flag: with the flag off the block is still
15
- // driven by its algorithm, so an empty strategyId is the normal state and must
16
- // not block the save.
17
- //
18
- // Deliberately no `getAvailableOptions`: a strategy the partner deleted in
19
- // Smart Recommender would then fail validation and strand an already-saved
20
- // template. The panel surfaces that case instead (see `strategy.ts`).
21
- key: "strategy",
22
- getValue: (e) => e.strategyId,
23
- condition: (e, n) => n.isRrsEnabled
24
12
  }
25
- ], s = "newsletter.recommendation-fill-required-fields";
26
- function c(e, n, u = l) {
27
- return u.filter((t) => {
28
- var i;
29
- if (t.condition && !t.condition(e, n))
13
+ ], o = "newsletter.recommendation-fill-required-fields";
14
+ function c(e, n, i = l) {
15
+ return i.filter((t) => {
16
+ var u;
17
+ if (t.condition && !t.condition(e))
30
18
  return !1;
31
- const a = (i = t.getAvailableOptions) == null ? void 0 : i.call(t, n);
32
- if (t.canBeEmpty && (a == null ? void 0 : a.length) === 0)
19
+ const r = (u = t.getAvailableOptions) == null ? void 0 : u.call(t, n);
20
+ if (t.canBeEmpty && (r == null ? void 0 : r.length) === 0)
33
21
  return !1;
34
- const r = t.getValue(e);
35
- return r ? a !== void 0 && !a.includes(r) : !0;
22
+ const a = t.getValue(e);
23
+ return a ? r !== void 0 && !r.includes(a) : !0;
36
24
  }).map((t) => t.key);
37
25
  }
38
- function o(e, n) {
26
+ function s(e, n) {
39
27
  return c(e, n).length === 0;
40
28
  }
41
29
  export {
42
30
  l as REQUIRED_RECOMMENDATION_FIELDS,
43
- s as RecommendationRequiredFieldsKey,
31
+ o as RecommendationRequiredFieldsKey,
44
32
  c as getInvalidFields,
45
- o as isConfigValid
33
+ s as isConfigValid
46
34
  };
@@ -5,9 +5,10 @@ const s = {
5
5
  PAGE_TYPE: "data-unsubscribe-page-type",
6
6
  PAGE_LIST: "data-unsubscribe-page-list",
7
7
  BLOCK_ID: "data-unsubscribe-block-id"
8
- }, c = ".unsubscribe-block-v2";
8
+ }, c = ".unsubscribe-block-v2", u = 'a[data-unsubscribe-link="true"], a.unsubscribe-link';
9
9
  export {
10
10
  b as DATA_ATTRIBUTES,
11
11
  c as UNSUBSCRIBE_BLOCK_SELECTOR,
12
- s as UNSUBSCRIBE_EVENTS
12
+ s as UNSUBSCRIBE_EVENTS,
13
+ u as UNSUBSCRIBE_LINK_SELECTOR
13
14
  };