mirror of
https://github.com/open-webui/open-webui
synced 2025-06-23 02:16:52 +00:00
fix: tag unarchive/archive issue
This commit is contained in:
parent
d8a30bd6ae
commit
6703cacb99
@ -401,10 +401,11 @@ class ChatTable:
|
|||||||
|
|
||||||
# search_text might contain 'tag:tag_name' format so we need to extract the tag_name, split the search_text and remove the tags
|
# search_text might contain 'tag:tag_name' format so we need to extract the tag_name, split the search_text and remove the tags
|
||||||
tag_ids = [
|
tag_ids = [
|
||||||
tag_name.replace("tag:", "").replace(" ", "_").lower()
|
word.replace("tag:", "").replace(" ", "_").lower()
|
||||||
for tag_name in search_text_words
|
for word in search_text_words
|
||||||
if tag_name.startswith("tag:")
|
if word.startswith("tag:")
|
||||||
]
|
]
|
||||||
|
|
||||||
search_text_words = [
|
search_text_words = [
|
||||||
word for word in search_text_words if not word.startswith("tag:")
|
word for word in search_text_words if not word.startswith("tag:")
|
||||||
]
|
]
|
||||||
@ -450,11 +451,11 @@ class ChatTable:
|
|||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM json_each(Chat.meta, '$.tags') AS tag
|
FROM json_each(Chat.meta, '$.tags') AS tag
|
||||||
WHERE tag.value = :tag_id
|
WHERE tag.value = :tag_id_{tag_idx}
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
).params(tag_id=tag_id)
|
).params(**{f"tag_id_{tag_idx}": tag_id})
|
||||||
for tag_id in tag_ids
|
for tag_idx, tag_id in enumerate(tag_ids)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -488,11 +489,11 @@ class ChatTable:
|
|||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM json_array_elements_text(Chat.meta->'tags') AS tag
|
FROM json_array_elements_text(Chat.meta->'tags') AS tag
|
||||||
WHERE tag = :tag_id
|
WHERE tag = :tag_id_{tag_idx}
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
).params(tag_id=tag_id)
|
).params(**{f"tag_id_{tag_idx}": tag_id})
|
||||||
for tag_id in tag_ids
|
for tag_idx, tag_id in enumerate(tag_ids)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -571,7 +572,7 @@ class ChatTable:
|
|||||||
|
|
||||||
def count_chats_by_tag_name_and_user_id(self, tag_name: str, user_id: str) -> int:
|
def count_chats_by_tag_name_and_user_id(self, tag_name: str, user_id: str) -> int:
|
||||||
with get_db() as db: # Assuming `get_db()` returns a session object
|
with get_db() as db: # Assuming `get_db()` returns a session object
|
||||||
query = db.query(Chat).filter_by(user_id=user_id)
|
query = db.query(Chat).filter_by(user_id=user_id, archived=False)
|
||||||
|
|
||||||
# Normalize the tag_name for consistency
|
# Normalize the tag_name for consistency
|
||||||
tag_id = tag_name.replace(" ", "_").lower()
|
tag_id = tag_name.replace(" ", "_").lower()
|
||||||
|
@ -114,13 +114,24 @@ async def search_user_chats(
|
|||||||
limit = 60
|
limit = 60
|
||||||
skip = (page - 1) * limit
|
skip = (page - 1) * limit
|
||||||
|
|
||||||
return [
|
chat_list = [
|
||||||
ChatTitleIdResponse(**chat.model_dump())
|
ChatTitleIdResponse(**chat.model_dump())
|
||||||
for chat in Chats.get_chats_by_user_id_and_search_text(
|
for chat in Chats.get_chats_by_user_id_and_search_text(
|
||||||
user.id, text, skip=skip, limit=limit
|
user.id, text, skip=skip, limit=limit
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Delete tag if no chat is found
|
||||||
|
words = text.strip().split(" ")
|
||||||
|
if page == 1 and len(words) == 1 and words[0].startswith("tag:"):
|
||||||
|
tag_id = words[0].replace("tag:", "")
|
||||||
|
if len(chat_list) == 0:
|
||||||
|
if Tags.get_tag_by_name_and_user_id(tag_id, user.id):
|
||||||
|
log.debug(f"deleting tag: {tag_id}")
|
||||||
|
Tags.delete_tag_by_name_and_user_id(tag_id, user.id)
|
||||||
|
|
||||||
|
return chat_list
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# GetPinnedChats
|
# GetPinnedChats
|
||||||
@ -315,7 +326,13 @@ async def update_chat_by_id(
|
|||||||
@router.delete("/{id}", response_model=bool)
|
@router.delete("/{id}", response_model=bool)
|
||||||
async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified_user)):
|
async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified_user)):
|
||||||
if user.role == "admin":
|
if user.role == "admin":
|
||||||
|
chat = Chats.get_chat_by_id(id)
|
||||||
|
for tag in chat.meta.get("tags", []):
|
||||||
|
if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 0:
|
||||||
|
Tags.delete_tag_by_name_and_user_id(tag, user.id)
|
||||||
|
|
||||||
result = Chats.delete_chat_by_id(id)
|
result = Chats.delete_chat_by_id(id)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
if not request.app.state.config.USER_PERMISSIONS.get("chat", {}).get(
|
if not request.app.state.config.USER_PERMISSIONS.get("chat", {}).get(
|
||||||
@ -326,6 +343,11 @@ async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified
|
|||||||
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
|
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
chat = Chats.get_chat_by_id(id)
|
||||||
|
for tag in chat.meta.get("tags", []):
|
||||||
|
if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 0:
|
||||||
|
Tags.delete_tag_by_name_and_user_id(tag, user.id)
|
||||||
|
|
||||||
result = Chats.delete_chat_by_id_and_user_id(id, user.id)
|
result = Chats.delete_chat_by_id_and_user_id(id, user.id)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -397,6 +419,20 @@ async def archive_chat_by_id(id: str, user=Depends(get_verified_user)):
|
|||||||
chat = Chats.get_chat_by_id_and_user_id(id, user.id)
|
chat = Chats.get_chat_by_id_and_user_id(id, user.id)
|
||||||
if chat:
|
if chat:
|
||||||
chat = Chats.toggle_chat_archive_by_id(id)
|
chat = Chats.toggle_chat_archive_by_id(id)
|
||||||
|
|
||||||
|
# Delete tags if chat is archived
|
||||||
|
if chat.archived:
|
||||||
|
for tag_id in chat.meta.get("tags", []):
|
||||||
|
if Chats.count_chats_by_tag_name_and_user_id(tag_id, user.id) == 0:
|
||||||
|
log.debug(f"deleting tag: {tag_id}")
|
||||||
|
Tags.delete_tag_by_name_and_user_id(tag_id, user.id)
|
||||||
|
else:
|
||||||
|
for tag_id in chat.meta.get("tags", []):
|
||||||
|
tag = Tags.get_tag_by_name_and_user_id(tag_id, user.id)
|
||||||
|
if tag is None:
|
||||||
|
log.debug(f"inserting tag: {tag_id}")
|
||||||
|
tag = Tags.insert_new_tag(tag_id, user.id)
|
||||||
|
|
||||||
return ChatResponse(**chat.model_dump())
|
return ChatResponse(**chat.model_dump())
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
@ -267,7 +267,7 @@ export const getAllUserChats = async (token: string) => {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAllChatTags = async (token: string) => {
|
export const getAllTags = async (token: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/tags`, {
|
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/tags`, {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import {
|
import {
|
||||||
addTagById,
|
addTagById,
|
||||||
deleteTagById,
|
deleteTagById,
|
||||||
getAllChatTags,
|
getAllTags,
|
||||||
getChatList,
|
getChatList,
|
||||||
getChatListByTagName,
|
getChatListByTagName,
|
||||||
getTagsById,
|
getTagsById,
|
||||||
@ -37,7 +37,7 @@
|
|||||||
tags: tags
|
tags: tags
|
||||||
});
|
});
|
||||||
|
|
||||||
await _tags.set(await getAllChatTags(localStorage.token));
|
await _tags.set(await getAllTags(localStorage.token));
|
||||||
dispatch('add', {
|
dispatch('add', {
|
||||||
name: tagName
|
name: tagName
|
||||||
});
|
});
|
||||||
@ -50,7 +50,7 @@
|
|||||||
tags: tags
|
tags: tags
|
||||||
});
|
});
|
||||||
|
|
||||||
await _tags.set(await getAllChatTags(localStorage.token));
|
await _tags.set(await getAllTags(localStorage.token));
|
||||||
dispatch('delete', {
|
dispatch('delete', {
|
||||||
name: tagName
|
name: tagName
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
getChatById,
|
getChatById,
|
||||||
getChatListByTagName,
|
getChatListByTagName,
|
||||||
updateChatById,
|
updateChatById,
|
||||||
getAllChatTags,
|
getAllTags,
|
||||||
archiveChatById,
|
archiveChatById,
|
||||||
cloneChatById,
|
cloneChatById,
|
||||||
getChatListBySearchText,
|
getChatListBySearchText,
|
||||||
@ -77,6 +77,8 @@
|
|||||||
|
|
||||||
const initChatList = async () => {
|
const initChatList = async () => {
|
||||||
// Reset pagination variables
|
// Reset pagination variables
|
||||||
|
tags.set(await getAllTags(localStorage.token));
|
||||||
|
|
||||||
currentChatPage.set(1);
|
currentChatPage.set(1);
|
||||||
allChatsLoaded = false;
|
allChatsLoaded = false;
|
||||||
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
||||||
@ -123,6 +125,10 @@
|
|||||||
searchDebounceTimeout = setTimeout(async () => {
|
searchDebounceTimeout = setTimeout(async () => {
|
||||||
currentChatPage.set(1);
|
currentChatPage.set(1);
|
||||||
await chats.set(await getChatListBySearchText(localStorage.token, search));
|
await chats.set(await getChatListBySearchText(localStorage.token, search));
|
||||||
|
|
||||||
|
if ($chats.length === 0) {
|
||||||
|
tags.set(await getAllTags(localStorage.token));
|
||||||
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -134,6 +140,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
tags.set(await getAllTags(localStorage.token));
|
||||||
|
|
||||||
if ($chatId === id) {
|
if ($chatId === id) {
|
||||||
await chatId.set('');
|
await chatId.set('');
|
||||||
await tick();
|
await tick();
|
||||||
@ -143,7 +151,6 @@
|
|||||||
allChatsLoaded = false;
|
allChatsLoaded = false;
|
||||||
currentChatPage.set(1);
|
currentChatPage.set(1);
|
||||||
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
||||||
|
|
||||||
await pinnedChats.set(await getPinnedChatList(localStorage.token));
|
await pinnedChats.set(await getPinnedChatList(localStorage.token));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -324,7 +331,7 @@
|
|||||||
bind:show={$showArchivedChats}
|
bind:show={$showArchivedChats}
|
||||||
on:change={async () => {
|
on:change={async () => {
|
||||||
await pinnedChats.set(await getPinnedChatList(localStorage.token));
|
await pinnedChats.set(await getPinnedChatList(localStorage.token));
|
||||||
await chats.set(await getChatList(localStorage.token));
|
await initChatList();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
getArchivedChatList
|
getArchivedChatList
|
||||||
} from '$lib/apis/chats';
|
} from '$lib/apis/chats';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
@ -30,7 +29,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
chats = await getArchivedChatList(localStorage.token);
|
chats = await getArchivedChatList(localStorage.token);
|
||||||
|
|
||||||
dispatch('change');
|
dispatch('change');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
archiveChatById,
|
archiveChatById,
|
||||||
cloneChatById,
|
cloneChatById,
|
||||||
deleteChatById,
|
deleteChatById,
|
||||||
|
getAllTags,
|
||||||
getChatList,
|
getChatList,
|
||||||
getChatListByTagName,
|
getChatListByTagName,
|
||||||
getPinnedChatList,
|
getPinnedChatList,
|
||||||
@ -22,7 +23,8 @@
|
|||||||
mobile,
|
mobile,
|
||||||
pinnedChats,
|
pinnedChats,
|
||||||
showSidebar,
|
showSidebar,
|
||||||
currentChatPage
|
currentChatPage,
|
||||||
|
tags
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
|
|
||||||
import ChatMenu from './ChatMenu.svelte';
|
import ChatMenu from './ChatMenu.svelte';
|
||||||
@ -77,6 +79,7 @@
|
|||||||
|
|
||||||
const archiveChatHandler = async (id) => {
|
const archiveChatHandler = async (id) => {
|
||||||
await archiveChatById(localStorage.token, id);
|
await archiveChatById(localStorage.token, id);
|
||||||
|
tags.set(await getAllTags(localStorage.token));
|
||||||
|
|
||||||
currentChatPage.set(1);
|
currentChatPage.set(1);
|
||||||
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
await chats.set(await getChatList(localStorage.token, $currentChatPage));
|
||||||
|
@ -15,13 +15,8 @@
|
|||||||
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
||||||
import Bookmark from '$lib/components/icons/Bookmark.svelte';
|
import Bookmark from '$lib/components/icons/Bookmark.svelte';
|
||||||
import BookmarkSlash from '$lib/components/icons/BookmarkSlash.svelte';
|
import BookmarkSlash from '$lib/components/icons/BookmarkSlash.svelte';
|
||||||
import {
|
import { getChatPinnedStatusById, toggleChatPinnedStatusById } from '$lib/apis/chats';
|
||||||
addTagById,
|
import { chats } from '$lib/stores';
|
||||||
deleteTagById,
|
|
||||||
getChatPinnedStatusById,
|
|
||||||
getTagsById,
|
|
||||||
toggleChatPinnedStatusById
|
|
||||||
} from '$lib/apis/chats';
|
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -146,6 +141,7 @@
|
|||||||
type: 'add',
|
type: 'add',
|
||||||
name: e.detail.name
|
name: e.detail.name
|
||||||
});
|
});
|
||||||
|
|
||||||
show = false;
|
show = false;
|
||||||
}}
|
}}
|
||||||
on:delete={(e) => {
|
on:delete={(e) => {
|
||||||
@ -153,6 +149,7 @@
|
|||||||
type: 'delete',
|
type: 'delete',
|
||||||
name: e.detail.name
|
name: e.detail.name
|
||||||
});
|
});
|
||||||
|
|
||||||
show = false;
|
show = false;
|
||||||
}}
|
}}
|
||||||
on:close={() => {
|
on:close={() => {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
import { getKnowledgeItems } from '$lib/apis/knowledge';
|
import { getKnowledgeItems } from '$lib/apis/knowledge';
|
||||||
import { getFunctions } from '$lib/apis/functions';
|
import { getFunctions } from '$lib/apis/functions';
|
||||||
import { getModels as _getModels, getVersionUpdates } from '$lib/apis';
|
import { getModels as _getModels, getVersionUpdates } from '$lib/apis';
|
||||||
import { getAllChatTags } from '$lib/apis/chats';
|
import { getAllTags } from '$lib/apis/chats';
|
||||||
import { getPrompts } from '$lib/apis/prompts';
|
import { getPrompts } from '$lib/apis/prompts';
|
||||||
import { getTools } from '$lib/apis/tools';
|
import { getTools } from '$lib/apis/tools';
|
||||||
import { getBanners } from '$lib/apis/configs';
|
import { getBanners } from '$lib/apis/configs';
|
||||||
@ -117,7 +117,7 @@
|
|||||||
banners.set(await getBanners(localStorage.token));
|
banners.set(await getBanners(localStorage.token));
|
||||||
})(),
|
})(),
|
||||||
(async () => {
|
(async () => {
|
||||||
tags.set(await getAllChatTags(localStorage.token));
|
tags.set(await getAllTags(localStorage.token));
|
||||||
})()
|
})()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user