@useinsider/guido 3.22.0-beta.9277778 → 3.22.0-beta.ce512a7
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.
- package/README.md +1 -9
- package/dist/@types/config/schemas.js +31 -32
- package/dist/components/Guido.vue.js +5 -5
- package/dist/components/Guido.vue2.js +92 -85
- package/dist/components/organisms/AutoSaveController.vue2.js +20 -10
- package/dist/components/organisms/header/AutoSaveStatus.vue.js +17 -0
- package/dist/components/organisms/header/AutoSaveStatus.vue2.js +25 -0
- package/dist/components/organisms/header/EditorActions.vue.js +13 -13
- package/dist/components/organisms/header/EditorActions.vue2.js +58 -73
- package/dist/components/organisms/header/EditorActionsMenu.vue.js +20 -0
- package/dist/components/organisms/header/EditorActionsMenu.vue2.js +99 -0
- package/dist/components/organisms/header/HeaderWrapper.vue.js +6 -6
- package/dist/components/organisms/header/HeaderWrapper.vue2.js +9 -17
- package/dist/components/organisms/header/LeftSlot.vue.js +1 -1
- package/dist/components/organisms/header/LeftSlot.vue2.js +28 -23
- package/dist/components/organisms/header/MiddleSlot.vue.js +4 -4
- package/dist/components/organisms/header/MiddleSlot.vue2.js +8 -7
- package/dist/components/organisms/header/RightSlot.vue.js +11 -10
- package/dist/components/organisms/header/RightSlot.vue2.js +13 -18
- package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue.js +18 -0
- package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue2.js +37 -0
- package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue.js +22 -0
- package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue2.js +48 -0
- package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue.js +19 -0
- package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue2.js +90 -0
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue.js +12 -12
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +60 -35
- package/dist/composables/useAccessibilityApi.js +51 -0
- package/dist/composables/useCustomInterfaceAppearance.js +42 -41
- package/dist/composables/useModuleRepair.js +23 -32
- package/dist/config/i18n/en/labels.json.js +36 -4
- package/dist/config/i18n/en/tooltips.json.js +2 -1
- package/dist/config/migrator/index.js +9 -10
- package/dist/enums/academy.js +1 -2
- package/dist/guido.css +1 -1
- package/dist/sprite.svg +10 -0
- package/dist/src/@types/config/schemas.d.ts +2 -4
- package/dist/src/components/organisms/AutoSaveController.vue.d.ts +19 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -19
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -19
- package/dist/src/components/organisms/header/accessibility/AccessibilityToolbar.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/accessibility/ColorVisionSelect.vue.d.ts +2 -0
- package/dist/src/components/organisms/onboarding/EditorTabBarOnboarding.vue.d.ts +2 -0
- package/dist/src/composables/useAccessibilityApi.d.ts +13 -0
- package/dist/src/composables/useActionsApi.d.ts +2 -2
- package/dist/src/composables/useConfig.d.ts +2 -2
- package/dist/src/composables/useModuleRepair.d.ts +11 -2
- package/dist/src/enums/academy.d.ts +0 -1
- package/dist/src/stores/autosave.d.ts +73 -1
- package/dist/src/stores/config.d.ts +20 -20
- package/dist/src/stores/editor.d.ts +109 -25
- package/dist/src/stores/onboarding.d.ts +966 -35
- package/dist/src/stores/version-history.d.ts +1 -1
- package/dist/src/utils/templatePreparation.d.ts +1 -1
- package/dist/src/utils/timeUtil.d.ts +5 -8
- package/dist/static/styles/components/accessibility.css.js +234 -0
- package/dist/static/styles/variables.css.js +2 -0
- package/dist/stores/autosave.js +12 -7
- package/dist/stores/editor.js +20 -16
- package/dist/stores/onboarding.js +48 -22
- package/dist/utils/timeUtil.js +6 -17
- package/package.json +1 -1
- package/dist/components/organisms/header/AutoSaveToggle.vue.js +0 -22
- package/dist/components/organisms/header/AutoSaveToggle.vue2.js +0 -19
- package/dist/components/organisms/unsubscribe/LegacyUnsubscribeConvertedModal.vue.js +0 -17
- package/dist/components/organisms/unsubscribe/LegacyUnsubscribeConvertedModal.vue2.js +0 -30
- package/dist/config/migrator/legacyUnsubscribeTextMigrator.js +0 -16
- package/dist/src/config/migrator/legacyUnsubscribeTextMigrator.d.ts +0 -1
- package/dist/src/utils/legacyUnsubscribeConversion.d.ts +0 -10
- package/dist/utils/legacyUnsubscribeConversion.js +0 -49
- /package/dist/src/components/organisms/header/{AutoSaveToggle.vue.d.ts → AutoSaveStatus.vue.d.ts} +0 -0
- /package/dist/src/components/organisms/{unsubscribe/LegacyUnsubscribeConvertedModal.vue.d.ts → header/EditorActionsMenu.vue.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -166,7 +166,7 @@ const config: GuidoConfigInput = {
|
|
|
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
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).
|
|
168
168
|
reusableRecommendationStrategy?: boolean, // Default: false - Assign an RRS strategy to recommendation blocks instead of per-block algorithm/filters/shuffle/product-count settings.
|
|
169
|
-
|
|
169
|
+
accessibilityTesting?: boolean, // Default: false - Show the Accessibility Test entry in the header kebab menu (Stripo's checker: contrast, image alternatives, colour-vision simulation) and the tab-bar onboarding tour that points at it.
|
|
170
170
|
},
|
|
171
171
|
|
|
172
172
|
// Optional: Callbacks
|
|
@@ -668,14 +668,6 @@ multiple partners (e.g. architect) should key by partner and place the active pa
|
|
|
668
668
|
first. Omit the prop and the repair is a safe no-op — nothing is rewritten and no
|
|
669
669
|
toaster fires (useful before the host has wired the catalog).
|
|
670
670
|
|
|
671
|
-
With `features.legacyUnsubscribeConversion: true`, a dropped or copied module's legacy
|
|
672
|
-
unsubscribe block that has no unsubscribe link (the old editor reused it as plain text,
|
|
673
|
-
e.g. a company address) becomes a plain text block that keeps its content, and a warning
|
|
674
|
-
modal explains it. The same conversion runs when a template is opened. Register these
|
|
675
|
-
keys host-side: `email-editor.legacy-unsubscribe-converted-modal-title`,
|
|
676
|
-
`email-editor.legacy-unsubscribe-converted-modal-message` and
|
|
677
|
-
`email-editor.legacy-unsubscribe-converted-modal-visit-academy` (OK reuses `action-builder.ok`).
|
|
678
|
-
|
|
679
671
|
---
|
|
680
672
|
|
|
681
673
|
## Development
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ModuleFolderDefaults as S } from "../../enums/defaults.js";
|
|
2
|
-
import { object as a, number as s, optional as e, string as t, picklist as m, pipe as i, minLength as b, custom as k, boolean as o, array as
|
|
2
|
+
import { object as a, number as s, optional as e, string as t, picklist as m, pipe as i, minLength as b, custom as k, boolean as o, array as c, transform as y, unknown as r, record as g, fallback as R, literal as u, looseObject as C, variant as T, union as h, lazy as I } from "../../node_modules/valibot/dist/index.js";
|
|
3
3
|
const p = {
|
|
4
4
|
/** Promotional/marketing emails */
|
|
5
5
|
PROMOTIONAL: 1,
|
|
@@ -76,30 +76,30 @@ const p = {
|
|
|
76
76
|
value: t()
|
|
77
77
|
})
|
|
78
78
|
)
|
|
79
|
-
}), f =
|
|
79
|
+
}), f = I(() => C({
|
|
80
80
|
text: e(t()),
|
|
81
81
|
// eslint-disable-next-line camelcase -- backend field name
|
|
82
82
|
tag_text: e(t()),
|
|
83
83
|
value: e(t()),
|
|
84
|
-
children: e(
|
|
84
|
+
children: e(c(f)),
|
|
85
85
|
// eslint-disable-next-line camelcase -- backend field name
|
|
86
|
-
select_items: e(
|
|
87
|
-
})),
|
|
86
|
+
select_items: e(c(f))
|
|
87
|
+
})), N = g(
|
|
88
88
|
t(),
|
|
89
|
-
R(
|
|
90
|
-
),
|
|
89
|
+
R(c(f), [])
|
|
90
|
+
), P = C({
|
|
91
91
|
/** Block ID (matches the dictionary key and the legacy HTML element id) */
|
|
92
92
|
id: e(s()),
|
|
93
93
|
/** Decimal places for price display (legacy data may use string or number) */
|
|
94
94
|
decimalCount: e(h([t(), s()])),
|
|
95
95
|
/** Pinned product IDs (empty array when filter-driven) */
|
|
96
|
-
productIds: e(
|
|
96
|
+
productIds: e(c(r())),
|
|
97
97
|
/** Whether the block requested live products at send time */
|
|
98
98
|
sendProductRequestFlag: e(o()),
|
|
99
99
|
/** Whether to randomize product order */
|
|
100
100
|
shuffleProducts: e(o()),
|
|
101
101
|
/** Filter rules driving product selection */
|
|
102
|
-
filters: e(
|
|
102
|
+
filters: e(c(r())),
|
|
103
103
|
/** Currency code (e.g. 'EUR') — sometimes absent in legacy data */
|
|
104
104
|
currency: e(t()),
|
|
105
105
|
/** Currency display settings (separators, alignment, decimals) */
|
|
@@ -109,7 +109,7 @@ const p = {
|
|
|
109
109
|
/** Recommendation strategy key (e.g. 'newArrivals') */
|
|
110
110
|
strategy: e(t()),
|
|
111
111
|
/** Snapshot of products as rendered by the legacy block */
|
|
112
|
-
recommendedProducts: e(
|
|
112
|
+
recommendedProducts: e(c(r())),
|
|
113
113
|
/** Number of product cards per row */
|
|
114
114
|
cardsInRow: e(s()),
|
|
115
115
|
/** Mobile-only padding (right) */
|
|
@@ -132,7 +132,7 @@ const p = {
|
|
|
132
132
|
isPriceMovedToNextLine: e(o()),
|
|
133
133
|
/** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
|
|
134
134
|
isPriceDeletedForZeroSale: e(o())
|
|
135
|
-
}),
|
|
135
|
+
}), v = a({
|
|
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
|
-
g(t(),
|
|
143
|
+
g(t(), P),
|
|
144
144
|
{}
|
|
145
145
|
)
|
|
146
146
|
}), x = a({
|
|
@@ -150,7 +150,7 @@ const p = {
|
|
|
150
150
|
css: e(t(), ""),
|
|
151
151
|
/** Preselected dynamic content items */
|
|
152
152
|
preselectedDynamicContent: e(
|
|
153
|
-
|
|
153
|
+
c(M),
|
|
154
154
|
[]
|
|
155
155
|
),
|
|
156
156
|
/**
|
|
@@ -159,11 +159,11 @@ 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(
|
|
162
|
+
dynamicContentList: e(N, {}),
|
|
163
163
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
164
|
-
customFieldAttributes: e(
|
|
164
|
+
customFieldAttributes: e(c(t()), []),
|
|
165
165
|
/** Selected unsubscribe page IDs */
|
|
166
|
-
selectedUnsubscribePages: e(
|
|
166
|
+
selectedUnsubscribePages: e(c(s()), []),
|
|
167
167
|
/** Force recreate template in Stripo storage (use true when updating externally modified templates) */
|
|
168
168
|
forceRecreate: e(o(), !1),
|
|
169
169
|
/**
|
|
@@ -176,7 +176,7 @@ const p = {
|
|
|
176
176
|
trackIdCounter: e(
|
|
177
177
|
i(
|
|
178
178
|
s(),
|
|
179
|
-
y((
|
|
179
|
+
y((n) => Number.isFinite(n) ? Math.max(0, Math.floor(n)) : 0)
|
|
180
180
|
),
|
|
181
181
|
0
|
|
182
182
|
),
|
|
@@ -190,11 +190,11 @@ const p = {
|
|
|
190
190
|
recommendationCampaignUrls: e(
|
|
191
191
|
i(
|
|
192
192
|
r(),
|
|
193
|
-
y((
|
|
193
|
+
y((n) => n && typeof n == "object" ? { ...n } : void 0)
|
|
194
194
|
)
|
|
195
195
|
),
|
|
196
196
|
/** Migration-only inputs (legacy block configs) */
|
|
197
|
-
migration: e(
|
|
197
|
+
migration: e(v, {})
|
|
198
198
|
}), D = a({
|
|
199
199
|
/** Sender display name */
|
|
200
200
|
senderName: e(t(), ""),
|
|
@@ -237,15 +237,14 @@ const p = {
|
|
|
237
237
|
liquidSyntax: e(o(), !1),
|
|
238
238
|
/** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
|
|
239
239
|
autosave: e(o(), !1),
|
|
240
|
+
accessibilityTesting: e(o(), !1),
|
|
240
241
|
/** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
|
|
241
242
|
allowlistEnabled: e(o(), !1),
|
|
242
243
|
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
243
244
|
linkTrackingIds: e(o(), !1),
|
|
244
245
|
/** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
|
|
245
246
|
allowSaveWithErrors: e(o(), !0),
|
|
246
|
-
reusableRecommendationStrategy: e(o(), !1)
|
|
247
|
-
/** Convert linkless legacy unsubscribe blocks into text blocks and warn with a modal (opt-in) */
|
|
248
|
-
legacyUnsubscribeConversion: e(o(), !1)
|
|
247
|
+
reusableRecommendationStrategy: e(o(), !1)
|
|
249
248
|
}), w = m([
|
|
250
249
|
"amp-accordion",
|
|
251
250
|
"amp-carousel",
|
|
@@ -271,12 +270,12 @@ const p = {
|
|
|
271
270
|
]), j = a({
|
|
272
271
|
/** Default blocks to exclude from the editor */
|
|
273
272
|
excludeDefaults: e(
|
|
274
|
-
|
|
273
|
+
c(w),
|
|
275
274
|
[]
|
|
276
275
|
),
|
|
277
276
|
/** Custom blocks to include in the editor */
|
|
278
277
|
includeCustoms: e(
|
|
279
|
-
|
|
278
|
+
c(B),
|
|
280
279
|
[]
|
|
281
280
|
)
|
|
282
281
|
}), d = a({
|
|
@@ -308,23 +307,23 @@ const p = {
|
|
|
308
307
|
...d.entries,
|
|
309
308
|
type: u("remove"),
|
|
310
309
|
/** Strings or patterns to remove */
|
|
311
|
-
targets:
|
|
310
|
+
targets: c(t())
|
|
312
311
|
}), G = a({
|
|
313
312
|
...d.entries,
|
|
314
313
|
type: u("custom"),
|
|
315
314
|
/** Custom processor function */
|
|
316
315
|
processor: k(
|
|
317
|
-
(
|
|
316
|
+
(n) => typeof n == "function",
|
|
318
317
|
"processor must be a function"
|
|
319
318
|
)
|
|
320
|
-
}), V =
|
|
319
|
+
}), V = T("type", [
|
|
321
320
|
H,
|
|
322
321
|
_,
|
|
323
322
|
q,
|
|
324
323
|
G
|
|
325
324
|
]), z = a({
|
|
326
325
|
/** Custom compiler rules to apply */
|
|
327
|
-
customRules: e(
|
|
326
|
+
customRules: e(c(V), []),
|
|
328
327
|
/** Skip default compiler rules */
|
|
329
328
|
ignoreDefaultRules: e(o(), !1)
|
|
330
329
|
}), W = a({
|
|
@@ -334,7 +333,7 @@ const p = {
|
|
|
334
333
|
*/
|
|
335
334
|
externalValidation: e(
|
|
336
335
|
k(
|
|
337
|
-
(
|
|
336
|
+
(n) => typeof n == "function",
|
|
338
337
|
"externalValidation must be a function"
|
|
339
338
|
)
|
|
340
339
|
)
|
|
@@ -368,7 +367,7 @@ export {
|
|
|
368
367
|
B as CustomBlockTypeSchema,
|
|
369
368
|
G as CustomRuleSchema,
|
|
370
369
|
w as DefaultBlockTypeSchema,
|
|
371
|
-
|
|
370
|
+
N as DynamicContentListSchema,
|
|
372
371
|
f as DynamicContentNodeSchema,
|
|
373
372
|
M as DynamicContentSchema,
|
|
374
373
|
O as EditorSchema,
|
|
@@ -377,14 +376,14 @@ export {
|
|
|
377
376
|
U as FeaturesSchema,
|
|
378
377
|
K as GuidoConfigSchema,
|
|
379
378
|
A as IdentitySchema,
|
|
380
|
-
|
|
379
|
+
P as LegacyRecommendationConfigSchema,
|
|
381
380
|
p as MessageType,
|
|
382
381
|
E as PartnerSchema,
|
|
383
382
|
l as ProductType,
|
|
384
383
|
_ as RegexRuleSchema,
|
|
385
384
|
q as RemoveRuleSchema,
|
|
386
385
|
H as ReplaceRuleSchema,
|
|
387
|
-
|
|
386
|
+
v as TemplateMigrationSchema,
|
|
388
387
|
x as TemplateSchema,
|
|
389
388
|
F as UISchema
|
|
390
389
|
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import o from "./Guido.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import i from "../_virtual/_plugin-vue2_normalizer.js";
|
|
4
|
-
var
|
|
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: "
|
|
6
|
+
return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper), r(e.AutoSaveController, { ref: "autoSaveControllerRef" }), 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.AuthErrorModal), 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
|
-
},
|
|
9
|
+
}, s = [], n = /* @__PURE__ */ i(
|
|
10
10
|
o,
|
|
11
|
-
s,
|
|
12
11
|
t,
|
|
12
|
+
s,
|
|
13
13
|
!1,
|
|
14
14
|
null,
|
|
15
|
-
"
|
|
15
|
+
"f0ba01bc"
|
|
16
16
|
);
|
|
17
17
|
const v = n.exports;
|
|
18
18
|
export {
|
|
@@ -1,62 +1,70 @@
|
|
|
1
|
-
import { defineComponent as de, defineAsyncComponent as
|
|
1
|
+
import { defineComponent as de, defineAsyncComponent as m, ref as W, computed as p, watch as G, onMounted as me, onUnmounted as le } from "vue";
|
|
2
2
|
import { useCortexBlueprintBridge as ue } from "../composables/useCortexBlueprintBridge.js";
|
|
3
3
|
import { useEditorLock as pe } from "../composables/useEditorLock.js";
|
|
4
4
|
import { provideGuidoActions as fe } from "../composables/useGuidoActions.js";
|
|
5
5
|
import { useGuidoStateBridge as ye } from "../composables/useGuidoStateBridge.js";
|
|
6
6
|
import { usePartner as ge } from "../composables/usePartner.js";
|
|
7
|
-
import { useSaveValidationRollout as
|
|
8
|
-
import { useStripo as
|
|
9
|
-
import { useTimerClone as
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
7
|
+
import { useSaveValidationRollout as ve } from "../composables/useSaveValidationRollout.js";
|
|
8
|
+
import { useStripo as Se } from "../composables/useStripo.js";
|
|
9
|
+
import { useTimerClone as be } from "../composables/useTimerClone.js";
|
|
10
|
+
import { useToaster as he } from "../composables/useToaster.js";
|
|
11
|
+
import { useTranslations as Ee } from "../composables/useTranslations.js";
|
|
12
|
+
import { migrate as $ } from "../config/migrator/index.js";
|
|
13
|
+
import { ModuleFolderDefaults as z } from "../enums/defaults.js";
|
|
14
|
+
import { RIBBON_SELECTOR as we } from "../enums/onboarding.js";
|
|
15
|
+
import { ToasterTypeOptions as De } from "../enums/toaster.js";
|
|
16
|
+
import { useRecommendationExtensionStore as q, disposeStrategyPageReturnListeners as Te } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
17
|
+
import { disposeUnsubscribeListeners as ke } from "../extensions/Blocks/Unsubscribe/block.js";
|
|
15
18
|
import Ce from "./organisms/AutoSaveController.vue.js";
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import { useStripoApi as
|
|
25
|
-
import { useConfigStore as
|
|
26
|
-
import { useDynamicContentStore as
|
|
19
|
+
import Re from "./organisms/base/AuthErrorModal.vue.js";
|
|
20
|
+
import Fe from "./organisms/base/Toaster.vue.js";
|
|
21
|
+
import Le from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
|
|
22
|
+
import Me from "./organisms/header/HeaderWrapper.vue.js";
|
|
23
|
+
import Ie from "./organisms/LoadingWrapper.vue.js";
|
|
24
|
+
import Ue from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
|
|
25
|
+
import Oe from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
|
|
26
|
+
import Ae from "./organisms/validation/ValidationErrorDrawer.vue.js";
|
|
27
|
+
import { useStripoApi as Be } from "../services/stripoApi.js";
|
|
28
|
+
import { useConfigStore as Ne } from "../stores/config.js";
|
|
29
|
+
import { useDynamicContentStore as Pe } from "../stores/dynamic-content.js";
|
|
27
30
|
import { useEditorStore as E } from "../stores/editor.js";
|
|
28
|
-
import { usePreviewStore as
|
|
29
|
-
import { useSaveValidationStore as
|
|
30
|
-
import { useTemplateStore as
|
|
31
|
-
import { useUnsubscribeStore as
|
|
32
|
-
import { readTrackFloor as
|
|
33
|
-
const
|
|
31
|
+
import { usePreviewStore as _e } from "../stores/preview.js";
|
|
32
|
+
import { useSaveValidationStore as Ve } from "../stores/save-validation.js";
|
|
33
|
+
import { useTemplateStore as xe } from "../stores/template.js";
|
|
34
|
+
import { useUnsubscribeStore as He } from "../stores/unsubscribe.js";
|
|
35
|
+
import { readTrackFloor as K } from "../utils/linkTrackingIds.js";
|
|
36
|
+
const To = /* @__PURE__ */ de({
|
|
34
37
|
__name: "Guido",
|
|
35
38
|
props: {
|
|
36
39
|
config: null,
|
|
37
40
|
ready: { type: Boolean, default: !0 }
|
|
38
41
|
},
|
|
39
42
|
emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
|
|
40
|
-
setup(
|
|
41
|
-
const
|
|
43
|
+
setup(j, { expose: J, emit: r }) {
|
|
44
|
+
const i = j, Q = m(
|
|
42
45
|
() => import("./organisms/email-preview/PreviewContainer.vue.js")
|
|
43
|
-
),
|
|
46
|
+
), X = m(
|
|
44
47
|
() => import("./organisms/onboarding/OnboardingWrapper.vue.js")
|
|
45
|
-
),
|
|
48
|
+
), Y = m(
|
|
46
49
|
() => import("./organisms/extensions/recommendation/AssignStrategyDrawer.vue.js")
|
|
47
|
-
),
|
|
50
|
+
), Z = m(
|
|
48
51
|
() => import("./organisms/extensions/recommendation/RemoveStrategyModal.vue.js")
|
|
49
|
-
),
|
|
52
|
+
), w = W(), ee = m(
|
|
50
53
|
() => import("./organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js")
|
|
51
|
-
),
|
|
52
|
-
|
|
53
|
-
),
|
|
54
|
-
a.ready && t.init(a.config);
|
|
55
|
-
const d = E(), ee = Ne(), u = l(() => d.hasChanges), { isTestPartner: oe } = ge(), { isEnabled: te, loadRollout: D } = be(), k = () => {
|
|
54
|
+
), f = W(), y = Pe(), D = He(), t = Ne();
|
|
55
|
+
i.ready && t.init(i.config);
|
|
56
|
+
const a = E(), oe = _e(), l = p(() => a.hasChanges), { isTestPartner: te } = ge(), { isEnabled: ne, loadRollout: T } = ve(), { showToaster: k } = he(), C = Ee(), R = () => {
|
|
56
57
|
var o;
|
|
57
|
-
|
|
58
|
+
if (a.isVersionHistoryOpen) {
|
|
59
|
+
console.debug("guido:save:silent:blocked", { isVersionHistoryOpen: !0 }), k({
|
|
60
|
+
type: De.Warning,
|
|
61
|
+
message: C("email-editor.save-blocked-outside-editor")
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
return (o = w.value) == null ? void 0 : o.saveSilent();
|
|
58
66
|
}, F = (o) => {
|
|
59
|
-
|
|
67
|
+
a.loadingStatus = o;
|
|
60
68
|
};
|
|
61
69
|
ue(), ye();
|
|
62
70
|
const g = () => {
|
|
@@ -66,18 +74,16 @@ const vo = /* @__PURE__ */ de({
|
|
|
66
74
|
userId: t.userId,
|
|
67
75
|
username: t.username,
|
|
68
76
|
partnerName: t.partnerName,
|
|
69
|
-
savedModulesFolderName: ((o = t.editor) == null ? void 0 : o.savedModulesFolderName) ||
|
|
70
|
-
defaultModulesFolderName: ((e = t.editor) == null ? void 0 : e.defaultModulesFolderName) ||
|
|
77
|
+
savedModulesFolderName: ((o = t.editor) == null ? void 0 : o.savedModulesFolderName) || z.SAVED_MODULES,
|
|
78
|
+
defaultModulesFolderName: ((e = t.editor) == null ? void 0 : e.defaultModulesFolderName) || z.DEFAULT_MODULES
|
|
71
79
|
};
|
|
72
|
-
}, { initPlugin: L, preloadRuntime:
|
|
73
|
-
let
|
|
74
|
-
const { getDefaultTemplate:
|
|
80
|
+
}, { initPlugin: L, preloadRuntime: M } = Se(), { runExclusive: I, beginMount: U, isCurrentMount: v } = pe();
|
|
81
|
+
let u = 0;
|
|
82
|
+
const { getDefaultTemplate: O } = Be(), { cloneTimersOnSave: A, hasTimerBlocks: B } = be(), re = p(() => {
|
|
75
83
|
var o;
|
|
76
84
|
return !((o = t.ui) != null && o.showHeader);
|
|
77
|
-
}),
|
|
78
|
-
() =>
|
|
79
|
-
), ae = l(
|
|
80
|
-
() => !!z().recommendationConfigs.strategyId
|
|
85
|
+
}), se = p(() => t.isFeatureEnabled("reusableRecommendationStrategy")), ie = p(
|
|
86
|
+
() => !!q().recommendationConfigs.strategyId
|
|
81
87
|
);
|
|
82
88
|
fe({
|
|
83
89
|
onBack: () => {
|
|
@@ -94,90 +100,91 @@ const vo = /* @__PURE__ */ de({
|
|
|
94
100
|
console.debug("guido:test-email:click"), r("test-email:click");
|
|
95
101
|
}
|
|
96
102
|
});
|
|
97
|
-
const
|
|
103
|
+
const N = (o) => {
|
|
98
104
|
console.debug("dynamic-content:close", o), y.setSelectedDynamicContent(o), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: o }));
|
|
99
|
-
},
|
|
105
|
+
}, P = () => {
|
|
100
106
|
console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
|
|
101
107
|
};
|
|
102
|
-
G(() =>
|
|
103
|
-
r("on-change",
|
|
108
|
+
G(() => l.value, () => {
|
|
109
|
+
r("on-change", l.value);
|
|
104
110
|
});
|
|
105
|
-
const
|
|
106
|
-
const e = o, { attribute: s, position:
|
|
107
|
-
console.debug("dynamic-content:open", e.detail), r("dynamic-content:open", s,
|
|
111
|
+
const S = (o) => {
|
|
112
|
+
const e = o, { attribute: s, position: d } = e.detail;
|
|
113
|
+
console.debug("dynamic-content:open", e.detail), r("dynamic-content:open", s, d);
|
|
108
114
|
};
|
|
109
|
-
let
|
|
110
|
-
const
|
|
115
|
+
let c = null;
|
|
116
|
+
const b = () => {
|
|
111
117
|
var e;
|
|
112
|
-
const o = document.querySelector(
|
|
118
|
+
const o = document.querySelector(we);
|
|
113
119
|
(e = f.value) == null || e.style.setProperty("--ribbon-offset", `${(o == null ? void 0 : o.offsetHeight) ?? 0}px`);
|
|
114
120
|
}, h = async () => {
|
|
115
121
|
var o;
|
|
116
122
|
try {
|
|
117
|
-
t.initialized || t.init(
|
|
118
|
-
const e = t.template, s = (e == null ? void 0 : e.html) || "",
|
|
119
|
-
|
|
120
|
-
const
|
|
123
|
+
t.initialized || t.init(i.config), a.templateId = t.templateId;
|
|
124
|
+
const e = t.template, s = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", _ = (e == null ? void 0 : e.preselectedDynamicContent) || [];
|
|
125
|
+
D.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
|
|
126
|
+
const V = ((o = e == null ? void 0 : e.migration) == null ? void 0 : o.recommendationConfigs) ?? {}, x = t.isFeatureEnabled("linkTrackingIds"), H = {
|
|
121
127
|
partnerName: t.partnerName,
|
|
122
128
|
campaignUrls: e == null ? void 0 : e.recommendationCampaignUrls,
|
|
123
129
|
rrsEnabled: t.isFeatureEnabled("reusableRecommendationStrategy")
|
|
124
130
|
};
|
|
125
131
|
let n = {
|
|
126
|
-
html: s && await
|
|
127
|
-
css:
|
|
132
|
+
html: s && await $(s, V, H),
|
|
133
|
+
css: d
|
|
128
134
|
};
|
|
129
|
-
n.html || (n = await
|
|
130
|
-
const
|
|
131
|
-
|
|
135
|
+
n.html || (n = await O(), n.html = await $(n.html, V, H));
|
|
136
|
+
const ae = x ? K(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
|
|
137
|
+
B(n.html) && (n.html = await A(n.html)), x && (a.trackIdSessionFloor = Math.max(ae, K(n.html)));
|
|
132
138
|
const ce = {
|
|
133
|
-
preselectedDynamicContentList:
|
|
139
|
+
preselectedDynamicContentList: _,
|
|
134
140
|
onReady: () => {
|
|
135
141
|
console.debug("guido:ready"), r("ready");
|
|
136
142
|
}
|
|
137
143
|
};
|
|
138
|
-
|
|
144
|
+
u = U(), await L(n, g(), ce), y.selectedDynamicContentList = _;
|
|
139
145
|
} catch (e) {
|
|
140
146
|
console.error("Failed to initialize Stripo editor:", e);
|
|
141
147
|
}
|
|
142
148
|
};
|
|
143
149
|
return me(async () => {
|
|
144
150
|
var e;
|
|
145
|
-
console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"),
|
|
151
|
+
console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), q().$reset(), E().$reset(), xe().$reset(), Ve().$reset(), T(), b();
|
|
146
152
|
const o = (e = f.value) == null ? void 0 : e.parentElement;
|
|
147
|
-
if (o && (
|
|
153
|
+
if (o && (c = new ResizeObserver(b), c.observe(o)), M(), i.ready)
|
|
148
154
|
await h();
|
|
149
155
|
else {
|
|
150
|
-
const s = G(() =>
|
|
151
|
-
|
|
156
|
+
const s = G(() => i.ready, (d) => {
|
|
157
|
+
d && (s(), h());
|
|
152
158
|
});
|
|
153
159
|
}
|
|
154
|
-
document.addEventListener("dynamic-content:open",
|
|
160
|
+
document.addEventListener("dynamic-content:open", S);
|
|
155
161
|
}), le(() => {
|
|
156
|
-
if (
|
|
162
|
+
if (ke(), Te(), c == null || c.disconnect(), document.removeEventListener("dynamic-content:open", S), v(u))
|
|
157
163
|
try {
|
|
158
|
-
E()
|
|
164
|
+
const o = E();
|
|
165
|
+
o.isStripoInitialized = !1, o.isAccessibilityTestingOpen = !1, o.imagesHidden = !1, o.colorVisionDeficiency = "";
|
|
159
166
|
} catch (o) {
|
|
160
167
|
console.debug("Failed to close the editor readiness gate on unmount", o);
|
|
161
168
|
}
|
|
162
|
-
|
|
163
|
-
if (
|
|
169
|
+
I(async () => {
|
|
170
|
+
if (v(u))
|
|
164
171
|
try {
|
|
165
172
|
window.UIEditor.removeEditor();
|
|
166
173
|
} catch {
|
|
167
174
|
console.debug("Failed to remove Stripo editor: No editor found");
|
|
168
175
|
}
|
|
169
176
|
}), t.reset();
|
|
170
|
-
}),
|
|
177
|
+
}), J({
|
|
171
178
|
dynamicContent: {
|
|
172
|
-
insert:
|
|
173
|
-
close:
|
|
179
|
+
insert: N,
|
|
180
|
+
close: P
|
|
174
181
|
},
|
|
175
|
-
hasChanges:
|
|
176
|
-
saveSilent:
|
|
182
|
+
hasChanges: l,
|
|
183
|
+
saveSilent: R,
|
|
177
184
|
setLoading: F
|
|
178
|
-
}), { __sfc: !0, PreviewContainer:
|
|
185
|
+
}), { __sfc: !0, PreviewContainer: Q, OnboardingWrapper: X, AssignStrategyDrawer: Y, RemoveStrategyModal: Z, autoSaveControllerRef: w, LegacyStrategyUpdatedModal: ee, wrapperRef: f, dynamicContentStore: y, unsubscribeStore: D, props: i, configStore: t, editorStore: a, previewStore: oe, hasChanges: l, isTestPartner: te, isSaveValidationEnabled: ne, loadRollout: T, showToaster: k, trans: C, saveSilent: R, setLoading: F, emit: r, buildMetadata: g, initPlugin: L, preloadRuntime: M, runExclusive: I, beginMount: U, isCurrentMount: v, mountGeneration: u, getDefaultTemplate: O, cloneTimersOnSave: A, hasTimerBlocks: B, noHeader: re, isRrsEnabled: se, hasAssignedStrategy: ie, insertDynamicContent: N, closeDynamicContent: P, handleDynamicContentOpen: S, ribbonObserver: c, updateRibbonOffset: b, startEditor: h, AutoSaveController: Ce, AuthErrorModal: Re, Toaster: Fe, FilterSelectionDrawer: Le, HeaderWrapper: Me, LoadingWrapper: Ie, SaveAsTemplateDrawer: Ue, UnsubscribeWrapper: Oe, ValidationErrorDrawer: Ae };
|
|
179
186
|
}
|
|
180
187
|
});
|
|
181
188
|
export {
|
|
182
|
-
|
|
189
|
+
To as default
|
|
183
190
|
};
|
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { useAutoSave as
|
|
3
|
-
import { useSave as
|
|
4
|
-
import { useSaveValidationRollout as
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import { defineComponent as c } from "vue";
|
|
2
|
+
import { useAutoSave as m } from "../../composables/useAutoSave.js";
|
|
3
|
+
import { useSave as f } from "../../composables/useSave.js";
|
|
4
|
+
import { useSaveValidationRollout as v } from "../../composables/useSaveValidationRollout.js";
|
|
5
|
+
import { useToaster as p } from "../../composables/useToaster.js";
|
|
6
|
+
import { useConfigStore as S } from "../../stores/config.js";
|
|
7
|
+
const A = /* @__PURE__ */ c({
|
|
7
8
|
__name: "AutoSaveController",
|
|
8
|
-
setup(
|
|
9
|
-
const { save: e, saveRawOnly: t } =
|
|
10
|
-
|
|
9
|
+
setup(d, { expose: u }) {
|
|
10
|
+
const { save: e, saveRawOnly: t } = f(), { isEnabled: r } = v(), { handleError: a } = p(), s = S(), o = () => r.value && s.allowSaveWithErrors, n = () => o() ? t() : e(!1, !0);
|
|
11
|
+
m(n, { clearsChanges: () => !o() });
|
|
12
|
+
const i = async () => {
|
|
13
|
+
try {
|
|
14
|
+
return await e(!0);
|
|
15
|
+
} catch (l) {
|
|
16
|
+
a(l, "Failed to save template");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
return u({ saveSilent: i }), { __sfc: !0, save: e, saveRawOnly: t, isEnabled: r, handleError: a, configStore: s, isRawAutosave: o, backgroundSave: n, saveSilent: i };
|
|
11
21
|
}
|
|
12
22
|
});
|
|
13
23
|
export {
|
|
14
|
-
|
|
24
|
+
A as default
|
|
15
25
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import t from "./AutoSaveStatus.vue2.js";
|
|
2
|
+
import r from "../../../_virtual/_plugin-vue2_normalizer.js";
|
|
3
|
+
var _ = function() {
|
|
4
|
+
var s = this, e = s._self._c, a = s._self._setupProxy;
|
|
5
|
+
return a.isFeatureEnabled("autosave") ? e("div", { staticClass: "d-f a-i-c auto-save-status" }, [a.autosaveStore.status === a.AUTOSAVE_STATUS.SAVING ? e("span", { staticClass: "d-f a-i-c f-s-1" }, [e(a.InLoading, { attrs: { "color-class": "i-c-53", size: "16" } }), e("span", { staticClass: "ml-1 t-c-53" }, [s._v(s._s(a.trans("newsletter.saving")))])], 1) : a.savedLabel ? e("span", { staticClass: "f-s-1 t-c-53" }, [s._v(s._s(a.savedLabel.before)), a.savedLabel.word ? e("span", { staticClass: "f-w-600" }, [s._v(s._s(a.savedLabel.word))]) : s._e(), s._v(s._s(a.savedLabel.after))]) : s._e()]) : s._e();
|
|
6
|
+
}, n = [], o = /* @__PURE__ */ r(
|
|
7
|
+
t,
|
|
8
|
+
_,
|
|
9
|
+
n,
|
|
10
|
+
!1,
|
|
11
|
+
null,
|
|
12
|
+
null
|
|
13
|
+
);
|
|
14
|
+
const v = o.exports;
|
|
15
|
+
export {
|
|
16
|
+
v as default
|
|
17
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineComponent as p, computed as S } from "vue";
|
|
2
|
+
import { useConfig as A } from "../../../composables/useConfig.js";
|
|
3
|
+
import { useTranslations as T } from "../../../composables/useTranslations.js";
|
|
4
|
+
import { useAutosaveStore as v, AUTOSAVE_STATUS as m } from "../../../stores/autosave.js";
|
|
5
|
+
import { autoSaveTimestamp as b } from "../../../utils/timeUtil.js";
|
|
6
|
+
import { InLoading as D } from "@useinsider/design-system-vue";
|
|
7
|
+
const j = /* @__PURE__ */ p({
|
|
8
|
+
__name: "AutoSaveStatus",
|
|
9
|
+
setup(O) {
|
|
10
|
+
const { isFeatureEnabled: u } = A(), a = v(), n = T(), t = "__BOLD_START__", o = "__BOLD_END__", s = (i) => i.split(t).join("").split(o).join(""), _ = S(() => {
|
|
11
|
+
if (a.status !== m.SAVED || !a.lastSavedAt)
|
|
12
|
+
return null;
|
|
13
|
+
const { isToday: i, time: c, date: f } = b(a.lastSavedAt), l = { boldStart: t, boldEnd: o }, e = i ? n("email-editor.autosaved-at-today", { ...l, time: c }) : n("email-editor.autosaved-at-date", { ...l, date: f }), r = e.indexOf(t), d = e.indexOf(o, r + t.length);
|
|
14
|
+
return r === -1 || d === -1 ? { before: s(e), word: "", after: "" } : {
|
|
15
|
+
before: s(e.slice(0, r)),
|
|
16
|
+
word: s(e.slice(r + t.length, d)),
|
|
17
|
+
after: s(e.slice(d + o.length))
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
return { __sfc: !0, isFeatureEnabled: u, autosaveStore: a, trans: n, BOLD_START: t, BOLD_END: o, stripMarkers: s, savedLabel: _, AUTOSAVE_STATUS: m, InLoading: D };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
export {
|
|
24
|
+
j as default
|
|
25
|
+
};
|