Skip to content

Commit 54d971c

Browse files
authored
Merge pull request #98 from iceljc/features/refine-chat-window
Features/refine chat window
2 parents a366982 + 2d99571 commit 54d971c

File tree

11 files changed

+160
-26
lines changed

11 files changed

+160
-26
lines changed

src/lib/common/StateModal.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
const lowerLimit = -1;
140140
const upperLimit = 9999;
141141
142-
if (rounds <= 0) {
142+
if (rounds < lowerLimit) {
143143
res = lowerLimit;
144144
} else if (rounds > upperLimit) {
145145
res = upperLimit;

src/lib/helpers/types.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,16 @@ IRichContent.prototype.text;
294294
* @property {string} conversation_id - The conversation id.
295295
* @property {string} message_id - The message id.
296296
* @property {Object} states - The states content.
297-
* @property {Date} created_at - The states sent time.
297+
* @property {Date} created_at - The log sent time.
298+
*/
299+
300+
/**
301+
* @typedef {Object} StateChangeModel
302+
* @property {string} conversation_id - The conversation id.
303+
* @property {string} message_id - The message id.
304+
* @property {string} before_value - The value before change.
305+
* @property {string} after_value - The value after change.
306+
* @property {Date} created_at - The log sent time.
298307
*/
299308

300309
/**
@@ -387,6 +396,13 @@ IRichContent.prototype.text;
387396
* @param {ConversationStateLogModel} log
388397
*/
389398

399+
/**
400+
* Conversation state change log
401+
*
402+
* @callback OnStateChangeGenerated
403+
* @param {StateChangeModel} log
404+
*/
405+
390406
/**
391407
* Conversation sender action
392408
*

src/lib/scss/custom/pages/_chat.scss

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@
168168
max-width: 80%;
169169
flex: 0 0 fit-content;
170170

171-
.button-group {
171+
.button-group-container {
172172
display: flex;
173173
flex-wrap: wrap;
174174

@@ -186,6 +186,7 @@
186186

187187
button {
188188
min-width: 50px;
189+
text-align: left;
189190
}
190191
}
191192

@@ -218,6 +219,7 @@
218219
.btn {
219220
display: block;
220221
margin-left: 0px !important;
222+
text-align: left;
221223
}
222224
}
223225
}
@@ -369,9 +371,23 @@
369371
// justify-content: flex-end;
370372
justify-content: space-between;
371373
}
374+
375+
.content-log-list {
376+
height: 90vh;
377+
}
378+
379+
.state-change-log-list {
380+
height: 35vh;
381+
border-bottom-style: solid;
382+
border-bottom-color: #fff;
383+
border-bottom-width: 5px;
384+
}
385+
386+
.state-log-list {
387+
height: 65vh;
388+
}
372389

373390
.log-list {
374-
height: 90vh;
375391
.log-element {
376392
margin-top: 25px;
377393
margin-bottom: 30px;

src/lib/services/signalr-service.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export const signalr = {
2727
/** @type {import('$types').OnConversationStateLogGenerated} */
2828
onConversationStateLogGenerated: () => {},
2929

30+
/** @type {import('$types').OnStateChangeGenerated} */
31+
onStateChangeGenerated: () => {},
32+
3033
/** @type {import('$types').OnSenderActionGenerated} */
3134
onSenderActionGenerated: () => {},
3235

@@ -101,6 +104,13 @@ export const signalr = {
101104
}
102105
});
103106

107+
connection.on('OnStateChangeGenerated', (log) => {
108+
const jsonData = JSON.parse(log);
109+
if (conversationId === jsonData?.conversation_id) {
110+
this.onStateChangeGenerated(jsonData);
111+
}
112+
});
113+
104114
connection.on('OnSenderActionGenerated', (data) => {
105115
if (conversationId === data?.conversation_id) {
106116
this.onSenderActionGenerated(data);

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
/** @type {import('$types').ConversationStateLogModel[]} */
8585
let stateLogs = [];
8686
87+
/** @type {import('$types').StateChangeLogModel[]} */
88+
let stateChangeLogs = [];
89+
8790
/** @type {import('$types').UserStateDetailModel[]} */
8891
let userAddStates = [];
8992
@@ -109,6 +112,7 @@
109112
signalr.onMessageReceivedFromAssistant = onMessageReceivedFromAssistant;
110113
signalr.onConversationContentLogGenerated = onConversationContentLogGenerated;
111114
signalr.onConversationStateLogGenerated = onConversationStateLogGenerated;
115+
signalr.onStateChangeGenerated = onStateChangeGenerated;
112116
signalr.onSenderActionGenerated = onSenderActionGenerated;
113117
signalr.onConversationMessageDeleted = onConversationMessageDeleted;
114118
await signalr.start(params.conversationId);
@@ -259,6 +263,14 @@
259263
stateLogs = stateLogs.map(x => { return { ...x }; });
260264
}
261265
266+
/** @param {import('$types').StateChangeModel} log */
267+
function onStateChangeGenerated(log) {
268+
if (!isLoadStateLog || log == null) return;
269+
270+
stateChangeLogs.push({ ...log });
271+
stateChangeLogs = stateChangeLogs.map(x => { return { ...x }; });
272+
}
273+
262274
/** @param {import('$types').ConversationSenderActionModel} data */
263275
function onSenderActionGenerated(data) {
264276
if (data?.sender_action == SenderAction.TypingOn) {
@@ -288,6 +300,7 @@
288300
*/
289301
function sendChatMessage(msgText, data = null) {
290302
isSendingMsg = true;
303+
stateChangeLogs = [];
291304
renewUserSentMessages(msgText);
292305
293306
const postback = buildPostbackMessage(dialogs, data?.payload || msgText, data?.truncateMsgId);
@@ -545,6 +558,7 @@
545558
546559
/** @param {string} messageId */
547560
async function handleDeleteMessage(messageId) {
561+
stateChangeLogs = [];
548562
await deleteConversationMessage(params.conversationId, messageId);
549563
}
550564
@@ -705,6 +719,7 @@
705719
<Pane size={30} minSize={20} maxSize={50} >
706720
<StateLog
707721
bind:stateLogs={stateLogs}
722+
bind:stateChangeLogs={stateChangeLogs}
708723
closeWindow={toggleStateLog}
709724
cleanScreen={cleanStateLogScreen}
710725
/>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
<i class="mdi mdi-window-close"></i>
8383
</button>
8484
</div>
85-
<div class="content-log-scrollbar log-list padding-side">
85+
<div class="content-log-scrollbar content-log-list log-list padding-side">
8686
<ul>
8787
{#each contentLogs as log}
8888
<ContentLogElement data={log} />

src/routes/chat/[agentId]/[conversationId]/richContent/rc-generic-options.svelte renamed to src/routes/chat/[agentId]/[conversationId]/richContent/rc-complex-options.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
function collectOptions(options) {
2424
const res = options?.map(op => {
2525
// @ts-ignore
26-
const options = op.buttons?.map(x => {
26+
const options = op.buttons?.filter(op => !!op.title && !!op.payload)?.map(x => {
2727
return {
2828
title: x.title,
2929
payload: x.payload
@@ -69,10 +69,10 @@
6969
<Card class="card-element">
7070
<CardBody>
7171
{#if !!card.title}
72-
<div class="card-element-title">{card.title}</div>
72+
<div class="card-element-title mb-3">{card.title}</div>
7373
{/if}
7474
{#if !!card.subtitle}
75-
<div class="card-element-subtitle">{card.subtitle}</div>
75+
<div class="card-element-subtitle mb-3">{card.subtitle}</div>
7676
{/if}
7777
{#if card.options?.length > 0}
7878
<div class="card-option-group">

src/routes/chat/[agentId]/[conversationId]/richContent/rc-options.svelte renamed to src/routes/chat/[agentId]/[conversationId]/richContent/rc-plain-options.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
3333
/** @param {any[]} options */
3434
function collectOptions(options) {
35-
const res = options?.map(op => {
35+
const res = options?.filter(op => !!op.title && !!op.payload)?.map(op => {
3636
return {
3737
title: op.title,
3838
payload: op.payload,
@@ -99,7 +99,7 @@
9999
</script>
100100
101101
{#if localOptions.length > 0}
102-
<div class="button-group">
102+
<div class="button-group-container">
103103
{#each localOptions as option, index}
104104
<button
105105
class="btn btn-outline-primary btn-rounded btn-sm m-1"

src/routes/chat/[agentId]/[conversationId]/richContent/rich-content.svelte

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script>
22
import { RichType } from "$lib/helpers/enums";
33
import Markdown from "$lib/common/Markdown.svelte";
4-
import RcOptions from "./rc-options.svelte";
5-
import RcGenericOptions from "./rc-generic-options.svelte";
4+
import RcPlainOptions from "./rc-plain-options.svelte";
5+
import RcComplexOptions from "./rc-complex-options.svelte";
66
77
/** @type {any} */
88
export let message;
@@ -16,13 +16,23 @@
1616
/** @type {(args0: string, args1: string) => any} */
1717
export let onConfirm = () => {};
1818
19+
/** @type {boolean} */
20+
let isComplexElement = false;
21+
1922
/**
2023
* @param {string} title
2124
* @param {string} payload
2225
*/
2326
function handleConfirm(title, payload) {
2427
onConfirm && onConfirm(title, payload);
2528
}
29+
30+
$: {
31+
const isGeneric = message?.rich_content?.message?.rich_type === RichType.Generic;
32+
// @ts-ignore
33+
const hasSuboptions = message?.rich_content?.message?.elements?.some(x => x.buttons?.length > 0) || false;
34+
isComplexElement = isGeneric && hasSuboptions;
35+
}
2636
</script>
2737
2838
<div class="ctext-wrap">
@@ -33,12 +43,16 @@
3343
3444
{#if displayExtraElements}
3545
{#if message?.rich_content?.message?.rich_type === RichType.QuickReply}
36-
<RcOptions options={message?.rich_content?.message?.quick_replies} disableOption={disableOption} onConfirm={handleConfirm} />
46+
<RcPlainOptions options={message?.rich_content?.message?.quick_replies} disableOption={disableOption} onConfirm={handleConfirm} />
3747
{:else if message?.rich_content?.message?.rich_type === RichType.Button}
38-
<RcOptions options={message?.rich_content?.message?.buttons} disableOption={disableOption} onConfirm={handleConfirm} />
48+
<RcPlainOptions options={message?.rich_content?.message?.buttons} disableOption={disableOption} onConfirm={handleConfirm} />
3949
{:else if message?.rich_content?.message?.rich_type === RichType.MultiSelect}
40-
<RcOptions options={message?.rich_content?.message?.options} isMultiSelect disableOption={disableOption} onConfirm={handleConfirm} />
50+
<RcPlainOptions options={message?.rich_content?.message?.options} isMultiSelect disableOption={disableOption} onConfirm={handleConfirm} />
4151
{:else if message?.rich_content?.message?.rich_type === RichType.Generic}
42-
<RcGenericOptions options={message?.rich_content?.message?.elements} disableOption={disableOption} onConfirm={handleConfirm} />
52+
{#if isComplexElement}
53+
<RcComplexOptions options={message?.rich_content?.message?.elements} disableOption={disableOption} onConfirm={handleConfirm} />
54+
{:else}
55+
<RcPlainOptions options={message?.rich_content?.message?.elements} disableOption={disableOption} onConfirm={handleConfirm} />
56+
{/if}
4357
{/if}
4458
{/if}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script>
2+
3+
/** @type {any} */
4+
export let data;
5+
</script>
6+
7+
<div class="log-element state-change-element">
8+
<div class="log-meta">
9+
<div><b>{`[${data?.name}]`}</b></div>
10+
</div>
11+
<div class="log-content">
12+
<div class="transition-word text-secondary">
13+
Before
14+
</div>
15+
<div class="state-value">
16+
<div>{`${data?.before_value || 'unknown'}`}</div>
17+
</div>
18+
19+
<div class="transition-word text-secondary">
20+
After
21+
</div>
22+
<div class="state-value">
23+
<div>{`${data?.after_value || 'unknown'}`}</div>
24+
</div>
25+
</div>
26+
</div>
27+
28+
<style>
29+
.transition-word {
30+
font-size: 12px;
31+
font-weight: 600;
32+
margin-top: 5px;
33+
margin-bottom: 5px;
34+
}
35+
36+
.state-change-element {
37+
margin-top: 15px !important;
38+
margin-bottom: 15px !important;
39+
}
40+
41+
.state-value {
42+
font-size: 15px;
43+
}
44+
</style>

0 commit comments

Comments
 (0)