Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib/helpers/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ IRichContent.prototype.text;
* @property {string} text - The message content.
* @property {string} function - The function name.
* @property {RichContent} rich_content - Rich content.
* @property {string} post_action_disclaimer - The message disclaimer.
* @property {string} data - The message data.
* @property {Date} created_at - The message sent time.
*/
Expand Down
12 changes: 10 additions & 2 deletions src/lib/scss/custom/pages/_chat.scss
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
display: flex;
position: relative;
width: 100%;
margin-bottom: 20px;

.cicon-wrap {
margin-right: 4px;
Expand Down Expand Up @@ -599,6 +600,13 @@
}
}

.conv-msg-wrapper {
margin-bottom: 20px;
.msg-disclaimer {
margin-top: 3px;
padding: 5px 10px;
border-radius: 5px;
border-color: var(--bs-success-border-subtle);
background-color: var(--bs-success-bg-subtle);
font-size: 0.85em;
font-weight: 500;
color: var(--bs-secondary)
}
143 changes: 81 additions & 62 deletions src/routes/chat/[agentId]/[conversationId]/chat-box.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
// trigger UI render
dialogs = dialogs?.map(item => { return { ...item }; }) || [];
lastBotMsg = findLastBotMessage(dialogs);
assignMessageDisclaimer(dialogs)
groupedDialogs = groupDialogs(dialogs);
await tick();

Expand All @@ -232,6 +233,29 @@
});
}

/** @param {import('$types').ChatResponseModel[]} dialogs */
function assignMessageDisclaimer(dialogs) {
if (!!!dialogs) return null;

for (let idx = 0; idx < dialogs.length; idx++) {
const curMsg = dialogs[idx];
// @ts-ignore
if (!curMsg.rich_content?.message?.buttons?.some(op => !!op.post_action_disclaimer)) {
continue;
}

const nextMsg = dialogs[idx + 1];
if (!!nextMsg) {
// @ts-ignore
const disclaimerOptions = curMsg.rich_content?.message?.buttons?.filter(op => !!op.post_action_disclaimer) || [];
const content = nextMsg?.rich_content?.message?.text || nextMsg?.text;
// @ts-ignore
const foundOption = disclaimerOptions.find(x => x.title === content);
nextMsg.post_action_disclaimer = foundOption?.post_action_disclaimer;
}
}
}

/** @param {import('$types').ChatResponseModel[]} dialogs */
function groupDialogs(dialogs) {
if (!!!dialogs) return [];
Expand Down Expand Up @@ -854,65 +878,62 @@
</div>
</li>
{#each dialogGroup as message}
<li id={'test_k' + message.message_id}
class:right={USER_SENDERS.includes(message.sender?.role)}>
<div class="conv-msg-wrapper">
<div class="conv-msg-container">
{#if USER_SENDERS.includes(message.sender?.role)}
<div class="msg-container">
<div
class="ctext-wrap user-msg"
class:clickable={!isLite && (isLoadContentLog || isLoadStateLog)}
id={`user-msg-${message.message_id}`}
tabindex="0"
aria-label="user-msg-to-log"
role="link"
on:keydown={() => {}}
on:click={() => directToLog(message.message_id)}
>
<div>
<!--<div class="conversation-name">{message.sender.full_name}</div>-->
<div class="text-start">{@html replaceNewLine(message.text)}</div>
<p class="chat-time mb-0">
<i class="bx bx-time-five align-middle me-1" />
<!-- {format(message.created_at, 'short-time')} -->
{utcToLocal(message.created_at, 'hh:mm A')}
</p>
</div>
<li id={'test_k' + message.message_id} class:right={USER_SENDERS.includes(message.sender?.role)}>
<div class="conv-msg-container">
{#if USER_SENDERS.includes(message.sender?.role)}
<div class="msg-container">
<div
class="ctext-wrap user-msg"
class:clickable={!isLite && (isLoadContentLog || isLoadStateLog)}
id={`user-msg-${message.message_id}`}
tabindex="0"
aria-label="user-msg-to-log"
role="link"
on:keydown={() => {}}
on:click={() => directToLog(message.message_id)}
>
<div>
<!--<div class="conversation-name">{message.sender.full_name}</div>-->
<div class="text-start">{@html replaceNewLine(message.text)}</div>
<p class="chat-time mb-0">
<i class="bx bx-time-five align-middle me-1" />
<!-- {format(message.created_at, 'short-time')} -->
{utcToLocal(message.created_at, 'hh:mm A')}
</p>
</div>
</div>
{#if !isLite}
<Dropdown>
<DropdownToggle class="dropdown-toggle" tag="span" disabled={isSendingMsg || isThinking}>
<i class="bx bx-dots-vertical-rounded" />
</DropdownToggle>
<DropdownMenu class="dropdown-menu-end">
<DropdownItem on:click={(e) => editMessage(e, message)}>Edit</DropdownItem>
<DropdownItem on:click={(e) => resendMessage(e, message)}>Resend</DropdownItem>
<DropdownItem on:click={(e) => deleteMessage(e, message.message_id)}>Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
{/if}
{:else}
<div class="cicon-wrap">
{#if message.sender.role == UserRole.Client}
{#if !!message.post_action_disclaimer}
<RcDisclaimer content={message.post_action_disclaimer} />
{/if}
</div>
{#if !isLite}
<Dropdown>
<DropdownToggle class="dropdown-toggle" tag="span" disabled={isSendingMsg || isThinking}>
<i class="bx bx-dots-vertical-rounded" />
</DropdownToggle>
<DropdownMenu class="dropdown-menu-end">
<DropdownItem on:click={(e) => editMessage(e, message)}>Edit</DropdownItem>
<DropdownItem on:click={(e) => resendMessage(e, message)}>Resend</DropdownItem>
<DropdownItem on:click={(e) => deleteMessage(e, message.message_id)}>Delete</DropdownItem>
</DropdownMenu>
</Dropdown>
{/if}
{:else}
<div class="cicon-wrap">
{#if message.sender.role == UserRole.Client}
<img src="images/users/user-dummy.jpg" class="rounded-circle avatar-xs" alt="avatar">
{:else}
{:else}
<img src={PUBLIC_LIVECHAT_ENTRY_ICON} class="rounded-circle avatar-xs" alt="avatar">
{/if}
</div>
<div class="msg-container">
<RichContent
message={message}
lastBotMessage={lastBotMsg}
disabled={isSendingMsg || isThinking}
onConfirm={confirmSelectedOption}
/>
</div>
{/if}
</div>
{#if USER_SENDERS.includes(message.sender?.role)}
<RcDisclaimer message={message} />
<div class="msg-container">
<RichContent
message={message}
lastBotMessage={lastBotMsg}
disabled={isSendingMsg || isThinking}
onConfirm={confirmSelectedOption}
/>
</div>
{/if}
</div>
</li>
Expand All @@ -921,15 +942,13 @@

{#if isThinking}
<li>
<div class="conv-msg-wrapper">
<div class="conv-msg-container">
<div class="cicon-wrap float-start">
<img src={PUBLIC_LIVECHAT_ENTRY_ICON} class="rounded-circle avatar-xs" alt="avatar">
</div>
<div class="ctext-wrap float-start" style="display: flex;">
<div class="flex-shrink-0 align-self-center">
<LoadingDots duration={'1s'} size={10} color={'var(--bs-primary)'} />
</div>
<div class="conv-msg-container">
<div class="cicon-wrap float-start">
<img src={PUBLIC_LIVECHAT_ENTRY_ICON} class="rounded-circle avatar-xs" alt="avatar">
</div>
<div class="ctext-wrap float-start" style="display: flex;">
<div class="flex-shrink-0 align-self-center">
<LoadingDots duration={'1s'} size={10} color={'var(--bs-primary)'} />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script>

/** @type {any} */
export let message;
/** @type {string} */
export let content;
</script>

<div>
{'post back message'}
<div class="msg-disclaimer">
{content}
</div>
2 changes: 1 addition & 1 deletion src/routes/page/conversation/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@

<HeadTitle title="{$_('Conversation List')}" />
<Breadcrumb title="{$_('Communication')}" pagetitle="{$_('Conversations')}" />
<LoadingToComplete isLoading={isLoading} isComplete={isComplete} isError={isError} successText={'Delete completed!'} />
<LoadingToComplete isLoading={isLoading} isComplete={true} isError={isError} successText={'Delete completed!'} />
<StateModal
isOpen={isOpenSearchStateModal}
validateKey={true}
Expand Down