@useinsider/guido 1.0.3-beta.1852ce0 → 1.0.3-beta.185718d

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 (60) hide show
  1. package/README.md +126 -0
  2. package/dist/components/Guido.vue.js +7 -7
  3. package/dist/components/Guido.vue2.js +36 -35
  4. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +28 -0
  5. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +38 -0
  6. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +17 -0
  7. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +37 -0
  8. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +20 -0
  9. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +44 -0
  10. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue.js +17 -0
  11. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +27 -0
  12. package/dist/components/organisms/header/LeftSlot.vue.js +1 -1
  13. package/dist/components/organisms/header/LeftSlot.vue2.js +16 -15
  14. package/dist/components/organisms/header/RightSlot.vue.js +5 -5
  15. package/dist/components/organisms/header/RightSlot.vue2.js +20 -19
  16. package/dist/composables/useBlocksConfig.js +58 -0
  17. package/dist/composables/usePartner.js +11 -10
  18. package/dist/composables/useStripo.js +39 -48
  19. package/dist/enums/defaults.js +10 -5
  20. package/dist/enums/extensions/recommendationBlock.js +80 -0
  21. package/dist/extensions/Blocks/RadioButton/template.js +6 -6
  22. package/dist/extensions/Blocks/Recommendation/block.js +27 -0
  23. package/dist/extensions/Blocks/Recommendation/control.js +277 -0
  24. package/dist/extensions/Blocks/Recommendation/extension.js +10 -0
  25. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +51 -0
  26. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +19 -0
  27. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +32 -0
  28. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +266 -0
  29. package/dist/extensions/Blocks/Recommendation/template.js +200 -0
  30. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +28 -0
  31. package/dist/extensions/Blocks/common-control.js +102 -0
  32. package/dist/guido.css +1 -1
  33. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +83 -72
  34. package/dist/services/recommendationApi.js +43 -0
  35. package/dist/src/@types/generic.d.ts +11 -0
  36. package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +19 -0
  37. package/dist/src/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.d.ts +2 -0
  38. package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +2 -0
  39. package/dist/src/components/organisms/extensions/recommendation/LogicAdapter.vue.d.ts +16 -0
  40. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  41. package/dist/src/composables/useBlocksConfig.d.ts +11 -0
  42. package/dist/src/composables/usePartner.d.ts +1 -0
  43. package/dist/src/enums/extensions/recommendationBlock.d.ts +16 -0
  44. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  45. package/dist/src/extensions/Blocks/Recommendation/control.d.ts +29 -0
  46. package/dist/src/extensions/Blocks/Recommendation/extension.d.ts +2 -0
  47. package/dist/src/extensions/Blocks/Recommendation/iconsRegistry.d.ts +4 -0
  48. package/dist/src/extensions/Blocks/Recommendation/settingsPanel.d.ts +4 -0
  49. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +555 -0
  50. package/dist/src/extensions/Blocks/Recommendation/template.d.ts +6 -0
  51. package/dist/src/extensions/Blocks/Recommendation/utils/filterUtil.d.ts +7 -0
  52. package/dist/src/extensions/Blocks/common-control.d.ts +66 -0
  53. package/dist/src/mock/api/recommendation.d.ts +2 -0
  54. package/dist/src/services/recommendationApi.d.ts +6 -0
  55. package/dist/src/stores/config.d.ts +4 -0
  56. package/dist/src/stores/editor.d.ts +21 -0
  57. package/dist/src/utils/genericUtil.d.ts +1 -0
  58. package/dist/stores/editor.js +2 -1
  59. package/dist/utils/genericUtil.js +8 -7
  60. package/package.json +2 -2
package/README.md CHANGED
@@ -191,6 +191,10 @@ interface GuidoConfig {
191
191
  saveAsTemplate: boolean;
192
192
  versionHistory: boolean;
193
193
  };
194
+ blocks?: {
195
+ excludeDefaults?: GuidoBlockType[];
196
+ includeCustoms?: GuidoCustomBlockType[];
197
+ };
194
198
  }
195
199
  ```
196
200
 
@@ -204,6 +208,9 @@ interface GuidoConfig {
204
208
  | `features.dynamicContent` | `boolean` | `true` | Enable dynamic content insertion feature |
205
209
  | `features.saveAsTemplate` | `boolean` | `true` | Enable save as template feature |
206
210
  | `features.versionHistory` | `boolean` | `true` | Enable version history feature |
211
+ | `blocks` | `BlocksConfig` | `{ excludeDefaults: [], includeCustoms: [] }` | Block configuration for excluding default blocks and including custom blocks. See [Blocks Configuration](#-blocks-configuration) section below |
212
+ | `blocks.excludeDefaults` | `GuidoBlockType[]` | `[]` | Array of default Stripo blocks to exclude from the editor |
213
+ | `blocks.includeCustoms` | `GuidoCustomBlockType[]` | `[]` | Array of custom blocks to include in the editor |
207
214
 
208
215
  ```typescript
209
216
  interface DynamicContent {
@@ -220,6 +227,125 @@ interface DynamicContent {
220
227
  | `text` | `string` | '' | Visible value of the dynamic content |
221
228
  | `fallback?` | `string` | '' | Fallback value of the dynamic content. Optional |
222
229
 
230
+ ## 🧱 Blocks Configuration
231
+
232
+ Guido allows you to customize which blocks are available in the editor. You can exclude default Stripo blocks and selectively include custom blocks to create tailored editing experiences for different product types.
233
+
234
+ ### Block Types
235
+
236
+ #### Default Blocks (GuidoBlockType)
237
+
238
+ These are the standard Stripo email editor blocks that can be excluded:
239
+
240
+ ```typescript
241
+ type GuidoBlockType =
242
+ | 'amp-accordion' // AMP accordion component
243
+ | 'amp-carousel' // AMP image carousel
244
+ | 'amp-form-controls' // AMP form elements
245
+ | 'banner-block' // Banner/hero section
246
+ | 'button-block' // Call-to-action buttons
247
+ | 'html-block' // Custom HTML
248
+ | 'image-block' // Image elements
249
+ | 'menu-block' // Navigation menu
250
+ | 'social-block' // Social media links
251
+ | 'spacer-block' // Vertical spacing
252
+ | 'text-block' // Text content
253
+ | 'timer-block' // Countdown timer
254
+ | 'video-block' // Video embeds
255
+ ```
256
+
257
+ #### Custom Blocks (GuidoCustomBlockType)
258
+
259
+ These are custom blocks that can be selectively included:
260
+
261
+ ```typescript
262
+ type GuidoCustomBlockType =
263
+ | 'dynamic-content' // Dynamic content merge tags
264
+ | 'checkbox-block' // Checkbox form input
265
+ | 'radio-button-block' // Radio button form input
266
+ | 'recommendation-block' // Product recommendations
267
+ | 'unsubscribe-block' // Unsubscribe link
268
+ | 'coupon-block' // Coupon/promo code
269
+ | 'items-block' // Cart items display
270
+ ```
271
+
272
+ ### Configuration Examples
273
+
274
+ #### Example 1: Exclude Specific Default Blocks
275
+
276
+ Disable button, image, and video blocks while keeping all custom blocks:
277
+
278
+ ```typescript
279
+ const guidoConfig = {
280
+ translationsPath: 'window.trans.en',
281
+ features: {
282
+ dynamicContent: true,
283
+ saveAsTemplate: true,
284
+ versionHistory: true
285
+ },
286
+ blocks: {
287
+ excludeDefaults: ['button-block', 'image-block', 'video-block']
288
+ }
289
+ };
290
+ ```
291
+
292
+ **Result:**
293
+ - Button, Image, Video blocks disabled
294
+ - All other default blocks enabled
295
+ - All custom blocks are disabled.
296
+
297
+ #### Example 2: Include Only Specific Custom Blocks
298
+
299
+ Enable only coupon and recommendation blocks:
300
+
301
+ ```typescript
302
+ const guidoConfig = {
303
+ translationsPath: 'window.trans.en',
304
+ features: {
305
+ dynamicContent: true,
306
+ saveAsTemplate: true,
307
+ versionHistory: true
308
+ },
309
+ blocks: {
310
+ includeCustoms: ['coupon-block', 'recommendation-block']
311
+ }
312
+ };
313
+ ```
314
+
315
+ **Result:**
316
+ - All default blocks enabled
317
+ - Only Coupon and Recommendation extensions enabled.
318
+ - Other custom blocks are disabled
319
+
320
+ ### Default Behavior
321
+
322
+ When `blocks` is not provided or is `undefined`:
323
+
324
+ ```typescript
325
+ const guidoConfig = {
326
+ translationsPath: 'window.trans.en',
327
+ features: {
328
+ dynamicContent: true,
329
+ saveAsTemplate: true,
330
+ versionHistory: true
331
+ }
332
+ // No blocks config
333
+ };
334
+ ```
335
+
336
+ **Result:**
337
+ - All 13 default Stripo blocks enabled
338
+ - All custom blocks are disabled.
339
+
340
+ ### Block Configuration Interface
341
+
342
+ ```typescript
343
+ interface BlocksConfig {
344
+ excludeDefaults?: GuidoBlockType[];
345
+ includeCustoms?: GuidoCustomBlockType[];
346
+ }
347
+ ```
348
+
223
349
  ### TypeScript Types
224
350
 
225
351
  The library exports the following TypeScript types:
@@ -1,18 +1,18 @@
1
1
  import a from "./Guido.vue2.js";
2
2
  /* empty css */
3
3
  import i from "../_virtual/_plugin-vue2_normalizer.js";
4
- var s = function() {
4
+ var t = function() {
5
5
  var o = this, r = o._self._c, e = o._self._setupProxy;
6
- return r("div", { staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), 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.SaveAsTemplateDrawer), e.isTestPartner() ? o._e() : r(e.OnboardingWrapper), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
7
- }, t = [], d = /* @__PURE__ */ i(
6
+ return r("div", { staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), 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), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
7
+ }, s = [], d = /* @__PURE__ */ i(
8
8
  a,
9
- s,
10
9
  t,
10
+ s,
11
11
  !1,
12
12
  null,
13
- "96687c1d"
13
+ "e8d51dec"
14
14
  );
15
- const v = d.exports;
15
+ const l = d.exports;
16
16
  export {
17
- v as default
17
+ l as default
18
18
  };
@@ -1,22 +1,23 @@
1
- import { defineComponent as x, defineAsyncComponent as U, ref as F, computed as I, watch as M, onMounted as z, onUnmounted as B } from "vue";
1
+ import { defineComponent as R, defineAsyncComponent as I, ref as x, computed as U, watch as M, onMounted as z, onUnmounted as B } from "vue";
2
2
  import { provideGuidoActions as K } from "../composables/useGuidoActions.js";
3
3
  import { usePartner as O } from "../composables/usePartner.js";
4
4
  import { useStripo as j } from "../composables/useStripo.js";
5
5
  import { migrate as W } from "../config/migrator/index.js";
6
6
  import { DefaultUsername as q, DefaultMessageType as J, DefaultGuidoConfig as Q } from "../enums/defaults.js";
7
7
  import V from "./organisms/base/Toaster.vue.js";
8
- import X from "./organisms/header/HeaderWrapper.vue.js";
9
- import Y from "./organisms/LoadingWrapper.vue.js";
10
- import Z from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
11
- import $ from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
12
- import { useStripoApi as ee } from "../services/stripoApi.js";
13
- import { useConfigStore as oe } from "../stores/config.js";
14
- import { useDynamicContentStore as te } from "../stores/dynamic-content.js";
15
- import { useEditorStore as ne } from "../stores/editor.js";
16
- import { usePreviewStore as re } from "../stores/preview.js";
8
+ import X from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
9
+ import Y from "./organisms/header/HeaderWrapper.vue.js";
10
+ import Z from "./organisms/LoadingWrapper.vue.js";
11
+ import $ from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
12
+ import ee from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
13
+ import { useStripoApi as oe } from "../services/stripoApi.js";
14
+ import { useConfigStore as te } from "../stores/config.js";
15
+ import { useDynamicContentStore as ne } from "../stores/dynamic-content.js";
16
+ import { useEditorStore as re } from "../stores/editor.js";
17
+ import { usePreviewStore as ae } from "../stores/preview.js";
17
18
  import { useUnsubscribeStore as se } from "../stores/unsubscribe.js";
18
- import ae from "../node_modules/lodash-es/merge.js";
19
- const Ee = /* @__PURE__ */ x({
19
+ import ie from "../node_modules/lodash-es/merge.js";
20
+ const Ge = /* @__PURE__ */ R({
20
21
  __name: "Guido",
21
22
  props: {
22
23
  templateId: null,
@@ -32,41 +33,41 @@ const Ee = /* @__PURE__ */ x({
32
33
  },
33
34
  emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready"],
34
35
  setup(_, { expose: L, emit: t }) {
35
- const d = _, k = U(
36
+ const u = _, k = I(
36
37
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
37
- ), A = U(
38
+ ), A = I(
38
39
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
39
- ), m = F(), s = te(), u = se(), l = oe(), p = ne(), N = re(), n = I(() => p.hasChanges), { getPartnerName: g, getProductType: f, isTestPartner: H } = O(), y = () => {
40
+ ), l = x(), a = ne(), p = se(), g = te(), s = re(), N = ae(), n = U(() => s.hasChanges), { getPartnerName: f, getProductType: y, isTestPartner: F } = O(), v = () => {
40
41
  var e;
41
- return (e = m.value) == null ? void 0 : e.handleSave(!0);
42
+ return (e = l.value) == null ? void 0 : e.handleSave(!0);
42
43
  }, {
43
- templateId: v,
44
+ templateId: i,
44
45
  userId: b,
45
46
  guidoConfig: C,
46
47
  templateConfig: o,
47
48
  html: r = "",
48
49
  css: h = "",
49
- partnerName: a = g(),
50
- productType: i = f(),
50
+ partnerName: c = f(),
51
+ productType: m = y(),
51
52
  messageType: S = J,
52
53
  username: w = q
53
- } = d, c = (o == null ? void 0 : o.preselectedDynamicContentList) || [];
54
- window.GuidoConfig = ae(Q, C), window.GuidoConfig.partner = {
55
- partnerName: a,
56
- productType: i,
54
+ } = u, d = (o == null ? void 0 : o.preselectedDynamicContentList) || [];
55
+ s.templateId = i, window.GuidoConfig = ie(Q, C), window.GuidoConfig.partner = {
56
+ partnerName: c,
57
+ productType: m,
57
58
  messageType: S
58
- }, l.templateConfig = o;
59
+ }, g.templateConfig = o;
59
60
  const { initPlugin: D } = j({
60
- emailId: v,
61
+ emailId: i,
61
62
  userId: b,
62
63
  username: w,
63
- partnerName: a,
64
- productType: i,
65
- preselectedDynamicContentList: c,
64
+ partnerName: c,
65
+ productType: m,
66
+ preselectedDynamicContentList: d,
66
67
  onReady: () => {
67
68
  console.debug("guido:ready"), t("ready");
68
69
  }
69
- }), { getDefaultTemplate: T } = ee(), R = I(() => {
70
+ }), { getDefaultTemplate: T } = oe(), H = U(() => {
70
71
  var e;
71
72
  return !((e = window.GuidoConfig) != null && e.useHeader);
72
73
  });
@@ -82,7 +83,7 @@ const Ee = /* @__PURE__ */ x({
82
83
  }
83
84
  });
84
85
  const E = (e) => {
85
- console.debug("dynamic-content:close", e), s.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
86
+ console.debug("dynamic-content:close", e), a.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
86
87
  }, P = () => {
87
88
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
88
89
  };
@@ -91,14 +92,14 @@ const Ee = /* @__PURE__ */ x({
91
92
  }), z(async () => {
92
93
  console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow");
93
94
  try {
94
- u.selectedUnsubscribePages = (o == null ? void 0 : o.selectedUnsubscribePages) || [];
95
+ p.selectedUnsubscribePages = (o == null ? void 0 : o.selectedUnsubscribePages) || [];
95
96
  let e = {
96
97
  html: r && await W(r),
97
98
  css: h,
98
99
  forceRecreate: !0
99
100
  // TODO: It should be false for old templates. We will communicate with Stripo
100
101
  };
101
- e.html || (e = await T(), e.html = await W(e.html)), await D(e), s.selectedDynamicContentList = c;
102
+ e.html || (e = await T(), e.html = await W(e.html)), await D(e), a.selectedDynamicContentList = d;
102
103
  } catch (e) {
103
104
  console.error("Failed to initialize Stripo editor:", e);
104
105
  }
@@ -118,10 +119,10 @@ const Ee = /* @__PURE__ */ x({
118
119
  close: P
119
120
  },
120
121
  hasChanges: n,
121
- saveSilent: y
122
- }), { __sfc: !0, PreviewContainer: k, OnboardingWrapper: A, headerWrapperRef: m, dynamicContentStore: s, unsubscribeStore: u, props: d, configStore: l, editorStore: p, previewStore: N, hasChanges: n, getPartnerName: g, getProductType: f, isTestPartner: H, saveSilent: y, templateId: v, userId: b, guidoConfig: C, templateConfig: o, html: r, css: h, partnerName: a, productType: i, messageType: S, username: w, preselectedDynamicContentList: c, emit: t, initPlugin: D, getDefaultTemplate: T, noHeader: R, insertDynamicContent: E, closeDynamicContent: P, Toaster: V, HeaderWrapper: X, LoadingWrapper: Y, SaveAsTemplateDrawer: Z, UnsubscribeWrapper: $ };
122
+ saveSilent: v
123
+ }), { __sfc: !0, PreviewContainer: k, OnboardingWrapper: A, headerWrapperRef: l, dynamicContentStore: a, unsubscribeStore: p, props: u, configStore: g, editorStore: s, previewStore: N, hasChanges: n, getPartnerName: f, getProductType: y, isTestPartner: F, saveSilent: v, templateId: i, userId: b, guidoConfig: C, templateConfig: o, html: r, css: h, partnerName: c, productType: m, messageType: S, username: w, preselectedDynamicContentList: d, emit: t, initPlugin: D, getDefaultTemplate: T, noHeader: H, insertDynamicContent: E, closeDynamicContent: P, Toaster: V, FilterSelectionDrawer: X, HeaderWrapper: Y, LoadingWrapper: Z, SaveAsTemplateDrawer: $, UnsubscribeWrapper: ee };
123
124
  }
124
125
  });
125
126
  export {
126
- Ee as default
127
+ Ge as default
127
128
  };
@@ -0,0 +1,28 @@
1
+ import r from "./FilterItem.vue2.js";
2
+ /* empty css */
3
+ import i from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var l = function() {
5
+ var a = this, e = a._self._c, t = a._self._setupProxy;
6
+ return e("div", { staticClass: "d-f f-d-c w-1 gap-16" }, [e("div", { staticClass: "d-f a-i-c j-c-s-b pt-4", class: { "bor-t-s-s bor-t-w-1 bor-t-c-50": a.index === 0 } }, [e("p", [a._v(" " + a._s(t.trans("newsletter.filter")) + " " + a._s(a.index + 1) + " ")]), e(t.InButtonV2, { attrs: { id: "guido__delete-filter-group-button", "left-icon": "line-delete", styling: "text", type: "danger", "label-text-status": !1 }, on: { click: function(s) {
7
+ return t.emit("delete-filter", t.props.filter);
8
+ } } })], 1), e("div", { staticClass: "w-1 d-f a-i-s j-c-s-b gap-16" }, [e(t.InSelect, { staticClass: "w-2", attrs: { "disabled-status": "", "search-status": "", "button-status": !1, "label-text": t.trans("action-builder.filter-type"), options: t.filterTypeOptions, value: [t.filterTypeOptions[0]] } }), e(t.InSelect, { staticClass: "w-2", attrs: { id: "filter-item-input--attribute-type", "search-status": "", "static-position": "bottom right", "button-status": !1, "label-text": t.trans("condition.attribute"), options: t.store.getFilterList, value: [t.selectedAttributeType] }, on: { select: function(s) {
9
+ return t.updateFilter({ text: "attribute", value: s.value });
10
+ } } })], 1), e("div", { staticClass: "w-1 d-f a-i-s j-c-s-b gap-16" }, [e(t.InSelect, { staticClass: "w-2", attrs: { "button-status": !1, "label-text": t.trans("condition.operator"), options: t.getOperatorOptions(t.selectedAttributeType.type), value: [t.selectedOperatorType] }, on: { select: function(s) {
11
+ return t.updateFilter({ text: "operator", value: s.value });
12
+ } } }), e(t.InBasicTextInput, { staticClass: "w-2", attrs: { id: "filter-item-input--value", name: "imageUrl", type: "text", "character-counter-status": !1, "label-text": t.trans("condition.value"), "max-character-length": 25, "placeholder-text": t.trans("condition.enter-value-placeholder"), "tooltip-status": !1, value: decodeURIComponent(t.props.filter.value) }, on: { input: function(s) {
13
+ t.updateFilter({ text: "value", value: encodeURIComponent(s) });
14
+ } } })], 1), t.props.hasLogicAdapter ? e("div", { staticClass: "w-1 d-f a-i-c j-c-c p-r bor-b-s-s bor-b-w-1 bor-b-c-50 mt-4" }, [e(t.LogicAdapter, { staticClass: "p-a", attrs: { logic: t.props.filter.innerGroupOperator }, on: { change: function(s) {
15
+ return t.updateFilter({ text: "innerGroupOperator", value: s });
16
+ } } })], 1) : a._e()]);
17
+ }, n = [], o = /* @__PURE__ */ i(
18
+ r,
19
+ l,
20
+ n,
21
+ !1,
22
+ null,
23
+ "6562e38c"
24
+ );
25
+ const f = o.exports;
26
+ export {
27
+ f as default
28
+ };
@@ -0,0 +1,38 @@
1
+ import { defineComponent as f, computed as i } from "vue";
2
+ import { useTranslations as v } from "../../../../composables/useTranslations.js";
3
+ import { getOperatorOptions as a } from "../../../../enums/extensions/recommendationBlock.js";
4
+ import { useRecommendationExtensionStore as x } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
5
+ import { InButtonV2 as y, InSelect as F, InBasicTextInput as T } from "@useinsider/design-system-vue";
6
+ import _ from "./LogicAdapter.vue.js";
7
+ import { useDebounceFn as b } from "../../../../node_modules/@vueuse/shared/index.js";
8
+ const h = /* @__PURE__ */ f({
9
+ __name: "FilterItem",
10
+ props: {
11
+ filter: null,
12
+ index: null,
13
+ hasLogicAdapter: { type: Boolean }
14
+ },
15
+ emits: ["delete-filter"],
16
+ setup(p, { emit: u }) {
17
+ const e = p, n = v(), r = x(), m = [
18
+ {
19
+ text: n("email-editor.standard-filter"),
20
+ value: "standardFilter"
21
+ }
22
+ ], s = i(() => e.filter.attribute || ""), l = i(() => r.getFilterList.find((t) => t.value === s.value) || { text: "", value: "", type: "" }), c = i(() => {
23
+ var t;
24
+ return a((t = l.value) == null ? void 0 : t.type).find((o) => o.value === e.filter.operator);
25
+ }), d = b((t) => {
26
+ console.debug("updateFilter: ", t);
27
+ const o = {
28
+ ...e.filter,
29
+ [t.text]: t.value
30
+ };
31
+ r.updateFilter(o);
32
+ }, 500);
33
+ return { __sfc: !0, trans: n, store: r, props: e, filterTypeOptions: m, attributeType: s, selectedAttributeType: l, selectedOperatorType: c, emit: u, updateFilter: d, getOperatorOptions: a, InBasicTextInput: T, InSelect: F, InButtonV2: y, LogicAdapter: _ };
34
+ }
35
+ });
36
+ export {
37
+ h as default
38
+ };
@@ -0,0 +1,17 @@
1
+ import o from "./FilterSelectionDrawer.vue2.js";
2
+ import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
3
+ var l = function() {
4
+ var e = this, r = e._self._c, t = e._self._setupProxy;
5
+ return r(t.WpDrawer, { attrs: { id: "recommendation-filter-drawer", "title-text": "Filter Selection", "footer-button-group-options": t.footerButtonGroupOptions, status: t.store.filterSelectionDrawerStatus }, on: { cancelOrBackButtonEvent: t.closeModal, onCloseEvent: t.closeModal, primaryButtonEvent: t.applyFilter } }, [r(t.Filters)], 1);
6
+ }, s = [], a = /* @__PURE__ */ n(
7
+ o,
8
+ l,
9
+ s,
10
+ !1,
11
+ null,
12
+ null
13
+ );
14
+ const p = a.exports;
15
+ export {
16
+ p as default
17
+ };
@@ -0,0 +1,37 @@
1
+ import { defineComponent as n, ref as a, computed as l } from "vue";
2
+ import i from "../../../wrappers/WpDrawer.vue.js";
3
+ import { useTranslations as p } from "../../../../composables/useTranslations.js";
4
+ import { useRecommendationExtensionStore as c } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
5
+ import u from "./Filters.vue.js";
6
+ const b = /* @__PURE__ */ n({
7
+ __name: "FilterSelectionDrawer",
8
+ setup(m) {
9
+ const t = p(), o = c(), e = a(!1), s = l(() => ({
10
+ primaryButton: {
11
+ styling: "solid",
12
+ type: "primary",
13
+ labelText: t(
14
+ e.value ? "unsubscription-preference.selecting-type" : "products.select-and-continue"
15
+ ),
16
+ loadingStatus: e.value,
17
+ disabledStatus: !1
18
+ },
19
+ cancelOrBackButton: {
20
+ styling: "ghost",
21
+ type: "secondary",
22
+ labelText: t("products.cancel"),
23
+ disabledStatus: e.value
24
+ }
25
+ })), r = () => {
26
+ o.filterSelectionDrawerStatus = !1;
27
+ };
28
+ return { __sfc: !0, trans: t, store: o, isApplying: e, footerButtonGroupOptions: s, closeModal: r, applyFilter: () => {
29
+ e.value = !0, setTimeout(() => {
30
+ console.debug("Filter applied!"), r(), o.generateFilterQuery();
31
+ }, 2e3);
32
+ }, WpDrawer: i, Filters: u };
33
+ }
34
+ });
35
+ export {
36
+ b as default
37
+ };
@@ -0,0 +1,20 @@
1
+ import s from "./Filters.vue2.js";
2
+ /* empty css */
3
+ import a from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var o = function() {
5
+ var i = this, e = i._self._c, t = i._self._setupProxy;
6
+ return e("div", { staticClass: "d-f f-d-c gap-16" }, [e("div", { staticClass: "d-f a-i-c j-c-s-b gap-16" }, [e(t.InSegments, { staticClass: "f-g-1 w-1", attrs: { id: "guido__filter-group-segments", "segment-list": t.filterGroupList, selected: t.selectedFilterGroup, "with-icon": !1 }, on: { click: t.changeFilterGroup } }), e(t.InButtonV2, { staticClass: "w-20-s f-g-1", attrs: { id: "guido__add-filter-group-button", "left-icon": "line-plus-netural", type: "secondary", "disabled-status": t.isMaxFilterGroupCount, "label-text": t.trans("smart-recommender.add-filter-group"), "tooltip-text": t.isMaxFilterGroupCount ? t.trans("email-editor.add-filter-tooltip") : "" }, on: { click: t.handleAddFilterGroup } })], 1), e("div", { staticClass: "d-f a-i-c j-c-s-b gap-16" }, [e("div", { staticClass: "d-f a-i-c" }, [t.selectedFilterGroup > 1 ? e(t.LogicAdapter, { staticClass: "mr-2" }) : i._e(), e("p", [i._v(" " + i._s(t.trans("email-editor.filter-group")) + " " + i._s(t.selectedFilterGroup) + " ")])], 1), t.hasRemoveFilterButton ? e(t.InButtonV2, { attrs: { id: "guido__delete-filter-group-button", "left-icon": "line-delete", styling: "text", type: "danger", "label-text-status": !1 }, on: { click: t.handleDeleteFilterGroup } }) : i._e()], 1), e("div", { staticClass: "d-f a-i-c j-c-s-b f-d-c" }, i._l(t.selectedFilterGroupFilters, function(l, r) {
7
+ return e(t.FilterItem, { key: r, attrs: { filter: l, "has-logic-adapter": t.hasLogicAdapter && r !== t.selectedFilterGroupFilters.length - 1, index: r }, on: { "delete-filter": t.handleDeleteFilter } });
8
+ }), 1), e("div", { staticClass: "d-f a-i-c j-c-c mt-3" }, [e(t.InButtonV2, { staticClass: "w-11-s", attrs: { id: "filter-group--add-filter-button", "left-icon": "line-plus-netural", type: "subtle-primary", "label-text": t.trans("smart-recommender.add-filter-condition") }, on: { click: t.handleAddFilter } })], 1)]);
9
+ }, d = [], n = /* @__PURE__ */ a(
10
+ s,
11
+ o,
12
+ d,
13
+ !1,
14
+ null,
15
+ "1ccb6d4a"
16
+ );
17
+ const _ = n.exports;
18
+ export {
19
+ _ as default
20
+ };
@@ -0,0 +1,44 @@
1
+ import { defineComponent as m, computed as o, ref as h } from "vue";
2
+ import { useTranslations as G } from "../../../../composables/useTranslations.js";
3
+ import { useRecommendationExtensionStore as g } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
4
+ import { InButtonV2 as v, InSegments as f } from "@useinsider/design-system-vue";
5
+ import _ from "./FilterItem.vue.js";
6
+ import A from "./LogicAdapter.vue.js";
7
+ const E = /* @__PURE__ */ m({
8
+ __name: "Filters",
9
+ setup(R) {
10
+ const i = G(), l = g(), u = o(() => l.getFilterGroupCount), t = o(() => Array.from({ length: u.value }, (e, a) => ({
11
+ text: (a + 1).toString(),
12
+ value: a + 1
13
+ }))), r = h(1), s = (e) => {
14
+ r.value = e;
15
+ }, d = () => {
16
+ const e = t.value.length + 1;
17
+ console.debug("handleAddFilterGroup", e), t.value.push({
18
+ text: e.toString(),
19
+ value: e
20
+ }), l.addFilterGroup(e);
21
+ }, p = o(() => t.value.length >= 3), n = o(() => l.getSelectedFilterGroup(r.value)), c = o(() => n.value.length > 1), F = o(() => t.value.length > 1);
22
+ return { __sfc: !0, MAX_FILTER_GROUP_COUNT: 3, trans: i, store: l, filterGroupCount: u, filterGroupList: t, selectedFilterGroup: r, changeFilterGroup: s, handleAddFilterGroup: d, isMaxFilterGroupCount: p, selectedFilterGroupFilters: n, hasLogicAdapter: c, hasRemoveFilterButton: F, handleAddFilter: () => {
23
+ l.addFilter({
24
+ type: "standardFilter",
25
+ attribute: "",
26
+ operatorReplace: "",
27
+ operator: "",
28
+ innerGroupOperator: "*",
29
+ outerGroupOperator: "*",
30
+ filterNumber: n.value.length + 1,
31
+ filterGroup: r.value,
32
+ isValid: !1,
33
+ value: ""
34
+ }), console.debug("handleAddFilter");
35
+ }, handleDeleteFilter: (e) => {
36
+ console.debug("handleDeleteFilter: ", e), l.deleteFilter(e);
37
+ }, handleDeleteFilterGroup: () => {
38
+ t.value.length !== 1 && (console.debug("handleDeleteFilterGroup"), t.value.splice(r.value - 1, 1), r.value > 1 && r.value--);
39
+ }, InSegments: f, InButtonV2: v, FilterItem: _, LogicAdapter: A };
40
+ }
41
+ });
42
+ export {
43
+ E as default
44
+ };
@@ -0,0 +1,17 @@
1
+ import s from "./LogicAdapter.vue2.js";
2
+ import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
3
+ var o = function() {
4
+ var t = this, r = t._self._c, e = t._self._setupProxy;
5
+ return r(e.InSegments, { staticClass: "guido__logic-adapter f-g-1", attrs: { "segment-list": e.logicAdapterList, selected: e.selectedLogicAdapter, "with-icon": !1 }, on: { click: e.changeLogicAdapter } });
6
+ }, a = [], c = /* @__PURE__ */ n(
7
+ s,
8
+ o,
9
+ a,
10
+ !1,
11
+ null,
12
+ null
13
+ );
14
+ const p = c.exports;
15
+ export {
16
+ p as default
17
+ };
@@ -0,0 +1,27 @@
1
+ import { defineComponent as s, ref as n } from "vue";
2
+ import { InSegments as p } from "@useinsider/design-system-vue";
3
+ const l = /* @__PURE__ */ s({
4
+ __name: "LogicAdapter",
5
+ props: {
6
+ logic: null
7
+ },
8
+ emits: ["change"],
9
+ setup(r, { emit: e }) {
10
+ const t = r, a = n([
11
+ {
12
+ text: "and",
13
+ value: "*"
14
+ },
15
+ {
16
+ text: "or",
17
+ value: "|"
18
+ }
19
+ ]), o = n(t.logic || "*");
20
+ return { __sfc: !0, logicAdapterList: a, emit: e, props: t, selectedLogicAdapter: o, changeLogicAdapter: (c) => {
21
+ o.value = c, e("change", c);
22
+ }, InSegments: p };
23
+ }
24
+ });
25
+ export {
26
+ l as default
27
+ };
@@ -10,7 +10,7 @@ var n = function() {
10
10
  a,
11
11
  !1,
12
12
  null,
13
- "2c168944"
13
+ "244e7935"
14
14
  );
15
15
  const p = i.exports;
16
16
  export {
@@ -1,28 +1,29 @@
1
- import { defineComponent as s, computed as c } from "vue";
1
+ import { defineComponent as c, computed as a } from "vue";
2
2
  import { useBack as m } from "../../../composables/useGuidoActions.js";
3
- import { usePreviewMode as a } from "../../../composables/usePreviewMode.js";
4
- import { useTranslations as p } from "../../../composables/useTranslations.js";
5
- import { useVersionHistoryApi as u } from "../../../composables/useVersionHistoryApi.js";
6
- import { useEditorStore as d } from "../../../stores/editor.js";
7
- import { InButtonV2 as f } from "@useinsider/design-system-vue";
8
- import l from "./version-history/RestoreButton.vue.js";
9
- const O = /* @__PURE__ */ s({
3
+ import { usePartner as u } from "../../../composables/usePartner.js";
4
+ import { usePreviewMode as p } from "../../../composables/usePreviewMode.js";
5
+ import { useTranslations as f } from "../../../composables/useTranslations.js";
6
+ import { useVersionHistoryApi as d } from "../../../composables/useVersionHistoryApi.js";
7
+ import { useEditorStore as l } from "../../../stores/editor.js";
8
+ import { InButtonV2 as k } from "@useinsider/design-system-vue";
9
+ import b from "./version-history/RestoreButton.vue.js";
10
+ const h = /* @__PURE__ */ c({
10
11
  __name: "LeftSlot",
11
- setup(k) {
12
- const o = d(), r = m(), { closeVersionHistory: t } = u(), { closePreviewMode: i } = a(), e = p(), n = c(() => o.isVersionHistoryOpen || o.isPreviewModeOpen ? e("email-editor.back-to-editor") : e("email-editor.back-to-design"));
13
- return { __sfc: !0, editorStore: o, handleBack: r, closeVersionHistory: t, closePreviewMode: i, trans: e, backButtonLabel: n, handleBackClick: () => {
14
- if (o.isVersionHistoryOpen) {
12
+ setup(_) {
13
+ const e = l(), r = m(), { closeVersionHistory: t } = d(), { closePreviewMode: i } = p(), { isUnsubscribePages: s } = u(), o = f(), n = a(() => e.isVersionHistoryOpen || e.isPreviewModeOpen ? o("email-editor.back-to-editor") : s() ? o("email-editor.back-to-unsubscribe-pages") : o("email-editor.back-to-design"));
14
+ return { __sfc: !0, editorStore: e, handleBack: r, closeVersionHistory: t, closePreviewMode: i, isUnsubscribePages: s, trans: o, backButtonLabel: n, handleBackClick: () => {
15
+ if (e.isVersionHistoryOpen) {
15
16
  t();
16
17
  return;
17
18
  }
18
- if (o.isPreviewModeOpen) {
19
+ if (e.isPreviewModeOpen) {
19
20
  i();
20
21
  return;
21
22
  }
22
23
  r();
23
- }, InButtonV2: f, RestoreButton: l };
24
+ }, InButtonV2: k, RestoreButton: b };
24
25
  }
25
26
  });
26
27
  export {
27
- O as default
28
+ h as default
28
29
  };
@@ -1,12 +1,12 @@
1
1
  import n from "./RightSlot.vue2.js";
2
2
  import a from "../../../_virtual/_plugin-vue2_normalizer.js";
3
3
  var l = function() {
4
- var s, i;
5
- var o = this, e = o._self._c, t = o._self._setupProxy;
6
- return e("div", { staticClass: "d-f" }, [(s = t.config.features) != null && s.versionHistory ? e(t.InButtonV2, { attrs: { id: "guido__history-button", "left-icon": "line-architect-version-history", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isVersionHistoryButtonDisabled, "label-text-status": !1, "selected-status": t.editorStore.isVersionHistoryOpen, "tooltip-options": t.getTooltipOptions("guido__history-button"), "tooltip-text": t.versionHistoryTooltipText }, on: { click: t.handleVersionHistory } }) : o._e(), e(t.InButtonV2, { attrs: { id: "guido__export-button", "left-icon": "line-export", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isExportButtonDisabled, "label-text-status": !1, "loading-status": t.isExporting, "tooltip-options": t.getTooltipOptions("guido__export-button"), "tooltip-text": t.trans("newsletter.export") }, on: { click: t.handleExport } }), (i = t.config.features) != null && i.saveAsTemplate ? e(t.InButtonV2, { attrs: { id: "guido__save-as-button", "left-icon": "line-newsletter-save-as-template", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isSaveAsButtonDisabled, "label-text-status": !1, "tooltip-options": t.getTooltipOptions("guido__save-as-button"), "tooltip-text": t.trans("newsletter.save-templates") }, on: { click: t.handleSaveAs } }) : o._e(), e(t.InButtonV2, { attrs: { id: "guido__test-button", "left-icon": "line-architect-test-journey", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isTestButtonDisabled, "label-text-status": !1, "tooltip-options": t.getTooltipOptions("guido__test-button"), "tooltip-text": t.trans("newsletter.test-email") } }), e(t.InButtonV2, { staticClass: "ml-3", attrs: { id: "guido__save-button", "label-text": "Save", "disabled-status": !t.isSaving && t.editorStore.isSaveButtonDisabled, "loading-status": t.isSaving }, on: { click: function(p) {
4
+ var o, i;
5
+ var s = this, e = s._self._c, t = s._self._setupProxy;
6
+ return e("div", { staticClass: "d-f" }, [(o = t.config.features) != null && o.versionHistory ? e(t.InButtonV2, { attrs: { id: "guido__history-button", "left-icon": "line-architect-version-history", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isVersionHistoryButtonDisabled, "label-text-status": !1, "selected-status": t.editorStore.isVersionHistoryOpen, "tooltip-options": t.getTooltipOptions("guido__history-button"), "tooltip-text": t.versionHistoryTooltipText }, on: { click: t.handleVersionHistory } }) : s._e(), e(t.InButtonV2, { attrs: { id: "guido__export-button", "left-icon": "line-export", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isExportButtonDisabled, "label-text-status": !1, "loading-status": t.isExporting, "tooltip-options": t.getTooltipOptions("guido__export-button"), "tooltip-text": t.trans("newsletter.export") }, on: { click: t.handleExport } }), (i = t.config.features) != null && i.saveAsTemplate ? e(t.InButtonV2, { attrs: { id: "guido__save-as-button", "left-icon": "line-newsletter-save-as-template", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isSaveAsButtonDisabled, "label-text-status": !1, "tooltip-options": t.getTooltipOptions("guido__save-as-button"), "tooltip-text": t.trans("newsletter.save-templates") }, on: { click: t.handleSaveAs } }) : s._e(), t.isUnsubscribePages() ? s._e() : e(t.InButtonV2, { attrs: { id: "guido__test-button", "left-icon": "line-architect-test-journey", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.isTestButtonDisabled, "label-text-status": !1, "tooltip-options": t.getTooltipOptions("guido__test-button"), "tooltip-text": t.trans("newsletter.test-email") } }), e(t.InButtonV2, { staticClass: "ml-3", attrs: { id: "guido__save-button", "label-text": "Save", "disabled-status": !t.isSaving && t.editorStore.isSaveButtonDisabled, "loading-status": t.isSaving }, on: { click: function(p) {
7
7
  return t.handleSave(!1);
8
8
  } } })], 1);
9
- }, r = [], d = /* @__PURE__ */ a(
9
+ }, r = [], u = /* @__PURE__ */ a(
10
10
  n,
11
11
  l,
12
12
  r,
@@ -14,7 +14,7 @@ var l = function() {
14
14
  null,
15
15
  null
16
16
  );
17
- const g = d.exports;
17
+ const g = u.exports;
18
18
  export {
19
19
  g as default
20
20
  };