@useinsider/guido 3.2.0-beta.803b92e → 3.2.0-beta.8220f9d

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 (113) hide show
  1. package/README.md +1 -25
  2. package/dist/@types/config/schemas.js +2 -2
  3. package/dist/components/Guido.vue.js +5 -5
  4. package/dist/components/Guido.vue2.js +88 -78
  5. package/dist/components/organisms/chat/blueprint/BlueprintCard.vue.js +20 -0
  6. package/dist/components/organisms/chat/blueprint/BlueprintCard.vue2.js +20 -0
  7. package/dist/components/organisms/chat/blueprint/EmailTemplateBlueprintCard.vue.js +23 -0
  8. package/dist/components/organisms/chat/blueprint/EmailTemplateBlueprintCard.vue2.js +18 -0
  9. package/dist/components/organisms/chat/chatbox/ChatboxContainer.vue.js +18 -0
  10. package/dist/components/organisms/chat/chatbox/ChatboxContainer.vue2.js +16 -0
  11. package/dist/components/organisms/chat/chatbox/ChatboxPanel.vue.js +20 -0
  12. package/dist/components/organisms/chat/chatbox/ChatboxPanel.vue2.js +19 -0
  13. package/dist/components/organisms/chat/conversation/ChatConversation.vue.js +28 -0
  14. package/dist/components/organisms/chat/conversation/ChatConversation.vue2.js +20 -0
  15. package/dist/components/organisms/chat/conversation/ChatWelcome.vue.js +18 -0
  16. package/dist/components/organisms/chat/conversation/ChatWelcome.vue2.js +11 -0
  17. package/dist/components/organisms/chat/conversation/QuickActionChips.vue.js +22 -0
  18. package/dist/components/organisms/chat/conversation/QuickActionChips.vue2.js +42 -0
  19. package/dist/components/organisms/chat/input/ChatInput.vue.js +29 -0
  20. package/dist/components/organisms/chat/input/ChatInput.vue2.js +39 -0
  21. package/dist/components/organisms/chat/input/GuidoAgentSelector.vue.js +22 -0
  22. package/dist/components/organisms/chat/input/GuidoAgentSelector.vue2.js +29 -0
  23. package/dist/components/organisms/chat/messages/AiMessage.vue.js +26 -0
  24. package/dist/components/organisms/chat/messages/AiMessage.vue2.js +41 -0
  25. package/dist/components/organisms/chat/messages/AiMessageActions.vue.js +18 -0
  26. package/dist/components/organisms/chat/messages/AiMessageActions.vue2.js +27 -0
  27. package/dist/components/organisms/chat/messages/ChatLoading.vue.js +18 -0
  28. package/dist/components/organisms/chat/messages/ChatLoading.vue2.js +30 -0
  29. package/dist/components/organisms/chat/messages/ChatMessages.vue.js +26 -0
  30. package/dist/components/organisms/chat/messages/ChatMessages.vue2.js +67 -0
  31. package/dist/components/organisms/chat/messages/UserMessage.vue.js +18 -0
  32. package/dist/components/organisms/chat/messages/UserMessage.vue2.js +26 -0
  33. package/dist/components/organisms/header/RightSlot.vue.js +8 -8
  34. package/dist/components/organisms/header/RightSlot.vue2.js +8 -9
  35. package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
  36. package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
  37. package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
  38. package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
  39. package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
  40. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
  41. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
  42. package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
  43. package/dist/composables/useChatState.js +130 -0
  44. package/dist/composables/useChatStreaming.js +191 -0
  45. package/dist/composables/useConversationEvents.js +37 -0
  46. package/dist/composables/useEmailTemplateApplier.js +41 -0
  47. package/dist/composables/useRibbonOffset.js +21 -0
  48. package/dist/composables/useSave.js +15 -15
  49. package/dist/config/compiler/unsubscribeCompilerRules.js +40 -37
  50. package/dist/enums/onboarding.js +7 -2
  51. package/dist/enums/unsubscribe.js +34 -27
  52. package/dist/guido.css +1 -1
  53. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +258 -235
  54. package/dist/node_modules/@vueuse/core/index.js +127 -0
  55. package/dist/node_modules/@vueuse/shared/index.js +68 -27
  56. package/dist/node_modules/dompurify/dist/purify.es.js +595 -0
  57. package/dist/node_modules/marked/lib/marked.esm.js +1152 -0
  58. package/dist/package.json.js +1 -1
  59. package/dist/services/chatService.js +163 -0
  60. package/dist/services/templateLibraryApi.js +5 -4
  61. package/dist/src/@types/chat.d.ts +138 -0
  62. package/dist/src/@types/config/schemas.d.ts +4 -4
  63. package/dist/src/components/Guido.vue.d.ts +5 -1
  64. package/dist/src/components/organisms/chat/blueprint/BlueprintCard.vue.d.ts +38 -0
  65. package/dist/src/components/organisms/chat/blueprint/EmailTemplateBlueprintCard.vue.d.ts +35 -0
  66. package/dist/src/components/organisms/chat/chatbox/ChatboxContainer.vue.d.ts +4 -0
  67. package/dist/src/components/organisms/chat/chatbox/ChatboxPanel.vue.d.ts +4 -0
  68. package/dist/src/components/organisms/chat/conversation/ChatConversation.vue.d.ts +31 -0
  69. package/dist/src/components/organisms/chat/conversation/QuickActionChips.vue.d.ts +30 -0
  70. package/dist/src/components/organisms/chat/input/ChatInput.vue.d.ts +37 -0
  71. package/dist/src/components/organisms/chat/messages/AiMessage.vue.d.ts +33 -0
  72. package/dist/src/components/organisms/chat/messages/AiMessageActions.vue.d.ts +18 -0
  73. package/dist/src/components/organisms/chat/messages/ChatLoading.vue.d.ts +32 -0
  74. package/dist/src/components/organisms/chat/messages/ChatMessages.vue.d.ts +37 -0
  75. package/dist/src/components/organisms/chat/messages/UserMessage.vue.d.ts +35 -0
  76. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  77. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  78. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  79. package/dist/src/composables/useChatState.d.ts +26 -0
  80. package/dist/src/composables/useChatStreaming.d.ts +26 -0
  81. package/dist/src/composables/useConfig.d.ts +2 -2
  82. package/dist/src/composables/useConversationEvents.d.ts +19 -0
  83. package/dist/src/composables/useEmailTemplateApplier.d.ts +21 -0
  84. package/dist/src/composables/useRibbonOffset.d.ts +4 -0
  85. package/dist/src/composables/useSave.d.ts +1 -1
  86. package/dist/src/enums/onboarding.d.ts +6 -0
  87. package/dist/src/enums/unsubscribe.d.ts +5 -0
  88. package/dist/src/services/chatService.d.ts +16 -0
  89. package/dist/src/stores/chat.d.ts +323 -0
  90. package/dist/src/stores/config.d.ts +18 -18
  91. package/dist/src/stores/editor.d.ts +23 -0
  92. package/dist/src/stores/onboarding.d.ts +4 -0
  93. package/dist/src/utils/generateId.d.ts +1 -0
  94. package/dist/src/utils/markdown.d.ts +1 -0
  95. package/dist/stores/chat.js +26 -0
  96. package/dist/stores/editor.js +1 -0
  97. package/dist/stores/onboarding.js +4 -0
  98. package/dist/utils/generateId.js +7 -0
  99. package/dist/utils/markdown.js +21 -0
  100. package/dist/utils/pairProductVariables.js +89 -88
  101. package/package.json +6 -3
  102. package/dist/components/organisms/AutoSaveController.vue.js +0 -17
  103. package/dist/components/organisms/AutoSaveController.vue2.js +0 -13
  104. package/dist/components/organisms/header/AutoSaveToggle.vue.js +0 -22
  105. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +0 -19
  106. package/dist/composables/useAutoSave.js +0 -68
  107. package/dist/src/composables/useAutoSave.d.ts +0 -3
  108. package/dist/src/stores/autosave.d.ts +0 -6
  109. package/dist/src/utils/timeUtil.d.ts +0 -8
  110. package/dist/stores/autosave.js +0 -11
  111. package/dist/utils/timeUtil.js +0 -19
  112. /package/dist/src/components/organisms/{AutoSaveController.vue.d.ts → chat/conversation/ChatWelcome.vue.d.ts} +0 -0
  113. /package/dist/src/components/organisms/{header/AutoSaveToggle.vue.d.ts → chat/input/GuidoAgentSelector.vue.d.ts} +0 -0
package/README.md CHANGED
@@ -143,8 +143,7 @@ const config: GuidoConfigInput = {
143
143
  displayConditions?: boolean, // Default: true
144
144
  unsubscribe?: boolean, // Default: true
145
145
  modulesDisabled?: boolean, // Default: false - Disable modules panel
146
- liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
147
- autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
146
+ liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
148
147
  },
149
148
 
150
149
  // Optional: Callbacks
@@ -203,7 +202,6 @@ interface SavedTemplateDetails {
203
202
  config: number[];
204
203
  };
205
204
  metadata: Metadata;
206
- silent: boolean; // true when triggered by autosave, false when user clicked Save
207
205
  }
208
206
 
209
207
  interface Metadata {
@@ -329,28 +327,6 @@ const config: GuidoConfigInput = {
329
327
 
330
328
  ---
331
329
 
332
- ## Autosave
333
-
334
- Guido ships an opt-in **autosave** that saves on a 3-minute interval and when the user leaves the tab. Enable it with the `features.autosave` feature flag — this **shows an "Auto Save" toggle in the editor header**; the end user switches autosave on per session.
335
-
336
- ```typescript
337
- const config: GuidoConfigInput = {
338
- identity: { templateId: 'tpl-123', userId: 'user-456' },
339
- partner: { name: 'partner' },
340
- features: {
341
- autosave: true, // Default: false — shows the Auto Save toggle in the header
342
- },
343
- };
344
- ```
345
-
346
- - Default is `false` — integrations see no change unless they opt in.
347
- - Autosave reuses the same save pipeline as the Save button, so your existing `@save:complete` handler receives autosave output identically to a manual save. No new events or callbacks.
348
- - Toggle state is **session-only** (Pinia) — resets to OFF on reload.
349
-
350
- For a deep dive on triggers, guards, and limitations, see **[wiki/AUTOSAVE.md](wiki/AUTOSAVE.md)**.
351
-
352
- ---
353
-
354
330
  ## HTML Compiler Rules
355
331
 
356
332
  Add custom rules to transform HTML during export:
@@ -124,8 +124,8 @@ const m = {
124
124
  modulesDisabled: e(o(), !1),
125
125
  /** Enable Liquid template syntax */
126
126
  liquidSyntax: e(o(), !1),
127
- /** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
128
- autosave: e(o(), !1)
127
+ /** Enable AI assistant chat panel (cortex-style chatbot) */
128
+ aiAssistant: e(o(), !1)
129
129
  }), g = n([
130
130
  "amp-accordion",
131
131
  "amp-carousel",
@@ -3,18 +3,18 @@ import i from "./Guido.vue2.js";
3
3
  import a from "../_virtual/_plugin-vue2_normalizer.js";
4
4
  var t = function() {
5
5
  var o = this, r = o._self._c, e = o._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) : o._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), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? o._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(p) {
6
+ return r("div", { ref: "wrapperRef", staticClass: "guido-editor__wrapper", class: { "guido-editor__no-header": e.noHeader } }, [r(e.HeaderWrapper, { ref: "headerWrapperRef" }), e.editorStore.isPreviewModeOpen ? r(e.PreviewContainer) : o._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), r(e.SaveAsTemplateDrawer), e.isTestPartner() ? o._e() : r(e.OnboardingWrapper, { on: { "onboarding-finished": function(p) {
7
7
  return e.emit("onboarding:finished");
8
- } } }), r(e.UnsubscribeWrapper), r(e.LoadingWrapper)], 1);
8
+ } } }), r(e.UnsubscribeWrapper), e.isAiAssistantEnabled && e.editorStore.isChatPanelOpen ? r(e.ChatboxContainer, { on: { close: e.closeChatPanel } }) : o._e(), r(e.LoadingWrapper)], 1);
9
9
  }, n = [], s = /* @__PURE__ */ a(
10
10
  i,
11
11
  t,
12
12
  n,
13
13
  !1,
14
14
  null,
15
- "fffc13d6"
15
+ "ec575441"
16
16
  );
17
- const l = s.exports;
17
+ const f = s.exports;
18
18
  export {
19
- l as default
19
+ f as default
20
20
  };
@@ -1,132 +1,142 @@
1
- import { defineComponent as j, defineAsyncComponent as N, ref as R, computed as I, watch as J, onMounted as Q, onUnmounted as X } from "vue";
2
- import { provideGuidoActions as Y } from "../composables/useGuidoActions.js";
3
- import { usePartner as Z } from "../composables/usePartner.js";
4
- import { useStripo as ee } from "../composables/useStripo.js";
5
- import { useTimerClone as te } from "../composables/useTimerClone.js";
6
- import { migrate as W } from "../config/migrator/index.js";
7
- import { ModuleFolderDefaults as B } from "../enums/defaults.js";
8
- import { RIBBON_SELECTOR as oe } from "../enums/onboarding.js";
9
- import ne from "./organisms/AutoSaveController.vue.js";
10
- import re from "./organisms/base/Toaster.vue.js";
11
- import se from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
12
- import ce from "./organisms/header/HeaderWrapper.vue.js";
13
- import ae from "./organisms/LoadingWrapper.vue.js";
14
- import ie from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
15
- import me from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
16
- import { useStripoApi as de } from "../services/stripoApi.js";
17
- import { useConfigStore as le } from "../stores/config.js";
18
- import { useDynamicContentStore as ue } from "../stores/dynamic-content.js";
19
- import { useEditorStore as pe } from "../stores/editor.js";
20
- import { usePreviewStore as fe } from "../stores/preview.js";
21
- import { useUnsubscribeStore as ve } from "../stores/unsubscribe.js";
22
- const Ie = /* @__PURE__ */ j({
1
+ import { defineComponent as ee, defineAsyncComponent as G, ref as z, computed as S, watch as te, onMounted as oe, onUnmounted as ne } from "vue";
2
+ import { useChatState as se, resetChatModuleState as re } from "../composables/useChatState.js";
3
+ import { provideGuidoActions as ae } from "../composables/useGuidoActions.js";
4
+ import { usePartner as ce } from "../composables/usePartner.js";
5
+ import { useStripo as ie } from "../composables/useStripo.js";
6
+ import { useTimerClone as le } from "../composables/useTimerClone.js";
7
+ import { migrate as q } from "../config/migrator/index.js";
8
+ import { ModuleFolderDefaults as K } from "../enums/defaults.js";
9
+ import { RIBBON_SELECTOR as me } from "../enums/onboarding.js";
10
+ import de from "./organisms/base/Toaster.vue.js";
11
+ import pe from "./organisms/chat/chatbox/ChatboxContainer.vue.js";
12
+ import ue from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
13
+ import he from "./organisms/header/HeaderWrapper.vue.js";
14
+ import fe from "./organisms/LoadingWrapper.vue.js";
15
+ import ve from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
16
+ import ye from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
17
+ import { useStripoApi as be } from "../services/stripoApi.js";
18
+ import { useConfigStore as Se } from "../stores/config.js";
19
+ import { useDynamicContentStore as ge } from "../stores/dynamic-content.js";
20
+ import { useEditorStore as Ce } from "../stores/editor.js";
21
+ import { usePreviewStore as Ee } from "../stores/preview.js";
22
+ import { useUnsubscribeStore as we } from "../stores/unsubscribe.js";
23
+ const Ve = /* @__PURE__ */ ee({
23
24
  __name: "Guido",
24
25
  props: {
25
26
  config: null
26
27
  },
27
- emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
28
- setup(H, { expose: x, emit: r }) {
29
- const S = H, G = N(
28
+ emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click", "chat:open", "chat:close"],
29
+ setup(V, { expose: $, emit: s }) {
30
+ const g = V, j = G(
30
31
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
31
- ), z = N(
32
+ ), J = G(
32
33
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
33
- ), b = R(), d = R(), l = ue(), g = ve(), a = le();
34
- a.init(S.config);
35
- const u = pe(), q = fe(), i = I(() => u.hasChanges), { isTestPartner: K } = Z(), w = () => {
34
+ ), C = z(), d = z(), p = ge(), E = we(), c = Se();
35
+ c.init(g.config);
36
+ const u = Ce(), Q = Ee(), i = S(() => u.hasChanges), { isTestPartner: X } = ce(), w = () => {
36
37
  var e;
37
- return (e = b.value) == null ? void 0 : e.handleSave(!0);
38
+ return (e = C.value) == null ? void 0 : e.handleSave(!0);
38
39
  }, {
39
- templateId: p,
40
- userId: E,
41
- partnerName: D,
42
- username: C,
40
+ templateId: h,
41
+ userId: D,
42
+ partnerName: T,
43
+ username: P,
43
44
  template: t,
44
- editor: s
45
- } = a, m = (t == null ? void 0 : t.html) || "", T = (t == null ? void 0 : t.css) || "", f = (t == null ? void 0 : t.preselectedDynamicContent) || [], k = (s == null ? void 0 : s.savedModulesFolderName) || B.SAVED_MODULES, F = (s == null ? void 0 : s.defaultModulesFolderName) || B.DEFAULT_MODULES;
46
- u.templateId = p;
47
- const v = {
48
- emailId: p,
49
- userId: E,
50
- username: C,
51
- partnerName: D,
52
- savedModulesFolderName: k,
45
+ editor: r,
46
+ features: l
47
+ } = c, m = (t == null ? void 0 : t.html) || "", k = (t == null ? void 0 : t.css) || "", f = (t == null ? void 0 : t.preselectedDynamicContent) || [], A = (r == null ? void 0 : r.savedModulesFolderName) || K.SAVED_MODULES, F = (r == null ? void 0 : r.defaultModulesFolderName) || K.DEFAULT_MODULES;
48
+ u.templateId = h;
49
+ const { openChat: L, closeChat: M } = se(), U = S(() => !!(l != null && l.aiAssistant)), v = {
50
+ emailId: h,
51
+ userId: D,
52
+ username: P,
53
+ partnerName: T,
54
+ savedModulesFolderName: A,
53
55
  defaultModulesFolderName: F
54
- }, L = {
56
+ }, _ = {
55
57
  preselectedDynamicContentList: f,
56
58
  onReady: () => {
57
- console.debug("guido:ready"), r("ready");
59
+ console.debug("guido:ready"), s("ready");
58
60
  }
59
- }, { initPlugin: U } = ee(v, L), { getDefaultTemplate: _ } = de(), { cloneTimersOnSave: M, hasTimerBlocks: O } = te(), V = I(() => {
61
+ }, { initPlugin: O } = ie(v, _), { getDefaultTemplate: N } = be(), { cloneTimersOnSave: R, hasTimerBlocks: I } = le(), Y = S(() => {
60
62
  var e;
61
- return !((e = a.ui) != null && e.showHeader);
63
+ return !((e = c.ui) != null && e.showHeader);
62
64
  });
63
- Y({
65
+ ae({
64
66
  onBack: () => {
65
- console.debug("guido:back"), r("back");
67
+ console.debug("guido:back"), s("back");
66
68
  },
67
69
  onSaveStart: () => {
68
- console.debug("guido:save:start"), r("save:start");
70
+ console.debug("guido:save:start"), s("save:start");
69
71
  },
70
72
  onSaveComplete: (e) => {
71
73
  const n = { ...e, metadata: v };
72
- console.debug("guido:save:complete", n), r("save:complete", n);
74
+ console.debug("guido:save:complete", n), s("save:complete", n);
73
75
  },
74
76
  onTestEmailClick: () => {
75
- console.debug("guido:test-email:click"), r("test-email:click");
77
+ console.debug("guido:test-email:click"), s("test-email:click");
76
78
  }
77
79
  });
78
- const P = (e) => {
79
- console.debug("dynamic-content:close", e), l.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
80
- }, A = () => {
80
+ const W = (e) => {
81
+ console.debug("dynamic-content:close", e), p.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
82
+ }, B = () => {
81
83
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
82
84
  };
83
- J(() => i.value, () => {
84
- r("on-change", i.value);
85
+ te(() => i.value, () => {
86
+ s("on-change", i.value);
85
87
  });
86
88
  const y = (e) => {
87
- const n = e, { attribute: o, position: $ } = n.detail;
88
- console.debug("dynamic-content:open", n.detail), r("dynamic-content:open", o, $);
89
+ const n = e, { attribute: o, position: Z } = n.detail;
90
+ console.debug("dynamic-content:open", n.detail), s("dynamic-content:open", o, Z);
89
91
  };
90
- let c = null;
91
- const h = () => {
92
+ let a = null;
93
+ const b = () => {
92
94
  var n;
93
- const e = document.querySelector(oe);
95
+ const e = document.querySelector(me);
94
96
  (n = d.value) == null || n.style.setProperty("--ribbon-offset", `${(e == null ? void 0 : e.offsetHeight) ?? 0}px`);
95
97
  };
96
- return Q(async () => {
98
+ oe(async () => {
97
99
  var n;
98
- console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), h();
100
+ console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), b();
99
101
  const e = (n = d.value) == null ? void 0 : n.parentElement;
100
- e && (c = new ResizeObserver(h), c.observe(e));
102
+ e && (a = new ResizeObserver(b), a.observe(e));
101
103
  try {
102
- g.selectedUnsubscribePages = (t == null ? void 0 : t.selectedUnsubscribePages) || [];
104
+ E.selectedUnsubscribePages = (t == null ? void 0 : t.selectedUnsubscribePages) || [];
103
105
  let o = {
104
- html: m && await W(m),
105
- css: T
106
+ html: m && await q(m),
107
+ css: k
106
108
  };
107
- o.html || (o = await _(), o.html = await W(o.html)), O(o.html) && (o.html = await M(o.html)), await U(o), l.selectedDynamicContentList = f;
109
+ o.html || (o = await N(), o.html = await q(o.html)), I(o.html) && (o.html = await R(o.html)), await O(o), p.selectedDynamicContentList = f;
108
110
  } catch (o) {
109
111
  console.error("Failed to initialize Stripo editor:", o);
110
112
  }
111
113
  document.addEventListener("dynamic-content:open", y);
112
- }), X(() => {
113
- c == null || c.disconnect(), document.removeEventListener("dynamic-content:open", y);
114
+ }), ne(() => {
115
+ a == null || a.disconnect(), document.removeEventListener("dynamic-content:open", y);
114
116
  try {
115
117
  window.UIEditor.removeEditor();
116
118
  } catch {
117
119
  console.debug("Failed to remove Stripo editor: No editor found");
118
120
  }
119
- a.reset();
120
- }), x({
121
+ c.reset(), re();
122
+ });
123
+ const x = () => {
124
+ U.value && (L(), s("chat:open"));
125
+ }, H = () => {
126
+ M(), s("chat:close");
127
+ };
128
+ return $({
121
129
  dynamicContent: {
122
- insert: P,
123
- close: A
130
+ insert: W,
131
+ close: B
124
132
  },
125
133
  hasChanges: i,
126
- saveSilent: w
127
- }), { __sfc: !0, PreviewContainer: G, OnboardingWrapper: z, headerWrapperRef: b, wrapperRef: d, dynamicContentStore: l, unsubscribeStore: g, props: S, configStore: a, editorStore: u, previewStore: q, hasChanges: i, isTestPartner: K, saveSilent: w, templateId: p, userId: E, partnerName: D, username: C, templateConfig: t, editorConfig: s, html: m, css: T, preselectedDynamicContentList: f, savedModulesFolderName: k, defaultModulesFolderName: F, emit: r, metadata: v, options: L, initPlugin: U, getDefaultTemplate: _, cloneTimersOnSave: M, hasTimerBlocks: O, noHeader: V, insertDynamicContent: P, closeDynamicContent: A, handleDynamicContentOpen: y, ribbonObserver: c, updateRibbonOffset: h, AutoSaveController: ne, Toaster: re, FilterSelectionDrawer: se, HeaderWrapper: ce, LoadingWrapper: ae, SaveAsTemplateDrawer: ie, UnsubscribeWrapper: me };
134
+ saveSilent: w,
135
+ openChatPanel: x,
136
+ closeChatPanel: H
137
+ }), { __sfc: !0, PreviewContainer: j, OnboardingWrapper: J, headerWrapperRef: C, wrapperRef: d, dynamicContentStore: p, unsubscribeStore: E, props: g, configStore: c, editorStore: u, previewStore: Q, hasChanges: i, isTestPartner: X, saveSilent: w, templateId: h, userId: D, partnerName: T, username: P, templateConfig: t, editorConfig: r, features: l, html: m, css: k, preselectedDynamicContentList: f, savedModulesFolderName: A, defaultModulesFolderName: F, emit: s, openChat: L, closeChat: M, isAiAssistantEnabled: U, metadata: v, options: _, initPlugin: O, getDefaultTemplate: N, cloneTimersOnSave: R, hasTimerBlocks: I, noHeader: Y, insertDynamicContent: W, closeDynamicContent: B, handleDynamicContentOpen: y, ribbonObserver: a, updateRibbonOffset: b, openChatPanel: x, closeChatPanel: H, Toaster: de, ChatboxContainer: pe, FilterSelectionDrawer: ue, HeaderWrapper: he, LoadingWrapper: fe, SaveAsTemplateDrawer: ve, UnsubscribeWrapper: ye };
128
138
  }
129
139
  });
130
140
  export {
131
- Ie as default
141
+ Ve as default
132
142
  };
@@ -0,0 +1,20 @@
1
+ import n from "./BlueprintCard.vue2.js";
2
+ /* empty css */
3
+ import e from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var a = function() {
5
+ var t = this, s = t._self._c, r = t._self._setupProxy;
6
+ return s("button", { staticClass: "blueprint-card", attrs: { type: "button" }, on: { click: function(o) {
7
+ return t.$emit("click");
8
+ } } }, [s("span", { staticClass: "blueprint-card__icon-box" }, [s(r.InIcons, { attrs: { name: "line-smart-sirius-ai", size: "24" } })], 1), s("span", { staticClass: "blueprint-card__body" }, [s("span", { staticClass: "blueprint-card__title" }, [t._v(t._s(r.titleWithVersion))]), s("span", { staticClass: "blueprint-card__date" }, [t._v(t._s(r.formattedDate))])]), s(r.InIcons, { staticClass: "blueprint-card__chevron", attrs: { name: "line-chevron-right", size: "24" } })], 1);
9
+ }, i = [], c = /* @__PURE__ */ e(
10
+ n,
11
+ a,
12
+ i,
13
+ !1,
14
+ null,
15
+ "28b88292"
16
+ );
17
+ const m = c.exports;
18
+ export {
19
+ m as default
20
+ };
@@ -0,0 +1,20 @@
1
+ import { defineComponent as d, computed as n } from "vue";
2
+ import { InIcons as l } from "@useinsider/design-system-vue";
3
+ const f = /* @__PURE__ */ d({
4
+ __name: "BlueprintCard",
5
+ props: {
6
+ title: { default: "" },
7
+ version: { default: 1 }
8
+ },
9
+ emits: ["click"],
10
+ setup(o) {
11
+ const t = o, r = n(() => `${t.title} (v${t.version})`), s = n(() => {
12
+ const a = Date.now(), e = new Date(a), i = String(e.getDate()).padStart(2, "0"), c = String(e.getMonth() + 1).padStart(2, "0"), p = String(e.getFullYear()).slice(2);
13
+ return `${i}.${c}.${p}`;
14
+ });
15
+ return { __sfc: !0, props: t, titleWithVersion: r, formattedDate: s, InIcons: l };
16
+ }
17
+ });
18
+ export {
19
+ f as default
20
+ };
@@ -0,0 +1,23 @@
1
+ import s from "./EmailTemplateBlueprintCard.vue2.js";
2
+ /* empty css */
3
+ import l from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var i = function() {
5
+ var a = this, e = a._self._c, t = a._self._setupProxy;
6
+ return e("div", { staticClass: "email-template-card", class: {
7
+ "email-template-card--applied": t.isApplied,
8
+ "email-template-card--failed": t.isFailed
9
+ } }, [e("span", { staticClass: "email-template-card__icon-box" }, [e(t.InIcons, { attrs: { size: "24", name: t.statusIcon } })], 1), e("span", { staticClass: "email-template-card__body" }, [e("span", { staticClass: "email-template-card__title" }, [a._v(" " + a._s(t.trans("newsletter.ai-template-generated-card")) + " ")]), e("span", { staticClass: "email-template-card__meta" }, [a._v(" " + a._s(t.versionLabel) + " ")])]), e("button", { staticClass: "email-template-card__action", attrs: { type: "button", disabled: t.isApplying }, on: { click: function(_) {
10
+ return t.emit("apply");
11
+ } } }, [a._v(" " + a._s(t.buttonLabel) + " ")])]);
12
+ }, n = [], r = /* @__PURE__ */ l(
13
+ s,
14
+ i,
15
+ n,
16
+ !1,
17
+ null,
18
+ "2853740d"
19
+ );
20
+ const d = r.exports;
21
+ export {
22
+ d as default
23
+ };
@@ -0,0 +1,18 @@
1
+ import { defineComponent as m, computed as e } from "vue";
2
+ import { useTranslations as c } from "../../../../composables/useTranslations.js";
3
+ import { InIcons as f } from "@useinsider/design-system-vue";
4
+ const _ = /* @__PURE__ */ m({
5
+ __name: "EmailTemplateBlueprintCard",
6
+ props: {
7
+ version: { default: 1 },
8
+ status: { default: "pending" }
9
+ },
10
+ emits: ["apply"],
11
+ setup(i, { emit: l }) {
12
+ const t = i, s = c(), n = e(() => t.status === "applied"), r = e(() => t.status === "applying"), a = e(() => t.status === "failed"), p = e(() => r.value ? s("newsletter.ai-template-applying") : n.value ? s("newsletter.ai-template-reapply") : a.value ? s("newsletter.ai-template-retry") : s("newsletter.ai-template-apply")), u = e(() => `v${t.version}`), o = e(() => n.value ? "line-success-status" : a.value ? "line-alert-triangle" : "line-smart-sirius-ai");
13
+ return { __sfc: !0, props: t, emit: l, trans: s, isApplied: n, isApplying: r, isFailed: a, buttonLabel: p, versionLabel: u, statusIcon: o, InIcons: f };
14
+ }
15
+ });
16
+ export {
17
+ _ as default
18
+ };
@@ -0,0 +1,18 @@
1
+ import a from "./ChatboxContainer.vue2.js";
2
+ /* empty css */
3
+ import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var r = function() {
5
+ var e = this, t = e._self._c, o = e._self._setupProxy;
6
+ return t("div", { staticClass: "chatbox-container" }, [t("div", { staticClass: "chatbox-container__shell" }, [t(o.ChatboxPanel, { on: { close: o.handleClose } })], 1)]);
7
+ }, s = [], _ = /* @__PURE__ */ n(
8
+ a,
9
+ r,
10
+ s,
11
+ !1,
12
+ null,
13
+ "a5430681"
14
+ );
15
+ const m = _.exports;
16
+ export {
17
+ m as default
18
+ };
@@ -0,0 +1,16 @@
1
+ import { defineComponent as t } from "vue";
2
+ import { useChatState as s } from "../../../../composables/useChatState.js";
3
+ import n from "./ChatboxPanel.vue.js";
4
+ const p = /* @__PURE__ */ t({
5
+ __name: "ChatboxContainer",
6
+ emits: ["close"],
7
+ setup(a, { emit: o }) {
8
+ const { closeChat: e } = s();
9
+ return { __sfc: !0, emit: o, closeChat: e, handleClose: () => {
10
+ e(), o("close");
11
+ }, ChatboxPanel: n };
12
+ }
13
+ });
14
+ export {
15
+ p as default
16
+ };
@@ -0,0 +1,20 @@
1
+ import a from "./ChatboxPanel.vue2.js";
2
+ /* empty css */
3
+ import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var o = function() {
5
+ var s = this, t = s._self._c, e = s._self._setupProxy;
6
+ return t("div", { staticClass: "chatbox-panel d-f f-d-c" }, [t("div", { staticClass: "chatbox-panel__gradient" }), t(e.ChatConversation, { attrs: { "is-loading": e.isLoading, messages: e.messages }, on: { "copy-message": e.handleCopyMessage, retry: e.handleRetry, send: e.handleSend, stop: e.handleStop }, scopedSlots: s._u([{ key: "header", fn: function() {
7
+ return [t("div", { staticClass: "chatbox-panel__header d-f a-i-c j-c-s-b" }, [t("span", { staticClass: "chatbox-panel__title" }, [s._v(" " + s._s(e.trans("newsletter.ai-assistant")) + " ")]), t("button", { staticClass: "chatbox-panel__close", attrs: { type: "button", title: e.trans("newsletter.ai-close") }, on: { click: e.onClose } }, [t(e.InIcons, { attrs: { name: "line-close", size: "24" } })], 1)])];
8
+ }, proxy: !0 }]) })], 1);
9
+ }, r = [], l = /* @__PURE__ */ n(
10
+ a,
11
+ o,
12
+ r,
13
+ !1,
14
+ null,
15
+ "26934e62"
16
+ );
17
+ const p = l.exports;
18
+ export {
19
+ p as default
20
+ };
@@ -0,0 +1,19 @@
1
+ import { defineComponent as i } from "vue";
2
+ import { useChatState as p } from "../../../../composables/useChatState.js";
3
+ import { useConversationEvents as l } from "../../../../composables/useConversationEvents.js";
4
+ import { useTranslations as c } from "../../../../composables/useTranslations.js";
5
+ import f from "../conversation/ChatConversation.vue.js";
6
+ import { InIcons as C } from "@useinsider/design-system-vue";
7
+ const y = /* @__PURE__ */ i({
8
+ __name: "ChatboxPanel",
9
+ emits: ["close"],
10
+ setup(d, { emit: o }) {
11
+ const e = c(), { isLoading: s } = p(), { messages: n, handleSend: t, handleStop: r, handleRetry: a, handleCopyMessage: m } = l();
12
+ return { __sfc: !0, emit: o, trans: e, isLoading: s, messages: n, handleSend: t, handleStop: r, handleRetry: a, handleCopyMessage: m, onClose: () => {
13
+ o("close");
14
+ }, ChatConversation: f, InIcons: C };
15
+ }
16
+ });
17
+ export {
18
+ y as default
19
+ };
@@ -0,0 +1,28 @@
1
+ import a from "./ChatConversation.vue2.js";
2
+ /* empty css */
3
+ import r from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var o = function() {
5
+ var t = this, e = t._self._c, n = t._self._setupProxy;
6
+ return e("div", { ref: "scrollContainerRef", staticClass: "chat-conversation" }, [e("div", { staticClass: "chat-conversation__header w-1" }, [t._t("header")], 2), e("div", { staticClass: "chat-conversation__messages" }, [t.messages.length > 0 ? e(n.ChatMessages, { attrs: { "auto-scroll": "", messages: t.messages }, on: { "copy-message": function(s) {
7
+ return t.$emit("copy-message", s);
8
+ }, retry: function(s) {
9
+ return t.$emit("retry");
10
+ } } }) : e("div", { staticClass: "chat-conversation__empty" }, [e(n.ChatWelcome), e(n.QuickActionChips, { attrs: { compact: "" }, on: { "chip-click": function(s) {
11
+ return t.$emit("send", s);
12
+ } } })], 1)], 1), e("div", { staticClass: "chat-conversation__input" }, [e(n.ChatInput, { attrs: { "is-loading": t.isLoading }, on: { send: function(s) {
13
+ return t.$emit("send", s);
14
+ }, stop: function(s) {
15
+ return t.$emit("stop");
16
+ } } })], 1)]);
17
+ }, i = [], c = /* @__PURE__ */ r(
18
+ a,
19
+ o,
20
+ i,
21
+ !1,
22
+ null,
23
+ "5a25bfc5"
24
+ );
25
+ const p = c.exports;
26
+ export {
27
+ p as default
28
+ };
@@ -0,0 +1,20 @@
1
+ import { defineComponent as e, ref as t, provide as r } from "vue";
2
+ import s from "./ChatWelcome.vue.js";
3
+ import n from "./QuickActionChips.vue.js";
4
+ import p from "../input/ChatInput.vue.js";
5
+ import a from "../messages/ChatMessages.vue.js";
6
+ const u = /* @__PURE__ */ e({
7
+ __name: "ChatConversation",
8
+ props: {
9
+ messages: null,
10
+ isLoading: { type: Boolean }
11
+ },
12
+ emits: ["send", "stop", "retry", "copy-message"],
13
+ setup(i) {
14
+ const o = t(null);
15
+ return r("chatScrollContainer", o), { __sfc: !0, scrollContainerRef: o, ChatWelcome: s, QuickActionChips: n, ChatInput: p, ChatMessages: a };
16
+ }
17
+ });
18
+ export {
19
+ u as default
20
+ };
@@ -0,0 +1,18 @@
1
+ import _ from "./ChatWelcome.vue2.js";
2
+ /* empty css */
3
+ import a from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var r = function() {
5
+ var e = this, t = e._self._c, s = e._self._setupProxy;
6
+ return t("div", { staticClass: "chat-welcome" }, [t("p", { staticClass: "chat-welcome__subtitle" }, [e._v(" " + e._s(s.trans("newsletter.ai-welcome-subtitle")) + " ")]), t("p", { staticClass: "chat-welcome__title" }, [e._v(" " + e._s(s.trans("newsletter.ai-welcome-title")) + " ")])]);
7
+ }, l = [], c = /* @__PURE__ */ a(
8
+ _,
9
+ r,
10
+ l,
11
+ !1,
12
+ null,
13
+ "715e7d06"
14
+ );
15
+ const p = c.exports;
16
+ export {
17
+ p as default
18
+ };
@@ -0,0 +1,11 @@
1
+ import { defineComponent as t } from "vue";
2
+ import { useTranslations as e } from "../../../../composables/useTranslations.js";
3
+ const a = /* @__PURE__ */ t({
4
+ __name: "ChatWelcome",
5
+ setup(n) {
6
+ return { __sfc: !0, trans: e() };
7
+ }
8
+ });
9
+ export {
10
+ a as default
11
+ };
@@ -0,0 +1,22 @@
1
+ import s from "./QuickActionChips.vue2.js";
2
+ /* empty css */
3
+ import o from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var e = function() {
5
+ var t = this, i = t._self._c, n = t._self._setupProxy;
6
+ return i("div", { staticClass: "quick-action-chips", class: { "quick-action-chips--compact": t.compact } }, t._l(n.chips, function(c) {
7
+ return i("button", { key: c.id, staticClass: "quick-action-chips__chip", on: { click: function(p) {
8
+ return n.onChipClick(c);
9
+ } } }, [t._v(" " + t._s(c.label) + " ")]);
10
+ }), 0);
11
+ }, r = [], _ = /* @__PURE__ */ o(
12
+ s,
13
+ e,
14
+ r,
15
+ !1,
16
+ null,
17
+ "0d23f2b4"
18
+ );
19
+ const m = _.exports;
20
+ export {
21
+ m as default
22
+ };
@@ -0,0 +1,42 @@
1
+ import { defineComponent as i, computed as n } from "vue";
2
+ import { useTranslations as c } from "../../../../composables/useTranslations.js";
3
+ const u = /* @__PURE__ */ i({
4
+ __name: "QuickActionChips",
5
+ props: {
6
+ compact: { type: Boolean, default: !1 }
7
+ },
8
+ emits: ["chip-click"],
9
+ setup(s, { emit: o }) {
10
+ const t = c(), a = [
11
+ {
12
+ id: "welcome",
13
+ labelKey: "newsletter.ai-quick-welcome",
14
+ prompt: "Generate a friendly welcome email for new subscribers, with a primary CTA to the catalog."
15
+ },
16
+ {
17
+ id: "promo-vip",
18
+ labelKey: "newsletter.ai-quick-promo",
19
+ prompt: "Generate a promotional email for VIP customers with a 20% off coupon and a hero banner."
20
+ },
21
+ {
22
+ id: "cart-abandonment",
23
+ labelKey: "newsletter.ai-quick-cart",
24
+ prompt: "Generate a cart-abandonment recovery email with a recommended products section."
25
+ },
26
+ {
27
+ id: "unsubscribe-footer",
28
+ labelKey: "newsletter.ai-quick-unsubscribe",
29
+ prompt: "Add a clean unsubscribe footer with a permission-reminder line and the company address."
30
+ }
31
+ ], r = n(() => a.map((e) => ({
32
+ ...e,
33
+ label: t(e.labelKey)
34
+ })));
35
+ return { __sfc: !0, emit: o, trans: t, chipDefinitions: a, chips: r, onChipClick: (e) => {
36
+ o("chip-click", e.prompt);
37
+ } };
38
+ }
39
+ });
40
+ export {
41
+ u as default
42
+ };