// ** React Imports import { useEffect, Fragment } from 'react' // ** Next Import import { useRouter } from 'next/router' // ** MUI Imports import Chip from '@mui/material/Chip' import Collapse from '@mui/material/Collapse' import ListItem from '@mui/material/ListItem' import { styled } from '@mui/material/styles' import Typography from '@mui/material/Typography' import Box, { BoxProps } from '@mui/material/Box' import ListItemIcon from '@mui/material/ListItemIcon' import ListItemButton from '@mui/material/ListItemButton' // ** Third Party Imports import clsx from 'clsx' // ** Icon Imports import Icon from 'src/@core/components/icon' // ** Configs Import import themeConfig from 'src/configs/themeConfig' // ** Utils import { hasActiveChild, removeChildren } from 'src/@core/layouts/utils' // ** Type Import import { NavGroup, LayoutProps } from 'src/@core/layouts/types' // ** Custom Components Imports import VerticalNavItems from './VerticalNavItems' import UserIcon from 'src/layouts/components/UserIcon' import Translations from 'src/layouts/components/Translations' import CanViewNavGroup from 'src/layouts/components/acl/CanViewNavGroup' interface Props { item: NavGroup navHover: boolean parent?: NavGroup navVisible?: boolean groupActive: string[] collapsedNavWidth: number currentActiveGroup: string[] navigationBorderWidth: number settings: LayoutProps['settings'] isSubToSub?: NavGroup | undefined saveSettings: LayoutProps['saveSettings'] setGroupActive: (values: string[]) => void setCurrentActiveGroup: (items: string[]) => void } const MenuItemTextWrapper = styled(Box)(({ theme }) => ({ width: '100%', display: 'flex', alignItems: 'center', gap: theme.spacing(2), justifyContent: 'space-between', transition: 'opacity .25s ease-in-out', ...(themeConfig.menuTextTruncate && { overflow: 'hidden' }) })) const VerticalNavGroup = (props: Props) => { // ** Props const { item, parent, settings, navHover, navVisible, isSubToSub, groupActive, setGroupActive, collapsedNavWidth, currentActiveGroup, setCurrentActiveGroup, navigationBorderWidth } = props // ** Hooks & Vars const router = useRouter() const currentURL = router.asPath const { direction, navCollapsed, verticalNavToggleType } = settings // ** Accordion menu group open toggle const toggleActiveGroup = (item: NavGroup, parent: NavGroup | undefined) => { let openGroup = groupActive // ** If Group is already open and clicked, close the group if (openGroup.includes(item.title)) { openGroup.splice(openGroup.indexOf(item.title), 1) // If clicked Group has open group children, Also remove those children to close those groups if (item.children) { removeChildren(item.children, openGroup, currentActiveGroup) } } else if (parent) { // ** If Group clicked is the child of an open group, first remove all the open groups under that parent if (parent.children) { removeChildren(parent.children, openGroup, currentActiveGroup) } // ** After removing all the open groups under that parent, add the clicked group to open group array if (!openGroup.includes(item.title)) { openGroup.push(item.title) } } else { // ** If clicked on another group that is not active or open, create openGroup array from scratch // ** Empty Open Group array openGroup = [] // ** push Current Active Group To Open Group array if (currentActiveGroup.every(elem => groupActive.includes(elem))) { openGroup.push(...currentActiveGroup) } // ** Push current clicked group item to Open Group array if (!openGroup.includes(item.title)) { openGroup.push(item.title) } } setGroupActive([...openGroup]) } // ** Menu Group Click const handleGroupClick = () => { const openGroup = groupActive if (verticalNavToggleType === 'collapse') { if (openGroup.includes(item.title)) { openGroup.splice(openGroup.indexOf(item.title), 1) } else { openGroup.push(item.title) } setGroupActive([...openGroup]) } else { toggleActiveGroup(item, parent) } } useEffect(() => { if (hasActiveChild(item, currentURL)) { if (!groupActive.includes(item.title)) groupActive.push(item.title) } else { const index = groupActive.indexOf(item.title) if (index > -1) groupActive.splice(index, 1) } setGroupActive([...groupActive]) setCurrentActiveGroup([...groupActive]) // Empty Active Group When Menu is collapsed and not hovered, to fix issue route change if (navCollapsed && !navHover) { setGroupActive([]) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [router.asPath]) useEffect(() => { if (navCollapsed && !navHover) { setGroupActive([]) } if ((navCollapsed && navHover) || (groupActive.length === 0 && !navCollapsed)) { setGroupActive([...currentActiveGroup]) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [navCollapsed, navHover]) useEffect(() => { if (groupActive.length === 0 && !navCollapsed) { setGroupActive([]) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [navHover]) const icon = parent && !item.icon ? themeConfig.navSubItemIcon : item.icon const menuGroupCollapsedStyles = navCollapsed && !navHover ? { opacity: 0 } : { opacity: 1 } return ( parent && item.children ? '0 !important' : `${theme.spacing(navCollapsed && !navHover ? 2 : 3)} !important` }} > {isSubToSub ? null : ( )} {item.badgeContent ? ( ) : null} e.stopPropagation()} in={groupActive.includes(item.title)} sx={{ pl: 0, width: '100%', ...menuGroupCollapsedStyles, transition: 'all 0.25s ease-in-out' }} > ) } export default VerticalNavGroup