@useinsider/guido 3.18.2-beta.9be830c → 3.18.2-beta.a5a0a11

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 (92) hide show
  1. package/dist/@types/config/schemas.js +13 -15
  2. package/dist/components/Guido.vue.js +7 -7
  3. package/dist/components/Guido.vue2.js +30 -30
  4. package/dist/components/organisms/AutoSaveController.vue2.js +8 -10
  5. package/dist/components/organisms/base/Toaster.vue2.js +13 -12
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -11
  7. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +74 -57
  8. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +23 -37
  9. package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
  10. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
  11. package/dist/components/organisms/header/EditorActions.vue.js +13 -13
  12. package/dist/components/organisms/header/EditorActions.vue2.js +52 -36
  13. package/dist/components/organisms/header/HeaderWrapper.vue.js +6 -6
  14. package/dist/components/organisms/header/HeaderWrapper.vue2.js +17 -9
  15. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  16. package/dist/components/organisms/header/LeftSlot.vue2.js +23 -28
  17. package/dist/components/organisms/header/MiddleSlot.vue.js +4 -4
  18. package/dist/components/organisms/header/MiddleSlot.vue2.js +7 -8
  19. package/dist/components/organisms/header/RightSlot.vue.js +8 -9
  20. package/dist/components/organisms/header/RightSlot.vue2.js +18 -13
  21. package/dist/components/organisms/onboarding/OnboardingWrapper.vue.js +12 -12
  22. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +38 -54
  23. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
  24. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +47 -0
  25. package/dist/composables/useCustomInterfaceAppearance.js +52 -45
  26. package/dist/composables/useHtmlValidator.js +87 -82
  27. package/dist/composables/useRecommendation.js +40 -35
  28. package/dist/composables/useStripo.js +30 -30
  29. package/dist/composables/useToaster.js +14 -20
  30. package/dist/config/i18n/en/labels.json.js +4 -36
  31. package/dist/config/i18n/en/tooltips.json.js +1 -2
  32. package/dist/enums/extensions/recommendationBlock.js +38 -31
  33. package/dist/extensions/Blocks/Recommendation/block.js +61 -42
  34. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +21 -20
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +40 -35
  36. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +84 -52
  37. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
  38. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +260 -140
  39. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +26 -16
  40. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +24 -0
  41. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +21 -12
  42. package/dist/guido.css +1 -1
  43. package/dist/node_modules/@vueuse/shared/index.js +28 -40
  44. package/dist/sprite.svg +0 -6
  45. package/dist/src/@types/config/schemas.d.ts +0 -4
  46. package/dist/src/components/organisms/AutoSaveController.vue.d.ts +1 -3
  47. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +3 -1
  48. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +3 -1
  49. package/dist/src/composables/useActionsApi.d.ts +2 -2
  50. package/dist/src/composables/useConfig.d.ts +0 -2
  51. package/dist/src/enums/extensions/recommendationBlock.d.ts +2 -0
  52. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  53. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  54. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  55. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -0
  56. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +9 -0
  57. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +7 -2
  58. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +86 -0
  59. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +14 -0
  60. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +4 -0
  61. package/dist/src/stores/config.d.ts +0 -18
  62. package/dist/src/stores/editor.d.ts +0 -107
  63. package/dist/src/stores/onboarding.d.ts +21 -195
  64. package/dist/src/stores/version-history.d.ts +1 -1
  65. package/dist/src/utils/timeUtil.d.ts +0 -10
  66. package/dist/static/styles/components/recommendation-strategy.css.js +34 -4
  67. package/dist/static/styles/components/skeleton.css.js +23 -0
  68. package/dist/static/styles/variables.css.js +0 -2
  69. package/dist/stores/editor.js +4 -13
  70. package/dist/stores/onboarding.js +50 -66
  71. package/dist/utils/templatePreparation.js +55 -55
  72. package/dist/utils/timeUtil.js +17 -7
  73. package/package.json +5 -5
  74. package/dist/components/organisms/header/AutoSaveStatus.vue.js +0 -17
  75. package/dist/components/organisms/header/AutoSaveStatus.vue2.js +0 -27
  76. package/dist/components/organisms/header/EditorActionsMenu.vue.js +0 -20
  77. package/dist/components/organisms/header/EditorActionsMenu.vue2.js +0 -48
  78. package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue.js +0 -18
  79. package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue2.js +0 -37
  80. package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue.js +0 -24
  81. package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue2.js +0 -48
  82. package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue.js +0 -19
  83. package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue2.js +0 -82
  84. package/dist/composables/useAccessibilityApi.js +0 -35
  85. package/dist/node_modules/@vueuse/core/index.js +0 -102
  86. package/dist/src/components/organisms/header/accessibility/AccessibilityToolbar.vue.d.ts +0 -2
  87. package/dist/src/components/organisms/header/accessibility/ColorVisionSelect.vue.d.ts +0 -2
  88. package/dist/src/components/organisms/onboarding/EditorTabBarOnboarding.vue.d.ts +0 -2
  89. package/dist/src/composables/useAccessibilityApi.d.ts +0 -15
  90. package/dist/static/styles/components/accessibility.css.js +0 -282
  91. /package/dist/src/components/organisms/header/{AutoSaveStatus.vue.d.ts → AutoSaveToggle.vue.d.ts} +0 -0
  92. /package/dist/src/components/organisms/{header/EditorActionsMenu.vue.d.ts → onboarding/RecommendationStrategyOnboarding.vue.d.ts} +0 -0
@@ -1,75 +1,64 @@
1
- import { useOnboardingApi as t } from "../services/onboardingApi.js";
2
- import { defineStore as e } from "pinia";
3
- const r = () => ({
1
+ import { useOnboardingApi as e } from "../services/onboardingApi.js";
2
+ import { defineStore as s } from "pinia";
3
+ const t = () => ({
4
4
  cardIndex: 0,
5
5
  isActive: !1,
6
6
  config: []
7
7
  }), a = () => ({
8
8
  onboardings: {
9
- newVersionPopup: r(),
10
- genericOnboarding: r(),
11
- textBlockOnboarding: r(),
12
- versionHistoryOnboarding: r(),
13
- ampOnboarding: r(),
14
- itemsOnboarding: r(),
15
- editorTabBarOnboarding: r()
9
+ newVersionPopup: t(),
10
+ genericOnboarding: t(),
11
+ textBlockOnboarding: t(),
12
+ versionHistoryOnboarding: t(),
13
+ ampOnboarding: t(),
14
+ itemsOnboarding: t(),
15
+ recommendationStrategyOnboarding: t()
16
16
  },
17
17
  userModalState: {},
18
- isFetched: !1,
19
- // Onboardings the user closed in this page session. The saved state cannot stand in
20
- // for it: close() fills it even when the save fails, and a test stub can keep
21
- // reporting "unseen". Being wiped by another onboarding is deliberately not in here,
22
- // so an interrupted tour can come back once that other one is done.
23
- closedThisSession: []
24
- }), g = e("guidoOnboarding", {
18
+ isFetched: !1
19
+ }), c = s("guidoOnboarding", {
25
20
  state: () => a(),
26
21
  getters: {
27
- getOnboarding: (n) => (i) => n.onboardings[i],
28
- isActive: (n) => (i) => n.onboardings[i].isActive,
29
- getCurrentCard: (n) => (i) => {
30
- const o = n.onboardings[i];
31
- return o.config[o.cardIndex];
22
+ getOnboarding: (n) => (o) => n.onboardings[o],
23
+ isActive: (n) => (o) => n.onboardings[o].isActive,
24
+ getCurrentCard: (n) => (o) => {
25
+ const i = n.onboardings[o];
26
+ return i.config[i.cardIndex];
32
27
  },
33
28
  getGenericCurrentCard: (n) => {
34
- const { genericOnboarding: i } = n.onboardings;
35
- return i.config[i.cardIndex];
29
+ const { genericOnboarding: o } = n.onboardings;
30
+ return o.config[o.cardIndex];
36
31
  },
37
32
  getTextBlockCurrentCard: (n) => {
38
- const { textBlockOnboarding: i } = n.onboardings;
39
- return i.config[i.cardIndex];
33
+ const { textBlockOnboarding: o } = n.onboardings;
34
+ return o.config[o.cardIndex];
40
35
  },
41
36
  getVersionHistoryCurrentCard: (n) => {
42
- const { versionHistoryOnboarding: i } = n.onboardings;
43
- return i.config[i.cardIndex];
37
+ const { versionHistoryOnboarding: o } = n.onboardings;
38
+ return o.config[o.cardIndex];
44
39
  },
45
40
  getAmpCurrentCard: (n) => {
46
- const { ampOnboarding: i } = n.onboardings;
47
- return i.config[i.cardIndex];
41
+ const { ampOnboarding: o } = n.onboardings;
42
+ return o.config[o.cardIndex];
48
43
  },
49
44
  getItemsCurrentCard: (n) => {
50
- const { itemsOnboarding: i } = n.onboardings;
51
- return i.config[i.cardIndex];
52
- },
53
- getEditorTabBarCurrentCard: (n) => {
54
- const { editorTabBarOnboarding: i } = n.onboardings;
55
- return i.config[i.cardIndex];
45
+ const { itemsOnboarding: o } = n.onboardings;
46
+ return o.config[o.cardIndex];
56
47
  },
57
- // Every tab-bar tour card after the first points at a row inside the kebab menu,
58
- // so the menu has to stay open under them.
59
- isEditorActionsMenuPinned: (n) => {
60
- const { editorTabBarOnboarding: i } = n.onboardings;
61
- return i.isActive && i.cardIndex > 0;
48
+ getRecommendationStrategyCurrentCard: (n) => {
49
+ const { recommendationStrategyOnboarding: o } = n.onboardings;
50
+ return o.config[o.cardIndex];
62
51
  },
63
- shouldShowOnboarding: (n) => (i) => {
64
- const o = n.userModalState.Guido;
65
- return i === "newVersionPopup" && (o != null && o.genericOnboarding) ? !1 : o ? !o[i] : !0;
52
+ shouldShowOnboarding: (n) => (o) => {
53
+ const i = n.userModalState.Guido;
54
+ return o === "newVersionPopup" && (i != null && i.genericOnboarding) ? !1 : i ? !i[o] : !0;
66
55
  }
67
56
  },
68
57
  actions: {
69
58
  closeOtherOnboardings(n) {
70
- Object.keys(this.onboardings).forEach((i) => {
71
- const o = i;
72
- o !== n && this.onboardings[o].isActive && (this.onboardings[o].isActive = !1, this.onboardings[o].cardIndex = 0, this.onboardings[o].config = []);
59
+ Object.keys(this.onboardings).forEach((o) => {
60
+ const i = o;
61
+ i !== n && this.onboardings[i].isActive && (this.onboardings[i].isActive = !1, this.onboardings[i].cardIndex = 0, this.onboardings[i].config = []);
73
62
  });
74
63
  },
75
64
  start(n) {
@@ -79,12 +68,7 @@ const r = () => ({
79
68
  this.shouldShowOnboarding(n) && !this.isActive(n) && this.start(n);
80
69
  },
81
70
  async close(n) {
82
- this.closedThisSession.includes(n) || this.closedThisSession.push(n), this.onboardings[n].isActive = !1, this.onboardings[n].cardIndex = 0, this.onboardings[n].config = [];
83
- try {
84
- await this.setUserModalState(n, "true", "Guido");
85
- } catch (i) {
86
- console.warn("guido:onboarding:close-not-persisted", n, i);
87
- }
71
+ await this.setUserModalState(n, "true", "Guido"), this.onboardings[n].isActive = !1, this.onboardings[n].cardIndex = 0, this.onboardings[n].config = [];
88
72
  },
89
73
  next(n) {
90
74
  this.onboardings[n].cardIndex < this.onboardings[n].config.length - 1 && this.onboardings[n].cardIndex++;
@@ -92,15 +76,15 @@ const r = () => ({
92
76
  previous(n) {
93
77
  this.onboardings[n].cardIndex > 0 && this.onboardings[n].cardIndex--;
94
78
  },
95
- updateCardPosition(n, i, o) {
96
- const s = this.onboardings[n].config[i];
97
- s && (s.top = o.top, s.position = o.position);
79
+ updateCardPosition(n, o, i) {
80
+ const r = this.onboardings[n].config[o];
81
+ r && (r.top = i.top, r.position = i.position);
98
82
  },
99
- setConfig(n, i) {
100
- this.onboardings[n].config = i ?? [], this.onboardings[n].cardIndex >= this.onboardings[n].config.length && (this.onboardings[n].cardIndex = 0);
83
+ setConfig(n, o) {
84
+ this.onboardings[n].config = o ?? [], this.onboardings[n].cardIndex >= this.onboardings[n].config.length && (this.onboardings[n].cardIndex = 0);
101
85
  },
102
86
  async onDiscoverNowClicked() {
103
- this.start("genericOnboarding"), await this.setUserModalState("newVersionPopup", "true", "Guido"), await this.setUserModalState("genericOnboarding", "true", "Guido");
87
+ await this.setUserModalState("newVersionPopup", "true", "Guido"), await this.setUserModalState("genericOnboarding", "true", "Guido"), this.start("genericOnboarding");
104
88
  },
105
89
  onRemindMeLater() {
106
90
  sessionStorage.setItem("newVersionPopupDismissed", "true");
@@ -114,19 +98,19 @@ const r = () => ({
114
98
  async fetchUserModalState() {
115
99
  if (this.isFetched)
116
100
  return;
117
- const { fetchUserModalState: n } = t();
101
+ const { fetchUserModalState: n } = e();
118
102
  try {
119
- const i = await n();
120
- this.userModalState = i, this.isFetched = !0;
103
+ const o = await n();
104
+ this.userModalState = o, this.isFetched = !0;
121
105
  } catch {
122
106
  }
123
107
  },
124
- async setUserModalState(n, i, o) {
125
- const { setUserModalState: s } = t();
126
- await s(n, i, o), this.isFetched = !1, await this.fetchUserModalState();
108
+ async setUserModalState(n, o, i) {
109
+ const { setUserModalState: r } = e();
110
+ await r(n, o, i), this.isFetched = !1, await this.fetchUserModalState();
127
111
  }
128
112
  }
129
113
  });
130
114
  export {
131
- g as useOnboardingStore
115
+ c as useOnboardingStore
132
116
  };
@@ -1,32 +1,32 @@
1
- import { useActionsApi as k } from "../composables/useActionsApi.js";
2
- import { useConfig as U } from "../composables/useConfig.js";
3
- import { useHtmlCompiler as x } from "../composables/useHtmlCompiler.js";
4
- import { DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as n } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
5
- import { useRecommendationExtensionStore as A } from "../extensions/Blocks/Recommendation/store/recommendation.js";
6
- import { mapLegacyStrategy as L } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
7
- import { DATA_ATTRIBUTES as T } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
8
- import { parsePageList as R } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
9
- import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
10
- import { useEditorStore as z } from "../stores/editor.js";
11
- import { useUnsubscribeStore as O } from "../stores/unsubscribe.js";
12
- import { isPlainObject as _ } from "./genericUtil.js";
13
- import { assignTrackingIds as v } from "./linkTrackingIds.js";
14
- function M(l) {
15
- const i = new DOMParser().parseFromString(l, "text/html").querySelectorAll(`[${T.PAGE_LIST}]`), t = [];
16
- return i.forEach((c) => {
17
- const o = c.getAttribute(T.PAGE_LIST);
18
- o && t.push(...R(o));
1
+ import { useActionsApi as R } from "../composables/useActionsApi.js";
2
+ import { useConfig as k } from "../composables/useConfig.js";
3
+ import { useHtmlCompiler as N } from "../composables/useHtmlCompiler.js";
4
+ import { RRS_CONFIG_VERSION as U, DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as n } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
5
+ import { useRecommendationExtensionStore as I } from "../extensions/Blocks/Recommendation/store/recommendation.js";
6
+ import { mapLegacyStrategy as x } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
7
+ import { DATA_ATTRIBUTES as A } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
8
+ import { parsePageList as L } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
9
+ import { useDynamicContentStore as z } from "../stores/dynamic-content.js";
10
+ import { useEditorStore as O } from "../stores/editor.js";
11
+ import { useUnsubscribeStore as _ } from "../stores/unsubscribe.js";
12
+ import { isPlainObject as v } from "./genericUtil.js";
13
+ import { assignTrackingIds as B } from "./linkTrackingIds.js";
14
+ function G(l) {
15
+ const i = new DOMParser().parseFromString(l, "text/html").querySelectorAll(`[${A.PAGE_LIST}]`), t = [];
16
+ return i.forEach((s) => {
17
+ const r = s.getAttribute(A.PAGE_LIST);
18
+ r && t.push(...L(r));
19
19
  }), [...new Set(t)];
20
20
  }
21
- async function q(l) {
21
+ async function M(l) {
22
22
  const a = new DOMParser().parseFromString(l, "text/html").querySelectorAll(".recommendation-block-v2");
23
23
  if (a.length === 0)
24
24
  return;
25
- const i = A();
25
+ const i = I();
26
26
  a.forEach((t) => {
27
- var r, d, g, f, s, y;
28
- const c = t.getAttribute("recommendation-id"), o = c ? Number(c) : NaN;
29
- if (!Number.isFinite(o))
27
+ var d, g, f, c, y, S;
28
+ const s = t.getAttribute("recommendation-id"), r = s ? Number(s) : NaN;
29
+ if (!Number.isFinite(r))
30
30
  return;
31
31
  const p = t.getAttribute("esd-ext-config");
32
32
  if (!p)
@@ -37,13 +37,13 @@ async function q(l) {
37
37
  } catch {
38
38
  return;
39
39
  }
40
- if (!_(e))
40
+ if (!v(e))
41
41
  return;
42
- const b = {
42
+ const C = !!e.strategyId || (e.configVersion ?? 0) >= U, o = {
43
43
  // Normalize legacy strategy keys (e.g. `mostViewed` → `mostPopular`) so
44
44
  // already-saved blocks that never re-run the migrator don't emit a
45
45
  // strategy-less campaign URL. `||` also catches '' / undefined (SD-144882).
46
- strategy: L(e.strategy) || n.strategy,
46
+ strategy: x(e.strategy) || (C ? "" : n.strategy),
47
47
  strategyId: e.strategyId ?? n.strategyId,
48
48
  language: e.language ?? n.language,
49
49
  size: e.size ?? n.size,
@@ -52,14 +52,14 @@ async function q(l) {
52
52
  productIds: e.productIds ?? [...n.productIds],
53
53
  filters: e.filters ?? [...n.filters],
54
54
  shuffleProducts: e.shuffleProducts ?? n.shuffleProducts,
55
- currencyCode: ((r = e.currency) == null ? void 0 : r.code) ?? m.code,
56
- currencySymbol: ((d = e.currency) == null ? void 0 : d.symbol) ?? m.symbol,
57
- currencyAlignment: ((g = e.currency) == null ? void 0 : g.alignment) ?? m.alignment,
58
- currencyDecimalCount: ((f = e.currency) == null ? void 0 : f.decimalCount) ?? m.decimalCount,
59
- currencyDecimalSeparator: ((s = e.currency) == null ? void 0 : s.decimalSeparator) ?? m.decimalSeparator,
60
- currencyThousandSeparator: ((y = e.currency) == null ? void 0 : y.thousandSeparator) ?? m.thousandSeparator
55
+ currencyCode: ((d = e.currency) == null ? void 0 : d.code) ?? m.code,
56
+ currencySymbol: ((g = e.currency) == null ? void 0 : g.symbol) ?? m.symbol,
57
+ currencyAlignment: ((f = e.currency) == null ? void 0 : f.alignment) ?? m.alignment,
58
+ currencyDecimalCount: ((c = e.currency) == null ? void 0 : c.decimalCount) ?? m.decimalCount,
59
+ currencyDecimalSeparator: ((y = e.currency) == null ? void 0 : y.decimalSeparator) ?? m.decimalSeparator,
60
+ currencyThousandSeparator: ((S = e.currency) == null ? void 0 : S.thousandSeparator) ?? m.thousandSeparator
61
61
  };
62
- i.seedBlockUrlConfig(o, b);
62
+ i.seedBlockUrlConfig(r, o);
63
63
  });
64
64
  try {
65
65
  await i.fetchRecommendationCreateData();
@@ -70,51 +70,51 @@ async function q(l) {
70
70
  );
71
71
  }
72
72
  }
73
- const te = () => {
74
- const l = N(), u = z(), a = O(), { getCompiledEmail: i, getTemplateData: t, updateHtmlAndCss: c } = k(), { compileHtml: o, compileAmpHtml: p } = x(), { isFeatureEnabled: e } = U();
73
+ const re = () => {
74
+ const l = z(), u = O(), a = _(), { getCompiledEmail: i, getTemplateData: t, updateHtmlAndCss: s } = R(), { compileHtml: r, compileAmpHtml: p } = N(), { isFeatureEnabled: e } = k();
75
75
  return {
76
76
  prepareTemplateDetails: async () => {
77
- let { html: r, css: d, syncModulesIds: g = [] } = await t();
77
+ let { html: o, css: d, syncModulesIds: g = [] } = await t();
78
78
  if (e("linkTrackingIds"))
79
79
  try {
80
- const { html: h, changed: F, nextSeq: H } = v(r, u.trackIdSessionFloor);
81
- u.trackIdSessionFloor = H, F && (r = h, await c(h, d));
82
- } catch (h) {
83
- console.error("Tracking-id step failed, saving anyway:", h);
80
+ const { html: b, changed: F, nextSeq: H } = B(o, u.trackIdSessionFloor);
81
+ u.trackIdSessionFloor = H, F && (o = b, await s(b, d));
82
+ } catch (b) {
83
+ console.error("Tracking-id step failed, saving anyway:", b);
84
84
  }
85
- const { html: f, ampHtml: s = "", ampErrors: y = [] } = await i({
85
+ const { html: f, ampHtml: c = "", ampErrors: y = [] } = await i({
86
86
  minimize: !0,
87
87
  resetDataSavedFlag: !1
88
88
  });
89
- a.selectedUnsubscribePages.length && await a.fetchTemplates(), await q(r);
90
- const { compiledHtml: I, stats: S, appliedRules: w } = o(f), D = s && p(s).compiledHtml, P = l.getSelectedDynamicContentList, E = A(), C = M(r);
89
+ a.selectedUnsubscribePages.length && await a.fetchTemplates(), await M(o);
90
+ const { compiledHtml: S, stats: h, appliedRules: w } = r(f), D = c && p(c).compiledHtml, E = l.getSelectedDynamicContentList, P = I(), T = G(o);
91
91
  return console.debug("HTML Compilation Stats:", {
92
- originalSize: S.originalSize,
93
- compiledSize: S.compiledSize,
94
- reduction: `${S.reductionPercentage.toFixed(2)}%`,
92
+ originalSize: h.originalSize,
93
+ compiledSize: h.compiledSize,
94
+ reduction: `${h.reductionPercentage.toFixed(2)}%`,
95
95
  appliedRules: w,
96
- executionTime: `${S.executionTime.toFixed(2)}ms`
96
+ executionTime: `${h.executionTime.toFixed(2)}ms`
97
97
  }), {
98
- dynamicContentList: P,
99
- compiledHtml: I,
100
- rawHtml: r,
98
+ dynamicContentList: E,
99
+ compiledHtml: S,
100
+ rawHtml: o,
101
101
  css: d,
102
102
  ampHtml: D,
103
103
  ampErrors: y,
104
104
  modules: g.map(Number),
105
105
  recommendation: {
106
- campaignUrls: E.recommendationCampaignUrls,
106
+ campaignUrls: P.recommendationCampaignUrls,
107
107
  configs: {}
108
108
  },
109
109
  unsubscribe: {
110
- status: C.length > 0,
111
- config: C
110
+ status: T.length > 0,
111
+ config: T
112
112
  }
113
113
  };
114
114
  }
115
115
  };
116
116
  };
117
117
  export {
118
- M as getHtmlReferencedUnsubscribePages,
119
- te as useTemplatePreparation
118
+ G as getHtmlReferencedUnsubscribePages,
119
+ re as useTemplatePreparation
120
120
  };
@@ -1,9 +1,19 @@
1
- const a = (t) => String(t).padStart(2, "0"), g = (t, e) => t.getFullYear() === e.getFullYear() && t.getMonth() === e.getMonth() && t.getDate() === e.getDate(), i = (t, e = /* @__PURE__ */ new Date()) => ({
2
- isToday: g(t, e),
3
- time: `${a(t.getHours())}:${a(t.getMinutes())}`,
4
- // Locale-aware order (US reads MM/DD/YYYY, TR reads DD.MM.YYYY) — mirrors formatLocalTime's Intl use.
5
- date: t.toLocaleDateString([], { day: "2-digit", month: "2-digit", year: "numeric" })
6
- });
1
+ const r = (t) => {
2
+ const e = -t.getTimezoneOffset(), o = e >= 0 ? "+" : "-", n = Math.abs(e), s = Math.floor(n / 60), i = n % 60;
3
+ return i === 0 ? `UTC${o}${s}` : `UTC${o}${s}:${String(i).padStart(2, "0")}`;
4
+ }, a = () => {
5
+ var e;
6
+ const { timeZone: t } = new Intl.DateTimeFormat().resolvedOptions();
7
+ return ((e = t.split("/").pop()) == null ? void 0 : e.replace(/_/g, " ")) ?? t;
8
+ }, c = (t, e = !1) => {
9
+ const o = t.toLocaleTimeString([], {
10
+ hour: "2-digit",
11
+ hour12: !1,
12
+ minute: "2-digit",
13
+ second: "2-digit"
14
+ });
15
+ return e ? `${o} (${r(t)} ${a()})` : o;
16
+ };
7
17
  export {
8
- i as autoSaveTimestamp
18
+ c as formatLocalTime
9
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.18.2-beta.9be830c",
3
+ "version": "3.18.2-beta.a5a0a11",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -77,7 +77,7 @@
77
77
  "@typescript-eslint/parser": "7.18.0",
78
78
  "@useinsider/eslint-config": "1.5.3",
79
79
  "@vitejs/plugin-vue2": "2.3.1",
80
- "@vitest/coverage-v8": "2.1.9",
80
+ "@vitest/coverage-v8": "4.1.11",
81
81
  "eslint": "8.57.1",
82
82
  "eslint-config-airbnb-base": "15.0.0",
83
83
  "eslint-config-airbnb-typescript": "18.0.0",
@@ -90,17 +90,17 @@
90
90
  "happy-dom": "15.11.7",
91
91
  "husky": "9.1.7",
92
92
  "msw": "2.10.3",
93
- "nyc": "17.1.0",
93
+ "nyc": "18.0.0",
94
94
  "sass": "1.69.7",
95
95
  "typescript": "5.5.4",
96
96
  "typescript-eslint": "8.26.0",
97
97
  "vite-plugin-dts": "4.5.4",
98
98
  "vite-plugin-istanbul": "7.0.0",
99
- "vitest": "2.1.9",
99
+ "vitest": "4.1.11",
100
100
  "vue-tsc": "2.2.10"
101
101
  },
102
102
  "overrides": {
103
- "axios": "1.8.2",
103
+ "axios": "1.20.0",
104
104
  "flatted": "3.4.2",
105
105
  "micromatch": "4.0.8",
106
106
  "path-to-regexp": "6.3.0"
@@ -1,17 +0,0 @@
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
- };
@@ -1,27 +0,0 @@
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
- // Stripped like the other two: copy that emits {boldEnd} before {boldStart} leaves a
16
- // stray marker in this slice, which is exactly the leak the guard above prevents.
17
- before: s(e.slice(0, r)),
18
- word: s(e.slice(r + t.length, d)),
19
- after: s(e.slice(d + o.length))
20
- };
21
- });
22
- return { __sfc: !0, isFeatureEnabled: u, autosaveStore: a, trans: n, BOLD_START: t, BOLD_END: o, stripMarkers: s, savedLabel: _, AUTOSAVE_STATUS: m, InLoading: D };
23
- }
24
- });
25
- export {
26
- j as default
27
- };
@@ -1,20 +0,0 @@
1
- import i from "./EditorActionsMenu.vue2.js";
2
- /* empty css */
3
- import a from "../../../_virtual/_plugin-vue2_normalizer.js";
4
- var o = function() {
5
- var s = this, e = s._self._c, t = s._self._setupProxy;
6
- return e("div", { ref: "root", staticClass: "editor-actions-menu p-r" }, [e(t.InButtonV2, { attrs: { id: "guido__kebab-button", "data-testid": "Editor Actions Menu", "left-icon": "line-more-vertical", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.loadingStatus, "label-text-status": !1, "selected-status": t.isPanelOpen, "tooltip-options": t.getTooltipOptions("guido__kebab-button"), "tooltip-text": t.trans("email-editor.more-actions") }, on: { click: function(l) {
7
- t.isOpen = !t.isOpen;
8
- } } }), t.isPanelOpen ? e("div", { staticClass: "editor-actions-menu__panel p-a" }, [t.isAutosaveVisible ? [e("p", { staticClass: "editor-actions-menu__section f-s-1 t-c-53" }, [s._v(" " + s._s(t.trans("email-editor.preferences")) + " ")]), e("div", { staticClass: "editor-actions-menu__row editor-actions-menu__row_static d-f a-i-c j-c-s-b", attrs: { id: "guido__kebab-autosave" } }, [e("span", { staticClass: "f-s-2" }, [s._v(s._s(t.trans("email-editor.auto-save")))]), e(t.InToggle, { attrs: { id: "guido__kebab-autosave-toggle", name: "guido-kebab-autosave-toggle", checked: t.autosaveStore.isOn, disable: t.editorStore.loadingStatus }, on: { click: t.toggleAutosave } })], 1), e("div", { staticClass: "editor-actions-menu__divider" })] : s._e(), e("p", { staticClass: "editor-actions-menu__section f-s-1 t-c-53" }, [s._v(" " + s._s(t.trans("email-editor.actions")) + " ")]), t.isVersionHistoryVisible ? e("button", { staticClass: "editor-actions-menu__row d-f a-i-c", attrs: { id: "guido__kebab-version-history", type: "button", disabled: t.editorStore.isVersionHistoryButtonDisabled }, on: { click: t.handleVersionHistory } }, [e(t.InIcons, { staticClass: "mr-2 editor-actions-menu__icon", attrs: { name: "line-architect-version-history", size: "24" } }), e("span", { staticClass: "f-s-2" }, [s._v(s._s(t.trans("newsletter.version-history")))])], 1) : s._e(), t.isAccessibilityVisible ? e("button", { staticClass: "editor-actions-menu__row d-f a-i-c", attrs: { id: "guido__kebab-accessibility", type: "button", disabled: t.editorStore.loadingStatus }, on: { click: t.handleAccessibility } }, [e(t.InIcons, { staticClass: "mr-2 editor-actions-menu__icon", attrs: { name: "line-accessibility", size: "24" } }), e("span", { staticClass: "f-s-2" }, [s._v(s._s(t.trans("email-editor.accessibility-test")))])], 1) : s._e(), t.isSaveAsVisible ? e("button", { staticClass: "editor-actions-menu__row d-f a-i-c", attrs: { id: "guido__kebab-save-as", type: "button", disabled: t.editorStore.isSaveAsButtonDisabled }, on: { click: t.handleSaveAs } }, [e(t.InIcons, { staticClass: "mr-2 editor-actions-menu__icon", attrs: { name: "line-newsletter-save-as-template", size: "24" } }), e("span", { staticClass: "f-s-2" }, [s._v(s._s(t.trans("newsletter.save-templates")))])], 1) : s._e(), e("button", { staticClass: "editor-actions-menu__row d-f a-i-c", attrs: { id: "guido__kebab-export", type: "button", disabled: t.isExporting || t.editorStore.isExportButtonDisabled }, on: { click: t.handleExport } }, [e(t.InIcons, { staticClass: "mr-2 editor-actions-menu__icon", attrs: { name: "line-export", size: "24" } }), e("span", { staticClass: "f-s-2" }, [s._v(s._s(t.trans("email-editor.export-html")))])], 1)], 2) : s._e()], 1);
9
- }, n = [], r = /* @__PURE__ */ a(
10
- i,
11
- o,
12
- n,
13
- !1,
14
- null,
15
- "abe82925"
16
- );
17
- const b = r.exports;
18
- export {
19
- b as default
20
- };
@@ -1,48 +0,0 @@
1
- import { defineComponent as h, ref as p, computed as i, watch as w } from "vue";
2
- import { useAccessibilityApi as x } from "../../../composables/useAccessibilityApi.js";
3
- import { useConfig as P } from "../../../composables/useConfig.js";
4
- import { useExport as I } from "../../../composables/useExport.js";
5
- import { useTranslations as B } from "../../../composables/useTranslations.js";
6
- import { useVersionHistoryApi as C } from "../../../composables/useVersionHistoryApi.js";
7
- import { useAutosaveStore as k } from "../../../stores/autosave.js";
8
- import { useEditorStore as D } from "../../../stores/editor.js";
9
- import { useOnboardingStore as F } from "../../../stores/onboarding.js";
10
- import { getTooltipOptions as j } from "../../../utils/tooltipUtils.js";
11
- import { InToggle as q, InIcons as z, InButtonV2 as G } from "@useinsider/design-system-vue";
12
- import { onClickOutside as J } from "../../../node_modules/@vueuse/core/index.js";
13
- const so = /* @__PURE__ */ h({
14
- __name: "EditorActionsMenu",
15
- setup(K) {
16
- const { config: n, isFeatureEnabled: r } = P(), { exportHtml: u } = I(), { openVersionHistory: m, closeVersionHistory: f } = C(), { toggleAccessibilityTestingMode: d } = x(), s = D(), v = k(), a = F(), g = B(), c = p(!1), y = i(() => c.value || a.isEditorActionsMenuPinned), l = p(!1), A = p(null), b = i(() => r("autosave")), V = i(
17
- () => {
18
- var o, t;
19
- return !!((t = (o = n.value) == null ? void 0 : o.features) != null && t.versionHistory) && !s.isPreviewModeOpen;
20
- }
21
- ), O = i(
22
- () => r("accessibilityTesting") && !s.isPreviewModeOpen
23
- ), S = i(() => {
24
- var o, t;
25
- return !!((t = (o = n.value) == null ? void 0 : o.features) != null && t.saveAsTemplate);
26
- }), e = () => {
27
- c.value = !1;
28
- };
29
- w(() => a.isEditorActionsMenuPinned, (o) => {
30
- o || e();
31
- });
32
- const E = () => {
33
- s.isVersionHistoryOpen ? f() : m(), e();
34
- }, H = () => {
35
- d(), e();
36
- }, _ = () => {
37
- s.isSaveAsTemplateDrawerOpen = !0, e();
38
- }, T = async () => {
39
- l.value = !0, await u(), l.value = !1, e();
40
- }, M = (o) => {
41
- v.isOn = o;
42
- };
43
- return J(A, e), { __sfc: !0, config: n, isFeatureEnabled: r, exportHtml: u, openVersionHistory: m, closeVersionHistory: f, toggleAccessibilityTestingMode: d, editorStore: s, autosaveStore: v, onboardingStore: a, trans: g, isOpen: c, isPanelOpen: y, isExporting: l, root: A, isAutosaveVisible: b, isVersionHistoryVisible: V, isAccessibilityVisible: O, isSaveAsVisible: S, close: e, handleVersionHistory: E, handleAccessibility: H, handleSaveAs: _, handleExport: T, toggleAutosave: M, getTooltipOptions: j, InButtonV2: G, InIcons: z, InToggle: q };
44
- }
45
- });
46
- export {
47
- so as default
48
- };
@@ -1,18 +0,0 @@
1
- import i from "./AccessibilityToolbar.vue2.js";
2
- /* empty css */
3
- import s from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
- var a = function() {
5
- var o = this, e = o._self._c, t = o._self._setupProxy;
6
- return e("div", { staticClass: "d-f a-i-c accessibility-toolbar" }, [e(t.InButtonV2, { attrs: { id: "guido__a11y-no-images", "data-testid": "Accessibility No Images", "left-icon": "line-image", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.loadingStatus, "label-text-status": !1, "selected-status": t.editorStore.imagesHidden, "tooltip-options": t.getTooltipOptions("guido__a11y-no-images"), "tooltip-text": t.imagesTooltip }, on: { click: t.toggleImages } }), e(t.InButtonV2, { attrs: { id: "guido__a11y-code", "data-testid": "Accessibility Code Editor", "left-icon": "line-code", styling: "ghost", type: "secondary", "disabled-status": t.editorStore.loadingStatus, "label-text-status": !1, "selected-status": t.editorStore.isCodeEditorOpen, "tooltip-options": t.getTooltipOptions("guido__a11y-code"), "tooltip-text": t.trans("newsletter.html-editor") }, on: { click: t.toggleCodeEditor } }), e(t.ColorVisionSelect), e(t.InSegments, { attrs: { id: "guido__a11y-view-selection", "with-icon": "", "segment-list": t.segmentList, selected: t.editorStore.editorVisualMode }, on: { click: t.handleView } })], 1);
7
- }, l = [], d = /* @__PURE__ */ s(
8
- i,
9
- a,
10
- l,
11
- !1,
12
- null,
13
- "a5b9b5d5"
14
- );
15
- const _ = d.exports;
16
- export {
17
- _ as default
18
- };
@@ -1,37 +0,0 @@
1
- import { defineComponent as d, computed as n } from "vue";
2
- import { useAccessibilityApi as c } from "../../../../composables/useAccessibilityApi.js";
3
- import { useTranslations as g } from "../../../../composables/useTranslations.js";
4
- import { useEditorStore as u } from "../../../../stores/editor.js";
5
- import { getTooltipOptions as e } from "../../../../utils/tooltipUtils.js";
6
- import { InSegments as _, InButtonV2 as f } from "@useinsider/design-system-vue";
7
- import w from "./ColorVisionSelect.vue.js";
8
- const A = /* @__PURE__ */ d({
9
- __name: "AccessibilityToolbar",
10
- setup(b) {
11
- const t = u(), o = g(), {
12
- toggleImages: r,
13
- toggleCodeEditor: m,
14
- switchToDesktopPreview: i,
15
- switchToMobilePreview: s
16
- } = c(), l = n(() => [
17
- {
18
- text: "",
19
- icon: "line-desktop",
20
- value: "desktop",
21
- tooltipText: o("newsletter.desktop"),
22
- tooltipOptions: e("guido__a11y-view-desktop")
23
- },
24
- {
25
- text: "",
26
- icon: "line-menu-mobileapp",
27
- value: "mobile",
28
- tooltipText: o("newsletter.mobile"),
29
- tooltipOptions: e("guido__a11y-view-mobile")
30
- }
31
- ]), p = n(() => t.imagesHidden ? o("email-editor.a11y-show-images") : o("email-editor.a11y-hide-images"));
32
- return { __sfc: !0, editorStore: t, trans: o, toggleImages: r, toggleCodeEditor: m, switchToDesktopPreview: i, switchToMobilePreview: s, segmentList: l, imagesTooltip: p, handleView: (a) => a === "mobile" ? s() : i(), getTooltipOptions: e, InButtonV2: f, InSegments: _, ColorVisionSelect: w };
33
- }
34
- });
35
- export {
36
- A as default
37
- };
@@ -1,24 +0,0 @@
1
- import n from "./ColorVisionSelect.vue2.js";
2
- /* empty css */
3
- import i from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
- var l = function() {
5
- var t = this, o = t._self._c, e = t._self._setupProxy;
6
- return o("div", { ref: "root", staticClass: "color-vision-select p-r" }, [o(e.InButtonV2, { attrs: { id: "guido__a11y-color-vision-trigger", "left-icon": "line-show-on", "right-icon": "line-chevron-small-down", type: "secondary", "disabled-status": e.editorStore.loadingStatus, "label-text": e.selectedLabel }, on: { click: function(s) {
7
- e.isOpen = !e.isOpen;
8
- } } }), e.isOpen ? o("div", { staticClass: "color-vision-select__menu p-a" }, t._l(e.OPTIONS, function(s) {
9
- return o("button", { key: s.value || "none", staticClass: "color-vision-select__option d-f f-d-c", class: { "color-vision-select__option_selected": s.value === e.editorStore.colorVisionDeficiency }, attrs: { type: "button" }, on: { click: function(_) {
10
- return e.select(s.value);
11
- } } }, [o("span", { staticClass: "color-vision-select__option-label f-s-2" }, [t._v(t._s(e.trans(s.labelKey)))]), s.descriptionKey ? o("span", { staticClass: "color-vision-select__option-description f-s-1 t-c-53" }, [t._v(" " + t._s(e.trans(s.descriptionKey)) + " ")]) : t._e()]);
12
- }), 0) : t._e()], 1);
13
- }, r = [], c = /* @__PURE__ */ i(
14
- n,
15
- l,
16
- r,
17
- !1,
18
- null,
19
- "869e2871"
20
- );
21
- const f = c.exports;
22
- export {
23
- f as default
24
- };