mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-17 01:17:29 +02:00
feat: command bar admin menu improvements (#9689)
This commit is contained in:
parent
6432262be5
commit
b9a7c0cda6
@ -1,16 +1,19 @@
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { adminRoutes } from './oldAdminRoutes';
|
||||
import { adminRoutes as oldAdminRoutes } from './oldAdminRoutes';
|
||||
import { adminRoutes } from './adminRoutes';
|
||||
import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus';
|
||||
import { filterAdminRoutes } from './filterAdminRoutes';
|
||||
import { filterByConfig, mapRouteLink } from 'component/common/util';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
|
||||
export const useAdminRoutes = () => {
|
||||
const newAdminUIEnabled = useUiFlag('adminNavUI');
|
||||
const { uiConfig, isPro, isEnterprise } = useUiConfig();
|
||||
const { isBilling } = useInstanceStatus();
|
||||
const routes = [...adminRoutes];
|
||||
const routes = newAdminUIEnabled ? [...adminRoutes] : [...oldAdminRoutes];
|
||||
|
||||
if (uiConfig.flags.UNLEASH_CLOUD) {
|
||||
const adminBillingMenuItem = adminRoutes.findIndex(
|
||||
const adminBillingMenuItem = routes.findIndex(
|
||||
(route) => route.title === 'Billing & invoices',
|
||||
);
|
||||
routes[adminBillingMenuItem] = {
|
||||
|
22
frontend/src/component/commandBar/ButtonItemIcon.tsx
Normal file
22
frontend/src/component/commandBar/ButtonItemIcon.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer';
|
||||
import InsightsIcon from '@mui/icons-material/Insights';
|
||||
import PlaygroundIcon from '@mui/icons-material/AutoFixNormal';
|
||||
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
||||
|
||||
export const ButtonItemIcon = ({
|
||||
path,
|
||||
}: {
|
||||
path: string;
|
||||
}) => {
|
||||
if (path === '/projects') {
|
||||
return <ProjectIcon />;
|
||||
}
|
||||
if (path === '/playground') {
|
||||
return <PlaygroundIcon />;
|
||||
}
|
||||
if (path === '/insights') {
|
||||
return <InsightsIcon />;
|
||||
}
|
||||
|
||||
return <IconRenderer path={path} />;
|
||||
};
|
@ -18,7 +18,6 @@ import {
|
||||
type CommandResultGroupItem,
|
||||
} from './RecentlyVisited/CommandResultGroup';
|
||||
import { CommandPageSuggestions } from './CommandPageSuggestions';
|
||||
import { useRoutes } from 'component/layout/MainLayout/NavigationSidebar/useRoutes';
|
||||
import { useAsyncDebounce } from 'react-table';
|
||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import {
|
||||
@ -31,6 +30,7 @@ import { CommandSearchPages } from './CommandSearchPages';
|
||||
import { CommandBarFeedback } from './CommandBarFeedback';
|
||||
import { RecentlyVisitedRecorder } from './RecentlyVisitedRecorder';
|
||||
import { ScreenReaderOnly } from 'component/common/ScreenReaderOnly/ScreenReaderOnly';
|
||||
import { useCommandBarRoutes } from './useCommandBarRoutes';
|
||||
|
||||
export const CommandResultsPaper = styled(Paper)(({ theme }) => ({
|
||||
position: 'absolute',
|
||||
@ -101,12 +101,6 @@ const StyledClose = styled(Close)(({ theme }) => ({
|
||||
fontSize: theme.typography.body1.fontSize,
|
||||
}));
|
||||
|
||||
interface IPageRouteInfo {
|
||||
path: string;
|
||||
route: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export const CommandBar = () => {
|
||||
const { trackEvent } = usePlausibleTracker();
|
||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||
@ -124,19 +118,7 @@ export const CommandBar = () => {
|
||||
useState<CommandQueryCounter>({ query: '', count: 0 });
|
||||
const [hasNoResults, setHasNoResults] = useState(false);
|
||||
const [value, setValue] = useState<string>('');
|
||||
const { routes } = useRoutes();
|
||||
const allRoutes: Record<string, IPageRouteInfo> = {};
|
||||
for (const route of [
|
||||
...routes.mainNavRoutes,
|
||||
...routes.adminRoutes,
|
||||
...routes.primaryRoutes,
|
||||
]) {
|
||||
allRoutes[route.path] = {
|
||||
path: route.path,
|
||||
route: route.route,
|
||||
title: route.title,
|
||||
};
|
||||
}
|
||||
const { allRoutes } = useCommandBarRoutes();
|
||||
|
||||
const hideSuggestions = () => {
|
||||
setShowSuggestions(false);
|
||||
@ -159,7 +141,7 @@ export const CommandBar = () => {
|
||||
setSearchedProjects(mappedProjects);
|
||||
|
||||
const filteredPages = Object.values(allRoutes).filter((route) =>
|
||||
route.title.toLowerCase().includes(query.toLowerCase()),
|
||||
route.searchText.toLowerCase().includes(query.toLowerCase()),
|
||||
);
|
||||
const mappedPages = filteredPages.map((page) => ({
|
||||
name: page.title,
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
type CommandResultGroupItem,
|
||||
} from './RecentlyVisited/CommandResultGroup';
|
||||
import { ListItemButton } from '@mui/material';
|
||||
import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer';
|
||||
import { ButtonItemIcon } from './ButtonItemIcon';
|
||||
|
||||
export const CommandSearchPages = ({
|
||||
items,
|
||||
@ -50,7 +50,7 @@ export const CommandSearchPages = ({
|
||||
sx={listItemButtonStyle}
|
||||
>
|
||||
<StyledListItemIcon>
|
||||
<IconRenderer path={item.link} />
|
||||
<ButtonItemIcon path={item.link} />
|
||||
</StyledListItemIcon>
|
||||
<StyledListItemText>
|
||||
<StyledButtonTypography color='textPrimary'>
|
||||
|
@ -10,14 +10,12 @@ import {
|
||||
import { Link } from 'react-router-dom';
|
||||
import type { Theme } from '@mui/material/styles/createTheme';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer';
|
||||
import InsightsIcon from '@mui/icons-material/Insights';
|
||||
import PlaygroundIcon from '@mui/icons-material/AutoFixNormal';
|
||||
import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver';
|
||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
||||
import { Children } from 'react';
|
||||
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
||||
import { ButtonItemIcon } from '../ButtonItemIcon';
|
||||
|
||||
export const listItemButtonStyle = (theme: Theme) => ({
|
||||
border: `1px solid transparent`,
|
||||
@ -48,24 +46,6 @@ export interface CommandResultGroupItem {
|
||||
description?: string | null;
|
||||
}
|
||||
|
||||
const ButtonItemIcon = ({
|
||||
path,
|
||||
}: {
|
||||
path: string;
|
||||
}) => {
|
||||
if (path === '/projects') {
|
||||
return <ProjectIcon />;
|
||||
}
|
||||
if (path === '/playground') {
|
||||
return <PlaygroundIcon />;
|
||||
}
|
||||
if (path === '/insights') {
|
||||
return <InsightsIcon />;
|
||||
}
|
||||
|
||||
return <IconRenderer path={path} />;
|
||||
};
|
||||
|
||||
export const RecentlyVisitedPathButton = ({
|
||||
keyName,
|
||||
path,
|
||||
|
55
frontend/src/component/commandBar/useCommandBarRoutes.ts
Normal file
55
frontend/src/component/commandBar/useCommandBarRoutes.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { adminGroups } from 'component/admin/adminRoutes';
|
||||
import { useRoutes } from 'component/layout/MainLayout/NavigationSidebar/useRoutes';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import type { INavigationMenuItem } from 'interfaces/route';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
interface IPageRouteInfo {
|
||||
path: string;
|
||||
route: string;
|
||||
title: string;
|
||||
searchText: string;
|
||||
}
|
||||
|
||||
export const useCommandBarRoutes = () => {
|
||||
const newAdminUIEnabled = useUiFlag('adminNavUI');
|
||||
const { routes } = useRoutes();
|
||||
const getSearchText = (route: INavigationMenuItem, title: string) => {
|
||||
if (route.group && adminGroups[route.group]) {
|
||||
return `${title} ${route.path} ${route.group} ${adminGroups[route.group]}`;
|
||||
}
|
||||
|
||||
return `${title} ${route.path}`;
|
||||
};
|
||||
|
||||
const getRouteTitle = (route: INavigationMenuItem) => {
|
||||
if (route.path === '/admin') {
|
||||
return 'Admin settings';
|
||||
}
|
||||
|
||||
return route.title;
|
||||
};
|
||||
return useMemo(() => {
|
||||
const allRoutes: Record<string, IPageRouteInfo> = {};
|
||||
for (const route of [
|
||||
...routes.mainNavRoutes,
|
||||
...routes.adminRoutes,
|
||||
...routes.primaryRoutes,
|
||||
]) {
|
||||
const title = getRouteTitle(route);
|
||||
allRoutes[route.path] = {
|
||||
path: route.path,
|
||||
route: route.route,
|
||||
title: title,
|
||||
searchText: newAdminUIEnabled
|
||||
? getSearchText(route, title)
|
||||
: title,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
allRoutes,
|
||||
newAdminUIEnabled,
|
||||
};
|
||||
}, [routes]);
|
||||
};
|
@ -13,7 +13,9 @@ import UsersIcon from '@mui/icons-material/GroupOutlined';
|
||||
import ServiceAccountIcon from '@mui/icons-material/Computer';
|
||||
import GroupsIcon from '@mui/icons-material/GroupsOutlined';
|
||||
import RoleIcon from '@mui/icons-material/AdminPanelSettingsOutlined';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import InsightsIcon from '@mui/icons-material/Insights';
|
||||
import ApiAccessIcon from '@mui/icons-material/KeyOutlined';
|
||||
import SingleSignOnIcon from '@mui/icons-material/AssignmentOutlined';
|
||||
import NetworkIcon from '@mui/icons-material/HubOutlined';
|
||||
@ -39,6 +41,7 @@ const icons: Record<
|
||||
typeof SvgIcon | FC<ComponentProps<typeof SvgIcon>>
|
||||
> = {
|
||||
'/search': SearchIcon,
|
||||
'/insights': InsightsIcon,
|
||||
'/applications': ApplicationsIcon,
|
||||
'/context': ContextFieldsIcon,
|
||||
'/feature-toggle-type': FlagTypesIcon,
|
||||
@ -47,13 +50,24 @@ const icons: Record<
|
||||
'/strategies': CustomStrategiesIcon,
|
||||
'/tag-types': TagTypesIcon,
|
||||
'/environments': EnvironmentsIcon,
|
||||
'/admin': SettingsIcon,
|
||||
'/admin/users': UsersIcon,
|
||||
'/admin/service-accounts': ServiceAccountIcon,
|
||||
'/admin/groups': GroupsIcon,
|
||||
'/admin/roles': RoleIcon,
|
||||
'/admin/roles/project-roles': RoleIcon,
|
||||
'/admin/api': ApiAccessIcon,
|
||||
'/admin/auth': SingleSignOnIcon,
|
||||
'/admin/auth/saml': SingleSignOnIcon,
|
||||
'/admin/auth/scim': SingleSignOnIcon,
|
||||
'/admin/auth/password': SingleSignOnIcon,
|
||||
'/admin/auth/google': SingleSignOnIcon,
|
||||
'/admin/network': NetworkIcon,
|
||||
'/admin/network/traffic': NetworkIcon,
|
||||
'/admin/network/data-usage': NetworkIcon,
|
||||
'/admin/network/frontend-data-usage': NetworkIcon,
|
||||
'/admin/network/connected-edges': NetworkIcon,
|
||||
'/admin/network/backend-connections': NetworkIcon,
|
||||
'/admin/maintenance': MaintenanceIcon,
|
||||
'/admin/banners': BannersIcon,
|
||||
'/admin/instance': InstanceStatsIcon,
|
||||
|
Loading…
Reference in New Issue
Block a user