mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: update configuration menu (#10041)
Updated "Configure" navigation, with all interactions including expanding/collapsing size of the menu.
This commit is contained in:
parent
e67e60a363
commit
016d82a797
@ -0,0 +1,77 @@
|
||||
import { type FC, useEffect, useState } from 'react';
|
||||
import { MenuListAccordion } from './ListItems.tsx';
|
||||
import { useExpanded } from './useExpanded.ts';
|
||||
import type { NavigationMode } from './NavigationMode.tsx';
|
||||
import { IconRenderer } from './IconRenderer.tsx';
|
||||
import { ConfigurationNavigationList } from './ConfigurationNavigationList.tsx';
|
||||
import { useRoutes } from './useRoutes.ts';
|
||||
|
||||
type ConfigurationAccordionProps = {
|
||||
mode: NavigationMode;
|
||||
setMode;
|
||||
activeItem?: string;
|
||||
onClick?: () => void;
|
||||
};
|
||||
|
||||
export const ConfigurationAccordion: FC<ConfigurationAccordionProps> = ({
|
||||
mode,
|
||||
setMode,
|
||||
activeItem,
|
||||
onClick,
|
||||
}) => {
|
||||
const [expanded, changeExpanded] = useExpanded<'configure'>();
|
||||
const [temporarilyExpanded, setTemporarilyExpanded] = useState(false);
|
||||
const { routes } = useRoutes();
|
||||
const subRoutes = routes.mainNavRoutes;
|
||||
const hasActiveItem = Boolean(
|
||||
activeItem && subRoutes.some((route) => route.path === activeItem),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode === 'mini') {
|
||||
setTemporarilyExpanded(false);
|
||||
}
|
||||
}, [mode]);
|
||||
|
||||
const onExpandChange = () => {
|
||||
changeExpanded('configure', !expanded.includes('configure'));
|
||||
|
||||
if (temporarilyExpanded) {
|
||||
setTemporarilyExpanded(false);
|
||||
setMode('mini');
|
||||
}
|
||||
if (mode === 'mini') {
|
||||
setTemporarilyExpanded(true);
|
||||
setMode('full');
|
||||
}
|
||||
};
|
||||
|
||||
const onItemClick = () => {
|
||||
if (temporarilyExpanded) {
|
||||
setTemporarilyExpanded(false);
|
||||
setMode('mini');
|
||||
}
|
||||
onClick?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<MenuListAccordion
|
||||
title='Configure'
|
||||
expanded={
|
||||
(expanded.includes('configure') || temporarilyExpanded) &&
|
||||
mode === 'full'
|
||||
}
|
||||
onExpandChange={onExpandChange}
|
||||
mode={mode}
|
||||
icon={<IconRenderer path='Configure' />}
|
||||
active={hasActiveItem}
|
||||
>
|
||||
<ConfigurationNavigationList
|
||||
routes={subRoutes}
|
||||
mode={mode}
|
||||
onClick={onItemClick}
|
||||
activeItem={activeItem}
|
||||
/>
|
||||
</MenuListAccordion>
|
||||
);
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
import type React from 'react';
|
||||
import type { FC } from 'react';
|
||||
import type { NavigationMode } from './NavigationMode.tsx';
|
||||
import type { NavigationMode } from './NavigationMode.ts';
|
||||
import { Typography } from '@mui/material';
|
||||
import Accordion from '@mui/material/Accordion';
|
||||
import AccordionDetails from '@mui/material/AccordionDetails';
|
||||
@ -21,7 +21,7 @@ const AccordionHeader: FC<{ children?: React.ReactNode }> = ({ children }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const SecondaryNavigation: FC<{
|
||||
export const ConfigurationNavigation: FC<{
|
||||
expanded: boolean;
|
||||
onExpandChange: (expanded: boolean) => void;
|
||||
mode: NavigationMode;
|
@ -1,7 +1,7 @@
|
||||
import type { FC } from 'react';
|
||||
import type { INavigationMenuItem } from 'interfaces/route';
|
||||
import type { NavigationMode } from './NavigationMode.tsx';
|
||||
import { FullListItem, MiniListItem } from './ListItems.tsx';
|
||||
import type { NavigationMode } from './NavigationMode.ts';
|
||||
import { MenuListItem } from './ListItems.tsx';
|
||||
import { List } from '@mui/material';
|
||||
import { IconRenderer } from './IconRenderer.tsx';
|
||||
import { useUiFlag } from 'hooks/useUiFlag.ts';
|
||||
@ -9,20 +9,19 @@ import StopRoundedIcon from '@mui/icons-material/StopRounded';
|
||||
import { useShowBadge } from 'component/layout/components/EnterprisePlanBadge/useShowBadge';
|
||||
import { EnterprisePlanBadge } from 'component/layout/components/EnterprisePlanBadge/EnterprisePlanBadge';
|
||||
|
||||
export const SecondaryNavigationList: FC<{
|
||||
export const ConfigurationNavigationList: FC<{
|
||||
routes: INavigationMenuItem[];
|
||||
mode: NavigationMode;
|
||||
onClick: (activeItem: string) => void;
|
||||
activeItem?: string;
|
||||
}> = ({ routes, mode, onClick, activeItem }) => {
|
||||
const showBadge = useShowBadge();
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
const sideMenuCleanup = useUiFlag('sideMenuCleanup');
|
||||
|
||||
return (
|
||||
<List>
|
||||
{routes.map((route) => (
|
||||
<DynamicListItem
|
||||
<MenuListItem
|
||||
key={route.title}
|
||||
onClick={() => onClick(route.path)}
|
||||
href={route.path}
|
||||
@ -33,13 +32,16 @@ export const SecondaryNavigationList: FC<{
|
||||
<EnterprisePlanBadge />
|
||||
) : null
|
||||
}
|
||||
>
|
||||
{sideMenuCleanup ? (
|
||||
mode={mode}
|
||||
icon={
|
||||
sideMenuCleanup ? (
|
||||
<StopRoundedIcon fontSize='small' color='primary' />
|
||||
) : (
|
||||
<IconRenderer path={route.path} />
|
||||
)}
|
||||
</DynamicListItem>
|
||||
)
|
||||
}
|
||||
secondary={sideMenuCleanup}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
);
|
@ -1,6 +1,8 @@
|
||||
import type React from 'react';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
ListItem,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
@ -13,6 +15,8 @@ import { Link } from 'react-router-dom';
|
||||
import { basePath } from 'utils/formatPath';
|
||||
import SignOutIcon from '@mui/icons-material/ExitToApp';
|
||||
import type { Theme } from '@mui/material/styles/createTheme';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import type { NavigationMode } from './NavigationMode.tsx';
|
||||
|
||||
const listItemButtonStyle = (theme: Theme) => ({
|
||||
borderRadius: theme.spacing(0.5),
|
||||
@ -22,12 +26,17 @@ const listItemButtonStyle = (theme: Theme) => ({
|
||||
},
|
||||
});
|
||||
|
||||
const CappedText = styled(Typography)({
|
||||
const CappedText = styled(Typography)<{
|
||||
bold?: boolean;
|
||||
}>(({ theme, bold }) => ({
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
width: '100%',
|
||||
});
|
||||
fontWeight: bold
|
||||
? theme.typography.fontWeightBold
|
||||
: theme.typography.fontWeightRegular,
|
||||
}));
|
||||
|
||||
const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({
|
||||
minWidth: theme.spacing(4),
|
||||
@ -38,37 +47,10 @@ const StyledListItemText = styled(ListItemText)(({ theme }) => ({
|
||||
margin: 0,
|
||||
}));
|
||||
|
||||
export const FullListItem: FC<{
|
||||
href: string;
|
||||
text: string;
|
||||
badge?: ReactNode;
|
||||
onClick: () => void;
|
||||
selected?: boolean;
|
||||
children?: React.ReactNode;
|
||||
}> = ({ href, text, badge, onClick, selected, children }) => {
|
||||
return (
|
||||
<ListItem disablePadding onClick={onClick}>
|
||||
<ListItemButton
|
||||
dense={true}
|
||||
component={Link}
|
||||
to={href}
|
||||
sx={listItemButtonStyle}
|
||||
selected={selected}
|
||||
>
|
||||
<StyledListItemIcon>{children}</StyledListItemIcon>
|
||||
<StyledListItemText>
|
||||
<CappedText>{text}</CappedText>
|
||||
</StyledListItemText>
|
||||
{badge}
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
export const ExternalFullListItem: FC<{
|
||||
href: string;
|
||||
text: string;
|
||||
children?: React.ReactNode;
|
||||
children?: ReactNode;
|
||||
}> = ({ href, text, children }) => {
|
||||
return (
|
||||
<ListItem disablePadding>
|
||||
@ -88,6 +70,7 @@ export const ExternalFullListItem: FC<{
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
export const SignOutItem = () => {
|
||||
return (
|
||||
<form method='POST' action={`${basePath}/logout`}>
|
||||
@ -110,26 +93,139 @@ export const SignOutItem = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const MiniListItem: FC<{
|
||||
export const MenuListItem: FC<{
|
||||
href: string;
|
||||
text: string;
|
||||
selected?: boolean;
|
||||
badge?: ReactNode;
|
||||
onClick: () => void;
|
||||
children?: React.ReactNode;
|
||||
}> = ({ href, text, selected, onClick, children }) => {
|
||||
icon?: ReactNode;
|
||||
children?: ReactNode;
|
||||
mode?: NavigationMode;
|
||||
secondary?: boolean;
|
||||
}> = ({
|
||||
href,
|
||||
text,
|
||||
selected,
|
||||
onClick,
|
||||
icon,
|
||||
mode = 'full',
|
||||
badge,
|
||||
children,
|
||||
secondary,
|
||||
}) => {
|
||||
return (
|
||||
<ListItem disablePadding onClick={onClick}>
|
||||
<ListItemButton
|
||||
dense={true}
|
||||
dense
|
||||
component={Link}
|
||||
to={href}
|
||||
sx={listItemButtonStyle}
|
||||
sx={(theme) => ({
|
||||
...listItemButtonStyle(theme),
|
||||
...(mode === 'full' &&
|
||||
secondary && {
|
||||
paddingLeft: theme.spacing(4),
|
||||
}),
|
||||
})}
|
||||
selected={selected}
|
||||
>
|
||||
{mode === 'mini' ? (
|
||||
<Tooltip title={text} placement='right'>
|
||||
<StyledListItemIcon>{children}</StyledListItemIcon>
|
||||
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<>
|
||||
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
||||
<StyledListItemText>
|
||||
<CappedText>{text}</CappedText>
|
||||
</StyledListItemText>
|
||||
{badge}
|
||||
</>
|
||||
)}
|
||||
</ListItemButton>
|
||||
{children}
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||
flexGrow: 1,
|
||||
'.MuiAccordionSummary-root': {
|
||||
minHeight: 'auto',
|
||||
borderRadius: theme.spacing(1),
|
||||
borderLeft: `${theme.spacing(0.5)} solid transparent`,
|
||||
margin: 0,
|
||||
paddingTop: theme.spacing(0.5),
|
||||
paddingBottom: theme.spacing(0.5),
|
||||
'.MuiAccordionSummary-content': { margin: 0 },
|
||||
'&>.MuiAccordionSummary-content.MuiAccordionSummary-content': {
|
||||
margin: '0',
|
||||
alignItems: 'center',
|
||||
},
|
||||
},
|
||||
'.MuiAccordionSummary-content': {
|
||||
margin: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
'.MuiAccordionSummary-expandIconWrapper': {
|
||||
position: 'absolute',
|
||||
right: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
export const MenuListAccordion: FC<{
|
||||
title: string;
|
||||
expanded: boolean;
|
||||
onExpandChange: (expanded: boolean) => void;
|
||||
children?: ReactNode;
|
||||
mode?: NavigationMode;
|
||||
icon?: ReactNode;
|
||||
active?: boolean;
|
||||
}> = ({ title, expanded, mode, icon, onExpandChange, children, active }) => {
|
||||
return (
|
||||
<ListItem disablePadding sx={{ display: 'flex' }}>
|
||||
<StyledAccordion
|
||||
disableGutters={true}
|
||||
sx={{
|
||||
boxShadow: 'none',
|
||||
'&:before': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
expanded={expanded}
|
||||
onChange={(_, expand) => {
|
||||
onExpandChange(expand);
|
||||
}}
|
||||
>
|
||||
<AccordionSummary
|
||||
sx={{ padding: 0 }}
|
||||
expandIcon={mode === 'full' ? <ExpandMoreIcon /> : null}
|
||||
>
|
||||
<ListItemButton
|
||||
dense
|
||||
sx={listItemButtonStyle}
|
||||
selected={active && mode === 'mini'}
|
||||
disableRipple
|
||||
>
|
||||
{mode === 'mini' ? (
|
||||
<Tooltip title={title} placement='right'>
|
||||
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<>
|
||||
<StyledListItemIcon>{icon}</StyledListItemIcon>
|
||||
<StyledListItemText>
|
||||
<CappedText bold={active}>
|
||||
{title}
|
||||
</CappedText>
|
||||
</StyledListItemText>
|
||||
</>
|
||||
)}
|
||||
</ListItemButton>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails sx={{ p: 0 }}>{children}</AccordionDetails>
|
||||
</StyledAccordion>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
@ -5,24 +5,32 @@ import {
|
||||
OtherLinksList,
|
||||
} from './NavigationList.tsx';
|
||||
import type { NewInUnleash } from './NewInUnleash/NewInUnleash.tsx';
|
||||
import { SecondaryNavigationList } from './SecondaryNavigationList.tsx';
|
||||
import { ConfigurationNavigationList } from './ConfigurationNavigationList.tsx';
|
||||
import { useRoutes } from './useRoutes.ts';
|
||||
import { useUiFlag } from 'hooks/useUiFlag.ts';
|
||||
|
||||
export const MobileNavigationSidebar: FC<{
|
||||
onClick: () => void;
|
||||
NewInUnleash?: typeof NewInUnleash;
|
||||
}> = ({ onClick, NewInUnleash }) => {
|
||||
const { routes } = useRoutes();
|
||||
const sideMenuCleanup = useUiFlag('sideMenuCleanup');
|
||||
|
||||
return (
|
||||
<>
|
||||
{NewInUnleash ? <NewInUnleash /> : null}
|
||||
<PrimaryNavigationList mode='full' onClick={onClick} />
|
||||
<SecondaryNavigationList
|
||||
<PrimaryNavigationList
|
||||
mode='full'
|
||||
onClick={onClick}
|
||||
setMode={() => {}}
|
||||
/>
|
||||
{!sideMenuCleanup ? (
|
||||
<ConfigurationNavigationList
|
||||
routes={routes.mainNavRoutes}
|
||||
mode='full'
|
||||
onClick={onClick}
|
||||
/>
|
||||
) : null}
|
||||
<AdminSettingsLink mode={'full'} onClick={onClick} />
|
||||
<OtherLinksList />
|
||||
</>
|
||||
|
@ -1,10 +1,9 @@
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentProps, FC } from 'react';
|
||||
import type { INavigationMenuItem } from 'interfaces/route';
|
||||
import type { NavigationMode } from './NavigationMode.tsx';
|
||||
import {
|
||||
ExternalFullListItem,
|
||||
FullListItem,
|
||||
MiniListItem,
|
||||
MenuListItem,
|
||||
SignOutItem,
|
||||
} from './ListItems.tsx';
|
||||
import { Box, List, Typography } from '@mui/material';
|
||||
@ -16,6 +15,7 @@ import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectO
|
||||
import { useNewAdminMenu } from 'hooks/useNewAdminMenu';
|
||||
import { AdminMenuNavigation } from '../AdminMenu/AdminNavigationItems.tsx';
|
||||
import { useUiFlag } from 'hooks/useUiFlag.ts';
|
||||
import { ConfigurationAccordion } from './ConfigurationAccordion.tsx';
|
||||
|
||||
export const OtherLinksList = () => {
|
||||
const { uiConfig } = useUiConfig();
|
||||
@ -36,105 +36,92 @@ export const OtherLinksList = () => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated remove with `sideMenuCleanup` flag
|
||||
*/
|
||||
export const RecentProjectsList: FC<{
|
||||
projectId: string;
|
||||
projectName: string;
|
||||
mode: NavigationMode;
|
||||
onClick: () => void;
|
||||
}> = ({ projectId, projectName, mode, onClick }) => {
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
|
||||
return (
|
||||
}> = ({ projectId, projectName, mode, onClick }) => (
|
||||
<List>
|
||||
<DynamicListItem
|
||||
<MenuListItem
|
||||
href={`/projects/${projectId}`}
|
||||
text={projectName}
|
||||
onClick={onClick}
|
||||
selected={false}
|
||||
>
|
||||
<ProjectIcon />
|
||||
</DynamicListItem>
|
||||
mode={mode}
|
||||
icon={<ProjectIcon />}
|
||||
/>
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated remove with `sideMenuCleanup` flag
|
||||
*/
|
||||
export const RecentFlagsList: FC<{
|
||||
flags: { featureId: string; projectId: string }[];
|
||||
mode: NavigationMode;
|
||||
onClick: () => void;
|
||||
}> = ({ flags, mode, onClick }) => {
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
|
||||
return (
|
||||
}> = ({ flags, mode, onClick }) => (
|
||||
<List>
|
||||
{flags.map((flag) => (
|
||||
<DynamicListItem
|
||||
<MenuListItem
|
||||
href={`/projects/${flag.projectId}/features/${flag.featureId}`}
|
||||
text={flag.featureId}
|
||||
onClick={onClick}
|
||||
selected={false}
|
||||
key={flag.featureId}
|
||||
>
|
||||
<FlagIcon />
|
||||
</DynamicListItem>
|
||||
mode={mode}
|
||||
icon={<FlagIcon />}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
export const PrimaryNavigationList: FC<{
|
||||
mode: NavigationMode;
|
||||
setMode: (mode: NavigationMode) => void;
|
||||
onClick: (activeItem: string) => void;
|
||||
activeItem?: string;
|
||||
}> = ({ mode, onClick, activeItem }) => {
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
}> = ({ mode, setMode, onClick, activeItem }) => {
|
||||
const PrimaryListItem = ({
|
||||
href,
|
||||
text,
|
||||
}: Pick<ComponentProps<typeof MenuListItem>, 'href' | 'text'>) => (
|
||||
<MenuListItem
|
||||
href={href}
|
||||
text={text}
|
||||
icon={<IconRenderer path={href} />}
|
||||
onClick={() => onClick(href)}
|
||||
selected={activeItem === href}
|
||||
mode={mode}
|
||||
/>
|
||||
);
|
||||
|
||||
const { isOss } = useUiConfig();
|
||||
const sideMenuCleanup = useUiFlag('sideMenuCleanup');
|
||||
|
||||
return (
|
||||
<List>
|
||||
<DynamicListItem
|
||||
href='/personal'
|
||||
text='Dashboard'
|
||||
onClick={() => onClick('/personal')}
|
||||
selected={activeItem === '/personal'}
|
||||
>
|
||||
<IconRenderer path='/personal' />
|
||||
</DynamicListItem>
|
||||
|
||||
<DynamicListItem
|
||||
href='/projects'
|
||||
text='Projects'
|
||||
onClick={() => onClick('/projects')}
|
||||
selected={activeItem === '/projects'}
|
||||
>
|
||||
<IconRenderer path='/projects' />
|
||||
</DynamicListItem>
|
||||
<DynamicListItem
|
||||
href='/search'
|
||||
text='Flags overview'
|
||||
onClick={() => onClick('/search')}
|
||||
selected={activeItem === '/search'}
|
||||
>
|
||||
<IconRenderer path='/search' />
|
||||
</DynamicListItem>
|
||||
<DynamicListItem
|
||||
href='/playground'
|
||||
text='Playground'
|
||||
onClick={() => onClick('/playground')}
|
||||
selected={activeItem === '/playground'}
|
||||
>
|
||||
<IconRenderer path='/playground' />
|
||||
</DynamicListItem>
|
||||
<PrimaryListItem href='/personal' text='Dashboard' />
|
||||
<PrimaryListItem href='/projects' text='Projects' />
|
||||
<PrimaryListItem href='/search' text='Flags overview' />
|
||||
<PrimaryListItem href='/playground' text='Playground' />
|
||||
{!isOss() ? (
|
||||
<DynamicListItem
|
||||
<PrimaryListItem
|
||||
href='/insights'
|
||||
text={sideMenuCleanup ? 'Analytics' : 'Insights'}
|
||||
onClick={() => onClick('/insights')}
|
||||
selected={activeItem === '/insights'}
|
||||
>
|
||||
<IconRenderer path='/insights' />
|
||||
</DynamicListItem>
|
||||
/>
|
||||
) : null}
|
||||
{sideMenuCleanup ? (
|
||||
<ConfigurationAccordion
|
||||
mode={mode}
|
||||
setMode={setMode}
|
||||
activeItem={activeItem}
|
||||
onClick={() => onClick('configure')}
|
||||
/>
|
||||
) : null}
|
||||
</List>
|
||||
);
|
||||
@ -173,22 +160,19 @@ export const AdminSettingsNavigation: FC<{
|
||||
export const AdminSettingsLink: FC<{
|
||||
mode: NavigationMode;
|
||||
onClick: (activeItem: string) => void;
|
||||
}> = ({ mode, onClick }) => {
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
return (
|
||||
}> = ({ mode, onClick }) => (
|
||||
<Box>
|
||||
<List>
|
||||
<DynamicListItem
|
||||
<MenuListItem
|
||||
href='/admin'
|
||||
text='Admin settings'
|
||||
onClick={() => onClick('/admin')}
|
||||
>
|
||||
<IconRenderer path='/admin' />
|
||||
</DynamicListItem>
|
||||
mode={mode}
|
||||
icon={<IconRenderer path='/admin' />}
|
||||
/>
|
||||
</List>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const RecentProjectsNavigation: FC<{
|
||||
mode: NavigationMode;
|
||||
|
@ -10,9 +10,8 @@ import {
|
||||
RecentProjectsNavigation,
|
||||
AdminSettingsNavigation,
|
||||
} from './NavigationList.tsx';
|
||||
import { SecondaryNavigationList } from './SecondaryNavigationList.tsx';
|
||||
import { SecondaryNavigation } from './SecondaryNavigation.tsx';
|
||||
import { FullListItem, MiniListItem } from './ListItems.tsx';
|
||||
import { ConfigurationNavigationList } from './ConfigurationNavigationList.tsx';
|
||||
import { ConfigurationNavigation } from './ConfigurationNavigation.tsx';
|
||||
import { useInitialPathname } from './useInitialPathname.ts';
|
||||
import { useLastViewedProject } from 'hooks/useLastViewedProject';
|
||||
import { useLastViewedFlags } from 'hooks/useLastViewedFlags';
|
||||
@ -105,7 +104,6 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({
|
||||
const { lastViewed: lastViewedFlags } = useLastViewedFlags();
|
||||
const showRecentFlags =
|
||||
!sideMenuCleanup && mode === 'full' && lastViewedFlags.length > 0;
|
||||
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||
|
||||
useEffect(() => {
|
||||
setActiveItem(initialPathname);
|
||||
@ -155,10 +153,12 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({
|
||||
<>
|
||||
<PrimaryNavigationList
|
||||
mode={mode}
|
||||
setMode={setMode}
|
||||
onClick={setActiveItem}
|
||||
activeItem={activeItem}
|
||||
/>
|
||||
<SecondaryNavigation
|
||||
{!sideMenuCleanup ? (
|
||||
<ConfigurationNavigation
|
||||
expanded={expanded.includes('configure')}
|
||||
onExpandChange={(expand) => {
|
||||
changeExpanded('configure', expand);
|
||||
@ -166,13 +166,14 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({
|
||||
mode={mode}
|
||||
title='Configure'
|
||||
>
|
||||
<SecondaryNavigationList
|
||||
<ConfigurationNavigationList
|
||||
routes={routes.mainNavRoutes}
|
||||
mode={mode}
|
||||
onClick={setActiveItem}
|
||||
activeItem={activeItem}
|
||||
/>
|
||||
</SecondaryNavigation>
|
||||
</ConfigurationNavigation>
|
||||
) : null}
|
||||
|
||||
<AdminSettingsNavigation
|
||||
onClick={setActiveItem}
|
||||
|
Loading…
Reference in New Issue
Block a user