mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-18 01:18:23 +02:00
feat: navigation sidebar stub (#7121)
This commit is contained in:
parent
7937301424
commit
be6837b53a
@ -1,5 +1,5 @@
|
|||||||
import { forwardRef, type ReactNode } from 'react';
|
import { forwardRef, type ReactNode } from 'react';
|
||||||
import { Grid, styled } from '@mui/material';
|
import { Box, Grid, styled } from '@mui/material';
|
||||||
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';
|
||||||
@ -14,6 +14,8 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
|||||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
||||||
import { DraftBanner } from './DraftBanner/DraftBanner';
|
import { DraftBanner } from './DraftBanner/DraftBanner';
|
||||||
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
|
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
|
||||||
|
import { NavigationSidebar } from './NavigationSidebar/NavigationSidebar';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
|
||||||
interface IMainLayoutProps {
|
interface IMainLayoutProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -102,6 +104,7 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const StyledMainLayoutContent = SpaciousMainLayoutContent;
|
const StyledMainLayoutContent = SpaciousMainLayoutContent;
|
||||||
|
const sidebarNavigationEnabled = useUiFlag('navigationSidebar');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -117,13 +120,25 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
|||||||
)}
|
)}
|
||||||
show={<DraftBanner project={projectId || ''} />}
|
show={<DraftBanner project={projectId || ''} />}
|
||||||
/>
|
/>
|
||||||
<StyledMainLayoutContent item xs={12} sm={12} my={2}>
|
<Box sx={{ display: 'flex', mt: '2px' }}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={sidebarNavigationEnabled}
|
||||||
|
show={<NavigationSidebar />}
|
||||||
|
/>
|
||||||
|
<StyledMainLayoutContent
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
sm={12}
|
||||||
|
my={2}
|
||||||
|
>
|
||||||
<MainLayoutContentContainer ref={ref}>
|
<MainLayoutContentContainer ref={ref}>
|
||||||
<BreadcrumbNav />
|
<BreadcrumbNav />
|
||||||
<Proclamation toast={uiConfig.toast} />
|
<Proclamation toast={uiConfig.toast} />
|
||||||
{children}
|
{children}
|
||||||
</MainLayoutContentContainer>
|
</MainLayoutContentContainer>
|
||||||
</StyledMainLayoutContent>
|
</StyledMainLayoutContent>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<ThemeMode
|
<ThemeMode
|
||||||
darkmode={
|
darkmode={
|
||||||
<StyledImg
|
<StyledImg
|
||||||
|
@ -0,0 +1,218 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
List,
|
||||||
|
ListItem,
|
||||||
|
ListItemButton,
|
||||||
|
ListItemIcon,
|
||||||
|
ListItemText,
|
||||||
|
styled,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
import PlaygroundIcon from '@mui/icons-material/AutoFixNormal';
|
||||||
|
import InsightsIcon from '@mui/icons-material/Insights';
|
||||||
|
import Accordion from '@mui/material/Accordion';
|
||||||
|
import AccordionSummary from '@mui/material/AccordionSummary';
|
||||||
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
|
import AccordionDetails from '@mui/material/AccordionDetails';
|
||||||
|
import IntegrationsIcon from '@mui/icons-material/IntegrationInstructionsOutlined';
|
||||||
|
import EnvironmentsIcon from '@mui/icons-material/CloudOutlined';
|
||||||
|
import ContextFieldsIcon from '@mui/icons-material/AccountTreeOutlined';
|
||||||
|
import SegmentsIcon from '@mui/icons-material/DonutLargeOutlined';
|
||||||
|
import TagTypesIcon from '@mui/icons-material/LabelImportantOutlined';
|
||||||
|
import ApplicationsIcon from '@mui/icons-material/AppsOutlined';
|
||||||
|
import CustomStrategiesIcon from '@mui/icons-material/ExtensionOutlined';
|
||||||
|
import UsersIcon from '@mui/icons-material/GroupOutlined';
|
||||||
|
import ServiceAccountIcon from '@mui/icons-material/SmartToyOutlined';
|
||||||
|
import GroupsIcon from '@mui/icons-material/GroupsOutlined';
|
||||||
|
import RoleIcon from '@mui/icons-material/AdminPanelSettingsOutlined';
|
||||||
|
import ApiAccessIcon from '@mui/icons-material/KeyOutlined';
|
||||||
|
import SingleSignOnIcon from '@mui/icons-material/AssignmentOutlined';
|
||||||
|
import NetworkIcon from '@mui/icons-material/HubOutlined';
|
||||||
|
import MaintenanceIcon from '@mui/icons-material/BuildOutlined';
|
||||||
|
import BannersIcon from '@mui/icons-material/PhotoOutlined';
|
||||||
|
import InstanceStatsIcon from '@mui/icons-material/QueryStatsOutlined';
|
||||||
|
import LicenseIcon from '@mui/icons-material/ReceiptLongOutlined';
|
||||||
|
import InstancePrivacyIcon from '@mui/icons-material/ShieldOutlined';
|
||||||
|
import LoginHistoryIcon from '@mui/icons-material/HistoryOutlined';
|
||||||
|
import EventLogIcon from '@mui/icons-material/EventNoteOutlined';
|
||||||
|
import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
export const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({
|
||||||
|
fill: theme.palette.neutral.main,
|
||||||
|
stroke: theme.palette.neutral.main,
|
||||||
|
// same as built-in icons
|
||||||
|
width: theme.spacing(3),
|
||||||
|
height: theme.spacing(3),
|
||||||
|
fontSize: theme.spacing(3),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledListItem: FC<{ href: string; text: string }> = ({
|
||||||
|
href,
|
||||||
|
text,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton dense={true} component={Link} to={href}>
|
||||||
|
<ListItemIcon sx={(theme) => ({ minWidth: theme.spacing(4) })}>
|
||||||
|
{children}
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={text} />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const StyledBox = styled(Box)(({ theme }) => ({
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
pt: theme.spacing(3),
|
||||||
|
pb: theme.spacing(3),
|
||||||
|
minHeight: '95vh',
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const NavigationSidebar = () => {
|
||||||
|
return (
|
||||||
|
<StyledBox>
|
||||||
|
<List>
|
||||||
|
<StyledListItem href='/projects' text='Projects'>
|
||||||
|
<StyledProjectIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/search' text='Search'>
|
||||||
|
<SearchIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/playground' text='Playground'>
|
||||||
|
<PlaygroundIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/insights' text='Insights'>
|
||||||
|
<InsightsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
</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>
|
||||||
|
<AccordionDetails sx={{ p: 0 }}>
|
||||||
|
<List>
|
||||||
|
<StyledListItem
|
||||||
|
href='/integrations'
|
||||||
|
text='Integrations'
|
||||||
|
>
|
||||||
|
<IntegrationsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/environments'
|
||||||
|
text='Environments'
|
||||||
|
>
|
||||||
|
<EnvironmentsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/context' text='Context fields'>
|
||||||
|
<ContextFieldsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/segments' text='Segments'>
|
||||||
|
<SegmentsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/tag-types' text='Tag types'>
|
||||||
|
<TagTypesIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/applications'
|
||||||
|
text='Applications'
|
||||||
|
>
|
||||||
|
<ApplicationsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/strategies'
|
||||||
|
text='Custom strategies'
|
||||||
|
>
|
||||||
|
<CustomStrategiesIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
</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>
|
||||||
|
<AccordionDetails sx={{ p: 0 }}>
|
||||||
|
<List>
|
||||||
|
<StyledListItem href='/admin/users' text='Users'>
|
||||||
|
<UsersIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/service-accounts'
|
||||||
|
text='Service accounts'
|
||||||
|
>
|
||||||
|
<ServiceAccountIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/groups' text='Groups'>
|
||||||
|
<GroupsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/roles' text='Roles'>
|
||||||
|
<RoleIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/api' text='API Access'>
|
||||||
|
<ApiAccessIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/auth'
|
||||||
|
text='Single sign-on'
|
||||||
|
>
|
||||||
|
<SingleSignOnIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/network' text='Network'>
|
||||||
|
<NetworkIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/maintenance'
|
||||||
|
text='Maintenance'
|
||||||
|
>
|
||||||
|
<MaintenanceIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/banners' text='Banners'>
|
||||||
|
<BannersIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/instance'
|
||||||
|
text='Instance stats'
|
||||||
|
>
|
||||||
|
<InstanceStatsIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/admin/license' text='License'>
|
||||||
|
<LicenseIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/instance-privacy'
|
||||||
|
text='Instance privacy'
|
||||||
|
>
|
||||||
|
<InstancePrivacyIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem
|
||||||
|
href='/admin/logins'
|
||||||
|
text='Login history'
|
||||||
|
>
|
||||||
|
<LoginHistoryIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
<StyledListItem href='/history' text='Event log'>
|
||||||
|
<EventLogIcon />
|
||||||
|
</StyledListItem>
|
||||||
|
</List>
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion>
|
||||||
|
</StyledBox>
|
||||||
|
);
|
||||||
|
};
|
@ -87,6 +87,7 @@ export type UiFlags = {
|
|||||||
newCreateProjectUI?: boolean;
|
newCreateProjectUI?: boolean;
|
||||||
manyStrategiesPagination?: boolean;
|
manyStrategiesPagination?: boolean;
|
||||||
enableLegacyVariants?: boolean;
|
enableLegacyVariants?: boolean;
|
||||||
|
navigationSidebar?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IVersionInfo {
|
export interface IVersionInfo {
|
||||||
|
@ -135,6 +135,7 @@ exports[`should create default config 1`] = `
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"migrationLock": true,
|
"migrationLock": true,
|
||||||
|
"navigationSidebar": false,
|
||||||
"newCreateProjectUI": false,
|
"newCreateProjectUI": false,
|
||||||
"outdatedSdksBanner": false,
|
"outdatedSdksBanner": false,
|
||||||
"parseProjectFromSession": false,
|
"parseProjectFromSession": false,
|
||||||
|
@ -63,7 +63,8 @@ export type IFlagKey =
|
|||||||
| 'manyStrategiesPagination'
|
| 'manyStrategiesPagination'
|
||||||
| 'newCreateProjectUI'
|
| 'newCreateProjectUI'
|
||||||
| 'enableLegacyVariants'
|
| 'enableLegacyVariants'
|
||||||
| 'debugMetrics';
|
| 'debugMetrics'
|
||||||
|
| 'navigationSidebar';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -304,6 +305,10 @@ const flags: IFlags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_DEBUG_METRICS,
|
process.env.UNLEASH_EXPERIMENTAL_DEBUG_METRICS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
navigationSidebar: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_SIDEBAR_NAVIGATION,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -56,6 +56,7 @@ process.nextTick(async () => {
|
|||||||
createProjectWithEnvironmentConfig: true,
|
createProjectWithEnvironmentConfig: true,
|
||||||
manyStrategiesPagination: true,
|
manyStrategiesPagination: true,
|
||||||
enableLegacyVariants: false,
|
enableLegacyVariants: false,
|
||||||
|
navigationSidebar: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user