File browser: folder upload + copy/move (0.13.0)
Folder upload: the Files page gained an "Upload folder" picker
(webkitdirectory); each file is sent with its webkitRelativePath and the
backend recreates the directory tree. upload_target now accepts an optional
rel_path, creating intermediate dirs (mkdir -p) inside the sandbox with each
component validated against traversal.
Copy/move: new file_service.copy/move + POST /api/files/{copy,move}
(admin, audit-logged). The UI adds per-row copy/cut actions, a clipboard bar
to paste into the current directory, and an overwrite prompt on conflict.
Both refuse to move/copy a folder into itself or its own subtree and are
sandbox-checked on source and destination.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e3313fb4ac
commit
25bba1cf2c
@@ -44,15 +44,26 @@ export const filesApi = {
|
||||
remove: (path: string, recursive = false) =>
|
||||
api.delete("/api/files", { params: { path, recursive } }).then((r) => r.data),
|
||||
|
||||
copy: (src: string, destDir: string, overwrite = false) =>
|
||||
api
|
||||
.post<{ path: string }>("/api/files/copy", { src, dest_dir: destDir, overwrite })
|
||||
.then((r) => r.data),
|
||||
|
||||
move: (src: string, destDir: string, overwrite = false) =>
|
||||
api
|
||||
.post<{ path: string }>("/api/files/move", { src, dest_dir: destDir, overwrite })
|
||||
.then((r) => r.data),
|
||||
|
||||
download: async (path: string, filename: string) => {
|
||||
const res = await api.get("/api/files/download", { params: { path }, responseType: "blob" });
|
||||
triggerDownload(res.data as Blob, filename);
|
||||
},
|
||||
|
||||
upload: async (path: string, file: File, overwrite = false) => {
|
||||
upload: async (path: string, file: File, overwrite = false, relPath = "") => {
|
||||
const form = new FormData();
|
||||
form.append("path", path);
|
||||
form.append("overwrite", String(overwrite));
|
||||
if (relPath) form.append("rel_path", relPath);
|
||||
form.append("file", file);
|
||||
const res = await api.post<{ ok: boolean; name: string }>("/api/files/upload", form);
|
||||
return res.data;
|
||||
|
||||
Reference in New Issue
Block a user