diff --git a/src/layouts/Navigation/CommunityMenu.tsx b/src/layouts/Navigation/NavDrawer/CommunityMenu.tsx similarity index 100% rename from src/layouts/Navigation/CommunityMenu.tsx rename to src/layouts/Navigation/NavDrawer/CommunityMenu.tsx diff --git a/src/layouts/Navigation/HelpMenu.tsx b/src/layouts/Navigation/NavDrawer/HelpMenu.tsx similarity index 100% rename from src/layouts/Navigation/HelpMenu.tsx rename to src/layouts/Navigation/NavDrawer/HelpMenu.tsx diff --git a/src/layouts/Navigation/NavDrawer.tsx b/src/layouts/Navigation/NavDrawer/NavDrawer.tsx similarity index 76% rename from src/layouts/Navigation/NavDrawer.tsx rename to src/layouts/Navigation/NavDrawer/NavDrawer.tsx index a15014f0..499c9c6f 100644 --- a/src/layouts/Navigation/NavDrawer.tsx +++ b/src/layouts/Navigation/NavDrawer/NavDrawer.tsx @@ -1,6 +1,5 @@ import { useState } from "react"; -import { useAtom, useSetAtom } from "jotai"; -import { find, groupBy } from "lodash-es"; +import { useSetAtom } from "jotai"; import { colord } from "colord"; import { @@ -10,15 +9,13 @@ import { Stack, IconButton, List, + Box, ListItemIcon, ListItemText, - Divider, ListItemSecondaryAction, - Box, + Divider, } from "@mui/material"; import CloseIcon from "@mui/icons-material/MenuOpen"; -import HomeIcon from "@mui/icons-material/HomeOutlined"; -import AddIcon from "@mui/icons-material/Add"; import DocsIcon from "@mui/icons-material/LibraryBooksOutlined"; import LearningIcon from "@mui/icons-material/LocalLibraryOutlined"; import HelpIcon from "@mui/icons-material/HelpOutline"; @@ -31,24 +28,14 @@ import { import Logo from "@src/assets/Logo"; import NavItem from "./NavItem"; -import SettingsNav from "./SettingsNav"; -import NavTableSection from "./NavTableSection"; import StepsProgress from "@src/components/StepsProgress"; import CommunityMenu from "./CommunityMenu"; import HelpMenu from "./HelpMenu"; +import { INavDrawerContentsProps } from "./NavDrawerContents"; -import { - projectScope, - userSettingsAtom, - tablesAtom, - tableSettingsDialogAtom, - getStartedChecklistAtom, -} from "@src/atoms/projectScope"; -import { TableSettings } from "@src/types/table"; -import { ROUTES } from "@src/constants/routes"; +import { projectScope, getStartedChecklistAtom } from "@src/atoms/projectScope"; import { EXTERNAL_LINKS, WIKI_LINKS } from "@src/constants/externalLinks"; -import { TOP_BAR_HEIGHT } from "./TopBar"; - +import { TOP_BAR_HEIGHT } from "@src/layouts/Navigation/TopBar"; export const NAV_DRAWER_WIDTH = 256; export const NAV_DRAWER_COLLAPSED_WIDTH = 56; @@ -56,50 +43,34 @@ export interface INavDrawerProps extends DrawerProps { open: boolean; isPermanent: boolean; onClose: NonNullable; + Contents: React.ComponentType; } export default function NavDrawer({ open, isPermanent, onClose, + Contents, }: INavDrawerProps) { - const [tables] = useAtom(tablesAtom, projectScope); - const [userSettings] = useAtom(userSettingsAtom, projectScope); - const openTableSettingsDialog = useSetAtom( - tableSettingsDialogAtom, - projectScope - ); - const openGetStartedChecklist = useSetAtom( - getStartedChecklistAtom, - projectScope - ); - - const [hover, setHover] = useState(false); - const [communityMenuAnchorEl, setCommunityMenuAnchorEl] = - useState(null); - const [helpMenuAnchorEl, setHelpMenuAnchorEl] = - useState(null); - - const menuOpen = communityMenuAnchorEl || helpMenuAnchorEl; - - const favorites = Array.isArray(userSettings.favoriteTables) - ? userSettings.favoriteTables - : []; - const sections = { - Favorites: favorites - .map((id) => find(tables, { id })) - .filter((x) => x !== undefined) as TableSettings[], - ...groupBy(tables, "section"), - }; - + const [hover, setHover] = useState(false); const collapsed = !open && isPermanent; - const tempExpanded = (hover || menuOpen) && collapsed; + const tempExpanded = hover && collapsed; const width = collapsed && !tempExpanded ? NAV_DRAWER_COLLAPSED_WIDTH : NAV_DRAWER_WIDTH; const closeDrawer = isPermanent ? undefined : (e: {}) => onClose(e, "escapeKeyDown"); + const openGetStartedChecklist = useSetAtom( + getStartedChecklistAtom, + projectScope + ); + + const [communityMenuAnchorEl, setCommunityMenuAnchorEl] = + useState(null); + const [helpMenuAnchorEl, setHelpMenuAnchorEl] = + useState(null); + const externalLinkIcon = ( @@ -188,8 +159,10 @@ export default function NavDrawer({ ]} PaperProps={{ elevation: isPermanent ? 0 : 8, - onMouseEnter: () => setHover(true), - onMouseLeave: () => setHover(false), + onMouseEnter: () => + setHover((h) => (h === "persist" ? "persist" : true)), + onMouseLeave: () => + setHover((h) => (h === "persist" ? "persist" : false)), }} > {!isPermanent && ( @@ -230,51 +203,14 @@ export default function NavDrawer({ backgroundColor: "var(--nav-bg)", }} > -
  • - - - - - - -
  • - - - - - {sections && - Object.entries(sections) - .filter(([, tables]) => tables.length > 0) - .map(([section, tables]) => ( - - ))} - -
  • - { - if (closeDrawer) closeDrawer(e); - openTableSettingsDialog({}); - }} - sx={{ mb: 1 }} - > - - - - - -
  • - - setCommunityMenuAnchorEl(e.currentTarget) - } + onClick={(e: any) => { + setCommunityMenuAnchorEl(e.currentTarget); + setHover("persist"); + }} > @@ -370,13 +307,19 @@ export default function NavDrawer({ setCommunityMenuAnchorEl(null)} + onClose={() => { + setCommunityMenuAnchorEl(null); + setHover(false); + }} />
  • setHelpMenuAnchorEl(e.currentTarget)} + onClick={(e: any) => { + setHelpMenuAnchorEl(e.currentTarget); + setHover("persist"); + }} > @@ -388,7 +331,10 @@ export default function NavDrawer({ setHelpMenuAnchorEl(null)} + onClose={() => { + setHelpMenuAnchorEl(null); + setHover(false); + }} />
  • diff --git a/src/layouts/Navigation/NavDrawer/NavDrawerContents.tsx b/src/layouts/Navigation/NavDrawer/NavDrawerContents.tsx new file mode 100644 index 00000000..75214827 --- /dev/null +++ b/src/layouts/Navigation/NavDrawer/NavDrawerContents.tsx @@ -0,0 +1,100 @@ +import { useAtom, useSetAtom } from "jotai"; +import { find, groupBy } from "lodash-es"; + +import { ListItemIcon, ListItemText, Divider } from "@mui/material"; +import HomeIcon from "@mui/icons-material/HomeOutlined"; +import AddIcon from "@mui/icons-material/Add"; + +import NavItem from "./NavItem"; +import SettingsNav from "./SettingsNav"; +import NavTableSection from "./NavTableSection"; + +import { + projectScope, + userSettingsAtom, + tablesAtom, + tableSettingsDialogAtom, +} from "@src/atoms/projectScope"; +import { TableSettings } from "@src/types/table"; +import { ROUTES } from "@src/constants/routes"; + +export interface INavDrawerContentsProps { + closeDrawer: ((e: {}) => void) | undefined; + open: boolean; + isPermanent: boolean; + tempExpanded: boolean; + setHover: React.Dispatch>; +} + +export default function NavDrawerContents({ + closeDrawer, + open, + isPermanent, + tempExpanded, +}: INavDrawerContentsProps) { + const [tables] = useAtom(tablesAtom, projectScope); + const [userSettings] = useAtom(userSettingsAtom, projectScope); + const openTableSettingsDialog = useSetAtom( + tableSettingsDialogAtom, + projectScope + ); + + const favorites = Array.isArray(userSettings.favoriteTables) + ? userSettings.favoriteTables + : []; + const sections = { + Favorites: favorites + .map((id) => find(tables, { id })) + .filter((x) => x !== undefined) as TableSettings[], + ...groupBy(tables, "section"), + }; + + return ( + <> +
  • + + + + + + +
  • + + + + + + {sections && + Object.entries(sections) + .filter(([, tables]) => tables.length > 0) + .map(([section, tables]) => ( + + ))} + +
  • + { + if (closeDrawer) closeDrawer(e); + openTableSettingsDialog({}); + }} + sx={{ mb: 1 }} + > + + + + + +
  • + + ); +} diff --git a/src/layouts/Navigation/NavItem.tsx b/src/layouts/Navigation/NavDrawer/NavItem.tsx similarity index 100% rename from src/layouts/Navigation/NavItem.tsx rename to src/layouts/Navigation/NavDrawer/NavItem.tsx diff --git a/src/layouts/Navigation/NavTableSection.tsx b/src/layouts/Navigation/NavDrawer/NavTableSection.tsx similarity index 100% rename from src/layouts/Navigation/NavTableSection.tsx rename to src/layouts/Navigation/NavDrawer/NavTableSection.tsx diff --git a/src/layouts/Navigation/SettingsNav.tsx b/src/layouts/Navigation/NavDrawer/SettingsNav.tsx similarity index 97% rename from src/layouts/Navigation/SettingsNav.tsx rename to src/layouts/Navigation/NavDrawer/SettingsNav.tsx index e54076c6..dc1dc0f1 100644 --- a/src/layouts/Navigation/SettingsNav.tsx +++ b/src/layouts/Navigation/NavDrawer/SettingsNav.tsx @@ -14,7 +14,7 @@ import SettingsIcon from "@mui/icons-material/SettingsOutlined"; import { ChevronDown } from "@src/assets/icons"; import NavItem from "./NavItem"; -import UpdateCheckBadge from "./UpdateCheckBadge"; +import UpdateCheckBadge from "@src/layouts/Navigation/UpdateCheckBadge"; import { projectScope, userRolesAtom } from "@src/atoms/projectScope"; import { ROUTES } from "@src/constants/routes"; diff --git a/src/layouts/Navigation/NavDrawer/index.ts b/src/layouts/Navigation/NavDrawer/index.ts new file mode 100644 index 00000000..9e0fc9f1 --- /dev/null +++ b/src/layouts/Navigation/NavDrawer/index.ts @@ -0,0 +1,2 @@ +export * from "./NavDrawer"; +export { default } from "./NavDrawer"; diff --git a/src/layouts/Navigation/Navigation.tsx b/src/layouts/Navigation/Navigation.tsx index 332313bd..f17053a1 100644 --- a/src/layouts/Navigation/Navigation.tsx +++ b/src/layouts/Navigation/Navigation.tsx @@ -7,6 +7,7 @@ import { useMediaQuery, Stack, GlobalStyles } from "@mui/material"; import TopBar, { TOP_BAR_HEIGHT } from "./TopBar"; import NavDrawer from "./NavDrawer"; +import NavDrawerContents from "./NavDrawer/NavDrawerContents"; import ErrorFallback, { IErrorFallbackProps, } from "@src/components/ErrorFallback"; @@ -51,6 +52,7 @@ export default function Navigation({ children }: React.PropsWithChildren<{}>) { open={open} isPermanent={isPermanent} onClose={() => setOpen(false)} + Contents={NavDrawerContents} />