Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/add conversation log #46

Merged
merged 5 commits into from
Feb 15, 2024
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
7 changes: 3 additions & 4 deletions src/lib/helpers/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,19 +260,18 @@ IRichContent.prototype.text;
*/

/**
* @typedef {Object} ContentLogModel
* @typedef {Object} ConversationContentLogModel
* @property {string} conversation_id - The conversation id.
* @property {string} name - The sender name.
* @property {string} role - The sender role.
* @property {string} content - The log content.
* @property {Date} created_at - The log sent time.
* @property {boolean} is_collapsed - For UI display.
*/

/**
* @typedef {Object} ConversationStateLogModel
* @property {string} conversation_id - The conversation id.
* @property {string} states - The states content.
* @property {Object} states - The states content.
* @property {Date} created_at - The states sent time.
*/

Expand Down Expand Up @@ -319,7 +318,7 @@ IRichContent.prototype.text;
* Content log
*
* @callback OnContentLogReceived
* @param {ContentLogModel} log
* @param {ConversationContentLogModel} log
*/

/**
Expand Down
2 changes: 1 addition & 1 deletion src/lib/scss/custom/pages/_chat.scss
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@

span {
color: white;
font-size: 18px;
font-size: 15px;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib/services/api-endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export const endpoints = {

// logging
loggingFullLogUrl: `${host}/logger/full-log`,
loggingContentLogUrl: `${host}/logger/conversation/{conversationId}/content-log`,
loggingStateLogUrl: `${host}/logger/conversation/{conversationId}/state-log`,

// knowledge base
knowledgeBaseUploadUrl: `${host}/knowledge-base/upload`,
Expand Down
23 changes: 23 additions & 0 deletions src/lib/services/logging-service.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { replaceUrl } from '$lib/helpers/http.js';
import { endpoints } from './api-endpoints.js';
import axios from 'axios';

Expand All @@ -18,4 +19,26 @@ export async function getFullLog() {
link.click();
link.remove();
})
}

/**
* Get conversation content log
* @param {string} conversationId
* @returns {Promise<import('$types').ConversationContentLogModel[]>}
*/
export async function GetContentLogs(conversationId) {
let url = replaceUrl(endpoints.loggingContentLogUrl, {conversationId: conversationId});
const response = await axios.get(url);
return response.data;
}

/**
* Get conversation state log
* @param {string} conversationId
* @returns {Promise<import('$types').ConversationStateLogModel[]>}
*/
export async function GetStateLogs(conversationId) {
let url = replaceUrl(endpoints.loggingStateLogUrl, {conversationId: conversationId});
const response = await axios.get(url);
return response.data;
}
1 change: 1 addition & 0 deletions src/lib/services/signalr-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const signalr = {
connection.on('onConversateStatesGenerated', (data) => {
const jsonData = JSON.parse(data);
if (conversationId === jsonData?.conversation_id) {
console.log(data, jsonData);
this.onConversationStatesGenerated(jsonData);
}
});
Expand Down
47 changes: 28 additions & 19 deletions src/routes/chat/[agentId]/[conversationId]/chat-box.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
/** @type {{ [s: string]: any; }} */
let groupedDialogs = [];

/** @type {import('$types').ContentLogModel[]} */
/** @type {import('$types').ConversationContentLogModel[]} */
let contentLogs = [];

/** @type {import('$types').ConversationStateLogModel[]} */
Expand All @@ -79,7 +79,7 @@
let isLoadContentLog = false;
let isLoadStateLog = false;
let isOpenEditMsgModal = false;
let isOpenStateModal = false;
let isOpenAddStateModal = false;
let isSendingMsg = false;

onMount(async () => {
Expand Down Expand Up @@ -137,17 +137,16 @@
refresh();
}

/** @param {import('$types').ContentLogModel} log */
/** @param {import('$types').ConversationContentLogModel} log */
function onContentLogGenerated(log) {
contentLogs.push({
...log,
is_collapsed: true
});
if (!isLoadContentLog) return;
contentLogs.push({ ...log });
contentLogs = contentLogs.map(x => { return { ...x }; });
}

/** @param {import('$types').ConversationStateLogModel} data */
function onConversationStatesGenerated(data) {
if (!isLoadStateLog) return;
stateLogs.push({ ...data });
stateLogs = stateLogs.map(x => { return { ...x }; });
}
Expand Down Expand Up @@ -248,6 +247,10 @@
return;
}

if (e.key === 'Enter') {
e.preventDefault();
}

prevSentMsgs = [...prevSentMsgs, text];
isSendingMsg = true;
sendMessageToHub(params.agentId, params.conversationId, text).then(() => {
Expand Down Expand Up @@ -281,14 +284,20 @@

function toggleContentLog() {
isLoadContentLog = !isLoadContentLog;
if (!isLoadContentLog) {
contentLogs = [];
}
}

function toggleStateLog() {
isLoadStateLog = !isLoadStateLog;
if (!isLoadStateLog) {
stateLogs = [];
}
}

function toggleStateModal() {
isOpenStateModal = !isOpenStateModal;
function toggleAddStateModal() {
isOpenAddStateModal = !isOpenAddStateModal;
}

function clearStates() {
Expand Down Expand Up @@ -404,10 +413,10 @@

<StateModal
className="custom-modal"
isOpen={isOpenStateModal}
toggleModal={toggleStateModal}
confirm={toggleStateModal}
cancel={toggleStateModal}
isOpen={isOpenAddStateModal}
toggleModal={toggleAddStateModal}
confirm={toggleAddStateModal}
cancel={toggleAddStateModal}
/>

<HeadTitle title="Chat" addOn='' />
Expand Down Expand Up @@ -442,7 +451,7 @@
{#if !isLoadContentLog}
<DropdownItem on:click={() => toggleContentLog()}>View Log</DropdownItem>
{/if}
{#if !isLoadStateLog || !isOpenStateModal}
{#if !isLoadStateLog || !isOpenAddStateModal}
<li>
<Dropdown direction="right" class="state-menu">
<DropdownToggle caret class="dropdown-item">
Expand All @@ -452,8 +461,8 @@
{#if !isLoadStateLog}
<DropdownItem on:click={() => toggleStateLog()}>View States</DropdownItem>
{/if}
{#if !isOpenStateModal}
<DropdownItem on:click={() => toggleStateModal()}>Add States</DropdownItem>
{#if !isOpenAddStateModal}
<DropdownItem on:click={() => toggleAddStateModal()}>Add States</DropdownItem>
{/if}
<DropdownItem on:click={() => clearStates()}>Clear States</DropdownItem>
</DropdownMenu>
Expand Down Expand Up @@ -508,7 +517,7 @@
{:else}
<img src={PUBLIC_LIVECHAT_ENTRY_ICON} class="rounded-circle avatar-xs" alt="avatar">
{/if}
</div>
</div>
{/if}

{#if message.sender.id === currentUser.id}
Expand Down Expand Up @@ -564,7 +573,7 @@
</div>
<div class="col">
<div class="position-relative">
<textarea rows={1} maxlength={500} class="form-control chat-input" bind:value={text} on:keydown={e => onSendMessage(e)} placeholder="Enter Message..." />
<textarea rows={1} maxlength={500} class="form-control chat-input" bind:value={text} on:keydown={e => onSendMessage(e)} disabled={isSendingMsg} placeholder="Enter Message..." />
<div class="chat-input-links" id="tooltip-container">
<ul class="list-inline mb-0">
<li class="list-inline-item">
Expand All @@ -591,7 +600,7 @@
</Pane>
{#if isLoadContentLog}
<Pane size={30} minSize={20} maxSize={50}>
<ContentLog logs={contentLogs} closeWindow={toggleContentLog} />
<ContentLog contentLogs={contentLogs} closeWindow={toggleContentLog} />
</Pane>
{/if}
</Splitpanes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import { replaceNewLine } from '$lib/helpers/http';
import { UserRole } from '$lib/helpers/enums';

/** @type {import('$types').ContentLogModel} */
/** @type {import('$types').ConversationContentLogModel} */
export let data;

let is_collapsed = true;

/** @param {any} e */
function toggleText(e) {
e.preventDefault();
data.is_collapsed = !data.is_collapsed;
is_collapsed = !is_collapsed;
}
</script>

Expand All @@ -19,12 +21,12 @@
<b>{`[${data?.name?.length > 0 ? data?.name + ' ' : ''}${moment.utc(data?.created_at).local().format('hh:mm:ss.SSS A, MMM DD YYYY')}]`}</b>
</div>
<br>
<div class="log-content" class:log-collapse={!!data?.is_collapsed}>
<div class="log-content" class:log-collapse={!!is_collapsed}>
{@html replaceNewLine(data?.content)}
</div>
{#if data.role != UserRole.User}
<Button class='toggle-btn' color="link" on:click={(e) => toggleText(e)}>
{`${!!data?.is_collapsed ? 'More +' : 'Less -'}`}
{`${is_collapsed ? 'More +' : 'Less -'}`}
</Button>
{/if}
</div>
31 changes: 20 additions & 11 deletions src/routes/chat/[agentId]/[conversationId]/content-log.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
<script>
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';
import { afterUpdate, onMount, tick } from 'svelte';
import { afterUpdate, onDestroy, onMount, tick } from 'svelte';
import ContentLogElement from './content-log-element.svelte';
import { page } from '$app/stores';
import { GetContentLogs } from '$lib/services/logging-service';

/** @type {import('$types').ContentLogModel[]} */
export let logs = [];
/** @type {import('$types').ConversationContentLogModel[]} */
export let contentLogs = [];

/** @type {() => void} */
export let closeWindow;

// @ts-ignore
let scrollbar;
/** @type {import('$types').ConversationContentLogModel[]} */
let initLogs = [];

$: allLogs = [...initLogs, ...contentLogs];

const options = {
scrollbars: {
Expand All @@ -26,24 +32,27 @@
};

onMount(async () => {
const conversationId = $page.params.conversationId;
initLogs = await GetContentLogs(conversationId);

const scrollElements = document.querySelectorAll('.content-log-scrollbar');
scrollElements.forEach((item) => {
scrollbar = OverlayScrollbars(item, options);
});

refreshLog();
refresh();
});

afterUpdate(() => {
refreshLog();
refresh();
});

onDestroy(() => {
initLogs = [];
contentLogs = [];
});

async function refreshLog() {
// trigger UI render
logs = logs || [];
await tick();

async function refresh() {
setTimeout(() => {
const { viewport } = scrollbar.elements();
viewport.scrollTo({ top: viewport.scrollHeight, behavior: 'smooth' }); // set scroll offset
Expand All @@ -64,7 +73,7 @@
</div>
<div class="content-log-scrollbar log-list padding-side">
<ul>
{#each logs as log}
{#each allLogs as log}
<ContentLogElement data={log} />
{/each}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

/** @type {any} */
export let data;

$: stateObj = JSON.parse(JSON.stringify(data?.states || {}));
</script>

<div class="log-element">
Expand All @@ -12,6 +14,6 @@
</div>
<br>
<div class="log-content">
<JSONTree value={JSON.parse(data?.states)} />
<JSONTree value={stateObj} />
</div>
</div>
Loading
Loading