@useinsider/guido 3.6.0-beta.a8be7f8 → 3.6.0-beta.d0bfe20

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.
@@ -3,7 +3,7 @@ import a from "./UnsubscribePageSelection.vue2.js";
3
3
  import n from "../../../_virtual/_plugin-vue2_normalizer.js";
4
4
  var o = function() {
5
5
  var r = this, e = r._self._c, t = r._self._setupProxy;
6
- return e(t.WpDrawer, { attrs: { id: "unsubscribe-modal", "description-status": "", size: "large", "footer-button-group-options": t.footerButtonGroupOptions, status: t.unsubscribeStore.pageSelectionDrawerStatus, "title-text": t.trans("newsletter.select-a-template") }, on: { cancelOrBackButtonEvent: t.handleBack, onCloseEvent: t.closeModal, primaryButtonEvent: t.handleSave }, scopedSlots: r._u([{ key: "headerBottomSlot", fn: function() {
6
+ return e(t.WpDrawer, { attrs: { id: "unsubscribe-modal", "description-status": "", size: "large", "footer-button-group-options": t.footerButtonGroupOptions, status: t.unsubscribeStore.pageSelectionDrawerStatus, "title-text": t.trans("newsletter.select-a-template") }, on: { cancelOrBackButtonEvent: t.handleBack, onCloseEvent: t.handleClose, primaryButtonEvent: t.handleSave }, scopedSlots: r._u([{ key: "headerBottomSlot", fn: function() {
7
7
  return [e(t.UnsubscribeBreadcrumb, { staticClass: "px-5 py-3" })];
8
8
  }, proxy: !0 }]) }, [e("div", { staticClass: "d-g templates-wrapper" }, r._l(t.unsubscribeStore.getTemplatesByActiveType, function(s) {
9
9
  return e("div", { key: s.id, staticClass: "template-wrapper", on: { click: function(u) {
@@ -16,7 +16,7 @@ var o = function() {
16
16
  i,
17
17
  !1,
18
18
  null,
19
- "df672485"
19
+ "824fa820"
20
20
  );
21
21
  const _ = c.exports;
22
22
  export {
@@ -1,15 +1,15 @@
1
- import { defineComponent as g, ref as y, computed as n, watch as S } from "vue";
2
- import T from "../../wrappers/WpDrawer.vue.js";
3
- import { useToaster as v } from "../../../composables/useToaster.js";
1
+ import { defineComponent as y, ref as S, computed as a, watch as T } from "vue";
2
+ import v from "../../wrappers/WpDrawer.vue.js";
3
+ import { useToaster as C } from "../../../composables/useToaster.js";
4
4
  import { useTranslations as B } from "../../../composables/useTranslations.js";
5
- import { ToasterTypeOptions as C } from "../../../enums/toaster.js";
6
- import { useUnsubscribeStore as w } from "../../../stores/unsubscribe.js";
7
- import { InContainer as h } from "@useinsider/design-system-vue";
8
- import U from "./UnsubscribeBreadcrumb.vue.js";
9
- const F = /* @__PURE__ */ g({
5
+ import { ToasterTypeOptions as w } from "../../../enums/toaster.js";
6
+ import { useUnsubscribeStore as h } from "../../../stores/unsubscribe.js";
7
+ import { InContainer as U } from "@useinsider/design-system-vue";
8
+ import P from "./UnsubscribeBreadcrumb.vue.js";
9
+ const L = /* @__PURE__ */ y({
10
10
  __name: "UnsubscribePageSelection",
11
- setup(P) {
12
- const s = B(), e = w(), { showToaster: a } = v(), o = y(!1), c = n(() => e.isActiveTypeLastInCollection ? o.value ? s("unsubscription-preference.applying-changes") : s("statistics.apply") : s("products.select-and-continue")), i = n(() => e.pageSelectionUpdateStatus && e.isActiveTypeFirstInCollection ? s("products.cancel") : s("newsletter.back")), u = n(() => ({
11
+ setup(_) {
12
+ const s = B(), e = h(), { showToaster: r } = C(), o = S(!1), c = a(() => e.isActiveTypeLastInCollection ? o.value ? s("unsubscription-preference.applying-changes") : s("statistics.apply") : s("products.select-and-continue")), i = a(() => e.pageSelectionUpdateStatus && e.isActiveTypeFirstInCollection ? s("products.cancel") : s("newsletter.back")), u = a(() => ({
13
13
  primaryButton: {
14
14
  styling: "solid",
15
15
  type: "primary",
@@ -23,42 +23,44 @@ const F = /* @__PURE__ */ g({
23
23
  labelText: i.value,
24
24
  disabledStatus: o.value
25
25
  }
26
- })), p = (t) => e.getSelectedTemplateByActiveType === t ? "bor-w-3 bor-s-s bor-c-7" : "bor-w-1 bor-s-s bor-c-6", r = (t) => {
26
+ })), p = (t) => e.getSelectedTemplateByActiveType === t ? "bor-w-3 bor-s-s bor-c-7" : "bor-w-1 bor-s-s bor-c-6", n = (t) => {
27
27
  e.pageSelectionDrawerStatus = !1, t && setTimeout(() => {
28
28
  t();
29
29
  }, 500);
30
30
  }, d = () => {
31
+ n(), e.pageSelectionUpdateStatus || document.dispatchEvent(new CustomEvent("unsubscribe:cancel"));
32
+ }, m = () => {
31
33
  if (e.isActiveTypeFirstInCollection) {
32
- r(), e.pageSelectionUpdateStatus || (e.typeSelectionDrawerStatus = !0);
34
+ n(), e.pageSelectionUpdateStatus || (e.typeSelectionDrawerStatus = !0);
33
35
  return;
34
36
  }
35
37
  e.setPreviousType();
36
- }, m = () => {
38
+ }, b = () => {
37
39
  if (e.isActiveTypeLastInCollection) {
38
40
  o.value = !0;
39
- const t = e.selectedCollectionType, l = e.getSelectedTemplatesByCollection(t), f = e.getSelectedUnsubscribePagesByCollection(t);
40
- e.removeUnsubscribePages(f), e.addUnsubscribePages(l), document.dispatchEvent(new CustomEvent("unsubscribe:select", {
41
+ const t = e.selectedCollectionType, l = e.getSelectedTemplatesByCollection(t), g = e.getSelectedUnsubscribePagesByCollection(t);
42
+ e.removeUnsubscribePages(g), e.addUnsubscribePages(l), document.dispatchEvent(new CustomEvent("unsubscribe:select", {
41
43
  detail: {
42
44
  collectionType: t,
43
45
  selectedPages: l
44
46
  }
45
- })), r(() => {
46
- o.value = !1, a({
47
- type: C.Success,
47
+ })), n(() => {
48
+ o.value = !1, r({
49
+ type: w.Success,
48
50
  message: s("global-unsubscribe.pages-were-attached")
49
51
  });
50
52
  });
51
53
  return;
52
54
  }
53
55
  e.setNextType();
54
- }, b = (t) => {
56
+ }, f = (t) => {
55
57
  e.setSelectedTemplate(t);
56
58
  };
57
- return S(() => e.pageSelectionDrawerStatus, (t) => {
59
+ return T(() => e.pageSelectionDrawerStatus, (t) => {
58
60
  t && e.pageSelectionUpdateStatus && e.fetchTemplates();
59
- }), { __sfc: !0, trans: s, unsubscribeStore: e, showToaster: a, isApplying: o, getPrimaryButtonText: c, getCancelOrBackButtonText: i, footerButtonGroupOptions: u, getBorderClass: p, closeModal: r, handleBack: d, handleSave: m, selectTemplate: b, WpDrawer: T, InContainer: h, UnsubscribeBreadcrumb: U };
61
+ }), { __sfc: !0, trans: s, unsubscribeStore: e, showToaster: r, isApplying: o, getPrimaryButtonText: c, getCancelOrBackButtonText: i, footerButtonGroupOptions: u, getBorderClass: p, closeModal: n, handleClose: d, handleBack: m, handleSave: b, selectTemplate: f, WpDrawer: v, InContainer: U, UnsubscribeBreadcrumb: P };
60
62
  }
61
63
  });
62
64
  export {
63
- F as default
65
+ L as default
64
66
  };
@@ -1,21 +1,22 @@
1
- import { getRecommendationFeedSourceMaps as I, URLS as C } from "../enums/extensions/recommendationBlock.js";
2
- import { MinDeviceViewport as R, DefaultPadding as b } from "../enums/recommendation.js";
3
- import { useRecommendationExtensionStore as m } from "../extensions/Blocks/Recommendation/store/recommendation.js";
1
+ import { getRecommendationFeedSourceMaps as I, URLS as R } from "../enums/extensions/recommendationBlock.js";
2
+ import { MinDeviceViewport as C, DefaultPadding as b } from "../enums/recommendation.js";
3
+ import { useRecommendationExtensionStore as l } from "../extensions/Blocks/Recommendation/store/recommendation.js";
4
4
  import { generateCompleteFilterQuery as h } from "../extensions/Blocks/Recommendation/utils/filterUtil.js";
5
+ import { getPartnerRecommendationParams as y } from "../extensions/Blocks/Recommendation/utils/partnerCustomizations.js";
5
6
  import { useConfigStore as x } from "../stores/config.js";
6
- const w = () => ({
7
+ const k = () => ({
7
8
  calculateCardWidth: ({
8
- mobileLeftPadding: o,
9
+ mobileLeftPadding: a,
9
10
  mobileRightPadding: s,
10
- cardsInRow: a,
11
- unresponsive: n
11
+ cardsInRow: c,
12
+ unresponsive: o
12
13
  }) => {
13
- const r = n ? a : 1, e = o + s + (r - 1) * b;
14
- return (R - e) / r;
14
+ const r = o ? c : 1, e = a + s + (r - 1) * b;
15
+ return (C - e) / r;
15
16
  },
16
- getRecommendationCampaignData: (o) => {
17
- const s = m(), a = Number(o), n = s.blockStates[a];
18
- if (!n)
17
+ getRecommendationCampaignData: (a) => {
18
+ const s = l(), c = Number(a), o = s.blockStates[c];
19
+ if (!o)
19
20
  return {
20
21
  textTrimming: !1,
21
22
  orientation: "vertical",
@@ -28,7 +29,7 @@ const w = () => ({
28
29
  discountBeforeTextValue: "",
29
30
  discountAfterTextValue: ""
30
31
  };
31
- const { recommendationConfigs: r } = n, e = r.orientation === "grid" ? "vertical" : "horizontal";
32
+ const { recommendationConfigs: r } = o, e = r.orientation === "grid" ? "vertical" : "horizontal";
32
33
  return {
33
34
  textTrimming: r.textTrimming,
34
35
  orientation: e,
@@ -42,35 +43,35 @@ const w = () => ({
42
43
  discountAfterTextValue: ""
43
44
  };
44
45
  },
45
- buildCampaignUrl: (o, s) => {
46
- var l;
47
- const a = m(), n = x(), r = Number(o);
46
+ buildCampaignUrl: (a, s) => {
47
+ var m;
48
+ const c = l(), o = x(), r = Number(a);
48
49
  let e;
49
50
  if (s)
50
51
  e = s;
51
52
  else {
52
- const c = a.blockStates[r];
53
- if (!c)
53
+ const i = c.blockStates[r];
54
+ if (!i)
54
55
  return "";
55
- const { recommendationConfigs: i } = c;
56
+ const { recommendationConfigs: n } = i;
56
57
  e = {
57
- strategy: i.strategy,
58
- language: i.language,
59
- currencyCode: i.currencySettings.value,
60
- size: i.size,
61
- productIds: i.productIds,
62
- filters: i.filters,
63
- shuffleProducts: i.shuffleProducts
58
+ strategy: n.strategy,
59
+ language: n.language,
60
+ currencyCode: n.currencySettings.value,
61
+ size: n.size,
62
+ productIds: n.productIds,
63
+ filters: n.filters,
64
+ shuffleProducts: n.shuffleProducts
64
65
  };
65
66
  }
66
- const f = ((l = I().find((c) => c.key === e.strategy)) == null ? void 0 : l.path) || "", t = new URLSearchParams();
67
- t.set("locale", e.language), t.set("currency", e.currencyCode), t.set("partnerName", n.partnerName), t.set("size", e.size), t.set("details", "true"), t.set("campaignId", n.variationId), e.strategy === "manualMerchandising" ? t.set("productId", e.productIds.join(",")) : e.strategy === "similarViewed" && t.set("productId", "{itemId}"), e.strategy === "userBased" && t.set("userId", "{user_id}");
68
- const g = e.filters.filter((c) => c.isValid), d = h(g);
69
- d && t.set("filter", d), e.shuffleProducts && t.set("shuffle", "true");
70
- const p = decodeURIComponent(t.toString()), u = `${C.RECOMMENDATION_API_URL}/v2/${f}?${p}`;
71
- return a.recommendationCampaignUrls[o] = u, u;
67
+ const f = ((m = I().find((i) => i.key === e.strategy)) == null ? void 0 : m.path) || "", t = new URLSearchParams();
68
+ t.set("locale", e.language), t.set("currency", e.currencyCode), t.set("partnerName", o.partnerName), t.set("size", e.size), t.set("details", "true"), t.set("campaignId", o.variationId), e.strategy === "manualMerchandising" ? t.set("productId", e.productIds.join(",")) : e.strategy === "similarViewed" && t.set("productId", "{itemId}"), e.strategy === "userBased" && t.set("userId", "{user_id}");
69
+ const g = e.filters.filter((i) => i.isValid), d = h(g);
70
+ d && t.set("filter", d), e.shuffleProducts && t.set("shuffle", "true"), Object.entries(y(o.partnerName, e.strategy)).forEach(([i, n]) => t.set(i, n));
71
+ const p = decodeURIComponent(t.toString()), u = `${R.RECOMMENDATION_API_URL}/v2/${f}?${p}`;
72
+ return c.recommendationCampaignUrls[a] = u, u;
72
73
  }
73
74
  });
74
75
  export {
75
- w as useRecommendation
76
+ k as useRecommendation
76
77
  };
@@ -1,40 +1,35 @@
1
- import { useRecommendationBlockWarning as l } from "../extensions/Blocks/Recommendation/useRecommendationBlockWarning.js";
2
- import { useStripoApi as m } from "../services/stripoApi.js";
3
- import { useEditorStore as b } from "../stores/editor.js";
4
- import { useOnboardingStore as p } from "../stores/onboarding.js";
5
- import { useUnsubscribeStore as f } from "../stores/unsubscribe.js";
6
- const h = () => {
7
- const { updateSyncModule: r, getSyncModule: c } = m(), { warnIfMultipleBlocks: s } = l(), d = b(), i = f(), a = () => {
8
- var o, t, n;
9
- const e = (n = (t = (o = document.querySelector("ui-editor")) == null ? void 0 : o.shadowRoot) == null ? void 0 : t.querySelector("iframe")) == null ? void 0 : n.contentDocument;
10
- e && s(e);
11
- }, u = {
1
+ import { useStripoApi as i } from "../services/stripoApi.js";
2
+ import { useEditorStore as u } from "../stores/editor.js";
3
+ import { useOnboardingStore as l } from "../stores/onboarding.js";
4
+ import { useUnsubscribeStore as b } from "../stores/unsubscribe.js";
5
+ const v = () => {
6
+ const { updateSyncModule: d, getSyncModule: r } = i(), n = u(), s = b(), a = {
12
7
  block_dropped: ({ blockName: e }) => {
13
8
  if (e === "BLOCK_TEXT") {
14
- const o = p(), t = !o.shouldShowOnboarding("textBlockOnboarding"), n = o.isActive("textBlockOnboarding");
15
- if (t || n)
9
+ const o = l(), t = !o.shouldShowOnboarding("textBlockOnboarding"), c = o.isActive("textBlockOnboarding");
10
+ if (t || c)
16
11
  return;
17
12
  o.start("textBlockOnboarding");
18
13
  }
19
14
  },
20
15
  module_saved: async (e) => {
21
- d.syncModulesEnabled && (console.debug("[module_saved] Saved module data:", e), await r(e));
16
+ n.syncModulesEnabled && (console.debug("[module_saved] Saved module data:", e), await d(e));
22
17
  },
23
18
  module_dropped: async (e) => {
24
- if (a(), !d.syncModulesEnabled)
19
+ if (!n.syncModulesEnabled)
25
20
  return;
26
- const { moduleId: o } = e, t = await c(o);
27
- console.debug("[module_dropped] Sync module data:", t), t.unsubscriptionPreferencePages.length && await i.fetchTemplates();
21
+ const { moduleId: o } = e, t = await r(o);
22
+ console.debug("[module_dropped] Sync module data:", t), t.unsubscriptionPreferencePages.length && await s.fetchTemplates();
28
23
  },
29
24
  module_updated: async (e) => {
30
- d.syncModulesEnabled && (console.debug("[module_updated] Updated module data:", e), await r(e));
25
+ n.syncModulesEnabled && (console.debug("[module_updated] Updated module data:", e), await d(e));
31
26
  }
32
27
  };
33
28
  return { handleEvent: async (e, o) => {
34
- const t = u[e];
29
+ const t = a[e];
35
30
  console.debug("Stripo Event: ", e, o), t && await t(o);
36
31
  } };
37
32
  };
38
33
  export {
39
- h as useStripoEventHandler
34
+ v as useStripoEventHandler
40
35
  };
@@ -1,4 +1,4 @@
1
- var c = /* @__PURE__ */ ((r) => (r.Success = "success", r.Warning = "warning", r.Alert = "alert", r.Dark = "dark", r))(c || {});
1
+ var c = /* @__PURE__ */ ((r) => (r.Success = "success", r.Warning = "warning", r.Alert = "alert", r))(c || {});
2
2
  export {
3
3
  c as ToasterTypeOptions
4
4
  };
@@ -1,18 +1,17 @@
1
1
  var k = Object.defineProperty;
2
- var B = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
- var d = (a, r, t) => B(a, typeof r != "symbol" ? r + "" : r, t);
4
- import { BlockId as R } from "../../../enums/block.js";
5
- import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as D, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ var y = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
+ var d = (a, r, t) => y(a, typeof r != "symbol" ? r + "" : r, t);
4
+ import { BlockId as B } from "../../../enums/block.js";
5
+ import { getMigrationBannerHtml as D } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as R, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
7
  import { regenerateMobileProductRows as b } from "./controls/main/utils.js";
8
8
  import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
9
  import { RecommendationConfigService as c } from "./services/configService.js";
10
10
  import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
11
  import { getDefaultTemplate as E } from "./templates/grid/template.js";
12
- import { useRecommendationBlockWarning as M } from "./useRecommendationBlockWarning.js";
13
- const I = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
14
- let _ = !1;
15
- class H extends D {
12
+ const _ = B.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
13
+ let I = !1;
14
+ class q extends R {
16
15
  constructor() {
17
16
  super();
18
17
  /**
@@ -22,7 +21,7 @@ class H extends D {
22
21
  d(this, "_pendingBlockId", null);
23
22
  }
24
23
  getId() {
25
- return I;
24
+ return _;
26
25
  }
27
26
  getIcon() {
28
27
  return "recommendation-icon";
@@ -39,8 +38,8 @@ class H extends D {
39
38
  );
40
39
  }
41
40
  getSettingsPanelTitleHtml() {
42
- return y(
43
- I,
41
+ return D(
42
+ _,
44
43
  this.api.translate("Recommendation Block"),
45
44
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
46
45
  );
@@ -96,7 +95,7 @@ class H extends D {
96
95
  documentModifier: this.api.getDocumentModifier()
97
96
  }));
98
97
  }
99
- s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
98
+ s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
100
99
  }
101
100
  /**
102
101
  * Called when the document changes or template is loaded
@@ -118,7 +117,7 @@ class H extends D {
118
117
  }
119
118
  this._healLingeringDuplicate(t), c.needsMigration(t) && this._migrateFromLegacy(t);
120
119
  try {
121
- _ || (p(this.api), _ = !0);
120
+ I || (p(this.api), I = !0);
122
121
  const e = c.getConfig(t), i = this._getBlockElement(t);
123
122
  if (i) {
124
123
  const n = !e.mobileLayoutEnabled;
@@ -138,24 +137,6 @@ class H extends D {
138
137
  const e = this._getRecommendationId(t);
139
138
  e && g().removeBlockState(e);
140
139
  }
141
- /**
142
- * Warns (dark advisory toaster) when the design holds more than one live
143
- * recommendation block. Triggered from the user-add paths only (fresh drop
144
- * and duplicate) — never from document-load/migration, so opening a template
145
- * that already has multiple blocks does not fire it.
146
- *
147
- * Counting lives in `useRecommendationBlockWarning` so the same DOM-based
148
- * logic (which ignores the empty shells deletions leave behind, SD-143028)
149
- * is shared with the `module_dropped` handler — recommendation blocks can
150
- * also arrive inside a saved structure. Wrapped in try/catch because the
151
- * document root may be unavailable during initial load.
152
- */
153
- _warnIfMultipleBlocks() {
154
- try {
155
- M().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
156
- } catch {
157
- }
158
- }
159
140
  /**
160
141
  * Generates the next unique recommendation ID by scanning all existing blocks
161
142
  * in the document and finding the maximum existing ID + 1.
@@ -228,7 +209,7 @@ class H extends D {
228
209
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
229
210
  _handleDuplicate(t, e) {
230
211
  const i = this._reassignDuplicateId(t, e), n = g();
231
- n.cloneBlockState(e, i), n.setCurrentBlock(i), this._warnIfMultipleBlocks();
212
+ n.cloneBlockState(e, i), n.setCurrentBlock(i);
232
213
  }
233
214
  /**
234
215
  * Core id-reassignment for a duplicated block: rewrites the DOM
@@ -310,6 +291,6 @@ class H extends D {
310
291
  }
311
292
  }
312
293
  export {
313
- I as BLOCK_ID,
314
- H as RecommendationBlock
294
+ _ as BLOCK_ID,
295
+ q as RecommendationBlock
315
296
  };
@@ -6,8 +6,9 @@ import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
6
  import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
7
7
  import { getDefaultProducts as S } from "../templates/utils.js";
8
8
  import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
9
- import { isFilterValid as v } from "../validation/filterSchema.js";
10
- import { isConfigValid as w } from "../validation/requiredFields.js";
9
+ import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
10
+ import { isFilterValid as w } from "../validation/filterSchema.js";
11
+ import { isConfigValid as N } from "../validation/requiredFields.js";
11
12
  const h = y();
12
13
  let m = null, u = null, d = null;
13
14
  function I() {
@@ -49,7 +50,7 @@ function k() {
49
50
  filterSnapshot: null
50
51
  };
51
52
  }
52
- const N = () => ({
53
+ const x = () => ({
53
54
  recommendationCampaignUrls: {},
54
55
  activePredictiveAlgorithms: [],
55
56
  languages: {},
@@ -58,8 +59,8 @@ const N = () => ({
58
59
  blockStates: {},
59
60
  currentRecommendationId: null,
60
61
  configVersion: 0
61
- }), M = P("guidoRecommendationExtension", {
62
- state: () => N(),
62
+ }), T = P("guidoRecommendationExtension", {
63
+ state: () => x(),
63
64
  getters: {
64
65
  // ====================================================================
65
66
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -378,7 +379,7 @@ const N = () => ({
378
379
  const n = [...e.recommendationConfigs.filters];
379
380
  n[r] = {
380
381
  ...t,
381
- isValid: v(t)
382
+ isValid: w(t)
382
383
  }, e.recommendationConfigs.filters = n;
383
384
  }
384
385
  },
@@ -424,7 +425,7 @@ const N = () => ({
424
425
  * every block's recommendationConfigs across user edits.
425
426
  */
426
427
  hasInvalidBlock() {
427
- return Object.values(this.blockStates).some((t) => !w(t.recommendationConfigs, this));
428
+ return Object.values(this.blockStates).some((t) => !N(t.recommendationConfigs, this));
428
429
  },
429
430
  // ====================================================================
430
431
  // Per-Block Product Fetching
@@ -453,7 +454,10 @@ const N = () => ({
453
454
  details: !0,
454
455
  campaignId: o.variationId
455
456
  };
456
- 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);
457
+ 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(
458
+ a,
459
+ v(o.partnerName, r.strategy)
460
+ );
457
461
  let f;
458
462
  try {
459
463
  f = await h.fetchRecommendationProducts(i, a);
@@ -471,5 +475,5 @@ const N = () => ({
471
475
  }
472
476
  });
473
477
  export {
474
- M as useRecommendationExtensionStore
478
+ T as useRecommendationExtensionStore
475
479
  };
@@ -0,0 +1,21 @@
1
+ const i = [
2
+ "ozonebg",
3
+ "ozonehr",
4
+ "ozonero",
5
+ "ozoneinfo",
6
+ "babybg",
7
+ "ozongr",
8
+ "iboodat",
9
+ "iboodbe",
10
+ "iboodde",
11
+ "iboodfr",
12
+ "iboodnl",
13
+ "iboodpl"
14
+ ], r = ["interencheres", "interencherespreprod"], d = ["lodenfrey", "lodenfreyuat"], c = "manualMerchandising";
15
+ function s(e, n) {
16
+ const o = {};
17
+ return i.includes(e) && (o.excludePurchaseDay = "30", o.userId = "{user_id}"), r.includes(e) && (o.hp = "1"), d.includes(e) && n === c && (o.includeOutOfStockItems = "true"), o;
18
+ }
19
+ export {
20
+ s as getPartnerRecommendationParams
21
+ };
@@ -1,28 +1,28 @@
1
- var d = Object.defineProperty;
2
- var h = (a, s, e) => s in a ? d(a, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[s] = e;
3
- var u = (a, s, e) => h(a, typeof s != "symbol" ? s + "" : s, e);
1
+ var T = Object.defineProperty;
2
+ var p = (o, s, e) => s in o ? T(o, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[s] = e;
3
+ var c = (o, s, e) => p(o, typeof s != "symbol" ? s + "" : s, e);
4
4
  import { useUnsubscribeStore as l } from "../../../stores/unsubscribe.js";
5
- import { Control as T, UEAttr as i, UIElementType as n } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
- import { DATA_ATTRIBUTES as p } from "./utils/constants.js";
7
- import { parsePageList as _ } from "./utils/utils.js";
8
- const v = "ui-elements-unsubscribe", r = {
5
+ import { Control as _, UEAttr as i, UIElementType as n } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
+ import { DATA_ATTRIBUTES as d } from "./utils/constants.js";
7
+ import { parsePageList as h } from "./utils/utils.js";
8
+ const g = "ui-elements-unsubscribe", r = {
9
9
  SELECT_BUTTON: "selectTemplateButton",
10
10
  PREV_BUTTON: "prevButton",
11
11
  NEXT_BUTTON: "nextButton",
12
12
  COUNTER_TEXT: "counterText",
13
13
  PREVIEW_IMAGE: "previewImage"
14
14
  };
15
- class B extends T {
15
+ class B extends _ {
16
16
  constructor() {
17
17
  super(...arguments);
18
- u(this, "currentPreviewIndex", 0);
19
- u(this, "currentNode");
20
- u(this, "currentPages");
21
- u(this, "valueChangeHandlers", []);
22
- u(this, "lastParsedAttribute");
18
+ c(this, "currentPreviewIndex", 0);
19
+ c(this, "currentNode");
20
+ c(this, "currentPages");
21
+ c(this, "valueChangeHandlers", []);
22
+ c(this, "lastParsedAttribute");
23
23
  }
24
24
  getId() {
25
- return v;
25
+ return g;
26
26
  }
27
27
  getTemplate() {
28
28
  return `
@@ -34,8 +34,8 @@ class B extends T {
34
34
  }
35
35
  onTemplateNodeUpdated(e) {
36
36
  if (this.currentNode = e, "getAttribute" in this.currentNode) {
37
- const t = this.currentNode.getAttribute(p.PAGE_LIST);
38
- t && (t !== this.lastParsedAttribute && (this.currentPages = _(t), this.lastParsedAttribute = t, this.currentPreviewIndex = 0), this._updateCounter(), this._loadAndUpdatePreview());
37
+ const t = this.currentNode.getAttribute(d.PAGE_LIST);
38
+ t && (t !== this.lastParsedAttribute && (this.currentPages = h(t), this.lastParsedAttribute = t, this.currentPreviewIndex = 0), this._updateCounter(), this._loadAndUpdatePreview());
39
39
  }
40
40
  }
41
41
  onRender() {
@@ -62,11 +62,18 @@ class B extends T {
62
62
  _onButtonClick() {
63
63
  try {
64
64
  const e = l();
65
- e.activeType = e.getSelectedCollection[this.currentPreviewIndex], e.pageSelectionUpdateStatus = !0, e.pageSelectionDrawerStatus = !0;
65
+ this._reseedSelectionFromBlock(), e.activeType = e.getSelectedCollection[this.currentPreviewIndex], e.pageSelectionUpdateStatus = !0, e.pageSelectionDrawerStatus = !0;
66
66
  } catch (e) {
67
67
  console.error("[UnsubscribeControl] Failed to open drawer:", e);
68
68
  }
69
69
  }
70
+ _reseedSelectionFromBlock() {
71
+ const e = l();
72
+ if (e.$reset(), !this.currentNode || !("getAttribute" in this.currentNode))
73
+ return;
74
+ const t = this.currentNode.getAttribute(d.PAGE_TYPE), a = this.currentNode.getAttribute(d.PAGE_LIST);
75
+ !t || !a || (e.setCollectionWithoutAutoSelection(Number(t)), e.loadSelectedTemplates(h(a)));
76
+ }
70
77
  _onPrevClick() {
71
78
  this.currentPreviewIndex > 0 && (this.currentPreviewIndex--, this._updatePreview(), this._updateCounter());
72
79
  }
@@ -80,21 +87,21 @@ class B extends T {
80
87
  var e;
81
88
  if ((e = this.currentPages) != null && e.length)
82
89
  try {
83
- const t = this.currentPages[this.currentPreviewIndex], o = l().getThumbnailByTemplateId(t);
84
- if (!o) {
90
+ const t = this.currentPages[this.currentPreviewIndex], u = l().getThumbnailByTemplateId(t);
91
+ if (!u) {
85
92
  console.warn("[UnsubscribeControl] No thumbnail found for page:", t);
86
93
  return;
87
94
  }
88
95
  this.api.updateValues({
89
- [r.PREVIEW_IMAGE]: o
96
+ [r.PREVIEW_IMAGE]: u
90
97
  });
91
98
  } catch (t) {
92
99
  console.error("[UnsubscribeControl] Failed to update preview:", t);
93
100
  }
94
101
  }
95
102
  _updateCounter() {
96
- const e = this.currentPreviewIndex + 1, t = this.totalTemplates, c = this.currentPreviewIndex === 0, o = this.currentPreviewIndex >= t - 1;
97
- this.api.setUIEAttribute(r.PREV_BUTTON, i.BUTTON.disabled, c), this.api.setUIEAttribute(r.NEXT_BUTTON, i.BUTTON.disabled, o), this.api.setUIEAttribute(
103
+ const e = this.currentPreviewIndex + 1, t = this.totalTemplates, a = this.currentPreviewIndex === 0, u = this.currentPreviewIndex >= t - 1;
104
+ this.api.setUIEAttribute(r.PREV_BUTTON, i.BUTTON.disabled, a), this.api.setUIEAttribute(r.NEXT_BUTTON, i.BUTTON.disabled, u), this.api.setUIEAttribute(
98
105
  r.COUNTER_TEXT,
99
106
  i.LABEL.text,
100
107
  `${this.api.translate("Showing")} ${e} ${this.api.translate("of")} ${t}`
@@ -135,14 +142,14 @@ class B extends T {
135
142
  </${n.LABEL}>
136
143
  `;
137
144
  }
138
- _getIconButton(e, t, c) {
139
- const o = c ? `${i.BUTTON.disabled}="true"` : "";
145
+ _getIconButton(e, t, a) {
146
+ const u = a ? `${i.BUTTON.disabled}="true"` : "";
140
147
  return `
141
148
  <${n.BUTTON}
142
149
  id="${e}"
143
150
  class="flat-inline flat-white"
144
151
  ${i.BUTTON.name}="${e}"
145
- ${o}
152
+ ${u}
146
153
  >
147
154
  <${n.ICON}
148
155
  src="${t}"
@@ -165,6 +172,6 @@ class B extends T {
165
172
  }
166
173
  }
167
174
  export {
168
- v as UNSUBSCRIBE_CONTROL_ID,
175
+ g as UNSUBSCRIBE_CONTROL_ID,
169
176
  B as UnsubscribeControl
170
177
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-4e2a4adb]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-b293a2b0]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-b293a2b0]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-b293a2b0]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-df672485]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-df672485]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-df672485]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-df672485]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-df672485]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-7419ae06] .vueperslides__bullets,[data-v-796d193b] .vueperslides__bullets{pointer-events:none!important}[data-v-796d193b] .vueperslides__parallax-wrapper{height:110px!important}[data-v-cadfc82d] .vueperslides__bullets{pointer-events:none!important}[data-v-cadfc82d] .vueperslides__parallax-wrapper{height:110px!important}
1
+ .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-4e2a4adb]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-b293a2b0]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-b293a2b0]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-b293a2b0]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-824fa820]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-824fa820]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-824fa820]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-824fa820]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-824fa820]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-7419ae06] .vueperslides__bullets,[data-v-796d193b] .vueperslides__bullets{pointer-events:none!important}[data-v-796d193b] .vueperslides__parallax-wrapper{height:110px!important}[data-v-cadfc82d] .vueperslides__bullets{pointer-events:none!important}[data-v-cadfc82d] .vueperslides__parallax-wrapper{height:110px!important}
@@ -1,6 +1,5 @@
1
1
  export declare enum ToasterTypeOptions {
2
2
  Success = "success",
3
3
  Warning = "warning",
4
- Alert = "alert",
5
- Dark = "dark"
4
+ Alert = "alert"
6
5
  }
@@ -55,19 +55,6 @@ export declare class RecommendationBlock extends Block {
55
55
  * @param node - The block node being deleted
56
56
  */
57
57
  onDelete(node: ImmutableHtmlNode): void;
58
- /**
59
- * Warns (dark advisory toaster) when the design holds more than one live
60
- * recommendation block. Triggered from the user-add paths only (fresh drop
61
- * and duplicate) — never from document-load/migration, so opening a template
62
- * that already has multiple blocks does not fire it.
63
- *
64
- * Counting lives in `useRecommendationBlockWarning` so the same DOM-based
65
- * logic (which ignores the empty shells deletions leave behind, SD-143028)
66
- * is shared with the `module_dropped` handler — recommendation blocks can
67
- * also arrive inside a saved structure. Wrapped in try/catch because the
68
- * document root may be unavailable during initial load.
69
- */
70
- private _warnIfMultipleBlocks;
71
58
  /**
72
59
  * Generates the next unique recommendation ID by scanning all existing blocks
73
60
  * in the document and finding the maximum existing ID + 1.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns the extra recommendation feed query params for an account, if any.
3
+ * Accounts without customizations get an empty object.
4
+ * @param partnerName Account subdomain (`config.partner.name`)
5
+ * @param strategy Recommendation strategy key of the block
6
+ */
7
+ export declare function getPartnerRecommendationParams(partnerName: string, strategy: string): Record<string, string>;
@@ -15,6 +15,7 @@ export declare class UnsubscribeControl extends Control {
15
15
  private get totalTemplates();
16
16
  private _listenToFormUpdates;
17
17
  private _onButtonClick;
18
+ private _reseedSelectionFromBlock;
18
19
  private _onPrevClick;
19
20
  private _onNextClick;
20
21
  private _loadAndUpdatePreview;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.6.0-beta.a8be7f8",
3
+ "version": "3.6.0-beta.d0bfe20",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -1,16 +0,0 @@
1
- import { useToaster as r } from "../../../composables/useToaster.js";
2
- import { useTranslations as s } from "../../../composables/useTranslations.js";
3
- import { ToasterTypeOptions as n } from "../../../enums/toaster.js";
4
- import { countLiveRecommendationBlocks as i } from "./utils/recommendationBlockCount.js";
5
- const a = "newsletter.multiple-reco-blocks-warning", f = () => {
6
- const { showToaster: o } = r(), t = s();
7
- return { warnIfMultipleBlocks: (e) => {
8
- i(e) > 1 && o({
9
- type: n.Dark,
10
- message: t(a)
11
- });
12
- } };
13
- };
14
- export {
15
- f as useRecommendationBlockWarning
16
- };
@@ -1,9 +0,0 @@
1
- const r = ".recommendation-block-v2", t = ".recommendation-product-row";
2
- function n(o) {
3
- return Array.from(o.querySelectorAll(r)).filter((e) => e.querySelector(t)).length;
4
- }
5
- export {
6
- r as RECOMMENDATION_BLOCK_SELECTOR,
7
- t as RECOMMENDATION_PRODUCT_ROW_SELECTOR,
8
- n as countLiveRecommendationBlocks
9
- };
@@ -1,11 +0,0 @@
1
- import type { QueryableRoot } from './utils/recommendationBlockCount';
2
- /**
3
- * Advisory shown when a design ends up with more than one recommendation block,
4
- * since multiple blocks can slow campaign delivery. Shared by the block
5
- * lifecycle (direct drop / duplicate, counting the editor's document root) and
6
- * the `module_dropped` event (counting a parsed `getTemplateData()` document, so
7
- * recommendation blocks that arrive inside a saved structure are also covered).
8
- */
9
- export declare const useRecommendationBlockWarning: () => {
10
- warnIfMultipleBlocks: (root: QueryableRoot) => void;
11
- };
@@ -1,28 +0,0 @@
1
- /**
2
- * Counts *live* recommendation blocks in a document.
3
- *
4
- * Deleting a recommendation block strips its inner content but leaves an empty
5
- * `.recommendation-block-v2` container shell behind — present in every document
6
- * representation the editor exposes (`getDocumentRoot`, `getDocumentRootHtmlNode`
7
- * and even `getTemplateData`). A raw class count therefore over-reports after a
8
- * delete→add cycle (SD-143028). The product row (`.recommendation-product-row`)
9
- * is present on every live block from drop time (the default template ships
10
- * product rows, both grid and list layouts) and is removed from a deleted
11
- * block's leftover shell, so filtering by it cleanly separates live blocks from
12
- * ghosts without reading any store.
13
- */
14
- export declare const RECOMMENDATION_BLOCK_SELECTOR = ".recommendation-block-v2";
15
- export declare const RECOMMENDATION_PRODUCT_ROW_SELECTOR = ".recommendation-product-row";
16
- interface QueryableNode {
17
- querySelector(selector: string): unknown;
18
- }
19
- export interface QueryableRoot {
20
- querySelectorAll(selector: string): Iterable<QueryableNode>;
21
- }
22
- /**
23
- * Counts the live recommendation blocks reachable from `root`. Works on the
24
- * editor's `ImmutableHtmlNode` document root (drop / duplicate paths) and on a
25
- * DOM `Document` parsed from `getTemplateData()` HTML (saved-module drop path).
26
- */
27
- export declare function countLiveRecommendationBlocks(root: QueryableRoot): number;
28
- export {};