@useinsider/guido 3.19.0-beta.80b64cf → 3.19.0-beta.84c97db

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 (110) hide show
  1. package/dist/@types/config/schemas.js +9 -8
  2. package/dist/components/Guido.vue.js +8 -8
  3. package/dist/components/Guido.vue2.js +104 -86
  4. package/dist/components/organisms/AutoSaveController.vue2.js +18 -8
  5. package/dist/components/organisms/base/AuthErrorModal.vue.js +18 -0
  6. package/dist/components/organisms/base/AuthErrorModal.vue2.js +42 -0
  7. package/dist/components/organisms/header/AutoSaveStatus.vue.js +17 -0
  8. package/dist/components/organisms/header/AutoSaveStatus.vue2.js +25 -0
  9. package/dist/components/organisms/header/EditorActions.vue.js +13 -13
  10. package/dist/components/organisms/header/EditorActions.vue2.js +37 -52
  11. package/dist/components/organisms/header/EditorActionsMenu.vue.js +20 -0
  12. package/dist/components/organisms/header/EditorActionsMenu.vue2.js +98 -0
  13. package/dist/components/organisms/header/HeaderWrapper.vue.js +6 -6
  14. package/dist/components/organisms/header/HeaderWrapper.vue2.js +9 -17
  15. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  16. package/dist/components/organisms/header/LeftSlot.vue2.js +32 -23
  17. package/dist/components/organisms/header/MiddleSlot.vue.js +4 -4
  18. package/dist/components/organisms/header/MiddleSlot.vue2.js +8 -7
  19. package/dist/components/organisms/header/RightSlot.vue.js +9 -8
  20. package/dist/components/organisms/header/RightSlot.vue2.js +13 -18
  21. package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue.js +18 -0
  22. package/dist/components/organisms/header/accessibility/AccessibilityToolbar.vue2.js +37 -0
  23. package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue.js +22 -0
  24. package/dist/components/organisms/header/accessibility/ColorVisionSelect.vue2.js +48 -0
  25. package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue.js +19 -0
  26. package/dist/components/organisms/onboarding/EditorTabBarOnboarding.vue2.js +90 -0
  27. package/dist/components/organisms/onboarding/OnboardingWrapper.vue.js +12 -12
  28. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +56 -38
  29. package/dist/components/wrappers/WpModal.vue.js +1 -1
  30. package/dist/components/wrappers/WpModal.vue2.js +4 -3
  31. package/dist/composables/useAccessibilityApi.js +45 -0
  32. package/dist/composables/useAuthError.js +52 -0
  33. package/dist/composables/useAutoSave.js +11 -11
  34. package/dist/composables/useCortexBlueprintBridge.js +122 -54
  35. package/dist/composables/useCustomInterfaceAppearance.js +42 -41
  36. package/dist/composables/useEmailTemplateApplier.js +111 -50
  37. package/dist/composables/useHttp.js +64 -54
  38. package/dist/composables/useLegacyStrategyConversion.js +23 -19
  39. package/dist/composables/useStripo.js +24 -20
  40. package/dist/composables/useToaster.js +17 -15
  41. package/dist/composables/validators/useLiquidValidator.js +15 -15
  42. package/dist/config/i18n/en/labels.json.js +36 -4
  43. package/dist/config/i18n/en/tooltips.json.js +2 -1
  44. package/dist/config/migrator/index.js +14 -13
  45. package/dist/config/migrator/itemsBlockMigrator.js +236 -248
  46. package/dist/config/migrator/recommendationMigrator.js +28 -21
  47. package/dist/config/migrator/recommendationPartnerMigrator.js +56 -0
  48. package/dist/enums/extensions/recommendationBlock.js +30 -29
  49. package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
  50. package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
  51. package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
  52. package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
  53. package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
  54. package/dist/extensions/Blocks/Items/template.js +219 -204
  55. package/dist/extensions/Blocks/Recommendation/block.js +54 -88
  56. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +32 -51
  57. package/dist/extensions/Blocks/Recommendation/utils/partnerScope.js +11 -12
  58. package/dist/guido.css +1 -1
  59. package/dist/sprite.svg +10 -0
  60. package/dist/src/@types/config/schemas.d.ts +2 -0
  61. package/dist/src/components/organisms/AutoSaveController.vue.d.ts +3 -1
  62. package/dist/src/components/organisms/header/AutoSaveStatus.vue.d.ts +2 -0
  63. package/dist/src/components/organisms/header/EditorActionsMenu.vue.d.ts +2 -0
  64. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -3
  65. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -3
  66. package/dist/src/components/organisms/header/accessibility/AccessibilityToolbar.vue.d.ts +2 -0
  67. package/dist/src/components/organisms/header/accessibility/ColorVisionSelect.vue.d.ts +2 -0
  68. package/dist/src/components/organisms/onboarding/EditorTabBarOnboarding.vue.d.ts +2 -0
  69. package/dist/src/components/wrappers/WpModal.vue.d.ts +5 -1
  70. package/dist/src/composables/useAccessibilityApi.d.ts +13 -0
  71. package/dist/src/composables/useActionsApi.d.ts +2 -2
  72. package/dist/src/composables/useAuthError.d.ts +12 -0
  73. package/dist/src/composables/useConfig.d.ts +2 -0
  74. package/dist/src/composables/useCortexBlueprintBridge.d.ts +2 -3
  75. package/dist/src/composables/useEmailTemplateApplier.d.ts +18 -5
  76. package/dist/src/composables/useGuidoActions.d.ts +2 -0
  77. package/dist/src/composables/useHttp.d.ts +2 -0
  78. package/dist/src/config/migrator/index.d.ts +2 -1
  79. package/dist/src/config/migrator/recommendationPartnerMigrator.d.ts +19 -0
  80. package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -1
  81. package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
  82. package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
  83. package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
  84. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -6
  85. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -5
  86. package/dist/src/extensions/Blocks/Recommendation/utils/partnerScope.d.ts +13 -7
  87. package/dist/src/mock/cortexChatStore.d.ts +12 -0
  88. package/dist/src/stores/autosave.d.ts +73 -1
  89. package/dist/src/stores/config.d.ts +20 -0
  90. package/dist/src/stores/editor.d.ts +109 -0
  91. package/dist/src/stores/guido-email-editor.d.ts +20 -10
  92. package/dist/src/stores/onboarding.d.ts +956 -21
  93. package/dist/src/stores/recommendation.d.ts +5 -0
  94. package/dist/src/stores/version-history.d.ts +1 -1
  95. package/dist/src/utils/dateUtil.d.ts +10 -0
  96. package/dist/src/utils/genericUtil.d.ts +3 -0
  97. package/dist/src/utils/timeUtil.d.ts +5 -0
  98. package/dist/static/styles/components/accessibility.css.js +234 -0
  99. package/dist/static/styles/components/version-history.css.js +2 -6
  100. package/dist/static/styles/variables.css.js +2 -0
  101. package/dist/stores/autosave.js +12 -7
  102. package/dist/stores/editor.js +7 -4
  103. package/dist/stores/guido-email-editor.js +3 -1
  104. package/dist/stores/onboarding.js +47 -21
  105. package/dist/utils/pairProductVariables.js +71 -71
  106. package/dist/utils/timeUtil.js +6 -17
  107. package/package.json +2 -1
  108. package/dist/components/organisms/header/AutoSaveToggle.vue.js +0 -22
  109. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +0 -19
  110. /package/dist/src/components/organisms/{header/AutoSaveToggle.vue.d.ts → base/AuthErrorModal.vue.d.ts} +0 -0
@@ -1,44 +1,44 @@
1
1
  import p from "../static/assets/icons/filled-arrow-rising.svg.js";
2
2
  import s from "../static/assets/icons/line-change.svg.js";
3
- import a from "../static/assets/icons/line-delete.svg.js";
4
- import f from "../static/assets/icons/line-info.svg.js";
3
+ import f from "../static/assets/icons/line-delete.svg.js";
4
+ import a from "../static/assets/icons/line-info.svg.js";
5
5
  import c from "../static/assets/icons/line-plus.svg.js";
6
6
  import l from "../static/styles/base.css.js";
7
- import C from "../static/styles/components/alert-message.css.js";
8
- import d from "../static/styles/components/amp-block.css.js";
9
- import u from "../static/styles/components/base-input.css.js";
10
- import h from "../static/styles/components/button-group.css.js";
11
- import I from "../static/styles/components/button.css.js";
12
- import g from "../static/styles/components/combobox.css.js";
13
- import w from "../static/styles/components/counter.css.js";
14
- import y from "../static/styles/components/dropdown-menu.css.js";
15
- import A from "../static/styles/components/loader.css.js";
16
- import $ from "../static/styles/components/narrow-panel.css.js";
17
- import b from "../static/styles/components/popup.css.js";
18
- import B from "../static/styles/components/recommendation-strategy.css.js";
19
- import D from "../static/styles/components/skeleton.css.js";
20
- import R from "../static/styles/components/switcher.css.js";
21
- import P from "../static/styles/components/tabs.css.js";
22
- import T from "../static/styles/components/tools.css.js";
23
- import x from "../static/styles/components/version-history.css.js";
24
- import M from "../static/styles/components/wide-panel.css.js";
25
- import O from "../static/styles/variables.css.js";
7
+ import C from "../static/styles/components/accessibility.css.js";
8
+ import d from "../static/styles/components/alert-message.css.js";
9
+ import u from "../static/styles/components/amp-block.css.js";
10
+ import h from "../static/styles/components/base-input.css.js";
11
+ import I from "../static/styles/components/button-group.css.js";
12
+ import g from "../static/styles/components/button.css.js";
13
+ import w from "../static/styles/components/combobox.css.js";
14
+ import y from "../static/styles/components/counter.css.js";
15
+ import A from "../static/styles/components/dropdown-menu.css.js";
16
+ import $ from "../static/styles/components/loader.css.js";
17
+ import b from "../static/styles/components/narrow-panel.css.js";
18
+ import B from "../static/styles/components/popup.css.js";
19
+ import D from "../static/styles/components/recommendation-strategy.css.js";
20
+ import R from "../static/styles/components/skeleton.css.js";
21
+ import P from "../static/styles/components/switcher.css.js";
22
+ import T from "../static/styles/components/tabs.css.js";
23
+ import x from "../static/styles/components/tools.css.js";
24
+ import M from "../static/styles/components/version-history.css.js";
25
+ import O from "../static/styles/components/wide-panel.css.js";
26
+ import V from "../static/styles/variables.css.js";
26
27
  function o(i, r) {
27
28
  return `--guido-icon-${i}: url("data:image/svg+xml,${encodeURIComponent(r.trim())}");`;
28
29
  }
29
- const V = `:host {
30
+ const W = `:host {
30
31
  ${o("line-change", s)}
31
- ${o("line-delete", a)}
32
+ ${o("line-delete", f)}
32
33
  ${o("filled-arrow-rising", p)}
33
- ${o("line-info", f)}
34
+ ${o("line-info", a)}
34
35
  ${o("line-plus", c)}
35
- }`, W = [
36
- O,
37
- // Must be on top
36
+ }`, _ = [
38
37
  V,
38
+ // Must be on top
39
+ W,
39
40
  l,
40
41
  // Must be on top
41
- C,
42
42
  d,
43
43
  u,
44
44
  h,
@@ -49,33 +49,34 @@ const V = `:host {
49
49
  A,
50
50
  $,
51
51
  b,
52
- D,
52
+ B,
53
53
  R,
54
54
  P,
55
55
  T,
56
56
  x,
57
57
  M,
58
- B
59
- // Last: overrides button.css / wide-panel.css defaults
58
+ O,
59
+ D,
60
+ C
60
61
  ].join(`
61
62
 
62
- `), _ = 3e4;
63
+ `), k = 3e4;
63
64
  let e = null;
64
- function k() {
65
- return e || (e = new CSSStyleSheet(), e.replaceSync(W)), e;
65
+ function q() {
66
+ return e || (e = new CSSStyleSheet(), e.replaceSync(_)), e;
66
67
  }
67
- const po = () => ({ importCss: () => {
68
- const r = k(), S = Date.now() + _, n = () => {
69
- var m;
70
- const t = (m = document.querySelector("ui-editor")) == null ? void 0 : m.shadowRoot;
68
+ const fo = () => ({ importCss: () => {
69
+ const r = q(), S = Date.now() + k, m = () => {
70
+ var n;
71
+ const t = (n = document.querySelector("ui-editor")) == null ? void 0 : n.shadowRoot;
71
72
  if (t) {
72
73
  t.adoptedStyleSheets.includes(r) || (t.adoptedStyleSheets = [...t.adoptedStyleSheets, r]);
73
74
  return;
74
75
  }
75
- Date.now() < S && requestAnimationFrame(n);
76
+ Date.now() < S && requestAnimationFrame(m);
76
77
  };
77
- n();
78
+ m();
78
79
  } });
79
80
  export {
80
- po as useCustomInterfaceAppearance
81
+ fo as useCustomInterfaceAppearance
81
82
  };
@@ -1,59 +1,120 @@
1
- import { useActionsApi as C } from "./useActionsApi.js";
2
- import { useConfig as h } from "./useConfig.js";
3
- import { useToaster as D } from "./useToaster.js";
4
- import { useTranslations as E } from "./useTranslations.js";
5
- import { ToasterTypeOptions as f } from "../enums/toaster.js";
6
- import { useDynamicContentStore as A } from "../stores/dynamic-content.js";
7
- import { flattenDynamicContentList as w } from "../utils/genericUtil.js";
8
- import { extractUsedDynamicContent as S } from "../utils/registerUsedDynamicContent.js";
9
- import { ref as O } from "vue";
10
- const U = 250, o = O({}), s = {}, u = /* @__PURE__ */ new Map(), z = () => {
11
- const { updateHtmlAndCss: r } = C(), { showToaster: m } = D(), y = E(), { template: T } = h(), d = A(), g = (e, t) => {
12
- const a = y(e);
13
- return a === e ? t : a;
14
- }, v = (e) => {
15
- o.value[e] === void 0 && (o.value = { ...o.value, [e]: "pending" });
16
- }, l = (e, t, a) => {
17
- var c;
18
- o.value = { ...o.value, [e]: "applying" };
1
+ import { useActionsApi as x } from "./useActionsApi.js";
2
+ import { useConfig as N } from "./useConfig.js";
3
+ import { useEditorLock as K } from "./useEditorLock.js";
4
+ import { useToaster as R } from "./useToaster.js";
5
+ import { useTranslations as F } from "./useTranslations.js";
6
+ import { ToasterTypeOptions as v } from "../enums/toaster.js";
7
+ import { useDynamicContentStore as G } from "../stores/dynamic-content.js";
8
+ import { useEditorStore as $ } from "../stores/editor.js";
9
+ import { flattenDynamicContentList as j } from "../utils/genericUtil.js";
10
+ import { extractUsedDynamicContent as J } from "../utils/registerUsedDynamicContent.js";
11
+ import { ref as V, watch as W } from "vue";
12
+ const X = 250, U = 12e4, Y = 1e3, p = { status: "superseded" }, M = { status: "failed", error: new Error("Blueprint has no html to apply") }, a = V({}), A = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
13
+ let d = null;
14
+ const T = () => {
15
+ d && (clearInterval(d), d = null);
16
+ }, me = () => {
17
+ const { updateHtmlAndCss: i } = x(), { runExclusive: O } = K(), { showToaster: P } = R(), _ = F(), { template: b } = N(), L = G(), w = $(), g = (e, t) => {
19
18
  try {
20
- r(t, a).catch((n) => {
21
- console.warn("Editor did not acknowledge the template apply.", n);
22
- }), o.value = { ...o.value, [e]: "applied" };
23
- try {
24
- const n = w((c = T.value) == null ? void 0 : c.dynamicContentList), i = S(t, n);
25
- i.length > 0 && d.registerDynamicContent(i);
26
- } catch {
27
- }
28
- u.get(e) !== t && (u.set(e, t), m({
29
- type: f.Success,
30
- message: g("newsletter.ai-template-applied", "Template applied to the editor")
31
- }));
19
+ P({ type: e, message: _(t) });
20
+ } catch (o) {
21
+ console.error("[guido:apply] could not show the apply toast", o);
22
+ }
23
+ }, y = (e, t) => {
24
+ m.get(e) !== t && (m.set(e, t), g(v.Error, "newsletter.ai-template-failed-apply"));
25
+ }, h = () => {
26
+ var e, t;
27
+ return w.isStripoInitialized && typeof ((t = (e = window.StripoEditorApi) == null ? void 0 : e.actionsApi) == null ? void 0 : t.updateHtmlAndCss) == "function";
28
+ }, Q = (e) => {
29
+ a.value[e] === void 0 && (a.value = { ...a.value, [e]: "pending" });
30
+ }, l = (e, t) => {
31
+ a.value = { ...a.value, [e]: t };
32
+ }, H = (e) => {
33
+ var t;
34
+ try {
35
+ const o = j((t = b.value) == null ? void 0 : t.dynamicContentList), r = J(e, o);
36
+ r.length > 0 && L.registerDynamicContent(r);
37
+ } catch {
38
+ }
39
+ }, I = (e, t) => {
40
+ m.delete(e), A.get(e) !== t && (A.set(e, t), g(v.Success, "newsletter.ai-template-applied"));
41
+ }, C = async (e, t, o) => {
42
+ const r = (u.get(e) ?? 0) + 1;
43
+ u.set(e, r), l(e, "applying");
44
+ try {
45
+ await O(() => i(t, o));
32
46
  } catch (n) {
33
- o.value = { ...o.value, [e]: "failed" }, m({
34
- type: f.Error,
35
- message: n instanceof Error ? n.message : "Failed to apply template"
36
- });
47
+ return u.get(e) !== r ? p : (console.error("[guido:apply] editor did not acknowledge the template apply", n), l(e, "failed"), y(e, t), { status: "failed", error: n });
37
48
  }
38
- }, p = (e) => {
39
- const t = s[e];
40
- t && (clearTimeout(t), delete s[e]);
41
- };
42
- return { applyStatus: o, markPending: v, applyTemplate: (e, t) => {
43
- t.html && (p(e), l(e, t.html, t.css ?? ""));
44
- }, applyTemplateDebounced: (e, t) => {
45
- if (!t.html)
49
+ return u.get(e) !== r ? p : (l(e, "applied"), H(t), I(e, t), { status: "applied" });
50
+ }, z = (e) => {
51
+ const t = s.get(e);
52
+ t && (clearTimeout(t.timer), s.delete(e), t.settle(p));
53
+ }, D = (e) => {
54
+ const t = c.get(e);
55
+ t && (clearTimeout(t.timer), c.delete(e), t.settle(p));
56
+ }, B = () => {
57
+ [...c.keys()].forEach(D);
58
+ }, f = async () => {
59
+ if (s.size === 0) {
60
+ T();
46
61
  return;
47
- p(e);
48
- const { html: a } = t, c = t.css ?? "";
49
- s[e] = setTimeout(() => {
50
- delete s[e], l(e, a, c);
62
+ }
63
+ if (!h())
64
+ return;
65
+ T();
66
+ const e = [...s.entries()];
67
+ s.clear(), e.forEach(([, n]) => clearTimeout(n.timer));
68
+ const t = e.pop();
69
+ if (e.forEach(([n, E]) => {
70
+ l(n, "failed"), E.settle({ status: "failed", error: new Error("Displaced by a newer apply") });
71
+ }), !t)
72
+ return;
73
+ const [o, r] = t;
74
+ r.settle(await C(o, r.html, r.css));
75
+ }, q = (e, t, o) => new Promise((r) => {
76
+ z(e);
77
+ const n = setTimeout(() => {
78
+ s.delete(e), l(e, "failed"), y(e, t), r({
79
+ status: "failed",
80
+ error: new Error(`Editor did not become ready within ${U}ms`)
81
+ });
51
82
  }, U);
83
+ s.set(e, { html: t, css: o, timer: n, settle: r }), l(e, "applying"), d ?? (d = setInterval(() => {
84
+ f();
85
+ }, Y));
86
+ }), S = (e, t, o) => {
87
+ if (h() && s.size === 0)
88
+ return C(e, t, o);
89
+ const r = q(e, t, o);
90
+ return f(), r;
91
+ };
92
+ return W(() => w.isStripoInitialized, (e) => {
93
+ e && f();
94
+ }, { immediate: !0 }), { applyStatus: a, markPending: Q, applyTemplate: (e, t) => {
95
+ const { html: o } = t;
96
+ return o ? (B(), S(e, o, t.css ?? "")) : Promise.resolve(M);
97
+ }, applyTemplateDebounced: (e, t) => {
98
+ const { html: o } = t;
99
+ if (!o)
100
+ return Promise.resolve(M);
101
+ const r = t.css ?? "";
102
+ return new Promise((n) => {
103
+ D(e);
104
+ const E = setTimeout(() => {
105
+ c.delete(e), S(e, o, r).then(n);
106
+ }, X);
107
+ c.set(e, { timer: E, settle: n });
108
+ });
52
109
  } };
53
- }, G = () => {
54
- Object.values(s).forEach(clearTimeout), Object.keys(s).forEach((r) => delete s[r]), o.value = {};
110
+ }, de = () => {
111
+ c.forEach((i) => {
112
+ clearTimeout(i.timer), i.settle(p);
113
+ }), c.clear(), s.forEach((i) => {
114
+ clearTimeout(i.timer), i.settle(p);
115
+ }), s.clear(), T(), m.clear(), a.value = {};
55
116
  };
56
117
  export {
57
- G as resetEmailTemplateApplier,
58
- z as useEmailTemplateApplier
118
+ de as resetEmailTemplateApplier,
119
+ me as useEmailTemplateApplier
59
120
  };
@@ -1,88 +1,98 @@
1
- import { getCsrfToken as O } from "../utils/genericUtil.js";
2
- import { ref as m, computed as T } from "vue";
3
- const X = (b = {}) => {
4
- const p = m(!1), a = m(null), u = m(null), g = T(() => p.value), y = T(() => a.value !== null), v = {
1
+ import { getCsrfToken as D } from "../utils/genericUtil.js";
2
+ import { ref as T, computed as w } from "vue";
3
+ import { isPanelOrigin as j, reportAuthError as X } from "./useAuthError.js";
4
+ const k = [401, 403, 419], _ = (g = {}) => {
5
+ const f = T(!1), n = T(null), c = T(null), b = w(() => f.value), y = w(() => n.value !== null), E = {
5
6
  baseURL: "",
6
7
  timeout: 1e4,
7
8
  retry: 0,
8
9
  retryDelay: 1e3,
9
10
  headers: {
10
11
  "Content-Type": "application/json",
11
- "X-CSRF-TOKEN": O(),
12
+ "X-CSRF-TOKEN": D(),
12
13
  Accept: "application/json",
14
+ // Without this a guest fetch gets a 302 to the login page, never an auth status.
13
15
  "X-Requested-With": "XMLHttpRequest"
14
16
  },
15
- ...b
16
- }, w = (e, s) => {
17
+ ...g
18
+ }, x = (e, r) => {
17
19
  if (e.startsWith("http://") || e.startsWith("https://"))
18
20
  return e;
19
- const t = s || v.baseURL || "";
21
+ const t = r || E.baseURL || "";
20
22
  return t.endsWith("/") && e.startsWith("/") ? `${t}${e.slice(1)}` : t.endsWith("/") || e.startsWith("/") ? `${t}${e}` : `${t}/${e}`;
21
- }, P = (e) => new Promise((s, t) => {
23
+ }, R = (e) => new Promise((r, t) => {
22
24
  setTimeout(() => {
23
25
  t(new Error("Request timeout"));
24
26
  }, e);
25
- }), x = (e) => new Promise((s) => {
26
- setTimeout(s, e);
27
- }), i = async (e, s, t, L = {}) => {
28
- a.value = null, p.value = !0, u.value = new AbortController();
29
- const n = { ...v, ...L }, D = w(s, n.baseURL), c = {
27
+ }), P = (e) => new Promise((r) => {
28
+ setTimeout(r, e);
29
+ }), i = async (e, r, t, W = {}) => {
30
+ n.value = null, f.value = !0, c.value = new AbortController();
31
+ const a = { ...E, ...W }, p = x(r, a.baseURL), d = {
30
32
  method: e,
31
- headers: { ...n.headers },
32
- signal: u.value.signal,
33
- ...n
33
+ headers: { ...a.headers },
34
+ signal: c.value.signal,
35
+ ...a
34
36
  };
35
- t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete c.headers["Content-Type"], c.body = t) : c.body = JSON.stringify(t));
36
- const E = async (h = 0) => {
37
+ t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete d.headers["Content-Type"], d.body = t) : d.body = JSON.stringify(t));
38
+ const v = async (m = 0) => {
39
+ if (window.isSessionExpired) {
40
+ n.value = { message: "Session expired", authReported: !0 };
41
+ const o = new Error("Session expired");
42
+ throw o.authReported = !0, o;
43
+ }
37
44
  try {
38
- const o = [fetch(D, c)];
39
- n.timeout && o.push(P(n.timeout));
40
- const r = await Promise.race(o);
41
- if (!r.ok) {
42
- const H = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(H);
43
- throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
45
+ const o = [fetch(p, d)];
46
+ a.timeout && o.push(R(a.timeout));
47
+ const s = await Promise.race(o);
48
+ if (!s.ok) {
49
+ const H = `HTTP Error: ${s.status} ${s.statusText}`, l = new Error(H);
50
+ throw l.status = s.status, l.statusText = s.statusText, l.response = s, l.authReported = k.includes(s.status) && j(p), l.authReported && Promise.resolve().then(() => s.clone().text().catch(() => "")).then((O) => X(
51
+ s.status,
52
+ O,
53
+ new URL(p, window.location.href).href
54
+ )).catch(() => {
55
+ }), l;
44
56
  }
45
- let f;
46
- const l = r.headers.get("content-type");
47
- return l != null && l.includes("application/json") ? f = await r.json() : l != null && l.includes("text/") ? f = await r.text() : f = await r.blob(), {
48
- data: f,
49
- status: r.status,
50
- statusText: r.statusText,
51
- headers: r.headers
57
+ let h;
58
+ const u = s.headers.get("content-type");
59
+ return u != null && u.includes("application/json") ? h = await s.json() : u != null && u.includes("text/") ? h = await s.text() : h = await s.blob(), {
60
+ data: h,
61
+ status: s.status,
62
+ statusText: s.statusText,
63
+ headers: s.headers
52
64
  };
53
65
  } catch (o) {
54
- const r = o instanceof Error && o.name === "AbortError";
55
- if (h < (n.retry || 0) && !r)
56
- return await x(n.retryDelay || 1e3), E(h + 1);
57
- throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
66
+ const s = o instanceof Error && o.name === "AbortError";
67
+ if (m < (a.retry || 0) && !s)
68
+ return await P(a.retryDelay || 1e3), v(m + 1);
69
+ throw o instanceof Error ? o.name === "AbortError" ? n.value = { message: "Request was cancelled" } : n.value = { message: o.message } : n.value = o, o;
58
70
  }
59
71
  };
60
72
  try {
61
- return await E();
73
+ return await v();
62
74
  } finally {
63
- p.value = !1, u.value = null;
75
+ f.value = !1, c.value = null;
64
76
  }
65
- }, C = (e, s) => i("GET", e, void 0, s), R = (e, s, t) => i("POST", e, s, t), $ = (e, s, t) => i("PUT", e, s, t), q = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), U = (e) => {
66
- u.value && u.value.abort(e);
67
- }, W = () => {
68
- a.value = null;
77
+ }, A = (e, r) => i("GET", e, void 0, r), S = (e, r, t) => i("POST", e, r, t), U = (e, r, t) => i("PUT", e, r, t), C = (e, r, t) => i("PATCH", e, r, t), $ = (e, r) => i("DELETE", e, void 0, r), q = (e) => {
78
+ c.value && c.value.abort(e);
79
+ }, L = () => {
80
+ n.value = null;
69
81
  };
70
82
  return {
71
- // State
72
- loading: g,
73
- error: T(() => a.value),
83
+ loading: b,
84
+ error: w(() => n.value),
74
85
  hasError: y,
75
- // Methods
76
86
  request: i,
77
- get: C,
78
- post: R,
79
- put: $,
80
- patch: q,
81
- delete: A,
82
- cancel: U,
83
- clearError: W
87
+ get: A,
88
+ post: S,
89
+ put: U,
90
+ patch: C,
91
+ delete: $,
92
+ cancel: q,
93
+ clearError: L
84
94
  };
85
95
  };
86
96
  export {
87
- X as useHttp
97
+ _ as useHttp
88
98
  };
@@ -1,23 +1,23 @@
1
- import { useRecommendation as I } from "./useRecommendation.js";
2
- import { useToaster as C } from "./useToaster.js";
1
+ import { useRecommendation as C } from "./useRecommendation.js";
2
+ import { useToaster as I } from "./useToaster.js";
3
3
  import { useTranslations as v } from "./useTranslations.js";
4
4
  import { ToasterTypeOptions as g } from "../enums/toaster.js";
5
5
  import "../extensions/Blocks/Recommendation/constants/selectors.js";
6
6
  import { CURRENT_CONFIG_VERSION as L } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
7
7
  import { useRecommendationExtensionStore as b } from "../extensions/Blocks/Recommendation/store/recommendation.js";
8
- import { resolveMigrationTarget as R, buildLegacyMigrationPayload as T } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js";
9
- import { commitBlockChangeOutsidePanel as h } from "../extensions/Blocks/Recommendation/utils/nodeConfigWriter.js";
10
- import { useConfigStore as k } from "../stores/config.js";
8
+ import { resolveMigrationTarget as k, buildLegacyMigrationPayload as R } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js";
9
+ import { commitBlockChangeOutsidePanel as T } from "../extensions/Blocks/Recommendation/utils/nodeConfigWriter.js";
10
+ import { useConfigStore as h } from "../stores/config.js";
11
11
  const F = () => {
12
- const e = b(), r = k(), { buildCampaignUrl: m } = I(), { showToaster: i } = C(), c = v();
12
+ const e = b(), r = h(), { buildCampaignUrl: m } = C(), { showToaster: c } = I(), a = v();
13
13
  return { convertLegacyStrategy: async () => {
14
14
  const t = e.currentRecommendationId;
15
15
  if (t === null || !e.isLegacyStrategyBlock || e.legacyConversionLoading)
16
16
  return "";
17
- const { strategy: d, productIds: y, size: l, strategyId: p, nodeConfigVersion: u } = e.recommendationConfigs, f = { strategyId: p, size: l, nodeConfigVersion: u }, s = R({
17
+ const { strategy: d, productIds: y, size: l, strategyId: p, nodeConfigVersion: u } = e.recommendationConfigs, f = { strategyId: p, size: l, nodeConfigVersion: u }, s = k({
18
18
  campaignId: r.campaignId,
19
19
  templateLibraryId: r.templateLibraryId
20
- }), S = T({
20
+ }), S = R({
21
21
  blockId: t,
22
22
  url: m(String(t)),
23
23
  campaignId: r.campaignId,
@@ -29,30 +29,34 @@ const F = () => {
29
29
  let o;
30
30
  try {
31
31
  o = await e.convertLegacyStrategy(S, s);
32
- } catch (n) {
33
- return console.error("[useLegacyStrategyConversion] migration failed", n), i({
32
+ } catch (i) {
33
+ return console.error("[useLegacyStrategyConversion] migration failed", i), c({
34
34
  type: g.Error,
35
- message: c("email-editor.legacy-strategy-update-failed")
35
+ message: a("email-editor.legacy-strategy-migration-failed"),
36
+ actionButton: {
37
+ text: a("ds-steps.create-recommendation-strategy"),
38
+ onClick: () => e.openStrategyCreation()
39
+ }
36
40
  }), "";
37
41
  }
38
42
  try {
39
43
  await e.fetchStrategyProductsForBlock(t);
40
- } catch (n) {
41
- console.error("[useLegacyStrategyConversion] product refetch failed", n);
44
+ } catch (i) {
45
+ console.error("[useLegacyStrategyConversion] product refetch failed", i);
42
46
  }
43
- const a = e.blockStates[t];
44
- return a ? h(
47
+ const n = e.blockStates[t];
48
+ return n ? T(
45
49
  t,
46
50
  {
47
51
  strategyId: o,
48
- size: a.recommendationConfigs.size,
52
+ size: n.recommendationConfigs.size,
49
53
  configVersion: L
50
54
  },
51
- a.recommendationProducts,
55
+ n.recommendationProducts,
52
56
  "Converted legacy recommendation strategy"
53
- ) ? (e.currentRecommendationId === t && e.openLegacyStrategyUpdatedModal(), o) : (console.error("[useLegacyStrategyConversion] node write failed", t), e.revertLegacyConversion(t, f), i({
57
+ ) ? (e.currentRecommendationId === t && e.openLegacyStrategyUpdatedModal(), o) : (console.error("[useLegacyStrategyConversion] node write failed", t), e.revertLegacyConversion(t, f), c({
54
58
  type: g.Error,
55
- message: c("email-editor.legacy-strategy-update-failed")
59
+ message: a("email-editor.legacy-strategy-update-failed")
56
60
  }), "") : o;
57
61
  } };
58
62
  };
@@ -17,21 +17,21 @@ import { buildMergeTagEntries as W, flattenDynamicContentList as Y } from "../ut
17
17
  import Z from "../package.json.js";
18
18
  let n = null;
19
19
  const he = () => {
20
- const { features: c, template: u, isFeatureEnabled: m } = H(), { handleError: p, showToaster: B } = G(), { getToken: M, getCustomFonts: T, getSyncModulesStatus: v } = K(), { handleEvent: F } = z(), { handleModuleAdd: A } = j(), { getStripoBlocksConfig: V } = O(), { getStripoNotifications: _ } = $(), f = () => n || (n = new Promise((i, s) => {
20
+ const { features: c, template: u, isFeatureEnabled: p } = H(), { handleError: m, showToaster: v } = G(), { getToken: B, getCustomFonts: M, getSyncModulesStatus: T } = K(), { handleEvent: F } = z(), { handleModuleAdd: A } = j(), { getStripoBlocksConfig: V } = O(), { getStripoNotifications: _ } = $(), f = () => n || (n = new Promise((r, s) => {
21
21
  var d;
22
22
  if (document.getElementById("UiEditorScript")) {
23
- i();
23
+ r();
24
24
  return;
25
25
  }
26
- const o = Z.guido, r = `https://email-static.useinsider.com/guido/${(d = o == null ? void 0 : o.stripo) == null ? void 0 : d.version}/UIEditor.js`, e = document.createElement("script");
27
- e.id = "UiEditorScript", e.type = "module", e.src = r, e.onload = () => i(), e.onerror = () => {
28
- e.remove(), s(new Error(`Failed to load Stripo UIEditor script from S3: ${r}`));
26
+ const o = Z.guido, i = `https://email-static.useinsider.com/guido/${(d = o == null ? void 0 : o.stripo) == null ? void 0 : d.version}/UIEditor.js`, e = document.createElement("script");
27
+ e.id = "UiEditorScript", e.type = "module", e.src = i, e.onload = () => r(), e.onerror = () => {
28
+ e.remove(), s(new Error(`Failed to load Stripo UIEditor script from S3: ${i}`));
29
29
  }, document.body.appendChild(e);
30
30
  }), n.catch(() => {
31
31
  n = null;
32
- }), n), D = async (i, s, o, a = [], r = !1) => {
32
+ }), n), D = async (r, s, o, a = [], i = !1) => {
33
33
  var y, E, h, C;
34
- const e = k(), { html: d, css: R } = i, { baseBlocks: g, extensions: P } = await V(), S = ((y = c.value) == null ? void 0 : y.displayConditions) ?? !0, U = ((E = c.value) == null ? void 0 : E.modulesDisabled) ?? !1, I = !!d || (((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1), q = "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com";
34
+ const e = k(), { html: d, css: R } = r, { baseBlocks: g, extensions: P } = await V(), S = ((y = c.value) == null ? void 0 : y.displayConditions) ?? !0, U = ((E = c.value) == null ? void 0 : E.modulesDisabled) ?? !1, I = !!d || (((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1), q = "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com";
35
35
  w().importCss(), await window.UIEditor.initEditor(
36
36
  document.querySelector("#guido-editor"),
37
37
  {
@@ -45,7 +45,7 @@ const he = () => {
45
45
  mobileViewButtonSelector: ".guido__view-option-selection-mobile",
46
46
  desktopViewButtonSelector: ".guido__view-option-selection-desktop",
47
47
  codeEditorButtonSelector: "#guido__code-button",
48
- customAppearanceMergetags: !m("liquidSyntax"),
48
+ customAppearanceMergetags: !p("liquidSyntax"),
49
49
  customAppearanceMergetagsBorderColor: "#f1f3fe",
50
50
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
51
51
  customViewStyles: Q,
@@ -53,7 +53,7 @@ const he = () => {
53
53
  customConditionsEnabled: S,
54
54
  enableXSSSecurity: !0,
55
55
  modulesDisabled: U,
56
- syncModulesEnabled: r,
56
+ syncModulesEnabled: i,
57
57
  messageSettingsEnabled: !0,
58
58
  displayGmailAnnotations: !0,
59
59
  displayHiddenPreheader: !1,
@@ -74,16 +74,16 @@ const he = () => {
74
74
  entries: W(
75
75
  o.preselectedDynamicContentList,
76
76
  Y((C = u.value) == null ? void 0 : C.dynamicContentList),
77
- m("liquidSyntax")
77
+ p("liquidSyntax")
78
78
  )
79
79
  }
80
80
  ],
81
81
  async onTokenRefreshRequest(t) {
82
82
  try {
83
- const l = await M();
83
+ const l = await B();
84
84
  t(l);
85
85
  } catch (l) {
86
- p(l, "Failed to refresh token");
86
+ m(l, "Failed to refresh token");
87
87
  }
88
88
  },
89
89
  onTemplateLoaded() {
@@ -93,7 +93,7 @@ const he = () => {
93
93
  e.hasChanges = !1;
94
94
  }, 1e3);
95
95
  } catch (t) {
96
- p(t, "Failed to load custom interface appearance");
96
+ m(t, "Failed to load custom interface appearance");
97
97
  }
98
98
  },
99
99
  onCodeEditorVisibilityChanged(t) {
@@ -111,27 +111,31 @@ const he = () => {
111
111
  onEvent: F,
112
112
  onModuleAdd: A,
113
113
  notifications: _(),
114
+ // Stripo deselects the block on any click outside the canvas, so every surface
115
+ // that belongs to the block's own flow has to be listed here (SD-153273).
114
116
  ignoreClickOutsideSelectors: [
115
117
  "#guido-dynamic-content-modal",
116
118
  ".in-on-board-wrapper",
117
- ".in-drawer__container"
119
+ ".in-drawer__container",
120
+ ".in-modal-v2-wrapper",
121
+ ".in-toasts-wrapper"
118
122
  ],
119
123
  extensions: P,
120
124
  localePatch: J
121
125
  }
122
126
  );
123
127
  };
124
- return { initPlugin: async (i, s, o) => {
128
+ return { initPlugin: async (r, s, o) => {
125
129
  const a = k();
126
130
  try {
127
131
  await f();
128
- const [r, e] = await Promise.all([
129
- T(),
130
- v()
132
+ const [i, e] = await Promise.all([
133
+ M(),
134
+ T()
131
135
  ]);
132
- a.syncModulesEnabled = e, await D(i, s, o, r, e);
136
+ a.syncModulesEnabled = e, await D(r, s, o, i, e);
133
137
  } catch {
134
- a.loadingStatus = !1, B({
138
+ a.loadingStatus = !1, v({
135
139
  type: X.Error,
136
140
  message: b["An error has occurred. Please report the error code to support."],
137
141
  actionButton: {