Make Menu Collapsable (#1025)
This commit is contained in:
@@ -15,21 +15,15 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { SvgIcon } from "@material-ui/core";
|
||||||
|
|
||||||
interface IConsoleLogo {
|
interface IConsoleLogo {
|
||||||
width?: number;
|
width?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConsoleLogo = ({ width = 120 }: IConsoleLogo) => {
|
const ConsoleLogo = () => {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 121.755 29.822">
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={width}
|
|
||||||
viewBox="0 0 121.755 29.822"
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<style>{".prefix__a{fill:#fff}"}</style>
|
|
||||||
</defs>
|
|
||||||
<path
|
<path
|
||||||
className="prefix__a"
|
className="prefix__a"
|
||||||
d="M15.647 15.935l-1.772 1.194a6.088 6.088 0 00-5.135-2.652 6.348 6.348 0 00-6.522 6.654 6.348 6.348 0 006.522 6.654 6.031 6.031 0 005.124-2.64l1.735 1.266a8.126 8.126 0 01-6.859 3.411A8.422 8.422 0 010 21.131a8.422 8.422 0 018.74-8.691 7.963 7.963 0 016.907 3.495zM35.641 21.131a8.422 8.422 0 01-8.74 8.691 8.422 8.422 0 01-8.739-8.691 8.421 8.421 0 018.739-8.691 8.422 8.422 0 018.74 8.691zm-15.261 0a6.347 6.347 0 006.521 6.654 6.347 6.347 0 006.521-6.654 6.347 6.347 0 00-6.521-6.654 6.347 6.347 0 00-6.521 6.654zM53.729 29.581h-1.917l-10.2-13.26-.012 13.248h-2.122V12.681h1.917l10.21 13.26V12.693h2.122zM69.551 16.02a8.835 8.835 0 00-5-1.555c-2.471 0-4.231 1.109-4.231 2.929 0 1.531 1.29 2.315 3.821 2.628l1.484.181c2.856.35 5.3 1.507 5.3 4.484 0 3.364-3.05 5.123-6.7 5.123a10.935 10.935 0 01-6.654-2.194l1.157-1.687a9.018 9.018 0 005.5 1.868c2.519 0 4.5-1.025 4.5-2.929 0-1.567-1.41-2.314-4.038-2.64l-1.567-.193c-2.784-.337-5-1.627-5-4.508 0-3.255 2.893-5.075 6.449-5.075a10.336 10.336 0 016.076 1.844zM91.268 21.131a8.422 8.422 0 01-8.74 8.691 8.422 8.422 0 01-8.739-8.691 8.421 8.421 0 018.739-8.691 8.422 8.422 0 018.74 8.691zm-15.261 0a6.348 6.348 0 006.521 6.654 6.347 6.347 0 006.521-6.654 6.347 6.347 0 00-6.521-6.654 6.348 6.348 0 00-6.521 6.654zM106.897 29.569h-11.79V12.693h2.122v14.863h9.668zM121.76 29.569h-11.982V12.693h11.862v1.988h-9.74v5.389h9.427v2H111.9v5.509h9.86zM14.9.167h2.576v7.547H14.9zM11.801.238l-5.23 3.194a.229.229 0 01-.242 0L1.099.238a.726.726 0 00-.374-.1H.719a.717.717 0 00-.717.717v6.864h2.574V4.462a.258.258 0 01.392-.22l2.931 1.793a.919.919 0 00.944.009L9.935 4.23a.258.258 0 01.388.222v3.267h2.575V.855a.717.717 0 00-.717-.717h-.006a.723.723 0 00-.374.1zM30.348.165h-2.613v3.463a.258.258 0 01-.379.228L20.585.249a.723.723 0 00-.337-.084.717.717 0 00-.717.717v6.832h2.592V4.306a.258.258 0 01.379-.227l6.8 3.606a.714.714 0 00.336.083.716.716 0 00.717-.717V.165zM32.439 7.712V.165h1.2v7.547zM40.536 7.878c-3.189 0-5.451-1.513-5.451-3.939S37.361 0 40.536 0s5.466 1.513 5.466 3.939-2.236 3.939-5.466 3.939zm0-6.87c-2.371 0-4.2 1.036-4.2 2.931s1.826 2.93 4.2 2.93 4.212-1.022 4.212-2.93-1.84-2.931-4.212-2.931z"
|
d="M15.647 15.935l-1.772 1.194a6.088 6.088 0 00-5.135-2.652 6.348 6.348 0 00-6.522 6.654 6.348 6.348 0 006.522 6.654 6.031 6.031 0 005.124-2.64l1.735 1.266a8.126 8.126 0 01-6.859 3.411A8.422 8.422 0 010 21.131a8.422 8.422 0 018.74-8.691 7.963 7.963 0 016.907 3.495zM35.641 21.131a8.422 8.422 0 01-8.74 8.691 8.422 8.422 0 01-8.739-8.691 8.421 8.421 0 018.739-8.691 8.422 8.422 0 018.74 8.691zm-15.261 0a6.347 6.347 0 006.521 6.654 6.347 6.347 0 006.521-6.654 6.347 6.347 0 00-6.521-6.654 6.347 6.347 0 00-6.521 6.654zM53.729 29.581h-1.917l-10.2-13.26-.012 13.248h-2.122V12.681h1.917l10.21 13.26V12.693h2.122zM69.551 16.02a8.835 8.835 0 00-5-1.555c-2.471 0-4.231 1.109-4.231 2.929 0 1.531 1.29 2.315 3.821 2.628l1.484.181c2.856.35 5.3 1.507 5.3 4.484 0 3.364-3.05 5.123-6.7 5.123a10.935 10.935 0 01-6.654-2.194l1.157-1.687a9.018 9.018 0 005.5 1.868c2.519 0 4.5-1.025 4.5-2.929 0-1.567-1.41-2.314-4.038-2.64l-1.567-.193c-2.784-.337-5-1.627-5-4.508 0-3.255 2.893-5.075 6.449-5.075a10.336 10.336 0 016.076 1.844zM91.268 21.131a8.422 8.422 0 01-8.74 8.691 8.422 8.422 0 01-8.739-8.691 8.421 8.421 0 018.739-8.691 8.422 8.422 0 018.74 8.691zm-15.261 0a6.348 6.348 0 006.521 6.654 6.347 6.347 0 006.521-6.654 6.347 6.347 0 00-6.521-6.654 6.348 6.348 0 00-6.521 6.654zM106.897 29.569h-11.79V12.693h2.122v14.863h9.668zM121.76 29.569h-11.982V12.693h11.862v1.988h-9.74v5.389h9.427v2H111.9v5.509h9.86zM14.9.167h2.576v7.547H14.9zM11.801.238l-5.23 3.194a.229.229 0 01-.242 0L1.099.238a.726.726 0 00-.374-.1H.719a.717.717 0 00-.717.717v6.864h2.574V4.462a.258.258 0 01.392-.22l2.931 1.793a.919.919 0 00.944.009L9.935 4.23a.258.258 0 01.388.222v3.267h2.575V.855a.717.717 0 00-.717-.717h-.006a.723.723 0 00-.374.1zM30.348.165h-2.613v3.463a.258.258 0 01-.379.228L20.585.249a.723.723 0 00-.337-.084.717.717 0 00-.717.717v6.832h2.592V4.306a.258.258 0 01.379-.227l6.8 3.606a.714.714 0 00.336.083.716.716 0 00.717-.717V.165zM32.439 7.712V.165h1.2v7.547zM40.536 7.878c-3.189 0-5.451-1.513-5.451-3.939S37.361 0 40.536 0s5.466 1.513 5.466 3.939-2.236 3.939-5.466 3.939zm0-6.87c-2.371 0-4.2 1.036-4.2 2.931s1.826 2.93 4.2 2.93 4.212-1.022 4.212-2.93-1.84-2.931-4.212-2.931z"
|
||||||
|
|||||||
@@ -31,12 +31,17 @@ import {
|
|||||||
GLOBAL_SET_DISTRIBUTED_SETUP,
|
GLOBAL_SET_DISTRIBUTED_SETUP,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
|
// determine whether we have the sidebar state stored on localstorage
|
||||||
|
const initSideBarOpen = localStorage.getItem("sidebarOpen")
|
||||||
|
? JSON.parse(localStorage.getItem("sidebarOpen")!)["open"]
|
||||||
|
: true;
|
||||||
|
|
||||||
const initialState: SystemState = {
|
const initialState: SystemState = {
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
operatorMode: false,
|
operatorMode: false,
|
||||||
session: "",
|
session: "",
|
||||||
userName: "",
|
userName: "",
|
||||||
sidebarOpen: true,
|
sidebarOpen: initSideBarOpen,
|
||||||
serverNeedsRestart: false,
|
serverNeedsRestart: false,
|
||||||
serverIsLoading: false,
|
serverIsLoading: false,
|
||||||
loadingProgress: 100,
|
loadingProgress: 100,
|
||||||
@@ -70,6 +75,11 @@ export function systemReducer(
|
|||||||
operatorMode: action.operatorMode,
|
operatorMode: action.operatorMode,
|
||||||
};
|
};
|
||||||
case MENU_OPEN:
|
case MENU_OPEN:
|
||||||
|
// persist preference to local storage
|
||||||
|
localStorage.setItem(
|
||||||
|
"sidebarOpen",
|
||||||
|
JSON.stringify({ open: action.open })
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
sidebarOpen: action.open,
|
sidebarOpen: action.open,
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import React from "react";
|
import React, { Fragment } from "react";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import { AppState } from "../../../../store";
|
||||||
interface IPageHeader {
|
import { connect } from "react-redux";
|
||||||
classes: any;
|
import { setMenuOpen, userLoggedIn } from "../../../../actions";
|
||||||
label: any;
|
import OperatorLogo from "../../../../icons/OperatorLogo";
|
||||||
actions?: any;
|
import ConsoleLogo from "../../../../icons/ConsoleLogo";
|
||||||
}
|
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
@@ -37,9 +36,28 @@ const styles = (theme: Theme) =>
|
|||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
},
|
},
|
||||||
|
logo: {
|
||||||
|
marginLeft: 34,
|
||||||
|
fill: theme.palette.primary.main,
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const PageHeader = ({ classes, label, actions }: IPageHeader) => {
|
interface IPageHeader {
|
||||||
|
classes: any;
|
||||||
|
sidebarOpen?: boolean;
|
||||||
|
operatorMode?: boolean;
|
||||||
|
label: any;
|
||||||
|
actions?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PageHeader = ({
|
||||||
|
classes,
|
||||||
|
label,
|
||||||
|
actions,
|
||||||
|
sidebarOpen,
|
||||||
|
operatorMode,
|
||||||
|
}: IPageHeader) => {
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
@@ -47,6 +65,11 @@ const PageHeader = ({ classes, label, actions }: IPageHeader) => {
|
|||||||
justify={"space-between"}
|
justify={"space-between"}
|
||||||
>
|
>
|
||||||
<Grid item className={classes.label}>
|
<Grid item className={classes.label}>
|
||||||
|
{!sidebarOpen && (
|
||||||
|
<div className={classes.logo}>
|
||||||
|
{operatorMode ? <OperatorLogo /> : <ConsoleLogo />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Typography variant="h4" className={classes.labelStyle}>
|
<Typography variant="h4" className={classes.labelStyle}>
|
||||||
{label}
|
{label}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -60,4 +83,11 @@ const PageHeader = ({ classes, label, actions }: IPageHeader) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withStyles(styles)(PageHeader);
|
const mapState = (state: AppState) => ({
|
||||||
|
sidebarOpen: state.system.sidebarOpen,
|
||||||
|
operatorMode: state.system.operatorMode,
|
||||||
|
});
|
||||||
|
|
||||||
|
const connector = connect(mapState, null);
|
||||||
|
|
||||||
|
export default connector(withStyles(styles)(PageHeader));
|
||||||
|
|||||||
@@ -384,20 +384,7 @@ const Console = ({
|
|||||||
{session.status === "ok" ? (
|
{session.status === "ok" ? (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
{!hideMenu && (
|
{!hideMenu && <Menu pages={session.pages} />}
|
||||||
<Drawer
|
|
||||||
variant="permanent"
|
|
||||||
classes={{
|
|
||||||
paper: clsx(
|
|
||||||
classes.drawerPaper,
|
|
||||||
!open && classes.drawerPaperClose
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
open={open}
|
|
||||||
>
|
|
||||||
<Menu pages={session.pages} />
|
|
||||||
</Drawer>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<main className={classes.content}>
|
<main className={classes.content}>
|
||||||
{needsRestart && (
|
{needsRestart && (
|
||||||
|
|||||||
@@ -14,19 +14,25 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { Fragment, useState } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { NavLink } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
import { Divider, withStyles } from "@material-ui/core";
|
import {
|
||||||
|
Divider,
|
||||||
|
Drawer,
|
||||||
|
IconButton,
|
||||||
|
Tooltip,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import { createStyles, Theme } from "@material-ui/core/styles";
|
import { createStyles, Theme } from "@material-ui/core/styles";
|
||||||
import ListItem from "@material-ui/core/ListItem";
|
import ListItem from "@material-ui/core/ListItem";
|
||||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||||
import ListItemText from "@material-ui/core/ListItemText";
|
import ListItemText from "@material-ui/core/ListItemText";
|
||||||
import List from "@material-ui/core/List";
|
import List from "@material-ui/core/List";
|
||||||
import { AppState } from "../../../store";
|
import { AppState } from "../../../store";
|
||||||
import { userLoggedIn } from "../../../actions";
|
import { setMenuOpen, userLoggedIn } from "../../../actions";
|
||||||
import { menuGroups } from "./utils";
|
import { menuGroups } from "./utils";
|
||||||
import { IMenuItem, IMenuProps } from "./types";
|
import { IMenuItem } from "./types";
|
||||||
import {
|
import {
|
||||||
BucketsIcon,
|
BucketsIcon,
|
||||||
DashboardIcon,
|
DashboardIcon,
|
||||||
@@ -52,6 +58,12 @@ import LogsIcon from "../../../icons/LogsIcon";
|
|||||||
import SettingsIcon from "../../../icons/SettingsIcon";
|
import SettingsIcon from "../../../icons/SettingsIcon";
|
||||||
import StorageIcon from "../../../icons/StorageIcon";
|
import StorageIcon from "../../../icons/StorageIcon";
|
||||||
import TenantsOutlinedIcon from "../../../icons/TenantsOutlineIcon";
|
import TenantsOutlinedIcon from "../../../icons/TenantsOutlineIcon";
|
||||||
|
import MenuIcon from "@material-ui/icons/Menu";
|
||||||
|
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { ChevronLeft } from "@material-ui/icons";
|
||||||
|
|
||||||
|
const drawerWidth = 245;
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
@@ -59,9 +71,39 @@ const styles = (theme: Theme) =>
|
|||||||
paddingTop: 25,
|
paddingTop: 25,
|
||||||
marginBottom: 30,
|
marginBottom: 30,
|
||||||
paddingLeft: 45,
|
paddingLeft: 45,
|
||||||
|
transition: theme.transitions.create("paddingLeft", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
"& img": {
|
"& img": {
|
||||||
width: 120,
|
width: 120,
|
||||||
},
|
},
|
||||||
|
"& .MuiIconButton-root": {
|
||||||
|
color: "#ffffff",
|
||||||
|
float: "right",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logoClosed: {
|
||||||
|
paddingTop: 25,
|
||||||
|
marginBottom: 30,
|
||||||
|
paddingLeft: 34,
|
||||||
|
transition: theme.transitions.create("paddingLeft", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
|
"& .MuiIconButton-root": {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logoSvg: {
|
||||||
|
width: 40,
|
||||||
|
},
|
||||||
|
logoSvgClosed: {
|
||||||
|
width: 0,
|
||||||
|
transition: theme.transitions.create("width", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
menuList: {
|
menuList: {
|
||||||
"& .active": {
|
"& .active": {
|
||||||
@@ -147,6 +189,80 @@ const styles = (theme: Theme) =>
|
|||||||
selectorArrowOpen: {
|
selectorArrowOpen: {
|
||||||
transform: "rotateZ(180deg)",
|
transform: "rotateZ(180deg)",
|
||||||
},
|
},
|
||||||
|
//new
|
||||||
|
appBar: {
|
||||||
|
zIndex: theme.zIndex.drawer + 1,
|
||||||
|
transition: theme.transitions.create(["width", "margin"], {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
appBarShift: {
|
||||||
|
marginLeft: drawerWidth,
|
||||||
|
width: `calc(100% - ${drawerWidth}px)`,
|
||||||
|
transition: theme.transitions.create(["width", "margin"], {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.enteringScreen,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
menuButton: {
|
||||||
|
marginRight: 36,
|
||||||
|
},
|
||||||
|
hide: {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
drawer: {
|
||||||
|
width: drawerWidth,
|
||||||
|
flexShrink: 0,
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
background:
|
||||||
|
"transparent linear-gradient(90deg, #073052 0%, #081C42 100%) 0% 0% no-repeat padding-box !important",
|
||||||
|
boxShadow: "0px 3px 7px #00000014",
|
||||||
|
"& .MuiPaper-root": {
|
||||||
|
backgroundColor: "inherit",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
drawerOpen: {
|
||||||
|
width: drawerWidth,
|
||||||
|
transition: theme.transitions.create("width", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.enteringScreen,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
drawerClose: {
|
||||||
|
transition: theme.transitions.create("width", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
|
overflowX: "hidden",
|
||||||
|
width: 115,
|
||||||
|
[theme.breakpoints.up("sm")]: {
|
||||||
|
width: 115,
|
||||||
|
},
|
||||||
|
"& .logo": {
|
||||||
|
background: "red",
|
||||||
|
},
|
||||||
|
"& .MuiListItem-root": {
|
||||||
|
padding: "2px 0 2px 16px",
|
||||||
|
marginLeft: 36,
|
||||||
|
height: 50,
|
||||||
|
width: "48px",
|
||||||
|
transition: theme.transitions.create("marginLeft", {
|
||||||
|
easing: theme.transitions.easing.sharp,
|
||||||
|
duration: theme.transitions.duration.leavingScreen,
|
||||||
|
}),
|
||||||
|
"& .MuiListItemText-root": {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logoIcon: {
|
||||||
|
float: "left",
|
||||||
|
"& svg": {
|
||||||
|
fill: "white",
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Menu State builder for groups
|
// Menu State builder for groups
|
||||||
@@ -161,15 +277,25 @@ const menuStateBuilder = () => {
|
|||||||
return elements;
|
return elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface IMenuProps {
|
||||||
|
classes: any;
|
||||||
|
userLoggedIn: typeof userLoggedIn;
|
||||||
|
pages: string[];
|
||||||
|
operatorMode: boolean;
|
||||||
|
distributedSetup: boolean;
|
||||||
|
sidebarOpen: boolean;
|
||||||
|
setMenuOpen: typeof setMenuOpen;
|
||||||
|
}
|
||||||
|
|
||||||
const Menu = ({
|
const Menu = ({
|
||||||
userLoggedIn,
|
userLoggedIn,
|
||||||
classes,
|
classes,
|
||||||
pages,
|
pages,
|
||||||
operatorMode,
|
operatorMode,
|
||||||
distributedSetup,
|
distributedSetup,
|
||||||
|
sidebarOpen,
|
||||||
|
setMenuOpen,
|
||||||
}: IMenuProps) => {
|
}: IMenuProps) => {
|
||||||
const [menuOpen, setMenuOpen] = useState<any>(menuStateBuilder());
|
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
const deleteSession = () => {
|
const deleteSession = () => {
|
||||||
clearSession();
|
clearSession();
|
||||||
@@ -385,91 +511,130 @@ const Menu = ({
|
|||||||
item.fsHidden !== false
|
item.fsHidden !== false
|
||||||
);
|
);
|
||||||
|
|
||||||
const setMenuCollapse = (menuClicked: string) => {
|
const handleDrawerOpen = () => {
|
||||||
let newMenu: any = { ...menuOpen };
|
setMenuOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
newMenu[menuClicked] = !newMenu[menuClicked];
|
const handleDrawerClose = () => {
|
||||||
|
setMenuOpen(false);
|
||||||
setMenuOpen(newMenu);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className={classes.logo}>
|
<Drawer
|
||||||
{operatorMode ? <OperatorLogo /> : <ConsoleLogo />}
|
variant="permanent"
|
||||||
</div>
|
className={clsx(classes.drawer, {
|
||||||
<List className={classes.menuList}>
|
[classes.drawerOpen]: sidebarOpen,
|
||||||
{menuGroups.map((groupMember, index) => {
|
[classes.drawerClose]: !sidebarOpen,
|
||||||
const filterByGroup = (allowedItems || []).filter(
|
|
||||||
(item: any) => item.group === groupMember.group
|
|
||||||
);
|
|
||||||
|
|
||||||
const countableElements = filterByGroup.filter(
|
|
||||||
(menuItem: any) => menuItem.type !== "title"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (countableElements.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment key={`menuElem-${index.toString()}`}>
|
|
||||||
<Divider className={classes.menuDivider} />
|
|
||||||
{filterByGroup.map((page: IMenuItem) => {
|
|
||||||
switch (page.type) {
|
|
||||||
case "item": {
|
|
||||||
return (
|
|
||||||
<ListItem
|
|
||||||
key={page.to}
|
|
||||||
button
|
|
||||||
onClick={page.onClick}
|
|
||||||
component={page.component}
|
|
||||||
to={page.to}
|
|
||||||
className={
|
|
||||||
page.extraMargin ? classes.extraMargin : null
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{page.icon && <ListItemIcon>{page.icon}</ListItemIcon>}
|
|
||||||
{page.name && <ListItemText primary={page.name} />}
|
|
||||||
</ListItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "title": {
|
|
||||||
return (
|
|
||||||
<ListItem
|
|
||||||
key={page.name}
|
|
||||||
component={page.component}
|
|
||||||
className={classes.subTitleMenu}
|
|
||||||
>
|
|
||||||
{page.name}
|
|
||||||
</ListItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
<Divider className={classes.menuDivider} />
|
classes={{
|
||||||
<ListItem button onClick={logout}>
|
paper: clsx({
|
||||||
<ListItemIcon>
|
[classes.drawerOpen]: sidebarOpen,
|
||||||
<LogoutIcon />
|
[classes.drawerClose]: !sidebarOpen,
|
||||||
</ListItemIcon>
|
}),
|
||||||
<ListItemText primary="Logout" />
|
}}
|
||||||
</ListItem>
|
>
|
||||||
</List>
|
<div
|
||||||
|
className={clsx({
|
||||||
|
[classes.logo]: sidebarOpen,
|
||||||
|
[classes.logoClosed]: !sidebarOpen,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{sidebarOpen && (
|
||||||
|
<span className={classes.logoIcon}>
|
||||||
|
{operatorMode ? <OperatorLogo /> : <ConsoleLogo />}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
if (sidebarOpen) {
|
||||||
|
setMenuOpen(false);
|
||||||
|
} else {
|
||||||
|
setMenuOpen(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{sidebarOpen ? <ChevronLeft /> : <MenuIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
<List className={classes.menuList}>
|
||||||
|
{menuGroups.map((groupMember, index) => {
|
||||||
|
const filterByGroup = (allowedItems || []).filter(
|
||||||
|
(item: any) => item.group === groupMember.group
|
||||||
|
);
|
||||||
|
|
||||||
|
const countableElements = filterByGroup.filter(
|
||||||
|
(menuItem: any) => menuItem.type !== "title"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (countableElements.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment key={`menuElem-${index.toString()}`}>
|
||||||
|
<Divider className={classes.menuDivider} />
|
||||||
|
{filterByGroup.map((page: IMenuItem) => {
|
||||||
|
switch (page.type) {
|
||||||
|
case "item": {
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
key={page.to}
|
||||||
|
button
|
||||||
|
onClick={page.onClick}
|
||||||
|
component={page.component}
|
||||||
|
to={page.to}
|
||||||
|
className={
|
||||||
|
page.extraMargin ? classes.extraMargin : null
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{page.icon && (
|
||||||
|
<Tooltip title={page.name}>
|
||||||
|
<ListItemIcon>{page.icon}</ListItemIcon>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{page.name && <ListItemText primary={page.name} />}
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "title": {
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
key={page.name}
|
||||||
|
component={page.component}
|
||||||
|
className={classes.subTitleMenu}
|
||||||
|
>
|
||||||
|
{page.name}
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Divider className={classes.menuDivider} />
|
||||||
|
<ListItem button onClick={logout}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<LogoutIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary="Logout" />
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</Drawer>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapState = (state: AppState) => ({
|
const mapState = (state: AppState) => ({
|
||||||
open: state.system.loggedIn,
|
sidebarOpen: state.system.sidebarOpen,
|
||||||
operatorMode: state.system.operatorMode,
|
operatorMode: state.system.operatorMode,
|
||||||
distributedSetup: state.system.distributedSetup,
|
distributedSetup: state.system.distributedSetup,
|
||||||
});
|
});
|
||||||
|
|
||||||
const connector = connect(mapState, { userLoggedIn });
|
const connector = connect(mapState, { userLoggedIn, setMenuOpen });
|
||||||
|
|
||||||
export default connector(withStyles(styles)(Menu));
|
export default connector(withStyles(styles)(Menu));
|
||||||
|
|||||||
@@ -16,14 +16,6 @@
|
|||||||
|
|
||||||
import { userLoggedIn } from "../../../actions";
|
import { userLoggedIn } from "../../../actions";
|
||||||
|
|
||||||
export interface IMenuProps {
|
|
||||||
classes: any;
|
|
||||||
userLoggedIn: typeof userLoggedIn;
|
|
||||||
pages: string[];
|
|
||||||
operatorMode: boolean;
|
|
||||||
distributedSetup: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMenuItem {
|
export interface IMenuItem {
|
||||||
group: string;
|
group: string;
|
||||||
type: string;
|
type: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user