@useinsider/guido 3.18.0-beta.41e529d → 3.18.0-beta.6817b07

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 (66) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +29 -29
  3. package/dist/components/Guido.vue.js +8 -8
  4. package/dist/components/Guido.vue2.js +43 -43
  5. package/dist/components/organisms/AutoSaveController.vue2.js +9 -8
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +7 -7
  7. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +57 -82
  8. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  9. package/dist/components/organisms/header/EditorActions.vue2.js +74 -43
  10. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  11. package/dist/components/organisms/header/LeftSlot.vue2.js +16 -12
  12. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +20 -0
  13. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +48 -0
  14. package/dist/components/wrappers/WpDrawer.vue.js +9 -7
  15. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  16. package/dist/composables/useCustomInterfaceAppearance.js +42 -46
  17. package/dist/composables/useHtmlCompiler.js +37 -26
  18. package/dist/composables/useHtmlValidator.js +2 -0
  19. package/dist/composables/useSave.js +88 -43
  20. package/dist/composables/useSaveValidation.js +279 -0
  21. package/dist/composables/useSaveValidationRollout.js +9 -0
  22. package/dist/composables/validators/useCouponBlockValidator.js +24 -21
  23. package/dist/composables/validators/useUnsubscribeBlockValidator.js +34 -27
  24. package/dist/enums/extensions/recommendationBlock.js +1 -2
  25. package/dist/enums/save-validation.js +4 -0
  26. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +69 -70
  27. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +31 -66
  28. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +49 -83
  29. package/dist/guido.css +1 -1
  30. package/dist/services/recommendationApi.js +52 -61
  31. package/dist/src/@types/config/schemas.d.ts +4 -4
  32. package/dist/src/@types/save-validation.d.ts +19 -0
  33. package/dist/src/components/Guido.vue.d.ts +17 -1
  34. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +17 -1
  35. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +17 -1
  36. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +17 -1
  37. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +4 -3
  38. package/dist/src/composables/useConfig.d.ts +2 -2
  39. package/dist/src/composables/useHtmlValidator.d.ts +21 -0
  40. package/dist/src/composables/useSave.d.ts +6 -1
  41. package/dist/src/composables/useSaveValidation.d.ts +6 -0
  42. package/dist/src/composables/useSaveValidationRollout.d.ts +3 -0
  43. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  44. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +10 -0
  45. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -1
  46. package/dist/src/enums/save-validation.d.ts +27 -0
  47. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -1
  48. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +6 -54
  49. package/dist/src/services/recommendationApi.d.ts +1 -2
  50. package/dist/src/stores/config.d.ts +30 -160
  51. package/dist/src/stores/save-validation.d.ts +22 -0
  52. package/dist/src/utils/templatePreparation.d.ts +30 -0
  53. package/dist/static/styles/components/recommendation-strategy.css.js +5 -70
  54. package/dist/stores/config.js +77 -67
  55. package/dist/stores/save-validation.js +30 -0
  56. package/dist/utils/templatePreparation.js +28 -25
  57. package/package.json +1 -1
  58. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +0 -18
  59. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +0 -25
  60. package/dist/composables/useLegacyStrategyConversion.js +0 -52
  61. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +0 -58
  62. package/dist/src/composables/useLegacyStrategyConversion.d.ts +0 -3
  63. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +0 -39
  64. package/dist/static/assets/icons/filled-arrow-rising.svg.js +0 -5
  65. package/dist/static/assets/icons/line-info.svg.js +0 -5
  66. /package/dist/src/components/organisms/{extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts → validation/ValidationErrorDrawer.vue.d.ts} +0 -0
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
+ allowSaveWithErrors?: boolean, // Default: true - Allow the validation drawer's "Save and Continue" soft-save. Set false to hard-block invalid saves (transactional + unsubscribe pages).
165
166
  reusableRecommendationStrategy?: boolean, // Default: false - Assign an RRS strategy to recommendation blocks instead of per-block algorithm/filters/shuffle/product-count settings.
166
167
  },
167
168
 
@@ -24,15 +24,13 @@ const p = {
24
24
  b(1, "userId is required")
25
25
  ),
26
26
  /** Optional variation ID for A/B testing */
27
- variationId: e(t()),
28
- /** Optional numeric campaign ID of the host campaign; absent for templates and modules */
29
- campaignId: e(t())
27
+ variationId: e(t())
30
28
  }), L = a({
31
29
  /** Fallback font name (e.g., "Georgia") */
32
30
  name: t(),
33
31
  /** Fallback font family (e.g., "serif" or "sans-serif") */
34
32
  family: t()
35
- }), M = a({
33
+ }), E = a({
36
34
  /** Partner/organization name (required) */
37
35
  name: m(
38
36
  t(),
@@ -56,7 +54,7 @@ const p = {
56
54
  username: e(t(), "Guido User"),
57
55
  /** Fallback font settings from partner settings — used to match backend size calculation */
58
56
  fallbackFont: e(L)
59
- }), E = a({
57
+ }), M = a({
60
58
  /** Display text for the dynamic content */
61
59
  text: t(),
62
60
  /** Template variable value (e.g., {{username}}) */
@@ -78,10 +76,10 @@ const p = {
78
76
  children: e(c(S)),
79
77
  // eslint-disable-next-line camelcase -- backend field name
80
78
  select_items: e(c(S))
81
- })), N = k(
79
+ })), v = k(
82
80
  t(),
83
81
  R(c(S), [])
84
- ), P = g({
82
+ ), N = g({
85
83
  /** Block ID (matches the dictionary key and the legacy HTML element id) */
86
84
  id: e(n()),
87
85
  /** Decimal places for price display (legacy data may use string or number) */
@@ -126,7 +124,7 @@ const p = {
126
124
  isPriceMovedToNextLine: e(o()),
127
125
  /** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
128
126
  isPriceDeletedForZeroSale: e(o())
129
- }), v = a({
127
+ }), P = a({
130
128
  /**
131
129
  * Legacy recommendation block configs keyed by block ID.
132
130
  * Pass this when loading a template authored with the v1
@@ -134,7 +132,7 @@ const p = {
134
132
  * strategy, currency, locale, and layout data.
135
133
  */
136
134
  recommendationConfigs: e(
137
- k(t(), P),
135
+ k(t(), N),
138
136
  {}
139
137
  )
140
138
  }), x = a({
@@ -144,7 +142,7 @@ const p = {
144
142
  css: e(t(), ""),
145
143
  /** Preselected dynamic content items */
146
144
  preselectedDynamicContent: e(
147
- c(E),
145
+ c(M),
148
146
  []
149
147
  ),
150
148
  /**
@@ -153,7 +151,7 @@ const p = {
153
151
  * (first) partner's leaf attributes into the label→token map that repairs
154
152
  * label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
155
153
  */
156
- dynamicContentList: e(N, {}),
154
+ dynamicContentList: e(v, {}),
157
155
  /** Valid custom field attribute names from the partner's categorized fields */
158
156
  customFieldAttributes: e(c(t()), []),
159
157
  /** Selected unsubscribe page IDs */
@@ -175,7 +173,7 @@ const p = {
175
173
  0
176
174
  ),
177
175
  /** Migration-only inputs (legacy block configs) */
178
- migration: e(v, {})
176
+ migration: e(P, {})
179
177
  }), D = a({
180
178
  /** Sender display name */
181
179
  senderName: e(t(), ""),
@@ -222,8 +220,10 @@ const p = {
222
220
  allowlistEnabled: e(o(), !1),
223
221
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
224
222
  linkTrackingIds: e(o(), !1),
223
+ /** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
224
+ allowSaveWithErrors: e(o(), !0),
225
225
  reusableRecommendationStrategy: e(o(), !1)
226
- }), B = i([
226
+ }), w = i([
227
227
  "amp-accordion",
228
228
  "amp-carousel",
229
229
  "amp-form-controls",
@@ -237,7 +237,7 @@ const p = {
237
237
  "text-block",
238
238
  "timer-block",
239
239
  "video-block"
240
- ]), w = i([
240
+ ]), B = i([
241
241
  "dynamic-content",
242
242
  "checkbox-block",
243
243
  "radio-button-block",
@@ -248,12 +248,12 @@ const p = {
248
248
  ]), H = a({
249
249
  /** Default blocks to exclude from the editor */
250
250
  excludeDefaults: e(
251
- c(B),
251
+ c(w),
252
252
  []
253
253
  ),
254
254
  /** Custom blocks to include in the editor */
255
255
  includeCustoms: e(
256
- c(w),
256
+ c(B),
257
257
  []
258
258
  )
259
259
  }), d = a({
@@ -304,7 +304,7 @@ const p = {
304
304
  customRules: e(c(V), []),
305
305
  /** Skip default compiler rules */
306
306
  ignoreDefaultRules: e(o(), !1)
307
- }), Z = a({
307
+ }), W = a({
308
308
  /**
309
309
  * External validation handler called before save completes.
310
310
  * Return false to cancel the save operation.
@@ -315,12 +315,12 @@ const p = {
315
315
  "externalValidation must be a function"
316
316
  )
317
317
  )
318
- }), Q = a({
318
+ }), K = a({
319
319
  // Required sections
320
320
  /** Identity configuration (required) */
321
321
  identity: A,
322
322
  /** Partner configuration (required) */
323
- partner: M,
323
+ partner: E,
324
324
  // Optional sections (with defaults)
325
325
  /** Template content and presets */
326
326
  template: e(x, {}),
@@ -335,33 +335,33 @@ const p = {
335
335
  /** Compiler configuration */
336
336
  compiler: e(z, {}),
337
337
  /** Callbacks and event handlers */
338
- callbacks: e(Z, {})
338
+ callbacks: e(W, {})
339
339
  });
340
340
  export {
341
341
  H as BlocksSchema,
342
- Z as CallbacksSchema,
342
+ W as CallbacksSchema,
343
343
  V as CompilerRuleSchema,
344
344
  z as CompilerSchema,
345
- w as CustomBlockTypeSchema,
345
+ B as CustomBlockTypeSchema,
346
346
  G as CustomRuleSchema,
347
- B as DefaultBlockTypeSchema,
348
- N as DynamicContentListSchema,
347
+ w as DefaultBlockTypeSchema,
348
+ v as DynamicContentListSchema,
349
349
  S as DynamicContentNodeSchema,
350
- E as DynamicContentSchema,
350
+ M as DynamicContentSchema,
351
351
  O as EditorSchema,
352
352
  D as EmailHeaderSchema,
353
353
  L as FallbackFontSchema,
354
354
  U as FeaturesSchema,
355
- Q as GuidoConfigSchema,
355
+ K as GuidoConfigSchema,
356
356
  A as IdentitySchema,
357
- P as LegacyRecommendationConfigSchema,
357
+ N as LegacyRecommendationConfigSchema,
358
358
  p as MessageType,
359
- M as PartnerSchema,
359
+ E as PartnerSchema,
360
360
  l as ProductType,
361
361
  j as RegexRuleSchema,
362
362
  q as RemoveRuleSchema,
363
363
  _ as ReplaceRuleSchema,
364
- v as TemplateMigrationSchema,
364
+ P as TemplateMigrationSchema,
365
365
  x as TemplateSchema,
366
366
  F as UISchema
367
367
  };
@@ -1,20 +1,20 @@
1
- import o from "./Guido.vue2.js";
1
+ import i from "./Guido.vue2.js";
2
2
  /* empty css */
3
- import i from "../_virtual/_plugin-vue2_normalizer.js";
3
+ import o from "../_virtual/_plugin-vue2_normalizer.js";
4
4
  var t = function() {
5
5
  var a = this, r = a._self._c, e = a._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) : a._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.isRrsEnabled || e.hasAssignedStrategy ? r(e.AssignStrategyDrawer) : a._e(), e.isRrsEnabled || e.hasAssignedStrategy ? r(e.RemoveStrategyModal) : a._e(), e.isRrsEnabled ? r(e.LegacyStrategyUpdatedModal) : a._e(), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? a._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(_) {
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) : a._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.isRrsEnabled || e.hasAssignedStrategy ? r(e.AssignStrategyDrawer) : a._e(), e.isRrsEnabled || e.hasAssignedStrategy ? r(e.RemoveStrategyModal) : a._e(), r(e.SaveAsTemplateDrawer), e.isSaveValidationEnabled ? r(e.ValidationErrorDrawer) : a._e(), e.isTestPartner() ? a._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(_) {
7
7
  return e.emit("onboarding:finished");
8
8
  } } }), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
9
- }, s = [], n = /* @__PURE__ */ i(
10
- o,
9
+ }, s = [], n = /* @__PURE__ */ o(
10
+ i,
11
11
  t,
12
12
  s,
13
13
  !1,
14
14
  null,
15
- "d1f80922"
15
+ "2db79b8f"
16
16
  );
17
- const f = n.exports;
17
+ const c = n.exports;
18
18
  export {
19
- f as default
19
+ c as default
20
20
  };
@@ -1,30 +1,32 @@
1
- import { defineComponent as ee, defineAsyncComponent as m, ref as U, computed as u, watch as A, onMounted as te, onUnmounted as oe } from "vue";
1
+ import { defineComponent as ee, defineAsyncComponent as l, ref as A, computed as u, watch as U, onMounted as te, onUnmounted as oe } from "vue";
2
2
  import { useCortexBlueprintBridge as ne } from "../composables/useCortexBlueprintBridge.js";
3
3
  import { provideGuidoActions as re } from "../composables/useGuidoActions.js";
4
4
  import { useGuidoStateBridge as se } from "../composables/useGuidoStateBridge.js";
5
5
  import { usePartner as ae } from "../composables/usePartner.js";
6
- import { useStripo as ie } from "../composables/useStripo.js";
7
- import { useTimerClone as ce } from "../composables/useTimerClone.js";
6
+ import { useSaveValidationRollout as ie } from "../composables/useSaveValidationRollout.js";
7
+ import { useStripo as ce } from "../composables/useStripo.js";
8
+ import { useTimerClone as de } from "../composables/useTimerClone.js";
8
9
  import { migrate as _ } from "../config/migrator/index.js";
9
10
  import { ModuleFolderDefaults as N } from "../enums/defaults.js";
10
- import { RIBBON_SELECTOR as de } from "../enums/onboarding.js";
11
+ import { RIBBON_SELECTOR as me } from "../enums/onboarding.js";
11
12
  import { useRecommendationExtensionStore as O } from "../extensions/Blocks/Recommendation/store/recommendation.js";
12
- import me from "./organisms/AutoSaveController.vue.js";
13
- import le from "./organisms/base/Toaster.vue.js";
14
- import ue from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
15
- import pe from "./organisms/header/HeaderWrapper.vue.js";
16
- import fe from "./organisms/LoadingWrapper.vue.js";
17
- import ye from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
18
- import ge from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
19
- import { useStripoApi as ve } from "../services/stripoApi.js";
20
- import { useConfigStore as Se } from "../stores/config.js";
21
- import { useDynamicContentStore as he } from "../stores/dynamic-content.js";
13
+ import le from "./organisms/AutoSaveController.vue.js";
14
+ import ue from "./organisms/base/Toaster.vue.js";
15
+ import pe from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
16
+ import fe from "./organisms/header/HeaderWrapper.vue.js";
17
+ import ye from "./organisms/LoadingWrapper.vue.js";
18
+ import ge from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
19
+ import ve from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
20
+ import Se from "./organisms/validation/ValidationErrorDrawer.vue.js";
21
+ import { useStripoApi as be } from "../services/stripoApi.js";
22
+ import { useConfigStore as he } from "../stores/config.js";
23
+ import { useDynamicContentStore as Ee } from "../stores/dynamic-content.js";
22
24
  import { useEditorStore as P } from "../stores/editor.js";
23
- import { usePreviewStore as be } from "../stores/preview.js";
24
- import { useTemplateStore as Ee } from "../stores/template.js";
25
- import { useUnsubscribeStore as we } from "../stores/unsubscribe.js";
25
+ import { usePreviewStore as we } from "../stores/preview.js";
26
+ import { useTemplateStore as De } from "../stores/template.js";
27
+ import { useUnsubscribeStore as Ce } from "../stores/unsubscribe.js";
26
28
  import { readTrackFloor as W } from "../utils/linkTrackingIds.js";
27
- const Je = /* @__PURE__ */ ee({
29
+ const Ze = /* @__PURE__ */ ee({
28
30
  __name: "Guido",
29
31
  props: {
30
32
  config: null,
@@ -32,21 +34,19 @@ const Je = /* @__PURE__ */ ee({
32
34
  },
33
35
  emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
34
36
  setup(x, { expose: G, emit: r }) {
35
- const a = x, H = m(
37
+ const a = x, H = l(
36
38
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
37
- ), $ = m(
39
+ ), V = l(
38
40
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
39
- ), z = m(
41
+ ), $ = l(
40
42
  () => import("./organisms/extensions/recommendation/AssignStrategyDrawer.vue.js")
41
- ), q = m(
43
+ ), z = l(
42
44
  () => import("./organisms/extensions/recommendation/RemoveStrategyModal.vue.js")
43
- ), K = m(
44
- () => import("./organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js")
45
- ), h = U(), p = U(), f = he(), b = we(), o = Se();
45
+ ), b = A(), p = A(), f = Ee(), h = Ce(), o = he();
46
46
  a.ready && o.init(a.config);
47
- const c = P(), V = be(), l = u(() => c.hasChanges), { isTestPartner: j } = ae(), E = () => {
47
+ const c = P(), q = we(), m = u(() => c.hasChanges), { isTestPartner: K } = ae(), { isEnabled: j } = ie(), E = () => {
48
48
  var t;
49
- return (t = h.value) == null ? void 0 : t.handleSave(!0);
49
+ return (t = b.value) == null ? void 0 : t.handleSave(!0);
50
50
  }, w = (t) => {
51
51
  c.loadingStatus = t;
52
52
  };
@@ -61,7 +61,7 @@ const Je = /* @__PURE__ */ ee({
61
61
  savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || N.SAVED_MODULES,
62
62
  defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || N.DEFAULT_MODULES
63
63
  };
64
- }, { initPlugin: C, preloadRuntime: D } = ie(), { getDefaultTemplate: k } = ve(), { cloneTimersOnSave: T, hasTimerBlocks: F } = ce(), J = u(() => {
64
+ }, { initPlugin: D, preloadRuntime: C } = ce(), { getDefaultTemplate: k } = be(), { cloneTimersOnSave: T, hasTimerBlocks: F } = de(), J = u(() => {
65
65
  var t;
66
66
  return !((t = o.ui) != null && t.showHeader);
67
67
  }), Q = u(() => o.isFeatureEnabled("reusableRecommendationStrategy")), X = u(
@@ -82,13 +82,13 @@ const Je = /* @__PURE__ */ ee({
82
82
  console.debug("guido:test-email:click"), r("test-email:click");
83
83
  }
84
84
  });
85
- const I = (t) => {
85
+ const R = (t) => {
86
86
  console.debug("dynamic-content:close", t), f.setSelectedDynamicContent(t), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: t }));
87
- }, R = () => {
87
+ }, I = () => {
88
88
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
89
89
  };
90
- A(() => l.value, () => {
91
- r("on-change", l.value);
90
+ U(() => m.value, () => {
91
+ r("on-change", m.value);
92
92
  });
93
93
  const g = (t) => {
94
94
  const e = t, { attribute: s, position: d } = e.detail;
@@ -97,14 +97,14 @@ const Je = /* @__PURE__ */ ee({
97
97
  let i = null;
98
98
  const v = () => {
99
99
  var e;
100
- const t = document.querySelector(de);
100
+ const t = document.querySelector(me);
101
101
  (e = p.value) == null || e.style.setProperty("--ribbon-offset", `${(t == null ? void 0 : t.offsetHeight) ?? 0}px`);
102
102
  }, S = async () => {
103
103
  var t;
104
104
  try {
105
105
  o.initialized || o.init(a.config), c.templateId = o.templateId;
106
106
  const e = o.template, s = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", L = (e == null ? void 0 : e.preselectedDynamicContent) || [];
107
- b.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
107
+ h.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
108
108
  const M = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, B = o.isFeatureEnabled("linkTrackingIds");
109
109
  let n = {
110
110
  html: s && await _(s, M),
@@ -119,19 +119,19 @@ const Je = /* @__PURE__ */ ee({
119
119
  console.debug("guido:ready"), r("ready");
120
120
  }
121
121
  };
122
- await C(n, y(), Z), f.selectedDynamicContentList = L;
122
+ await D(n, y(), Z), f.selectedDynamicContentList = L;
123
123
  } catch (e) {
124
124
  console.error("Failed to initialize Stripo editor:", e);
125
125
  }
126
126
  };
127
127
  return te(async () => {
128
128
  var e;
129
- console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), O().$reset(), P().$reset(), Ee().$reset(), v();
129
+ console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), O().$reset(), P().$reset(), De().$reset(), v();
130
130
  const t = (e = p.value) == null ? void 0 : e.parentElement;
131
- if (t && (i = new ResizeObserver(v), i.observe(t)), D(), a.ready)
131
+ if (t && (i = new ResizeObserver(v), i.observe(t)), C(), a.ready)
132
132
  await S();
133
133
  else {
134
- const s = A(() => a.ready, (d) => {
134
+ const s = U(() => a.ready, (d) => {
135
135
  d && (s(), S());
136
136
  });
137
137
  }
@@ -146,15 +146,15 @@ const Je = /* @__PURE__ */ ee({
146
146
  o.reset();
147
147
  }), G({
148
148
  dynamicContent: {
149
- insert: I,
150
- close: R
149
+ insert: R,
150
+ close: I
151
151
  },
152
- hasChanges: l,
152
+ hasChanges: m,
153
153
  saveSilent: E,
154
154
  setLoading: w
155
- }), { __sfc: !0, PreviewContainer: H, OnboardingWrapper: $, AssignStrategyDrawer: z, RemoveStrategyModal: q, LegacyStrategyUpdatedModal: K, headerWrapperRef: h, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: b, props: a, configStore: o, editorStore: c, previewStore: V, hasChanges: l, isTestPartner: j, saveSilent: E, setLoading: w, emit: r, buildMetadata: y, initPlugin: C, preloadRuntime: D, getDefaultTemplate: k, cloneTimersOnSave: T, hasTimerBlocks: F, noHeader: J, isRrsEnabled: Q, hasAssignedStrategy: X, insertDynamicContent: I, closeDynamicContent: R, handleDynamicContentOpen: g, ribbonObserver: i, updateRibbonOffset: v, startEditor: S, AutoSaveController: me, Toaster: le, FilterSelectionDrawer: ue, HeaderWrapper: pe, LoadingWrapper: fe, SaveAsTemplateDrawer: ye, UnsubscribeWrapper: ge };
155
+ }), { __sfc: !0, PreviewContainer: H, OnboardingWrapper: V, AssignStrategyDrawer: $, RemoveStrategyModal: z, headerWrapperRef: b, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: h, props: a, configStore: o, editorStore: c, previewStore: q, hasChanges: m, isTestPartner: K, isSaveValidationEnabled: j, saveSilent: E, setLoading: w, emit: r, buildMetadata: y, initPlugin: D, preloadRuntime: C, getDefaultTemplate: k, cloneTimersOnSave: T, hasTimerBlocks: F, noHeader: J, isRrsEnabled: Q, hasAssignedStrategy: X, insertDynamicContent: R, closeDynamicContent: I, handleDynamicContentOpen: g, ribbonObserver: i, updateRibbonOffset: v, startEditor: S, AutoSaveController: le, Toaster: ue, FilterSelectionDrawer: pe, HeaderWrapper: fe, LoadingWrapper: ye, SaveAsTemplateDrawer: ge, UnsubscribeWrapper: ve, ValidationErrorDrawer: Se };
156
156
  }
157
157
  });
158
158
  export {
159
- Je as default
159
+ Ze as default
160
160
  };
@@ -1,13 +1,14 @@
1
- import { defineComponent as t } from "vue";
2
- import { useAutoSave as r } from "../../composables/useAutoSave.js";
3
- import { useSave as s } from "../../composables/useSave.js";
4
- const f = /* @__PURE__ */ t({
1
+ import { defineComponent as r } from "vue";
2
+ import { useAutoSave as s } from "../../composables/useAutoSave.js";
3
+ import { useSave as n } from "../../composables/useSave.js";
4
+ import { useSaveValidationRollout as u } from "../../composables/useSaveValidationRollout.js";
5
+ const v = /* @__PURE__ */ r({
5
6
  __name: "AutoSaveController",
6
- setup(a) {
7
- const { save: e } = s(), o = () => e(!1, !0);
8
- return r(o), { __sfc: !0, save: e, backgroundSave: o };
7
+ setup(m) {
8
+ const { save: e, saveRawOnly: o } = n(), { isEnabled: t } = u(), a = () => t.value ? o() : e(!1, !0);
9
+ return s(a), { __sfc: !0, save: e, saveRawOnly: o, isEnabled: t, backgroundSave: a };
9
10
  }
10
11
  });
11
12
  export {
12
- f as default
13
+ v as default
13
14
  };
@@ -1,19 +1,19 @@
1
1
  import r from "./AssignStrategyDrawer.vue2.js";
2
2
  /* empty css */
3
3
  /* empty css */
4
- import o from "../../../../_virtual/_plugin-vue2_normalizer.js";
5
- var a = function() {
4
+ import a from "../../../../_virtual/_plugin-vue2_normalizer.js";
5
+ var o = function() {
6
6
  var e = this, s = e._self._c, t = e._self._setupProxy;
7
7
  return t.store.assignStrategyDrawerStatus ? s(t.OrgStrategyDetailModal, { staticClass: "assign-strategy-drawer", attrs: { "description-status": "", show: "", "description-text": t.drawerDescription, "footer-button-group-options": t.footerButtonGroupOptions, strategy: t.selectedStrategy ?? {}, "title-text": t.trans("gpt-app-builder.assign-recommendation-strategy") }, on: { close: t.closeDrawer, primaryClick: t.assignStrategy }, scopedSlots: e._u([{ key: "contentTop", fn: function() {
8
- return [s("div", { staticClass: "assign-strategy-drawer-content px-5 py-5" }, [s(t.OrgStrategyDropdown, { staticClass: "assign-strategy-select", attrs: { id: "assign-strategy-select", "info-box-position": "bottom right", "create-button-visible": !1, loading: t.store.strategiesLoading || t.store.legacyConversionLoading, "placeholder-text": t.trans("smart-recommender.select-recommendation-strategy"), "selected-strategy-id": t.selectedStrategyId, state: t.showSelectionError ? "error" : "default", "state-message": t.showSelectionError ? t.trans("ds-steps.select-strategy-tooltip") : "", strategies: t.strategyOptions }, on: { infoBoxButtonClick: t.onInfoBoxButtonClick, select: t.onSelect } })], 1)];
9
- }, proxy: !0 }], null, !1, 239334473) }) : e._e();
10
- }, n = [], i = /* @__PURE__ */ o(
8
+ return [s("div", { staticClass: "assign-strategy-drawer-content px-5 py-5" }, [s(t.OrgStrategyDropdown, { staticClass: "assign-strategy-select", attrs: { id: "assign-strategy-select", "info-box-position": "bottom right", "create-button-visible": !1, loading: t.store.strategiesLoading, "placeholder-text": t.trans("smart-recommender.select-recommendation-strategy"), "selected-strategy-id": t.selectedStrategyId, state: t.showSelectionError ? "error" : "default", "state-message": t.showSelectionError ? t.trans("ds-steps.select-strategy-tooltip") : "", strategies: t.strategyOptions }, on: { select: t.onSelect } })], 1)];
9
+ }, proxy: !0 }], null, !1, 2542767044) }) : e._e();
10
+ }, n = [], i = /* @__PURE__ */ a(
11
11
  r,
12
- a,
12
+ o,
13
13
  n,
14
14
  !1,
15
15
  null,
16
- "4019dc4d"
16
+ "2580a7d9"
17
17
  );
18
18
  const y = i.exports;
19
19
  export {
@@ -1,73 +1,48 @@
1
- import { defineComponent as h, defineAsyncComponent as T, ref as _, computed as s, watch as B } from "vue";
1
+ import { defineComponent as v, defineAsyncComponent as y, ref as u, computed as l, watch as O } from "vue";
2
2
  import "@useinsider/design-system-organisms/style";
3
- import { useLegacyStrategyConversion as I } from "../../../../composables/useLegacyStrategyConversion.js";
4
- import { useToaster as N } from "../../../../composables/useToaster.js";
5
- import { useTranslations as k } from "../../../../composables/useTranslations.js";
6
- import { DOTTED_DATE_LOCALE as P } from "../../../../enums/date.js";
7
- import { URLS as U } from "../../../../enums/extensions/recommendationBlock.js";
8
- import { ToasterTypeOptions as p } from "../../../../enums/toaster.js";
9
- import { useRecommendationExtensionStore as b } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
10
- import G from "./StrategyInfoBoxContent.vue.js";
11
- import { formatShortDate as M } from "../../../../utils/dateUtil.js";
12
- import { asText as D } from "../../../../utils/genericUtil.js";
13
- import { escapeHtml as x } from "../../../../utils/htmlEscape.js";
14
- import { InSkeleton as R } from "@useinsider/design-system-vue";
15
- const st = /* @__PURE__ */ h({
3
+ import { useToaster as x } from "../../../../composables/useToaster.js";
4
+ import { useTranslations as A } from "../../../../composables/useTranslations.js";
5
+ import { DOTTED_DATE_LOCALE as E } from "../../../../enums/date.js";
6
+ import { URLS as h } from "../../../../enums/extensions/recommendationBlock.js";
7
+ import { ToasterTypeOptions as m } from "../../../../enums/toaster.js";
8
+ import { useRecommendationExtensionStore as C } from "../../../../extensions/Blocks/Recommendation/store/recommendation.js";
9
+ import B from "./StrategyInfoBoxContent.vue.js";
10
+ import { formatShortDate as I } from "../../../../utils/dateUtil.js";
11
+ import { asText as f } from "../../../../utils/genericUtil.js";
12
+ import { escapeHtml as N } from "../../../../utils/htmlEscape.js";
13
+ import { InSkeleton as b } from "@useinsider/design-system-vue";
14
+ const W = /* @__PURE__ */ v({
16
15
  __name: "AssignStrategyDrawer",
17
- setup(H) {
18
- const l = () => import("@useinsider/design-system-organisms"), g = (t, a) => ({
19
- render: (n) => n(R, { props: { sizing: { width: t, height: a } } })
20
- }), O = T({
21
- loader: async () => (await l()).OrgStrategyDetailModal,
16
+ setup(k) {
17
+ const c = () => import("@useinsider/design-system-organisms"), g = (t, r) => ({
18
+ render: (a) => a(b, { props: { sizing: { width: t, height: r } } })
19
+ }), S = y({
20
+ loader: async () => (await c()).OrgStrategyDetailModal,
22
21
  loadingComponent: g(480, 240),
23
22
  delay: 0
24
- }), w = T({
25
- loader: async () => (await l()).OrgStrategyDropdown,
23
+ }), T = y({
24
+ loader: async () => (await c()).OrgStrategyDropdown,
26
25
  loadingComponent: g(240, 42),
27
26
  delay: 0
28
- }), r = k(), e = b(), { showToaster: i } = N(), { convertLegacyStrategy: u } = I(), o = _(null), y = "legacy", d = "guido__btn-update-legacy-strategy", c = _(!1), A = s(() => e.assignStrategyDrawerStatus ? r("email-editor.assign-strategy-description", { url: U.RECOMMENDATION_STRATEGIES_PANEL_PATH }) : "");
29
- B(() => e.assignStrategyDrawerStatus, (t) => {
27
+ }), o = A(), e = C(), { showToaster: s } = x(), n = u(null), i = u(!1), _ = l(() => e.assignStrategyDrawerStatus ? o("email-editor.assign-strategy-description", { url: h.RECOMMENDATION_STRATEGIES_PANEL_PATH }) : "");
28
+ O(() => e.assignStrategyDrawerStatus, (t) => {
30
29
  if (!t)
31
30
  return;
32
- const { strategyId: a } = e.recommendationConfigs;
33
- o.value = a || (e.isLegacyStrategyBlock ? y : null), c.value = !1, e.fetchStrategies().catch(() => {
34
- i({
35
- type: p.Error,
36
- message: r("discovery-strategy.error-description")
31
+ const { strategyId: r } = e.recommendationConfigs;
32
+ n.value = r || null, i.value = !1, e.fetchStrategies().catch(() => {
33
+ s({
34
+ type: m.Error,
35
+ message: o("discovery-strategy.error-description")
37
36
  });
38
37
  });
39
38
  });
40
- const f = (t) => {
41
- const a = D(t.updated_at || t.created_at);
42
- if (!a)
39
+ const p = (t) => {
40
+ const r = f(t.updated_at || t.created_at);
41
+ if (!r)
43
42
  return "";
44
- const n = M(a, P);
45
- return r("recommendation-strategy.last-updated-on", { value: n });
46
- }, S = s(() => ({
47
- text: r("ds-steps.legacy-strategy"),
48
- value: y,
49
- infoBoxProps: {
50
- id: "strategy-info-legacy",
51
- theme: "light",
52
- variant: "information",
53
- className: "assign-strategy-info-box",
54
- titleText: x(r("ds-steps.legacy-strategy")),
55
- descriptionStatus: !0,
56
- descriptionText: r("statistics.legacy-strategy-description"),
57
- buttonOptions: [{
58
- id: d,
59
- type: "primary",
60
- text: r("ds-steps.update"),
61
- loadingStatus: e.legacyConversionLoading,
62
- disabledStatus: e.legacyConversionLoading
63
- }]
64
- }
65
- })), E = async (t) => {
66
- if ((t == null ? void 0 : t.id) !== d)
67
- return;
68
- const a = await u();
69
- a && (o.value = a);
70
- }, m = s(() => e.strategies.map((t) => ({
43
+ const a = I(r, E);
44
+ return o("recommendation-strategy.last-updated-on", { value: a });
45
+ }, D = l(() => e.strategies.map((t) => ({
71
46
  text: t.name,
72
47
  value: t.strategy_id,
73
48
  infoBoxProps: {
@@ -75,57 +50,57 @@ const st = /* @__PURE__ */ h({
75
50
  theme: "light",
76
51
  variant: "information",
77
52
  className: "assign-strategy-info-box",
78
- titleText: x(D(t.name)),
53
+ titleText: N(f(t.name)),
79
54
  descriptionStatus: !0,
80
- descriptionText: f(t),
81
- slot: G,
55
+ descriptionText: p(t),
56
+ slot: B,
82
57
  slotProps: { strategy: t }
83
58
  }
84
- }))), C = s(() => e.isLegacyStrategyBlock ? [S.value, ...m.value] : m.value), v = s(() => {
85
- const t = e.strategies.find((a) => String(a.strategy_id) === String(o.value ?? ""));
59
+ }))), d = l(() => {
60
+ const t = e.strategies.find((r) => String(r.strategy_id) === String(n.value ?? ""));
86
61
  return t ? { ...t, fallback_config: null } : null;
87
- }), L = s(() => ({
62
+ }), w = l(() => ({
88
63
  primaryButton: {
89
64
  styling: "solid",
90
65
  type: "primary",
91
- labelText: r("products.assign-btn")
66
+ labelText: o("products.assign-btn")
92
67
  },
93
68
  cancelOrBackButton: {
94
69
  styling: "ghost",
95
70
  type: "secondary",
96
- labelText: r("products.cancel")
71
+ labelText: o("products.cancel")
97
72
  }
98
73
  }));
99
- return { __sfc: !0, loadOrganisms: l, skeleton: g, OrgStrategyDetailModal: O, OrgStrategyDropdown: w, trans: r, store: e, showToaster: i, convertLegacyStrategy: u, selectedStrategyId: o, LEGACY_OPTION_VALUE: y, LEGACY_UPDATE_BUTTON_ID: d, showSelectionError: c, drawerDescription: A, lastUpdatedText: f, legacyStrategyOption: S, onInfoBoxButtonClick: E, remoteStrategyOptions: m, strategyOptions: C, selectedStrategy: v, footerButtonGroupOptions: L, closeDrawer: () => {
74
+ return { __sfc: !0, loadOrganisms: c, skeleton: g, OrgStrategyDetailModal: S, OrgStrategyDropdown: T, trans: o, store: e, showToaster: s, selectedStrategyId: n, showSelectionError: i, drawerDescription: _, lastUpdatedText: p, strategyOptions: D, selectedStrategy: d, footerButtonGroupOptions: w, closeDrawer: () => {
100
75
  e.closeAssignStrategyDrawer();
101
76
  }, assignStrategy: async () => {
102
- const t = v.value;
77
+ const t = d.value;
103
78
  if (!t) {
104
- c.value = !0;
79
+ i.value = !0;
105
80
  return;
106
81
  }
107
- let a = "";
82
+ let r = "";
108
83
  try {
109
- a = await e.resolveStrategyUrlTemplate(t, e.recommendationConfigs.currencySettings.value);
110
- } catch (n) {
111
- console.error("[AssignStrategyDrawer] resolveStrategyUrlTemplate failed", n);
84
+ r = await e.resolveStrategyUrlTemplate(t, e.recommendationConfigs.currencySettings.value);
85
+ } catch (a) {
86
+ console.error("[AssignStrategyDrawer] resolveStrategyUrlTemplate failed", a);
112
87
  }
113
- if (!a) {
114
- i({
115
- type: p.Error,
116
- message: r("email-editor.strategy-assign-failed", { strategyName: t.name })
88
+ if (!r) {
89
+ s({
90
+ type: m.Error,
91
+ message: o("email-editor.strategy-assign-failed", { strategyName: t.name })
117
92
  });
118
93
  return;
119
94
  }
120
- e.assignStrategy(t), i({
121
- type: p.Success,
122
- message: r("email-editor.strategy-assigned-success", { strategyName: t.name })
95
+ e.assignStrategy(t), s({
96
+ type: m.Success,
97
+ message: o("email-editor.strategy-assigned-success", { strategyName: t.name })
123
98
  }), e.closeAssignStrategyDrawer();
124
99
  }, onSelect: (t) => {
125
- o.value = t.value, c.value = !1;
100
+ n.value = t.value, i.value = !1;
126
101
  } };
127
102
  }
128
103
  });
129
104
  export {
130
- st as default
105
+ W as default
131
106
  };