konowebcodecs/apps/website/src/components/Playground/Workspace/FileSystemManager.tsx
小さい猫 2c2e2e2ad9
playground: add a rename button (#669)
Signed-off-by: Ookiineko <chiisaineko@protonmail.com>
2024-03-06 23:10:53 +08:00

246 lines
8.3 KiB
TypeScript

import React, { useState, ChangeEvent } from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import Modal from "@mui/material/Modal";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import Tooltip from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import FolderIcon from "@mui/icons-material/Folder";
import RefreshIcon from "@mui/icons-material/Refresh";
import UploadFileIcon from "@mui/icons-material/UploadFile";
import UploadIcon from "@mui/icons-material/Upload";
import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile";
import CreateNewFolderIcon from "@mui/icons-material/CreateNewFolder";
import MoreButton from "./MoreButton";
import { Node } from "./types";
interface FileSystemManagerProps {
path: string;
nodes: Node[];
oldName: string;
newName: string;
renameOpen: boolean;
onNewNameChange: () => (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
onCloseRenameModal: () => () => Promise<void>;
onFileUpload: (
isText: boolean
) => (event: ChangeEvent<HTMLInputElement>) => Promise<void>;
onDirClick: (name: string) => () => Promise<void>;
onFileClick: (name: string) => (option: string) => Promise<void>;
onDirCreate: (name: string) => () => Promise<void>;
onRename: (old_name: string, new_name: string) => () => Promise<void>;
onRefresh: () => Promise<void>;
onLoadSamples: () => Promise<void>;
}
const modalStyle = {
position: "absolute" as "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
p: 4,
};
export const options = [
{ text: "Rename", key: "rename" },
{ text: "Download", key: "download" },
{ text: "Download as Text File", key: "download-text" },
{ text: "Delete", key: "delete" },
];
export default function FileSystemManager({
path = "/",
nodes = [],
oldName = "",
newName = "",
renameOpen = false,
onNewNameChange = () => () => Promise.resolve(),
onCloseRenameModal = () => () => Promise.resolve(),
onFileUpload = () => () => Promise.resolve(),
onFileClick = () => () => Promise.resolve(),
onDirClick = () => () => Promise.resolve(),
onDirCreate = () => () => Promise.resolve(),
onRename = () => () => Promise.resolve(),
onRefresh = () => Promise.resolve(),
onLoadSamples = () => Promise.resolve(),
}: FileSystemManagerProps) {
const [newFolderOpen, setNewFolderOpen] = useState(false);
const [dirName, setDirName] = useState("");
const handleNewFolderModalOpen = () => setNewFolderOpen(true);
const handleNewFolderModalClose = () => setNewFolderOpen(false);
return (
<>
<Paper variant="outlined" style={{ padding: 8, height: "100%" }}>
<Stack justifyContent="space-between" style={{ height: "100%" }}>
<>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Typography>File System:</Typography>
<Box>
<Tooltip title="Upload a media file">
<IconButton
aria-label="upload-media-file"
component="label"
size="small"
>
<input
hidden
multiple
type="file"
onChange={onFileUpload(false)}
/>
<UploadFileIcon fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Upload a text file">
<IconButton
onClick={() => {}}
aria-label="upload-text"
component="label"
size="small"
>
<input
hidden
multiple
type="file"
onChange={onFileUpload(true)}
/>
<UploadIcon fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Create a new folder">
<IconButton
onClick={() => {
setDirName("");
handleNewFolderModalOpen();
}}
aria-label="create-a-new-folder"
size="small"
>
<CreateNewFolderIcon />
</IconButton>
</Tooltip>
<Tooltip title="Refresh directory">
<IconButton
onClick={onRefresh}
aria-label="fresh"
size="small"
>
<RefreshIcon fontSize="small" />
</IconButton>
</Tooltip>
</Box>
</Stack>
<Typography>{`Path: ${path}`}</Typography>
<List style={{ height: 480, overflowX: "auto" }}>
{nodes.map(({ name, isDir }, index) =>
isDir ? (
<ListItemButton key={index} onClick={onDirClick(name)}>
<ListItemIcon>
<FolderIcon />
</ListItemIcon>
<ListItemText primary={name} />
</ListItemButton>
) : (
<ListItem
key={index}
secondaryAction={
<MoreButton
options={options}
onItemClick={onFileClick(name)}
/>
}
>
<ListItemIcon>
<InsertDriveFileIcon />
</ListItemIcon>
<ListItemText primary={name} />
</ListItem>
)
)}
</List>
</>
<Button onClick={onLoadSamples}>Load Sample Files</Button>
</Stack>
</Paper>
<Modal
open={newFolderOpen}
onClose={handleNewFolderModalClose}
aria-labelledby="new-folder-name"
aria-describedby="new-folder-name-description"
>
<Box sx={modalStyle}>
<Stack spacing={4}>
<Typography id="modal-modal-title" variant="h6" component="h2">
Folder Name:
</Typography>
<TextField
id="outlined-basic"
label="my-folder"
variant="outlined"
value={dirName}
onChange={(event) => setDirName(event.target.value)}
/>
<Stack direction="row" justifyContent="flex-end">
<Button onClick={handleNewFolderModalClose}>Cancel</Button>
<Button
variant="contained"
onClick={() => {
onDirCreate(dirName);
handleNewFolderModalClose();
}}
>
Create
</Button>
</Stack>
</Stack>
</Box>
</Modal>
<Modal
open={renameOpen}
onClose={onCloseRenameModal()}
aria-labelledby="new-name"
aria-describedby="new-name-description"
>
<Box sx={modalStyle}>
<Stack spacing={4}>
<Typography id="modal-modal-title" variant="h6" component="h2">
New Name:
</Typography>
<TextField
id="outlined-basic"
label="my-file"
variant="outlined"
value={newName}
onChange={onNewNameChange()}
/>
<Stack direction="row" justifyContent="flex-end">
<Button onClick={onCloseRenameModal()}>Cancel</Button>
<Button
variant="contained"
onClick={onRename(oldName, newName)}
>
Rename
</Button>
</Stack>
</Stack>
</Box>
</Modal>
</>
);
}