@useinsider/guido 3.18.1-beta.8d3bf29 → 3.18.1-beta.c5d7fb4

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.
@@ -1,15 +1,17 @@
1
- import { defineComponent as u, computed as n } from "vue";
2
- import y from "../../../wrappers/WpModal.vue.js";
3
- import { useToaster as f } from "../../../../composables/useToaster.js";
1
+ import { defineComponent as y, computed as n } from "vue";
2
+ import f from "../../../wrappers/WpModal.vue.js";
3
+ import { useToaster as u } from "../../../../composables/useToaster.js";
4
4
  import { useTranslations as _ } from "../../../../composables/useTranslations.js";
5
- import { ToasterTypeOptions as v } from "../../../../enums/toaster.js";
6
- import { useRecommendationExtensionStore as T } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
7
- import { commitBlockChangeOutsidePanel as h } from "../../../../extensions/Blocks/Recommendation/utils/nodeConfigWriter.js";
8
- import { escapeHtml as R } from "../../../../utils/htmlEscape.js";
9
- const P = /* @__PURE__ */ u({
5
+ import { ToasterTypeOptions as R } from "../../../../enums/toaster.js";
6
+ import "../../../../extensions/Blocks/Recommendation/constants/selectors.js";
7
+ import { CURRENT_CONFIG_VERSION as T } from "../../../../extensions/Blocks/Recommendation/constants/defaultConfig.js";
8
+ import { useRecommendationExtensionStore as v } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
9
+ import { commitBlockChangeOutsidePanel as N } from "../../../../extensions/Blocks/Recommendation/utils/nodeConfigWriter.js";
10
+ import { escapeHtml as S } from "../../../../utils/htmlEscape.js";
11
+ const w = /* @__PURE__ */ y({
10
12
  __name: "RemoveStrategyModal",
11
- setup(S) {
12
- const t = _(), e = T(), { showToaster: a } = f(), i = n(() => ({
13
+ setup(h) {
14
+ const t = _(), e = v(), { showToaster: a } = u(), i = n(() => ({
13
15
  cancelOrBackButton: {
14
16
  type: "secondary",
15
17
  labelText: t("products.cancel"),
@@ -20,38 +22,38 @@ const P = /* @__PURE__ */ u({
20
22
  labelText: t("discovery-strategy.remove")
21
23
  }
22
24
  })), m = n(() => {
23
- var o;
24
- const { strategyId: r } = e.recommendationConfigs;
25
- return ((o = e.assignedStrategy) == null ? void 0 : o.name) || `#${r}`;
25
+ var r;
26
+ const { strategyId: o } = e.recommendationConfigs;
27
+ return o ? ((r = e.assignedStrategy) == null ? void 0 : r.name) || `#${o}` : t("ds-steps.legacy-strategy");
26
28
  }), s = "__STRATEGY_NAME__", d = n(() => t("email-editor.remove-strategy-confirm-message", { strategyName: s }).split(s)), c = () => {
27
29
  e.closeRemoveStrategyModal();
28
30
  };
29
31
  return { __sfc: !0, trans: t, store: e, showToaster: a, footerButtonOptions: i, strategyName: m, NAME_TOKEN: s, messageParts: d, close: c, handleConfirm: async () => {
30
- const r = m.value, o = e.currentRecommendationId;
32
+ const o = m.value, r = e.currentRecommendationId;
31
33
  e.removeStrategy(), c();
32
34
  const { strategyId: l, size: g } = e.recommendationConfigs;
33
35
  if (a({
34
- type: v.Success,
36
+ type: R.Success,
35
37
  // The toast renders through a sanitizing v-html, so the name is escaped first.
36
38
  message: t("email-editor.strategy-removed-success", {
37
- strategyName: `<b>${R(r)}</b>`
39
+ strategyName: `<b>${S(o)}</b>`
38
40
  })
39
- }), o !== null) {
41
+ }), r !== null) {
40
42
  try {
41
43
  await e.fetchRecommendationProducts();
42
44
  } catch (p) {
43
45
  console.error("[RemoveStrategyModal] product refetch failed", p);
44
46
  }
45
- h(
46
- o,
47
- { strategyId: l, size: g },
47
+ N(
48
+ r,
49
+ { strategyId: l, size: g, configVersion: T },
48
50
  e.recommendationProducts,
49
51
  "Removed recommendation strategy"
50
52
  );
51
53
  }
52
- }, WpModal: y };
54
+ }, WpModal: f };
53
55
  }
54
56
  });
55
57
  export {
56
- P as default
58
+ w as default
57
59
  };
@@ -1,25 +1,25 @@
1
1
  var p = Object.defineProperty;
2
- var S = (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) => S(i, typeof s != "symbol" ? s + "" : s, t);
4
- import { useLegacyStrategyConversion as v } from "../../../../../composables/useLegacyStrategyConversion.js";
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
5
  import { ACADEMY_LINKS as b } from "../../../../../enums/academy.js";
6
- import { useOnboardingStore as _ } from "../../../../../stores/onboarding.js";
6
+ import { useOnboardingStore as S } from "../../../../../stores/onboarding.js";
7
7
  import { CommonControl as f } from "../../../common-control.js";
8
- import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
9
- const $ = "recommendation-strategy-control";
8
+ import { useRecommendationExtensionStore as $ } from "../../store/recommendation.js";
9
+ const C = "recommendation-strategy-control";
10
10
  class N extends f {
11
11
  constructor() {
12
12
  super(...arguments);
13
- r(this, "store", C());
14
- r(this, "onboardingStore", _());
15
- r(this, "legacyConversion", v());
13
+ r(this, "store", $());
14
+ r(this, "onboardingStore", S());
15
+ r(this, "legacyConversion", _());
16
16
  r(this, "storeUnsubscription", () => {
17
17
  });
18
18
  r(this, "listeners", []);
19
19
  r(this, "lastPaintedState", null);
20
20
  }
21
21
  getId() {
22
- return $;
22
+ return C;
23
23
  }
24
24
  getTemplate() {
25
25
  const t = this.api.translate(
@@ -78,6 +78,11 @@ class N extends f {
78
78
  id: "guido__btn-change-legacy-strategy",
79
79
  label: this.api.translate("Change"),
80
80
  modifier: "change"
81
+ })}
82
+ ${this._strategyAction({
83
+ id: "guido__btn-remove-legacy-strategy",
84
+ label: this.api.translate("Remove"),
85
+ modifier: "remove"
81
86
  })}
82
87
  </div>
83
88
  </div>
@@ -134,19 +139,19 @@ class N extends f {
134
139
  const n = t.querySelector(a);
135
140
  n && (n.addEventListener("click", o), this.listeners.push({ element: n, handler: o }));
136
141
  };
137
- 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-update-legacy-strategy", () => {
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", () => {
138
143
  this.legacyConversion.convertLegacyStrategy();
139
144
  });
140
145
  }
141
146
  _renderState() {
142
- var m;
143
- const { strategyId: t } = this.store.recommendationConfigs, e = t ? ((m = this.store.assignedStrategy) == null ? void 0 : m.name) ?? "" : "", a = this.store.legacyConversionLoading, o = this.store.isLegacyStrategyBlock, n = `${t}\0${e}\0${a}\0${o}`;
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}`;
144
149
  if (n === this.lastPaintedState)
145
150
  return;
146
151
  const c = this.getContainer();
147
152
  if (!c)
148
153
  return;
149
- const d = c.querySelector("[data-strategy-empty-state]"), y = c.querySelector("[data-strategy-assigned-state]"), g = c.querySelector("[data-strategy-legacy-state]"), h = c.querySelector("[data-strategy-name]");
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]");
150
155
  if (!d || !y || !g)
151
156
  return;
152
157
  const u = t ? y : o ? g : d;
@@ -154,10 +159,10 @@ class N extends f {
154
159
  l.style.display = l === u ? "" : "none";
155
160
  }), g.querySelectorAll("button").forEach((l) => {
156
161
  l.disabled = a;
157
- }), g.classList.toggle("is-converting", a), h && t && (h.textContent = e || `#${t}`), this.lastPaintedState = n;
162
+ }), g.classList.toggle("is-converting", a), m && t && (m.textContent = e || `#${t}`), this.lastPaintedState = n;
158
163
  }
159
164
  }
160
165
  export {
161
- $ as STRATEGY_CONTROL_ID,
166
+ C as STRATEGY_CONTROL_ID,
162
167
  N as StrategyControl
163
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;
@@ -1,12 +1,12 @@
1
- import { getRecommendationFeedSourceMaps as b, getOperatorOptions as D, PriceAttributes as F } from "../../../../enums/extensions/recommendationBlock.js";
1
+ import { getRecommendationFeedSourceMaps as R, getOperatorOptions as D, PriceAttributes as F } from "../../../../enums/extensions/recommendationBlock.js";
2
2
  import { useRecommendationApi as P } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as R } from "../../../../stores/config.js";
3
+ import { useConfigStore as k } from "../../../../stores/config.js";
4
4
  import { defineStore as L } from "pinia";
5
5
  import "../constants/selectors.js";
6
6
  import { DEFAULT_MOBILE_CARDS_IN_ROW as U, DEFAULT_CARDS_IN_ROW as _ } from "../constants/layout.js";
7
- import { DEFAULT_NODE_CONFIG as N, CURRENT_CONFIG_VERSION as w, EXCLUDED_ALGORITHM_IDS as M } from "../constants/defaultConfig.js";
8
- import { getDefaultProducts as k } from "../templates/utils.js";
9
- import { generateCompleteFilterQuery as C } from "../utils/filterUtil.js";
7
+ import { CURRENT_CONFIG_VERSION as y, DEFAULT_NODE_CONFIG as N, EXCLUDED_ALGORITHM_IDS as M } from "../constants/defaultConfig.js";
8
+ import { getDefaultProducts as C } from "../templates/utils.js";
9
+ import { generateCompleteFilterQuery as v } from "../utils/filterUtil.js";
10
10
  import { isLegacyStrategyConfig as x } from "../utils/legacyStrategyMigration.js";
11
11
  import { getPartnerRecommendationParams as z } from "../utils/partnerCustomizations.js";
12
12
  import { sanitizeProductIds as B } from "../utils/productIds.js";
@@ -39,7 +39,7 @@ function G() {
39
39
  shuffleProducts: !1,
40
40
  strategy: "mostPopular",
41
41
  strategyId: "",
42
- nodeConfigVersion: w,
42
+ nodeConfigVersion: y,
43
43
  textTrimming: !0,
44
44
  unresponsive: !1,
45
45
  size: "6",
@@ -48,7 +48,7 @@ function G() {
48
48
  priceHideIfSameAsDiscounted: !1
49
49
  };
50
50
  }
51
- function v() {
51
+ function w() {
52
52
  return {
53
53
  recommendationConfigs: G(),
54
54
  recommendationProducts: [],
@@ -107,7 +107,7 @@ const E = () => ({
107
107
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
108
108
  },
109
109
  isLegacyStrategyBlock() {
110
- return R().isFeatureEnabled("reusableRecommendationStrategy") && x(this.recommendationConfigs);
110
+ return k().isFeatureEnabled("reusableRecommendationStrategy") && x(this.recommendationConfigs);
111
111
  },
112
112
  legacyConversionLoading(t) {
113
113
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyConversionLoading : !1;
@@ -150,7 +150,7 @@ const E = () => ({
150
150
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
151
151
  },
152
152
  getActivePredictiveAlgorithms: (t) => {
153
- const e = b(), r = [];
153
+ const e = R(), r = [];
154
154
  return t.activePredictiveAlgorithms.filter((n) => !M.includes(n)).forEach((n) => {
155
155
  r.push(...e.filter((s) => s.id === n));
156
156
  }), r.map((n) => ({
@@ -191,7 +191,7 @@ const E = () => ({
191
191
  setCurrentBlock(t) {
192
192
  this.blockStates[t] || (this.blockStates = {
193
193
  ...this.blockStates,
194
- [t]: v()
194
+ [t]: w()
195
195
  }), this.currentRecommendationId = t;
196
196
  },
197
197
  /**
@@ -259,7 +259,7 @@ const E = () => ({
259
259
  decimalCount: String(e.currencyDecimalCount),
260
260
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
261
261
  thousandSeparator: r(e.currencyThousandSeparator, ".")
262
- }, s = !this.blockStates[t], i = s ? v() : this.blockStates[t];
262
+ }, s = !this.blockStates[t], i = s ? w() : this.blockStates[t];
263
263
  i.recommendationConfigs = {
264
264
  ...i.recommendationConfigs,
265
265
  strategy: e.strategy,
@@ -414,7 +414,7 @@ const E = () => ({
414
414
  return s.recommendationConfigs = {
415
415
  ...s.recommendationConfigs,
416
416
  strategyId: r,
417
- nodeConfigVersion: w,
417
+ nodeConfigVersion: y,
418
418
  ...(n == null ? void 0 : n.size) !== void 0 ? { size: String(n.size) } : {}
419
419
  }, this.currentRecommendationId === e && this.configVersion++, r;
420
420
  } finally {
@@ -422,7 +422,11 @@ const E = () => ({
422
422
  }
423
423
  },
424
424
  removeStrategy() {
425
- this.patchCurrentBlockConfig({ strategyId: "", size: N.size });
425
+ this.patchCurrentBlockConfig({
426
+ strategyId: "",
427
+ size: N.size,
428
+ nodeConfigVersion: y
429
+ });
426
430
  },
427
431
  // ====================================================================
428
432
  // Shared Data Fetching (fetched once, used by all blocks)
@@ -532,7 +536,7 @@ const E = () => ({
532
536
  }), e.recommendationConfigs.filters = r;
533
537
  },
534
538
  generateFilterQuery() {
535
- return C(this.recommendationConfigs.filters);
539
+ return v(this.recommendationConfigs.filters);
536
540
  },
537
541
  /**
538
542
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -561,12 +565,12 @@ const E = () => ({
561
565
  },
562
566
  async _doFetchProducts() {
563
567
  var d;
564
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = R();
568
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = k();
565
569
  if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
566
570
  await this._doFetchStrategyProducts(t);
567
571
  return;
568
572
  }
569
- const s = r.filters.filter((u) => u.isValid), i = C(s), o = ((d = b().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
573
+ const s = r.filters.filter((u) => u.isValid), i = v(s), o = ((d = R().find((u) => u.key === r.strategy)) == null ? void 0 : d.path) || "", c = parseInt(r.size) || 6, a = {
570
574
  locale: r.language,
571
575
  currency: r.currencySettings.value,
572
576
  partnerName: n.partnerName,
@@ -598,8 +602,8 @@ const E = () => ({
598
602
  );
599
603
  if (i) {
600
604
  s = parseInt(String(i.size ?? "")) || s;
601
- const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((I) => I && !I.startsWith("user_id=")), y = u.length ? `${d}?${u.join("&")}` : d;
602
- y && (n = await m.fetchRecommendationProductsByUrl(y));
605
+ const o = r.currencySettings.value, a = (await this.resolveStrategyUrlTemplate(i, o)).replaceAll("{locale}", r.language).replaceAll("{currency}", o), l = a.indexOf("?"), d = l === -1 ? a : a.slice(0, l), u = (l === -1 ? "" : a.slice(l + 1)).split("&").filter((b) => b && !b.startsWith("user_id=")), I = u.length ? `${d}?${u.join("&")}` : d;
606
+ I && (n = await m.fetchRecommendationProductsByUrl(I));
603
607
  }
604
608
  } catch {
605
609
  n = [];
@@ -609,10 +613,10 @@ const E = () => ({
609
613
  _setBlockProducts(t, e, r) {
610
614
  if (!this.blockStates[t])
611
615
  return;
612
- const n = e.length > 0 ? e : k(r);
616
+ const n = e.length > 0 ? e : C(r);
613
617
  this.blockStates[t].recommendationProducts = [
614
618
  ...n.slice(0, r),
615
- ...k(Math.max(0, r - n.length))
619
+ ...C(Math.max(0, r - n.length))
616
620
  ];
617
621
  }
618
622
  }
@@ -1,12 +1,12 @@
1
1
  import { ModificationDescription as f } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { RECOMMENDATION_ID_ATTR as m } from "../constants/selectors.js";
3
- import { isPartnerManagedBlock as a, updateProductContentInPlace as d, regenerateProductRowsWithStyles as l } from "../controls/main/utils.js";
4
- import { RecommendationConfigService as s } from "../services/configService.js";
3
+ import { isPartnerManagedBlock as l, updateProductContentInPlace as a, regenerateProductRowsWithStyles as d } from "../controls/main/utils.js";
4
+ import { RecommendationConfigService as p } from "../services/configService.js";
5
5
  let e = null;
6
- function N(r) {
6
+ function M(r) {
7
7
  e = r;
8
8
  }
9
- function D(r, c, i, u) {
9
+ function N(r, c, i, u) {
10
10
  const n = e == null ? void 0 : e.getDocumentRootHtmlNode();
11
11
  if (!e || !n || !("querySelector" in n))
12
12
  return !1;
@@ -14,9 +14,9 @@ function D(r, c, i, u) {
14
14
  if (!t)
15
15
  return !1;
16
16
  const o = e.getDocumentModifier();
17
- return s.stageConfig(o, t, c), a(t) ? (o.apply(new f(u)), !0) : (d({ currentNode: t, documentModifier: o, products: i }) || l({ currentNode: t, documentModifier: o, products: i }), !0);
17
+ return p.stageConfig(o, t, c), l(t) ? (o.apply(new f(u)), !0) : (a({ currentNode: t, documentModifier: o, products: i, forceApply: !0 }) || d({ currentNode: t, documentModifier: o, products: i, forceApply: !0 }), !0);
18
18
  }
19
19
  export {
20
- D as commitBlockChangeOutsidePanel,
21
- N as registerNodeConfigWriter
20
+ N as commitBlockChangeOutsidePanel,
21
+ M as registerNodeConfigWriter
22
22
  };
@@ -88,6 +88,8 @@ export interface RegenerateWithStylesOptions extends Omit<RegenerateProductRowsO
88
88
  products?: RecommendationProduct[];
89
89
  /** Optional: pass layout directly to avoid stale DOM reads after setAttribute */
90
90
  layout?: Orientation;
91
+ /** Applies the batch even when the rows are unchanged, for callers that staged their own edits. */
92
+ forceApply?: boolean;
91
93
  }
92
94
  /**
93
95
  * Regenerates product rows while preserving user-applied styles, in a SINGLE commit.
@@ -151,6 +153,8 @@ export interface UpdateProductContentInPlaceOptions {
151
153
  currentNode: ImmutableHtmlNode | null | undefined;
152
154
  documentModifier: DocumentModifier;
153
155
  products: RecommendationProduct[];
156
+ /** Applies the batch even when the cards are unchanged, for callers that staged their own edits. */
157
+ forceApply?: boolean;
154
158
  }
155
159
  /**
156
160
  * Updates product content in-place without regenerating HTML structure.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.18.1-beta.8d3bf29",
3
+ "version": "3.18.1-beta.c5d7fb4",
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",