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

feat: rename search page and change icon (#9706)

Behind flagsReleaseManagementUI flag
This commit is contained in:
Tymoteusz Czech 2025-04-07 15:49:44 +02:00 committed by GitHub
parent 5e35a0fa22
commit 1a85b46acc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 33 deletions

View File

@ -1,4 +1,4 @@
import type { ComponentProps, FC } from 'react'; import { useMemo, type ComponentProps, type FC } from 'react';
import EmptyIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined'; import EmptyIcon from '@mui/icons-material/CheckBoxOutlineBlankOutlined';
import type SvgIcon from '@mui/material/SvgIcon/SvgIcon'; import type SvgIcon from '@mui/material/SvgIcon/SvgIcon';
import ApplicationsIcon from '@mui/icons-material/AppsOutlined'; import ApplicationsIcon from '@mui/icons-material/AppsOutlined';
@ -34,6 +34,8 @@ import FactCheckOutlinedIcon from '@mui/icons-material/FactCheckOutlined';
import PersonalDashboardIcon from '@mui/icons-material/DashboardOutlined'; import PersonalDashboardIcon from '@mui/icons-material/DashboardOutlined';
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon'; import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
import PlaygroundIcon from '@mui/icons-material/AutoFixNormal'; import PlaygroundIcon from '@mui/icons-material/AutoFixNormal';
import FlagOutlinedIcon from '@mui/icons-material/FlagOutlined';
import { useUiFlag } from 'hooks/useUiFlag';
// TODO: move to routes // TODO: move to routes
const icons: Record< const icons: Record<
@ -85,12 +87,13 @@ const icons: Record<
Documentation: LibraryBooksIcon, Documentation: LibraryBooksIcon,
}; };
const findIcon = (key: string) => {
return icons[key] || EmptyIcon;
};
export const IconRenderer: FC<{ path: string }> = ({ path }) => { export const IconRenderer: FC<{ path: string }> = ({ path }) => {
const IconComponent = findIcon(path); // Fallback to 'default' if the type is not found const flagsReleaseManagementUI = useUiFlag('flagsReleaseManagementUI');
const IconComponent = useMemo(() => icons[path] || EmptyIcon, [path]); // Fallback to 'default' if the type is not found
if (flagsReleaseManagementUI && path === '/search') {
return <FlagOutlinedIcon />;
}
return <IconComponent />; return <IconComponent />;
}; };

View File

@ -13,18 +13,12 @@ import { Box, List, Typography } from '@mui/material';
import { useUiFlag } from 'hooks/useUiFlag'; import { useUiFlag } from 'hooks/useUiFlag';
import { IconRenderer } from './IconRenderer'; import { IconRenderer } from './IconRenderer';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import SearchIcon from '@mui/icons-material/Search';
import PlaygroundIcon from '@mui/icons-material/AutoFixNormal';
import InsightsIcon from '@mui/icons-material/Insights';
import PersonalDashboardIcon from '@mui/icons-material/DashboardOutlined';
import Accordion from '@mui/material/Accordion'; import Accordion from '@mui/material/Accordion';
import AccordionDetails from '@mui/material/AccordionDetails'; import AccordionDetails from '@mui/material/AccordionDetails';
import AccordionSummary from '@mui/material/AccordionSummary'; 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 { 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'; import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
import { useShowBadge } from 'component/layout/components/EnterprisePlanBadge/useShowBadge'; import { useShowBadge } from 'component/layout/components/EnterprisePlanBadge/useShowBadge';
import { EnterprisePlanBadge } from 'component/layout/components/EnterprisePlanBadge/EnterprisePlanBadge'; import { EnterprisePlanBadge } from 'component/layout/components/EnterprisePlanBadge/EnterprisePlanBadge';
@ -132,6 +126,7 @@ export const PrimaryNavigationList: FC<{
}> = ({ mode, onClick, activeItem }) => { }> = ({ mode, onClick, activeItem }) => {
const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem;
const { isOss } = useUiConfig(); const { isOss } = useUiConfig();
const flagsReleaseManagementUI = useUiFlag('flagsReleaseManagementUI');
return ( return (
<List> <List>
@ -141,7 +136,7 @@ export const PrimaryNavigationList: FC<{
onClick={() => onClick('/personal')} onClick={() => onClick('/personal')}
selected={activeItem === '/personal'} selected={activeItem === '/personal'}
> >
<PersonalDashboardIcon /> <IconRenderer path='/personal' />
</DynamicListItem> </DynamicListItem>
<DynamicListItem <DynamicListItem
@ -150,15 +145,15 @@ export const PrimaryNavigationList: FC<{
onClick={() => onClick('/projects')} onClick={() => onClick('/projects')}
selected={activeItem === '/projects'} selected={activeItem === '/projects'}
> >
<ProjectIcon /> <IconRenderer path='/projects' />
</DynamicListItem> </DynamicListItem>
<DynamicListItem <DynamicListItem
href='/search' href='/search'
text='Search' text={flagsReleaseManagementUI ? 'Flags overview' : 'Search'}
onClick={() => onClick('/search')} onClick={() => onClick('/search')}
selected={activeItem === '/search'} selected={activeItem === '/search'}
> >
<SearchIcon /> <IconRenderer path='/search' />
</DynamicListItem> </DynamicListItem>
<DynamicListItem <DynamicListItem
href='/playground' href='/playground'
@ -166,21 +161,18 @@ export const PrimaryNavigationList: FC<{
onClick={() => onClick('/playground')} onClick={() => onClick('/playground')}
selected={activeItem === '/playground'} selected={activeItem === '/playground'}
> >
<PlaygroundIcon /> <IconRenderer path='/playground' />
</DynamicListItem> </DynamicListItem>
<ConditionallyRender {!isOss() ? (
condition={!isOss()}
show={
<DynamicListItem <DynamicListItem
href='/insights' href='/insights'
text='Insights' text='Insights'
onClick={() => onClick('/insights')} onClick={() => onClick('/insights')}
selected={activeItem === '/insights'} selected={activeItem === '/insights'}
> >
<InsightsIcon /> <IconRenderer path='/insights' />
</DynamicListItem> </DynamicListItem>
} ) : null}
/>
</List> </List>
); );
}; };
@ -294,7 +286,7 @@ export const AdminSettingsLink: FC<{
text='Admin settings' text='Admin settings'
onClick={() => onClick('/admin')} onClick={() => onClick('/admin')}
> >
<SettingsIcon /> <IconRenderer path='/admin' />
</DynamicListItem> </DynamicListItem>
</List> </List>
</Box> </Box>

View File

@ -111,10 +111,21 @@ exports[`returns all baseRoutes 1`] = `
"menu": { "menu": {
"primary": true, "primary": true,
}, },
"notFlag": "flagsReleaseManagementUI",
"path": "/search", "path": "/search",
"title": "Search", "title": "Search",
"type": "protected", "type": "protected",
}, },
{
"component": [Function],
"flag": "flagsReleaseManagementUI",
"menu": {
"primary": true,
},
"path": "/search",
"title": "Flags overview",
"type": "protected",
},
{ {
"component": { "component": {
"$$typeof": Symbol(react.lazy), "$$typeof": Symbol(react.lazy),

View File

@ -137,13 +137,22 @@ export const routes: IRoute[] = [
menu: {}, menu: {},
}, },
// Features // Flags overview
{ {
path: '/search', path: '/search',
title: 'Search', title: 'Search',
component: FeatureToggleListTable, component: FeatureToggleListTable,
type: 'protected', type: 'protected',
menu: { primary: true }, menu: { primary: true },
notFlag: 'flagsReleaseManagementUI',
},
{
path: '/search',
title: 'Flags overview',
component: FeatureToggleListTable,
type: 'protected',
menu: { primary: true },
flag: 'flagsReleaseManagementUI',
}, },
// Playground // Playground

View File

@ -93,6 +93,7 @@ export type UiFlags = {
globalChangeRequestConfig?: boolean; globalChangeRequestConfig?: boolean;
addEditStrategy?: boolean; addEditStrategy?: boolean;
newStrategyDropdown?: boolean; newStrategyDropdown?: boolean;
flagsReleaseManagementUI?: boolean;
}; };
export interface IVersionInfo { export interface IVersionInfo {

View File

@ -67,7 +67,8 @@ export type IFlagKey =
| 'globalChangeRequestConfig' | 'globalChangeRequestConfig'
| 'addEditStrategy' | 'addEditStrategy'
| 'newStrategyDropdown' | 'newStrategyDropdown'
| 'flagsOverviewSearch'; | 'flagsOverviewSearch'
| 'flagsReleaseManagementUI';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
@ -324,6 +325,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_FLAGS_OVERVIEW_SEARCH, process.env.UNLEASH_EXPERIMENTAL_FLAGS_OVERVIEW_SEARCH,
false, false,
), ),
flagsReleaseManagementUI: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_FLAGS_RELEASE_MANAGEMENT_UI,
false,
),
}; };
export const defaultExperimentalOptions: IExperimentalOptions = { export const defaultExperimentalOptions: IExperimentalOptions = {