mirror of
https://github.com/open-webui/open-webui
synced 2025-04-22 15:33:21 +00:00
enh: drag and drop folders
This commit is contained in:
parent
d5bf32f240
commit
36a541d6b0
@ -137,7 +137,7 @@ async def update_folder_name_by_id(
|
|||||||
|
|
||||||
|
|
||||||
class FolderParentIdForm(BaseModel):
|
class FolderParentIdForm(BaseModel):
|
||||||
parent_id: str
|
parent_id: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{id}/update/parent")
|
@router.post("/{id}/update/parent")
|
||||||
|
@ -164,10 +164,43 @@ export const updateFolderIsExpandedById = async (
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateFolderParentIdById = async (token: string, id: string, parentId?: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/update/parent`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
parent_id: parentId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
type FolderItems = {
|
type FolderItems = {
|
||||||
chat_ids: string[];
|
chat_ids: string[];
|
||||||
file_ids: string[];
|
file_ids: string[];
|
||||||
folder_ids: string[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateFolderItemsById = async (token: string, id: string, items: FolderItems) => {
|
export const updateFolderItemsById = async (token: string, id: string, items: FolderItems) => {
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
import Folder from '../common/Folder.svelte';
|
import Folder from '../common/Folder.svelte';
|
||||||
import Plus from '../icons/Plus.svelte';
|
import Plus from '../icons/Plus.svelte';
|
||||||
import Tooltip from '../common/Tooltip.svelte';
|
import Tooltip from '../common/Tooltip.svelte';
|
||||||
import { createNewFolder, getFolders } from '$lib/apis/folders';
|
import { createNewFolder, getFolders, updateFolderParentIdById } from '$lib/apis/folders';
|
||||||
import Folders from './Sidebar/Folders.svelte';
|
import Folders from './Sidebar/Folders.svelte';
|
||||||
|
|
||||||
const BREAKPOINT = 768;
|
const BREAKPOINT = 768;
|
||||||
@ -656,7 +656,12 @@
|
|||||||
|
|
||||||
<div class=" flex-1 flex flex-col overflow-y-auto scrollbar-hidden">
|
<div class=" flex-1 flex flex-col overflow-y-auto scrollbar-hidden">
|
||||||
{#if !search && folders}
|
{#if !search && folders}
|
||||||
<Folders {folders} />
|
<Folders
|
||||||
|
{folders}
|
||||||
|
on:update={async (e) => {
|
||||||
|
await initFolders();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Folder
|
<Folder
|
||||||
@ -677,6 +682,21 @@
|
|||||||
initChatList();
|
initChatList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (type === 'folder') {
|
||||||
|
if (folders[id].parent_id === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await updateFolderParentIdById(localStorage.token, id, null).catch(
|
||||||
|
(error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
await initFolders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
import RecursiveFolder from './RecursiveFolder.svelte';
|
import RecursiveFolder from './RecursiveFolder.svelte';
|
||||||
export let folders = {};
|
export let folders = {};
|
||||||
|
|
||||||
@ -15,5 +18,12 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each folderList as folderId (folderId)}
|
{#each folderList as folderId (folderId)}
|
||||||
<RecursiveFolder className="px-2" {folders} {folderId} />
|
<RecursiveFolder
|
||||||
|
className="px-2"
|
||||||
|
{folders}
|
||||||
|
{folderId}
|
||||||
|
on:update={(e) => {
|
||||||
|
dispatch('update', e.detail);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -11,7 +11,11 @@
|
|||||||
|
|
||||||
import FolderOpen from '$lib/components/icons/FolderOpen.svelte';
|
import FolderOpen from '$lib/components/icons/FolderOpen.svelte';
|
||||||
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
|
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
|
||||||
import { updateFolderIsExpandedById, updateFolderNameById } from '$lib/apis/folders';
|
import {
|
||||||
|
updateFolderIsExpandedById,
|
||||||
|
updateFolderNameById,
|
||||||
|
updateFolderParentIdById
|
||||||
|
} from '$lib/apis/folders';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
|
|
||||||
export let open = true;
|
export let open = true;
|
||||||
@ -41,7 +45,7 @@
|
|||||||
draggedOver = true;
|
draggedOver = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDrop = (e) => {
|
const onDrop = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (dragged || parentDragged) {
|
if (dragged || parentDragged) {
|
||||||
@ -56,7 +60,28 @@
|
|||||||
const dataTransfer = e.dataTransfer.getData('text/plain');
|
const dataTransfer = e.dataTransfer.getData('text/plain');
|
||||||
const data = JSON.parse(dataTransfer);
|
const data = JSON.parse(dataTransfer);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
dispatch('drop', data);
|
|
||||||
|
const { type, id } = data;
|
||||||
|
|
||||||
|
if (type === 'folder') {
|
||||||
|
if (id === folderId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Move the folder
|
||||||
|
const res = await updateFolderParentIdById(localStorage.token, id, folderId).catch(
|
||||||
|
(error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
dispatch('update');
|
||||||
|
}
|
||||||
|
} else if (type === 'chat') {
|
||||||
|
// Move the chat
|
||||||
|
console.log('Move the chat');
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -285,7 +310,14 @@
|
|||||||
>
|
>
|
||||||
{#if folders[folderId]?.childrenIds}
|
{#if folders[folderId]?.childrenIds}
|
||||||
{#each folders[folderId]?.childrenIds as childId (`${folderId}-${childId}`)}
|
{#each folders[folderId]?.childrenIds as childId (`${folderId}-${childId}`)}
|
||||||
<svelte:self {folders} folderId={childId} parentDragged={dragged} />
|
<svelte:self
|
||||||
|
{folders}
|
||||||
|
folderId={childId}
|
||||||
|
parentDragged={dragged}
|
||||||
|
on:update={(e) => {
|
||||||
|
dispatch('update', e.detail);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user