import React, { useCallback, useEffect, useState } from "react"; import { makeStyles } from "@material-ui/core"; import { useDispatch, useSelector } from "react-redux"; import Drawer from "@material-ui/core/Drawer"; import Toolbar from "@material-ui/core/Toolbar"; import { Clear, Folder } from "@material-ui/icons"; import Divider from "@material-ui/core/Divider"; import { setSideBar } from "../../../redux/explorer/action"; import TypeIcon from "../TypeIcon"; import Typography from "@material-ui/core/Typography"; import IconButton from "@material-ui/core/IconButton"; import Grid from "@material-ui/core/Grid"; import API from "../../../middleware/Api"; import { filename, sizeToString } from "../../../utils"; import Link from "@material-ui/core/Link"; import Tooltip from "@material-ui/core/Tooltip"; import TimeAgo from "timeago-react"; import ListLoading from "../../Placeholder/ListLoading"; import Hidden from "@material-ui/core/Hidden"; import Dialog from "@material-ui/core/Dialog"; import Slide from "@material-ui/core/Slide"; import AppBar from "@material-ui/core/AppBar"; import { formatLocalTime } from "../../../utils/datetime"; import { navigateTo, toggleSnackbar } from "../../../redux/explorer"; import { Trans, useTranslation } from "react-i18next"; const drawerWidth = 350; const useStyles = makeStyles((theme) => ({ drawer: { width: drawerWidth, flexShrink: 0, }, drawerPaper: { width: drawerWidth, boxShadow: "0px 8px 10px -5px rgb(0 0 0 / 20%), 0px 16px 24px 2px rgb(0 0 0 / 14%), 0px 6px 30px 5px rgb(0 0 0 / 12%)", }, drawerContainer: { overflow: "auto", }, header: { display: "flex", padding: theme.spacing(3), placeContent: "space-between", }, fileIcon: { width: 33, height: 33 }, fileIconSVG: { fontSize: 20 }, folderIcon: { color: theme.palette.text.secondary, width: 33, height: 33, }, fileName: { marginLeft: theme.spacing(2), marginRight: theme.spacing(2), wordBreak: "break-all", flexGrow: 2, }, closeIcon: { placeSelf: "flex-start", marginTop: 2, }, propsContainer: { padding: theme.spacing(3), }, propsLabel: { color: theme.palette.text.secondary, padding: theme.spacing(1), }, propsTime: { color: theme.palette.text.disabled, padding: theme.spacing(1), }, propsValue: { padding: theme.spacing(1), wordBreak: "break-all", }, appBar: { position: "relative", }, title: { marginLeft: theme.spacing(2), flex: 1, }, })); const Transition = React.forwardRef(function Transition(props, ref) { return ; }); export default function SideDrawer() { const { t } = useTranslation(); const dispatch = useDispatch(); const sideBarOpen = useSelector((state) => state.explorer.sideBarOpen); const selected = useSelector((state) => state.explorer.selected); const SetSideBar = useCallback((open) => dispatch(setSideBar(open)), [ dispatch, ]); const ToggleSnackbar = useCallback( (vertical, horizontal, msg, color) => dispatch(toggleSnackbar(vertical, horizontal, msg, color)), [dispatch] ); const NavigateTo = useCallback((k) => dispatch(navigateTo(k)), [dispatch]); const search = useSelector((state) => state.explorer.search); const [target, setTarget] = useState(null); const [details, setDetails] = useState(null); const loadProps = (object) => { API.get( "/object/property/" + object.id + "?trace_root=" + (search ? "true" : "false") + "&is_folder=" + (object.type === "dir").toString() ) .then((response) => { setDetails(response.data); }) .catch((error) => { ToggleSnackbar("top", "right", error.message, "error"); }); }; useEffect(() => { setDetails(null); if (sideBarOpen) { if (selected.length !== 1) { SetSideBar(false); } else { setTarget(selected[0]); loadProps(selected[0]); } } }, [selected, sideBarOpen]); const classes = useStyles(); const propsItem = [ { label: t("fileManager.size"), value: (d, target) => sizeToString(d.size) + t("fileManager.bytes", { bytes: d.size.toLocaleString() }), show: (d) => true, }, { label: t("fileManager.storagePolicy"), value: (d, target) => d.policy, show: (d) => d.type === "file", }, { label: t("fileManager.storagePolicy"), value: (d, target) => d.policy === "" ? t("fileManager.inheritedFromParent") : d.policy, show: (d) => d.type === "dir", }, { label: t("fileManager.childFolders"), value: (d, target) => t("fileManager.childCount", { num: d.child_folder_num.toLocaleString(), }), show: (d) => d.type === "dir", }, { label: t("fileManager.childFiles"), value: (d, target) => t("fileManager.childCount", { num: d.child_file_num.toLocaleString(), }), show: (d) => d.type === "dir", }, { label: t("fileManager.parentFolder"), // eslint-disable-next-line react/display-name value: (d, target) => { const path = d.path === "" ? target.path : d.path; const name = filename(path); return ( NavigateTo(path)} > {name === "" ? t("fileManager.rootFolder") : name} ); }, show: (d) => true, }, { label: t("fileManager.modifiedAt"), value: (d, target) => formatLocalTime(d.updated_at), show: (d) => true, }, { label: t("fileManager.createdAt"), value: (d) => formatLocalTime(d.created_at), show: (d) => true, }, ]; const content = ( {!details && } {details && ( <> {propsItem.map((item) => { if (item.show(target)) { return ( <> {item.label} {item.value(details, target)} > ); } })} {target.type === "dir" && ( , , , ]} /> )} > )} ); return ( <> {target && ( <> SetSideBar(false)} aria-label="close" > {target.name} {content} > )} {target && ( <> {target.type === "dir" && ( )} {target.type !== "dir" && ( )} {target.name} SetSideBar(false)} className={classes.closeIcon} aria-label="close" size={"small"} > > )} {content} > ); }