|
@@ -4,30 +4,38 @@ import List from '@material-ui/core/List';
|
|
|
import ListItem from '@material-ui/core/ListItem';
|
|
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
|
|
import ListItemText from '@material-ui/core/ListItemText';
|
|
|
-import Collapse from '@material-ui/core/Collapse';
|
|
|
import { NavMenuItem, NavMenuType } from './Types';
|
|
|
import icons from '../icons/Icons';
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
import Typography from '@material-ui/core/Typography';
|
|
|
+import ChevronRightIcon from '@material-ui/icons/ChevronRight';
|
|
|
|
|
|
const useStyles = makeStyles((theme: Theme) =>
|
|
|
createStyles({
|
|
|
root: {
|
|
|
- width: (props: any) => props.width || '100%',
|
|
|
background: theme.palette.common.white,
|
|
|
-
|
|
|
paddingBottom: theme.spacing(5),
|
|
|
display: 'flex',
|
|
|
flexDirection: 'column',
|
|
|
justifyContent: 'space-between',
|
|
|
+ transition: theme.transitions.create('width', {
|
|
|
+ duration: theme.transitions.duration.enteringScreen,
|
|
|
+ }),
|
|
|
+ overflow: 'hidden',
|
|
|
+ },
|
|
|
+ rootCollapse: {
|
|
|
+ width: '60px',
|
|
|
+ },
|
|
|
+ rootExpand: {
|
|
|
+ width: (props: any) => props.width || '100%',
|
|
|
},
|
|
|
nested: {
|
|
|
paddingLeft: theme.spacing(4),
|
|
|
},
|
|
|
item: {
|
|
|
marginBottom: theme.spacing(2),
|
|
|
- marginLeft: theme.spacing(3),
|
|
|
-
|
|
|
+ boxSizing: 'content-box',
|
|
|
+ height: theme.spacing(3),
|
|
|
width: 'initial',
|
|
|
color: theme.palette.milvusGrey.dark,
|
|
|
},
|
|
@@ -45,7 +53,7 @@ const useStyles = makeStyles((theme: Theme) =>
|
|
|
},
|
|
|
active: {
|
|
|
color: theme.palette.primary.main,
|
|
|
- borderRight: `2px solid ${theme.palette.primary.main}`,
|
|
|
+ borderLeft: `4px solid ${theme.palette.primary.main}`,
|
|
|
|
|
|
'& .icon': {
|
|
|
'& path': {
|
|
@@ -70,10 +78,37 @@ const useStyles = makeStyles((theme: Theme) =>
|
|
|
lineHeight: '19px',
|
|
|
letterSpacing: '0.15px',
|
|
|
color: '#323232',
|
|
|
+ whiteSpace: 'nowrap',
|
|
|
},
|
|
|
},
|
|
|
logo: {
|
|
|
marginRight: theme.spacing(1),
|
|
|
+ transition: theme.transitions.create('all', {
|
|
|
+ duration: theme.transitions.duration.enteringScreen,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ logoCollapse: {
|
|
|
+ backgroundColor: theme.palette.primary.main,
|
|
|
+ '& path': {
|
|
|
+ fill: 'white',
|
|
|
+ },
|
|
|
+ transform: 'scale(1.5)',
|
|
|
+ },
|
|
|
+ actionIcon: {
|
|
|
+ position: 'fixed',
|
|
|
+ borderRadius: '50%',
|
|
|
+ backgroundColor: 'white',
|
|
|
+ top: '50%',
|
|
|
+ transition: theme.transitions.create('all', {
|
|
|
+ duration: theme.transitions.duration.enteringScreen,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ expandIcon: {
|
|
|
+ left: '187px',
|
|
|
+ transform: 'rotateZ(180deg)',
|
|
|
+ },
|
|
|
+ collapseIcon: {
|
|
|
+ left: '47px',
|
|
|
},
|
|
|
})
|
|
|
);
|
|
@@ -81,22 +116,12 @@ const useStyles = makeStyles((theme: Theme) =>
|
|
|
const NavMenu: FC<NavMenuType> = props => {
|
|
|
const { width, data, defaultActive = '', defaultOpen = {} } = props;
|
|
|
const classes = useStyles({ width });
|
|
|
- const [open, setOpen] = useState<{ [x: string]: boolean }>(defaultOpen);
|
|
|
+ const [expanded, setExpanded] = useState<boolean>(true);
|
|
|
const [active, setActive] = useState<string>(defaultActive);
|
|
|
|
|
|
const { t } = useTranslation();
|
|
|
const milvusTrans: { [key in string]: string } = t('milvus');
|
|
|
|
|
|
- const ExpandLess = icons.expandLess;
|
|
|
- const ExpandMore = icons.expandMore;
|
|
|
-
|
|
|
- const handleClick = (label: string) => {
|
|
|
- setOpen(v => ({
|
|
|
- ...v,
|
|
|
- [label]: !v[label],
|
|
|
- }));
|
|
|
- };
|
|
|
-
|
|
|
useEffect(() => {
|
|
|
if (defaultActive) {
|
|
|
setActive(defaultActive);
|
|
@@ -116,32 +141,16 @@ const NavMenu: FC<NavMenuType> = props => {
|
|
|
? v.iconActiveClass
|
|
|
: v.iconNormalClass
|
|
|
: 'icon';
|
|
|
- if (v.children) {
|
|
|
- return (
|
|
|
- <div key={v.label}>
|
|
|
- <ListItem button onClick={() => handleClick(v.label)}>
|
|
|
- <ListItemIcon>
|
|
|
- <IconComponent classes={{ root: iconClass }} />
|
|
|
- </ListItemIcon>
|
|
|
-
|
|
|
- <ListItemText primary={v.label} />
|
|
|
- {open[v.label] ? <ExpandLess /> : <ExpandMore />}
|
|
|
- </ListItem>
|
|
|
- <Collapse in={open[v.label]} timeout="auto" unmountOnExit>
|
|
|
- <List component="div" disablePadding>
|
|
|
- <NestList data={v.children} className={classes.nested} />
|
|
|
- </List>
|
|
|
- </Collapse>
|
|
|
- </div>
|
|
|
- );
|
|
|
- }
|
|
|
return (
|
|
|
<ListItem
|
|
|
button
|
|
|
key={v.label}
|
|
|
- className={`${className || ''} ${classes.item} ${
|
|
|
- isActive ? classes.active : ''
|
|
|
- }`}
|
|
|
+ title={v.label}
|
|
|
+ className={`
|
|
|
+ ${className || ''}
|
|
|
+ ${classes.item}
|
|
|
+ ${isActive ? classes.active : ''}
|
|
|
+ `}
|
|
|
onClick={() => {
|
|
|
setActive(v.label);
|
|
|
v.onClick && v.onClick();
|
|
@@ -151,7 +160,7 @@ const NavMenu: FC<NavMenuType> = props => {
|
|
|
<IconComponent classes={{ root: iconClass }} />
|
|
|
</ListItemIcon>
|
|
|
|
|
|
- <ListItemText primary={v.label} />
|
|
|
+ <ListItemText hidden={!expanded} primary={v.label} />
|
|
|
</ListItem>
|
|
|
);
|
|
|
})}
|
|
@@ -162,11 +171,15 @@ const NavMenu: FC<NavMenuType> = props => {
|
|
|
const Logo = icons.milvus;
|
|
|
|
|
|
return (
|
|
|
- <List component="nav" className={classes.root}>
|
|
|
+ <List component="nav" className={`${expanded ? classes.rootExpand : classes.rootCollapse} ${classes.root} `}>
|
|
|
<div>
|
|
|
<div className={classes.logoWrapper}>
|
|
|
- <Logo classes={{ root: classes.logo }} />
|
|
|
- <Typography variant="h3" className="title">
|
|
|
+ <Logo classes={{ root: classes.logo }} className={`${expanded ? '' : classes.logoCollapse}`} />
|
|
|
+ <ChevronRightIcon
|
|
|
+ onClick={() => { setExpanded(!expanded) }}
|
|
|
+ className={`${expanded ? classes.expandIcon : classes.collapseIcon} ${classes.actionIcon}`}
|
|
|
+ />
|
|
|
+ <Typography hidden={!expanded} variant="h3" className="title">
|
|
|
{milvusTrans.admin}
|
|
|
</Typography>
|
|
|
</div>
|