diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx index 2f9a5bbe34..563c58e75b 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx @@ -43,6 +43,7 @@ import FlagTypesIcon from '@mui/icons-material/OutlinedFlag'; import EmptyIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined'; import CorsIcon from '@mui/icons-material/StorageOutlined'; import BillingIcon from '@mui/icons-material/CreditCardOutlined'; +import SignOutIcon from '@mui/icons-material/ExitToApp'; import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg'; import { type FC, @@ -60,6 +61,9 @@ import { EnterpriseBadge } from 'component/common/EnterpriseBadge/EnterpriseBadg import type { INavigationMenuItem } from 'interfaces/route'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; +import GitHubIcon from '@mui/icons-material/GitHub'; +import LibraryBooksIcon from '@mui/icons-material/LibraryBooks'; +import { basePath } from 'utils/formatPath'; export const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({ fill: theme.palette.neutral.main, @@ -83,14 +87,14 @@ const EnterprisePlanBadge = () => ( ); -const FullListItem: FC<{ href: string; text: string; badge?: ReactNode }> = ({ - href, - text, - badge, - children, -}) => { +const FullListItem: FC<{ + href: string; + text: string; + badge?: ReactNode; + onClick?: () => void; +}> = ({ href, text, badge, onClick, children }) => { return ( - + ({ minWidth: theme.spacing(4) })}> {children} @@ -102,6 +106,46 @@ const FullListItem: FC<{ href: string; text: string; badge?: ReactNode }> = ({ ); }; +const ExternalFullListItem: FC<{ href: string; text: string }> = ({ + href, + text, + children, +}) => { + return ( + + + ({ minWidth: theme.spacing(4) })}> + {children} + + + + + ); +}; + +const SignOutItem = () => { + return ( +
+ + + ({ minWidth: theme.spacing(4) })} + > + + + + + +
+ ); +}; + const MiniListItem: FC<{ href: string; text: string }> = ({ href, text, @@ -156,6 +200,8 @@ const icons: Record = { '/admin/cors': CorsIcon, '/admin/billing': BillingIcon, '/history': EventLogIcon, + GitHub: GitHubIcon, + Documentation: LibraryBooksIcon, }; const findIconByPath = (path: string) => { @@ -199,7 +245,7 @@ const ShowHide: FC<{ mode: 'full' | 'mini'; onChange: () => void }> = ({ }; const useRoutes = () => { - const { uiConfig, isPro } = useUiConfig(); + const { uiConfig } = useUiConfig(); const routes = getRoutes(); const adminRoutes = useAdminRoutes(); @@ -213,6 +259,12 @@ const useRoutes = () => { adminRoutes, }; + return { routes: filteredMainRoutes }; +}; + +const useShowBadge = () => { + const { isPro } = useUiConfig(); + const showBadge = useCallback( (mode?: INavigationMenuItem['menu']['mode']) => { return !!( @@ -223,8 +275,7 @@ const useRoutes = () => { }, [isPro], ); - - return { routes: filteredMainRoutes, showBadge }; + return showBadge; }; const useNavigationMode = () => { @@ -247,29 +298,137 @@ const useNavigationMode = () => { return [mode, setMode] as const; }; -export const NavigationSidebar = () => { - const { routes, showBadge } = useRoutes(); +const MainNavigationList: FC<{ mode: 'mini' | 'full'; onClick?: () => void }> = + ({ mode, onClick }) => { + const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; - const [mode, setMode] = useNavigationMode(); - - const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; - - return ( - + return ( - + - + - + - + + ); + }; + +const ConfigureNavigationList: FC<{ + routes: INavigationMenuItem[]; + mode: 'mini' | 'full'; + onClick?: () => void; +}> = ({ routes, mode, onClick }) => { + const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; + + return ( + + {routes.map((route) => ( + + + + ))} + + ); +}; + +const AdminNavigationList: FC<{ + routes: INavigationMenuItem[]; + mode: 'mini' | 'full'; + badge?: ReactNode; + onClick?: () => void; +}> = ({ routes, mode, onClick, badge }) => { + const showBadge = useShowBadge(); + const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; + + return ( + + {routes.map((route) => ( + + ) : null + } + > + + + ))} + + ); +}; + +const OtherLinksList = () => { + const { uiConfig } = useUiConfig(); + + return ( + + {uiConfig.links.map((link) => ( + + + + ))} + + + ); +}; + +export const MobileNavigationSidebar: FC<{ onClick: () => void }> = ({ + onClick, +}) => { + const { routes } = useRoutes(); + + return ( + <> + + + + + + ); +}; + +export const NavigationSidebar = () => { + const { routes } = useRoutes(); + + const [mode, setMode] = useNavigationMode(); + + return ( + + {mode === 'full' && ( { )} - - {routes.mainNavRoutes.map((route) => ( - - - - ))} - + @@ -313,21 +466,10 @@ export const NavigationSidebar = () => { )} - - {routes.adminRoutes.map((route) => ( - - ) : null - } - > - - - ))} - + ({ display: 'flex', @@ -48,6 +51,8 @@ export const DrawerMenu: VFC = ({ toggleDrawer, routes, }) => { + const sidebarNavigationEnabled = useUiFlag('navigationSidebar'); + const renderLinks = () => { return links.map((link) => { let icon = null; @@ -99,37 +104,50 @@ export const DrawerMenu: VFC = ({ - - {routes.mobileRoutes.map((item) => ( - toggleDrawer()} - path={item.path} - text={item.title} - key={item.path} - /> - ))} - - + } + elseShow={ + <> + + {routes.mobileRoutes.map((item) => ( + toggleDrawer()} + path={item.path} + text={item.title} + key={item.path} + /> + ))} + + - - {routes.adminRoutes.map((item) => ( - toggleDrawer()} - path={item.path} - text={item.title} - key={item.path} - mode={item.menu?.mode} - /> - ))} - - -
- {renderLinks()} - - - Sign out - -
+ + {routes.adminRoutes.map((item) => ( + toggleDrawer()} + path={item.path} + text={item.title} + key={item.path} + mode={item.menu?.mode} + /> + ))} + + +
+ {renderLinks()} + + + Sign out + +
+ + } + /> );