@useinsider/guido 3.18.1-beta.fd927f4 → 3.18.1-beta.fefef3c

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 (52) 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 +83 -87
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +7 -7
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +82 -57
  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 +24 -22
  10. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +28 -24
  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 +21 -0
  14. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +46 -0
  15. package/dist/composables/useActionsApi.js +20 -24
  16. package/dist/composables/useCortexBlueprintBridge.js +54 -115
  17. package/dist/composables/useCustomInterfaceAppearance.js +46 -42
  18. package/dist/composables/useEmailTemplateApplier.js +50 -93
  19. package/dist/composables/useLegacyStrategyConversion.js +61 -0
  20. package/dist/enums/extensions/recommendationBlock.js +17 -14
  21. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +70 -69
  22. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +72 -28
  23. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +45 -44
  24. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +104 -58
  25. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +72 -0
  26. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +7 -7
  27. package/dist/guido.css +1 -1
  28. package/dist/services/recommendationApi.js +93 -84
  29. package/dist/src/@types/config/schemas.d.ts +16 -0
  30. package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
  31. package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts +2 -0
  32. package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
  33. package/dist/src/composables/useConfig.d.ts +4 -0
  34. package/dist/src/composables/useCortexBlueprintBridge.d.ts +3 -4
  35. package/dist/src/composables/useEmailTemplateApplier.d.ts +2 -22
  36. package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
  37. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  38. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +2 -0
  39. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +4 -0
  40. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +54 -1
  41. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +44 -0
  42. package/dist/src/services/recommendationApi.d.ts +2 -1
  43. package/dist/src/stores/config.d.ts +322 -0
  44. package/dist/src/stores/guido-email-editor.d.ts +7 -29
  45. package/dist/src/stores/onboarding.d.ts +808 -10
  46. package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
  47. package/dist/static/assets/icons/line-info.svg.js +5 -0
  48. package/dist/static/styles/components/recommendation-strategy.css.js +70 -5
  49. package/dist/stores/config.js +74 -60
  50. package/dist/stores/guido-email-editor.js +1 -5
  51. package/dist/stores/onboarding.js +46 -36
  52. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  var m = Object.defineProperty;
2
- var C = (h, l, t) => l in h ? m(h, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[l] = t;
3
- var n = (h, l, t) => C(h, typeof l != "symbol" ? l + "" : l, t);
2
+ var C = (g, l, t) => l in g ? m(g, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[l] = t;
3
+ var r = (g, l, t) => C(g, typeof l != "symbol" ? l + "" : l, t);
4
4
  import { useConfig as p } from "../../../../../composables/useConfig.js";
5
5
  import { ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
6
  import { CommonControl as N } from "../../../common-control.js";
@@ -12,9 +12,9 @@ import { registerNodeConfigWriter as b } from "../../utils/nodeConfigWriter.js";
12
12
  import { AlgorithmControl as T } from "./algorithm.js";
13
13
  import { ALGORITHM_CONTROL_ID as ut } from "./algorithm.js";
14
14
  import { CurrencyControl as P } from "./currency.js";
15
- import { CURRENCY_CONTROL_ID as ht } from "./currency.js";
15
+ import { CURRENCY_CONTROL_ID as gt } from "./currency.js";
16
16
  import { FiltersControl as S } from "./filters.js";
17
- import { FILTERS_CONTROL_ID as gt } from "./filters.js";
17
+ import { FILTERS_CONTROL_ID as ht } from "./filters.js";
18
18
  import { LayoutOrientationControl as O } from "./layoutOrientation.js";
19
19
  import { LAYOUT_ORIENTATION_CONTROL_ID as Ct } from "./layoutOrientation.js";
20
20
  import { LocaleControl as L } from "./locale.js";
@@ -29,38 +29,38 @@ import { ShuffleControl as F } from "./shuffle.js";
29
29
  import { SHUFFLE_CONTROL_ID as St } from "./shuffle.js";
30
30
  import { StrategyControl as w } from "./strategy.js";
31
31
  import { STRATEGY_CONTROL_ID as Lt } from "./strategy.js";
32
- import { setCurrencyAttributes as A, getBlockElement as v, isPartnerManagedBlock as x, updateProductContentInPlace as B, regenerateProductRowsWithStyles as U } from "./utils.js";
33
- import { adjustProductsToSize as kt, formatProductPrice as Dt, getCardComposition as Ft, getCurrentLayout as wt, getMainContainerTbody as At, regenerateMobileProductRows as vt, updatePricesInPlace as xt, updateSingleProductContent as Bt } from "./utils.js";
32
+ import { setCurrencyAttributes as A, getBlockElement as B, isPartnerManagedBlock as v, updateProductContentInPlace as x, regenerateProductRowsWithStyles as U } from "./utils.js";
33
+ import { adjustProductsToSize as kt, formatProductPrice as Dt, getCardComposition as Ft, getCurrentLayout as wt, getMainContainerTbody as At, regenerateMobileProductRows as Bt, updatePricesInPlace as vt, updateSingleProductContent as xt } from "./utils.js";
34
34
  import { useDebounceFn as f } from "../../../../../node_modules/@vueuse/shared/index.js";
35
35
  const $ = "ui-elements-recommendation-block";
36
36
  class at extends N {
37
37
  constructor() {
38
38
  super(...arguments);
39
- n(this, "store", R());
40
- n(this, "storeUnsubscription", () => {
39
+ r(this, "store", R());
40
+ r(this, "storeUnsubscription", () => {
41
41
  });
42
42
  // blockId -> fingerprint of the node config as it looked at the last sync.
43
- n(this, "syncedConfigs", /* @__PURE__ */ new Map());
43
+ r(this, "syncedConfigs", /* @__PURE__ */ new Map());
44
44
  // A config change waiting to reach the node config. Deferred so it can ride the
45
45
  // re-render's single apply() — one user action must cost one undo press.
46
- n(this, "pendingNodeConfigWrite", null);
47
- n(this, "pendingConfigFlushTimer", null);
46
+ r(this, "pendingNodeConfigWrite", null);
47
+ r(this, "pendingConfigFlushTimer", null);
48
48
  // Sub-control instances for lifecycle management
49
- n(this, "algorithmControl", null);
50
- n(this, "localeControl", null);
51
- n(this, "currencyControl", null);
52
- n(this, "productCountControl", null);
53
- n(this, "productLayoutControl", null);
54
- n(this, "filtersControl", null);
55
- n(this, "shuffleControl", null);
56
- n(this, "pricePlacementControl", null);
57
- n(this, "layoutOrientationControl", null);
58
- n(this, "strategyControl", null);
59
- n(this, "rrsEnabled", !1);
49
+ r(this, "algorithmControl", null);
50
+ r(this, "localeControl", null);
51
+ r(this, "currencyControl", null);
52
+ r(this, "productCountControl", null);
53
+ r(this, "productLayoutControl", null);
54
+ r(this, "filtersControl", null);
55
+ r(this, "shuffleControl", null);
56
+ r(this, "pricePlacementControl", null);
57
+ r(this, "layoutOrientationControl", null);
58
+ r(this, "strategyControl", null);
59
+ r(this, "rrsEnabled", !1);
60
60
  /**
61
61
  * Debounced product fetch to prevent rapid API calls during config changes
62
62
  */
63
- n(this, "_debouncedFetchProducts", f(async () => {
63
+ r(this, "_debouncedFetchProducts", f(async () => {
64
64
  try {
65
65
  await this.store.fetchRecommendationProducts();
66
66
  } finally {
@@ -78,16 +78,16 @@ class at extends N {
78
78
  * count. The store pads products to the configured size, so in-place only
79
79
  * fails when the size actually changed.
80
80
  */
81
- n(this, "_debouncedRegenerateWithProducts", f(() => {
81
+ r(this, "_debouncedRegenerateWithProducts", f(() => {
82
82
  const t = this.store.recommendationProducts;
83
83
  if (!this.currentNode || !this.api)
84
84
  return;
85
85
  const e = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(e);
86
- if (x(this.currentNode)) {
86
+ if (v(this.currentNode)) {
87
87
  o && (e.apply(new y("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
88
88
  return;
89
89
  }
90
- B({
90
+ x({
91
91
  currentNode: this.currentNode,
92
92
  documentModifier: e,
93
93
  products: t
@@ -142,8 +142,8 @@ class at extends N {
142
142
  const e = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
143
143
  if (!e)
144
144
  return;
145
- const o = this._getRecommendationIdFromNode(t) === null ? null : c.getConfig(t), r = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _);
146
- e.classList.toggle("strategy-block", r);
145
+ const o = this._getRecommendationIdFromNode(t) === null ? null : c.getConfig(t), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _), s = this.rrsEnabled && !!o && !n;
146
+ e.classList.toggle("strategy-block", n), e.classList.toggle("legacy-strategy-block", s);
147
147
  }
148
148
  async onRender() {
149
149
  var o;
@@ -161,9 +161,9 @@ class at extends N {
161
161
  const e = this._getRecommendationIdFromNode(t);
162
162
  e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigIfChanged(e), this._showControlsForBlock(t), e !== null && !((o = this.store.blockStates[e]) != null && o.isInitialized) && this._fetchBlockData(e).then(() => {
163
163
  this._initializeSubControls();
164
- }), this._subControls.forEach((r) => {
165
- var i;
166
- r != null && r.api && (r.currentNode = t, (i = r.onTemplateNodeUpdated) == null || i.call(r, t));
164
+ }), this._subControls.forEach((n) => {
165
+ var s;
166
+ n != null && n.api && (n.currentNode = t, (s = n.onTemplateNodeUpdated) == null || s.call(n, t));
167
167
  });
168
168
  }
169
169
  onDestroy() {
@@ -210,11 +210,11 @@ class at extends N {
210
210
  const t = this.store.currentRecommendationId;
211
211
  if (!this.currentNode || !this.api || t === null)
212
212
  return;
213
- const { filters: e, strategyId: o, size: r } = this.store.recommendationConfigs;
213
+ const { filters: e, strategyId: o, size: n, nodeConfigVersion: s } = this.store.recommendationConfigs;
214
214
  this.pendingNodeConfigWrite = {
215
215
  blockId: t,
216
216
  node: this.currentNode,
217
- updates: { filters: e, strategyId: o, size: r }
217
+ updates: { filters: e, strategyId: o, size: n, configVersion: s }
218
218
  };
219
219
  }
220
220
  /**
@@ -257,11 +257,12 @@ class at extends N {
257
257
  JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategyId === t.updates.strategyId && o.size === t.updates.size || c.updateConfig(this.api, e, t.updates, "Update recommendation filters");
258
258
  }
259
259
  _syncNodeConfigToStore() {
260
- var r;
261
- const t = c.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
260
+ var n;
261
+ const t = c.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
262
262
  this.store.patchCurrentBlockConfig({
263
263
  strategy: t.strategy,
264
264
  strategyId: t.strategyId,
265
+ nodeConfigVersion: t.configVersion,
265
266
  language: t.language,
266
267
  size: t.size,
267
268
  productIds: t.productIds,
@@ -300,8 +301,8 @@ class at extends N {
300
301
  t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
301
302
  this.store.fetchRecommendationCreateData(),
302
303
  this.store.fetchRecommendationFilters()
303
- ])).forEach((o, r) => {
304
- o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][r]} failed`, o.reason);
304
+ ])).forEach((o, n) => {
305
+ o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][n]} failed`, o.reason);
305
306
  }), this._applySmartDefaults();
306
307
  try {
307
308
  await this.store.fetchRecommendationProducts();
@@ -323,30 +324,30 @@ class at extends N {
323
324
  if (!this.currentNode || !this.api)
324
325
  return;
325
326
  const t = c.getConfig(this.currentNode), e = {};
326
- let o = null, r = null, i = null;
327
+ let o = null, n = null, s = null;
327
328
  if (t.currency.code === a.currency.code) {
328
- const { currencyList: s } = this.store;
329
- s.length > 0 && (s.some(
329
+ const { currencyList: i } = this.store;
330
+ i.length > 0 && (i.some(
330
331
  (d) => d.value === `price.${a.currency.code}`
331
- ) || (o = s[0].value.replace("price.", ""), e.currency = {
332
+ ) || (o = i[0].value.replace("price.", ""), e.currency = {
332
333
  ...a.currency,
333
334
  code: o,
334
335
  symbol: o
335
336
  }));
336
337
  }
337
338
  if (t.strategy === a.strategy) {
338
- const s = this.store.getActivePredictiveAlgorithms;
339
- s.length > 0 && (s.some(
339
+ const i = this.store.getActivePredictiveAlgorithms;
340
+ i.length > 0 && (i.some(
340
341
  (d) => d.value === a.strategy
341
- ) || (r = s[0].value, e.strategy = r));
342
+ ) || (n = i[0].value, e.strategy = n));
342
343
  }
343
344
  if (t.language === a.language) {
344
- const s = this.store.getLanguages;
345
- s.length > 0 && (s.some(
345
+ const i = this.store.getLanguages;
346
+ i.length > 0 && (i.some(
346
347
  (d) => d.value === a.language
347
- ) || (i = s[0].value, e.language = i));
348
+ ) || (s = i[0].value, e.language = s));
348
349
  }
349
- !o && !r && !i || (c.updateConfig(
350
+ !o && !n && !s || (c.updateConfig(
350
351
  this.api,
351
352
  this.currentNode,
352
353
  e,
@@ -367,22 +368,22 @@ class at extends N {
367
368
  thousandSeparator: a.currency.thousandSeparator
368
369
  }
369
370
  } : {},
370
- ...r ? { strategy: r } : {},
371
- ...i ? { language: i } : {}
371
+ ...n ? { strategy: n } : {},
372
+ ...s ? { language: s } : {}
372
373
  }, { triggerRefetch: !1 }));
373
374
  }
374
375
  /**
375
376
  * Reads the recommendation-id attribute from the block element within the node
376
377
  */
377
378
  _getRecommendationIdFromNode(t) {
378
- const e = v(t);
379
+ const e = B(t);
379
380
  if (!e || !("getAttribute" in e))
380
381
  return null;
381
382
  const o = e.getAttribute(I);
382
383
  if (!o)
383
384
  return null;
384
- const r = parseInt(o);
385
- return Number.isNaN(r) ? null : r;
385
+ const n = parseInt(o);
386
+ return Number.isNaN(n) ? null : n;
386
387
  }
387
388
  /**
388
389
  * Listen to store changes that require product refresh or regeneration.
@@ -399,17 +400,17 @@ class at extends N {
399
400
  */
400
401
  _listenStateUpdates() {
401
402
  const { store: t } = this;
402
- let e = t.recommendationProducts, o = t.$state.configVersion, r = t.currentRecommendationId;
403
+ let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
403
404
  this.storeUnsubscription = t.$subscribe(() => {
404
- const i = t.currentRecommendationId;
405
- if (i !== r) {
406
- r = i, e = t.recommendationProducts, o = t.$state.configVersion;
405
+ const s = t.currentRecommendationId;
406
+ if (s !== n) {
407
+ n = s, e = t.recommendationProducts, o = t.$state.configVersion;
407
408
  return;
408
409
  }
409
- const s = t.$state.configVersion;
410
- s !== o && (o = s, this._capturePendingNodeConfigWrite(), this._debouncedFetchProducts());
411
- const u = t.recommendationProducts, d = u !== e, g = Array.isArray(u) && u.length > 0;
412
- d && g && (e = u, this._debouncedRegenerateWithProducts());
410
+ const i = t.$state.configVersion;
411
+ i !== o && (o = i, this._capturePendingNodeConfigWrite(), this._debouncedFetchProducts());
412
+ const u = t.recommendationProducts, d = u !== e, h = Array.isArray(u) && u.length > 0;
413
+ d && h && (e = u, this._debouncedRegenerateWithProducts());
413
414
  });
414
415
  }
415
416
  }
@@ -417,9 +418,9 @@ export {
417
418
  ut as ALGORITHM_CONTROL_ID,
418
419
  T as AlgorithmControl,
419
420
  $ as CONTROL_BLOCK_ID,
420
- ht as CURRENCY_CONTROL_ID,
421
+ gt as CURRENCY_CONTROL_ID,
421
422
  P as CurrencyControl,
422
- gt as FILTERS_CONTROL_ID,
423
+ ht as FILTERS_CONTROL_ID,
423
424
  S as FiltersControl,
424
425
  Ct as LAYOUT_ORIENTATION_CONTROL_ID,
425
426
  yt as LOCALE_CONTROL_ID,
@@ -438,15 +439,15 @@ export {
438
439
  w as StrategyControl,
439
440
  kt as adjustProductsToSize,
440
441
  Dt as formatProductPrice,
441
- v as getBlockElement,
442
+ B as getBlockElement,
442
443
  Ft as getCardComposition,
443
444
  wt as getCurrentLayout,
444
445
  At as getMainContainerTbody,
445
- x as isPartnerManagedBlock,
446
- vt as regenerateMobileProductRows,
446
+ v as isPartnerManagedBlock,
447
+ Bt as regenerateMobileProductRows,
447
448
  U as regenerateProductRowsWithStyles,
448
449
  A as setCurrencyAttributes,
449
- xt as updatePricesInPlace,
450
- B as updateProductContentInPlace,
451
- Bt as updateSingleProductContent
450
+ vt as updatePricesInPlace,
451
+ x as updateProductContentInPlace,
452
+ xt as updateSingleProductContent
452
453
  };
@@ -1,26 +1,32 @@
1
- var d = Object.defineProperty;
2
- var y = (r, s, t) => s in r ? d(r, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[s] = t;
3
- var o = (r, s, t) => y(r, typeof s != "symbol" ? s + "" : s, t);
4
- import { ACADEMY_LINKS as m } from "../../../../../enums/academy.js";
5
- import { CommonControl as h } from "../../../common-control.js";
6
- import { useRecommendationExtensionStore as u } from "../../store/recommendation.js";
7
- const p = "recommendation-strategy-control";
8
- class f extends h {
1
+ var p = Object.defineProperty;
2
+ var v = (i, s, t) => s in i ? p(i, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[s] = t;
3
+ var r = (i, s, t) => v(i, typeof s != "symbol" ? s + "" : s, t);
4
+ import { useLegacyStrategyConversion as _ } from "../../../../../composables/useLegacyStrategyConversion.js";
5
+ import { ACADEMY_LINKS as b } from "../../../../../enums/academy.js";
6
+ import { useOnboardingStore as S } from "../../../../../stores/onboarding.js";
7
+ import { CommonControl as f } from "../../../common-control.js";
8
+ import { useRecommendationExtensionStore as $ } from "../../store/recommendation.js";
9
+ const C = "recommendation-strategy-control";
10
+ class N extends f {
9
11
  constructor() {
10
12
  super(...arguments);
11
- o(this, "store", u());
12
- o(this, "storeUnsubscription", () => {
13
+ r(this, "store", $());
14
+ r(this, "onboardingStore", S());
15
+ r(this, "legacyConversion", _());
16
+ r(this, "storeUnsubscription", () => {
13
17
  });
14
- o(this, "listeners", []);
15
- o(this, "lastPaintedState", null);
18
+ r(this, "listeners", []);
19
+ r(this, "lastPaintedState", null);
16
20
  }
17
21
  getId() {
18
- return p;
22
+ return C;
19
23
  }
20
24
  getTemplate() {
21
25
  const t = this.api.translate(
22
26
  "You can assign a recommendation strategy by selecting an existing one or creating a new one to show specific content."
23
- ), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy");
27
+ ), e = this.api.translate("For more information, you can"), a = this.api.translate("visit Academy"), o = this.api.translate("Legacy Strategy"), n = this.api.translate(
28
+ "Note that this is an older version of the Recommendation Strategy. We recommend you update it to the new Recommendation Strategy for an improved experience."
29
+ );
24
30
  return `
25
31
  <div class="strategy-control-container">
26
32
  <div class="strategy-control-header">
@@ -31,7 +37,7 @@ class f extends h {
31
37
  ${t}
32
38
  ${e}
33
39
  <a
34
- href="${m.EMAIL_RECOMMENDATION_BLOCK}"
40
+ href="${b.EMAIL_RECOMMENDATION_BLOCK}"
35
41
  target="_blank"
36
42
  rel="noopener noreferrer">${a}</a>.
37
43
  </p>
@@ -53,6 +59,33 @@ class f extends h {
53
59
  })
54
60
  ], "strategy-control-cta-row")}
55
61
  </div>
62
+ <div data-strategy-legacy-state style="display: none;">
63
+ <div class="strategy-control-notice-row">
64
+ <div class="strategy-control-notice">
65
+ <p class="strategy-control-notice-text">${n}</p>
66
+ </div>
67
+ </div>
68
+ <div class="strategy-control-name-band">
69
+ <span class="strategy-control-name">${o}</span>
70
+ ${this._strategyAction({
71
+ id: "guido__btn-update-legacy-strategy",
72
+ label: this.api.translate("Update"),
73
+ modifier: "update"
74
+ })}
75
+ </div>
76
+ <div class="strategy-control-actions">
77
+ ${this._strategyAction({
78
+ id: "guido__btn-change-legacy-strategy",
79
+ label: this.api.translate("Change"),
80
+ modifier: "change"
81
+ })}
82
+ ${this._strategyAction({
83
+ id: "guido__btn-remove-legacy-strategy",
84
+ label: this.api.translate("Remove"),
85
+ modifier: "remove"
86
+ })}
87
+ </div>
88
+ </div>
56
89
  <div data-strategy-assigned-state style="display: none;">
57
90
  <div class="strategy-control-name-band">
58
91
  <span class="strategy-control-name" data-strategy-name></span>
@@ -88,6 +121,8 @@ class f extends h {
88
121
  this._renderState();
89
122
  }), this.store.recommendationConfigs.strategyId && !this.store.strategies.length && this.store.fetchStrategies().catch(() => {
90
123
  });
124
+ const t = this.store.currentRecommendationId, e = t !== null && !!this.store.blockStates[t], a = this.store.isLegacyStrategyBlock;
125
+ e && !this.store.recommendationConfigs.strategyId && !a && this.onboardingStore.startOnboarding("recommendationStrategyOnboarding"), e && a && this.onboardingStore.startOnboarding("recommendationLegacyStrategyOnboarding");
91
126
  }
92
127
  onDestroy() {
93
128
  this._teardown();
@@ -100,25 +135,34 @@ class f extends h {
100
135
  const t = this.getContainer();
101
136
  if (!t)
102
137
  return;
103
- const e = (a, n) => {
104
- const i = t.querySelector(a);
105
- i && (i.addEventListener("click", n), this.listeners.push({ element: i, handler: n }));
138
+ const e = (a, o) => {
139
+ const n = t.querySelector(a);
140
+ n && (n.addEventListener("click", o), this.listeners.push({ element: n, handler: o }));
106
141
  };
107
- e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal());
142
+ e("#guido__btn-assign-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-change-legacy-strategy", () => this.store.openAssignStrategyDrawer()), e("#guido__btn-remove-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-remove-legacy-strategy", () => this.store.openRemoveStrategyModal()), e("#guido__btn-update-legacy-strategy", () => {
143
+ this.legacyConversion.convertLegacyStrategy();
144
+ });
108
145
  }
109
146
  _renderState() {
110
- var l;
111
- const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((l = this.store.assignedStrategy) == null ? void 0 : l.name) ?? "" : "", a = `${t}\0${e}`;
112
- if (a === this.lastPaintedState)
147
+ var h;
148
+ const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((h = this.store.assignedStrategy) == null ? void 0 : h.name) ?? "" : "", a = this.store.legacyConversionLoading, o = this.store.isLegacyStrategyBlock, n = `${t}\0${e}\0${a}\0${o}`;
149
+ if (n === this.lastPaintedState)
150
+ return;
151
+ const c = this.getContainer();
152
+ if (!c)
113
153
  return;
114
- const n = this.getContainer();
115
- if (!n)
154
+ const d = c.querySelector("[data-strategy-empty-state]"), y = c.querySelector("[data-strategy-assigned-state]"), g = c.querySelector("[data-strategy-legacy-state]"), m = c.querySelector("[data-strategy-name]");
155
+ if (!d || !y || !g)
116
156
  return;
117
- const i = n.querySelector("[data-strategy-empty-state]"), c = n.querySelector("[data-strategy-assigned-state]"), g = n.querySelector("[data-strategy-name]");
118
- !i || !c || (i.style.display = t ? "none" : "", c.style.display = t ? "" : "none", g && t && (g.textContent = e || `#${t}`), this.lastPaintedState = a);
157
+ const u = t ? y : o ? g : d;
158
+ [d, y, g].forEach((l) => {
159
+ l.style.display = l === u ? "" : "none";
160
+ }), g.querySelectorAll("button").forEach((l) => {
161
+ l.disabled = a;
162
+ }), g.classList.toggle("is-converting", a), m && t && (m.textContent = e || `#${t}`), this.lastPaintedState = n;
119
163
  }
120
164
  }
121
165
  export {
122
- p as STRATEGY_CONTROL_ID,
123
- f as StrategyControl
166
+ C as STRATEGY_CONTROL_ID,
167
+ N as StrategyControl
124
168
  };
@@ -94,9 +94,9 @@ function j(e, t = {}) {
94
94
  const u = s ?? P(n), l = y.getConfig(n);
95
95
  if (u === "list" || !l.mobileLayoutEnabled)
96
96
  return te({ currentNode: n, documentModifier: o });
97
- const c = A(), a = $(r, c.recommendationProducts), f = i ?? U(n, c.filterList), p = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${k(a, u, {
97
+ const c = A(), f = $(r, c.recommendationProducts), a = i ?? U(n, c.filterList), p = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${k(f, u, {
98
98
  productsPerRow: l.mobileCardsInRow,
99
- composition: f,
99
+ composition: a,
100
100
  filterList: c.filterList,
101
101
  priceInline: !l.priceMovedToNextLine,
102
102
  // Match the initial render's gutter so a regeneration never changes block height (SD-143023, #386).
@@ -122,9 +122,9 @@ function ie(e, t = {}) {
122
122
  const u = n.querySelector(L) ?? n.querySelector(W);
123
123
  if (!u)
124
124
  return !1;
125
- const l = A(), c = $(r, l.recommendationProducts), { cardsInRow: a } = y.getConfig(n), f = i ?? U(n, l.filterList), d = s ?? P(n), p = y.getConfig(n), E = k(c, d, {
126
- productsPerRow: a,
127
- composition: f,
125
+ const l = A(), c = $(r, l.recommendationProducts), { cardsInRow: f } = y.getConfig(n), a = i ?? U(n, l.filterList), d = s ?? P(n), p = y.getConfig(n), E = k(c, d, {
126
+ productsPerRow: f,
127
+ composition: a,
128
128
  filterList: l.filterList,
129
129
  priceInline: !p.priceMovedToNextLine,
130
130
  // Match the initial render's gutter so a regeneration never changes block height (SD-143023, #386).
@@ -153,10 +153,10 @@ function ce(e, t, n) {
153
153
  return !1;
154
154
  const s = A(), i = r.split(",").filter(Boolean), u = D(i, o, s.filterList), l = [], c = u.join(",") !== i.join(",");
155
155
  c && l.push([R, u.join(",")]);
156
- const a = le(
156
+ const f = le(
157
157
  o.getAttribute(q)
158
- ), f = a && z(a, o, s.filterList);
159
- if (a && f && f.join(",") !== a.join(",") && l.push([q, JSON.stringify(f)]), l.length === 0)
158
+ ), a = f && z(f, o, s.filterList);
159
+ if (f && a && a.join(",") !== f.join(",") && l.push([q, JSON.stringify(a)]), l.length === 0)
160
160
  return !1;
161
161
  if (l.forEach(([d, p]) => {
162
162
  t.modifyHtml(o).setAttribute(d, p);
@@ -177,19 +177,20 @@ function Te(e) {
177
177
  products: r,
178
178
  layout: s,
179
179
  composition: i,
180
- skipStylePreservation: u
180
+ skipStylePreservation: u,
181
+ forceApply: l = !1
181
182
  } = e;
182
183
  if (!t)
183
184
  return;
184
- const l = u ? {} : x(t), c = {
185
+ const c = u ? {} : x(t), f = {
185
186
  currentNode: t,
186
187
  documentModifier: n,
187
188
  products: r,
188
189
  layout: s,
189
190
  composition: i
190
191
  };
191
- let a = ie(c, l);
192
- a = j(c, l) || a, a && (ce(t, n, i), n.apply(new S("Regenerate products with styles"))), o == null || o();
192
+ let a = ie(f, c);
193
+ a = j(f, c) || a, a && ce(t, n, i), (a || l) && n.apply(new S("Regenerate products with styles")), o == null || o();
193
194
  }
194
195
  function Re(e, t) {
195
196
  return e.length === t ? e : e.length > t ? e.slice(0, t) : [...e, ...H(t - e.length)];
@@ -250,16 +251,16 @@ function se(e) {
250
251
  omnibusDiscountEl: l,
251
252
  buttonEl: c
252
253
  } = e;
253
- let a = !1;
254
+ let f = !1;
254
255
  if (o && "querySelector" in o) {
255
- const f = o.querySelector("img");
256
- f && (t.modifyHtml(f).setAttribute("src", X(n.image_url)).setAttribute("alt", n.name), a = !0);
256
+ const a = o.querySelector("img");
257
+ a && (t.modifyHtml(a).setAttribute("src", X(n.image_url)).setAttribute("alt", n.name), f = !0);
257
258
  const d = o.querySelector("a");
258
- d && (t.modifyHtml(d).setAttribute("href", n.url), a = !0);
259
+ d && (t.modifyHtml(d).setAttribute("href", n.url), f = !0);
259
260
  }
260
261
  if (r && "querySelector" in r) {
261
- const f = r.querySelector("strong") ?? r.querySelector("p");
262
- b(t, f ?? null, n.name) && (a = !0);
262
+ const a = r.querySelector("strong") ?? r.querySelector("p");
263
+ b(t, a ?? null, n.name) && (f = !0);
263
264
  }
264
265
  if (K({
265
266
  documentModifier: t,
@@ -268,11 +269,11 @@ function se(e) {
268
269
  oldPriceEl: i,
269
270
  omnibusPriceEl: u,
270
271
  omnibusDiscountEl: l
271
- }) && (a = !0), c && "querySelector" in c) {
272
- const f = c.querySelector("a.es-button") || c.querySelector("a");
273
- f && (t.modifyHtml(f).setAttribute("href", n.url), a = !0);
272
+ }) && (f = !0), c && "querySelector" in c) {
273
+ const a = c.querySelector("a.es-button") || c.querySelector("a");
274
+ a && (t.modifyHtml(a).setAttribute("href", n.url), f = !0);
274
275
  }
275
- return a;
276
+ return f;
276
277
  }
277
278
  function V(e) {
278
279
  return "querySelector" in e ? e.querySelector(L) ?? e : e;
@@ -308,14 +309,14 @@ function fe(e, t, n) {
308
309
  let s = !1;
309
310
  return r.forEach((i, u) => {
310
311
  const l = Math.min(i.length, n.length);
311
- i.slice(0, l).forEach((c, a) => {
312
+ i.slice(0, l).forEach((c, f) => {
312
313
  if (!("querySelector" in c))
313
314
  return;
314
- const f = ae(u, n[a]);
315
- if (f === null)
315
+ const a = ae(u, n[f]);
316
+ if (a === null)
316
317
  return;
317
318
  const d = c.querySelector("p") ?? null;
318
- b(t, d, f) && (s = !0);
319
+ b(t, d, a) && (s = !0);
319
320
  });
320
321
  }), s;
321
322
  }
@@ -336,9 +337,9 @@ function O(e, t, n) {
336
337
  `[esd-extension-block-id="${m.OMNIBUS_DISCOUNT}"]`
337
338
  ), c = e.querySelectorAll(
338
339
  `[esd-extension-block-id="${m.BUTTON}"]`
339
- ), a = Math.min(o.length, n.length);
340
- let f = !1;
341
- for (let d = 0; d < a; d++) {
340
+ ), f = Math.min(o.length, n.length);
341
+ let a = !1;
342
+ for (let d = 0; d < f; d++) {
342
343
  const p = se({
343
344
  documentModifier: t,
344
345
  product: n[d],
@@ -350,33 +351,33 @@ function O(e, t, n) {
350
351
  omnibusDiscountEl: l[d] ?? null,
351
352
  buttonEl: c[d] ?? null
352
353
  });
353
- f = f || p;
354
+ a = a || p;
354
355
  }
355
- return fe(e, t, n) && (f = !0), f;
356
+ return fe(e, t, n) && (a = !0), a;
356
357
  }
357
358
  function qe(e) {
358
- const { currentNode: t, documentModifier: n, products: o } = e;
359
+ const { currentNode: t, documentModifier: n, products: o, forceApply: r = !1 } = e;
359
360
  if (!t || !("querySelectorAll" in t))
360
361
  return !1;
361
- const r = V(t);
362
- if (!("querySelectorAll" in r) || r.querySelectorAll(
362
+ const s = V(t);
363
+ if (!("querySelectorAll" in s) || s.querySelectorAll(
363
364
  `[esd-extension-block-id="${m.IMAGE}"]`
364
365
  ).length !== o.length)
365
366
  return !1;
366
- let i = O(r, n, o);
367
- const u = P(t), l = y.getConfig(t);
368
- if (u !== "list" && l.mobileLayoutEnabled && "querySelector" in t) {
369
- const c = t.querySelector(N);
370
- if (c) {
367
+ let u = O(s, n, o);
368
+ const l = P(t), c = y.getConfig(t);
369
+ if (l !== "list" && c.mobileLayoutEnabled && "querySelector" in t) {
370
+ const f = t.querySelector(N);
371
+ if (f) {
371
372
  const a = O(
372
- c,
373
+ f,
373
374
  n,
374
375
  o
375
376
  );
376
- i = i || a;
377
+ u = u || a;
377
378
  }
378
379
  }
379
- return i && n.apply(new S("Updated product content in-place")), !0;
380
+ return (u || r) && n.apply(new S("Updated product content in-place")), !0;
380
381
  }
381
382
  function _(e, t, n) {
382
383
  if (!("querySelectorAll" in e))
@@ -417,8 +418,8 @@ function Me(e) {
417
418
  if (u !== "list" && l.mobileLayoutEnabled && "querySelector" in t) {
418
419
  const c = t.querySelector(N);
419
420
  if (c) {
420
- const a = _(c, n, r);
421
- i = i || a;
421
+ const f = _(c, n, r);
422
+ i = i || f;
422
423
  }
423
424
  }
424
425
  return i && n.apply(new S("Updated price formatting in-place")), i;