mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
chore: menu cleanups (#9792)
This commit is contained in:
parent
5ef33b56d6
commit
d406420223
@ -1,24 +0,0 @@
|
|||||||
import { styled } from '@mui/material';
|
|
||||||
import type { FC } from 'react';
|
|
||||||
import { NavLink } from 'react-router-dom';
|
|
||||||
|
|
||||||
const StyledNavLink = styled(NavLink)(({ theme }) => ({
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
textDecoration: 'none',
|
|
||||||
color: 'inherit',
|
|
||||||
padding: theme.spacing(0, 5),
|
|
||||||
'&.active': {
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const CenteredNavLink: FC<{
|
|
||||||
to: string;
|
|
||||||
children?: React.ReactNode;
|
|
||||||
}> = ({ to, children }) => {
|
|
||||||
return <StyledNavLink to={to}>{children}</StyledNavLink>;
|
|
||||||
};
|
|
@ -1,156 +0,0 @@
|
|||||||
import { Grid, styled, Paper, useMediaQuery, useTheme } from '@mui/material';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { Sticky } from 'component/common/Sticky/Sticky';
|
|
||||||
import { AdminMenuNavigation } from './AdminNavigationItems';
|
|
||||||
import { useNewAdminMenu } from '../../../../hooks/useNewAdminMenu';
|
|
||||||
|
|
||||||
const breakpointLgMinusPadding = 1250;
|
|
||||||
const breakpointLgMinusPaddingAdmin = 1550;
|
|
||||||
const breakpointXlMinusPadding = 1512;
|
|
||||||
const breakpointXlAdmin = 1812;
|
|
||||||
const breakpointXxl = 1856;
|
|
||||||
|
|
||||||
const MainLayoutContent = styled(Grid)(({ theme }) => ({
|
|
||||||
minWidth: 0, // this is a fix for overflowing flex
|
|
||||||
maxWidth: `${breakpointXlMinusPadding}px`,
|
|
||||||
margin: '0 auto',
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
paddingRight: theme.spacing(2),
|
|
||||||
[theme.breakpoints.up(breakpointXxl)]: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down(breakpointXxl)]: {
|
|
||||||
marginLeft: theme.spacing(7),
|
|
||||||
marginRight: theme.spacing(7),
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('lg')]: {
|
|
||||||
maxWidth: `${breakpointLgMinusPadding}px`,
|
|
||||||
paddingLeft: theme.spacing(1),
|
|
||||||
paddingRight: theme.spacing(1),
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down(1024)]: {
|
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 0,
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
minWidth: '100%',
|
|
||||||
},
|
|
||||||
minHeight: '94vh',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const AdminMainLayoutContent = styled(Grid)(({ theme }) => ({
|
|
||||||
minWidth: 0, // this is a fix for overflowing flex
|
|
||||||
maxWidth: `${breakpointXlMinusPadding}px`,
|
|
||||||
margin: '0 auto',
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
paddingRight: theme.spacing(2),
|
|
||||||
[theme.breakpoints.up(breakpointXxl)]: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down(breakpointXxl)]: {
|
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 0,
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('lg')]: {
|
|
||||||
maxWidth: `${breakpointLgMinusPadding}px`,
|
|
||||||
paddingLeft: theme.spacing(1),
|
|
||||||
paddingRight: theme.spacing(1),
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down(1024)]: {
|
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 0,
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
minWidth: '100%',
|
|
||||||
},
|
|
||||||
minHeight: '94vh',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledAdminMainGrid = styled(Grid)(({ theme }) => ({
|
|
||||||
minWidth: 0, // this is a fix for overflowing flex
|
|
||||||
maxWidth: `${breakpointXlAdmin}px`,
|
|
||||||
margin: '0 auto',
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
paddingRight: theme.spacing(2),
|
|
||||||
[theme.breakpoints.down('lg')]: {
|
|
||||||
maxWidth: `${breakpointLgMinusPaddingAdmin}px`,
|
|
||||||
paddingLeft: theme.spacing(1),
|
|
||||||
paddingRight: theme.spacing(1),
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down(1024)]: {
|
|
||||||
marginLeft: 0,
|
|
||||||
marginRight: 0,
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
minWidth: '100%',
|
|
||||||
},
|
|
||||||
minHeight: '94vh',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledMenuPaper = styled(Paper)(({ theme }) => ({
|
|
||||||
width: '100%',
|
|
||||||
minWidth: 320,
|
|
||||||
padding: theme.spacing(3),
|
|
||||||
marginTop: theme.spacing(6.5),
|
|
||||||
borderRadius: `${theme.shape.borderRadiusLarge}px`,
|
|
||||||
boxShadow: 'none',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StickyContainer = styled(Sticky)(({ theme }) => ({
|
|
||||||
position: 'sticky',
|
|
||||||
top: 0,
|
|
||||||
background: theme.palette.background.application,
|
|
||||||
transition: 'padding 0.3s ease',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IWrapIfAdminSubpageProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const WrapIfAdminSubpage = ({ children }: IWrapIfAdminSubpageProps) => {
|
|
||||||
const showOnlyAdminMenu = useNewAdminMenu();
|
|
||||||
const theme = useTheme();
|
|
||||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down('lg'));
|
|
||||||
const showAdminMenu = !isSmallScreen && showOnlyAdminMenu;
|
|
||||||
|
|
||||||
if (showAdminMenu) {
|
|
||||||
return (
|
|
||||||
<AdminMenu>
|
|
||||||
<AdminMainLayoutContent>{children}</AdminMainLayoutContent>
|
|
||||||
</AdminMenu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return <MainLayoutContent>{children}</MainLayoutContent>;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface IAdminMenuProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AdminMenu = ({ children }: IAdminMenuProps) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const isBreakpoint = useMediaQuery(theme.breakpoints.down(1352));
|
|
||||||
const breakpointedSize = isBreakpoint ? 8 : 9;
|
|
||||||
const onClick = () => {
|
|
||||||
scrollTo({
|
|
||||||
top: 0,
|
|
||||||
behavior: 'smooth',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledAdminMainGrid container spacing={1}>
|
|
||||||
<Grid item>
|
|
||||||
<StickyContainer>
|
|
||||||
<StyledMenuPaper>
|
|
||||||
<AdminMenuNavigation onClick={onClick} />
|
|
||||||
</StyledMenuPaper>
|
|
||||||
</StickyContainer>
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={breakpointedSize}>
|
|
||||||
{children}
|
|
||||||
</Grid>
|
|
||||||
</StyledAdminMainGrid>
|
|
||||||
);
|
|
||||||
};
|
|
@ -39,20 +39,6 @@
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigationLink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--drawer-link-inactive);
|
|
||||||
padding: var(--drawer-padding);
|
|
||||||
display: flex;
|
|
||||||
align-items: centre;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigationLinkActive {
|
|
||||||
background-color: var(--drawer-link-active-bg);
|
|
||||||
color: var(--drawer-link-active);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigationIcon {
|
.navigationIcon {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
fill: #635dc5;
|
fill: #635dc5;
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
import { ListItem, Link, styled } from '@mui/material';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { EnterpriseBadge } from 'component/common/EnterpriseBadge/EnterpriseBadge';
|
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
|
||||||
import type { INavigationMenuItem } from 'interfaces/route';
|
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
|
||||||
interface INavigationLinkProps {
|
|
||||||
path: string;
|
|
||||||
text: string;
|
|
||||||
handleClose: () => void;
|
|
||||||
mode?: INavigationMenuItem['menu']['mode'];
|
|
||||||
}
|
|
||||||
|
|
||||||
const StyledListItem = styled(ListItem)({
|
|
||||||
minWidth: '150px',
|
|
||||||
height: '100%',
|
|
||||||
width: '100%',
|
|
||||||
margin: '0',
|
|
||||||
padding: '0',
|
|
||||||
});
|
|
||||||
|
|
||||||
const StyledLink = styled(RouterLink)(({ theme }) => ({
|
|
||||||
textDecoration: 'none',
|
|
||||||
alignItems: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
color: 'inherit',
|
|
||||||
height: '100%',
|
|
||||||
width: '100%',
|
|
||||||
'&&': {
|
|
||||||
// Override MenuItem's built-in padding.
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
padding: theme.spacing(1, 2),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledSpan = styled('span')(({ theme }) => ({
|
|
||||||
width: '12.5px',
|
|
||||||
height: '12.5px',
|
|
||||||
display: 'block',
|
|
||||||
backgroundColor: theme.palette.primary.main,
|
|
||||||
marginRight: '1rem',
|
|
||||||
borderRadius: '2px',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledBadgeContainer = styled('div')(({ theme }) => ({
|
|
||||||
marginLeft: 'auto',
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
display: 'flex',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const NavigationLink = ({
|
|
||||||
path,
|
|
||||||
text,
|
|
||||||
handleClose,
|
|
||||||
...props
|
|
||||||
}: INavigationLinkProps) => {
|
|
||||||
const { isPro } = useUiConfig();
|
|
||||||
const showEnterpriseBadgeToPro = Boolean(
|
|
||||||
isPro() &&
|
|
||||||
!props.mode?.includes('pro') &&
|
|
||||||
props.mode?.includes('enterprise'),
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledListItem
|
|
||||||
onClick={() => {
|
|
||||||
handleClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
style={{ textDecoration: 'none' }}
|
|
||||||
component={StyledLink}
|
|
||||||
to={path}
|
|
||||||
underline='hover'
|
|
||||||
>
|
|
||||||
<StyledSpan />
|
|
||||||
{text}
|
|
||||||
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showEnterpriseBadgeToPro}
|
|
||||||
show={
|
|
||||||
<StyledBadgeContainer>
|
|
||||||
<EnterpriseBadge />
|
|
||||||
</StyledBadgeContainer>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
</StyledListItem>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NavigationLink;
|
|
@ -1,122 +0,0 @@
|
|||||||
import { Divider, Tooltip } from '@mui/material';
|
|
||||||
import { Menu, MenuItem, styled } from '@mui/material';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
|
||||||
import type { INavigationMenuItem } from 'interfaces/route';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { EnterpriseBadge } from '../../../common/EnterpriseBadge/EnterpriseBadge';
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
interface INavigationMenuProps {
|
|
||||||
options: INavigationMenuItem[];
|
|
||||||
id: string;
|
|
||||||
anchorEl: any;
|
|
||||||
handleClose: () => void;
|
|
||||||
style: Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
const StyledLink = styled(Link)(({ theme }) => ({
|
|
||||||
textDecoration: 'none',
|
|
||||||
alignItems: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
color: 'inherit',
|
|
||||||
height: '100%',
|
|
||||||
width: '100%',
|
|
||||||
'&&': {
|
|
||||||
// Override MenuItem's built-in padding.
|
|
||||||
padding: theme.spacing(1, 2),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledSpan = styled('span')(({ theme }) => ({
|
|
||||||
width: '12.5px',
|
|
||||||
height: '12.5px',
|
|
||||||
display: 'block',
|
|
||||||
backgroundColor: theme.palette.primary.main,
|
|
||||||
marginRight: theme.spacing(2),
|
|
||||||
borderRadius: '2px',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledBadgeContainer = styled('div')(({ theme }) => ({
|
|
||||||
marginLeft: 'auto',
|
|
||||||
paddingLeft: theme.spacing(2),
|
|
||||||
display: 'flex',
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const NavigationMenu = ({
|
|
||||||
options,
|
|
||||||
id,
|
|
||||||
handleClose,
|
|
||||||
anchorEl,
|
|
||||||
style,
|
|
||||||
}: INavigationMenuProps) => {
|
|
||||||
const { isPro, isOss } = useUiConfig();
|
|
||||||
|
|
||||||
const showBadge = useCallback(
|
|
||||||
(mode?: INavigationMenuItem['menu']['mode']) => {
|
|
||||||
if (
|
|
||||||
isPro() &&
|
|
||||||
!mode?.includes('pro') &&
|
|
||||||
mode?.includes('enterprise')
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
[isPro],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Menu
|
|
||||||
id={id}
|
|
||||||
onClose={handleClose}
|
|
||||||
anchorEl={anchorEl}
|
|
||||||
open={Boolean(anchorEl)}
|
|
||||||
style={style}
|
|
||||||
>
|
|
||||||
{options
|
|
||||||
.flatMap((option, i) => {
|
|
||||||
const previousGroup = options[i - 1]?.group;
|
|
||||||
const addDivider =
|
|
||||||
previousGroup &&
|
|
||||||
previousGroup !== option.group &&
|
|
||||||
(!isOss() || option.group === 'log');
|
|
||||||
|
|
||||||
return [
|
|
||||||
addDivider ? (
|
|
||||||
<Divider variant='middle' key={option.group} />
|
|
||||||
) : null,
|
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
showBadge(option?.menu?.mode)
|
|
||||||
? 'This is an Enterprise feature'
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
arrow
|
|
||||||
placement='left'
|
|
||||||
key={option.path}
|
|
||||||
>
|
|
||||||
<MenuItem
|
|
||||||
component={StyledLink}
|
|
||||||
to={option.path}
|
|
||||||
onClick={handleClose}
|
|
||||||
>
|
|
||||||
<StyledSpan />
|
|
||||||
{option.title}
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showBadge(option?.menu?.mode)}
|
|
||||||
show={
|
|
||||||
<StyledBadgeContainer>
|
|
||||||
<EnterpriseBadge />
|
|
||||||
</StyledBadgeContainer>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</MenuItem>
|
|
||||||
</Tooltip>,
|
|
||||||
];
|
|
||||||
})
|
|
||||||
.filter(Boolean)}
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user