@useinsider/guido 3.19.0-beta.ab4fcb3 → 3.19.0-beta.b539426

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 (36) hide show
  1. package/dist/components/Guido.vue.js +6 -6
  2. package/dist/components/Guido.vue2.js +27 -26
  3. package/dist/components/organisms/base/AuthErrorModal.vue.js +18 -0
  4. package/dist/components/organisms/base/AuthErrorModal.vue2.js +42 -0
  5. package/dist/components/wrappers/WpModal.vue.js +1 -1
  6. package/dist/components/wrappers/WpModal.vue2.js +4 -3
  7. package/dist/composables/useAuthError.js +52 -0
  8. package/dist/composables/useAutoSave.js +11 -11
  9. package/dist/composables/useHttp.js +64 -54
  10. package/dist/composables/useLegacyStrategyConversion.js +23 -19
  11. package/dist/composables/useStripo.js +24 -20
  12. package/dist/composables/useToaster.js +17 -15
  13. package/dist/composables/validators/useLiquidValidator.js +15 -15
  14. package/dist/config/migrator/recommendationMigrator.js +28 -21
  15. package/dist/config/migrator/recommendationPartnerMigrator.js +36 -30
  16. package/dist/enums/extensions/recommendationBlock.js +30 -29
  17. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +105 -96
  18. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +29 -29
  19. package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +72 -70
  20. package/dist/extensions/Blocks/Recommendation/utils/compositionKeys.js +69 -60
  21. package/dist/guido.css +1 -1
  22. package/dist/src/components/organisms/base/AuthErrorModal.vue.d.ts +2 -0
  23. package/dist/src/components/wrappers/WpModal.vue.d.ts +5 -1
  24. package/dist/src/composables/useAuthError.d.ts +12 -0
  25. package/dist/src/composables/useGuidoActions.d.ts +2 -0
  26. package/dist/src/composables/useHttp.d.ts +2 -0
  27. package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -1
  28. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +2 -0
  29. package/dist/src/extensions/Blocks/Recommendation/utils/compositionKeys.d.ts +4 -0
  30. package/dist/src/mock/cortexChatStore.d.ts +12 -0
  31. package/dist/src/stores/onboarding.d.ts +4 -0
  32. package/dist/src/stores/recommendation.d.ts +5 -0
  33. package/dist/src/utils/dateUtil.d.ts +10 -0
  34. package/dist/src/utils/genericUtil.d.ts +3 -0
  35. package/dist/stores/onboarding.js +4 -0
  36. package/package.json +1 -1
@@ -1,18 +1,18 @@
1
1
  import o from "./Guido.vue2.js";
2
2
  /* empty css */
3
- import i from "../_virtual/_plugin-vue2_normalizer.js";
4
- var t = function() {
3
+ import t from "../_virtual/_plugin-vue2_normalizer.js";
4
+ var i = function() {
5
5
  var a = this, r = a._self._c, e = a._self._setupProxy;
6
- return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), r(e.AutoSaveController), e.editorStore.isPreviewModeOpen ? r(e.PreviewContainer) : a._e(), r("div", { directives: [{ name: "show", rawName: "v-show", value: !e.previewStore.isLoaded, expression: "!previewStore.isLoaded" }], staticClass: "guido-editor__container", class: { "guido-editor__no-header": e.noHeader }, attrs: { id: "guido-editor" } }), r(e.Toaster), r(e.FilterSelectionDrawer), e.isRrsEnabled || e.hasAssignedStrategy ? r(e.AssignStrategyDrawer) : a._e(), e.isRrsEnabled || e.hasAssignedStrategy ? r(e.RemoveStrategyModal) : a._e(), e.isRrsEnabled ? r(e.LegacyStrategyUpdatedModal) : a._e(), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? a._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(_) {
6
+ return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), r(e.AutoSaveController), e.editorStore.isPreviewModeOpen ? r(e.PreviewContainer) : a._e(), r("div", { directives: [{ name: "show", rawName: "v-show", value: !e.previewStore.isLoaded, expression: "!previewStore.isLoaded" }], staticClass: "guido-editor__container", class: { "guido-editor__no-header": e.noHeader }, attrs: { id: "guido-editor" } }), r(e.Toaster), r(e.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.isTestPartner() ? a._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(_) {
7
7
  return e.emit("onboarding:finished");
8
8
  } } }), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
9
- }, s = [], n = /* @__PURE__ */ i(
9
+ }, s = [], n = /* @__PURE__ */ t(
10
10
  o,
11
- t,
11
+ i,
12
12
  s,
13
13
  !1,
14
14
  null,
15
- "55f67f37"
15
+ "926b01f5"
16
16
  );
17
17
  const f = n.exports;
18
18
  export {
@@ -11,21 +11,22 @@ import { ModuleFolderDefaults as H } from "../enums/defaults.js";
11
11
  import { RIBBON_SELECTOR as ye } from "../enums/onboarding.js";
12
12
  import { useRecommendationExtensionStore as h } from "../extensions/Blocks/Recommendation/store/recommendation.js";
13
13
  import ge from "./organisms/AutoSaveController.vue.js";
14
- import Se from "./organisms/base/Toaster.vue.js";
15
- import ve from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
16
- import be from "./organisms/header/HeaderWrapper.vue.js";
17
- import he from "./organisms/LoadingWrapper.vue.js";
18
- import Ee from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
19
- import we from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
20
- import { useStripoApi as Ce } from "../services/stripoApi.js";
21
- import { useConfigStore as De } from "../stores/config.js";
22
- import { useDynamicContentStore as ke } from "../stores/dynamic-content.js";
14
+ import Se from "./organisms/base/AuthErrorModal.vue.js";
15
+ import ve from "./organisms/base/Toaster.vue.js";
16
+ import be from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
17
+ import he from "./organisms/header/HeaderWrapper.vue.js";
18
+ import Ee from "./organisms/LoadingWrapper.vue.js";
19
+ import we from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
20
+ import Ce from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
21
+ import { useStripoApi as De } from "../services/stripoApi.js";
22
+ import { useConfigStore as ke } from "../stores/config.js";
23
+ import { useDynamicContentStore as Fe } from "../stores/dynamic-content.js";
23
24
  import { useEditorStore as $ } from "../stores/editor.js";
24
- import { usePreviewStore as Fe } from "../stores/preview.js";
25
+ import { usePreviewStore as Me } from "../stores/preview.js";
25
26
  import { useTemplateStore as Re } from "../stores/template.js";
26
27
  import { useUnsubscribeStore as Te } from "../stores/unsubscribe.js";
27
28
  import { readTrackFloor as z } from "../utils/linkTrackingIds.js";
28
- const ot = /* @__PURE__ */ ae({
29
+ const rt = /* @__PURE__ */ ae({
29
30
  __name: "Guido",
30
31
  props: {
31
32
  config: null,
@@ -43,9 +44,9 @@ const ot = /* @__PURE__ */ ae({
43
44
  () => import("./organisms/extensions/recommendation/RemoveStrategyModal.vue.js")
44
45
  ), X = m(
45
46
  () => import("./organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js")
46
- ), E = x(), p = x(), f = ke(), w = Te(), o = De();
47
+ ), E = x(), p = x(), f = Fe(), w = Te(), o = ke();
47
48
  s.ready && o.init(s.config);
48
- const c = $(), Y = Fe(), l = u(() => c.hasChanges), { isTestPartner: Z } = ue(), C = () => {
49
+ const c = $(), Y = Me(), l = u(() => c.hasChanges), { isTestPartner: Z } = ue(), C = () => {
49
50
  var t;
50
51
  return (t = E.value) == null ? void 0 : t.handleSave(!0);
51
52
  }, D = (t) => {
@@ -62,9 +63,9 @@ const ot = /* @__PURE__ */ ae({
62
63
  savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || H.SAVED_MODULES,
63
64
  defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || H.DEFAULT_MODULES
64
65
  };
65
- }, { initPlugin: k, preloadRuntime: F } = pe(), { runExclusive: R, beginMount: T, isCurrentMount: M } = de();
66
+ }, { initPlugin: k, preloadRuntime: F } = pe(), { runExclusive: M, beginMount: R, isCurrentMount: T } = de();
66
67
  let g = 0;
67
- const { getDefaultTemplate: I } = Ce(), { cloneTimersOnSave: L, hasTimerBlocks: U } = fe(), ee = u(() => {
68
+ const { getDefaultTemplate: I } = De(), { cloneTimersOnSave: L, hasTimerBlocks: U } = fe(), ee = u(() => {
68
69
  var t;
69
70
  return !((t = o.ui) != null && t.showHeader);
70
71
  }), te = u(() => o.isFeatureEnabled("reusableRecommendationStrategy")), oe = u(
@@ -85,9 +86,9 @@ const ot = /* @__PURE__ */ ae({
85
86
  console.debug("guido:test-email:click"), r("test-email:click");
86
87
  }
87
88
  });
88
- const B = (t) => {
89
+ const A = (t) => {
89
90
  console.debug("dynamic-content:close", t), f.setSelectedDynamicContent(t), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: t }));
90
- }, N = () => {
91
+ }, B = () => {
91
92
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
92
93
  };
93
94
  W(() => l.value, () => {
@@ -106,7 +107,7 @@ const ot = /* @__PURE__ */ ae({
106
107
  var t;
107
108
  try {
108
109
  o.initialized || o.init(s.config), c.templateId = o.templateId;
109
- const e = o.template, a = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", A = (e == null ? void 0 : e.preselectedDynamicContent) || [];
110
+ const e = o.template, a = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", N = (e == null ? void 0 : e.preselectedDynamicContent) || [];
110
111
  w.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
111
112
  const P = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, _ = o.isFeatureEnabled("linkTrackingIds"), O = {
112
113
  partnerName: o.partnerName,
@@ -121,12 +122,12 @@ const ot = /* @__PURE__ */ ae({
121
122
  const ne = _ ? z(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
122
123
  U(n.html) && (n.html = await L(n.html)), _ && (c.trackIdSessionFloor = Math.max(ne, z(n.html)));
123
124
  const re = {
124
- preselectedDynamicContentList: A,
125
+ preselectedDynamicContentList: N,
125
126
  onReady: () => {
126
127
  console.debug("guido:ready"), r("ready");
127
128
  }
128
129
  };
129
- g = T(), await k(n, y(), re), f.selectedDynamicContentList = A;
130
+ g = R(), await k(n, y(), re), f.selectedDynamicContentList = N;
130
131
  } catch (e) {
131
132
  console.error("Failed to initialize Stripo editor:", e);
132
133
  }
@@ -144,8 +145,8 @@ const ot = /* @__PURE__ */ ae({
144
145
  }
145
146
  document.addEventListener("dynamic-content:open", S);
146
147
  }), ie(() => {
147
- i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", S), h().disposeStrategyPageReturn(), R(async () => {
148
- if (M(g))
148
+ i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", S), h().disposeStrategyPageReturn(), M(async () => {
149
+ if (T(g))
149
150
  try {
150
151
  window.UIEditor.removeEditor();
151
152
  } catch {
@@ -154,15 +155,15 @@ const ot = /* @__PURE__ */ ae({
154
155
  }), o.reset();
155
156
  }), K({
156
157
  dynamicContent: {
157
- insert: B,
158
- close: N
158
+ insert: A,
159
+ close: B
159
160
  },
160
161
  hasChanges: l,
161
162
  saveSilent: C,
162
163
  setLoading: D
163
- }), { __sfc: !0, PreviewContainer: V, OnboardingWrapper: j, AssignStrategyDrawer: J, RemoveStrategyModal: Q, LegacyStrategyUpdatedModal: X, headerWrapperRef: E, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: w, props: s, configStore: o, editorStore: c, previewStore: Y, hasChanges: l, isTestPartner: Z, saveSilent: C, setLoading: D, emit: r, buildMetadata: y, initPlugin: k, preloadRuntime: F, runExclusive: R, beginMount: T, isCurrentMount: M, mountGeneration: g, getDefaultTemplate: I, cloneTimersOnSave: L, hasTimerBlocks: U, noHeader: ee, isRrsEnabled: te, hasAssignedStrategy: oe, insertDynamicContent: B, closeDynamicContent: N, handleDynamicContentOpen: S, ribbonObserver: i, updateRibbonOffset: v, startEditor: b, AutoSaveController: ge, Toaster: Se, FilterSelectionDrawer: ve, HeaderWrapper: be, LoadingWrapper: he, SaveAsTemplateDrawer: Ee, UnsubscribeWrapper: we };
164
+ }), { __sfc: !0, PreviewContainer: V, OnboardingWrapper: j, AssignStrategyDrawer: J, RemoveStrategyModal: Q, LegacyStrategyUpdatedModal: X, headerWrapperRef: E, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: w, props: s, configStore: o, editorStore: c, previewStore: Y, hasChanges: l, isTestPartner: Z, saveSilent: C, setLoading: D, emit: r, buildMetadata: y, initPlugin: k, preloadRuntime: F, runExclusive: M, beginMount: R, isCurrentMount: T, mountGeneration: g, getDefaultTemplate: I, cloneTimersOnSave: L, hasTimerBlocks: U, noHeader: ee, isRrsEnabled: te, hasAssignedStrategy: oe, insertDynamicContent: A, closeDynamicContent: B, handleDynamicContentOpen: S, ribbonObserver: i, updateRibbonOffset: v, startEditor: b, AutoSaveController: ge, AuthErrorModal: Se, Toaster: ve, FilterSelectionDrawer: be, HeaderWrapper: he, LoadingWrapper: Ee, SaveAsTemplateDrawer: we, UnsubscribeWrapper: Ce };
164
165
  }
165
166
  });
166
167
  export {
167
- ot as default
168
+ rt as default
168
169
  };
@@ -0,0 +1,18 @@
1
+ import e from "./AuthErrorModal.vue2.js";
2
+ /* empty css */
3
+ import s from "../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var a = function() {
5
+ var o = this, r = o._self._c, t = o._self._setupProxy;
6
+ return t.authError ? r("div", { staticClass: "auth-error-modal" }, [r(t.WpModal, { attrs: { id: "guido__auth-error-modal", state: "warning", "close-button-status": !1, "close-on-outside-click": !1, "footer-button-options": t.footerButtonOptions, title: t.title }, on: { close: t.dismiss, "primary-action": t.recover } }, [r("p", [o._v(o._s(t.message))])])], 1) : o._e();
7
+ }, n = [], i = /* @__PURE__ */ s(
8
+ e,
9
+ a,
10
+ n,
11
+ !1,
12
+ null,
13
+ "b4d7ae51"
14
+ );
15
+ const m = i.exports;
16
+ export {
17
+ m as default
18
+ };
@@ -0,0 +1,42 @@
1
+ import { defineComponent as c, computed as n } from "vue";
2
+ import p from "../../wrappers/WpModal.vue.js";
3
+ import { useAuthError as d } from "../../../composables/useAuthError.js";
4
+ import { useTranslations as m } from "../../../composables/useTranslations.js";
5
+ const _ = /* @__PURE__ */ c({
6
+ __name: "AuthErrorModal",
7
+ setup(v) {
8
+ const e = m(), { authError: t } = d(), r = n(() => {
9
+ var o;
10
+ return ((o = t.value) == null ? void 0 : o.status) === 419 && t.value.data !== null;
11
+ }), s = n(() => {
12
+ var o;
13
+ return ((o = t.value) == null ? void 0 : o.status) === 419 && t.value.data === null;
14
+ }), i = n(() => r.value ? e("integration-hub.reload-this-page") : e("action-builder.session-expired")), u = n(() => r.value ? e("auth.error-occurred-refresh") : s.value ? e("settings.session-on-another-device") : e("journey-builder.login-session-expired")), l = n(() => ({
15
+ primaryButton: {
16
+ type: "primary",
17
+ labelText: r.value ? e("integration-hub.reload") : e("journey-builder.login-popup-button")
18
+ },
19
+ cancelOrBackButton: {
20
+ type: "secondary",
21
+ styling: "ghost",
22
+ labelText: e("settings.cancel")
23
+ }
24
+ })), a = () => {
25
+ if (r.value) {
26
+ window.location.reload();
27
+ return;
28
+ }
29
+ window.location.replace("/");
30
+ };
31
+ return { __sfc: !0, trans: e, authError: t, isPageExpired: r, isTakenOver: s, title: i, message: u, footerButtonOptions: l, recover: a, dismiss: () => {
32
+ if (r.value) {
33
+ t.value = null;
34
+ return;
35
+ }
36
+ a();
37
+ }, WpModal: p };
38
+ }
39
+ });
40
+ export {
41
+ _ as default
42
+ };
@@ -2,7 +2,7 @@ import r from "./WpModal.vue2.js";
2
2
  import s from "../../_virtual/_plugin-vue2_normalizer.js";
3
3
  var i = function() {
4
4
  var t = this, o = t._self._c, e = t._self._setupProxy;
5
- return o(e.InModalV2, { attrs: { id: t.id, "description-status": "", status: "", "close-button-status": t.closeButtonStatus, "close-on-outside-click": t.closeOnOutsideClick, "description-text": t.description, "footer-button-group-options": t.footerButtonOptions, "footer-status": t.footerStatus, size: t.size, "title-text": t.title }, on: { cancelOrBackButtonEvent: function(n) {
5
+ return o(e.InModalV2, { attrs: { id: t.id, "description-status": "", status: "", "close-button-status": t.closeButtonStatus, "close-on-outside-click": t.closeOnOutsideClick, "description-text": t.description, "footer-button-group-options": t.footerButtonOptions, "footer-status": t.footerStatus, size: t.size, state: t.state, "title-text": t.title }, on: { cancelOrBackButtonEvent: function(n) {
6
6
  return e.emit("close");
7
7
  }, onCloseEvent: function(n) {
8
8
  return e.emit("close");
@@ -1,11 +1,12 @@
1
1
  import { defineComponent as e } from "vue";
2
2
  import { InModalV2 as o } from "@useinsider/design-system-vue";
3
- const u = /* @__PURE__ */ e({
3
+ const n = /* @__PURE__ */ e({
4
4
  __name: "WpModal",
5
5
  props: {
6
6
  id: null,
7
7
  title: null,
8
8
  description: { default: "" },
9
+ state: { default: "default" },
9
10
  size: { default: "small" },
10
11
  footerButtonOptions: { default: void 0 },
11
12
  closeButtonStatus: { type: Boolean, default: !0 },
@@ -13,10 +14,10 @@ const u = /* @__PURE__ */ e({
13
14
  footerStatus: { type: Boolean, default: !0 }
14
15
  },
15
16
  emits: ["close", "primary-action", "secondary-action"],
16
- setup(l, { emit: t }) {
17
+ setup(a, { emit: t }) {
17
18
  return { __sfc: !0, emit: t, InModalV2: o };
18
19
  }
19
20
  });
20
21
  export {
21
- u as default
22
+ n as default
22
23
  };
@@ -0,0 +1,52 @@
1
+ import { ToasterTypeOptions as l } from "../enums/toaster.js";
2
+ import { ref as p } from "vue";
3
+ import { useToaster as u } from "./useToaster.js";
4
+ import { useTranslations as f } from "./useTranslations.js";
5
+ const d = ["accessExpired", "domainRestricted", "ipRestricted", "insiderAccessRestricted"], n = p(null), a = (e) => {
6
+ try {
7
+ return new URL(e, window.location.href).origin === window.location.origin;
8
+ } catch {
9
+ return !0;
10
+ }
11
+ }, g = (e) => {
12
+ try {
13
+ const o = new URL(e, window.location.href);
14
+ return o.origin === window.location.origin ? o.href : "";
15
+ } catch {
16
+ return "";
17
+ }
18
+ }, w = (e) => {
19
+ try {
20
+ const o = JSON.parse(e);
21
+ return o && typeof o == "object" && Object.keys(o).length ? o : null;
22
+ } catch {
23
+ return null;
24
+ }
25
+ }, y = (e) => typeof (e == null ? void 0 : e.message) == "string" ? e.message : "", s = (e) => y(e) || f()("user-management.collaborate-forbidden-action"), c = (e) => {
26
+ u().showToaster({ type: l.Error, message: e });
27
+ }, R = (e, o, t) => {
28
+ if (t && !a(t))
29
+ return;
30
+ const r = w(o);
31
+ if (e === 403) {
32
+ c(s(r));
33
+ return;
34
+ }
35
+ if (e === 401 && (r == null ? void 0 : r.type) === "groupLevelAccess") {
36
+ c(s(r));
37
+ return;
38
+ }
39
+ if (e === 401 && typeof (r == null ? void 0 : r.type) == "string" && d.includes(r.type)) {
40
+ const i = typeof r.redirect == "string" ? g(r.redirect) : "";
41
+ if (i) {
42
+ window.location.replace(i);
43
+ return;
44
+ }
45
+ }
46
+ e !== 401 && e !== 419 || n.value || (window.isSessionExpired = !0, n.value = { status: e, data: r });
47
+ }, T = () => ({ authError: n });
48
+ export {
49
+ a as isPanelOrigin,
50
+ R as reportAuthError,
51
+ T as useAuthError
52
+ };
@@ -1,17 +1,17 @@
1
1
  import { useConfig as E } from "./useConfig.js";
2
- import { useEditorLock as p } from "./useEditorLock.js";
3
- import { useAutosaveStore as A, AUTOSAVE_STATUS as s } from "../stores/autosave.js";
4
- import { useEditorStore as f } from "../stores/editor.js";
2
+ import { useEditorLock as f } from "./useEditorLock.js";
3
+ import { useAutosaveStore as p, AUTOSAVE_STATUS as s } from "../stores/autosave.js";
4
+ import { useEditorStore as A } from "../stores/editor.js";
5
5
  import { computed as y, watch as I, onUnmounted as L } from "vue";
6
6
  const w = 18e4, v = 6e4, R = (b) => {
7
- const { isFeatureEnabled: S } = E(), o = f(), t = A(), { isEditorBusy: g } = p();
7
+ const { isFeatureEnabled: S } = E(), o = A(), t = p(), { isEditorBusy: g } = f();
8
8
  let i = null, c = 0;
9
9
  const u = y(
10
10
  () => S("autosave") && t.isOn
11
11
  ), m = () => o.hasChanges && o.isInSaveableState, h = () => ({
12
12
  hasChanges: o.hasChanges,
13
13
  isInSaveableState: o.isInSaveableState
14
- }), r = async (e) => {
14
+ }), l = async (e) => {
15
15
  if (!u.value) {
16
16
  console.debug("guido:autosave:skipped", { trigger: e, reason: "not-active" });
17
17
  return;
@@ -28,7 +28,7 @@ const w = 18e4, v = 6e4, R = (b) => {
28
28
  console.debug("guido:autosave:skipped", { trigger: e, reason: "editor-busy" });
29
29
  return;
30
30
  }
31
- console.debug("guido:autosave:save-start", { trigger: e }), t.status = s.SAVING;
31
+ e === "visibility" && (c = Date.now()), console.debug("guido:autosave:save-start", { trigger: e }), t.status = s.SAVING;
32
32
  try {
33
33
  if (await b() === void 0) {
34
34
  console.debug("guido:autosave:blocked", { trigger: e, reason: "save-returned-undefined" }), t.status = s.ERROR;
@@ -53,22 +53,22 @@ const w = 18e4, v = 6e4, R = (b) => {
53
53
  });
54
54
  return;
55
55
  }
56
- c = Date.now(), r("visibility");
56
+ l("visibility");
57
57
  }, d = () => {
58
58
  i && (clearInterval(i), i = null);
59
- }, l = () => {
59
+ }, r = () => {
60
60
  document.removeEventListener("visibilitychange", n), window.removeEventListener("pagehide", n);
61
61
  };
62
62
  I(
63
63
  u,
64
64
  (e) => {
65
65
  console.debug("guido:autosave:active-changed", { active: e }), e ? (d(), i = setInterval(() => {
66
- console.debug("guido:autosave:interval-tick"), r("interval");
67
- }, w), document.addEventListener("visibilitychange", n), window.addEventListener("pagehide", n)) : (d(), l(), t.status = s.IDLE);
66
+ console.debug("guido:autosave:interval-tick"), l("interval");
67
+ }, w), document.addEventListener("visibilitychange", n), window.addEventListener("pagehide", n)) : (d(), r(), t.status = s.IDLE);
68
68
  },
69
69
  { immediate: !0 }
70
70
  ), L(() => {
71
- d(), l(), t.status = s.IDLE, t.lastSavedAt = null;
71
+ d(), r(), t.status = s.IDLE, t.lastSavedAt = null;
72
72
  });
73
73
  };
74
74
  export {
@@ -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
  };