From bcf78b4efa3a600df472923a0de26e4e2c319839 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 27 Apr 2024 18:24:59 -0400 Subject: [PATCH] feat: show user chats in admin panel --- backend/apps/web/models/chats.py | 9 ++ backend/apps/web/routers/chats.py | 21 +-- src/lib/apis/chats/index.ts | 31 ++++ .../components/admin/UserChatsModal.svelte | 141 ++++++++++++++++++ src/lib/components/chat/MessageInput.svelte | 9 +- src/lib/components/icons/ChatBubble.svelte | 19 +++ src/lib/components/icons/ChatBubbles.svelte | 19 +++ src/routes/(app)/admin/+page.svelte | 104 ++++++++----- 8 files changed, 301 insertions(+), 52 deletions(-) create mode 100644 src/lib/components/admin/UserChatsModal.svelte create mode 100644 src/lib/components/icons/ChatBubble.svelte create mode 100644 src/lib/components/icons/ChatBubbles.svelte diff --git a/backend/apps/web/models/chats.py b/backend/apps/web/models/chats.py index c83f26a9c..891151b94 100644 --- a/backend/apps/web/models/chats.py +++ b/backend/apps/web/models/chats.py @@ -270,6 +270,15 @@ class ChatTable: # .limit(limit).offset(skip) ] + def delete_chat_by_id(self, id: str) -> bool: + try: + query = Chat.delete().where((Chat.id == id)) + query.execute() # Remove the rows, return number of rows removed. + + return True and self.delete_shared_chat_by_chat_id(id) + except: + return False + def delete_chat_by_id_and_user_id(self, id: str, user_id: str) -> bool: try: query = Chat.delete().where((Chat.id == id) & (Chat.user_id == user_id)) diff --git a/backend/apps/web/routers/chats.py b/backend/apps/web/routers/chats.py index 4d03740cb..73b15e04a 100644 --- a/backend/apps/web/routers/chats.py +++ b/backend/apps/web/routers/chats.py @@ -188,17 +188,18 @@ async def update_chat_by_id( @router.delete("/{id}", response_model=bool) async def delete_chat_by_id(request: Request, id: str, user=Depends(get_current_user)): - if ( - user.role == "user" - and not request.app.state.USER_PERMISSIONS["chat"]["deletion"] - ): - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=ERROR_MESSAGES.ACCESS_PROHIBITED, - ) + if user.role == "admin": + result = Chats.delete_chat_by_id(id) + return result + else: + if not request.app.state.USER_PERMISSIONS["chat"]["deletion"]: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) - result = Chats.delete_chat_by_id_and_user_id(id, user.id) - return result + result = Chats.delete_chat_by_id_and_user_id(id, user.id) + return result ############################ diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index 5a9071bbc..7b76b11fa 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -62,6 +62,37 @@ export const getChatList = async (token: string = '') => { return res; }; +export const getChatListByUserId = async (token: string = '', userId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/list/user/${userId}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const getArchivedChatList = async (token: string = '') => { let error = null; diff --git a/src/lib/components/admin/UserChatsModal.svelte b/src/lib/components/admin/UserChatsModal.svelte new file mode 100644 index 000000000..4cf6425ed --- /dev/null +++ b/src/lib/components/admin/UserChatsModal.svelte @@ -0,0 +1,141 @@ + + + +
+
+
+ {$i18n.t("{{user}}'s Chats", { user: user.name })} +
+ +
+
+ +
+
+ {#if chats.length > 0} +
+
+ + + + + + + + + {#each chats as chat, idx} + + + + + + + + {/each} + +
{$i18n.t('Name')} +
+ +
+ {chat.title} +
+
+
+
+ + + +
+
+
+ +
+ {:else} +
You have no archived conversations.
+ {/if} +
+
+
+
diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 2793a8d4b..ba907f780 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -13,6 +13,7 @@ import Models from './MessageInput/Models.svelte'; import { transcribeAudio } from '$lib/apis/audio'; import Tooltip from '../common/Tooltip.svelte'; + import Page from '../../../routes/(app)/+page.svelte'; const i18n = getContext('i18n'); @@ -692,6 +693,7 @@ e.preventDefault(); } if (prompt !== '' && e.keyCode == 13 && !e.shiftKey) { + // TODO: Only if screensize > xl submitPrompt(prompt, user); } }} @@ -756,7 +758,11 @@ ...document.getElementsByClassName('selected-command-option-button') ]?.at(-1); - commandOptionButton?.click(); + if (commandOptionButton) { + commandOptionButton?.click(); + } else { + document.getElementById('send-message-button')?.click(); + } } if (['/', '#', '@'].includes(prompt.charAt(0)) && e.key === 'Tab') { @@ -895,6 +901,7 @@ + + + - + + + + + + + + +