diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py index edc9f85ff2..489a699bf3 100644 --- a/backend/open_webui/routers/folders.py +++ b/backend/open_webui/routers/folders.py @@ -49,7 +49,7 @@ async def get_folders(user=Depends(get_verified_user)): **folder.model_dump(), "items": { "chats": [ - {"title": chat.title, "id": chat.id} + {"title": chat.title, "id": chat.id, "updated_at": chat.updated_at} for chat in Chats.get_chats_by_folder_id_and_user_id( folder.id, user.id ) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 1f49f6ace8..fd6756f62f 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -2113,8 +2113,8 @@ showBanners={!showCommands} /> -
- {#if $settings?.landingPageMode === 'chat' || createMessagesList(history, history.currentId).length > 0} +
+ {#if ($settings?.landingPageMode === 'chat' && !$selectedFolder) || createMessagesList(history, history.currentId).length > 0} {:else} -
+
{#if $selectedFolder} -
-
-
- -
+ { + selectedFolder.set(folder); -
- {$selectedFolder?.name} -
-
+ await chats.set(await getChatList(localStorage.token, $currentChatPage)); + currentChatPage.set(1); + }} + onDelete={async () => { + await chats.set(await getChatList(localStorage.token, $currentChatPage)); + currentChatPage.set(1); -
- -
-
+ selectedFolder.set(null); + }} + /> {:else}
@@ -249,16 +243,26 @@
-
-
- + + {#if $selectedFolder} +
+
-
+ {:else} +
+
+ +
+
+ {/if}
diff --git a/src/lib/components/chat/Placeholder/ChatList.svelte b/src/lib/components/chat/Placeholder/ChatList.svelte new file mode 100644 index 0000000000..1e48298ec5 --- /dev/null +++ b/src/lib/components/chat/Placeholder/ChatList.svelte @@ -0,0 +1,103 @@ + + +{#if chatList} +
+ {#if chatList.length === 0} +
+ {$i18n.t('No chats found')} +
+ {/if} + + {#each chatList as chat, idx (chat.id)} + {#if (idx === 0 || (idx > 0 && chat.time_range !== chatList[idx - 1].time_range)) && chat?.time_range} +
+ {$i18n.t(chat.time_range)} + +
+ {/if} + + (show = false)} + > +
+ {chat?.title} +
+ + +
+ {/each} + + +
+{/if} diff --git a/src/lib/components/chat/Placeholder/FolderKnowledge.svelte b/src/lib/components/chat/Placeholder/FolderKnowledge.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/lib/components/chat/Placeholder/FolderPlaceholder.svelte b/src/lib/components/chat/Placeholder/FolderPlaceholder.svelte new file mode 100644 index 0000000000..057dd7018d --- /dev/null +++ b/src/lib/components/chat/Placeholder/FolderPlaceholder.svelte @@ -0,0 +1,51 @@ + + +
+ + +
+ {#if selectedTab === 'knowledge'} + + {:else if selectedTab === 'chats'} + + {/if} +
+
diff --git a/src/lib/components/chat/Placeholder/FolderTitle.svelte b/src/lib/components/chat/Placeholder/FolderTitle.svelte new file mode 100644 index 0000000000..9b91a89c6d --- /dev/null +++ b/src/lib/components/chat/Placeholder/FolderTitle.svelte @@ -0,0 +1,147 @@ + + +{#if folder} + + + { + deleteHandler(); + }} + > +
+ {@html DOMPurify.sanitize( + $i18n.t( + 'This will delete {{NAME}} and all its contents.', + { + NAME: folder.name + } + ) + )} +
+
+ +
+
+
+ +
+ +
+ {folder.name} +
+
+ +
+ { + showFolderModal = true; + }} + onDelete={() => { + showDeleteConfirm = true; + }} + onExport={() => { + exportHandler(); + }} + > + + +
+
+{/if} diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index b053de8ecf..168f0482e3 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -363,9 +363,7 @@ }); chats.subscribe((value) => { - if ($selectedFolder) { - initFolders(); - } + initFolders(); }); await initChannels(); diff --git a/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte b/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte index 00338e01ee..576d16c9d3 100644 --- a/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte +++ b/src/lib/components/layout/Sidebar/Folders/FolderMenu.svelte @@ -12,6 +12,7 @@ import Tooltip from '$lib/components/common/Tooltip.svelte'; import Download from '$lib/components/icons/Download.svelte'; + export let align: 'start' | 'end' = 'start'; export let onEdit = () => {}; export let onExport = () => {}; export let onDelete = () => {}; @@ -36,7 +37,7 @@ class="w-full max-w-[170px] rounded-lg px-1 py-1.5 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg" sideOffset={-2} side="bottom" - align="start" + {align} transition={flyAndScale} > {}; + export let edit = false; + export let folder = null; let name = ''; @@ -53,7 +55,11 @@
- {$i18n.t('Edit Folder')} + {#if edit} + {$i18n.t('Edit Folder')} + {:else} + {$i18n.t('Create Folder')} + {/if}