import { useState, useEffect, useMemo, useRef } from "react"; import Box from "@mui/material/Box"; import { FileBrowser, FileContextMenu, FileList, FileNavbar, FileToolbar, setChonkyDefaults, ChonkyActions, } from "chonky"; import { ChonkyIconFA } from "chonky-icon-fontawesome"; import { getServerFiles, createServerFolder, deleteServerItem, getServerItem, } from "@mcl/queries"; import "@mcl/css/header.css"; export default function MineclusterFiles(props) { // Chonky configuration setChonkyDefaults({ iconComponent: ChonkyIconFA }); const fileActions = useMemo( () => [ ChonkyActions.CreateFolder, ChonkyActions.UploadFiles, ChonkyActions.DownloadFiles, ChonkyActions.CopyFiles, ChonkyActions.DeleteFiles, ], [], ); const { server: serverName } = props; const inputRef = useRef(null); const [dirStack, setDirStack] = useState(["."]); const [files, setFiles] = useState([]); const updateFiles = () => getServerFiles(serverName, dirStack.join("/")).then((f) => setFiles(f ?? []), ); useEffect(() => { updateFiles(); }, [dirStack]); const getFolderChain = () => { if (dirStack.length === 1) return [{ id: "home", name: "/", isDir: true }]; return dirStack.map((d, i) => ({ id: `${d}-${i}`, name: d, isDir: true })); }; const openParentFolder = () => setDirStack(dirStack.slice(0, -1)); function openFolder(payload) { const { targetFile: file } = payload; if (!file || !file.isDir) return; setDirStack([...dirStack, file.name]); } function createFolder() { const name = prompt("What is the name of the new folder?"); const path = [...dirStack, name].join("/"); createServerFolder(serverName, path).then(updateFiles); } function deleteItems(files) { Promise.all( files.map((f) => deleteServerItem(serverName, [...dirStack, f.name].join("/"), f.isDir), ), ) .catch((e) => console.error("Error deleting some files!", e)) .then(updateFiles); } function uploadFileSelection(e) { if (!e.target.files || e.target.files.length === 0) return; const { files } = e.target; Promise.all([...files].map((f) => uploadFile(f))) .catch((e) => console.log("Error uploading a file", e)) .then(updateFiles); } async function uploadFile(file) { const formData = new FormData(); formData.append("file", file); formData.append("name", serverName); formData.append("path", [...dirStack, name].join("/")); await fetch("/api/files/upload", { method: "POST", body: formData, }); } async function downloadFiles(files) { Promise.all( files.map((f) => getServerItem(serverName, f.name, [...dirStack, f.name].join("/")), ), ) .then(() => console.log("Done")) .catch((e) => console.error("Error Downloading files!", e)); } function fileClick(chonkyEvent) { const { id: clickEvent, payload } = chonkyEvent; console.log(chonkyEvent); if (clickEvent === "open_parent_folder") return openParentFolder(); if (clickEvent === "create_folder") return createFolder(); if (clickEvent === "upload_files") return inputRef.current.click(); if (clickEvent === "download_files") return downloadFiles(chonkyEvent.state.selectedFilesForAction); if (clickEvent === "delete_files") return deleteItems(chonkyEvent.state.selectedFilesForAction); if (clickEvent !== "open_files") return console.log(clickEvent); openFolder(payload); } return ( ); }