frontend/app/admin/AdminContainer.tsx (199 lines of code) (raw):

import React from "react"; import clsx from 'clsx'; import {RouteComponentProps} from "react-router"; import BreadcrumbComponent from "../common/BreadcrumbComponent"; import { AppBar, Divider, Drawer, Icon, IconButton, Link, List, ListItem, ListItemIcon, ListItemText, makeStyles, Toolbar, Typography, useTheme } from "@material-ui/core"; import {MenuIcon} from "@material-ui/data-grid"; import { ArrowRightAlt, ChevronLeft, ChevronRight, DeleteForever, DirectionsRun, Healing, ImportExport, PeopleAlt, Storage, TrackChanges, Work, WorkSharp } from "@material-ui/icons"; import {Link as RouterLink} from "react-router-dom"; import ErrorCatcher from "./ErrorCatcher"; /* mostly taken from the "Persistent Drawer" example at https://material-ui.com/components/drawers/ */ const drawerWidth = 220; const useStyles = makeStyles((theme)=>({ appBar: { transition: theme.transitions.create(['margin', 'width'], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), }, appBarShift: { width: `calc(100% - ${drawerWidth}px)`, transition: theme.transitions.create(['margin', 'width'], { easing: theme.transitions.easing.easeOut, duration: theme.transitions.duration.enteringScreen, }), marginRight: drawerWidth, }, title: { flexGrow: 1, }, hide: { display: 'none', }, drawer: { width: drawerWidth, flexShrink: 0, }, linkText: { textAlign: "right", color: "#AAAAAA" }, drawerPaper: { width: drawerWidth, top: "auto", borderTop: "1px solid rgba(255,255,255,0.12)", borderBottom: "1px solid rgba(255,255,255,0.12)", marginTop: "1em", height: "auto" }, drawerHeader: { display: 'flex', alignItems: 'center', padding: theme.spacing(0, 1), // necessary for content to be below app bar ...theme.mixins.toolbar, justifyContent: 'flex-start', }, content: { flexGrow: 1, padding: theme.spacing(3), transition: theme.transitions.create('margin', { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), marginRight: 0, marginLeft: 0, }, contentShift: { transition: theme.transitions.create('margin', { easing: theme.transitions.easing.easeOut, duration: theme.transitions.duration.enteringScreen, }), marginRight: 0, marginLeft: drawerWidth }, menuButton: { }, right: { textAlign: "right" } })); const menuItems = [ { uri: "/admin/scanTargets", icon: <TrackChanges/>, name: "Scan Targets" }, { uri: "/admin/jobs", icon: <Work/>, name: "Jobs" }, { uri: "/admin/users", icon: <PeopleAlt/>, name: "Users", }, { uri: "/admin/proxyFramework", icon: <Storage/>, name: "Proxying Framework" }, { uri: "/admin/proxyHealth", icon: <Healing/>, name: "Proxying Health Indicator" }, { uri: "/admin/deleteditems", icon: <DeleteForever/>, name: "Deleted items", }, { uri: "/admin/quickrestore", icon: <DirectionsRun/>, name: "Failsafe media restore" },{ uri: "/admin/pathcache", icon: <ArrowRightAlt/>, name: "Paths caching" }, { uri: "/admin/manualimport", icon: <ImportExport/>, name: "Manual path import" } ] /** * AdminContainer is a container component that renders a side-drawer with the Admin menu around any child * component that is passed into it * @param props * @constructor */ const AdminContainer:React.FC<RouteComponentProps> = (props) => { const classes = useStyles(); const theme = useTheme(); const [open, setOpen] = React.useState(true); const handleDrawerOpen = ()=>setOpen(true); const handleDrawerClose = ()=>setOpen(false); return ( <> <IconButton color="inherit" aria-label="open drawer" onClick={handleDrawerOpen} edge="start" className={clsx(classes.menuButton, open && classes.hide)} > <MenuIcon/> </IconButton> { props.location.pathname.endsWith("/admin") ? null : <BreadcrumbComponent path={props.location.pathname}/> } <Drawer variant="persistent" anchor="left" open={open} classes={{ paper: classes.drawerPaper }}> <div className={classes.drawerHeader}> <IconButton onClick={handleDrawerClose}> {theme.direction === 'ltr' ? <ChevronLeft/> : <ChevronRight/>} </IconButton> <Typography variant="h6" className={classes.right}>Admin</Typography> </div> <Divider/> <List> { menuItems.map((itm, idx)=>( <ListItem button key={idx}> {itm.icon ? <ListItemIcon>{itm.icon}</ListItemIcon> : null} <ListItemText className={classes.linkText}> <Link component={RouterLink} to={itm.uri}>{itm.name}</Link> </ListItemText> </ListItem> )) } <Divider/> <ListItem button key="abt"> <ListItemText className={classes.linkText}> <Link component={RouterLink} to="/admin/about" >About</Link> </ListItemText> </ListItem> </List> </Drawer> <main className={clsx(classes.content, { [classes.contentShift]: open })} > <ErrorCatcher>{props.children}</ErrorCatcher> </main> </> ) } export default AdminContainer;