open-chat-studio-widget 0.9.1 → 0.10.0
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-fFSp-Z_h.js → index-DMXmZhVD.js} +3 -3
- package/dist/cjs/index-DMXmZhVD.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js +1251 -314
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.entry.cjs.js.map +1 -1
- package/dist/collection/components/ocs-chat/ocs-chat.js +90 -5
- package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
- package/dist/collection/services/chat-session-service.js +5 -0
- package/dist/collection/services/chat-session-service.js.map +1 -1
- package/dist/components/open-chat-studio-widget.js +1251 -313
- package/dist/components/open-chat-studio-widget.js.map +1 -1
- package/dist/esm/{index-ythTKHg-.js → index-JDApwJx_.js} +3 -3
- package/dist/esm/index-JDApwJx_.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/open-chat-studio-widget.entry.js +1251 -314
- package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
- package/dist/esm/open-chat-studio-widget.js +3 -3
- 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-ythTKHg-.js → p-JDApwJx_.js} +2 -2
- package/dist/open-chat-studio-widget/p-JDApwJx_.js.map +1 -0
- package/dist/open-chat-studio-widget/p-c2d3b2d1.entry.js +4 -0
- package/dist/open-chat-studio-widget/p-c2d3b2d1.entry.js.map +1 -0
- package/dist/types/components/ocs-chat/ocs-chat.d.ts +15 -0
- package/dist/types/services/chat-session-service.d.ts +2 -0
- package/package.json +2 -2
- package/dist/cjs/index-fFSp-Z_h.js.map +0 -1
- package/dist/esm/index-ythTKHg-.js.map +0 -1
- package/dist/open-chat-studio-widget/p-2d31a15c.entry.js +0 -4
- package/dist/open-chat-studio-widget/p-2d31a15c.entry.js.map +0 -1
- package/dist/open-chat-studio-widget/p-ythTKHg-.js.map +0 -1
|
@@ -69,6 +69,7 @@ export class OcsChat {
|
|
|
69
69
|
this.parsedStarterQuestions = [];
|
|
70
70
|
this.isFullscreen = false;
|
|
71
71
|
this.showNewChatConfirmation = false;
|
|
72
|
+
this.sessionEnded = false;
|
|
72
73
|
this.selectedFiles = [];
|
|
73
74
|
this.isUploadingFiles = false;
|
|
74
75
|
this.buttonPosition = { x: 30, y: 30 };
|
|
@@ -294,6 +295,23 @@ export class OcsChat {
|
|
|
294
295
|
this.removeButtonEventListeners();
|
|
295
296
|
window.removeEventListener('resize', this.handleWindowResize);
|
|
296
297
|
}
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
// Public event API
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
/**
|
|
302
|
+
* Dispatch a composed, bubbling CustomEvent on the host element so that
|
|
303
|
+
* embedders can listen with plain addEventListener outside the shadow root.
|
|
304
|
+
*
|
|
305
|
+
* All events are dispatched synchronously so that handlers can update
|
|
306
|
+
* reactive props (e.g. `pageContext`) before the calling code reads them.
|
|
307
|
+
*/
|
|
308
|
+
dispatchWidgetEvent(name, detail = null) {
|
|
309
|
+
this.host.dispatchEvent(new CustomEvent(name, {
|
|
310
|
+
bubbles: true,
|
|
311
|
+
composed: true,
|
|
312
|
+
detail,
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
297
315
|
applySessionToken(token) {
|
|
298
316
|
var _a;
|
|
299
317
|
this.currentSessionToken = token;
|
|
@@ -345,6 +363,38 @@ export class OcsChat {
|
|
|
345
363
|
this.clearSessionStorage();
|
|
346
364
|
this.addErrorMessage(this.translationManager.get('status.sessionExpired', 'Your chat session expired. Starting a new chat — please resend your message.'));
|
|
347
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* The server reported the session has ended (e.g. closed from another tab or
|
|
368
|
+
* by the bot). Polling has already stopped; disable the composer and tell the
|
|
369
|
+
* user. Unbound widgets can recover via the "new chat" button (clearSession).
|
|
370
|
+
*/
|
|
371
|
+
handleSessionEnded() {
|
|
372
|
+
var _a;
|
|
373
|
+
if (this.sessionEnded) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
this.sessionEnded = true;
|
|
377
|
+
this.dispatchWidgetEvent('ocs:session:ended', { sessionId: this.activeSessionId });
|
|
378
|
+
this.stopMessagePolling();
|
|
379
|
+
this.isTyping = false;
|
|
380
|
+
this.typingProgressMessage = '';
|
|
381
|
+
const content = (_a = this.translationManager.get('status.chatEnded')) !== null && _a !== void 0 ? _a : 'This chat has ended.';
|
|
382
|
+
// An unbound widget restores persisted messages and re-polls after a reload,
|
|
383
|
+
// so the notice may already be the last message.
|
|
384
|
+
const last = this.messages.at(-1);
|
|
385
|
+
if ((last === null || last === void 0 ? void 0 : last.role) === 'system' && last.content === content) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const notice = {
|
|
389
|
+
created_at: new Date().toISOString(),
|
|
390
|
+
role: 'system',
|
|
391
|
+
content,
|
|
392
|
+
attachments: [],
|
|
393
|
+
};
|
|
394
|
+
this.messages = [...this.messages, notice];
|
|
395
|
+
this.saveSessionToStorage();
|
|
396
|
+
this.scrollToBottom();
|
|
397
|
+
}
|
|
348
398
|
handleError(errorText) {
|
|
349
399
|
// show as system message
|
|
350
400
|
this.addErrorMessage(errorText);
|
|
@@ -443,6 +493,7 @@ export class OcsChat {
|
|
|
443
493
|
this.activeSessionId = data.session_id;
|
|
444
494
|
this.applySessionToken((_a = data.session_token) !== null && _a !== void 0 ? _a : undefined);
|
|
445
495
|
this.saveSessionToStorage();
|
|
496
|
+
this.dispatchWidgetEvent('ocs:session:started', { sessionId: this.activeSessionId });
|
|
446
497
|
this.startMessagePolling();
|
|
447
498
|
}
|
|
448
499
|
catch (_error) {
|
|
@@ -506,7 +557,8 @@ export class OcsChat {
|
|
|
506
557
|
}
|
|
507
558
|
}
|
|
508
559
|
async sendMessage(message) {
|
|
509
|
-
|
|
560
|
+
var _a;
|
|
561
|
+
if (!message.trim() || this.sessionEnded)
|
|
510
562
|
return;
|
|
511
563
|
const epoch = this.sessionEpoch;
|
|
512
564
|
// Start session if we don't have one yet
|
|
@@ -568,6 +620,12 @@ export class OcsChat {
|
|
|
568
620
|
this.selectedFiles = []; // Clear selected files after sending
|
|
569
621
|
}
|
|
570
622
|
this.scrollToBottom();
|
|
623
|
+
// Fire before-send first so handlers can update pageContext synchronously
|
|
624
|
+
// before we read internalPageContext into the request body.
|
|
625
|
+
this.dispatchWidgetEvent('ocs:message:before-send', {
|
|
626
|
+
message: message.trim(),
|
|
627
|
+
sessionId: (_a = this.activeSessionId) !== null && _a !== void 0 ? _a : '',
|
|
628
|
+
});
|
|
571
629
|
const requestBody = { message: message.trim() };
|
|
572
630
|
if (this.allowAttachments && attachmentIds.length > 0) {
|
|
573
631
|
requestBody.attachment_ids = attachmentIds;
|
|
@@ -585,6 +643,10 @@ export class OcsChat {
|
|
|
585
643
|
throw new Error(data.error || 'Failed to send message');
|
|
586
644
|
}
|
|
587
645
|
this.internalPageContext = undefined;
|
|
646
|
+
this.dispatchWidgetEvent('ocs:message:sent', {
|
|
647
|
+
message: message.trim(),
|
|
648
|
+
sessionId: this.activeSessionId,
|
|
649
|
+
});
|
|
588
650
|
this.startTaskPolling(data.task_id);
|
|
589
651
|
}
|
|
590
652
|
catch (error) {
|
|
@@ -700,6 +762,7 @@ export class OcsChat {
|
|
|
700
762
|
return;
|
|
701
763
|
}
|
|
702
764
|
this.saveVisibleState(visible);
|
|
765
|
+
this.dispatchWidgetEvent(visible ? 'ocs:open' : 'ocs:close');
|
|
703
766
|
if (this.isButtonDragging) {
|
|
704
767
|
this.isButtonDragging = false;
|
|
705
768
|
this.buttonWasDragged = false;
|
|
@@ -736,8 +799,13 @@ export class OcsChat {
|
|
|
736
799
|
}
|
|
737
800
|
this.taskPollingHandle = this.getChatService().pollTask(this.activeSessionId, taskId, {
|
|
738
801
|
onMessage: message => {
|
|
802
|
+
var _a;
|
|
739
803
|
this.messages = [...this.messages, message];
|
|
740
804
|
this.saveSessionToStorage();
|
|
805
|
+
this.dispatchWidgetEvent('ocs:message:received', {
|
|
806
|
+
message: Object.assign({}, message),
|
|
807
|
+
sessionId: (_a = this.activeSessionId) !== null && _a !== void 0 ? _a : '',
|
|
808
|
+
});
|
|
741
809
|
this.scrollToBottom();
|
|
742
810
|
this.isTyping = false;
|
|
743
811
|
this.typingProgressMessage = '';
|
|
@@ -779,7 +847,7 @@ export class OcsChat {
|
|
|
779
847
|
});
|
|
780
848
|
}
|
|
781
849
|
startMessagePolling() {
|
|
782
|
-
if (!this.activeSessionId || this.currentPollTaskId || !this.visible) {
|
|
850
|
+
if (!this.activeSessionId || this.currentPollTaskId || !this.visible || this.sessionEnded) {
|
|
783
851
|
return;
|
|
784
852
|
}
|
|
785
853
|
if (this.messagePollingHandle) {
|
|
@@ -788,13 +856,26 @@ export class OcsChat {
|
|
|
788
856
|
this.messagePollingHandle = this.getChatService().startMessagePolling(this.activeSessionId, {
|
|
789
857
|
getSince: () => { var _a; return (this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined); },
|
|
790
858
|
onMessages: messages => {
|
|
859
|
+
var _a;
|
|
791
860
|
if (messages.length === 0)
|
|
792
861
|
return;
|
|
793
862
|
this.messages = [...this.messages, ...messages];
|
|
794
863
|
this.saveSessionToStorage();
|
|
864
|
+
for (const message of messages) {
|
|
865
|
+
if (message.role !== 'user') {
|
|
866
|
+
this.dispatchWidgetEvent('ocs:message:received', {
|
|
867
|
+
message: Object.assign({}, message),
|
|
868
|
+
sessionId: (_a = this.activeSessionId) !== null && _a !== void 0 ? _a : '',
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
}
|
|
795
872
|
this.scrollToBottom();
|
|
796
873
|
this.focusInput();
|
|
797
874
|
},
|
|
875
|
+
onSessionEnded: () => {
|
|
876
|
+
this.messagePollingHandle = undefined;
|
|
877
|
+
this.handleSessionEnded();
|
|
878
|
+
},
|
|
798
879
|
onError: () => {
|
|
799
880
|
// Silently ignore polling errors to match previous behaviour
|
|
800
881
|
},
|
|
@@ -1233,7 +1314,9 @@ export class OcsChat {
|
|
|
1233
1314
|
return newUserId;
|
|
1234
1315
|
}
|
|
1235
1316
|
saveVisibleState(visible) {
|
|
1236
|
-
|
|
1317
|
+
// Kiosk visibility is forced, so persisting it would only leak into a
|
|
1318
|
+
// standard-mode widget for the same chatbot on another page.
|
|
1319
|
+
if (!this.persistentSession || this.isKioskMode())
|
|
1237
1320
|
return;
|
|
1238
1321
|
try {
|
|
1239
1322
|
const keys = this.getStorageKeys();
|
|
@@ -1307,6 +1390,7 @@ export class OcsChat {
|
|
|
1307
1390
|
this.applySessionToken(this.isSessionBound() ? this.sessionToken : undefined);
|
|
1308
1391
|
this.messages = [];
|
|
1309
1392
|
this.isTyping = false;
|
|
1393
|
+
this.sessionEnded = false;
|
|
1310
1394
|
this.currentPollTaskId = '';
|
|
1311
1395
|
if (this.allowAttachments) {
|
|
1312
1396
|
this.selectedFiles = [];
|
|
@@ -1328,12 +1412,12 @@ export class OcsChat {
|
|
|
1328
1412
|
if (this.error && !this.activeSessionId) {
|
|
1329
1413
|
return (h(Host, null, h("p", { class: "error-message" }, this.error)));
|
|
1330
1414
|
}
|
|
1331
|
-
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() }, !this.isKioskMode() && (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 && !this.isSessionBound() && (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.isKioskMode() && 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.activeSessionId && (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' ? 'message-bubble-user' : message.role === 'assistant' ? 'message-bubble-assistant' : '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.typingProgressMessage || 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 => {
|
|
1415
|
+
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() }, !this.isKioskMode() && (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 && !this.isSessionBound() && (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.isKioskMode() && 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.activeSessionId && (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' ? 'message-bubble-user' : message.role === 'assistant' ? 'message-bubble-assistant' : '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.typingProgressMessage || 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.sessionEnded ? this.translationManager.get('status.chatEnded') : 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.sessionEnded }), this.allowAttachments && (h("input", { ref: el => {
|
|
1332
1416
|
// Unclear why but after removing all attachments this is being set to `null`.
|
|
1333
1417
|
if (el) {
|
|
1334
1418
|
this.fileInputRef = el;
|
|
1335
1419
|
}
|
|
1336
|
-
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', 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() ? 'send-button-enabled' : '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", rel: "noopener noreferrer" }, "Dimagi"))))))));
|
|
1420
|
+
}, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', 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 || this.sessionEnded, 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.sessionEnded && !!this.messageInput.trim() ? 'send-button-enabled' : 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || this.sessionEnded || !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", rel: "noopener noreferrer" }, "Dimagi"))))))));
|
|
1337
1421
|
}
|
|
1338
1422
|
static get is() { return "open-chat-studio-widget"; }
|
|
1339
1423
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1900,6 +1984,7 @@ export class OcsChat {
|
|
|
1900
1984
|
"generatedUserId": {},
|
|
1901
1985
|
"isFullscreen": {},
|
|
1902
1986
|
"showNewChatConfirmation": {},
|
|
1987
|
+
"sessionEnded": {},
|
|
1903
1988
|
"selectedFiles": {},
|
|
1904
1989
|
"isUploadingFiles": {},
|
|
1905
1990
|
"isButtonDragging": {},
|