@useinsider/guido 3.19.0-beta.3906ea8 → 3.19.0-beta.3abc7c5

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 (54) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +33 -31
  3. package/dist/components/Guido.vue.js +8 -8
  4. package/dist/components/Guido.vue2.js +50 -48
  5. package/dist/components/organisms/AutoSaveController.vue2.js +9 -8
  6. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  7. package/dist/components/organisms/header/EditorActions.vue2.js +85 -57
  8. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  9. package/dist/components/organisms/header/LeftSlot.vue2.js +16 -12
  10. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +20 -0
  11. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +48 -0
  12. package/dist/components/wrappers/WpDrawer.vue.js +9 -7
  13. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  14. package/dist/composables/useActionsApi.js +52 -47
  15. package/dist/composables/useCodeEditorApi.js +23 -9
  16. package/dist/composables/useHtmlCompiler.js +37 -26
  17. package/dist/composables/useHtmlValidator.js +2 -0
  18. package/dist/composables/useSave.js +90 -45
  19. package/dist/composables/useSaveValidation.js +279 -0
  20. package/dist/composables/useSaveValidationRollout.js +9 -0
  21. package/dist/composables/useTranslations.js +3 -2
  22. package/dist/composables/useVersionHistoryApi.js +33 -24
  23. package/dist/composables/validators/useCouponBlockValidator.js +24 -21
  24. package/dist/composables/validators/useUnsubscribeBlockValidator.js +34 -27
  25. package/dist/enums/save-validation.js +4 -0
  26. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +54 -47
  27. package/dist/guido.css +1 -1
  28. package/dist/src/@types/config/schemas.d.ts +4 -0
  29. package/dist/src/@types/save-validation.d.ts +19 -0
  30. package/dist/src/components/Guido.vue.d.ts +17 -1
  31. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +17 -1
  32. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +17 -1
  33. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +17 -1
  34. package/dist/src/components/organisms/validation/ValidationErrorDrawer.vue.d.ts +2 -0
  35. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +4 -3
  36. package/dist/src/composables/useConfig.d.ts +2 -0
  37. package/dist/src/composables/useHtmlValidator.d.ts +21 -0
  38. package/dist/src/composables/useSave.d.ts +6 -1
  39. package/dist/src/composables/useSaveValidation.d.ts +6 -0
  40. package/dist/src/composables/useSaveValidationRollout.d.ts +3 -0
  41. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  42. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +10 -0
  43. package/dist/src/enums/save-validation.d.ts +27 -0
  44. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +5 -0
  45. package/dist/src/stores/config.d.ts +32 -0
  46. package/dist/src/stores/save-validation.d.ts +22 -0
  47. package/dist/src/utils/stripoEditorApi.d.ts +4 -0
  48. package/dist/src/utils/templatePreparation.d.ts +30 -0
  49. package/dist/stores/config.js +84 -67
  50. package/dist/stores/save-validation.js +30 -0
  51. package/dist/stores/unsubscribe.js +3 -3
  52. package/dist/utils/stripoEditorApi.js +11 -0
  53. package/dist/utils/templatePreparation.js +39 -36
  54. package/package.json +3 -2
package/README.md CHANGED
@@ -164,6 +164,7 @@ const config: GuidoConfigInput = {
164
164
  liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
165
165
  autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
166
166
  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).
167
+ allowSaveWithErrors?: boolean, // Default: true - Allow the validation drawer's "Save and Continue" soft-save. Set false to hard-block invalid saves (transactional + unsubscribe pages).
167
168
  reusableRecommendationStrategy?: boolean, // Default: false - Assign an RRS strategy to recommendation blocks instead of per-block algorithm/filters/shuffle/product-count settings.
168
169
  },
169
170
 
@@ -1,5 +1,5 @@
1
1
  import { ModuleFolderDefaults as f } from "../../enums/defaults.js";
2
- import { object as o, number as n, optional as e, string as t, picklist as i, pipe as m, minLength as b, custom as h, boolean as a, array as c, transform as C, record as k, fallback as R, literal as u, looseObject as g, variant as I, union as y, unknown as r, lazy as T } from "../../node_modules/valibot/dist/index.js";
2
+ import { object as o, number as n, optional as e, string as t, picklist as i, pipe as m, minLength as b, custom as y, boolean as a, array as c, transform as C, record as k, fallback as R, literal as u, looseObject as g, variant as I, union as h, unknown as r, lazy as T } from "../../node_modules/valibot/dist/index.js";
3
3
  const p = {
4
4
  /** Promotional/marketing emails */
5
5
  PROMOTIONAL: 1,
@@ -38,7 +38,7 @@ const p = {
38
38
  name: t(),
39
39
  /** Fallback font family (e.g., "serif" or "sans-serif") */
40
40
  family: t()
41
- }), M = o({
41
+ }), E = o({
42
42
  /** Partner/organization name (required) */
43
43
  name: m(
44
44
  t(),
@@ -62,7 +62,7 @@ const p = {
62
62
  username: e(t(), "Guido User"),
63
63
  /** Fallback font settings from partner settings — used to match backend size calculation */
64
64
  fallbackFont: e(L)
65
- }), E = o({
65
+ }), M = o({
66
66
  /** Display text for the dynamic content */
67
67
  text: t(),
68
68
  /** Template variable value (e.g., {{username}}) */
@@ -84,14 +84,14 @@ const p = {
84
84
  children: e(c(S)),
85
85
  // eslint-disable-next-line camelcase -- backend field name
86
86
  select_items: e(c(S))
87
- })), N = k(
87
+ })), v = k(
88
88
  t(),
89
89
  R(c(S), [])
90
- ), P = g({
90
+ ), N = g({
91
91
  /** Block ID (matches the dictionary key and the legacy HTML element id) */
92
92
  id: e(n()),
93
93
  /** Decimal places for price display (legacy data may use string or number) */
94
- decimalCount: e(y([t(), n()])),
94
+ decimalCount: e(h([t(), n()])),
95
95
  /** Pinned product IDs (empty array when filter-driven) */
96
96
  productIds: e(c(r())),
97
97
  /** Whether the block requested live products at send time */
@@ -125,14 +125,14 @@ const p = {
125
125
  /** Block type marker used by some legacy variants */
126
126
  blockType: e(t()),
127
127
  /** Size variant marker (legacy data may use string or number) */
128
- size: e(y([t(), n()])),
128
+ size: e(h([t(), n()])),
129
129
  /** Vertical responsiveness flag (legacy size=1 variants) */
130
130
  verticalResponsiveness: e(a()),
131
131
  /** Legacy "Move to next line" price placement toggle (cardPricePlacement.js) */
132
132
  isPriceMovedToNextLine: e(a()),
133
133
  /** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
134
134
  isPriceDeletedForZeroSale: e(a())
135
- }), v = o({
135
+ }), P = o({
136
136
  /**
137
137
  * Legacy recommendation block configs keyed by block ID.
138
138
  * Pass this when loading a template authored with the v1
@@ -140,7 +140,7 @@ const p = {
140
140
  * strategy, currency, locale, and layout data.
141
141
  */
142
142
  recommendationConfigs: e(
143
- k(t(), P),
143
+ k(t(), N),
144
144
  {}
145
145
  )
146
146
  }), x = o({
@@ -150,7 +150,7 @@ const p = {
150
150
  css: e(t(), ""),
151
151
  /** Preselected dynamic content items */
152
152
  preselectedDynamicContent: e(
153
- c(E),
153
+ c(M),
154
154
  []
155
155
  ),
156
156
  /**
@@ -159,7 +159,7 @@ const p = {
159
159
  * (first) partner's leaf attributes into the label→token map that repairs
160
160
  * label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
161
161
  */
162
- dynamicContentList: e(N, {}),
162
+ dynamicContentList: e(v, {}),
163
163
  /** Valid custom field attribute names from the partner's categorized fields */
164
164
  customFieldAttributes: e(c(t()), []),
165
165
  /** Selected unsubscribe page IDs */
@@ -181,7 +181,7 @@ const p = {
181
181
  0
182
182
  ),
183
183
  /** Migration-only inputs (legacy block configs) */
184
- migration: e(v, {})
184
+ migration: e(P, {})
185
185
  }), D = o({
186
186
  /** Sender display name */
187
187
  senderName: e(t(), ""),
@@ -228,8 +228,10 @@ const p = {
228
228
  allowlistEnabled: e(a(), !1),
229
229
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
230
230
  linkTrackingIds: e(a(), !1),
231
+ /** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
232
+ allowSaveWithErrors: e(a(), !0),
231
233
  reusableRecommendationStrategy: e(a(), !1)
232
- }), B = i([
234
+ }), w = i([
233
235
  "amp-accordion",
234
236
  "amp-carousel",
235
237
  "amp-form-controls",
@@ -243,7 +245,7 @@ const p = {
243
245
  "text-block",
244
246
  "timer-block",
245
247
  "video-block"
246
- ]), w = i([
248
+ ]), B = i([
247
249
  "dynamic-content",
248
250
  "checkbox-block",
249
251
  "radio-button-block",
@@ -254,12 +256,12 @@ const p = {
254
256
  ]), H = o({
255
257
  /** Default blocks to exclude from the editor */
256
258
  excludeDefaults: e(
257
- c(B),
259
+ c(w),
258
260
  []
259
261
  ),
260
262
  /** Custom blocks to include in the editor */
261
263
  includeCustoms: e(
262
- c(w),
264
+ c(B),
263
265
  []
264
266
  )
265
267
  }), d = o({
@@ -296,7 +298,7 @@ const p = {
296
298
  ...d.entries,
297
299
  type: u("custom"),
298
300
  /** Custom processor function */
299
- processor: h(
301
+ processor: y(
300
302
  (s) => typeof s == "function",
301
303
  "processor must be a function"
302
304
  )
@@ -310,23 +312,23 @@ const p = {
310
312
  customRules: e(c(V), []),
311
313
  /** Skip default compiler rules */
312
314
  ignoreDefaultRules: e(a(), !1)
313
- }), Z = o({
315
+ }), W = o({
314
316
  /**
315
317
  * External validation handler called before save completes.
316
318
  * Return false to cancel the save operation.
317
319
  */
318
320
  externalValidation: e(
319
- h(
321
+ y(
320
322
  (s) => typeof s == "function",
321
323
  "externalValidation must be a function"
322
324
  )
323
325
  )
324
- }), Q = o({
326
+ }), K = o({
325
327
  // Required sections
326
328
  /** Identity configuration (required) */
327
329
  identity: A,
328
330
  /** Partner configuration (required) */
329
- partner: M,
331
+ partner: E,
330
332
  // Optional sections (with defaults)
331
333
  /** Template content and presets */
332
334
  template: e(x, {}),
@@ -341,33 +343,33 @@ const p = {
341
343
  /** Compiler configuration */
342
344
  compiler: e(z, {}),
343
345
  /** Callbacks and event handlers */
344
- callbacks: e(Z, {})
346
+ callbacks: e(W, {})
345
347
  });
346
348
  export {
347
349
  H as BlocksSchema,
348
- Z as CallbacksSchema,
350
+ W as CallbacksSchema,
349
351
  V as CompilerRuleSchema,
350
352
  z as CompilerSchema,
351
- w as CustomBlockTypeSchema,
353
+ B as CustomBlockTypeSchema,
352
354
  G as CustomRuleSchema,
353
- B as DefaultBlockTypeSchema,
354
- N as DynamicContentListSchema,
355
+ w as DefaultBlockTypeSchema,
356
+ v as DynamicContentListSchema,
355
357
  S as DynamicContentNodeSchema,
356
- E as DynamicContentSchema,
358
+ M as DynamicContentSchema,
357
359
  O as EditorSchema,
358
360
  D as EmailHeaderSchema,
359
361
  L as FallbackFontSchema,
360
362
  U as FeaturesSchema,
361
- Q as GuidoConfigSchema,
363
+ K as GuidoConfigSchema,
362
364
  A as IdentitySchema,
363
- P as LegacyRecommendationConfigSchema,
365
+ N as LegacyRecommendationConfigSchema,
364
366
  p as MessageType,
365
- M as PartnerSchema,
367
+ E as PartnerSchema,
366
368
  l as ProductType,
367
369
  j as RegexRuleSchema,
368
370
  q as RemoveRuleSchema,
369
371
  _ as ReplaceRuleSchema,
370
- v as TemplateMigrationSchema,
372
+ P as TemplateMigrationSchema,
371
373
  x as TemplateSchema,
372
374
  F as UISchema
373
375
  };
@@ -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(), e.isRrsEnabled ? r(e.LegacyStrategyUpdatedModal) : 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
- "36867e2e"
15
+ "74f39e54"
16
16
  );
17
- const g = n.exports;
17
+ const v = n.exports;
18
18
  export {
19
- g as default
19
+ v as default
20
20
  };
@@ -1,41 +1,43 @@
1
- import { defineComponent as re, defineAsyncComponent as m, ref as O, computed as u, watch as x, onMounted as se, onUnmounted as ae } from "vue";
2
- import { useCortexBlueprintBridge as ie } from "../composables/useCortexBlueprintBridge.js";
3
- import { useEditorLock as ce } from "../composables/useEditorLock.js";
4
- import { provideGuidoActions as de } from "../composables/useGuidoActions.js";
5
- import { useGuidoStateBridge as me } from "../composables/useGuidoStateBridge.js";
6
- import { usePartner as le } from "../composables/usePartner.js";
7
- import { useStripo as ue } from "../composables/useStripo.js";
8
- import { useTimerClone as pe } from "../composables/useTimerClone.js";
1
+ import { defineComponent as se, defineAsyncComponent as m, ref as O, computed as u, watch as x, onMounted as ae, onUnmounted as ie } from "vue";
2
+ import { useCortexBlueprintBridge as ce } from "../composables/useCortexBlueprintBridge.js";
3
+ import { useEditorLock as de } from "../composables/useEditorLock.js";
4
+ import { provideGuidoActions as me } from "../composables/useGuidoActions.js";
5
+ import { useGuidoStateBridge as le } from "../composables/useGuidoStateBridge.js";
6
+ import { usePartner as ue } from "../composables/usePartner.js";
7
+ import { useSaveValidationRollout as pe } from "../composables/useSaveValidationRollout.js";
8
+ import { useStripo as fe } from "../composables/useStripo.js";
9
+ import { useTimerClone as ye } from "../composables/useTimerClone.js";
9
10
  import { migrate as W } from "../config/migrator/index.js";
10
11
  import { ModuleFolderDefaults as G } from "../enums/defaults.js";
11
- import { RIBBON_SELECTOR as fe } from "../enums/onboarding.js";
12
+ import { RIBBON_SELECTOR as ge } from "../enums/onboarding.js";
12
13
  import { useRecommendationExtensionStore as h } from "../extensions/Blocks/Recommendation/store/recommendation.js";
13
- import ye from "./organisms/AutoSaveController.vue.js";
14
- import ge from "./organisms/base/Toaster.vue.js";
15
- import ve from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
16
- import Se from "./organisms/header/HeaderWrapper.vue.js";
17
- import be from "./organisms/LoadingWrapper.vue.js";
18
- import he from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
19
- import Ee from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
20
- import { useStripoApi as we } from "../services/stripoApi.js";
21
- import { useConfigStore as Ce } from "../stores/config.js";
22
- import { useDynamicContentStore as De } from "../stores/dynamic-content.js";
14
+ import ve from "./organisms/AutoSaveController.vue.js";
15
+ import Se from "./organisms/base/Toaster.vue.js";
16
+ import be from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
17
+ import he from "./organisms/header/HeaderWrapper.vue.js";
18
+ import Ee from "./organisms/LoadingWrapper.vue.js";
19
+ import we from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
20
+ import Ce from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
21
+ import De from "./organisms/validation/ValidationErrorDrawer.vue.js";
22
+ import { useStripoApi as ke } from "../services/stripoApi.js";
23
+ import { useConfigStore as Re } from "../stores/config.js";
24
+ import { useDynamicContentStore as Te } from "../stores/dynamic-content.js";
23
25
  import { useEditorStore as H } from "../stores/editor.js";
24
- import { usePreviewStore as ke } from "../stores/preview.js";
25
- import { useTemplateStore as Te } from "../stores/template.js";
26
- import { useUnsubscribeStore as Fe } from "../stores/unsubscribe.js";
27
- import { readTrackFloor as $ } from "../utils/linkTrackingIds.js";
28
- const tt = /* @__PURE__ */ re({
26
+ import { usePreviewStore as Fe } from "../stores/preview.js";
27
+ import { useTemplateStore as Me } from "../stores/template.js";
28
+ import { useUnsubscribeStore as Ie } from "../stores/unsubscribe.js";
29
+ import { readTrackFloor as V } from "../utils/linkTrackingIds.js";
30
+ const at = /* @__PURE__ */ se({
29
31
  __name: "Guido",
30
32
  props: {
31
33
  config: null,
32
34
  ready: { type: Boolean, default: !0 }
33
35
  },
34
36
  emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
35
- setup(z, { expose: q, emit: r }) {
36
- const a = z, K = m(
37
+ setup($, { expose: z, emit: r }) {
38
+ const a = $, q = m(
37
39
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
38
- ), V = m(
40
+ ), K = m(
39
41
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
40
42
  ), j = m(
41
43
  () => import("./organisms/extensions/recommendation/AssignStrategyDrawer.vue.js")
@@ -43,15 +45,15 @@ const tt = /* @__PURE__ */ re({
43
45
  () => import("./organisms/extensions/recommendation/RemoveStrategyModal.vue.js")
44
46
  ), Q = m(
45
47
  () => import("./organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js")
46
- ), E = O(), p = O(), f = De(), w = Fe(), o = Ce();
48
+ ), E = O(), p = O(), f = Te(), w = Ie(), o = Re();
47
49
  a.ready && o.init(a.config);
48
- const c = H(), X = ke(), l = u(() => c.hasChanges), { isTestPartner: Y } = le(), C = () => {
50
+ const c = H(), X = Fe(), l = u(() => c.hasChanges), { isTestPartner: Y } = ue(), { isEnabled: Z } = pe(), C = () => {
49
51
  var t;
50
52
  return (t = E.value) == null ? void 0 : t.handleSave(!0);
51
53
  }, D = (t) => {
52
54
  c.loadingStatus = t;
53
55
  };
54
- ie(), me();
56
+ ce(), le();
55
57
  const y = () => {
56
58
  var t, e;
57
59
  return {
@@ -62,15 +64,15 @@ const tt = /* @__PURE__ */ re({
62
64
  savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || G.SAVED_MODULES,
63
65
  defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || G.DEFAULT_MODULES
64
66
  };
65
- }, { initPlugin: k, preloadRuntime: T } = ue(), { runExclusive: F, beginMount: M, isCurrentMount: R } = ce();
67
+ }, { initPlugin: k, preloadRuntime: R } = fe(), { runExclusive: T, beginMount: F, isCurrentMount: M } = de();
66
68
  let g = 0;
67
- const { getDefaultTemplate: I } = we(), { cloneTimersOnSave: L, hasTimerBlocks: B } = pe(), Z = u(() => {
69
+ const { getDefaultTemplate: I } = ke(), { cloneTimersOnSave: L, hasTimerBlocks: B } = ye(), ee = u(() => {
68
70
  var t;
69
71
  return !((t = o.ui) != null && t.showHeader);
70
- }), ee = u(() => o.isFeatureEnabled("reusableRecommendationStrategy")), te = u(
72
+ }), te = u(() => o.isFeatureEnabled("reusableRecommendationStrategy")), oe = u(
71
73
  () => !!h().recommendationConfigs.strategyId
72
74
  );
73
- de({
75
+ me({
74
76
  onBack: () => {
75
77
  console.debug("guido:back"), r("back");
76
78
  },
@@ -100,7 +102,7 @@ const tt = /* @__PURE__ */ re({
100
102
  let i = null;
101
103
  const S = () => {
102
104
  var e;
103
- const t = document.querySelector(fe);
105
+ const t = document.querySelector(ge);
104
106
  (e = p.value) == null || e.style.setProperty("--ribbon-offset", `${(t == null ? void 0 : t.offsetHeight) ?? 0}px`);
105
107
  }, b = async () => {
106
108
  var t;
@@ -114,24 +116,24 @@ const tt = /* @__PURE__ */ re({
114
116
  css: d
115
117
  };
116
118
  n.html || (n = await I(), n.html = await W(n.html, _));
117
- const oe = N ? $(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
118
- B(n.html) && (n.html = await L(n.html)), N && (c.trackIdSessionFloor = Math.max(oe, $(n.html)));
119
- const ne = {
119
+ const ne = N ? V(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
120
+ B(n.html) && (n.html = await L(n.html)), N && (c.trackIdSessionFloor = Math.max(ne, V(n.html)));
121
+ const re = {
120
122
  preselectedDynamicContentList: P,
121
123
  onReady: () => {
122
124
  console.debug("guido:ready"), r("ready");
123
125
  }
124
126
  };
125
- g = M(), await k(n, y(), ne), f.selectedDynamicContentList = P;
127
+ g = F(), await k(n, y(), re), f.selectedDynamicContentList = P;
126
128
  } catch (e) {
127
129
  console.error("Failed to initialize Stripo editor:", e);
128
130
  }
129
131
  };
130
- return se(async () => {
132
+ return ae(async () => {
131
133
  var e;
132
- console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), h().$reset(), H().$reset(), Te().$reset(), S();
134
+ console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), h().$reset(), H().$reset(), Me().$reset(), S();
133
135
  const t = (e = p.value) == null ? void 0 : e.parentElement;
134
- if (t && (i = new ResizeObserver(S), i.observe(t)), T(), a.ready)
136
+ if (t && (i = new ResizeObserver(S), i.observe(t)), R(), a.ready)
135
137
  await b();
136
138
  else {
137
139
  const s = x(() => a.ready, (d) => {
@@ -139,16 +141,16 @@ const tt = /* @__PURE__ */ re({
139
141
  });
140
142
  }
141
143
  document.addEventListener("dynamic-content:open", v);
142
- }), ae(() => {
143
- i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", v), h().disposeStrategyPageReturn(), F(async () => {
144
- if (R(g))
144
+ }), ie(() => {
145
+ i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", v), h().disposeStrategyPageReturn(), T(async () => {
146
+ if (M(g))
145
147
  try {
146
148
  window.UIEditor.removeEditor();
147
149
  } catch {
148
150
  console.debug("Failed to remove Stripo editor: No editor found");
149
151
  }
150
152
  }), o.reset();
151
- }), q({
153
+ }), z({
152
154
  dynamicContent: {
153
155
  insert: U,
154
156
  close: A
@@ -156,9 +158,9 @@ const tt = /* @__PURE__ */ re({
156
158
  hasChanges: l,
157
159
  saveSilent: C,
158
160
  setLoading: D
159
- }), { __sfc: !0, PreviewContainer: K, OnboardingWrapper: V, AssignStrategyDrawer: j, RemoveStrategyModal: J, LegacyStrategyUpdatedModal: Q, headerWrapperRef: E, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: w, props: a, configStore: o, editorStore: c, previewStore: X, hasChanges: l, isTestPartner: Y, saveSilent: C, setLoading: D, emit: r, buildMetadata: y, initPlugin: k, preloadRuntime: T, runExclusive: F, beginMount: M, isCurrentMount: R, mountGeneration: g, getDefaultTemplate: I, cloneTimersOnSave: L, hasTimerBlocks: B, noHeader: Z, isRrsEnabled: ee, hasAssignedStrategy: te, insertDynamicContent: U, closeDynamicContent: A, handleDynamicContentOpen: v, ribbonObserver: i, updateRibbonOffset: S, startEditor: b, AutoSaveController: ye, Toaster: ge, FilterSelectionDrawer: ve, HeaderWrapper: Se, LoadingWrapper: be, SaveAsTemplateDrawer: he, UnsubscribeWrapper: Ee };
161
+ }), { __sfc: !0, PreviewContainer: q, OnboardingWrapper: K, AssignStrategyDrawer: j, RemoveStrategyModal: J, LegacyStrategyUpdatedModal: Q, headerWrapperRef: E, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: w, props: a, configStore: o, editorStore: c, previewStore: X, hasChanges: l, isTestPartner: Y, isSaveValidationEnabled: Z, saveSilent: C, setLoading: D, emit: r, buildMetadata: y, initPlugin: k, preloadRuntime: R, runExclusive: T, beginMount: F, isCurrentMount: M, mountGeneration: g, getDefaultTemplate: I, cloneTimersOnSave: L, hasTimerBlocks: B, noHeader: ee, isRrsEnabled: te, hasAssignedStrategy: oe, insertDynamicContent: U, closeDynamicContent: A, handleDynamicContentOpen: v, ribbonObserver: i, updateRibbonOffset: S, startEditor: b, AutoSaveController: ve, Toaster: Se, FilterSelectionDrawer: be, HeaderWrapper: he, LoadingWrapper: Ee, SaveAsTemplateDrawer: we, UnsubscribeWrapper: Ce, ValidationErrorDrawer: De };
160
162
  }
161
163
  });
162
164
  export {
163
- tt as default
165
+ at as default
164
166
  };
@@ -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
  };
@@ -4,7 +4,7 @@ import d from "../../../_virtual/_plugin-vue2_normalizer.js";
4
4
  var u = function() {
5
5
  var s, i, n, a;
6
6
  var o = this, e = o._self._c, t = o._self._setupProxy;
7
- return e("div", { staticClass: "d-f editor-actions" }, [t.isVersionHistoryButtonVisible ? 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 = (s = t.config) == null ? void 0 : s.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(), (a = (n = t.config) == null ? void 0 : n.features) != null && a.testMessage ? 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", { staticPosition: "bottom right" }), "tooltip-text": t.trans("newsletter.test-email") }, on: { click: t.handleTestEmail } }) : o._e(), t.editorStore.isPreviewModeOpen ? o._e() : 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(r) {
7
+ return e("div", { staticClass: "d-f editor-actions" }, [t.isVersionHistoryButtonVisible ? 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 = (s = t.config) == null ? void 0 : s.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(), (a = (n = t.config) == null ? void 0 : n.features) != null && a.testMessage ? 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", { staticPosition: "bottom right" }), "tooltip-text": t.trans("newsletter.test-email") }, on: { click: t.handleTestEmail } }) : o._e(), t.editorStore.isPreviewModeOpen ? o._e() : e(t.InButtonV2, { staticClass: "ml-3", attrs: { id: "guido__save-button", "disabled-status": !t.isSaving && t.editorStore.isSaveButtonDisabled, "label-text": t.saveLabel, "loading-status": t.isSaving }, on: { click: function(r) {
8
8
  return t.handleSave(!1);
9
9
  } } }), e(t.MigrationConfirmModal, { ref: "migrationModalRef", on: { confirm: function(r) {
10
10
  return t.executeSave(!1);
@@ -15,7 +15,7 @@ var u = function() {
15
15
  p,
16
16
  !1,
17
17
  null,
18
- "1ca6baf0"
18
+ "5e7f10cc"
19
19
  );
20
20
  const v = c.exports;
21
21
  export {