diff --git a/ui/client-app/src/components/FileSystemNavigator.js b/ui/client-app/src/components/FileSystemNavigator.js index c14f892..fcefd6b 100644 --- a/ui/client-app/src/components/FileSystemNavigator.js +++ b/ui/client-app/src/components/FileSystemNavigator.js @@ -12,6 +12,8 @@ const [error, setError] = useState(null); const [selectedFile, setSelectedFile] = useState(null); // { path, content } const [isEditing, setIsEditing] = useState(false); + const [newItemModal, setNewItemModal] = useState(null); // { parentPath, isDir } + const [operationLoading, setOperationLoading] = useState(false); const fetchLevel = useCallback(async (path) => { const data = await nodeFsList(nodeId, path); @@ -50,45 +52,61 @@ } }; - const handleCreate = async (parentPath, isDir) => { - const name = prompt(`Enter ${isDir ? 'folder' : 'file'} name:`); - if (!name) return; + const handleCreateFinal = async (name) => { + if (!name || !newItemModal) return; + const { parentPath, isDir } = newItemModal; const fullPath = parentPath === "." ? name : `${parentPath}/${name}`; + setOperationLoading(true); + setError(null); try { await nodeFsTouch(nodeId, fullPath, "", isDir); + setNewItemModal(null); loadRoot(); // Refresh } catch (err) { - alert(`Failed to create: ${err.message}`); + setError(`Failed to create: ${err.message}`); + } finally { + setOperationLoading(false); } }; const handleDelete = async (path) => { if (!window.confirm(`Delete ${path}?`)) return; + setOperationLoading(true); + setError(null); try { await nodeFsRm(nodeId, path); loadRoot(); // Refresh } catch (err) { - alert(`Failed to delete: ${err.message}`); + setError(`Failed to delete: ${err.message}`); + } finally { + setOperationLoading(false); } }; const handleView = async (path) => { + setOperationLoading(true); + setError(null); try { const res = await nodeFsCat(nodeId, path); setSelectedFile({ path, content: res.content }); setIsEditing(false); } catch (err) { - alert(`Failed to read file: ${err.message}`); + setError(`Failed to read file: ${err.message}`); + } finally { + setOperationLoading(false); } }; const handleSave = async () => { + setOperationLoading(true); + setError(null); try { await nodeFsTouch(nodeId, selectedFile.path, selectedFile.content, false); - alert("File saved!"); setSelectedFile(null); } catch (err) { - alert(`Failed to save: ${err.message}`); + setError(`Failed to save: ${err.message}`); + } finally { + setOperationLoading(false); } }; @@ -127,7 +145,7 @@