Files
dailygrubs_console/src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavGroup.js

344 lines
9.8 KiB
JavaScript

import PropTypes from 'prop-types';
import { Fragment, useEffect, useState } from 'react';
import { useLocation } from 'react-router';
// material-ui
import { styled, useTheme } from '@mui/material/styles';
import {
Box,
ClickAwayListener,
List,
ListItemButton,
ListItemIcon,
ListItemText,
Paper,
Popper,
Typography,
useMediaQuery
} from '@mui/material';
// third-party
import { FormattedMessage } from 'react-intl';
// project import
import NavItem from './NavItem';
import NavCollapse from './NavCollapse';
import SimpleBar from 'components/third-party/SimpleBar';
import Transitions from 'components/@extended/Transitions';
import { MenuOrientation } from 'config';
import useConfig from 'hooks/useConfig';
import { dispatch, useSelector } from 'store';
import { activeID } from 'store/reducers/menu';
// assets
import { DownOutlined, RightOutlined } from '@ant-design/icons';
// ==============================|| NAVIGATION - LIST GROUP ||============================== //
const PopperStyled = styled(Popper)(({ theme }) => ({
overflow: 'visible',
zIndex: 1202,
minWidth: 180,
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 5,
left: 32,
width: 12,
height: 12,
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 120,
borderWidth: '6px',
borderStyle: 'solid',
borderColor: `${theme.palette.background.paper} transparent transparent ${theme.palette.background.paper}`
}
}));
const NavGroup = ({ item, lastItem, remItems, lastItemId, setSelectedItems, selectedItems, setSelectedLevel, selectedLevel }) => {
const theme = useTheme();
const { pathname } = useLocation();
const { menuOrientation } = useConfig();
const menu = useSelector((state) => state.menu);
const { drawerOpen, selectedID } = menu;
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const [anchorEl, setAnchorEl] = useState(null);
const [currentItem, setCurrentItem] = useState(item);
const openMini = Boolean(anchorEl);
useEffect(() => {
if (lastItem) {
if (item.id === lastItemId) {
const localItem = { ...item };
const elements = remItems.map((ele) => ele.elements);
localItem.children = elements.flat(1);
setCurrentItem(localItem);
} else {
setCurrentItem(item);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [item, lastItem, downLG]);
const checkOpenForParent = (child, id) => {
child.forEach((ele) => {
if (ele.children?.length) {
checkOpenForParent(ele.children, currentItem.id);
}
if (ele.url === pathname) {
dispatch(activeID(id));
}
});
};
const checkSelectedOnload = (data) => {
const childrens = data.children ? data.children : [];
childrens.forEach((itemCheck) => {
if (itemCheck.children?.length) {
checkOpenForParent(itemCheck.children, currentItem.id);
}
if (itemCheck.url === pathname) {
dispatch(activeID(currentItem.id));
}
});
};
useEffect(() => {
checkSelectedOnload(currentItem);
if (openMini) setAnchorEl(null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname, currentItem]);
const handleClick = (event) => {
if (!openMini) {
setAnchorEl(event?.currentTarget);
}
};
const handleClose = () => {
setAnchorEl(null);
};
const Icon = currentItem?.icon;
const itemIcon = currentItem?.icon ? (
<Icon
style={{
fontSize: 20,
stroke: '1.5',
color: selectedID === currentItem.id ? theme.palette.primary.main : theme.palette.secondary.dark
}}
/>
) : null;
const navCollapse = item.children?.map((menuItem) => {
switch (menuItem.type) {
case 'collapse':
return (
<NavCollapse
key={menuItem.id}
menu={menuItem}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
level={1}
parentId={currentItem.id}
/>
);
case 'item':
return <NavItem key={menuItem.id} item={menuItem} level={1} />;
default:
}
});
const moreItems = remItems.map((itemRem, i) => (
<Fragment key={i}>
{itemRem.title && (
<Typography variant="caption" sx={{ pl: 2 }}>
{itemRem.title}
</Typography>
)}
{itemRem?.elements?.map((menu) => {
switch (menu.type) {
case 'collapse':
return (
<NavCollapse
key={menu.id}
menu={menu}
level={1}
parentId={currentItem.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
/>
);
case 'item':
return <NavItem key={menu.id} item={menu} level={1} />;
default:
return (
<Typography key={menu.id} variant="h6" color="error" align="center">
Menu Items Error
</Typography>
);
}
})}
</Fragment>
));
// menu list collapse & items
const items = currentItem.children?.map((menu) => {
switch (menu.type) {
case 'collapse':
return (
<NavCollapse
key={menu.id}
menu={menu}
level={1}
parentId={currentItem.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
/>
);
case 'item':
return <NavItem key={menu.id} item={menu} level={1} />;
default:
return (
<Typography key={menu.id} variant="h6" color="error" align="center">
Menu Items Error
</Typography>
);
}
});
const popperId = openMini ? `group-pop-${item.id}` : undefined;
return (
<>
{menuOrientation === MenuOrientation.VERTICAL || downLG ? (
<List
subheader={
item.title &&
drawerOpen && (
<Box sx={{ pl: 3, mb: 1.5 }}>
<Typography
variant="subtitle2"
sx={{ color: '#fff' }}
>
{item.title}
</Typography>
{item.caption && (
<Typography variant="caption" color="secondary">
{item.caption}
</Typography>
)}
</Box>
)
}
sx={{ mt: drawerOpen && item.title ? 1.5 : 0, py: 0, zIndex: 0 }}
>
{navCollapse}
</List>
) : (
<List>
<ListItemButton
selected={selectedID === currentItem.id}
sx={{
p: 1,
my: 0.5,
mr: 1,
display: 'flex',
alignItems: 'center',
backgroundColor: 'inherit',
'&.Mui-selected': {
bgcolor: 'transparent'
}
}}
onMouseEnter={handleClick}
onClick={handleClick}
onMouseLeave={handleClose}
aria-describedby={popperId}
>
{itemIcon && (
<ListItemIcon sx={{ minWidth: 28 }}>
{currentItem.id === lastItemId ? <DownOutlined style={{ fontSize: 20, stroke: '1.5' }} /> : itemIcon}
</ListItemIcon>
)}
<ListItemText
sx={{ mr: 1 }}
primary={
<Typography
variant="body1"
color={selectedID === currentItem.id ? theme.palette.primary.main : theme.palette.secondary.dark}
>
{currentItem.id === lastItemId ? <FormattedMessage id="More Items" /> : currentItem.title}
</Typography>
}
/>
{openMini ? (
<DownOutlined style={{ fontSize: 16, stroke: '1.5' }} />
) : (
<RightOutlined style={{ fontSize: 16, stroke: '1.5' }} />
)}
{anchorEl && (
<PopperStyled
id={popperId}
open={openMini}
anchorEl={anchorEl}
placement="bottom-start"
style={{
zIndex: 2001
}}
>
{({ TransitionProps }) => (
<Transitions in={openMini} {...TransitionProps}>
<Paper
sx={{
mt: 0.5,
py: 1.25,
boxShadow: theme.shadows[8],
backgroundImage: 'none'
}}
>
<ClickAwayListener onClickAway={handleClose}>
<SimpleBar
sx={{
overflowX: 'hidden',
overflowY: 'auto',
maxHeight: 'calc(100vh - 170px)'
}}
>
{currentItem.id !== lastItemId ? items : moreItems}
</SimpleBar>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</PopperStyled>
)}
</ListItemButton>
</List>
)}
</>
);
};
NavGroup.propTypes = {
item: PropTypes.object,
lastItem: PropTypes.number,
remItems: PropTypes.array,
lastItemId: PropTypes.string,
setSelectedItems: PropTypes.func,
selectedItems: PropTypes.string,
setSelectedLevel: PropTypes.func,
selectedLevel: PropTypes.number
};
export default NavGroup;