1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-17 01:17:29 +02:00

feat/admin menu reorganize (#4129)

## About the changes
<!-- Describe the changes introduced. What are they and why are they
being introduced? Feel free to also add screenshots or steps to view the
changes if they're visual. -->

Reorganizes the items in the menu to align with the tabs on the admin
page.
Also makes admin menu available to all users, they can get there anyways
when using API access link, and all admin-only pages are disabled for
non-admins.
Also adds API access to the mobile drawer menu, in accordance with how
the configure menu is laid out.
This commit is contained in:
David Leek 2023-07-03 13:36:49 +02:00 committed by GitHub
parent 6145d9d71e
commit aa7627bc0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 85 deletions

View File

@ -7,7 +7,6 @@ import ExitToApp from '@mui/icons-material/ExitToApp';
import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg'; import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg';
import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText.svg'; import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText.svg';
import NavigationLink from '../NavigationLink/NavigationLink'; import NavigationLink from '../NavigationLink/NavigationLink';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { basePath } from 'utils/formatPath'; import { basePath } from 'utils/formatPath';
import { IFlags } from 'interfaces/uiConfig'; import { IFlags } from 'interfaces/uiConfig';
import { INavigationMenuItem } from 'interfaces/route'; import { INavigationMenuItem } from 'interfaces/route';
@ -31,7 +30,6 @@ interface IDrawerMenuProps {
title?: string; title?: string;
open?: boolean; open?: boolean;
toggleDrawer: () => void; toggleDrawer: () => void;
admin?: boolean;
links: Array<{ links: Array<{
value: string; value: string;
icon: ReactNode; icon: ReactNode;
@ -51,7 +49,6 @@ export const DrawerMenu: VFC<IDrawerMenuProps> = ({
flags = {}, flags = {},
open = false, open = false,
toggleDrawer, toggleDrawer,
admin = false,
routes, routes,
}) => { }) => {
const renderLinks = () => { const renderLinks = () => {
@ -115,25 +112,18 @@ export const DrawerMenu: VFC<IDrawerMenuProps> = ({
/> />
))} ))}
</List> </List>
<ConditionallyRender <Divider />
condition={admin}
show={
<>
<Divider />
<List className={styles.drawerList}> <List className={styles.drawerList}>
{routes.adminRoutes.map(item => ( {routes.adminRoutes.map(item => (
<NavigationLink <NavigationLink
handleClose={() => toggleDrawer()} handleClose={() => toggleDrawer()}
path={item.path} path={item.path}
text={item.title} text={item.title}
key={item.path} key={item.path}
/> />
))} ))}
</List> </List>
</>
}
/>
<Divider /> <Divider />
<div className={styles.iconLinkList}> <div className={styles.iconLinkList}>
{renderLinks()} {renderLinks()}

View File

@ -1,4 +1,4 @@
import { useEffect, useState, VFC } from 'react'; import { useState, VFC } from 'react';
import useMediaQuery from '@mui/material/useMediaQuery'; import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles'; import { useTheme } from '@mui/material/styles';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -21,8 +21,6 @@ import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText
import { DrawerMenu } from './DrawerMenu/DrawerMenu'; import { DrawerMenu } from './DrawerMenu/DrawerMenu';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { flexRow, focusable } from 'themes/themeStyles'; import { flexRow, focusable } from 'themes/themeStyles';
import { ADMIN } from 'component/providers/AccessProvider/permissions';
import { IPermission } from 'interfaces/user';
import { NavigationMenu } from './NavigationMenu/NavigationMenu'; import { NavigationMenu } from './NavigationMenu/NavigationMenu';
import { import {
getRoutes, getRoutes,
@ -35,7 +33,6 @@ import {
LightModeOutlined, LightModeOutlined,
} from '@mui/icons-material'; } from '@mui/icons-material';
import { filterByConfig } from 'component/common/util'; import { filterByConfig } from 'component/common/util';
import { useAuthPermissions } from 'hooks/api/getters/useAuth/useAuthPermissions';
import { useId } from 'hooks/useId'; import { useId } from 'hooks/useId';
import { INavigationMenuItem } from 'interfaces/route'; import { INavigationMenuItem } from 'interfaces/route';
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode'; import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
@ -118,8 +115,6 @@ const Header: VFC = () => {
const [adminRef, setAdminRef] = useState<HTMLButtonElement | null>(null); const [adminRef, setAdminRef] = useState<HTMLButtonElement | null>(null);
const [configRef, setConfigRef] = useState<HTMLButtonElement | null>(null); const [configRef, setConfigRef] = useState<HTMLButtonElement | null>(null);
const [admin, setAdmin] = useState(false);
const { permissions } = useAuthPermissions();
const { uiConfig, isOss, isPro, isEnterprise } = useUiConfig(); const { uiConfig, isOss, isPro, isEnterprise } = useUiConfig();
const smallScreen = useMediaQuery(theme.breakpoints.down('md')); const smallScreen = useMediaQuery(theme.breakpoints.down('md'));
const [openDrawer, setOpenDrawer] = useState(false); const [openDrawer, setOpenDrawer] = useState(false);
@ -128,16 +123,6 @@ const Header: VFC = () => {
const onAdminClose = () => setAdminRef(null); const onAdminClose = () => setAdminRef(null);
const onConfigureClose = () => setConfigRef(null); const onConfigureClose = () => setConfigRef(null);
useEffect(() => {
const admin = permissions?.find(
(element: IPermission) => element.permission === ADMIN
);
if (admin) {
setAdmin(true);
}
}, [permissions]);
const routes = getRoutes(); const routes = getRoutes();
const filterByMode = (route: INavigationMenuItem): boolean => { const filterByMode = (route: INavigationMenuItem): boolean => {
@ -159,9 +144,15 @@ const Header: VFC = () => {
}, },
]) ])
.filter(filterByConfig(uiConfig)), .filter(filterByConfig(uiConfig)),
mobileRoutes: getCondensedRoutes(routes.mobileRoutes).filter( mobileRoutes: getCondensedRoutes(routes.mobileRoutes)
filterByConfig(uiConfig) .concat([
), {
path: '/admin/api',
title: 'API access',
menu: {},
},
])
.filter(filterByConfig(uiConfig)),
adminRoutes: adminMenuRoutes adminRoutes: adminMenuRoutes
.filter(filterByConfig(uiConfig)) .filter(filterByConfig(uiConfig))
.filter(filterByMode) .filter(filterByMode)
@ -191,7 +182,6 @@ const Header: VFC = () => {
links={uiConfig.links} links={uiConfig.links}
open={openDrawer} open={openDrawer}
toggleDrawer={toggleDrawer} toggleDrawer={toggleDrawer}
admin={admin}
routes={filteredMainRoutes} routes={filteredMainRoutes}
/> />
<StyledUserContainer> <StyledUserContainer>
@ -273,29 +263,18 @@ const Header: VFC = () => {
<MenuBookIcon /> <MenuBookIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<ConditionallyRender <Tooltip title="Settings" arrow>
condition={admin} <StyledIconButton
show={ onClick={e => setAdminRef(e.currentTarget)}
<Tooltip title="Settings" arrow> aria-controls={adminRef ? adminId : undefined}
<StyledIconButton aria-expanded={Boolean(adminRef)}
onClick={e => size="large"
setAdminRef(e.currentTarget) disableRipple
} >
aria-controls={ <SettingsIcon />
adminRef ? adminId : undefined <KeyboardArrowDown sx={styledIconProps} />
} </StyledIconButton>
aria-expanded={Boolean(adminRef)} </Tooltip>
size="large"
disableRipple
>
<SettingsIcon />
<KeyboardArrowDown
sx={styledIconProps}
/>
</StyledIconButton>
</Tooltip>
}
/>
<NavigationMenu <NavigationMenu
id={adminId} id={adminId}
options={filteredMainRoutes.adminRoutes} options={filteredMainRoutes.adminRoutes}

View File

@ -442,21 +442,16 @@ export const routes: IRoute[] = [
]; ];
export const adminMenuRoutes: INavigationMenuItem[] = [ export const adminMenuRoutes: INavigationMenuItem[] = [
{
path: '/history',
title: 'Event log',
menu: { adminSettings: true },
},
{
path: '/admin/logins',
title: 'Login history',
menu: { adminSettings: true, mode: ['enterprise'] },
},
{ {
path: '/admin/users', path: '/admin/users',
title: 'Users', title: 'Users',
menu: { adminSettings: true }, menu: { adminSettings: true },
}, },
{
path: '/admin/service-accounts',
title: 'Service accounts',
menu: { adminSettings: true, mode: ['enterprise'] },
},
{ {
path: '/admin/groups', path: '/admin/groups',
title: 'Groups', title: 'Groups',
@ -468,6 +463,12 @@ export const adminMenuRoutes: INavigationMenuItem[] = [
title: 'Roles', title: 'Roles',
menu: { adminSettings: true, mode: ['enterprise'] }, menu: { adminSettings: true, mode: ['enterprise'] },
}, },
{
path: '/admin/cors',
title: 'CORS origins',
flag: 'embedProxyFrontend',
menu: { adminSettings: true },
},
{ {
path: '/admin/auth', path: '/admin/auth',
title: 'Single sign-on', title: 'Single sign-on',
@ -478,11 +479,6 @@ export const adminMenuRoutes: INavigationMenuItem[] = [
title: 'Instance stats', title: 'Instance stats',
menu: { adminSettings: true }, menu: { adminSettings: true },
}, },
{
path: '/admin/service-accounts',
title: 'Service accounts',
menu: { adminSettings: true, mode: ['enterprise'] },
},
{ {
path: '/admin/network/*', path: '/admin/network/*',
title: 'Network', title: 'Network',
@ -494,12 +490,6 @@ export const adminMenuRoutes: INavigationMenuItem[] = [
title: 'Maintenance', title: 'Maintenance',
menu: { adminSettings: true }, menu: { adminSettings: true },
}, },
{
path: '/admin/cors',
title: 'CORS origins',
flag: 'embedProxyFrontend',
menu: { adminSettings: true },
},
{ {
path: '/admin/admin-invoices', path: '/admin/admin-invoices',
title: 'Billing & invoices', title: 'Billing & invoices',
@ -510,6 +500,16 @@ export const adminMenuRoutes: INavigationMenuItem[] = [
title: 'Instance privacy', title: 'Instance privacy',
menu: { adminSettings: true }, menu: { adminSettings: true },
}, },
{
path: '/history',
title: 'Event log',
menu: { adminSettings: true },
},
{
path: '/admin/logins',
title: 'Login history',
menu: { adminSettings: true, mode: ['enterprise'] },
},
]; ];
export const getRoute = (path: string) => export const getRoute = (path: string) =>