@theonexai/chartsconnect-chat-widget 1.0.24 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChatWidget-Bs0XV_7i.js → ChatWidget-79vp_nl2.js} +75 -54
- package/dist/ChatWidget-79vp_nl2.js.map +1 -0
- package/dist/ChatWidget-C2nD4vfC.cjs +2 -0
- package/dist/ChatWidget-C2nD4vfC.cjs.map +1 -0
- package/dist/ChatWidget-CWV3Ff5h.js +1233 -0
- package/dist/ChatWidget-CWV3Ff5h.js.map +1 -0
- package/dist/ChatWidget-D3aD5QUM.cjs +2 -0
- package/dist/ChatWidget-D3aD5QUM.cjs.map +1 -0
- package/dist/adapters/vue/useChatMode.d.ts +4 -3
- package/dist/adapters/vue/useChatMode.d.ts.map +1 -1
- package/dist/components/ChatWidget.d.ts +3 -1
- package/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/core/stateManager.d.ts +3 -2
- package/dist/core/stateManager.d.ts.map +1 -1
- package/dist/core/types.d.ts +17 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/entry/vite.d.ts +1 -1
- package/dist/hooks/useChatMode.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.esm.js +5 -1196
- package/dist/index.esm.js.map +1 -1
- package/dist/next.cjs.js +2 -0
- package/dist/next.cjs.js.map +1 -0
- package/dist/next.esm.js +9 -0
- package/dist/next.esm.js.map +1 -0
- package/dist/nuxt.cjs.js +1 -1
- package/dist/nuxt.esm.js +2 -2
- package/dist/react.cjs.js +2 -0
- package/dist/react.cjs.js.map +1 -0
- package/dist/react.esm.js +5 -0
- package/dist/react.esm.js.map +1 -0
- package/dist/services/chatService.d.ts +0 -1
- package/dist/services/chatService.d.ts.map +1 -1
- package/dist/{sanitize-Cm1kskSD.js → types-CeJ683A3.js} +44 -23
- package/dist/types-CeJ683A3.js.map +1 -0
- package/dist/{sanitize-C8MB41vY.cjs → types-LrqQ9JyT.cjs} +3 -3
- package/dist/types-LrqQ9JyT.cjs.map +1 -0
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/vite.cjs.js +2 -0
- package/dist/vite.cjs.js.map +1 -0
- package/dist/vite.esm.js +5 -0
- package/dist/vite.esm.js.map +1 -0
- package/dist/vue.cjs.js +1 -1
- package/dist/vue.esm.js +2 -2
- package/package.json +9 -4
- package/dist/ChatWidget-Bs0XV_7i.js.map +0 -1
- package/dist/ChatWidget-PcqRrOmi.cjs +0 -2
- package/dist/ChatWidget-PcqRrOmi.cjs.map +0 -1
- package/dist/sanitize-C8MB41vY.cjs.map +0 -1
- package/dist/sanitize-Cm1kskSD.js.map +0 -1
- package/dist/services/dialogflowClient.d.ts +0 -36
- package/dist/services/dialogflowClient.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, computed, onUnmounted, watch, defineComponent, nextTick, onMounted, openBlock, createElementBlock, mergeProps, unref, createElementVNode, toDisplayString, withModifiers, createCommentVNode, createTextVNode, Fragment, renderList, normalizeClass } from "vue";
|
|
2
|
-
import {
|
|
2
|
+
import { a as createChatService, c as createDialogflowSession, g as generateMessageId, C as ChatResolvedError, s as sendDialogflowMessage, f as filterNoMatchResponse, b as safeLinkifyText } from "./types-CeJ683A3.js";
|
|
3
3
|
class WidgetStateManager {
|
|
4
4
|
constructor(config) {
|
|
5
5
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -21,6 +21,7 @@ class WidgetStateManager {
|
|
|
21
21
|
this.historyLoaded = null;
|
|
22
22
|
this.typingTimeout = null;
|
|
23
23
|
this.agentTypingTimeout = null;
|
|
24
|
+
this.welcomePopupTimeout = null;
|
|
24
25
|
this.config = config;
|
|
25
26
|
this.state = {
|
|
26
27
|
isOpen: false,
|
|
@@ -38,7 +39,7 @@ class WidgetStateManager {
|
|
|
38
39
|
debug: this.config.debug || false
|
|
39
40
|
});
|
|
40
41
|
if (typeof window !== "undefined" && window.localStorage) {
|
|
41
|
-
const savedMode = localStorage.getItem("
|
|
42
|
+
const savedMode = localStorage.getItem("chartsconnect_chat_mode");
|
|
42
43
|
this.chatMode = savedMode === "HUMAN" ? "human" : "ai";
|
|
43
44
|
this.state.chatMode = this.chatMode;
|
|
44
45
|
this.chatId = localStorage.getItem("chartsconnect_chat_id");
|
|
@@ -98,7 +99,7 @@ class WidgetStateManager {
|
|
|
98
99
|
});
|
|
99
100
|
if (session.message) {
|
|
100
101
|
const welcomeMessage = {
|
|
101
|
-
id:
|
|
102
|
+
id: generateMessageId("welcome"),
|
|
102
103
|
text: session.message,
|
|
103
104
|
sender: "bot",
|
|
104
105
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -115,7 +116,7 @@ class WidgetStateManager {
|
|
|
115
116
|
error: error.message || "Failed to initialize chat"
|
|
116
117
|
});
|
|
117
118
|
const fallbackMessage = {
|
|
118
|
-
id:
|
|
119
|
+
id: generateMessageId("fallback"),
|
|
119
120
|
text: this.config.fallbackWelcomeMessage || "Hello! How can I help you today?",
|
|
120
121
|
sender: "bot",
|
|
121
122
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -141,11 +142,11 @@ class WidgetStateManager {
|
|
|
141
142
|
/**
|
|
142
143
|
* Toggle chat
|
|
143
144
|
*/
|
|
144
|
-
toggleChat() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.
|
|
145
|
+
async toggleChat() {
|
|
146
|
+
if (this.state.isOpen) {
|
|
147
|
+
this.closeChat();
|
|
148
|
+
} else {
|
|
149
|
+
await this.openChat();
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
/**
|
|
@@ -169,7 +170,7 @@ class WidgetStateManager {
|
|
|
169
170
|
}
|
|
170
171
|
if (this.collectingUserInfo) {
|
|
171
172
|
const userMessage = {
|
|
172
|
-
id:
|
|
173
|
+
id: generateMessageId("user"),
|
|
173
174
|
text: text.trim(),
|
|
174
175
|
sender: "user",
|
|
175
176
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -185,7 +186,7 @@ class WidgetStateManager {
|
|
|
185
186
|
}
|
|
186
187
|
if (!skipUserMessage) {
|
|
187
188
|
const userMessage = {
|
|
188
|
-
id:
|
|
189
|
+
id: generateMessageId("user"),
|
|
189
190
|
text: text.trim(),
|
|
190
191
|
sender: "user",
|
|
191
192
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -216,7 +217,7 @@ class WidgetStateManager {
|
|
|
216
217
|
return;
|
|
217
218
|
}
|
|
218
219
|
const errorMessage = {
|
|
219
|
-
id:
|
|
220
|
+
id: generateMessageId("error"),
|
|
220
221
|
text: this.config.debug ? `Error: ${error.message || "Failed to send message"}` : error.message?.includes("CORS") || error.message?.includes("Failed to fetch") ? "Unable to connect to Dialogflow. Please check your configuration and network." : "Sorry, I'm having trouble processing your message. Please try again.",
|
|
221
222
|
sender: "bot",
|
|
222
223
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -266,31 +267,40 @@ class WidgetStateManager {
|
|
|
266
267
|
});
|
|
267
268
|
}
|
|
268
269
|
if (response.handoff === true) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
if (response.response) {
|
|
271
|
+
const botMessage = {
|
|
272
|
+
id: generateMessageId("bot"),
|
|
273
|
+
text: response.response,
|
|
274
|
+
sender: "bot",
|
|
275
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
276
|
+
richContent: response.richContent
|
|
277
|
+
};
|
|
278
|
+
this.setState({
|
|
279
|
+
messages: [...this.state.messages, botMessage],
|
|
280
|
+
isLoading: false
|
|
281
|
+
});
|
|
282
|
+
} else {
|
|
283
|
+
this.setState({ isLoading: false });
|
|
284
|
+
}
|
|
285
|
+
this.startUserInfoCollection();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const filteredText = filterNoMatchResponse(response.response, this.config.noMatchMessage);
|
|
289
|
+
if (filteredText) {
|
|
290
|
+
const botMessage = {
|
|
291
|
+
id: generateMessageId("bot"),
|
|
292
|
+
text: filteredText,
|
|
272
293
|
sender: "bot",
|
|
273
294
|
timestamp: /* @__PURE__ */ new Date(),
|
|
274
295
|
richContent: response.richContent
|
|
275
296
|
};
|
|
276
297
|
this.setState({
|
|
277
|
-
messages: [...this.state.messages,
|
|
298
|
+
messages: [...this.state.messages, botMessage],
|
|
278
299
|
isLoading: false
|
|
279
300
|
});
|
|
280
|
-
|
|
281
|
-
|
|
301
|
+
} else {
|
|
302
|
+
this.setState({ isLoading: false });
|
|
282
303
|
}
|
|
283
|
-
const botMessage = {
|
|
284
|
-
id: `bot-${Date.now()}`,
|
|
285
|
-
text: response.response || this.config.fallbackWelcomeMessage || "No response",
|
|
286
|
-
sender: "bot",
|
|
287
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
288
|
-
richContent: response.richContent
|
|
289
|
-
};
|
|
290
|
-
this.setState({
|
|
291
|
-
messages: [...this.state.messages, botMessage],
|
|
292
|
-
isLoading: false
|
|
293
|
-
});
|
|
294
304
|
}
|
|
295
305
|
/**
|
|
296
306
|
* Send message to human support
|
|
@@ -298,7 +308,7 @@ class WidgetStateManager {
|
|
|
298
308
|
async sendHumanMessage(text) {
|
|
299
309
|
if (!this.chatId || !this.supportSessionId) {
|
|
300
310
|
const errorMessage = {
|
|
301
|
-
id:
|
|
311
|
+
id: generateMessageId("error"),
|
|
302
312
|
text: "Chat session not initialized. Please try again.",
|
|
303
313
|
sender: "bot",
|
|
304
314
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -398,7 +408,8 @@ class WidgetStateManager {
|
|
|
398
408
|
initializeWelcomePopup() {
|
|
399
409
|
if (this.config.showWelcomePopup !== false) {
|
|
400
410
|
const delay = this.config.welcomePopupDelay || 1500;
|
|
401
|
-
setTimeout(() => {
|
|
411
|
+
this.welcomePopupTimeout = setTimeout(() => {
|
|
412
|
+
this.welcomePopupTimeout = null;
|
|
402
413
|
if (!this.state.isOpen) {
|
|
403
414
|
this.setState({ showWelcomePopup: true });
|
|
404
415
|
}
|
|
@@ -415,7 +426,7 @@ class WidgetStateManager {
|
|
|
415
426
|
this.collectedUserEmail = "";
|
|
416
427
|
this.collectedUserMobile = "";
|
|
417
428
|
const namePrompt = {
|
|
418
|
-
id:
|
|
429
|
+
id: generateMessageId("prompt"),
|
|
419
430
|
text: "To connect you with a human agent, I'll need some information. Please provide your name:",
|
|
420
431
|
sender: "bot",
|
|
421
432
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -433,7 +444,7 @@ class WidgetStateManager {
|
|
|
433
444
|
this.collectedUserName = name;
|
|
434
445
|
this.userInfoStep = "email";
|
|
435
446
|
const emailPrompt = {
|
|
436
|
-
id:
|
|
447
|
+
id: generateMessageId("prompt"),
|
|
437
448
|
text: "Thank you! Now please provide your email address:",
|
|
438
449
|
sender: "bot",
|
|
439
450
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -448,7 +459,7 @@ class WidgetStateManager {
|
|
|
448
459
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
449
460
|
if (!emailRegex.test(email)) {
|
|
450
461
|
const invalidEmailMessage = {
|
|
451
|
-
id:
|
|
462
|
+
id: generateMessageId("prompt"),
|
|
452
463
|
text: "Please provide a valid email address:",
|
|
453
464
|
sender: "bot",
|
|
454
465
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -462,7 +473,7 @@ class WidgetStateManager {
|
|
|
462
473
|
this.collectedUserEmail = email;
|
|
463
474
|
this.userInfoStep = "mobile";
|
|
464
475
|
const mobilePrompt = {
|
|
465
|
-
id:
|
|
476
|
+
id: generateMessageId("prompt"),
|
|
466
477
|
text: "Thank you! Now please provide your mobile number:",
|
|
467
478
|
sender: "bot",
|
|
468
479
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -477,7 +488,7 @@ class WidgetStateManager {
|
|
|
477
488
|
const mobileRegex = /^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/;
|
|
478
489
|
if (!mobileRegex.test(mobile) || mobile.length < 10) {
|
|
479
490
|
const invalidMobileMessage = {
|
|
480
|
-
id:
|
|
491
|
+
id: generateMessageId("prompt"),
|
|
481
492
|
text: "Please provide a valid mobile number (e.g., +1234567890):",
|
|
482
493
|
sender: "bot",
|
|
483
494
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -588,7 +599,7 @@ class WidgetStateManager {
|
|
|
588
599
|
this.chatResolved = false;
|
|
589
600
|
this.agentAccepted = false;
|
|
590
601
|
const connectingMessage = {
|
|
591
|
-
id:
|
|
602
|
+
id: generateMessageId("connecting"),
|
|
592
603
|
text: "Connecting you to a human agent...",
|
|
593
604
|
sender: "bot",
|
|
594
605
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -612,7 +623,7 @@ class WidgetStateManager {
|
|
|
612
623
|
} catch (error) {
|
|
613
624
|
console.error("Error handling handoff:", error);
|
|
614
625
|
const errorMessage = {
|
|
615
|
-
id:
|
|
626
|
+
id: generateMessageId("error"),
|
|
616
627
|
text: this.config.debug ? `Handoff error: ${error.message}` : "Failed to connect to agent. Please try again.",
|
|
617
628
|
sender: "bot",
|
|
618
629
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -632,7 +643,7 @@ class WidgetStateManager {
|
|
|
632
643
|
if (message.content) {
|
|
633
644
|
if (message.sender_type === "agent" || !message.sender_type) {
|
|
634
645
|
const agentMessage = {
|
|
635
|
-
id: message.id ||
|
|
646
|
+
id: message.id || generateMessageId("agent"),
|
|
636
647
|
text: message.content,
|
|
637
648
|
sender: "agent",
|
|
638
649
|
timestamp: new Date(message.timestamp || Date.now())
|
|
@@ -678,7 +689,7 @@ class WidgetStateManager {
|
|
|
678
689
|
name: message.to_agent
|
|
679
690
|
};
|
|
680
691
|
const systemMessage = {
|
|
681
|
-
id:
|
|
692
|
+
id: generateMessageId("system"),
|
|
682
693
|
text: message.from_agent ? `Chat has been transferred from ${message.from_agent} to ${message.to_agent}` : `Chat has been transferred to ${message.to_agent}`,
|
|
683
694
|
sender: "bot",
|
|
684
695
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -692,7 +703,7 @@ class WidgetStateManager {
|
|
|
692
703
|
this.agentAccepted = true;
|
|
693
704
|
this.isConnectingToAgent = false;
|
|
694
705
|
const acceptedMessage = {
|
|
695
|
-
id: message.id ||
|
|
706
|
+
id: message.id || generateMessageId("agent-accepted"),
|
|
696
707
|
text: "You can chat now, the agent has accepted your request.",
|
|
697
708
|
sender: "bot",
|
|
698
709
|
timestamp: message.timestamp ? new Date(message.timestamp) : /* @__PURE__ */ new Date()
|
|
@@ -731,7 +742,7 @@ class WidgetStateManager {
|
|
|
731
742
|
case "error":
|
|
732
743
|
console.error("WebSocket error:", message.error);
|
|
733
744
|
const errorMessage = {
|
|
734
|
-
id:
|
|
745
|
+
id: generateMessageId("error"),
|
|
735
746
|
text: message.error || "An error occurred. Please try again.",
|
|
736
747
|
sender: "bot",
|
|
737
748
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -764,7 +775,7 @@ class WidgetStateManager {
|
|
|
764
775
|
localStorage.removeItem("chartsconnect_session_id");
|
|
765
776
|
}
|
|
766
777
|
const thankYouMessage = {
|
|
767
|
-
id:
|
|
778
|
+
id: generateMessageId("resolved"),
|
|
768
779
|
text: "Thank you for contacting us!",
|
|
769
780
|
sender: "bot",
|
|
770
781
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -802,7 +813,7 @@ class WidgetStateManager {
|
|
|
802
813
|
});
|
|
803
814
|
if (session.message) {
|
|
804
815
|
const welcomeMessage = {
|
|
805
|
-
id:
|
|
816
|
+
id: generateMessageId("welcome"),
|
|
806
817
|
text: session.message,
|
|
807
818
|
sender: "bot",
|
|
808
819
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -819,7 +830,7 @@ class WidgetStateManager {
|
|
|
819
830
|
error: error.message || "Failed to initialize chat"
|
|
820
831
|
});
|
|
821
832
|
const fallbackMessage = {
|
|
822
|
-
id:
|
|
833
|
+
id: generateMessageId("fallback"),
|
|
823
834
|
text: this.config.fallbackWelcomeMessage || "Hello! How can I help you today?",
|
|
824
835
|
sender: "bot",
|
|
825
836
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -842,7 +853,7 @@ class WidgetStateManager {
|
|
|
842
853
|
if (this.chatId && this.supportSessionId) {
|
|
843
854
|
const history = await this.chatService.loadMessageHistory(this.chatId, this.supportSessionId);
|
|
844
855
|
const historyMessages = history.map((msg) => ({
|
|
845
|
-
id: msg.id ||
|
|
856
|
+
id: msg.id || generateMessageId("history"),
|
|
846
857
|
text: msg.content,
|
|
847
858
|
sender: msg.sender_type === "agent" ? "agent" : "user",
|
|
848
859
|
timestamp: new Date(msg.timestamp)
|
|
@@ -866,7 +877,7 @@ class WidgetStateManager {
|
|
|
866
877
|
console.error("Error loading message history:", error);
|
|
867
878
|
if (this.config.debug) {
|
|
868
879
|
const errorMessage = {
|
|
869
|
-
id:
|
|
880
|
+
id: generateMessageId("error"),
|
|
870
881
|
text: `Failed to load chat history: ${error.message}`,
|
|
871
882
|
sender: "bot",
|
|
872
883
|
timestamp: /* @__PURE__ */ new Date()
|
|
@@ -900,6 +911,9 @@ class WidgetStateManager {
|
|
|
900
911
|
if (this.agentTypingTimeout) {
|
|
901
912
|
clearTimeout(this.agentTypingTimeout);
|
|
902
913
|
}
|
|
914
|
+
if (this.welcomePopupTimeout) {
|
|
915
|
+
clearTimeout(this.welcomePopupTimeout);
|
|
916
|
+
}
|
|
903
917
|
if (this.chatService) {
|
|
904
918
|
this.chatService.disconnectWebSocket();
|
|
905
919
|
}
|
|
@@ -981,7 +995,9 @@ const _hoisted_3 = { class: "custom-welcome-message" };
|
|
|
981
995
|
const _hoisted_4 = { class: "custom-welcome-cta" };
|
|
982
996
|
const _hoisted_5 = {
|
|
983
997
|
key: 2,
|
|
984
|
-
class: "custom-chat-window"
|
|
998
|
+
class: "custom-chat-window",
|
|
999
|
+
role: "dialog",
|
|
1000
|
+
"aria-label": "Chat window"
|
|
985
1001
|
};
|
|
986
1002
|
const _hoisted_6 = { class: "custom-chat-header" };
|
|
987
1003
|
const _hoisted_7 = { class: "custom-chat-header-content" };
|
|
@@ -1040,7 +1056,7 @@ const _hoisted_26 = {
|
|
|
1040
1056
|
key: 4,
|
|
1041
1057
|
class: "custom-agent-typing-indicator"
|
|
1042
1058
|
};
|
|
1043
|
-
const _hoisted_27 = ["value", "placeholder", "disabled"];
|
|
1059
|
+
const _hoisted_27 = ["value", "placeholder", "aria-label", "disabled"];
|
|
1044
1060
|
const _hoisted_28 = ["disabled"];
|
|
1045
1061
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
1046
1062
|
...{
|
|
@@ -1065,7 +1081,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1065
1081
|
fallbackWelcomeMessage: { default: "Hello! I'm Charts Connect AI Assistant. How can I help you today?" },
|
|
1066
1082
|
inputPlaceholder: { default: "Type your message..." },
|
|
1067
1083
|
emptyStateMessage: { default: "Hi! I'm Charts Connect AI Assistant. How can I help you today?" },
|
|
1068
|
-
debug: { type: Boolean, default: false }
|
|
1084
|
+
debug: { type: Boolean, default: false },
|
|
1085
|
+
noMatchMessage: {}
|
|
1069
1086
|
},
|
|
1070
1087
|
setup(__props) {
|
|
1071
1088
|
const props = __props;
|
|
@@ -1208,7 +1225,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1208
1225
|
createElementVNode("div", {
|
|
1209
1226
|
class: "custom-chat-messages",
|
|
1210
1227
|
ref_key: "messagesContainer",
|
|
1211
|
-
ref: messagesContainer
|
|
1228
|
+
ref: messagesContainer,
|
|
1229
|
+
role: "log",
|
|
1230
|
+
"aria-live": "polite",
|
|
1231
|
+
"aria-label": "Chat messages"
|
|
1212
1232
|
}, [
|
|
1213
1233
|
isInitializing.value && unref(state).messages.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_15, [..._cache[2] || (_cache[2] = [
|
|
1214
1234
|
createElementVNode("div", { class: "custom-typing-indicator" }, [
|
|
@@ -1232,7 +1252,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1232
1252
|
}, [
|
|
1233
1253
|
createElementVNode("div", {
|
|
1234
1254
|
class: normalizeClass(["custom-message-content", { "custom-handoff-content": isHandoffMessage(message.text) }]),
|
|
1235
|
-
innerHTML: unref(safeLinkifyText)(message.text)
|
|
1255
|
+
innerHTML: unref(safeLinkifyText)(message.text)
|
|
1236
1256
|
}, null, 10, _hoisted_17),
|
|
1237
1257
|
message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_18, [
|
|
1238
1258
|
(openBlock(true), createElementBlock(Fragment, null, renderList(message.richContent, (contentGroup, groupIndex) => {
|
|
@@ -1308,6 +1328,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1308
1328
|
value: unref(state).inputValue,
|
|
1309
1329
|
onInput: handleInput,
|
|
1310
1330
|
placeholder: config.value.inputPlaceholder,
|
|
1331
|
+
"aria-label": config.value.inputPlaceholder,
|
|
1311
1332
|
disabled: unref(state).isLoading || isInitializing.value || isStartingNewChat.value
|
|
1312
1333
|
}, null, 40, _hoisted_27),
|
|
1313
1334
|
createElementVNode("button", {
|
|
@@ -1347,10 +1368,10 @@ const _export_sfc = (sfc, props) => {
|
|
|
1347
1368
|
}
|
|
1348
1369
|
return target;
|
|
1349
1370
|
};
|
|
1350
|
-
const ChatWidgetComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
1371
|
+
const ChatWidgetComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-2c695aef"]]);
|
|
1351
1372
|
export {
|
|
1352
1373
|
ChatWidgetComponent as C,
|
|
1353
1374
|
WidgetStateManager as W,
|
|
1354
1375
|
useChatWidget as u
|
|
1355
1376
|
};
|
|
1356
|
-
//# sourceMappingURL=ChatWidget-
|
|
1377
|
+
//# sourceMappingURL=ChatWidget-79vp_nl2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidget-79vp_nl2.js","sources":["../src/core/stateManager.ts","../src/composables/useChatWidget.ts","../src/components/ChatWidget.vue"],"sourcesContent":["/**\n * State Manager - Framework Agnostic\n * Manages widget state independently of framework\n */\n\nimport { generateMessageId, filterNoMatchResponse, type WidgetState, type WidgetConfig, type ChatMessage } from './types';\nimport {\n createDialogflowSession,\n sendDialogflowMessage,\n type DialogflowBackendConfig,\n} from '../services/dialogflowBackendService';\nimport { \n createChatService, \n ChatResolvedError,\n type WebSocketMessage\n} from '../services/chatService';\n\nexport class WidgetStateManager {\n private state: WidgetState;\n private config: WidgetConfig;\n private listeners: Set<(state: WidgetState) => void> = new Set();\n private chatMode: 'ai' | 'human' = 'ai';\n private chatId: string | null = null;\n private supportSessionId: string | null = null;\n private chatService: ReturnType<typeof createChatService> | null = null;\n \n // User info collection for handoff\n private collectingUserInfo: boolean = false;\n private userInfoStep: 'name' | 'email' | 'mobile' | null = null;\n private collectedUserName: string = '';\n private collectedUserEmail: string = '';\n private collectedUserMobile: string = '';\n \n // Additional state for human support\n private wsConnected: boolean = false;\n private agentTyping: boolean = false;\n private currentAgent: { name: string; id?: string } = { name: 'Agent' };\n private isConnectingToAgent: boolean = false;\n private agentAccepted: boolean = false;\n private chatResolved: boolean = false;\n private historyLoaded: string | null = null;\n \n // Typing timeout refs (stored as class properties since we can't use refs)\n private typingTimeout: NodeJS.Timeout | null = null;\n private agentTypingTimeout: NodeJS.Timeout | null = null;\n private welcomePopupTimeout: NodeJS.Timeout | null = null;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.state = {\n isOpen: false,\n showWelcomePopup: false,\n messages: [],\n inputValue: '',\n isLoading: false,\n error: null,\n sessionId: null,\n chatMode: 'ai',\n };\n \n // Initialize ChatService\n this.chatService = createChatService({\n baseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n wsUrl: this.config.backendWsUrl || 'ws://localhost:8012',\n debug: this.config.debug || false,\n });\n \n // Load chat mode and chat IDs from localStorage if available\n if (typeof window !== 'undefined' && window.localStorage) {\n const savedMode = localStorage.getItem('chartsconnect_chat_mode');\n this.chatMode = savedMode === 'HUMAN' ? 'human' : 'ai';\n this.state.chatMode = this.chatMode;\n \n this.chatId = localStorage.getItem('chartsconnect_chat_id');\n this.supportSessionId = localStorage.getItem('chartsconnect_session_id');\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: (state: WidgetState) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return { ...this.state };\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<WidgetState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach(listener => listener(this.getState()));\n }\n\n /**\n * Update configuration\n */\n updateConfig(config: Partial<WidgetConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Open chat\n */\n async openChat(): Promise<void> {\n this.setState({ isOpen: true });\n if (this.state.showWelcomePopup) {\n this.setState({ showWelcomePopup: false });\n }\n \n // Initialize Dialogflow session when chat opens (if in AI mode and no session exists)\n if (this.state.chatMode === 'ai' && !this.state.sessionId && this.config.dfProjectId && this.config.dfAgentId) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: generateMessageId('welcome'),\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error initializing Dialogflow session:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: generateMessageId('fallback'),\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }\n\n /**\n * Close chat\n */\n closeChat(): void {\n this.setState({ isOpen: false });\n }\n\n /**\n * Close welcome popup\n */\n closeWelcomePopup(): void {\n this.setState({ showWelcomePopup: false });\n }\n\n /**\n * Toggle chat\n */\n async toggleChat(): Promise<void> {\n if (this.state.isOpen) {\n this.closeChat();\n } else {\n await this.openChat();\n }\n }\n\n /**\n * Set input value\n */\n setInputValue(value: string): void {\n this.setState({ inputValue: value });\n }\n\n /**\n * Clear error\n */\n clearError(): void {\n this.setState({ error: null });\n }\n\n /**\n * Send message\n */\n async sendMessage(text: string, skipUserMessage: boolean = false): Promise<void> {\n if (!text.trim() || this.state.isLoading) {\n return;\n }\n\n // Handle user info collection for handoff\n if (this.collectingUserInfo) {\n // Add user message first so it appears in chat\n const userMessage: ChatMessage = {\n id: generateMessageId('user'),\n text: text.trim(),\n sender: 'user',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: false,\n error: null,\n });\n \n // Then handle the info collection\n await this.handleUserInfoCollection(text);\n return;\n }\n\n // Add user message unless skipped (e.g., when chip button already added it)\n if (!skipUserMessage) {\n const userMessage: ChatMessage = {\n id: generateMessageId('user'),\n text: text.trim(),\n sender: 'user',\n timestamp: new Date(),\n };\n\n this.setState({\n messages: [...this.state.messages, userMessage],\n inputValue: '',\n isLoading: true,\n error: null,\n });\n } else {\n this.setState({\n inputValue: '',\n isLoading: true,\n error: null,\n });\n }\n\n try {\n if (this.state.chatMode === 'human') {\n // Human support mode\n await this.sendHumanMessage(text);\n } else {\n // AI mode (Dialogflow)\n await this.sendAIMessage(text);\n }\n } catch (error: any) {\n console.error('Error sending message:', error);\n \n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n \n // Add error message to chat\n const errorMessage: ChatMessage = {\n id: generateMessageId('error'),\n text: this.config.debug \n ? `Error: ${error.message || 'Failed to send message'}`\n : error.message?.includes('CORS') || error.message?.includes('Failed to fetch')\n ? 'Unable to connect to Dialogflow. Please check your configuration and network.'\n : 'Sorry, I\\'m having trouble processing your message. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n \n this.setState({\n messages: [...this.state.messages, errorMessage],\n error: error.message || 'Failed to send message',\n isLoading: false,\n });\n }\n }\n\n /**\n * Send message to Dialogflow\n */\n private async sendAIMessage(text: string): Promise<void> {\n if (!this.config.dfProjectId || !this.config.dfAgentId) {\n throw new Error('Dialogflow configuration is missing');\n }\n\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId!,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId!,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n\n // Create session if needed\n if (!this.state.sessionId) {\n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ sessionId: session.session_id });\n }\n\n // Send message (correct parameter order: message, sessionId, config)\n if (this.config.debug) {\n console.log('Sending message to Dialogflow:', {\n message: text,\n sessionId: this.state.sessionId,\n hasConfig: !!dialogflowConfig,\n });\n }\n \n const response = await sendDialogflowMessage(\n text,\n this.state.sessionId!,\n dialogflowConfig\n );\n\n if (this.config.debug) {\n console.log('Dialogflow response:', {\n response: response.response,\n hasRichContent: !!response.richContent,\n richContent: response.richContent,\n });\n }\n\n // Check for handoff\n if (response.handoff === true) {\n // Add bot response first (only if there's actual text)\n if (response.response) {\n const botMessage: ChatMessage = {\n id: generateMessageId('bot'),\n text: response.response,\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n } else {\n this.setState({ isLoading: false });\n }\n\n // Start collecting user info for handoff\n this.startUserInfoCollection();\n return;\n }\n\n // Filter no-match/fallback responses from Dialogflow\n const filteredText = filterNoMatchResponse(response.response, this.config.noMatchMessage);\n\n if (filteredText) {\n const botMessage: ChatMessage = {\n id: generateMessageId('bot'),\n text: filteredText,\n sender: 'bot',\n timestamp: new Date(),\n richContent: response.richContent,\n };\n\n this.setState({\n messages: [...this.state.messages, botMessage],\n isLoading: false,\n });\n } else {\n // No-match response suppressed — don't show any bubble\n this.setState({ isLoading: false });\n }\n }\n\n /**\n * Send message to human support\n */\n private async sendHumanMessage(text: string): Promise<void> {\n if (!this.chatId || !this.supportSessionId) {\n const errorMessage: ChatMessage = {\n id: generateMessageId('error'),\n text: 'Chat session not initialized. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n isLoading: false,\n });\n return;\n }\n\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n // Send typing_stop before sending message\n this.chatService.sendTypingIndicator('typing_stop');\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n this.typingTimeout = null;\n }\n\n try {\n // Try WebSocket first, fallback to REST API\n const sentViaWs = this.chatService.sendMessageViaWebSocket(text.trim());\n \n if (!sentViaWs) {\n // Fallback to REST API\n await this.chatService.sendMessageToAgent(this.chatId, this.supportSessionId, text.trim());\n }\n \n this.setState({ isLoading: false });\n } catch (error: any) {\n // chat_resolved is a normal terminal condition, not an error\n if (error instanceof ChatResolvedError || error?.name === 'ChatResolvedError' || error?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n\n // Handle 401/404 - clear chat_id and reinitialize\n if (error.message?.includes('Chat not found') ||\n error.message?.includes('unauthorized') ||\n error.message?.includes('401') ||\n error.message?.includes('404')) {\n if (this.config.debug) {\n console.log('⚠️ Chat expired. Re-initializing...');\n }\n \n // Clear chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Try to reinitialize chat\n try {\n const newSession = await this.chatService.startSupportChat(\n this.state.sessionId || null,\n null,\n null,\n null\n );\n this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry sending message\n if (this.chatId && this.supportSessionId) {\n await this.chatService.sendMessageToAgent(\n this.chatId,\n this.supportSessionId,\n text.trim()\n );\n }\n this.setState({ isLoading: false });\n return;\n } catch (retryError: any) {\n if (retryError instanceof ChatResolvedError || retryError?.message === 'chat_resolved') {\n this.enterResolvedState(this.chatId);\n return;\n }\n throw retryError;\n }\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Switch to human mode\n */\n switchToHumanMode(): void {\n this.chatMode = 'human';\n this.setState({ chatMode: 'human' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'HUMAN');\n }\n }\n\n /**\n * Switch to AI mode\n */\n switchToBotMode(): void {\n this.chatMode = 'ai';\n this.setState({ chatMode: 'ai' });\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_mode', 'BOT');\n }\n }\n\n /**\n * Initialize welcome popup\n */\n initializeWelcomePopup(): void {\n if (this.config.showWelcomePopup !== false) {\n const delay = this.config.welcomePopupDelay || 1500;\n this.welcomePopupTimeout = setTimeout(() => {\n this.welcomePopupTimeout = null;\n if (!this.state.isOpen) {\n this.setState({ showWelcomePopup: true });\n }\n }, delay);\n }\n }\n\n /**\n * Start user info collection for handoff\n */\n private startUserInfoCollection(): void {\n this.collectingUserInfo = true;\n this.userInfoStep = 'name';\n this.collectedUserName = '';\n this.collectedUserEmail = '';\n this.collectedUserMobile = '';\n \n // Ask for name\n const namePrompt: ChatMessage = {\n id: generateMessageId('prompt'),\n text: 'To connect you with a human agent, I\\'ll need some information. Please provide your name:',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, namePrompt],\n });\n }\n\n /**\n * Handle user info collection\n */\n private async handleUserInfoCollection(text: string): Promise<void> {\n if (this.userInfoStep === 'name') {\n // Save name and ask for email\n const name = text.trim();\n this.collectedUserName = name;\n this.userInfoStep = 'email';\n \n // Ask for email\n const emailPrompt: ChatMessage = {\n id: generateMessageId('prompt'),\n text: 'Thank you! Now please provide your email address:',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, emailPrompt],\n inputValue: '',\n });\n return;\n } else if (this.userInfoStep === 'email') {\n // Validate email format\n const email = text.trim();\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n \n if (!emailRegex.test(email)) {\n // Invalid email, ask again\n const invalidEmailMessage: ChatMessage = {\n id: generateMessageId('prompt'),\n text: 'Please provide a valid email address:',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, invalidEmailMessage],\n inputValue: '',\n });\n return;\n }\n \n // Save email and ask for mobile\n this.collectedUserEmail = email;\n this.userInfoStep = 'mobile';\n \n // Ask for mobile\n const mobilePrompt: ChatMessage = {\n id: generateMessageId('prompt'),\n text: 'Thank you! Now please provide your mobile number:',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, mobilePrompt],\n inputValue: '',\n });\n return;\n } else if (this.userInfoStep === 'mobile') {\n // Validate mobile format\n const mobile = text.trim();\n const mobileRegex = /^[\\+]?[(]?[0-9]{1,4}[)]?[-\\s\\.]?[(]?[0-9]{1,4}[)]?[-\\s\\.]?[0-9]{1,9}$/;\n \n if (!mobileRegex.test(mobile) || mobile.length < 10) {\n // Invalid mobile, ask again\n const invalidMobileMessage: ChatMessage = {\n id: generateMessageId('prompt'),\n text: 'Please provide a valid mobile number (e.g., +1234567890):',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, invalidMobileMessage],\n inputValue: '',\n });\n return;\n }\n \n // Save mobile and proceed with handoff\n this.collectedUserMobile = mobile;\n \n // Reset collection state\n this.collectingUserInfo = false;\n this.userInfoStep = null;\n \n // Proceed with handoff using collected info\n await this.handleHandoff(this.collectedUserName, this.collectedUserEmail, mobile);\n this.setState({ inputValue: '' });\n }\n }\n\n /**\n * Handle handoff from Dialogflow to human support\n */\n async handleHandoff(customerName?: string, customerEmail?: string, customerMobile?: string): Promise<void> {\n if (!this.chatService) {\n throw new Error('Chat service not initialized');\n }\n\n try {\n this.isConnectingToAgent = true;\n \n // Get Dialogflow session ID if available\n const dialogflowSessionId = this.state.sessionId;\n \n // STEP 1: Ensure chat is initialized\n const session = await this.chatService.ensureChatInitialized(\n this.chatId,\n this.supportSessionId,\n dialogflowSessionId || null,\n customerName || null,\n customerEmail || null,\n customerMobile || null\n );\n \n if (!session || !session.chat_id) {\n throw new Error('Failed to initialize chat session');\n }\n \n const currentChatId = session.chat_id;\n const currentSupportSessionId = session.session_id;\n \n // Update state if chat was newly initialized\n if (currentChatId !== this.chatId) {\n this.chatId = currentChatId;\n this.supportSessionId = currentSupportSessionId;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n if (this.config.debug) {\n console.log('✅ Chat initialized:', { chatId: currentChatId, sessionId: currentSupportSessionId });\n }\n }\n\n // STEP 2: Request handoff\n try {\n await this.chatService.requestHandoff(\n currentChatId,\n currentSupportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null,\n customerName || null,\n customerEmail || null,\n customerMobile || null\n );\n \n if (this.config.debug) {\n console.log('✅ Handoff requested successfully');\n }\n } catch (handoffError: any) {\n // Handle 401/404 or \"chat not found\" - clear chat_id and retry\n if (handoffError.message?.includes('Invalid chat_id') || \n handoffError.message?.includes('Chat not found') ||\n handoffError.message?.includes('unauthorized') ||\n handoffError.message?.includes('400') ||\n handoffError.message?.includes('401') ||\n handoffError.message?.includes('404') ||\n handoffError.message?.includes('expired')) {\n if (this.config.debug) {\n console.log('⚠️ Chat expired or not found. Re-initializing chat...');\n }\n \n // Clear old chat_id\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Create new chat session\n const newSession = await this.chatService.startSupportChat(\n dialogflowSessionId || null,\n customerName || null,\n customerEmail || null,\n customerMobile || null\n );\n \n if (!newSession || !newSession.chat_id) {\n throw new Error('Failed to re-initialize chat session');\n }\n \n this.chatId = newSession.chat_id;\n this.supportSessionId = newSession.session_id;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem('chartsconnect_chat_id', this.chatId);\n localStorage.setItem('chartsconnect_session_id', this.supportSessionId);\n }\n \n // Retry handoff with new chat_id\n await this.chatService.requestHandoff(\n this.chatId,\n this.supportSessionId,\n 'Customer requested human agent',\n dialogflowSessionId || null,\n customerName || null,\n customerEmail || null,\n customerMobile || null\n );\n \n if (this.config.debug) {\n console.log('✅ Handoff requested successfully after retry');\n }\n } else {\n throw handoffError;\n }\n }\n\n // Switch to human mode\n this.switchToHumanMode();\n this.chatResolved = false;\n this.agentAccepted = false;\n\n // Add connecting message\n const connectingMessage: ChatMessage = {\n id: generateMessageId('connecting'),\n text: 'Connecting you to a human agent...',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, connectingMessage],\n });\n\n // Connect WebSocket with handlers\n if (currentChatId && currentSupportSessionId) {\n this.chatService.connectWebSocket(\n currentChatId,\n currentSupportSessionId,\n (message: WebSocketMessage) => {\n this.handleWebSocketMessage(message);\n },\n (connected: boolean) => {\n this.wsConnected = connected;\n }\n );\n }\n \n this.isConnectingToAgent = false;\n } catch (error: any) {\n console.error('Error handling handoff:', error);\n const errorMessage: ChatMessage = {\n id: generateMessageId('error'),\n text: this.config.debug\n ? `Handoff error: ${error.message}`\n : 'Failed to connect to agent. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n this.isConnectingToAgent = false;\n }\n }\n\n /**\n * Handle WebSocket messages\n */\n private handleWebSocketMessage(message: WebSocketMessage): void {\n switch (message.type) {\n case 'message':\n if (message.content) {\n // Only display messages from agent\n if (message.sender_type === 'agent' || !message.sender_type) {\n const agentMessage: ChatMessage = {\n id: message.id || generateMessageId('agent'),\n text: message.content,\n sender: 'agent',\n timestamp: new Date(message.timestamp || Date.now()),\n };\n \n // Avoid duplicate messages\n const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(agentMessage.id)) {\n this.setState({\n messages: [...this.state.messages, agentMessage],\n });\n }\n \n // Hide typing indicator when message received\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n }\n break;\n\n case 'typing_start':\n if (message.sender_type === 'agent') {\n this.agentTyping = true;\n // Auto-hide after 3 seconds if no message received\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n this.agentTypingTimeout = setTimeout(() => {\n this.agentTyping = false;\n }, 3000);\n }\n break;\n\n case 'typing_stop':\n if (message.sender_type === 'agent') {\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n }\n break;\n\n case 'agent_changed':\n if (message.to_agent) {\n this.currentAgent = {\n id: message.to_agent_id,\n name: message.to_agent,\n };\n\n // Add system message to chat\n const systemMessage: ChatMessage = {\n id: generateMessageId('system'),\n text: message.from_agent\n ? `Chat has been transferred from ${message.from_agent} to ${message.to_agent}`\n : `Chat has been transferred to ${message.to_agent}`,\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, systemMessage],\n });\n }\n break;\n\n case 'agent_accepted':\n this.agentAccepted = true;\n this.isConnectingToAgent = false;\n const acceptedMessage: ChatMessage = {\n id: message.id || generateMessageId('agent-accepted'),\n text: 'You can chat now, the agent has accepted your request.',\n sender: 'bot',\n timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),\n };\n const existingIds = new Set(this.state.messages.map(m => m.id));\n if (!existingIds.has(acceptedMessage.id)) {\n this.setState({\n messages: [...this.state.messages, acceptedMessage],\n });\n }\n if (message.to_agent) {\n this.currentAgent = {\n name: message.to_agent,\n id: message.to_agent_id,\n };\n }\n break;\n\n case 'chat_resolved':\n case 'chat_ended':\n this.enterResolvedState(message.chat_id || null);\n break;\n\n case 'chat_info':\n if (message.status === 'active') {\n this.isConnectingToAgent = false;\n this.agentAccepted = true;\n } else if (message.status === 'resolved' || message.status === 'ended') {\n this.enterResolvedState(message.chat_id || null);\n }\n if (message.agent_id) {\n this.currentAgent = {\n ...this.currentAgent,\n id: message.agent_id,\n };\n }\n break;\n\n case 'error':\n console.error('WebSocket error:', message.error);\n const errorMessage: ChatMessage = {\n id: generateMessageId('error'),\n text: message.error || 'An error occurred. Please try again.',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n break;\n }\n }\n\n /**\n * Enter resolved state\n */\n private enterResolvedState(resolvedChatId?: string | null): void {\n this.chatResolved = true;\n this.isConnectingToAgent = false;\n this.agentAccepted = false;\n this.agentTyping = false;\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n this.agentTypingTimeout = null;\n }\n\n // Stop WS + prevent any reuse of the old chat_id\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.chatId = null;\n this.supportSessionId = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem('chartsconnect_chat_id');\n localStorage.removeItem('chartsconnect_session_id');\n }\n \n // Add thank you message before reset\n const thankYouMessage: ChatMessage = {\n id: generateMessageId('resolved'),\n text: 'Thank you for contacting us!',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, thankYouMessage],\n });\n \n // Automatically reset to BOT mode after showing thank you message\n setTimeout(async () => {\n this.switchToBotMode();\n this.chatResolved = false;\n this.setState({\n messages: [],\n sessionId: null, // Clear session ID to force recreation\n });\n this.collectingUserInfo = false;\n this.userInfoStep = null;\n this.collectedUserName = '';\n this.collectedUserEmail = '';\n this.collectedUserMobile = '';\n \n // Recreate Dialogflow session to start fresh\n if (this.config.dfProjectId && this.config.dfAgentId && this.state.isOpen) {\n try {\n this.setState({ isLoading: true });\n const dialogflowConfig: DialogflowBackendConfig = {\n dfProjectId: this.config.dfProjectId,\n dfLocation: this.config.dfLocation || 'us-central1',\n dfAgentId: this.config.dfAgentId,\n languageCode: this.config.languageCode || 'en',\n backendBaseUrl: this.config.backendBaseUrl || 'http://localhost:8012',\n };\n \n const session = await createDialogflowSession(dialogflowConfig);\n this.setState({ \n sessionId: session.session_id,\n isLoading: false,\n });\n \n // Add welcome message from Dialogflow if available\n if (session.message) {\n const welcomeMessage: ChatMessage = {\n id: generateMessageId('welcome'),\n text: session.message,\n sender: 'bot',\n timestamp: new Date(),\n richContent: session.richContent,\n };\n this.setState({\n messages: [welcomeMessage],\n });\n }\n } catch (error: any) {\n console.error('Error recreating Dialogflow session after handoff:', error);\n this.setState({ \n isLoading: false,\n error: error.message || 'Failed to initialize chat',\n });\n \n // Show fallback welcome message\n const fallbackMessage: ChatMessage = {\n id: generateMessageId('fallback'),\n text: this.config.fallbackWelcomeMessage || 'Hello! How can I help you today?',\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [fallbackMessage],\n });\n }\n }\n }, 2000);\n }\n\n /**\n * Load message history\n */\n async loadMessageHistory(preserveExisting: boolean = false): Promise<void> {\n if (!this.chatService || !this.chatId || !this.supportSessionId) {\n return;\n }\n\n try {\n if (this.chatId && this.supportSessionId) {\n const history = await this.chatService.loadMessageHistory(this.chatId, this.supportSessionId);\n \n const historyMessages: ChatMessage[] = history.map((msg: any) => ({\n id: msg.id || generateMessageId('history'),\n text: msg.content,\n sender: msg.sender_type === 'agent' ? 'agent' : 'user',\n timestamp: new Date(msg.timestamp),\n }));\n\n if (preserveExisting) {\n // Merge with existing messages, avoiding duplicates\n const existingIds = new Set(this.state.messages.map(m => m.id));\n const newMessages = historyMessages.filter(m => !existingIds.has(m.id));\n \n // Combine existing messages with new history messages\n // Sort by timestamp to maintain chronological order\n const combined = [...this.state.messages, ...newMessages].sort((a, b) => \n a.timestamp.getTime() - b.timestamp.getTime()\n );\n \n this.setState({\n messages: combined,\n });\n } else {\n // Replace all messages\n this.setState({\n messages: historyMessages,\n });\n }\n }\n } catch (error: any) {\n console.error('Error loading message history:', error);\n if (this.config.debug) {\n const errorMessage: ChatMessage = {\n id: generateMessageId('error'),\n text: `Failed to load chat history: ${error.message}`,\n sender: 'bot',\n timestamp: new Date(),\n };\n this.setState({\n messages: [...this.state.messages, errorMessage],\n });\n }\n }\n }\n\n /**\n * Get additional state for UI (not in WidgetState but needed by components)\n */\n getAdditionalState() {\n return {\n wsConnected: this.wsConnected,\n agentTyping: this.agentTyping,\n currentAgent: this.currentAgent,\n isConnectingToAgent: this.isConnectingToAgent,\n agentAccepted: this.agentAccepted,\n chatResolved: this.chatResolved,\n };\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n if (this.typingTimeout) {\n clearTimeout(this.typingTimeout);\n }\n if (this.agentTypingTimeout) {\n clearTimeout(this.agentTypingTimeout);\n }\n if (this.welcomePopupTimeout) {\n clearTimeout(this.welcomePopupTimeout);\n }\n if (this.chatService) {\n this.chatService.disconnectWebSocket();\n }\n this.listeners.clear();\n }\n}\n","/**\n * useChatWidget Composable\n * Headless mode for Vue 3 - use logic without UI\n */\n\nimport { ref, computed, onUnmounted, watch, readonly, type Ref } from 'vue';\nimport { WidgetStateManager } from '../core/stateManager';\nimport type { WidgetConfig, WidgetState, ChatMessage } from '../core/types';\n\nexport interface UseChatWidgetReturn {\n // State\n state: Readonly<Ref<WidgetState>>;\n isOpen: Readonly<Ref<boolean>>;\n messages: Readonly<Ref<ChatMessage[]>>;\n isLoading: Readonly<Ref<boolean>>;\n error: Readonly<Ref<string | null>>;\n chatMode: Readonly<Ref<'ai' | 'human'>>;\n\n // Additional state\n wsConnected: Readonly<Ref<boolean>>;\n agentTyping: Readonly<Ref<boolean>>;\n currentAgent: Readonly<Ref<{ name: string; id?: string }>>;\n isConnectingToAgent: Readonly<Ref<boolean>>;\n\n // Actions\n openChat: () => Promise<void>;\n closeChat: () => void;\n sendMessage: (text: string) => Promise<void>;\n toggleChat: () => Promise<void>;\n setInputValue: (value: string) => void;\n clearError: () => void;\n\n // Manager instance (for advanced usage)\n manager: WidgetStateManager;\n}\n\n/**\n * Headless chat widget composable\n * Use this for custom UI implementations\n */\nexport function useChatWidget(config: WidgetConfig): UseChatWidgetReturn {\n // Create state manager\n const manager = new WidgetStateManager(config);\n\n // Reactive state\n const state = ref<WidgetState>(manager.getState());\n const wsConnected = ref(false);\n const agentTyping = ref(false);\n const currentAgent = ref<{ name: string; id?: string }>({ name: 'Agent' });\n const isConnectingToAgent = ref(false);\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n state.value = { ...newState };\n \n // Update additional state\n const additional = manager.getAdditionalState();\n wsConnected.value = additional.wsConnected;\n agentTyping.value = additional.agentTyping;\n currentAgent.value = additional.currentAgent;\n isConnectingToAgent.value = additional.isConnectingToAgent;\n });\n\n // Computed properties\n const isOpen = computed(() => state.value.isOpen);\n const messages = computed(() => state.value.messages);\n const isLoading = computed(() => state.value.isLoading);\n const error = computed(() => state.value.error);\n const chatMode = computed(() => state.value.chatMode);\n\n // Actions\n const openChat = async () => {\n await manager.openChat();\n };\n\n const closeChat = () => {\n manager.closeChat();\n };\n\n const sendMessage = async (text: string) => {\n await manager.sendMessage(text);\n };\n\n const toggleChat = async () => {\n await manager.toggleChat();\n };\n\n const setInputValue = (value: string) => {\n manager.setInputValue(value);\n };\n\n const clearError = () => {\n manager.clearError();\n };\n\n // Cleanup on unmount\n onUnmounted(() => {\n unsubscribe();\n manager.destroy();\n });\n\n // Watch config changes\n watch(\n () => config,\n (newConfig) => {\n manager.updateConfig(newConfig);\n },\n { deep: true }\n );\n\n return {\n state: state as Readonly<Ref<WidgetState>>,\n isOpen: isOpen as Readonly<Ref<boolean>>,\n messages: messages as Readonly<Ref<ChatMessage[]>>,\n isLoading: isLoading as Readonly<Ref<boolean>>,\n error: error as Readonly<Ref<string | null>>,\n chatMode: chatMode as Readonly<Ref<'ai' | 'human'>>,\n wsConnected: wsConnected as Readonly<Ref<boolean>>,\n agentTyping: agentTyping as Readonly<Ref<boolean>>,\n currentAgent: currentAgent as Readonly<Ref<{ name: string; id?: string }>>,\n isConnectingToAgent: isConnectingToAgent as Readonly<Ref<boolean>>,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n };\n}\n","<template>\n <div class=\"custom-chat-widget\" v-bind=\"$attrs\">\n <!-- Welcome Popup -->\n <div\n v-if=\"state.showWelcomePopup && !state.isOpen\"\n class=\"custom-welcome-popup\"\n @click=\"handleOpenChat\"\n >\n <div class=\"custom-welcome-header\">\n <div class=\"custom-welcome-title\">{{ config.welcomeTitle }}</div>\n <button\n class=\"custom-close-popup\"\n @click.stop=\"handleCloseWelcomePopup\"\n aria-label=\"Close welcome popup\"\n >\n ×\n </button>\n </div>\n <div class=\"custom-welcome-message\">{{ config.welcomeMessage }}</div>\n <div class=\"custom-welcome-cta\">{{ config.welcomeCta }}</div>\n </div>\n\n <!-- Chat Toggle Button -->\n <button\n v-if=\"!state.isOpen\"\n class=\"custom-chat-toggle-btn\"\n @click=\"handleOpenChat\"\n aria-label=\"Open chat\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\n </svg>\n </button>\n\n <!-- Chat Window -->\n <div v-if=\"state.isOpen\" class=\"custom-chat-window\" role=\"dialog\" aria-label=\"Chat window\">\n <div class=\"custom-chat-header\">\n <div class=\"custom-chat-header-content\">\n <div class=\"custom-chat-title\">{{ config.title }}</div>\n <div class=\"custom-chat-subtitle\">\n {{ config.subtitle }}\n <span v-if=\"state.chatMode === 'human'\" class=\"custom-mode-indicator\">\n • {{ wsConnected ? '🟢 Connected' : '🟡 Connecting...' }}\n </span>\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-mode-badge\">\n Human Support Mode\n </div>\n <div v-if=\"state.chatMode === 'human'\" class=\"custom-agent-info\">\n <span class=\"custom-agent-label\">Agent:</span>\n <span class=\"custom-agent-name\">{{ currentAgent.name }}</span>\n </div>\n <div v-if=\"state.chatMode === 'ai'\" class=\"custom-mode-badge\">\n Bot Mode\n </div>\n </div>\n <button\n class=\"custom-chat-close-btn\"\n @click=\"handleCloseChat\"\n aria-label=\"Close chat\"\n >\n ×\n </button>\n </div>\n\n <div class=\"custom-chat-messages\" ref=\"messagesContainer\" role=\"log\" aria-live=\"polite\" aria-label=\"Chat messages\">\n <!-- Empty State -->\n <div v-if=\"isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <p>Initializing chat...</p>\n </div>\n <div v-else-if=\"!isInitializing && state.messages.length === 0\" class=\"custom-chat-empty\">\n <div class=\"custom-chat-empty-icon\">👋</div>\n <p>{{ config.emptyStateMessage }}</p>\n </div>\n\n <!-- Messages -->\n <div\n v-for=\"message in state.messages\"\n :key=\"message.id\"\n :class=\"[\n 'custom-message', \n `custom-message-${message.sender}`,\n { 'custom-handoff-message': isHandoffMessage(message.text) }\n ]\"\n >\n <div \n class=\"custom-message-content\"\n :class=\"{ 'custom-handoff-content': isHandoffMessage(message.text) }\"\n v-html=\"safeLinkifyText(message.text)\"\n ></div>\n \n <!-- Rich Content (Chips) -->\n <div\n v-if=\"message.richContent && Array.isArray(message.richContent) && message.richContent.length > 0\"\n class=\"custom-chips-container\"\n >\n <template v-for=\"(contentGroup, groupIndex) in message.richContent\" :key=\"groupIndex\">\n <template v-if=\"!Array.isArray(contentGroup)\">\n <div\n v-if=\"contentGroup.type === 'chips' && contentGroup.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in contentGroup.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n <template v-else>\n <template\n v-for=\"(content, contentIndex) in contentGroup\"\n :key=\"`${groupIndex}-${contentIndex}`\"\n >\n <div\n v-if=\"content.type === 'chips' && content.options\"\n class=\"custom-chips-group\"\n >\n <button\n v-for=\"(chip, chipIndex) in content.options\"\n :key=\"chipIndex\"\n class=\"custom-chip-button\"\n type=\"button\"\n @click=\"handleChipClick(chip.text, chip.payload)\"\n >\n {{ chip.text }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n\n <div class=\"custom-message-time\">\n {{ formatTime(message.timestamp) }}\n </div>\n </div>\n\n <!-- Loading Indicator -->\n <div v-if=\"state.isLoading\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n </div>\n\n <!-- Connecting to Agent Indicator -->\n <div v-if=\"isConnectingToAgent\" class=\"custom-message custom-message-bot\">\n <div class=\"custom-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <div class=\"custom-message-content\">\n Connecting to agent...\n </div>\n </div>\n\n <!-- Agent Typing Indicator -->\n <div v-if=\"state.chatMode === 'human' && agentTyping\" class=\"custom-agent-typing-indicator\">\n <span class=\"custom-typing-dots\">\n <span></span>\n <span></span>\n <span></span>\n </span>\n <span class=\"custom-typing-text\">Agent is typing...</span>\n </div>\n\n <div ref=\"messagesEndRef\"></div>\n </div>\n\n <!-- Input Form -->\n <form class=\"custom-chat-input-form\" @submit.prevent=\"handleSubmit\">\n <input\n type=\"text\"\n class=\"custom-chat-input\"\n :value=\"state.inputValue\"\n @input=\"handleInput\"\n :placeholder=\"config.inputPlaceholder\"\n :aria-label=\"config.inputPlaceholder\"\n :disabled=\"state.isLoading || isInitializing || isStartingNewChat\"\n />\n <button\n type=\"submit\"\n class=\"custom-chat-send-btn\"\n :disabled=\"!state.inputValue.trim() || state.isLoading || isInitializing || isStartingNewChat\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </form>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, nextTick, watch } from 'vue';\nimport { useChatWidget } from '../composables/useChatWidget';\nimport { safeLinkifyText } from '../utils/sanitize';\nimport type { WidgetConfig } from '../core/types';\n\n// Handle attributes properly to avoid Vue warnings\n// For Vue 3.3+, defineOptions is available as a compiler macro\n// @ts-ignore - defineOptions is a compiler macro\ndefineOptions({\n inheritAttrs: false, // We handle attrs manually via v-bind=\"$attrs\"\n});\n\n// Props\nconst props = withDefaults(defineProps<WidgetConfig>(), {\n title: '💬 Charts Connect AI Assistant',\n subtitle: \"We're here to help\",\n welcomeTitle: '👋 Welcome to Charts Connect',\n welcomeMessage: \"My name is Charts Connect AI Assistant and I'll guide you.\",\n welcomeCta: '💬 Click here to start chatting!',\n showWelcomePopup: true,\n welcomePopupDelay: 1500,\n fallbackWelcomeMessage: \"Hello! I'm Charts Connect AI Assistant. How can I help you today?\",\n inputPlaceholder: 'Type your message...',\n emptyStateMessage: \"Hi! I'm Charts Connect AI Assistant. How can I help you today?\",\n debug: false,\n});\n\n// Use headless composable\nconst {\n state,\n isOpen,\n messages,\n isLoading,\n error,\n chatMode,\n wsConnected,\n agentTyping,\n currentAgent,\n isConnectingToAgent: isConnectingToAgentFromComposable,\n openChat,\n closeChat,\n sendMessage,\n toggleChat,\n setInputValue,\n clearError,\n manager,\n} = useChatWidget(props);\n\n// Refs\nconst messagesEndRef = ref<HTMLDivElement | null>(null);\nconst messagesContainer = ref<HTMLDivElement | null>(null);\n\n// Computed config (for reactivity)\nconst config = computed(() => props);\n\n// Computed state for initialization and connection (matching React component)\nconst isInitializing = computed(() => {\n return state.value.isLoading && state.value.messages.length === 0 && !state.value.sessionId;\n});\n\nconst isStartingNewChat = computed(() => {\n // This would be tracked in manager if needed, for now return false\n return false;\n});\n\n// Use isConnectingToAgent from composable (already computed in manager)\nconst isConnectingToAgent = isConnectingToAgentFromComposable;\n\n// Auto-scroll to bottom when messages change\nwatch(\n () => messages.value.length,\n () => {\n nextTick(() => {\n messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n);\n\n// Handlers\nconst handleOpenChat = async () => {\n // Ensure immediate UI response\n if (!state.value.isOpen) {\n state.value.isOpen = true;\n state.value.showWelcomePopup = false;\n }\n await openChat();\n};\n\nconst handleCloseChat = () => {\n closeChat();\n};\n\nconst handleCloseWelcomePopup = () => {\n manager.closeWelcomePopup();\n};\n\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n setInputValue(target.value);\n};\n\nconst handleSubmit = async (event: Event) => {\n event.preventDefault();\n if (state.value.inputValue.trim()) {\n await sendMessage(state.value.inputValue);\n }\n};\n\nconst handleChipClick = async (chipText: string, payload?: string) => {\n const messageToSend = chipText || payload || '';\n await sendMessage(messageToSend);\n};\n\n// Utility functions\nconst formatTime = (date: Date): string => {\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n });\n};\n\n// Check if message is a handoff message\nconst isHandoffMessage = (text: string): boolean => {\n return text.includes('👤') || \n text.includes('being connected') || \n text.includes('live support agent') ||\n text.includes('transfer your conversation');\n};\n\n// Initialize welcome popup on mount (SSR-safe)\nonMounted(() => {\n if (config.value.showWelcomePopup && typeof window !== 'undefined') {\n manager.initializeWelcomePopup();\n }\n});\n</script>\n\n<style scoped>\n/* Styles are imported separately by users */\n/* This ensures SSR compatibility */\n</style>\n"],"names":["existingIds","_openBlock","_createElementBlock","_mergeProps","$attrs","_unref","_createElementVNode","_toDisplayString","_Fragment","_renderList","_normalizeClass"],"mappings":"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"}
|