diff --git a/portal-ui/src/icons/ConsoleLogo.tsx b/portal-ui/src/icons/ConsoleLogo.tsx index 4e32db4a0..f95432781 100644 --- a/portal-ui/src/icons/ConsoleLogo.tsx +++ b/portal-ui/src/icons/ConsoleLogo.tsx @@ -15,21 +15,15 @@ // along with this program. If not, see . import React from "react"; +import { SvgIcon } from "@material-ui/core"; interface IConsoleLogo { width?: number; } -const ConsoleLogo = ({ width = 120 }: IConsoleLogo) => { +const ConsoleLogo = () => { return ( - - - - + createStyles({ @@ -37,9 +36,28 @@ const styles = (theme: Theme) => marginTop: 16, 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 ( { justify={"space-between"} > + {!sidebarOpen && ( +
+ {operatorMode ? : } +
+ )} {label} @@ -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)); diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx index 05b89e155..6200614ec 100644 --- a/portal-ui/src/screens/Console/Console.tsx +++ b/portal-ui/src/screens/Console/Console.tsx @@ -384,20 +384,7 @@ const Console = ({ {session.status === "ok" ? (
- {!hideMenu && ( - - - - )} + {!hideMenu && }
{needsRestart && ( diff --git a/portal-ui/src/screens/Console/Menu/Menu.tsx b/portal-ui/src/screens/Console/Menu/Menu.tsx index 5ca0e1628..0ba3f028d 100644 --- a/portal-ui/src/screens/Console/Menu/Menu.tsx +++ b/portal-ui/src/screens/Console/Menu/Menu.tsx @@ -14,19 +14,25 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { useState } from "react"; +import React, { Fragment, useState } from "react"; import { connect } from "react-redux"; 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 ListItem from "@material-ui/core/ListItem"; import ListItemIcon from "@material-ui/core/ListItemIcon"; import ListItemText from "@material-ui/core/ListItemText"; import List from "@material-ui/core/List"; import { AppState } from "../../../store"; -import { userLoggedIn } from "../../../actions"; +import { setMenuOpen, userLoggedIn } from "../../../actions"; import { menuGroups } from "./utils"; -import { IMenuItem, IMenuProps } from "./types"; +import { IMenuItem } from "./types"; import { BucketsIcon, DashboardIcon, @@ -52,6 +58,12 @@ import LogsIcon from "../../../icons/LogsIcon"; import SettingsIcon from "../../../icons/SettingsIcon"; import StorageIcon from "../../../icons/StorageIcon"; 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) => createStyles({ @@ -59,9 +71,39 @@ const styles = (theme: Theme) => paddingTop: 25, marginBottom: 30, paddingLeft: 45, + transition: theme.transitions.create("paddingLeft", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), "& img": { 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: { "& .active": { @@ -147,6 +189,80 @@ const styles = (theme: Theme) => selectorArrowOpen: { 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 @@ -161,15 +277,25 @@ const menuStateBuilder = () => { return elements; }; +interface IMenuProps { + classes: any; + userLoggedIn: typeof userLoggedIn; + pages: string[]; + operatorMode: boolean; + distributedSetup: boolean; + sidebarOpen: boolean; + setMenuOpen: typeof setMenuOpen; +} + const Menu = ({ userLoggedIn, classes, pages, operatorMode, distributedSetup, + sidebarOpen, + setMenuOpen, }: IMenuProps) => { - const [menuOpen, setMenuOpen] = useState(menuStateBuilder()); - const logout = () => { const deleteSession = () => { clearSession(); @@ -385,91 +511,130 @@ const Menu = ({ item.fsHidden !== false ); - const setMenuCollapse = (menuClicked: string) => { - let newMenu: any = { ...menuOpen }; + const handleDrawerOpen = () => { + setMenuOpen(true); + }; - newMenu[menuClicked] = !newMenu[menuClicked]; - - setMenuOpen(newMenu); + const handleDrawerClose = () => { + setMenuOpen(false); }; return ( -
- {operatorMode ? : } -
- - {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 ( - - - {filterByGroup.map((page: IMenuItem) => { - switch (page.type) { - case "item": { - return ( - - {page.icon && {page.icon}} - {page.name && } - - ); - } - case "title": { - return ( - - {page.name} - - ); - } - default: - return null; - } - })} - - ); + - - - - - - - + classes={{ + paper: clsx({ + [classes.drawerOpen]: sidebarOpen, + [classes.drawerClose]: !sidebarOpen, + }), + }} + > +
+ {sidebarOpen && ( + + {operatorMode ? : } + + )} + + { + if (sidebarOpen) { + setMenuOpen(false); + } else { + setMenuOpen(true); + } + }} + > + {sidebarOpen ? : } + +
+ + {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 ( + + + {filterByGroup.map((page: IMenuItem) => { + switch (page.type) { + case "item": { + return ( + + {page.icon && ( + + {page.icon} + + )} + {page.name && } + + ); + } + case "title": { + return ( + + {page.name} + + ); + } + default: + return null; + } + })} + + ); + })} + + + + + + + + +
); }; const mapState = (state: AppState) => ({ - open: state.system.loggedIn, + sidebarOpen: state.system.sidebarOpen, operatorMode: state.system.operatorMode, distributedSetup: state.system.distributedSetup, }); -const connector = connect(mapState, { userLoggedIn }); +const connector = connect(mapState, { userLoggedIn, setMenuOpen }); export default connector(withStyles(styles)(Menu)); diff --git a/portal-ui/src/screens/Console/Menu/types.ts b/portal-ui/src/screens/Console/Menu/types.ts index b99d447cb..a913ae033 100644 --- a/portal-ui/src/screens/Console/Menu/types.ts +++ b/portal-ui/src/screens/Console/Menu/types.ts @@ -16,14 +16,6 @@ import { userLoggedIn } from "../../../actions"; -export interface IMenuProps { - classes: any; - userLoggedIn: typeof userLoggedIn; - pages: string[]; - operatorMode: boolean; - distributedSetup: boolean; -} - export interface IMenuItem { group: string; type: string;