@useinsider/guido 3.16.0-beta.c615198 → 3.16.0-beta.ff4f1bd

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 (76) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +12 -6
  3. package/dist/components/Guido.vue.js +6 -6
  4. package/dist/components/Guido.vue2.js +31 -30
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +18 -0
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +61 -0
  7. package/dist/composables/useRecommendation.js +49 -43
  8. package/dist/config/migrator/recommendationMigrator.js +6 -4
  9. package/dist/enums/extensions/recommendationBlock.js +25 -23
  10. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +13 -11
  11. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +26 -37
  12. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +120 -98
  13. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +106 -0
  14. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +186 -52
  15. package/dist/guido.css +1 -1
  16. package/dist/node_modules/@useinsider/design-system-organisms/dist/index-5JHlb8rM.js +524 -0
  17. package/dist/node_modules/@useinsider/design-system-organisms/dist/index.js +8450 -0
  18. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InAccordion.js +174 -0
  19. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBasicTextInput.js +381 -0
  20. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBox.js +236 -0
  21. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InBulkActions.js +70 -0
  22. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InButton.js +350 -0
  23. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InButtonV2.js +371 -0
  24. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InCheckBox.js +152 -0
  25. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InChips.js +141 -0
  26. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InCustomDropDown.js +1047 -0
  27. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDataTableV2.js +96050 -0
  28. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDatePicker.js +2042 -0
  29. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDrawer.js +166 -0
  30. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InDropDown.js +1098 -0
  31. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InIcons.js +55 -0
  32. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InInfoBox.js +265 -0
  33. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InLinks.js +184 -0
  34. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InLoading.js +50 -0
  35. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InModals.js +453 -0
  36. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InNoData.js +145 -0
  37. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InOnPageMessage.js +176 -0
  38. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InProgress.js +266 -0
  39. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InRadioButton.js +114 -0
  40. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSegments.js +200 -0
  41. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSelect.js +451 -0
  42. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InSkeleton.js +49 -0
  43. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InStatusText.js +119 -0
  44. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTabs.js +4309 -0
  45. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTagsText.js +129 -0
  46. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTextInput.js +503 -0
  47. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InToasts.js +253 -0
  48. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InToggle.js +107 -0
  49. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTooltip.js +134 -0
  50. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/InTooltipV2.js +464 -0
  51. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/_commonjsHelpers.BItOPCY9.js +28 -0
  52. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/_plugin-vue2_normalizer.WQT2Fc8L.js +23 -0
  53. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/clickOutside.qP9M0QCm.js +29 -0
  54. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/helpers.CgHNyjAJ.js +109 -0
  55. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/index.Bw_06igr.js +2339 -0
  56. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/localLocalesMixin.DYMhydo2.js +16 -0
  57. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/useLocalLocales.Ckuhy7d-.js +17 -0
  58. package/dist/node_modules/@useinsider/design-system-organisms/node_modules/@useinsider/design-system-vue/dist/chunks/vue-property-decorator.BtlM7Epa.js +188 -0
  59. package/dist/services/recommendationApi.js +77 -28
  60. package/dist/src/@types/config/schemas.d.ts +12 -0
  61. package/dist/src/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.d.ts +3 -0
  62. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  63. package/dist/src/composables/useConfig.d.ts +2 -0
  64. package/dist/src/composables/useRecommendation.d.ts +1 -0
  65. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  66. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +6 -3
  67. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +26 -0
  68. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +199 -10
  69. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
  70. package/dist/src/mock/api/recommendation-strategies.d.ts +41 -0
  71. package/dist/src/services/recommendationApi.d.ts +4 -1
  72. package/dist/src/stores/config.d.ts +18 -0
  73. package/dist/utils/templatePreparation.js +37 -34
  74. package/package.json +2 -1
  75. package/dist/extensions/Blocks/Recommendation/utils/productIds.js +0 -6
  76. package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +0 -6
package/README.md CHANGED
@@ -162,6 +162,7 @@ const config: GuidoConfigInput = {
162
162
  liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
163
163
  autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
164
164
  allowlistEnabled?: boolean, // Default: false - Pre-save domain-allowlist check (opt-in). Guido self-serves the block toaster (role lookup, deep-link, copy from window.trans).
165
+ reusableRecommendationStrategy?: boolean, // Default: false - Assign an RRS strategy to recommendation blocks instead of per-block algorithm/filters/shuffle/product-count settings.
165
166
  },
166
167
 
167
168
  // Optional: Callbacks
@@ -1,5 +1,5 @@
1
1
  import { ModuleFolderDefaults as f } from "../../enums/defaults.js";
2
- import { object as a, number as n, optional as e, string as t, picklist as i, pipe as m, minLength as b, custom as k, boolean as o, array as c, transform as C, record as y, fallback as R, literal as u, looseObject as g, variant as T, union as h, unknown as r, lazy as I } from "../../node_modules/valibot/dist/index.js";
2
+ import { object as a, number as n, optional as e, string as t, picklist as i, pipe as m, minLength as b, custom as y, boolean as o, array as c, transform as C, record as k, fallback as R, literal as u, looseObject as g, variant as T, union as h, unknown as r, lazy as I } from "../../node_modules/valibot/dist/index.js";
3
3
  const p = {
4
4
  /** Promotional/marketing emails */
5
5
  PROMOTIONAL: 1,
@@ -76,7 +76,7 @@ const p = {
76
76
  children: e(c(S)),
77
77
  // eslint-disable-next-line camelcase -- backend field name
78
78
  select_items: e(c(S))
79
- })), N = y(
79
+ })), N = k(
80
80
  t(),
81
81
  R(c(S), [])
82
82
  ), P = g({
@@ -132,7 +132,7 @@ const p = {
132
132
  * strategy, currency, locale, and layout data.
133
133
  */
134
134
  recommendationConfigs: e(
135
- y(t(), P),
135
+ k(t(), P),
136
136
  {}
137
137
  )
138
138
  }), x = a({
@@ -219,7 +219,13 @@ const p = {
219
219
  /** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
220
220
  allowlistEnabled: e(o(), !1),
221
221
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
222
- linkTrackingIds: e(o(), !1)
222
+ linkTrackingIds: e(o(), !1),
223
+ /**
224
+ * Assign a Reusable Recommendation Strategy (RRS) to recommendation blocks instead of
225
+ * per-block algorithm settings. Hides Algorithm, Filters, Shuffle and Number of Products
226
+ * (they live on the strategy) and adds the Assign Strategy flow.
227
+ */
228
+ reusableRecommendationStrategy: e(o(), !1)
223
229
  }), B = i([
224
230
  "amp-accordion",
225
231
  "amp-carousel",
@@ -287,7 +293,7 @@ const p = {
287
293
  ...d.entries,
288
294
  type: u("custom"),
289
295
  /** Custom processor function */
290
- processor: k(
296
+ processor: y(
291
297
  (s) => typeof s == "function",
292
298
  "processor must be a function"
293
299
  )
@@ -307,7 +313,7 @@ const p = {
307
313
  * Return false to cancel the save operation.
308
314
  */
309
315
  externalValidation: e(
310
- k(
316
+ y(
311
317
  (s) => typeof s == "function",
312
318
  "externalValidation must be a function"
313
319
  )
@@ -1,18 +1,18 @@
1
- import i from "./Guido.vue2.js";
1
+ import a from "./Guido.vue2.js";
2
2
  /* empty css */
3
- import a from "../_virtual/_plugin-vue2_normalizer.js";
3
+ import i from "../_virtual/_plugin-vue2_normalizer.js";
4
4
  var t = function() {
5
5
  var o = this, r = o._self._c, e = o._self._setupProxy;
6
- return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), r(e.AutoSaveController), e.editorStore.isPreviewModeOpen ? r(e.PreviewContainer) : o._e(), r("div", { directives: [{ name: "show", rawName: "v-show", value: !e.previewStore.isLoaded, expression: "!previewStore.isLoaded" }], staticClass: "guido-editor__container", class: { "guido-editor__no-header": e.noHeader }, attrs: { id: "guido-editor" } }), r(e.Toaster), r(e.FilterSelectionDrawer), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? o._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(p) {
6
+ return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), r(e.AutoSaveController), e.editorStore.isPreviewModeOpen ? r(e.PreviewContainer) : o._e(), r("div", { directives: [{ name: "show", rawName: "v-show", value: !e.previewStore.isLoaded, expression: "!previewStore.isLoaded" }], staticClass: "guido-editor__container", class: { "guido-editor__no-header": e.noHeader }, attrs: { id: "guido-editor" } }), r(e.Toaster), r(e.FilterSelectionDrawer), e.configStore.isFeatureEnabled("reusableRecommendationStrategy") ? r(e.AssignStrategyDrawer) : o._e(), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? o._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(p) {
7
7
  return e.emit("onboarding:finished");
8
8
  } } }), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
9
- }, n = [], s = /* @__PURE__ */ a(
10
- i,
9
+ }, n = [], s = /* @__PURE__ */ i(
10
+ a,
11
11
  t,
12
12
  n,
13
13
  !1,
14
14
  null,
15
- "b0d3b445"
15
+ "e9d4540f"
16
16
  );
17
17
  const l = s.exports;
18
18
  export {
@@ -5,26 +5,27 @@ import { useGuidoStateBridge as Z } from "../composables/useGuidoStateBridge.js"
5
5
  import { usePartner as ee } from "../composables/usePartner.js";
6
6
  import { useStripo as te } from "../composables/useStripo.js";
7
7
  import { useTimerClone as oe } from "../composables/useTimerClone.js";
8
- import { migrate as N } from "../config/migrator/index.js";
9
- import { ModuleFolderDefaults as O } from "../enums/defaults.js";
8
+ import { migrate as A } from "../config/migrator/index.js";
9
+ import { ModuleFolderDefaults as N } from "../enums/defaults.js";
10
10
  import { RIBBON_SELECTOR as ne } from "../enums/onboarding.js";
11
11
  import { useRecommendationExtensionStore as re } from "../extensions/Blocks/Recommendation/store/recommendation.js";
12
12
  import se from "./organisms/AutoSaveController.vue.js";
13
13
  import ae from "./organisms/base/Toaster.vue.js";
14
- import ie from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
15
- import ce from "./organisms/header/HeaderWrapper.vue.js";
16
- import de from "./organisms/LoadingWrapper.vue.js";
17
- import me from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
18
- import le from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
19
- import { useStripoApi as ue } from "../services/stripoApi.js";
20
- import { useConfigStore as pe } from "../stores/config.js";
21
- import { useDynamicContentStore as fe } from "../stores/dynamic-content.js";
22
- import { useEditorStore as P } from "../stores/editor.js";
23
- import { usePreviewStore as ye } from "../stores/preview.js";
24
- import { useTemplateStore as ve } from "../stores/template.js";
25
- import { useUnsubscribeStore as he } from "../stores/unsubscribe.js";
26
- import { readTrackFloor as A } from "../utils/linkTrackingIds.js";
27
- const ze = /* @__PURE__ */ j({
14
+ import ie from "./organisms/extensions/recommendation/AssignStrategyDrawer.vue.js";
15
+ import ce from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
16
+ import de from "./organisms/header/HeaderWrapper.vue.js";
17
+ import me from "./organisms/LoadingWrapper.vue.js";
18
+ import le from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
19
+ import ue from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
20
+ import { useStripoApi as pe } from "../services/stripoApi.js";
21
+ import { useConfigStore as fe } from "../stores/config.js";
22
+ import { useDynamicContentStore as ye } from "../stores/dynamic-content.js";
23
+ import { useEditorStore as O } from "../stores/editor.js";
24
+ import { usePreviewStore as ve } from "../stores/preview.js";
25
+ import { useTemplateStore as ge } from "../stores/template.js";
26
+ import { useUnsubscribeStore as Se } from "../stores/unsubscribe.js";
27
+ import { readTrackFloor as P } from "../utils/linkTrackingIds.js";
28
+ const Ke = /* @__PURE__ */ j({
28
29
  __name: "Guido",
29
30
  props: {
30
31
  config: null,
@@ -36,11 +37,11 @@ const ze = /* @__PURE__ */ j({
36
37
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
37
38
  ), H = R(
38
39
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
39
- ), h = B(), l = B(), u = fe(), S = he(), o = pe();
40
+ ), g = B(), l = B(), u = ye(), S = Se(), o = fe();
40
41
  a.ready && o.init(a.config);
41
- const c = P(), $ = ye(), m = U(() => c.hasChanges), { isTestPartner: z } = ee(), g = () => {
42
+ const c = O(), $ = ve(), m = U(() => c.hasChanges), { isTestPartner: z } = ee(), h = () => {
42
43
  var t;
43
- return (t = h.value) == null ? void 0 : t.handleSave(!0);
44
+ return (t = g.value) == null ? void 0 : t.handleSave(!0);
44
45
  }, b = (t) => {
45
46
  c.loadingStatus = t;
46
47
  };
@@ -52,10 +53,10 @@ const ze = /* @__PURE__ */ j({
52
53
  userId: o.userId,
53
54
  username: o.username,
54
55
  partnerName: o.partnerName,
55
- savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || O.SAVED_MODULES,
56
- defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || O.DEFAULT_MODULES
56
+ savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || N.SAVED_MODULES,
57
+ defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || N.DEFAULT_MODULES
57
58
  };
58
- }, { initPlugin: E, preloadRuntime: w } = te(), { getDefaultTemplate: C } = ue(), { cloneTimersOnSave: D, hasTimerBlocks: k } = oe(), q = U(() => {
59
+ }, { initPlugin: E, preloadRuntime: w } = te(), { getDefaultTemplate: D } = pe(), { cloneTimersOnSave: C, hasTimerBlocks: k } = oe(), q = U(() => {
59
60
  var t;
60
61
  return !((t = o.ui) != null && t.showHeader);
61
62
  });
@@ -99,12 +100,12 @@ const ze = /* @__PURE__ */ j({
99
100
  S.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
100
101
  const L = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, M = o.isFeatureEnabled("linkTrackingIds");
101
102
  let n = {
102
- html: s && await N(s, L),
103
+ html: s && await A(s, L),
103
104
  css: d
104
105
  };
105
- n.html || (n = await C(), n.html = await N(n.html, L));
106
- const K = M ? A(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
107
- k(n.html) && (n.html = await D(n.html)), M && (c.trackIdSessionFloor = Math.max(K, A(n.html)));
106
+ n.html || (n = await D(), n.html = await A(n.html, L));
107
+ const K = M ? P(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
108
+ k(n.html) && (n.html = await C(n.html)), M && (c.trackIdSessionFloor = Math.max(K, P(n.html)));
108
109
  const V = {
109
110
  preselectedDynamicContentList: I,
110
111
  onReady: () => {
@@ -118,7 +119,7 @@ const ze = /* @__PURE__ */ j({
118
119
  };
119
120
  return J(async () => {
120
121
  var e;
121
- console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), re().$reset(), P().$reset(), ve().$reset(), y();
122
+ console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), re().$reset(), O().$reset(), ge().$reset(), y();
122
123
  const t = (e = l.value) == null ? void 0 : e.parentElement;
123
124
  if (t && (i = new ResizeObserver(y), i.observe(t)), w(), a.ready)
124
125
  await v();
@@ -142,11 +143,11 @@ const ze = /* @__PURE__ */ j({
142
143
  close: F
143
144
  },
144
145
  hasChanges: m,
145
- saveSilent: g,
146
+ saveSilent: h,
146
147
  setLoading: b
147
- }), { __sfc: !0, PreviewContainer: G, OnboardingWrapper: H, headerWrapperRef: h, wrapperRef: l, dynamicContentStore: u, unsubscribeStore: S, props: a, configStore: o, editorStore: c, previewStore: $, hasChanges: m, isTestPartner: z, saveSilent: g, setLoading: b, emit: r, buildMetadata: p, initPlugin: E, preloadRuntime: w, getDefaultTemplate: C, cloneTimersOnSave: D, hasTimerBlocks: k, noHeader: q, insertDynamicContent: T, closeDynamicContent: F, handleDynamicContentOpen: f, ribbonObserver: i, updateRibbonOffset: y, startEditor: v, AutoSaveController: se, Toaster: ae, FilterSelectionDrawer: ie, HeaderWrapper: ce, LoadingWrapper: de, SaveAsTemplateDrawer: me, UnsubscribeWrapper: le };
148
+ }), { __sfc: !0, PreviewContainer: G, OnboardingWrapper: H, headerWrapperRef: g, wrapperRef: l, dynamicContentStore: u, unsubscribeStore: S, props: a, configStore: o, editorStore: c, previewStore: $, hasChanges: m, isTestPartner: z, saveSilent: h, setLoading: b, emit: r, buildMetadata: p, initPlugin: E, preloadRuntime: w, getDefaultTemplate: D, cloneTimersOnSave: C, hasTimerBlocks: k, noHeader: q, insertDynamicContent: T, closeDynamicContent: F, handleDynamicContentOpen: f, ribbonObserver: i, updateRibbonOffset: y, startEditor: v, AutoSaveController: se, Toaster: ae, AssignStrategyDrawer: ie, FilterSelectionDrawer: ce, HeaderWrapper: de, LoadingWrapper: me, SaveAsTemplateDrawer: le, UnsubscribeWrapper: ue };
148
149
  }
149
150
  });
150
151
  export {
151
- ze as default
152
+ Ke as default
152
153
  };
@@ -0,0 +1,18 @@
1
+ import s from "./AssignStrategyDrawer.vue2.js";
2
+ /* empty css */
3
+ import a from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var o = function() {
5
+ var r = this, e = r._self._c, t = r._self._setupProxy;
6
+ return e(t.WpDrawer, { attrs: { id: "assign-strategy-drawer", "description-status": "", size: "medium", "description-text": t.drawerDescription, "footer-button-group-options": t.footerButtonGroupOptions, status: t.store.assignStrategyDrawerStatus, "title-text": t.trans("gpt-app-builder.assign-recommendation-strategy") }, on: { cancelOrBackButtonEvent: t.closeDrawer, onCloseEvent: t.closeDrawer, primaryButtonEvent: t.assignStrategy } }, [t.store.assignStrategyDrawerStatus ? e("div", { staticClass: "assign-strategy-drawer-content" }, [e(t.OrgStrategyDropdown, { attrs: { "create-button-visible": !1, loading: t.store.strategiesLoading, "selected-strategy-id": t.selectedStrategyId, strategies: t.strategyOptions }, on: { select: t.onSelect } }), t.selectedStrategy ? e("div", { key: String(t.selectedStrategy.strategy_id), staticClass: "assign-strategy-detail" }, [e(t.OrgStrategyDetailModal, { attrs: { show: "", "footer-status": !1, strategy: t.selectedStrategy } })], 1) : r._e()], 1) : r._e()]);
7
+ }, n = [], i = /* @__PURE__ */ a(
8
+ s,
9
+ o,
10
+ n,
11
+ !1,
12
+ null,
13
+ "3a49b374"
14
+ );
15
+ const p = i.exports;
16
+ export {
17
+ p as default
18
+ };
@@ -0,0 +1,61 @@
1
+ import { defineComponent as S, ref as g, computed as o, watch as f } from "vue";
2
+ /* empty css */
3
+ import v from "../../../wrappers/WpDrawer.vue.js";
4
+ import { useToaster as _ } from "../../../../composables/useToaster.js";
5
+ import { useTranslations as w } from "../../../../composables/useTranslations.js";
6
+ import { ToasterTypeOptions as D } from "../../../../enums/toaster.js";
7
+ import { useRecommendationExtensionStore as T } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
8
+ import { OrgStrategyDropdown as h, OrgStrategyDetailModal as x } from "../../../../node_modules/@useinsider/design-system-organisms/dist/index.js";
9
+ const $ = /* @__PURE__ */ S({
10
+ __name: "AssignStrategyDrawer",
11
+ setup(O) {
12
+ const i = "/discovery/recommendation-strategies", s = w(), e = T(), { showToaster: l, handleError: c } = _(), a = g(null), r = g(!1), d = o(() => e.assignStrategyDrawerStatus ? s("email-editor.assign-strategy-description", { url: i }) : "");
13
+ f(() => e.assignStrategyDrawerStatus, (t) => {
14
+ if (!t)
15
+ return;
16
+ const { strategyId: p } = e.recommendationConfigs;
17
+ a.value = p || null, e.fetchStrategies().catch((y) => {
18
+ c(y, "Failed to load recommendation strategies");
19
+ });
20
+ });
21
+ const m = o(() => e.strategies.map((t) => ({
22
+ text: t.name,
23
+ value: t.strategy_id,
24
+ infoBoxProps: {
25
+ id: `strategy-info-${t.strategy_id}`,
26
+ theme: "light",
27
+ variant: "information",
28
+ titleText: t.name,
29
+ descriptionText: [t.algorithm, t.size ? `${t.size} products` : ""].filter(Boolean).join(" · ")
30
+ }
31
+ }))), n = o(() => e.strategies.find((t) => String(t.strategy_id) === String(a.value ?? "")) ?? null), u = o(() => ({
32
+ primaryButton: {
33
+ styling: "solid",
34
+ type: "primary",
35
+ labelText: s("products.assign-btn"),
36
+ loadingStatus: r.value,
37
+ disabledStatus: !n.value
38
+ },
39
+ cancelOrBackButton: {
40
+ styling: "ghost",
41
+ type: "secondary",
42
+ labelText: s("products.cancel"),
43
+ disabledStatus: r.value
44
+ }
45
+ }));
46
+ return { __sfc: !0, RRS_PANEL_PATH: i, trans: s, store: e, showToaster: l, handleError: c, selectedStrategyId: a, isAssigning: r, drawerDescription: d, strategyOptions: m, selectedStrategy: n, footerButtonGroupOptions: u, closeDrawer: () => {
47
+ e.closeAssignStrategyDrawer();
48
+ }, assignStrategy: () => {
49
+ const t = n.value;
50
+ t && (r.value = !0, e.assignStrategy(t), l({
51
+ type: D.Success,
52
+ message: s("email-editor.strategy-assigned-success", { strategyName: t.name })
53
+ }), e.closeAssignStrategyDrawer(), r.value = !1);
54
+ }, onSelect: (t) => {
55
+ a.value = t.value;
56
+ }, WpDrawer: v, OrgStrategyDetailModal: x, OrgStrategyDropdown: h };
57
+ }
58
+ });
59
+ export {
60
+ $ as default
61
+ };
@@ -1,23 +1,22 @@
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
- import { generateCompleteFilterQuery as h } from "../extensions/Blocks/Recommendation/utils/filterUtil.js";
5
- import { getPartnerRecommendationParams as y } from "../extensions/Blocks/Recommendation/utils/partnerCustomizations.js";
6
- import { sanitizeProductIds as x } from "../extensions/Blocks/Recommendation/utils/productIds.js";
7
- import { useConfigStore as P } from "../stores/config.js";
8
- const B = () => ({
1
+ import { getRecommendationFeedSourceMaps as y, URLS as I } from "../enums/extensions/recommendationBlock.js";
2
+ import { MinDeviceViewport as C, DefaultPadding as R } from "../enums/recommendation.js";
3
+ import { useRecommendationExtensionStore as m } from "../extensions/Blocks/Recommendation/store/recommendation.js";
4
+ import { generateCompleteFilterQuery as b } from "../extensions/Blocks/Recommendation/utils/filterUtil.js";
5
+ import { getPartnerRecommendationParams as h } from "../extensions/Blocks/Recommendation/utils/partnerCustomizations.js";
6
+ import { useConfigStore as x } from "../stores/config.js";
7
+ const k = () => ({
9
8
  calculateCardWidth: ({
10
- mobileLeftPadding: a,
11
- mobileRightPadding: s,
12
- cardsInRow: c,
13
- unresponsive: n
9
+ mobileLeftPadding: i,
10
+ mobileRightPadding: c,
11
+ cardsInRow: s,
12
+ unresponsive: o
14
13
  }) => {
15
- const r = n ? c : 1, e = a + s + (r - 1) * b;
16
- return (C - e) / r;
14
+ const n = o ? s : 1, e = i + c + (n - 1) * R;
15
+ return (C - e) / n;
17
16
  },
18
- getRecommendationCampaignData: (a) => {
19
- const s = l(), c = Number(a), n = s.blockStates[c];
20
- if (!n)
17
+ getRecommendationCampaignData: (i) => {
18
+ const c = m(), s = Number(i), o = c.blockStates[s];
19
+ if (!o)
21
20
  return {
22
21
  textTrimming: !1,
23
22
  orientation: "vertical",
@@ -30,49 +29,56 @@ const B = () => ({
30
29
  discountBeforeTextValue: "",
31
30
  discountAfterTextValue: ""
32
31
  };
33
- const { recommendationConfigs: r } = n, e = r.orientation === "grid" ? "vertical" : "horizontal";
32
+ const { recommendationConfigs: n } = o, e = n.orientation === "grid" ? "vertical" : "horizontal";
34
33
  return {
35
- textTrimming: r.textTrimming,
34
+ textTrimming: n.textTrimming,
36
35
  orientation: e,
37
36
  mobileLeftPadding: 0,
38
37
  mobileRightPadding: 0,
39
- cardsInRow: r.cardsInRow,
40
- unresponsive: r.unresponsive,
38
+ cardsInRow: n.cardsInRow,
39
+ unresponsive: n.unresponsive,
41
40
  priceBeforeTextValue: "",
42
41
  priceAfterTextValue: "",
43
42
  discountBeforeTextValue: "",
44
43
  discountAfterTextValue: ""
45
44
  };
46
45
  },
47
- buildCampaignUrl: (a, s) => {
48
- var m;
49
- const c = l(), n = P(), r = Number(a);
46
+ buildCampaignUrl: (i, c) => {
47
+ var l;
48
+ const s = m(), o = x(), n = Number(i);
50
49
  let e;
51
- if (s)
52
- e = s;
50
+ if (c)
51
+ e = c;
53
52
  else {
54
- const i = c.blockStates[r];
55
- if (!i)
53
+ const a = s.blockStates[n];
54
+ if (!a)
56
55
  return "";
57
- const { recommendationConfigs: o } = i;
56
+ const { recommendationConfigs: r } = a;
58
57
  e = {
59
- strategy: o.strategy,
60
- language: o.language,
61
- currencyCode: o.currencySettings.value,
62
- size: o.size,
63
- productIds: o.productIds,
64
- filters: o.filters,
65
- shuffleProducts: o.shuffleProducts
58
+ strategy: r.strategy,
59
+ strategyId: r.strategyId,
60
+ language: r.language,
61
+ currencyCode: r.currencySettings.value,
62
+ size: r.size,
63
+ productIds: r.productIds,
64
+ filters: r.filters,
65
+ shuffleProducts: r.shuffleProducts
66
66
  };
67
67
  }
68
- const f = ((m = I().find((i) => i.key === e.strategy)) == null ? void 0 : m.path) || "", t = new URLSearchParams();
69
- 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", x(e.productIds)) : e.strategy === "similarViewed" && t.set("productId", "{itemId}"), e.strategy === "userBased" && t.set("userId", "{user_id}");
70
- const g = e.filters.filter((i) => i.isValid), d = h(g);
71
- d && t.set("filter", d), e.shuffleProducts && t.set("shuffle", "true"), Object.entries(y(n.partnerName, e.strategy)).forEach(([i, o]) => t.set(i, o));
72
- const p = decodeURIComponent(t.toString()), u = `${R.RECOMMENDATION_API_URL}/v2/${f}?${p}`;
73
- return c.recommendationCampaignUrls[a] = u, u;
68
+ if (e.strategyId)
69
+ return s.recommendationCampaignUrls[i] = {
70
+ strategyId: e.strategyId,
71
+ locale: e.language,
72
+ currency: e.currencyCode
73
+ }, "";
74
+ const g = ((l = y().find((a) => a.key === e.strategy)) == null ? void 0 : l.path) || "", t = new URLSearchParams();
75
+ 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}");
76
+ const f = e.filters.filter((a) => a.isValid), d = b(f);
77
+ d && t.set("filter", d), e.shuffleProducts && t.set("shuffle", "true"), Object.entries(h(o.partnerName, e.strategy)).forEach(([a, r]) => t.set(a, r));
78
+ const p = decodeURIComponent(t.toString()), u = `${I.RECOMMENDATION_API_URL}/v2/${g}?${p}`;
79
+ return s.recommendationCampaignUrls[i] = u, u;
74
80
  }
75
81
  });
76
82
  export {
77
- B as useRecommendation
83
+ k as useRecommendation
78
84
  };
@@ -1,6 +1,6 @@
1
1
  import { BlockId as f } from "../../enums/block.js";
2
- import { useTemplateStore as b } from "../../stores/template.js";
3
- import { mapComposition as y } from "./recommendation/compositionMapper.js";
2
+ import { useTemplateStore as y } from "../../stores/template.js";
3
+ import { mapComposition as b } from "./recommendation/compositionMapper.js";
4
4
  import { extractCurrencyFromBlock as v, extractTitleText as C, extractCardBgColor as M, isPartnerManagedBlock as S } from "./recommendation/extractors.js";
5
5
  import { buildBlockHtml as w } from "./recommendation/htmlBuilder.js";
6
6
  import { parseRecommendationId as x, parseLegacyConfig as R } from "./recommendation/parseLegacyConfig.js";
@@ -20,8 +20,10 @@ function B(i, t, a) {
20
20
  ), !1;
21
21
  const n = a[String(o)] ?? {
22
22
  currencySettings: v(t)
23
- }, c = T(n, r, o), e = y((d = r.composition) == null ? void 0 : d.variables), l = C(t), g = M(t), p = {
23
+ }, c = T(n, r, o), e = b((d = r.composition) == null ? void 0 : d.variables), l = C(t), g = M(t), p = {
24
24
  ...c,
25
+ // Legacy blocks predate RRS — never strategy-backed.
26
+ strategyId: "",
25
27
  composition: e.composition,
26
28
  visibility: e.visibility,
27
29
  textTrimming: e.anyTextTrimming
@@ -56,7 +58,7 @@ function B(i, t, a) {
56
58
  function q(i, t = {}) {
57
59
  const a = new DOMParser(), o = a.parseFromString(i, "text/html"), r = Array.from(o.querySelectorAll(h));
58
60
  try {
59
- b().$patch((e) => {
61
+ y().$patch((e) => {
60
62
  e.migrations = {
61
63
  ...e.migrations,
62
64
  [f.Recommendation]: r.length
@@ -2,10 +2,11 @@ import { useTranslations as r } from "../../composables/useTranslations.js";
2
2
  const l = {
3
3
  RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com",
4
4
  // Relative path → same-origin as the embedding inone dashboard.
5
- PRODUCT_ATTRIBUTES_PATH: "/product-attributes/get-attributes"
6
- }, c = {
5
+ PRODUCT_ATTRIBUTES_PATH: "/product-attributes/get-attributes",
6
+ RECOMMENDATION_STRATEGIES_PATH: "/api/recommendation-strategies"
7
+ }, c = "[sr_strategies.status][=][active]*[sr_strategies.suitable_channels][~][EMAIL]", d = {
7
8
  CLIENT_ID: "clientId"
8
- }, d = () => {
9
+ }, m = () => {
9
10
  const e = r();
10
11
  return [
11
12
  {
@@ -69,14 +70,14 @@ const l = {
69
70
  path: "top-sellers"
70
71
  }
71
72
  ];
72
- }, m = ["discount", "omnibus_price", "omnibus_discount", "price", "original_price"], p = [
73
+ }, p = ["discount", "omnibus_price", "omnibus_discount", "price", "original_price"], v = [
73
74
  { text: "before the amount", value: "0" },
74
75
  { text: "after the amount", value: "1" }
75
- ], v = [
76
+ ], h = [
76
77
  { text: "dot(.)", value: "." },
77
78
  { text: "comma(,)", value: "," },
78
79
  { text: "space( )", value: " " }
79
- ], h = [
80
+ ], x = [
80
81
  { text: "0", value: "0" },
81
82
  { text: "1", value: "1" },
82
83
  { text: "2", value: "2" },
@@ -88,54 +89,55 @@ const l = {
88
89
  { text: "contains", value: "~" },
89
90
  { text: "does not contain", value: "!~" },
90
91
  { text: "any of", value: a }
91
- ], n = [
92
+ ], s = [
92
93
  { text: "is exactly", value: "=" },
93
94
  { text: "is not exactly", value: "!==" },
94
95
  { text: "contains", value: "~" },
95
96
  { text: "does not contain", value: "!~" },
96
97
  { text: "any of", value: a }
97
- ], o = [
98
+ ], n = [
98
99
  { text: "is equal to", value: "=" },
99
100
  { text: "is greater than", value: ">" },
100
101
  { text: "is less than", value: "<" }
101
- ], s = [
102
+ ], o = [
102
103
  { text: "is equal to", value: "=" },
103
104
  { text: "after", value: ">" },
104
105
  { text: "before", value: "<" }
105
106
  ], i = [
106
107
  { text: "true", value: "==" },
107
108
  { text: "false", value: "!=" }
108
- ], x = (e) => {
109
+ ], b = (e) => {
109
110
  if (!e)
110
111
  return t;
111
112
  switch (e) {
112
113
  case "Boolean":
113
114
  return i;
114
115
  case "Date":
115
- return s;
116
- case "Number":
117
116
  return o;
117
+ case "Number":
118
+ return n;
118
119
  case "String":
119
120
  return t;
120
121
  case "Strings":
121
- return n;
122
+ return s;
122
123
  default:
123
124
  return t;
124
125
  }
125
126
  };
126
127
  export {
127
128
  a as OP_ANY_OF,
128
- m as PriceAttributes,
129
- c as QUERY_PARAMS,
129
+ p as PriceAttributes,
130
+ d as QUERY_PARAMS,
131
+ c as RRS_ACTIVE_EMAIL_FILTER,
130
132
  l as URLS,
131
- h as currencyDecimalCounts,
132
- p as currencyLocationMaps,
133
- v as currencyOperators,
134
- x as getOperatorOptions,
135
- d as getRecommendationFeedSourceMaps,
136
- n as operatorOptionsForArrayOfStrings,
133
+ x as currencyDecimalCounts,
134
+ v as currencyLocationMaps,
135
+ h as currencyOperators,
136
+ b as getOperatorOptions,
137
+ m as getRecommendationFeedSourceMaps,
138
+ s as operatorOptionsForArrayOfStrings,
137
139
  i as operatorOptionsForBooleans,
138
- s as operatorOptionsForDates,
139
- o as operatorOptionsForNumbers,
140
+ o as operatorOptionsForDates,
141
+ n as operatorOptionsForNumbers,
140
142
  t as operatorOptionsForStrings
141
143
  };
@@ -1,16 +1,16 @@
1
- import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
1
+ import { DEFAULT_COLUMN_SPACING as n, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as R, DEFAULT_MOBILE_COLUMN_SPACING as U, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as a } from "./layout.js";
2
2
  import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as i, ATTR_PRODUCT_BUTTON as I } from "./selectors.js";
3
- const D = {
3
+ const C = {
4
4
  code: "USD",
5
5
  symbol: "USD",
6
6
  alignment: "after",
7
7
  decimalCount: 2,
8
8
  decimalSeparator: ".",
9
9
  thousandSeparator: ","
10
- }, O = {
10
+ }, D = {
11
11
  textBefore: "",
12
12
  textAfter: ""
13
- }, a = {
13
+ }, O = {
14
14
  textBefore: "",
15
15
  textAfter: ""
16
16
  }, A = [
@@ -36,11 +36,13 @@ const D = {
36
36
  size: "6",
37
37
  shuffleProducts: !1,
38
38
  language: "en_US",
39
- currency: D,
39
+ currency: C,
40
40
  filters: [],
41
+ // Version NOT bumped: mergeWithDefaults() backfills '' for older configs.
42
+ strategyId: "",
41
43
  // Layout
42
44
  layout: "grid",
43
- cardsInRow: C,
45
+ cardsInRow: a,
44
46
  mobileCardsInRow: e,
45
47
  mobileLayoutEnabled: !1,
46
48
  previousMobileCardsInRow: e,
@@ -52,8 +54,8 @@ const D = {
52
54
  composition: A,
53
55
  visibility: c,
54
56
  // Element settings
55
- omnibusPrice: O,
56
- omnibusDiscount: a,
57
+ omnibusPrice: D,
58
+ omnibusDiscount: O,
57
59
  textTrimming: !1,
58
60
  // Price placement (block-level, affects all cards)
59
61
  // Default ON = current stacked look, so existing templates are unaffected.
@@ -71,10 +73,10 @@ const D = {
71
73
  export {
72
74
  m as CURRENT_CONFIG_VERSION,
73
75
  A as DEFAULT_COMPOSITION,
74
- D as DEFAULT_CURRENCY,
76
+ C as DEFAULT_CURRENCY,
75
77
  l as DEFAULT_NODE_CONFIG,
76
- a as DEFAULT_OMNIBUS_DISCOUNT,
77
- O as DEFAULT_OMNIBUS_PRICE,
78
+ O as DEFAULT_OMNIBUS_DISCOUNT,
79
+ D as DEFAULT_OMNIBUS_PRICE,
78
80
  c as DEFAULT_VISIBILITY,
79
81
  N as EXCLUDED_ALGORITHM_IDS
80
82
  };