open-chat-studio-widget 0.5.0 → 0.5.2
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/cjs/{index-CC3Krx2K.js → index-Ctja7z-R.js} +3 -3
- package/dist/cjs/{index-CC3Krx2K.js.map → index-Ctja7z-R.js.map} +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js +45 -38
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.js +1 -1
- package/dist/cjs/open-chat-studio-widget.entry.cjs.js.map +1 -1
- package/dist/collection/components/ocs-chat/ocs-chat.js +44 -37
- package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
- package/dist/collection/services/chat-session-service.js.map +1 -1
- package/dist/collection/utils/translations.js +2 -2
- package/dist/collection/utils/translations.js.map +1 -1
- package/dist/components/open-chat-studio-widget.js +44 -37
- package/dist/components/open-chat-studio-widget.js.map +1 -1
- package/dist/esm/{index-BF7CYZiN.js → index-BbCwiO7g.js} +3 -3
- package/dist/esm/{index-BF7CYZiN.js.map → index-BbCwiO7g.js.map} +1 -1
- package/dist/esm/loader.js +2 -2
- package/dist/esm/open-chat-studio-widget.entry.js +45 -38
- package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
- package/dist/esm/open-chat-studio-widget.js +2 -2
- package/dist/open-chat-studio-widget/open-chat-studio-widget.entry.esm.js.map +1 -1
- package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
- package/dist/open-chat-studio-widget/{p-400b1f47.entry.js → p-96920183.entry.js} +4 -4
- package/dist/open-chat-studio-widget/p-96920183.entry.js.map +1 -0
- package/dist/open-chat-studio-widget/{p-BF7CYZiN.js → p-BbCwiO7g.js} +2 -2
- package/dist/open-chat-studio-widget/{p-BF7CYZiN.js.map → p-BbCwiO7g.js.map} +1 -1
- package/dist/types/components/ocs-chat/ocs-chat.d.ts +5 -1
- package/dist/types/services/chat-session-service.d.ts +0 -1
- package/package.json +2 -2
- package/dist/open-chat-studio-widget/p-400b1f47.entry.js.map +0 -1
|
@@ -235,17 +235,16 @@ export class OcsChat {
|
|
|
235
235
|
this.chatWindowFullscreenWidth = varToPixels(fullscreenWidthVar, window.innerWidth, this.chatWindowFullscreenWidth);
|
|
236
236
|
// Initialize button position from computed styles
|
|
237
237
|
this.initializeButtonPosition();
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
238
|
+
// Defer position initialization to avoid state changes during componentDidLoad
|
|
239
|
+
setTimeout(() => {
|
|
240
|
+
if (this.visible) {
|
|
241
|
+
this.initializePosition();
|
|
242
|
+
}
|
|
243
|
+
// Resume polling for existing session (don't auto-start new sessions)
|
|
244
|
+
if (this.visible && this.sessionId) {
|
|
245
|
+
this.startMessagePolling();
|
|
246
|
+
}
|
|
247
|
+
}, 0);
|
|
249
248
|
window.addEventListener('resize', this.handleWindowResize);
|
|
250
249
|
}
|
|
251
250
|
disconnectedCallback() {
|
|
@@ -357,13 +356,7 @@ export class OcsChat {
|
|
|
357
356
|
const data = await this.getChatService().startSession(requestBody);
|
|
358
357
|
this.sessionId = data.session_id;
|
|
359
358
|
this.saveSessionToStorage();
|
|
360
|
-
|
|
361
|
-
if (data.seed_message_task_id) {
|
|
362
|
-
this.startTaskPolling(data.seed_message_task_id);
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
this.startMessagePolling();
|
|
366
|
-
}
|
|
359
|
+
this.startMessagePolling();
|
|
367
360
|
}
|
|
368
361
|
catch (_error) {
|
|
369
362
|
this.handleError('Failed to start chat session');
|
|
@@ -392,8 +385,20 @@ export class OcsChat {
|
|
|
392
385
|
}
|
|
393
386
|
}
|
|
394
387
|
async sendMessage(message) {
|
|
395
|
-
if (!
|
|
388
|
+
if (!message.trim())
|
|
396
389
|
return;
|
|
390
|
+
// Start session if we don't have one yet
|
|
391
|
+
if (!this.sessionId) {
|
|
392
|
+
// Prevent concurrent session initialization
|
|
393
|
+
if (this.isLoading) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
await this.startSession();
|
|
397
|
+
// Check if session started successfully
|
|
398
|
+
if (!this.sessionId) {
|
|
399
|
+
return; // startSession already handled the error
|
|
400
|
+
}
|
|
401
|
+
}
|
|
397
402
|
try {
|
|
398
403
|
let attachmentIds = [];
|
|
399
404
|
if (this.allowAttachments && this.selectedFiles.length > 0) {
|
|
@@ -408,10 +413,11 @@ export class OcsChat {
|
|
|
408
413
|
}
|
|
409
414
|
// If this is the first user message and there are welcome messages,
|
|
410
415
|
// add them to chat history as assistant messages
|
|
411
|
-
|
|
416
|
+
const welcomeMessagesToAdd = this.getWelcomeMessages();
|
|
417
|
+
if (this.messages.length === 0 && welcomeMessagesToAdd.length > 0) {
|
|
412
418
|
const now = new Date();
|
|
413
|
-
const welcomeMessages =
|
|
414
|
-
created_at: new Date(now.getTime() - (
|
|
419
|
+
const welcomeMessages = welcomeMessagesToAdd.map((welcomeMsg, index) => ({
|
|
420
|
+
created_at: new Date(now.getTime() - (welcomeMessagesToAdd.length - index) * 1000).toISOString(),
|
|
415
421
|
role: 'assistant',
|
|
416
422
|
content: welcomeMsg,
|
|
417
423
|
attachments: []
|
|
@@ -545,16 +551,14 @@ export class OcsChat {
|
|
|
545
551
|
}
|
|
546
552
|
if (visible) {
|
|
547
553
|
this.initializePosition();
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.stopMessagePolling();
|
|
554
|
+
// Resume polling for existing session (don't auto-start new sessions)
|
|
555
|
+
if (this.sessionId) {
|
|
556
|
+
this.scrollToBottom(true);
|
|
557
|
+
this.startMessagePolling();
|
|
558
|
+
}
|
|
554
559
|
}
|
|
555
560
|
else {
|
|
556
|
-
this.
|
|
557
|
-
this.startMessagePolling();
|
|
561
|
+
this.stopMessagePolling();
|
|
558
562
|
}
|
|
559
563
|
}
|
|
560
564
|
startTaskPolling(taskId) {
|
|
@@ -1057,9 +1061,13 @@ export class OcsChat {
|
|
|
1057
1061
|
}
|
|
1058
1062
|
async confirmNewChat() {
|
|
1059
1063
|
this.hideConfirmationDialog();
|
|
1060
|
-
await this.
|
|
1064
|
+
await this.clearSession();
|
|
1061
1065
|
}
|
|
1062
|
-
|
|
1066
|
+
/**
|
|
1067
|
+
* This clears out all data related to the previous session. A new session
|
|
1068
|
+
* will start when the user sends a message.
|
|
1069
|
+
*/
|
|
1070
|
+
async clearSession() {
|
|
1063
1071
|
this.clearSessionStorage();
|
|
1064
1072
|
this.sessionId = undefined;
|
|
1065
1073
|
this.messages = [];
|
|
@@ -1069,7 +1077,6 @@ export class OcsChat {
|
|
|
1069
1077
|
this.selectedFiles = [];
|
|
1070
1078
|
}
|
|
1071
1079
|
this.cleanup();
|
|
1072
|
-
await this.startSession();
|
|
1073
1080
|
}
|
|
1074
1081
|
toggleFullscreen() {
|
|
1075
1082
|
this.isFullscreen = !this.isFullscreen;
|
|
@@ -1081,18 +1088,18 @@ export class OcsChat {
|
|
|
1081
1088
|
if (this.error && !this.sessionId) {
|
|
1082
1089
|
return (h(Host, null, h("p", { class: "error-message" }, this.error)));
|
|
1083
1090
|
}
|
|
1084
|
-
return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: (el) => this.chatWindowRef = el, id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots header-button" }, h(GripDotsVerticalIcon, null))), h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), h("div", { class: "header-buttons" }, this.messages.length > 0 && (h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, h(PlusWithCircleIcon, null))), this.allowFullScreen && h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen'), "aria-label": this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen') }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null)), h("button", { class: "header-button", onClick: () => this.visible = false, "aria-label": this.translationManager.get('window.close') }, h(XMarkIcon, null)))), this.showNewChatConfirmation && (h("div", { class: "confirmation-overlay" }, h("div", { class: "confirmation-dialog" }, h("div", { class: "confirmation-content" }, h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), h("div", { class: "confirmation-buttons" }, h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), h("div", { class: "chat-content" }, this.isLoading && !this.sessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), (h("div", { ref: (el) => this.messageListRef = el, class: "messages-container" }, this.messages.length === 0 && this.
|
|
1091
|
+
return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: (el) => this.chatWindowRef = el, id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots header-button" }, h(GripDotsVerticalIcon, null))), h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), h("div", { class: "header-buttons" }, this.messages.length > 0 && (h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, h(PlusWithCircleIcon, null))), this.allowFullScreen && h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen'), "aria-label": this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen') }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null)), h("button", { class: "header-button", onClick: () => this.visible = false, "aria-label": this.translationManager.get('window.close') }, h(XMarkIcon, null)))), this.showNewChatConfirmation && (h("div", { class: "confirmation-overlay" }, h("div", { class: "confirmation-dialog" }, h("div", { class: "confirmation-content" }, h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), h("div", { class: "confirmation-buttons" }, h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), h("div", { class: "chat-content" }, this.isLoading && !this.sessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), (h("div", { ref: (el) => this.messageListRef = el, class: "messages-container" }, this.messages.length === 0 && this.getWelcomeMessages().length > 0 && (h("div", { class: "welcome-messages" }, this.getWelcomeMessages().map((message, index) => (h("div", { key: `welcome-${index}`, class: "message-row message-row-assistant" }, h("div", { class: "message-bubble message-bubble-assistant" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, h("div", { class: `message-bubble ${message.role === 'user'
|
|
1085
1092
|
? 'message-bubble-user'
|
|
1086
1093
|
: message.role === 'assistant'
|
|
1087
1094
|
? 'message-bubble-assistant'
|
|
1088
|
-
: 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" })))))), this.messages.length === 0 && this.
|
|
1095
|
+
: 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" })))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (h("div", { class: "selected-files-container" }, h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index) => (h("div", { key: index, class: "selected-file-item" }, h("div", { class: "flex items-center gap-[0.5em]" }, h("span", { class: "selected-file-icon" }, h(PaperClipIcon, null)), h("span", null, selectedFile.file.name), h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && (h("span", { class: "selected-file-error" }, selectedFile.error)), selectedFile.uploaded && (h("span", { class: "selected-file-success-icon" }, h(CheckDocumentIcon, null)))), h("button", { onClick: () => this.removeSelectedFile(index), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, h(XIcon, null)))))))), h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: (el) => this.textareaRef = el, class: "message-textarea", rows: 1, placeholder: this.translationManager.get('composer.placeholder'), value: this.messageInput, onInput: (e) => this.handleInputChange(e), onKeyPress: (e) => this.handleKeyPress(e), disabled: this.isTyping || this.isUploadingFiles || this.isLoading }), this.allowAttachments && (h("input", { ref: (el) => {
|
|
1089
1096
|
// Unclear why but after removing all attachments this is being set to `null`.
|
|
1090
1097
|
if (el) {
|
|
1091
1098
|
this.fileInputRef = el;
|
|
1092
1099
|
}
|
|
1093
|
-
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(','), onChange: (e) => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (h("button", { class: "file-attachment-button", onClick: () => { var _a; return (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: this.isTyping || this.isUploadingFiles, title: this.translationManager.get('attach.add'), "aria-label": this.translationManager.get('attach.add') }, h(PaperClipIcon, null))), h("button", { class: `send-button ${!this.isTyping && !!this.messageInput.trim()
|
|
1100
|
+
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(','), onChange: (e) => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (h("button", { class: "file-attachment-button", onClick: () => { var _a; return (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: this.isTyping || this.isUploadingFiles || this.isLoading, title: this.translationManager.get('attach.add'), "aria-label": this.translationManager.get('attach.add') }, h(PaperClipIcon, null))), h("button", { class: `send-button ${!this.isTyping && !this.isLoading && !!this.messageInput.trim()
|
|
1094
1101
|
? 'send-button-enabled'
|
|
1095
|
-
: 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send'))))
|
|
1102
|
+
: 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send')))), h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, h("p", null, this.translationManager.get('branding.poweredBy'), ' ', " ", h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank" }, "Dimagi"))))))));
|
|
1096
1103
|
}
|
|
1097
1104
|
static get is() { return "open-chat-studio-widget"; }
|
|
1098
1105
|
static get encapsulation() { return "shadow"; }
|