diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py
index 437bf1e22..0ac53a023 100644
--- a/backend/open_webui/models/chats.py
+++ b/backend/open_webui/models/chats.py
@@ -417,6 +417,7 @@ class ChatTable:
self,
user_id: str,
include_archived: bool = False,
+ filter: Optional[dict] = None,
skip: int = 0,
limit: int = 50,
) -> list[ChatModel]:
@@ -425,7 +426,23 @@ class ChatTable:
if not include_archived:
query = query.filter_by(archived=False)
- query = query.order_by(Chat.updated_at.desc())
+ if filter:
+ query_key = filter.get("query")
+ if query_key:
+ query = query.filter(Chat.title.ilike(f"%{query_key}%"))
+
+ order_by = filter.get("order_by")
+ direction = filter.get("direction")
+
+ if order_by and direction and getattr(Chat, order_by):
+ if direction.lower() == "asc":
+ query = query.order_by(getattr(Chat, order_by).asc())
+ elif direction.lower() == "desc":
+ query = query.order_by(getattr(Chat, order_by).desc())
+ else:
+ raise ValueError("Invalid direction for ordering")
+ else:
+ query = query.order_by(Chat.updated_at.desc())
if skip:
query = query.offset(skip)
@@ -566,7 +583,9 @@ class ChatTable:
search_text = search_text.lower().strip()
if not search_text:
- return self.get_chat_list_by_user_id(user_id, include_archived, skip, limit)
+ return self.get_chat_list_by_user_id(
+ user_id, include_archived, filter={}, skip=skip, limit=limit
+ )
search_text_words = search_text.split(" ")
diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py
index 8dc049aec..98628642c 100644
--- a/backend/open_webui/routers/chats.py
+++ b/backend/open_webui/routers/chats.py
@@ -76,17 +76,34 @@ async def delete_all_user_chats(request: Request, user=Depends(get_verified_user
@router.get("/list/user/{user_id}", response_model=list[ChatTitleIdResponse])
async def get_user_chat_list_by_user_id(
user_id: str,
+ page: Optional[int] = None,
+ query: Optional[str] = None,
+ order_by: Optional[str] = None,
+ direction: Optional[str] = None,
user=Depends(get_admin_user),
- skip: int = 0,
- limit: int = 50,
):
if not ENABLE_ADMIN_CHAT_ACCESS:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
)
+
+ if page is None:
+ page = 1
+
+ limit = 60
+ skip = (page - 1) * limit
+
+ filter = {}
+ if query:
+ filter["query"] = query
+ if order_by:
+ filter["order_by"] = order_by
+ if direction:
+ filter["direction"] = direction
+
return Chats.get_chat_list_by_user_id(
- user_id, include_archived=True, skip=skip, limit=limit
+ user_id, include_archived=True, filter=filter, skip=skip, limit=limit
)
diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts
index 756128613..9d24b3971 100644
--- a/src/lib/apis/chats/index.ts
+++ b/src/lib/apis/chats/index.ts
@@ -111,17 +111,37 @@ export const getChatList = async (token: string = '', page: number | null = null
}));
};
-export const getChatListByUserId = async (token: string = '', userId: string) => {
+export const getChatListByUserId = async (
+ token: string = '',
+ userId: string,
+ page: number = 1,
+ filter?: object
+) => {
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}` })
+ const searchParams = new URLSearchParams();
+
+ searchParams.append('page', `${page}`);
+
+ if (filter) {
+ Object.entries(filter).forEach(([key, value]) => {
+ if (value !== undefined && value !== null) {
+ searchParams.append(key, value.toString());
+ }
+ });
+ }
+
+ const res = await fetch(
+ `${WEBUI_API_BASE_URL}/chats/list/user/${userId}?${searchParams.toString()}`,
+ {
+ 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();
@@ -188,7 +208,10 @@ export const getArchivedChatList = async (
throw error;
}
- return res;
+ return res.map((chat) => ({
+ ...chat,
+ time_range: getTimeRange(chat.updated_at)
+ }));
};
export const getAllChats = async (token: string) => {
diff --git a/src/lib/components/admin/Users/UserList.svelte b/src/lib/components/admin/Users/UserList.svelte
index 61816780b..31eec1fbd 100644
--- a/src/lib/components/admin/Users/UserList.svelte
+++ b/src/lib/components/admin/Users/UserList.svelte
@@ -165,7 +165,10 @@
getUserList();
}}
/>
-
setSortKey('title')} - > - {$i18n.t('Title')} - {#if sortKey === 'title'} - {sortOrder === 'asc' ? '▲' : '▼'} - {:else} - ▲ - {/if} - | - -- |
---|---|
-
-
- {chat.title}
-
-
- |
-
-
-
-
-
-
- |
-