diff --git a/src/lib/apis/terminal/index.ts b/src/lib/apis/terminal/index.ts index 5815bcd3c..74c936af7 100644 --- a/src/lib/apis/terminal/index.ts +++ b/src/lib/apis/terminal/index.ts @@ -193,3 +193,29 @@ export const setCwd = async ( }); return res; }; + +export const moveEntry = async ( + baseUrl: string, + apiKey: string, + source: string, + destination: string +): Promise<{ source: string; destination: string } | null> => { + const url = `${baseUrl.replace(/\/$/, '')}/files/move`; + const res = await fetch(url, { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ source, destination }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.error('open-terminal moveEntry error:', err); + return null; + }); + return res; +}; diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 84ad18a71..2f70afc17 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -21,6 +21,7 @@ uploadToTerminal, createDirectory, deleteEntry, + moveEntry, setCwd, type FileEntry } from '$lib/apis/terminal'; @@ -323,6 +324,23 @@ showDeleteConfirm = true; }; + // ── Move (drag-and-drop) ──────────────────────────────────────────── + const handleMove = async (source: string, destFolder: string) => { + const terminal = selectedTerminal; + if (!terminal) return; + + const fileName = source.split('/').pop() ?? ''; + const destination = `${destFolder}${fileName}`; + + if (source === destination) return; + + const result = await moveEntry(terminal.url, terminal.key, source, destination); + toast[result ? 'success' : 'error']( + $i18n.t(result ? 'Moved {{name}}' : 'Failed to move {{name}}', { name: fileName }) + ); + await loadDir(currentPath); + }; + // ── Lifecycle ──────────────────────────────────────────────────────── onMount(async () => { const terminal = getTerminal(); @@ -717,6 +735,7 @@ onOpen={openEntry} onDownload={downloadFile} onDelete={requestDelete} + onMove={handleMove} /> {/each} diff --git a/src/lib/components/chat/FileNav/FileEntryRow.svelte b/src/lib/components/chat/FileNav/FileEntryRow.svelte index c5d778555..f97aa7270 100644 --- a/src/lib/components/chat/FileNav/FileEntryRow.svelte +++ b/src/lib/components/chat/FileNav/FileEntryRow.svelte @@ -18,24 +18,66 @@ export let onOpen: (entry: FileEntry) => void = () => {}; export let onDownload: (path: string) => void = () => {}; export let onDelete: (path: string, name: string) => void = () => {}; + export let onMove: (source: string, destFolder: string) => void = () => {}; + + let dragOverFolder = false;