feat(ui): show total archived chat count in ChatsModal title (#25872)
This commit is contained in:
5 files changed
+75
-3
No files matched your search
@@ -831,6 +831,17 @@ class ChatTable:
|
|||||||
for chat in all_chats
|
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(
|
async def get_shared_chat_list_by_user_id(
|
||||||
self,
|
self,
|
||||||
user_id: str,
|
user_id: str,
|
||||||
|
|||||||
@@ -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
|
# ArchiveAllChats
|
||||||
############################
|
############################
|
||||||
|
|||||||
@@ -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) => {
|
export const getSharedChatList = async (token: string = '', page: number = 1, filter?: object) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import {
|
import {
|
||||||
archiveChatById,
|
archiveChatById,
|
||||||
getAllArchivedChats,
|
getAllArchivedChats,
|
||||||
|
getArchivedChatCount,
|
||||||
getArchivedChatList,
|
getArchivedChatList,
|
||||||
unarchiveAllChats
|
unarchiveAllChats
|
||||||
} from '$lib/apis/chats';
|
} from '$lib/apis/chats';
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let chatList: any[] | null = null;
|
let chatList: any[] | null = null;
|
||||||
|
let chatCount: number | null = null;
|
||||||
let page = 1;
|
let page = 1;
|
||||||
|
|
||||||
let query = '';
|
let query = '';
|
||||||
@@ -110,8 +112,9 @@
|
|||||||
toast.error(`${error}`);
|
toast.error(`${error}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
chatList = chatList?.filter((c) => c.id !== chatId) ?? null;
|
||||||
|
if (chatCount !== null) chatCount--;
|
||||||
onUpdate();
|
onUpdate();
|
||||||
init();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const unarchiveAllHandler = async () => {
|
const unarchiveAllHandler = async () => {
|
||||||
@@ -130,6 +133,7 @@
|
|||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
chatList = await getArchivedChatList(localStorage.token);
|
chatList = await getArchivedChatList(localStorage.token);
|
||||||
|
chatCount = await getArchivedChatCount(localStorage.token);
|
||||||
};
|
};
|
||||||
|
|
||||||
$: if (show) {
|
$: if (show) {
|
||||||
@@ -153,13 +157,15 @@
|
|||||||
bind:direction
|
bind:direction
|
||||||
title={$i18n.t('Archived Chats')}
|
title={$i18n.t('Archived Chats')}
|
||||||
emptyPlaceholder={$i18n.t('You have no archived conversations.')}
|
emptyPlaceholder={$i18n.t('You have no archived conversations.')}
|
||||||
|
count={chatCount}
|
||||||
{chatList}
|
{chatList}
|
||||||
{allChatsLoaded}
|
{allChatsLoaded}
|
||||||
{chatListLoading}
|
{chatListLoading}
|
||||||
onUpdate={() => {
|
onUpdate={() => {
|
||||||
init();
|
onUpdate();
|
||||||
}}
|
}}
|
||||||
onDelete={(id) => {
|
onDelete={(id) => {
|
||||||
|
if (chatCount !== null) chatCount--;
|
||||||
onDelete(id);
|
onDelete(id);
|
||||||
}}
|
}}
|
||||||
loadHandler={loadMoreChats}
|
loadHandler={loadMoreChats}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
export let showSearch = true;
|
export let showSearch = true;
|
||||||
export let readOnly = false;
|
export let readOnly = false;
|
||||||
|
|
||||||
|
export let count: number | null = null;
|
||||||
|
|
||||||
export let query = '';
|
export let query = '';
|
||||||
|
|
||||||
export let orderBy = 'updated_at';
|
export let orderBy = 'updated_at';
|
||||||
@@ -71,6 +73,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
chatList = chatList?.filter((c) => c.id !== chatId) ?? null;
|
||||||
onDelete(chatId);
|
onDelete(chatId);
|
||||||
}
|
}
|
||||||
onUpdate();
|
onUpdate();
|
||||||
@@ -90,7 +93,18 @@
|
|||||||
<Modal size="lg" bind:show>
|
<Modal size="lg" bind:show>
|
||||||
<div>
|
<div>
|
||||||
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-1">
|
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-1">
|
||||||
<div class=" text-lg font-medium self-center">{title}</div>
|
<div class="flex items-center gap-2 text-lg font-medium self-center">
|
||||||
|
<div>{title}</div>
|
||||||
|
{#if count !== null}
|
||||||
|
<div class="text-lg font-medium text-gray-500 dark:text-gray-500">
|
||||||
|
{count}
|
||||||
|
</div>
|
||||||
|
{:else if chatList}
|
||||||
|
<div class="text-lg font-medium text-gray-500 dark:text-gray-500">
|
||||||
|
{chatList.length}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
class="self-center"
|
class="self-center"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
|||||||
Reference in new issue
Block a user