Skip to content

Commit c724d1d

Browse files
authored
Merge pull request #238 from iceljc/features/add-notification
add notification
2 parents 78c534b + 4135ac7 commit c724d1d

File tree

13 files changed

+252
-26
lines changed

13 files changed

+252
-26
lines changed

src/lib/common/DialogModal.svelte

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
/** @type {boolean} */
55
export let isOpen;
66
7+
/** @type {boolean} */
8+
export let closeable = false;
9+
710
/** @type {string} */
811
export let size = 'xl';
912
10-
/** @type {string} */
13+
/** @type {string | any} */
1114
export let title;
1215
1316
/** @type {string} */
@@ -28,6 +31,9 @@
2831
/** @type {() => void} */
2932
export let cancel = () => {};
3033
34+
/** @type {() => void} */
35+
export let close = () => {};
36+
3137
/** @type {boolean} */
3238
export let disableConfirmBtn = false;
3339
@@ -43,13 +49,44 @@
4349
cancel && cancel();
4450
}
4551
52+
/** @param {any} e */
53+
function handleClose(e) {
54+
e.preventDefault();
55+
close && close();
56+
}
4657
</script>
4758

4859

49-
<Modal class={className} fade size={size} isOpen={isOpen} toggle={() => toggleModal()}>
50-
{#if !!title}
51-
<ModalHeader>{title}</ModalHeader>
52-
{/if}
60+
<Modal
61+
class={`dialog-modal-container ${className}`}
62+
fade
63+
size={size}
64+
isOpen={isOpen}
65+
toggle={() => toggleModal()}
66+
unmountOnClose
67+
>
68+
<ModalHeader>
69+
<div class="dialog-modal-header">
70+
{#if !!title}
71+
<div class="header-title">
72+
<slot name='title-icon'/>
73+
<div>{title}</div>
74+
</div>
75+
{/if}
76+
{#if closeable}
77+
<div class="header-close">
78+
<!-- svelte-ignore a11y-no-static-element-interactions -->
79+
<!-- svelte-ignore a11y-click-events-have-key-events -->
80+
<div
81+
class="clickable"
82+
on:click={e => handleClose(e)}
83+
>
84+
<i class="mdi mdi-close" />
85+
</div>
86+
</div>
87+
{/if}
88+
</div>
89+
</ModalHeader>
5390
<ModalBody>
5491
<slot />
5592
</ModalBody>

src/lib/common/LiveChatEntry.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
showChatBox = false;
2424
} else if (e.data.action == ChatAction.Open) {
2525
// showChatBox = true;
26-
} else if (e.data.action == ChatAction.ReceiveMsg && !showChatBox) {
26+
} else if (e.data.action == ChatAction.ReceiveNotification && !showChatBox) {
2727
receivedMsg = e.data?.data?.rich_content?.message?.text || e.data?.data?.text || '';
2828
showBubbleMsg = true;
2929
wave();

src/lib/common/StateModal.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158
}
159159
</script>
160160
161-
<Modal class={className} fade size={size} isOpen={isOpen} toggle={() => toggleModal && toggleModal()}>
161+
<Modal class={className} fade size={size} isOpen={isOpen} unmountOnClose toggle={() => toggleModal && toggleModal()}>
162162
<ModalHeader>{title}</ModalHeader>
163163
<ModalBody>
164164
<Form class="state-form">

src/lib/helpers/enums.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const contentLogSource = {
3838
Prompt: "prompt",
3939
FunctionCall: "function call",
4040
AgentResponse: "agent response",
41-
HardRule: "hard rule"
41+
HardRule: "hard rule",
42+
Notification: "notification"
4243
};
4344
export const ContentLogSource = Object.freeze(contentLogSource);
4445

@@ -106,6 +107,6 @@ const chatAction = {
106107
Logout: 'logout',
107108
Chat: 'chat',
108109
NewChat: 'new-chat',
109-
ReceiveMsg: 'receive-msg'
110+
ReceiveNotification: 'receive-notification'
110111
};
111112
export const ChatAction = Object.freeze(chatAction);

src/lib/scss/custom/components/_chat.scss

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
$bubble-chat-theme-color: rgba($primary, 80%);
22

3+
.dialog-modal-container {
4+
.modal-title {
5+
width: 100%;
6+
}
7+
8+
.dialog-modal-header {
9+
display: flex;
10+
justify-content: space-between;
11+
12+
.header-title {
13+
display: flex;
14+
gap: 8px;
15+
}
16+
}
17+
}
18+
19+
320
.chat-util-common {
421
display: block;
522
position: absolute;
@@ -45,7 +62,12 @@ $bubble-chat-theme-color: rgba($primary, 80%);
4562
font-size: 30px;
4663
}
4764

48-
65+
.chat-notification {
66+
min-height: 20px;
67+
max-height: 150px;
68+
overflow-y: auto;
69+
scrollbar-width: none;
70+
}
4971

5072
.chat-bubble-container {
5173
display: flex;

src/lib/services/api-endpoints.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const endpoints = {
3939
// conversation
4040
conversationInitUrl: `${host}/conversation/{agentId}`,
4141
conversationMessageUrl: `${host}/conversation/{agentId}/{conversationId}`,
42+
notificationUrl: `${host}/conversation/{conversationId}/notification`,
4243
conversationsUrl: `${host}/conversations`,
4344
conversationCountUrl: `${host}/conversations/count`,
4445
conversationDeletionUrl: `${host}/conversation/{conversationId}`,

src/lib/services/conversation-service.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,24 @@ export async function sendMessageToHub(agentId, conversationId, text, data = nul
106106
}
107107

108108

109+
/**
110+
* send a notification to conversation
111+
* @param {string} conversationId - The conversation id
112+
* @param {string} text - The text message sent to CSR
113+
* @param {import('$conversationTypes').MessageData?} data - Additional data
114+
*/
115+
export async function sendNotification(conversationId, text, data = null) {
116+
let url = replaceUrl(endpoints.notificationUrl, {
117+
conversationId: conversationId
118+
});
119+
const response = await axios.post(url, {
120+
text: text,
121+
states: [],
122+
postback: data?.postback
123+
});
124+
return response.data;
125+
}
126+
109127
/**
110128
* @param {string} conversationId
111129
*/

src/lib/services/signalr-service.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export const signalr = {
2121
/** @type {import('$conversationTypes').OnMessageReceived} */
2222
onMessageReceivedFromAssistant: () => {},
2323

24+
/** @type {import('$conversationTypes').OnMessageReceived} */
25+
onNotificationGenerated: () => {},
26+
2427
/** @type {import('$conversationTypes').OnConversationContentLogReceived} */
2528
onConversationContentLogGenerated: () => {},
2629

@@ -93,6 +96,13 @@ export const signalr = {
9396
}
9497
});
9598

99+
connection.on('OnNotificationGenerated', (json) => {
100+
const message = JSON.parse(json);
101+
if (conversationId === message?.conversation_id) {
102+
this.onNotificationGenerated(message);
103+
}
104+
});
105+
96106
connection.on('OnConversationContentLogGenerated', (log) => {
97107
const jsonLog = JSON.parse(log);
98108
if (conversationId === jsonLog?.conversation_id) {

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
let truncateMsgId = "";
9393
let indication = "";
9494
let mode = '';
95+
let notificationText = '';
9596
9697
/** @type {number} */
9798
let messageInputTimeout;
@@ -158,6 +159,7 @@
158159
let disableSpeech = false;
159160
let isLoading = false;
160161
let isCreatingNewConv = false;
162+
let isDisplayNotification = false;
161163
162164
$: {
163165
const editor = lastBotMsg?.rich_content?.editor || '';
@@ -184,6 +186,7 @@
184186
signalr.onMessageReceivedFromClient = onMessageReceivedFromClient;
185187
signalr.onMessageReceivedFromCsr = onMessageReceivedFromCsr;
186188
signalr.onMessageReceivedFromAssistant = onMessageReceivedFromAssistant;
189+
signalr.onNotificationGenerated = onNotificationGenerated;
187190
signalr.onConversationContentLogGenerated = onConversationContentLogGenerated;
188191
signalr.onConversationStateLogGenerated = onConversationStateLogGenerated;
189192
signalr.onStateChangeGenerated = onStateChangeGenerated;
@@ -255,9 +258,9 @@
255258
}
256259
257260
/** @param {import('$conversationTypes').ChatResponseModel} message */
258-
function sendReceivedMessage(message) {
261+
function sendReceivedNotification(message) {
259262
if (isFrame) {
260-
window.parent.postMessage({ action: ChatAction.ReceiveMsg, data: message }, "*");
263+
window.parent.postMessage({ action: ChatAction.ReceiveNotification, data: message }, "*");
261264
}
262265
}
263266
@@ -431,10 +434,21 @@
431434
...message,
432435
is_chat_message: true
433436
});
434-
sendReceivedMessage(message);
435437
refresh();
436438
}
437439
440+
/** @param {import('$conversationTypes').ChatResponseModel} message */
441+
function onNotificationGenerated(message) {
442+
notificationText = message?.rich_content?.message?.text || message.text || '';
443+
isDisplayNotification = true;
444+
setTimeout(() => {
445+
isDisplayNotification = false;
446+
notificationText = '';
447+
}, notificationText?.length > 200 ? 8000 : 3000);
448+
449+
sendReceivedNotification(message);
450+
}
451+
438452
/** @param {import('$conversationTypes').ConversationContentLogModel} log */
439453
function onConversationContentLogGenerated(log) {
440454
if (!isLoadPersistLog) return;
@@ -1094,6 +1108,13 @@
10941108
};
10951109
sendChatMessage(text, data);
10961110
}
1111+
1112+
function toggleNotificationModal() {
1113+
isDisplayNotification = !isDisplayNotification;
1114+
if (!isDisplayNotification) {
1115+
notificationText = '';
1116+
}
1117+
}
10971118
</script>
10981119
10991120
@@ -1103,6 +1124,25 @@
11031124
<Loader size={35} />
11041125
{/if}
11051126
1127+
<DialogModal
1128+
title={'Notification'}
1129+
size={'md'}
1130+
isOpen={isDisplayNotification}
1131+
closeable
1132+
toggleModal={() => toggleNotificationModal()}
1133+
confirmBtnText={''}
1134+
cancelBtnText={''}
1135+
close={() => toggleNotificationModal()}
1136+
>
1137+
<div slot='title-icon' class="color: text-warning">
1138+
<i class="mdi mdi-bell-ring" />
1139+
</div>
1140+
<div class="chat-notification">
1141+
{notificationText}
1142+
</div>
1143+
</DialogModal>
1144+
1145+
11061146
<DialogModal
11071147
title={'Edit message'}
11081148
size={'md'}

src/routes/chat/[agentId]/[conversationId]/persist-log/content-log-element.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
const includedSources = [
1717
ContentLogSource.Prompt,
1818
ContentLogSource.AgentResponse,
19-
ContentLogSource.FunctionCall
19+
ContentLogSource.FunctionCall,
20+
ContentLogSource.Notification
2021
];
2122
2223
$: {
23-
if (data.source === ContentLogSource.AgentResponse) {
24+
if (data.source === ContentLogSource.AgentResponse || data.source === ContentLogSource.Notification) {
2425
logDisplayStyle = 'border border-secondary';
2526
logTextStyle = 'text-info';
2627
} else if (data.source === ContentLogSource.FunctionCall) {

0 commit comments

Comments
 (0)