mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: Mini navigation sidebar (#7131)
This commit is contained in:
parent
4b68a0b3fd
commit
79ed56ecfc
@ -43,7 +43,13 @@ import EmptyIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined';
|
||||
import CorsIcon from '@mui/icons-material/StorageOutlined';
|
||||
import BillingIcon from '@mui/icons-material/CreditCardOutlined';
|
||||
import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg';
|
||||
import { type FC, type ReactNode, useCallback } from 'react';
|
||||
import {
|
||||
type FC,
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { getCondensedRoutes, getRoutes } from '../../../menu/routes';
|
||||
import { useAdminRoutes } from '../../../admin/useAdminRoutes';
|
||||
import { filterByConfig, mapRouteLink } from 'component/common/util';
|
||||
@ -74,7 +80,7 @@ const EnterprisePlanBadge = () => (
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
const StyledListItem: FC<{ href: string; text: string; badge?: ReactNode }> = ({
|
||||
const FullListItem: FC<{ href: string; text: string; badge?: ReactNode }> = ({
|
||||
href,
|
||||
text,
|
||||
badge,
|
||||
@ -93,6 +99,26 @@ const StyledListItem: FC<{ href: string; text: string; badge?: ReactNode }> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const MiniListItem: FC<{ href: string; text: string }> = ({
|
||||
href,
|
||||
text,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<ListItem disablePadding>
|
||||
<ListItemButton dense={true} component={Link} to={href}>
|
||||
<Tooltip title={text} placement='right'>
|
||||
<ListItemIcon
|
||||
sx={(theme) => ({ minWidth: theme.spacing(4) })}
|
||||
>
|
||||
{children}
|
||||
</ListItemIcon>
|
||||
</Tooltip>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
export const StyledBox = styled(Box)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
pt: theme.spacing(3),
|
||||
@ -166,62 +192,95 @@ const useRoutes = () => {
|
||||
return { routes: filteredMainRoutes, showBadge };
|
||||
};
|
||||
|
||||
const useNavigationMode = () => {
|
||||
const [mode, setMode] = useState<'mini' | 'full'>('full');
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'b' && (event.metaKey || event.ctrlKey)) {
|
||||
event.preventDefault();
|
||||
setMode(mode === 'mini' ? 'full' : 'mini');
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [mode]);
|
||||
|
||||
return mode;
|
||||
};
|
||||
|
||||
export const NavigationSidebar = () => {
|
||||
const { routes, showBadge } = useRoutes();
|
||||
|
||||
const mode = useNavigationMode();
|
||||
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
|
||||
return (
|
||||
<StyledBox>
|
||||
<List>
|
||||
<StyledListItem href='/projects' text='Projects'>
|
||||
<DynamicListItem href='/projects' text='Projects'>
|
||||
<StyledProjectIcon />
|
||||
</StyledListItem>
|
||||
<StyledListItem href='/search' text='Search'>
|
||||
</DynamicListItem>
|
||||
<DynamicListItem href='/search' text='Search'>
|
||||
<SearchIcon />
|
||||
</StyledListItem>
|
||||
<StyledListItem href='/playground' text='Playground'>
|
||||
</DynamicListItem>
|
||||
<DynamicListItem href='/playground' text='Playground'>
|
||||
<PlaygroundIcon />
|
||||
</StyledListItem>
|
||||
<StyledListItem href='/insights' text='Insights'>
|
||||
</DynamicListItem>
|
||||
<DynamicListItem href='/insights' text='Insights'>
|
||||
<InsightsIcon />
|
||||
</StyledListItem>
|
||||
</DynamicListItem>
|
||||
</List>
|
||||
<Accordion disableGutters={true} sx={{ boxShadow: 'none' }}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls='configure-content'
|
||||
id='configure-header'
|
||||
>
|
||||
<Typography sx={{ fontWeight: 'bold', fontSize: 'small' }}>
|
||||
Configure
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
{mode === 'full' && (
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls='configure-content'
|
||||
id='configure-header'
|
||||
>
|
||||
<Typography
|
||||
sx={{ fontWeight: 'bold', fontSize: 'small' }}
|
||||
>
|
||||
Configure
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
)}
|
||||
<AccordionDetails sx={{ p: 0 }}>
|
||||
<List>
|
||||
{routes.mainNavRoutes.map((route) => (
|
||||
<StyledListItem
|
||||
<DynamicListItem
|
||||
href={route.path}
|
||||
text={route.title}
|
||||
>
|
||||
<IconRenderer path={route.path} />
|
||||
</StyledListItem>
|
||||
</DynamicListItem>
|
||||
))}
|
||||
</List>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
<Accordion disableGutters={true} sx={{ boxShadow: 'none' }}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls='admin-content'
|
||||
id='admin-header'
|
||||
>
|
||||
<Typography sx={{ fontWeight: 'bold', fontSize: 'small' }}>
|
||||
Admin
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
{mode === 'full' && (
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls='admin-content'
|
||||
id='admin-header'
|
||||
>
|
||||
<Typography
|
||||
sx={{ fontWeight: 'bold', fontSize: 'small' }}
|
||||
>
|
||||
Admin
|
||||
</Typography>
|
||||
</AccordionSummary>
|
||||
)}
|
||||
|
||||
<AccordionDetails sx={{ p: 0 }}>
|
||||
<List>
|
||||
{routes.adminRoutes.map((route) => (
|
||||
<StyledListItem
|
||||
<DynamicListItem
|
||||
href={route.path}
|
||||
text={route.title}
|
||||
badge={
|
||||
@ -231,7 +290,7 @@ export const NavigationSidebar = () => {
|
||||
}
|
||||
>
|
||||
<IconRenderer path={route.path} />
|
||||
</StyledListItem>
|
||||
</DynamicListItem>
|
||||
))}
|
||||
</List>
|
||||
</AccordionDetails>
|
||||
|
Loading…
Reference in New Issue
Block a user