UNPKG

@diagramers/admin

Version:

Diagramers Admin Template - React starter for admin dashboards.

149 lines (137 loc) 5.82 kB
import React, { useCallback, useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import classNames from 'classnames'; import { MENU_PLACEMENT, MENU_BEHAVIOUR } from 'constants.js'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; import { getMenuItems } from 'routing/helper'; import { useWindowSize } from 'hooks/useWindowSize'; import { useWindowScroll } from 'hooks/useWindowScroll'; import routesAndMenuItems from 'routes.js'; import { layoutShowingNavMenu } from 'layout/layoutSlice'; import MainMenuItems from './MainMenuItems'; import { menuChangeAttrMenuAnimate, menuChangeAttrMobile, menuChangeBehaviourStatus, menuChangeCollapseAll, menuChangeNavClasses, menuChangePinButtonEnable, menuChangePlacementStatus, } from './menuSlice'; import { checkBehaviour, checkPlacement, isDeeplyDiffBehaviourStatus, isDeeplyDiffPlacementStatus } from './helper'; const MainMenu = () => { const dispatch = useDispatch(); const { placement, behaviour, placementStatus, behaviourStatus, attrMobile, breakpoints, useSidebar } = useSelector((state) => state.menu); const { isLogin, currentUser } = useSelector((state) => state.auth); const scrolled = useWindowScroll(); const { width } = useWindowSize(); const menuItemsMemo = useMemo( () => getMenuItems({ data: attrMobile && useSidebar ? routesAndMenuItems : routesAndMenuItems.mainMenuItems, isLogin, userRole: currentUser.role, }), [isLogin, currentUser, attrMobile, useSidebar] ); useEffect(() => { dispatch(menuChangeAttrMenuAnimate('')); dispatch(layoutShowingNavMenu('')); if (placementStatus.status === 2 || placementStatus.status === 4) { // Switching back from the mobile menu layout fast dispatch(menuChangeNavClasses({})); dispatch(menuChangeAttrMobile(false)); } // Prevents menu animation to make a fast switch if (behaviourStatus.status === 1) { dispatch(menuChangeCollapseAll(true)); dispatch(menuChangePinButtonEnable(true)); } else if (behaviourStatus.status === 2) { dispatch(menuChangeCollapseAll(true)); dispatch(menuChangePinButtonEnable(false)); } else if (behaviourStatus.status === 3) { dispatch(menuChangePinButtonEnable(true)); dispatch(menuChangeCollapseAll(false)); } else if (behaviourStatus.status === 4) { dispatch(menuChangePinButtonEnable(false)); dispatch(menuChangeCollapseAll(true)); } else if (behaviourStatus.status === 5) { dispatch(menuChangeCollapseAll(false)); dispatch(menuChangePinButtonEnable(true)); } else if (behaviourStatus.status === 6) { dispatch(menuChangeCollapseAll(false)); dispatch(menuChangePinButtonEnable(true)); } // eslint-disable-next-line }, [behaviourStatus, placementStatus]); useEffect(() => { if (placementStatus.placementHtmlData === MENU_PLACEMENT.Vertical && behaviourStatus.behaviourHtmlData === MENU_BEHAVIOUR.Unpinned && attrMobile !== true) { dispatch(menuChangeCollapseAll(true)); dispatch(menuChangeAttrMenuAnimate('hidden')); } return () => {}; // eslint-disable-next-line }, [attrMobile]); useEffect(() => { if (placementStatus.placementHtmlData === MENU_PLACEMENT.Horizontal && !attrMobile && behaviourStatus.behaviourHtmlData === MENU_BEHAVIOUR.Unpinned) { if (scrolled) { dispatch(menuChangeAttrMenuAnimate('hidden')); // Hiding all dropdowns to make sure they are closed when menu collapses document.documentElement.click(); } else { dispatch(menuChangeAttrMenuAnimate('')); } } return () => {}; // eslint-disable-next-line }, [scrolled]); const getMenuStatus = useCallback( (pBreakpoints, pPlacement, pBehaviour) => { if (pBreakpoints) { const placementStatusCB = checkPlacement({ placement: pPlacement, breakpoints: pBreakpoints }); const behaviourStatusCB = checkBehaviour({ placement: placementStatusCB.placementHtmlData, behaviour: pBehaviour, breakpoints: pBreakpoints }); if (isDeeplyDiffPlacementStatus(placementStatusCB, placementStatus)) { dispatch(menuChangePlacementStatus(placementStatusCB)); } if (isDeeplyDiffBehaviourStatus(behaviourStatusCB, behaviourStatus)) { dispatch(menuChangeBehaviourStatus(behaviourStatusCB)); } } // eslint-disable-next-line }, [behaviourStatus,placementStatus,breakpoints]); useEffect(() => { if (width && placement && behaviour && breakpoints) { getMenuStatus(breakpoints, placement, behaviour); } // eslint-disable-next-line }, [width, breakpoints, placement, behaviour]); // Initializes the horizontal menu // Customizes dropdown clicks to prevent auto closing and making sure all sub menus are closed when parent is closed if (menuItemsMemo) { if (placementStatus.view === MENU_PLACEMENT.Horizontal) { return ( <div className="menu-container flex-grow-1"> <ul id="menu" className={classNames('menu show')}> <MainMenuItems menuItems={menuItemsMemo} menuPlacement={placementStatus.view} /> </ul> </div> ); } // Vertical menu scrollbar init return ( <OverlayScrollbarsComponent options={{ scrollbars: { autoHide: 'leave', autoHideDelay: 600 }, overflowBehavior: { x: 'hidden', y: 'scroll' }, }} className="menu-container flex-grow-1" > <ul id="menu" className={classNames('menu show')}> <MainMenuItems menuItems={menuItemsMemo} menuPlacement={placementStatus.view} /> </ul> </OverlayScrollbarsComponent> ); } return <></>; }; export default React.memo(MainMenu);