From dee07d8a303fa75b8bc8e8150f70da0d6ca790c8 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Tue, 16 Jun 2026 20:57:27 -0400 Subject: [PATCH] feat(ui): show total archived chat count in ChatsModal title (#25872) --- backend/open_webui/models/chats.py | 11 ++++++++ backend/open_webui/routers/chats.py | 13 +++++++++ src/lib/apis/chats/index.ts | 28 +++++++++++++++++++ .../layout/ArchivedChatsModal.svelte | 10 +++++-- src/lib/components/layout/ChatsModal.svelte | 16 ++++++++++- 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index 9dfeeab491..f96ec76e2a 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -831,6 +831,17 @@ class ChatTable: for chat in all_chats ] + async def count_archived_chats_by_user_id( + self, + user_id: str, + db: AsyncSession | None = None, + ) -> int: + async with get_async_db_context(db) as session: + result = await session.execute( + select(func.count(Chat.id)).filter_by(user_id=user_id, archived=True) + ) + return result.scalar() or 0 + async def get_shared_chat_list_by_user_id( self, user_id: str, diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 48b6a29315..06457b4c55 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -819,6 +819,19 @@ async def get_archived_session_user_chat_list( ) +############################ +# GetArchivedChatsCount +############################ + + +@router.get('/archived/count', response_model=int) +async def get_archived_session_user_chat_count( + user=Depends(get_verified_user), + db: AsyncSession = Depends(get_async_session), +): + return await Chats.count_archived_chats_by_user_id(user.id, db=db) + + ############################ # ArchiveAllChats ############################ diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index 1916e35086..6c1f6454a3 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -255,6 +255,34 @@ export const getArchivedChatList = async ( })); }; +export const getArchivedChatCount = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/archived/count`, { + 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(); + }) + .catch((err) => { + error = err; + console.error(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const getSharedChatList = async (token: string = '', page: number = 1, filter?: object) => { let error = null; diff --git a/src/lib/components/layout/ArchivedChatsModal.svelte b/src/lib/components/layout/ArchivedChatsModal.svelte index 31e322a105..e695300d09 100644 --- a/src/lib/components/layout/ArchivedChatsModal.svelte +++ b/src/lib/components/layout/ArchivedChatsModal.svelte @@ -9,6 +9,7 @@ import { archiveChatById, getAllArchivedChats, + getArchivedChatCount, getArchivedChatList, unarchiveAllChats } from '$lib/apis/chats'; @@ -25,6 +26,7 @@ let loading = false; let chatList: any[] | null = null; + let chatCount: number | null = null; let page = 1; let query = ''; @@ -110,8 +112,9 @@ toast.error(`${error}`); }); + chatList = chatList?.filter((c) => c.id !== chatId) ?? null; + if (chatCount !== null) chatCount--; onUpdate(); - init(); }; const unarchiveAllHandler = async () => { @@ -130,6 +133,7 @@ const init = async () => { chatList = await getArchivedChatList(localStorage.token); + chatCount = await getArchivedChatCount(localStorage.token); }; $: if (show) { @@ -153,13 +157,15 @@ bind:direction title={$i18n.t('Archived Chats')} emptyPlaceholder={$i18n.t('You have no archived conversations.')} + count={chatCount} {chatList} {allChatsLoaded} {chatListLoading} onUpdate={() => { - init(); + onUpdate(); }} onDelete={(id) => { + if (chatCount !== null) chatCount--; onDelete(id); }} loadHandler={loadMoreChats} diff --git a/src/lib/components/layout/ChatsModal.svelte b/src/lib/components/layout/ChatsModal.svelte index b56ed780d3..902baebe50 100644 --- a/src/lib/components/layout/ChatsModal.svelte +++ b/src/lib/components/layout/ChatsModal.svelte @@ -36,6 +36,8 @@ export let showSearch = true; export let readOnly = false; + export let count: number | null = null; + export let query = ''; export let orderBy = 'updated_at'; @@ -71,6 +73,7 @@ }); if (res) { + chatList = chatList?.filter((c) => c.id !== chatId) ?? null; onDelete(chatId); } onUpdate(); @@ -90,7 +93,18 @@
-
{title}
+
+
{title}
+ {#if count !== null} +
+ {count} +
+ {:else if chatList} +
+ {chatList.length} +
+ {/if} +