diff --git a/frontend/src/component/layout/MainLayout/AdminMenu/AdminListItem.tsx b/frontend/src/component/layout/MainLayout/AdminMenu/AdminListItem.tsx index c9059271a4..19f1eee21e 100644 --- a/frontend/src/component/layout/MainLayout/AdminMenu/AdminListItem.tsx +++ b/frontend/src/component/layout/MainLayout/AdminMenu/AdminListItem.tsx @@ -72,6 +72,7 @@ interface IMenuGroupProps { icon: ReactNode; activeIcon: ReactNode; isActiveMenu: boolean; + staticExpanded?: true | undefined; } export const MenuGroup = ({ @@ -80,10 +81,12 @@ export const MenuGroup = ({ icon, activeIcon, isActiveMenu, + staticExpanded, }: IMenuGroupProps) => { return ( } + expandIcon={staticExpanded ? null : } aria-controls='configure-content' id='configure-header' sx={listItemButtonStyle} diff --git a/frontend/src/component/layout/MainLayout/AdminMenu/AdminMenu.tsx b/frontend/src/component/layout/MainLayout/AdminMenu/AdminMenu.tsx index f30ad1e777..424ebb5303 100644 --- a/frontend/src/component/layout/MainLayout/AdminMenu/AdminMenu.tsx +++ b/frontend/src/component/layout/MainLayout/AdminMenu/AdminMenu.tsx @@ -1,38 +1,8 @@ -import { - Grid, - styled, - Paper, - Typography, - Button, - List, - useMediaQuery, - useTheme, -} from '@mui/material'; +import { Grid, styled, Paper, useMediaQuery, useTheme } from '@mui/material'; import { useUiFlag } from 'hooks/useUiFlag'; import type { ReactNode } from 'react'; -import ArrowBackIcon from '@mui/icons-material/ArrowBack'; -import StopRoundedIcon from '@mui/icons-material/StopRounded'; -import { AdminListItem, AdminSubListItem, MenuGroup } from './AdminListItem'; -import { useLocation } from 'react-router-dom'; import { Sticky } from 'component/common/Sticky/Sticky'; -import { adminRoutes, adminGroups } from 'component/admin/adminRoutes'; -import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { filterByConfig } from 'component/common/util'; -import { filterAdminRoutes } from 'component/admin/filterAdminRoutes'; -import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus'; -import { IconRenderer } from './AdminMenuIcons'; - -interface IMenuLinkItem { - href: string; - text: string; - icon: ReactNode; -} - -interface IMenuItem { - href: string; - text: string; - items?: IMenuLinkItem[]; -} +import { AdminMenuNavigation } from './AdminNavigationItems'; const StyledAdminMainGrid = styled(Grid)(({ theme }) => ({ minWidth: 0, // this is a fix for overflowing flex @@ -79,20 +49,6 @@ const StickyContainer = styled(Sticky)(({ theme }) => ({ transition: 'padding 0.3s ease', })); -const SettingsHeader = styled(Typography)(({ theme }) => ({ - fontSize: theme.fontSizes.mainHeader, - fontWeight: theme.fontWeight.bold, -})); - -const StyledButton = styled(Button)(({ theme }) => ({ - paddingLeft: theme.spacing(0), - marginBottom: theme.spacing(3), -})); - -const StyledStopRoundedIcon = styled(StopRoundedIcon)(({ theme }) => ({ - color: theme.palette.primary.main, -})); - interface IWrapIfAdminSubpageProps { children: ReactNode; } @@ -113,29 +69,11 @@ export const WrapIfAdminSubpage = ({ children }: IWrapIfAdminSubpageProps) => { return <>{children}; }; -const DashboardLink = () => { - return ( - <> - } - > - Back to Unleash - - - ); -}; - interface IAdminMenuProps { children: ReactNode; } export const AdminMenu = ({ children }: IAdminMenuProps) => { - const { uiConfig, isPro, isEnterprise } = useUiConfig(); - const { isBilling } = useInstanceStatus(); - const isActiveItem = (item?: string) => - item !== undefined && location.pathname === item; const theme = useTheme(); const isBreakpoint = useMediaQuery(theme.breakpoints.down(1350)); const onClick = () => { @@ -144,109 +82,13 @@ export const AdminMenu = ({ children }: IAdminMenuProps) => { behavior: 'smooth', }); }; - const location = useLocation(); - const routes = adminRoutes - .filter(filterByConfig(uiConfig)) - .filter((route) => - filterAdminRoutes(route?.menu, { - enterprise: isEnterprise(), - pro: isPro(), - billing: isBilling, - }), - ); - - const menuStructure = routes.reduce( - (acc: Record, route) => { - if (route.group && adminGroups[route.group]) { - if (!acc[route.group]) { - acc[route.group] = { - href: route.group, - text: adminGroups[route.group], - items: [], - }; - } - acc[route.group].items?.push({ - href: route.path, - text: route.title, - icon: , - }); - } - if (!route.group) { - acc[route.path] = { - href: route.path, - text: route.title, - }; - } - return acc; - }, - {}, - ); - - const items = Object.values(menuStructure); return ( - Admin settings - - - {items.map((item) => { - if (item.items) { - const isActiveMenu = item.items.find( - (itm) => isActiveItem(itm.href), - ); - return ( - - } - activeIcon={ - - } - isActiveMenu={Boolean(isActiveMenu)} - key={item.text} - > - {item.items.map((subItem) => ( - - - - ))} - - ); - } - return ( - - - - ); - })} - + diff --git a/frontend/src/component/layout/MainLayout/AdminMenu/AdminNavigationItems.tsx b/frontend/src/component/layout/MainLayout/AdminMenu/AdminNavigationItems.tsx new file mode 100644 index 0000000000..361f514f8d --- /dev/null +++ b/frontend/src/component/layout/MainLayout/AdminMenu/AdminNavigationItems.tsx @@ -0,0 +1,185 @@ +import { Button, styled, Typography, List } from '@mui/material'; +import { OtherLinksList } from '../NavigationSidebar/NavigationList'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import StopRoundedIcon from '@mui/icons-material/StopRounded'; +import { AdminListItem, AdminSubListItem, MenuGroup } from './AdminListItem'; +import { IconRenderer } from './AdminMenuIcons'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus'; +import { useLocation } from 'react-router-dom'; +import { filterByConfig } from 'component/common/util'; +import { filterAdminRoutes } from 'component/admin/filterAdminRoutes'; +import { adminGroups, adminRoutes } from 'component/admin/adminRoutes'; +import type { ReactNode } from 'react'; + +interface IMenuLinkItem { + href: string; + text: string; + icon: ReactNode; +} + +interface IMenuItem { + href: string; + text: string; + items?: IMenuLinkItem[]; +} + +const SettingsHeader = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.mainHeader, + fontWeight: theme.fontWeight.bold, +})); + +const StyledButton = styled(Button)(({ theme }) => ({ + paddingLeft: theme.spacing(0), + marginBottom: theme.spacing(3), +})); + +const StyledDiv = styled('div')(({ theme }) => ({ + padding: theme.spacing(2, 2.5, 0, 2.5), +})); + +const StyledStopRoundedIcon = styled(StopRoundedIcon)(({ theme }) => ({ + color: theme.palette.primary.main, +})); + +export const DashboardLink = () => { + return ( + } + > + Back to Unleash + + ); +}; + +export const AdminMobileNavigation = ({ onClick }: { onClick: () => void }) => { + return ( + <> + + + + + + + + + ); +}; + +export const AdminMenuNavigation = ({ onClick }: { onClick: () => void }) => { + return ( + <> + + + + ); +}; + +export const AdminNavigationHeader = () => { + return ( + <> + Admin settings + + + ); +}; + +export const AdminNavigationItems = ({ + onClick, + staticExpanded, +}: { onClick: () => void; staticExpanded?: true | undefined }) => { + const { uiConfig, isPro, isEnterprise } = useUiConfig(); + const { isBilling } = useInstanceStatus(); + const isActiveItem = (item?: string) => + item !== undefined && location.pathname === item; + const location = useLocation(); + + const routes = adminRoutes + .filter(filterByConfig(uiConfig)) + .filter((route) => + filterAdminRoutes(route?.menu, { + enterprise: isEnterprise(), + pro: isPro(), + billing: isBilling, + }), + ); + + const menuStructure = routes.reduce( + (acc: Record, route) => { + if (route.group && adminGroups[route.group]) { + if (!acc[route.group]) { + acc[route.group] = { + href: route.group, + text: adminGroups[route.group], + items: [], + }; + } + acc[route.group].items?.push({ + href: route.path, + text: route.title, + icon: , + }); + } + if (!route.group) { + acc[route.path] = { + href: route.path, + text: route.title, + }; + } + return acc; + }, + {}, + ); + + const items = Object.values(menuStructure); + return ( + + {items.map((item) => { + if (item.items) { + const isActiveMenu = item.items.find((itm) => + isActiveItem(itm.href), + ); + return ( + + } + activeIcon={ + + } + isActiveMenu={Boolean(isActiveMenu)} + key={item.text} + staticExpanded={staticExpanded} + > + {item.items.map((subItem) => ( + + + + ))} + + ); + } + return ( + + + + ); + })} + + ); +}; diff --git a/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx b/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx index 747bde2ecf..02e9947b02 100644 --- a/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx +++ b/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx @@ -1,4 +1,4 @@ -import type { ReactNode, VFC } from 'react'; +import type { VFC } from 'react'; import { Link } from 'react-router-dom'; import { Divider, Drawer, styled } from '@mui/material'; import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg'; @@ -8,6 +8,8 @@ import theme from 'themes/theme'; import { ThemeMode } from 'component/common/ThemeMode/ThemeMode'; import { MobileNavigationSidebar } from 'component/layout/MainLayout/NavigationSidebar/NavigationSidebar'; import { NewInUnleash } from 'component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash'; +import { useUiFlag } from 'hooks/useUiFlag'; +import { AdminMobileNavigation } from 'component/layout/MainLayout/AdminMenu/AdminNavigationItems'; const StyledDrawerHeader = styled('div')(({ theme }) => ({ display: 'flex', @@ -25,19 +27,18 @@ interface IDrawerMenuProps { title?: string; open?: boolean; toggleDrawer: () => void; - links: Array<{ - value: string; - icon: ReactNode; - href: string; - title: string; - }>; } export const DrawerMenu: VFC = ({ - links = [], open = false, toggleDrawer, }) => { + const newAdminUIEnabled = useUiFlag('adminNavUI'); + const showOnlyAdminMenu = + newAdminUIEnabled && location.pathname.indexOf('/admin') === 0; + const onClick = () => { + toggleDrawer(); + }; return ( = ({ - + {showOnlyAdminMenu ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/menu/Header/Header.tsx b/frontend/src/component/menu/Header/Header.tsx index afad324779..9157d6c7bf 100644 --- a/frontend/src/component/menu/Header/Header.tsx +++ b/frontend/src/component/menu/Header/Header.tsx @@ -118,11 +118,7 @@ const Header = () => { - +