mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-31 01:16:01 +02:00
feat: rework navigation sidebar admin section (#9556)
This commit is contained in:
parent
bf34ac18fc
commit
35ed2dabf3
@ -1,5 +1,6 @@
|
|||||||
import { forwardRef, type ReactNode } from 'react';
|
import { forwardRef, type ReactNode } from 'react';
|
||||||
import { Box, Grid, styled, useMediaQuery, useTheme } from '@mui/material';
|
import { Box, Grid, styled, useMediaQuery, useTheme } from '@mui/material';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
import Header from 'component/menu/Header/Header';
|
import Header from 'component/menu/Header/Header';
|
||||||
import Footer from 'component/menu/Footer/Footer';
|
import Footer from 'component/menu/Footer/Footer';
|
||||||
import Proclamation from 'component/common/Proclamation/Proclamation';
|
import Proclamation from 'component/common/Proclamation/Proclamation';
|
||||||
@ -17,6 +18,7 @@ import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
|
|||||||
import { NavigationSidebar } from './NavigationSidebar/NavigationSidebar';
|
import { NavigationSidebar } from './NavigationSidebar/NavigationSidebar';
|
||||||
import { EventTimelineProvider } from 'component/events/EventTimeline/EventTimelineProvider';
|
import { EventTimelineProvider } from 'component/events/EventTimeline/EventTimelineProvider';
|
||||||
import { NewInUnleash } from './NavigationSidebar/NewInUnleash/NewInUnleash';
|
import { NewInUnleash } from './NavigationSidebar/NewInUnleash/NewInUnleash';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
|
||||||
interface IMainLayoutProps {
|
interface IMainLayoutProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -90,7 +92,9 @@ const MainLayoutContentContainer = styled('main')(({ theme }) => ({
|
|||||||
|
|
||||||
export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
||||||
({ children }, ref) => {
|
({ children }, ref) => {
|
||||||
|
const newAdminUIEnabled = useUiFlag('adminNavUI');
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
|
const location = useLocation();
|
||||||
const projectId = useOptionalPathParam('projectId');
|
const projectId = useOptionalPathParam('projectId');
|
||||||
const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled(
|
const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled(
|
||||||
projectId || '',
|
projectId || '',
|
||||||
@ -98,6 +102,10 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
|||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down('lg'));
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down('lg'));
|
||||||
|
const showOnlyAdminMenu =
|
||||||
|
newAdminUIEnabled && location.pathname.indexOf('/admin') === 0;
|
||||||
|
const showRegularNavigationSideBar =
|
||||||
|
!isSmallScreen && !showOnlyAdminMenu;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EventTimelineProvider>
|
<EventTimelineProvider>
|
||||||
@ -119,7 +127,7 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={!isSmallScreen}
|
condition={showRegularNavigationSideBar}
|
||||||
show={
|
show={
|
||||||
<NavigationSidebar
|
<NavigationSidebar
|
||||||
NewInUnleash={NewInUnleash}
|
NewInUnleash={NewInUnleash}
|
||||||
|
@ -2,6 +2,7 @@ import type React from 'react';
|
|||||||
import { type FC, useCallback } from 'react';
|
import { type FC, useCallback } from 'react';
|
||||||
import type { INavigationMenuItem } from 'interfaces/route';
|
import type { INavigationMenuItem } from 'interfaces/route';
|
||||||
import type { NavigationMode } from './NavigationMode';
|
import type { NavigationMode } from './NavigationMode';
|
||||||
|
import { ShowAdmin } from './ShowHide';
|
||||||
import {
|
import {
|
||||||
ExternalFullListItem,
|
ExternalFullListItem,
|
||||||
FullListItem,
|
FullListItem,
|
||||||
@ -9,6 +10,7 @@ import {
|
|||||||
SignOutItem,
|
SignOutItem,
|
||||||
} from './ListItems';
|
} from './ListItems';
|
||||||
import { Box, List, styled, Tooltip, Typography } from '@mui/material';
|
import { Box, List, styled, Tooltip, Typography } from '@mui/material';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
import { IconRenderer } from './IconRenderer';
|
import { IconRenderer } from './IconRenderer';
|
||||||
import { EnterpriseBadge } from 'component/common/EnterpriseBadge/EnterpriseBadge';
|
import { EnterpriseBadge } from 'component/common/EnterpriseBadge/EnterpriseBadge';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
@ -22,8 +24,9 @@ import AccordionSummary from '@mui/material/AccordionSummary';
|
|||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
import FlagIcon from '@mui/icons-material/OutlinedFlag';
|
import FlagIcon from '@mui/icons-material/OutlinedFlag';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
|
||||||
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
||||||
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
|
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
||||||
|
|
||||||
const StyledBadgeContainer = styled('div')(({ theme }) => ({
|
const StyledBadgeContainer = styled('div')(({ theme }) => ({
|
||||||
paddingLeft: theme.spacing(2),
|
paddingLeft: theme.spacing(2),
|
||||||
@ -251,6 +254,81 @@ export const SecondaryNavigation: FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const AdminSettingsNavigation: FC<{
|
||||||
|
onClick: (activeItem: string) => void;
|
||||||
|
onSetFullMode: () => void;
|
||||||
|
expanded: boolean;
|
||||||
|
routes: INavigationMenuItem[];
|
||||||
|
onExpandChange: (expanded: boolean) => void;
|
||||||
|
activeItem: string;
|
||||||
|
mode: NavigationMode;
|
||||||
|
}> = ({
|
||||||
|
onClick,
|
||||||
|
onSetFullMode,
|
||||||
|
expanded,
|
||||||
|
routes,
|
||||||
|
onExpandChange,
|
||||||
|
activeItem,
|
||||||
|
mode,
|
||||||
|
}) => {
|
||||||
|
const newAdminUIEnabled = useUiFlag('adminNavUI');
|
||||||
|
|
||||||
|
if (newAdminUIEnabled) {
|
||||||
|
return <AdminSettingsLink mode={mode} onClick={onClick} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{mode === 'full' && (
|
||||||
|
<SecondaryNavigation
|
||||||
|
expanded={expanded}
|
||||||
|
onExpandChange={(expand) => {
|
||||||
|
onExpandChange(expand);
|
||||||
|
}}
|
||||||
|
mode={mode}
|
||||||
|
title='Admin'
|
||||||
|
>
|
||||||
|
<SecondaryNavigationList
|
||||||
|
routes={routes}
|
||||||
|
mode={mode}
|
||||||
|
onClick={onClick}
|
||||||
|
activeItem={activeItem}
|
||||||
|
/>
|
||||||
|
</SecondaryNavigation>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{mode === 'mini' && (
|
||||||
|
<ShowAdmin
|
||||||
|
onChange={() => {
|
||||||
|
onExpandChange(true);
|
||||||
|
onSetFullMode();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AdminSettingsLink: FC<{
|
||||||
|
mode: NavigationMode;
|
||||||
|
onClick: (activeItem: string) => void;
|
||||||
|
}> = ({ mode, onClick }) => {
|
||||||
|
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<List>
|
||||||
|
<DynamicListItem
|
||||||
|
href='/admin'
|
||||||
|
text='Admin settings'
|
||||||
|
onClick={() => onClick('/admin')}
|
||||||
|
>
|
||||||
|
<SettingsIcon />
|
||||||
|
</DynamicListItem>
|
||||||
|
</List>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const RecentProjectsNavigation: FC<{
|
export const RecentProjectsNavigation: FC<{
|
||||||
mode: NavigationMode;
|
mode: NavigationMode;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Box, styled } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
import { type FC, useState, useEffect } from 'react';
|
import { type FC, useState, useEffect } from 'react';
|
||||||
import { useNavigationMode } from './useNavigationMode';
|
import { useNavigationMode } from './useNavigationMode';
|
||||||
import { ShowAdmin, ShowHide } from './ShowHide';
|
import { ShowHide } from './ShowHide';
|
||||||
import { useRoutes } from './useRoutes';
|
import { useRoutes } from './useRoutes';
|
||||||
import { useExpanded } from './useExpanded';
|
import { useExpanded } from './useExpanded';
|
||||||
import {
|
import {
|
||||||
@ -11,7 +11,9 @@ import {
|
|||||||
RecentProjectsNavigation,
|
RecentProjectsNavigation,
|
||||||
SecondaryNavigation,
|
SecondaryNavigation,
|
||||||
SecondaryNavigationList,
|
SecondaryNavigationList,
|
||||||
|
AdminSettingsNavigation,
|
||||||
} from './NavigationList';
|
} from './NavigationList';
|
||||||
|
import { FullListItem, MiniListItem } from './ListItems';
|
||||||
import { useInitialPathname } from './useInitialPathname';
|
import { useInitialPathname } from './useInitialPathname';
|
||||||
import { useLastViewedProject } from 'hooks/useLastViewedProject';
|
import { useLastViewedProject } from 'hooks/useLastViewedProject';
|
||||||
import { useLastViewedFlags } from 'hooks/useLastViewedFlags';
|
import { useLastViewedFlags } from 'hooks/useLastViewedFlags';
|
||||||
@ -115,6 +117,7 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({
|
|||||||
|
|
||||||
const { lastViewed: lastViewedFlags } = useLastViewedFlags();
|
const { lastViewed: lastViewedFlags } = useLastViewedFlags();
|
||||||
const showRecentFlags = mode === 'full' && lastViewedFlags.length > 0;
|
const showRecentFlags = mode === 'full' && lastViewedFlags.length > 0;
|
||||||
|
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActiveItem(initialPathname);
|
setActiveItem(initialPathname);
|
||||||
@ -178,32 +181,18 @@ export const NavigationSidebar: FC<{ NewInUnleash?: typeof NewInUnleash }> = ({
|
|||||||
activeItem={activeItem}
|
activeItem={activeItem}
|
||||||
/>
|
/>
|
||||||
</SecondaryNavigation>
|
</SecondaryNavigation>
|
||||||
{mode === 'full' && (
|
|
||||||
<SecondaryNavigation
|
|
||||||
expanded={expanded.includes('admin')}
|
|
||||||
onExpandChange={(expand) => {
|
|
||||||
changeExpanded('admin', expand);
|
|
||||||
}}
|
|
||||||
mode={mode}
|
|
||||||
title='Admin'
|
|
||||||
>
|
|
||||||
<SecondaryNavigationList
|
|
||||||
routes={routes.adminRoutes}
|
|
||||||
mode={mode}
|
|
||||||
onClick={setActiveItem}
|
|
||||||
activeItem={activeItem}
|
|
||||||
/>
|
|
||||||
</SecondaryNavigation>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{mode === 'mini' && (
|
<AdminSettingsNavigation
|
||||||
<ShowAdmin
|
onClick={setActiveItem}
|
||||||
onChange={() => {
|
mode={mode}
|
||||||
changeExpanded('admin', true);
|
onSetFullMode={() => setMode('full')}
|
||||||
setMode('full');
|
activeItem={activeItem}
|
||||||
}}
|
onExpandChange={(expand) => {
|
||||||
/>
|
changeExpanded('admin', expand);
|
||||||
)}
|
}}
|
||||||
|
expanded={expanded.includes('admin')}
|
||||||
|
routes={routes.adminRoutes}
|
||||||
|
/>
|
||||||
|
|
||||||
{showRecentProject && (
|
{showRecentProject && (
|
||||||
<RecentProjectsNavigation
|
<RecentProjectsNavigation
|
||||||
|
@ -58,7 +58,7 @@ process.nextTick(async () => {
|
|||||||
filterExistingFlagNames: true,
|
filterExistingFlagNames: true,
|
||||||
teamsIntegrationChangeRequests: true,
|
teamsIntegrationChangeRequests: true,
|
||||||
simplifyDisableFeature: true,
|
simplifyDisableFeature: true,
|
||||||
adminNavUI: true,
|
adminNavUI: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user