Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/SciSharp/BotSharp-UI into f…
Browse files Browse the repository at this point in the history
…eatures/refine-chat-window
  • Loading branch information
Jicheng Lu committed Nov 27, 2024
2 parents c73b117 + d0cfdb6 commit 50a76b5
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/lib/helpers/types/userTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,15 @@
* @property {string[]} [external_ids] - The external ids.
*/

/**
* @typedef {Object} DashboardModel
* @property {DashboardConversation[]} [conversation_list] - conversation components
*/

/**
* @typedef {Object} DashboardConversation
* @property {string} [name] - The conversation name.
* @property {string} [conversation_id] - The conversation id.
* @property {string} [instruction] - The user input instruction.
*/
export default {};
5 changes: 5 additions & 0 deletions src/lib/services/api-endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const endpoints = {
conversationMessageUpdateUrl: `${host}/conversation/{conversationId}/update-message`,
conversationTagsUpdateUrl: `${host}/conversation/{conversationId}/update-tags`,
fileUploadUrl: `${host}/agent/{agentId}/conversation/{conversationId}/upload`,
pinConversationUrl: `${host}/agent/{agentId}/conversation/{conversationId}/dashboard`,

// LLM provider
llmProvidersUrl: `${host}/llm-providers`,
Expand Down Expand Up @@ -93,6 +94,10 @@ export const endpoints = {
// chathub
chatHubUrl: `${host}/chatHub`,

// dashboard
dashboardSettingUrl: `${host}/dashboard/components`,
dashConversationInstructionUrl: `${host}/dashboard/component/conversation?userId={userId}`,

// Google geocode api
addressUrl: `${host}/address/options`
}
Expand Down
41 changes: 41 additions & 0 deletions src/lib/services/conversation-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,47 @@ export async function sendMessageToHub(agentId, conversationId, text, data = nul
return response.data;
}

/**
* pin a conversation to dashboard
* @param {string} agentId - The agent id
* @param {string} conversationId - The conversation id
*/
export async function pinConversationToDashboard(agentId, conversationId) {
let url = replaceUrl(endpoints.pinConversationUrl, {
agentId: agentId,
conversationId: conversationId
});
const response = await axios.put(url);
return response.data;
}

/**
* unpin a conversation from dashboard
* @param {string} agentId - The agent id
* @param {string} conversationId - The conversation id
*/
export async function unpinConversationFromDashboard(agentId, conversationId) {
let url = replaceUrl(endpoints.pinConversationUrl, {
agentId: agentId,
conversationId: conversationId
});
const response = await axios.delete(url);
return response.data;
}

/**
* update a dashboard conversation instuction
* @param {string} userId - The conversation id
* @param {import('$userTypes').DashboardConversation} dashConv - The instruction
*/
export async function updateDashboardConversation(userId, dashConv) {
let url = replaceUrl(endpoints.dashConversationInstructionUrl, {
userId: userId
});
const response = await axios.post(url, dashConv);
return response.data;
}


/**
* send a notification to conversation
Expand Down
19 changes: 19 additions & 0 deletions src/lib/services/dashboard-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { endpoints } from '$lib/services/api-endpoints.js';
import axios from 'axios';

/**
* Get dashboard settings
* @param {string} userId - The user id
* @returns {Promise<import('$userTypes').DashboardModel>}
*/
export async function getDashboardSettings(userId) {
let userIdParam = userId;
let url = endpoints.dashboardSettingUrl;
console.log(url);
const response = await axios.get(url, {
params: {
"userId" : userId
}
});
return response.data;
}
12 changes: 11 additions & 1 deletion src/routes/chat/[agentId]/[conversationId]/chat-box.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
getConversationUser,
uploadConversationFiles,
getAddressOptions,
pinConversationToDashboard,
} from '$lib/services/conversation-service.js';
import {
PUBLIC_LIVECHAT_ENTRY_ICON,
Expand Down Expand Up @@ -553,6 +554,12 @@
window.location.href = url.toString();
}
function pinDashboard() {
const agentId = params.agentId;
const convId = params.conversationId;
pinConversationToDashboard(agentId, convId).then().finally();
}
function handleSaveKnowledge() {
sendChatMessage("Save knowledge");
}
Expand Down Expand Up @@ -1520,7 +1527,10 @@
{/if}
{#if agent?.id === LEARNER_ID && mode === TRAINING_MODE}
<DropdownItem on:click={() => handleSaveKnowledge()}>Save Knowledge</DropdownItem>
{/if}
{/if}
<DropdownItem on:click={() => pinDashboard()}>
Pin to Dashboard
</DropdownItem>
</DropdownMenu>
</Dropdown>
{:else}
Expand Down
34 changes: 32 additions & 2 deletions src/routes/page/dashboard/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,44 @@
} from '$env/static/public';
import { onMount } from 'svelte';
import { getUserStore, userStore } from '$lib/helpers/store';
import Conversation from './Conversation.svelte';
import { getDashboardSettings } from '$lib/services/dashboard-service';
let subscribemodal = false;
let user = {full_name: ""};
let user = {full_name: "", id: ""};
/**
* @type {import("../../../lib/helpers/types/userTypes").DashboardModel}
*/
let dashboard_model ;
const togglesubscribemodal = (() => {
subscribemodal = !subscribemodal;
})
onMount(() => {
const userModelSubscribe = userStore.subscribe((/** @type {{ full_name: string; }} */ value) => {
const userModelSubscribe = userStore.subscribe((/** @type {{ full_name: string; id: string }} */ value) => {
user = value;
})
user = getUserStore();
loadDashboardComponents(user.id);
setTimeout(() => {
subscribemodal = true;
}, 1000);
})
/**
* delete a message in conversation
* @param {string} userId The user input
*/
async function loadDashboardComponents(userId) {
getDashboardSettings(userId)
.then(
response => {
dashboard_model = response
}
)
.catch();
}
</script>

<HeadTitle title={$_('Dashboard')} />
Expand Down Expand Up @@ -207,6 +229,14 @@
</Col>
</Row>

<Row>
{#each dashboard_model?.conversation_list || [] as conv, index (conv.conversation_id)}
{#if conv?.conversation_id}
<Conversation conversationId={conv.conversation_id} instruction={conv.instruction} userId={user.id}/>
{/if}
{/each}
</Row>

<Row>
<SocialSource />
<Activity />
Expand Down
155 changes: 155 additions & 0 deletions src/routes/page/dashboard/Conversation.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<script>
import { Card, CardBody, CardTitle, Col, Row } from '@sveltestrap/sveltestrap';
import { _ } from 'svelte-i18n';
import { onMount } from 'svelte';
import ChatTextArea from '../../chat/[agentId]/[conversationId]/chat-util/chat-text-area.svelte';
import { getConversation, updateDashboardConversation, unpinConversationFromDashboard } from '$lib/services/conversation-service';
/** @type {string}*/
export let conversationId;
/** @type {string}*/
export let instruction;
/** @type {string}*/
export let userId;
/** @type {import('$conversationTypes').ConversationModel}*/
let conversationModel;
let agent = {
name: "Loading",
icon_url: "https://botsharp.azurewebsites.net/images/users/bot.png"
};
let isLoading = true;
/** @type {string} */
let hide = '';
/** @type {string} */
let text;
/** @type {boolean} */
let loadUtils;
/** @type {number} */
let messageInputTimeout;
/** @type {string[]} */
let chatUtilOptions = [];
onMount(() => {
if (conversationId) {
loadDashboardComponents(conversationId);
}
if (instruction) {
text = instruction;
}
}
);
/**
* delete a message in conversation
* @param {string} id The user input
*/
async function loadDashboardComponents(id) {
getConversation(id)
.then(
response => {
conversationModel = response;
isLoading = false;
}
)
.catch();
}
/** @param {any} e */
function handleMessageInput(e) {
const value = e.target.value;
clearTimeout(messageInputTimeout);
chatUtilOptions = [];
}
</script>

<Col xl={4}>
<Card bind:class={hide}>
<CardBody>
{#if isLoading}
<CardTitle class="mb-0">{"Loading..."} </CardTitle>
<p> Loading ... </p>
{:else}
<div class="row">
<div class="col-10">
<CardTitle class="mb-0">{conversationModel.title} </CardTitle>
</div>
<div class="col-2 ">
<button
class={`btn btn-rounded btn-sm btn-light`}
on:click={() => {
hide = 'hide';
unpinConversationFromDashboard(conversationModel.agent_id, conversationId);
}}
>
<i
class="mdi mdi-pin-off"
style="font-size: 12px;"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Unpin"
/>
</button>
</div>
</div>
<div class="card mb-2">
<div class="chat-head">
<div class="row chat-row">
<div class="col-md-0 col-7 chat-head-info">
<div class="chat-head-agent">
{#if agent?.icon_url}
<div class="line-align-center">
<img class="chat-head-agent-icon" src={agent.icon_url} alt="">
</div>
{/if}
<div class="chat-head-agent-name line-align-center ellipsis">{conversationModel.agent_id}</div>
</div>
</div>
</div>
</div>

<div class={`chat-input-section css-animation fade-in-from-none mb-2`}>
<div class="row">
<div class="col-10">
<div class="position-relative">
<ChatTextArea
className={`chat-input`}
maxLength={1024}
disabled={false}
bind:text={text}
bind:loadUtils={loadUtils}
bind:options={chatUtilOptions}
onFocus={e => chatUtilOptions = []}
>
</ChatTextArea>
</div>
</div>
<div class="col-auto">
<button
type="submit"
class={`btn btn-rounded chat-send waves-effect waves-light btn-primary`}
disabled={!!!(text)}
on:click={() => updateDashboardConversation(userId, {
conversation_id: conversationId,
name: '',
instruction: text
})}
>
<i class="mdi mdi-send" />
</button>
</div>
</div>
</div>
</div>
{/if}

</CardBody>
</Card>
</Col>

0 comments on commit 50a76b5

Please sign in to comment.