mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: command bar refactor of search result items for consistent styling and icons (#7483)
This commit is contained in:
		
							parent
							
								
									d01aba955a
								
							
						
					
					
						commit
						bdce76e84a
					
				| @ -14,7 +14,6 @@ import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut'; | ||||
| import { SEARCH_INPUT } from 'utils/testIds'; | ||||
| import { useOnClickOutside } from 'hooks/useOnClickOutside'; | ||||
| import { useOnBlur } from 'hooks/useOnBlur'; | ||||
| import { CommandRecent } from './CommandRecent'; | ||||
| import { useRecentlyVisited } from 'hooks/useRecentlyVisited'; | ||||
| import { | ||||
|     CommandResultGroup, | ||||
| @ -26,6 +25,8 @@ import { useAsyncDebounce } from 'react-table'; | ||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||
| import { CommandFeatures } from './CommandFeatures'; | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| import { CommandRecent } from './CommandRecent'; | ||||
| import { CommandPages } from './CommandPages'; | ||||
| 
 | ||||
| export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ | ||||
|     position: 'absolute', | ||||
| @ -259,11 +260,7 @@ export const CommandBar = () => { | ||||
|                             icon={'flag'} | ||||
|                             items={searchedProjects} | ||||
|                         /> | ||||
|                         <CommandResultGroup | ||||
|                             groupName={'Pages'} | ||||
|                             icon={'flag'} | ||||
|                             items={searchedPages} | ||||
|                         /> | ||||
|                         <CommandPages items={searchedPages} /> | ||||
|                     </CommandResultsPaper> | ||||
|                 } | ||||
|                 elseShow={ | ||||
|  | ||||
| @ -1,49 +1,16 @@ | ||||
| import { | ||||
|     List, | ||||
|     ListItemButton, | ||||
|     ListItemIcon, | ||||
|     ListItemText, | ||||
|     styled, | ||||
|     Typography, | ||||
| } from '@mui/material'; | ||||
|     CommandResultGroup, | ||||
|     listItemButtonStyle, | ||||
|     StyledButtonTypography, | ||||
|     StyledListItemIcon, | ||||
|     StyledListItemText, | ||||
| } from './RecentlyVisited/CommandResultGroup'; | ||||
| import { ListItemButton } from '@mui/material'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||
| import type { Theme } from '@mui/material/styles/createTheme'; | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| import type { JSX } from 'react'; | ||||
| 
 | ||||
| const listItemButtonStyle = (theme: Theme) => ({ | ||||
|     border: `1px solid transparent`, | ||||
|     borderLeft: `${theme.spacing(0.5)} solid transparent`, | ||||
|     '&:hover': { | ||||
|         border: `1px solid ${theme.palette.primary.main}`, | ||||
|         borderLeft: `${theme.spacing(0.5)} solid ${theme.palette.primary.main}`, | ||||
|     }, | ||||
| }); | ||||
| 
 | ||||
| const StyledContainer = styled('div')(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(3), | ||||
| })); | ||||
| 
 | ||||
| const StyledButtonTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.smallerBody, | ||||
| })); | ||||
| 
 | ||||
| const StyledTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
|     padding: theme.spacing(0, 2.5), | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | ||||
|     minWidth: theme.spacing(4), | ||||
|     margin: theme.spacing(0.25, 0), | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
| })); | ||||
| 
 | ||||
| interface IPageSuggestionItem { | ||||
|     icon: JSX.Element; | ||||
|     name: string; | ||||
| @ -93,38 +60,34 @@ export const CommandPageSuggestions = ({ | ||||
|         }); | ||||
|     }; | ||||
|     return ( | ||||
|         <StyledContainer> | ||||
|             <StyledTypography color='textSecondary'>Pages</StyledTypography> | ||||
|             <List> | ||||
|                 {pageItems.map((item, index) => ( | ||||
|                     <ListItemButton | ||||
|                         key={`recently-visited-${index}`} | ||||
|                         dense={true} | ||||
|                         component={Link} | ||||
|                         to={item.path} | ||||
|                         onClick={() => { | ||||
|                             onClick(item); | ||||
|                         }} | ||||
|                         sx={listItemButtonStyle} | ||||
|         <CommandResultGroup icon='pages' groupName='Pages'> | ||||
|             {pageItems.map((item, index) => ( | ||||
|                 <ListItemButton | ||||
|                     key={`recently-visited-${index}`} | ||||
|                     dense={true} | ||||
|                     component={Link} | ||||
|                     to={item.path} | ||||
|                     onClick={() => { | ||||
|                         onClick(item); | ||||
|                     }} | ||||
|                     sx={listItemButtonStyle} | ||||
|                 > | ||||
|                     <StyledListItemIcon | ||||
|                         sx={(theme) => ({ | ||||
|                             fontSize: theme.fontSizes.smallBody, | ||||
|                             minWidth: theme.spacing(0.5), | ||||
|                             margin: theme.spacing(0, 1, 0, 0), | ||||
|                         })} | ||||
|                     > | ||||
|                         <StyledListItemIcon | ||||
|                             sx={(theme) => ({ | ||||
|                                 color: theme.palette.primary.main, | ||||
|                                 fontSize: theme.fontSizes.smallBody, | ||||
|                                 minWidth: theme.spacing(0.5), | ||||
|                                 margin: theme.spacing(0, 1, 0, 0), | ||||
|                             })} | ||||
|                         > | ||||
|                             {item.icon} | ||||
|                         </StyledListItemIcon> | ||||
|                         <StyledListItemText> | ||||
|                             <StyledButtonTypography color='textPrimary'> | ||||
|                                 {item.name} | ||||
|                             </StyledButtonTypography> | ||||
|                         </StyledListItemText> | ||||
|                     </ListItemButton> | ||||
|                 ))} | ||||
|             </List> | ||||
|         </StyledContainer> | ||||
|                         {item.icon} | ||||
|                     </StyledListItemIcon> | ||||
|                     <StyledListItemText> | ||||
|                         <StyledButtonTypography color='textPrimary'> | ||||
|                             {item.name} | ||||
|                         </StyledButtonTypography> | ||||
|                     </StyledListItemText> | ||||
|                 </ListItemButton> | ||||
|             ))} | ||||
|         </CommandResultGroup> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
							
								
								
									
										63
									
								
								frontend/src/component/commandBar/CommandPages.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								frontend/src/component/commandBar/CommandPages.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { | ||||
|     CommandResultGroup, | ||||
|     StyledButtonTypography, | ||||
|     StyledListItemIcon, | ||||
|     StyledListItemText, | ||||
|     listItemButtonStyle, | ||||
|     type CommandResultGroupItem, | ||||
| } from './RecentlyVisited/CommandResultGroup'; | ||||
| import { ListItemButton } from '@mui/material'; | ||||
| import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||
| 
 | ||||
| export const CommandPages = ({ | ||||
|     items, | ||||
| }: { | ||||
|     items: CommandResultGroupItem[]; | ||||
| }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
|     const groupName = 'Pages'; | ||||
| 
 | ||||
|     const onClick = (item: CommandResultGroupItem) => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'search', | ||||
|                 eventTarget: groupName, | ||||
|                 ...(groupName === 'Pages' && { pageType: item.name }), | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
|     return ( | ||||
|         <CommandResultGroup groupName={'Pages'} icon={'default'}> | ||||
|             {items.map((item, index) => ( | ||||
|                 <ListItemButton | ||||
|                     key={`command-result-group-pages-${index}`} | ||||
|                     dense={true} | ||||
|                     component={Link} | ||||
|                     to={item.link} | ||||
|                     onClick={() => { | ||||
|                         onClick(item); | ||||
|                     }} | ||||
|                     sx={listItemButtonStyle} | ||||
|                 > | ||||
|                     <StyledListItemIcon | ||||
|                         sx={(theme) => ({ | ||||
|                             fontSize: theme.fontSizes.smallBody, | ||||
|                             minWidth: theme.spacing(0.5), | ||||
|                             margin: theme.spacing(0, 1, 0, 0), | ||||
|                         })} | ||||
|                     > | ||||
|                         <IconRenderer path={item.link} /> | ||||
|                     </StyledListItemIcon> | ||||
|                     <StyledListItemText> | ||||
|                         <StyledButtonTypography color='textPrimary'> | ||||
|                             {item.name} | ||||
|                         </StyledButtonTypography> | ||||
|                     </StyledListItemText> | ||||
|                 </ListItemButton> | ||||
|             ))} | ||||
|         </CommandResultGroup> | ||||
|     ); | ||||
| }; | ||||
| @ -1,60 +1,11 @@ | ||||
| import { | ||||
|     Icon, | ||||
|     List, | ||||
|     ListItemButton, | ||||
|     ListItemIcon, | ||||
|     ListItemText, | ||||
|     styled, | ||||
|     Typography, | ||||
| } from '@mui/material'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { | ||||
|     IconRenderer, | ||||
|     StyledProjectIcon, | ||||
| } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||
|     CommandResultGroup, | ||||
|     RecentlyVisitedFeatureButton, | ||||
|     RecentlyVisitedPathButton, | ||||
|     RecentlyVisitedProjectButton, | ||||
| } from './RecentlyVisited/CommandResultGroup'; | ||||
| import { List } from '@mui/material'; | ||||
| import type { LastViewedPage } from 'hooks/useRecentlyVisited'; | ||||
| import type { Theme } from '@mui/material/styles/createTheme'; | ||||
| import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| 
 | ||||
| const listItemButtonStyle = (theme: Theme) => ({ | ||||
|     border: `1px solid transparent`, | ||||
|     borderLeft: `${theme.spacing(0.5)} solid transparent`, | ||||
|     '&:hover': { | ||||
|         border: `1px solid ${theme.palette.primary.main}`, | ||||
|         borderLeft: `${theme.spacing(0.5)} solid ${theme.palette.primary.main}`, | ||||
|     }, | ||||
| }); | ||||
| 
 | ||||
| const StyledContainer = styled('div')(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(3), | ||||
| })); | ||||
| 
 | ||||
| const StyledButtonTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.smallerBody, | ||||
| })); | ||||
| 
 | ||||
| const ColoredStyledProjectIcon = styled(StyledProjectIcon)(({ theme }) => ({ | ||||
|     fill: theme.palette.primary.main, | ||||
|     stroke: theme.palette.primary.main, | ||||
| })); | ||||
| 
 | ||||
| const StyledTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
|     padding: theme.spacing(0, 2.5), | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | ||||
|     minWidth: theme.spacing(0.5), | ||||
|     margin: theme.spacing(0, 1, 0, 0), | ||||
|     color: theme.palette.primary.main, | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     fontSize: theme.fontSizes.smallBody, | ||||
| })); | ||||
| 
 | ||||
| const toListItemButton = ( | ||||
|     item: LastViewedPage, | ||||
| @ -86,127 +37,6 @@ const toListItemButton = ( | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const RecentlyVisitedFeatureButton = ({ | ||||
|     key, | ||||
|     projectId, | ||||
|     featureId, | ||||
| }: { key: string; projectId: string; featureId: string }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
| 
 | ||||
|     const onClick = () => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Flags', | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             onClick={onClick} | ||||
|             to={`/projects/${projectId}/features/${featureId}`} | ||||
|             sx={listItemButtonStyle} | ||||
|         > | ||||
|             <StyledListItemIcon> | ||||
|                 <Icon>{'flag'}</Icon> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {featureId} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const RecentlyVisitedPathButton = ({ | ||||
|     path, | ||||
|     key, | ||||
|     name, | ||||
| }: { path: string; key: string; name: string }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
| 
 | ||||
|     const onClick = () => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Pages', | ||||
|                 pageType: name, | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             to={path} | ||||
|             onClick={onClick} | ||||
|             sx={listItemButtonStyle} | ||||
|         > | ||||
|             <StyledListItemIcon | ||||
|                 sx={(theme) => ({ color: theme.palette.primary.main })} | ||||
|             > | ||||
|                 <ConditionallyRender | ||||
|                     condition={path === '/projects'} | ||||
|                     show={<ColoredStyledProjectIcon />} | ||||
|                     elseShow={<IconRenderer path={path} />} | ||||
|                 /> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {name} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const RecentlyVisitedProjectButton = ({ | ||||
|     projectId, | ||||
|     key, | ||||
| }: { projectId: string; key: string }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
|     const { project, loading } = useProjectOverview(projectId); | ||||
|     const projectDeleted = !project.name && !loading; | ||||
| 
 | ||||
|     const onClick = () => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Projects', | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     if (projectDeleted) return null; | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             to={`/projects/${projectId}`} | ||||
|             onClick={onClick} | ||||
|             sx={listItemButtonStyle} | ||||
|         > | ||||
|             <StyledListItemIcon> | ||||
|                 <ColoredStyledProjectIcon /> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {project.name} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| export const CommandRecent = ({ | ||||
|     lastVisited, | ||||
|     routes, | ||||
| @ -218,11 +48,8 @@ export const CommandRecent = ({ | ||||
|         toListItemButton(item, routes, index), | ||||
|     ); | ||||
|     return ( | ||||
|         <StyledContainer> | ||||
|             <StyledTypography color='textSecondary'> | ||||
|                 Recently visited | ||||
|             </StyledTypography> | ||||
|         <CommandResultGroup icon='default' groupName='Quick suggestions'> | ||||
|             <List>{buttons}</List> | ||||
|         </StyledContainer> | ||||
|         </CommandResultGroup> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -10,30 +10,43 @@ import { | ||||
| import { Link } from 'react-router-dom'; | ||||
| import type { Theme } from '@mui/material/styles/createTheme'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StyledProjectIcon } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||
| import { | ||||
|     IconRenderer, | ||||
|     StyledProjectIcon, | ||||
| } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||
| import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver'; | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview'; | ||||
| 
 | ||||
| const listItemButtonStyle = (theme: Theme) => ({ | ||||
|     borderRadius: theme.spacing(0.5), | ||||
| export const listItemButtonStyle = (theme: Theme) => ({ | ||||
|     border: `1px solid transparent`, | ||||
|     borderLeft: `${theme.spacing(0.5)} solid transparent`, | ||||
|     '&.Mui-selected': { | ||||
|     '&:hover, &:focus': { | ||||
|         border: `1px solid ${theme.palette.primary.main}`, | ||||
|         borderLeft: `${theme.spacing(0.5)} solid ${theme.palette.primary.main}`, | ||||
|     }, | ||||
| }); | ||||
| const StyledContainer = styled('div')(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(3), | ||||
| })); | ||||
| 
 | ||||
| const StyledTypography = styled(Typography)(({ theme }) => ({ | ||||
| export const StyledTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.bodySize, | ||||
|     padding: theme.spacing(0, 3), | ||||
|     padding: theme.spacing(0, 2.5), | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | ||||
|     minWidth: theme.spacing(4), | ||||
|     margin: theme.spacing(0.25, 0), | ||||
| export const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | ||||
|     minWidth: theme.spacing(0.5), | ||||
|     margin: theme.spacing(0, 1, 0, 0), | ||||
| })); | ||||
| 
 | ||||
| const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | ||||
| export const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | ||||
|     margin: 0, | ||||
|     fontSize: theme.fontSizes.bodySize, | ||||
| })); | ||||
| 
 | ||||
| export const StyledButtonTypography = styled(Typography)(({ theme }) => ({ | ||||
|     fontSize: theme.fontSizes.bodySize, | ||||
| })); | ||||
| 
 | ||||
| export interface CommandResultGroupItem { | ||||
| @ -42,24 +55,150 @@ export interface CommandResultGroupItem { | ||||
|     description?: string | null; | ||||
| } | ||||
| 
 | ||||
| export const RecentlyVisitedPathButton = ({ | ||||
|     path, | ||||
|     key, | ||||
|     name, | ||||
| }: { path: string; key: string; name: string }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
| 
 | ||||
|     const onClick = () => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Pages', | ||||
|                 pageType: name, | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             to={path} | ||||
|             sx={listItemButtonStyle} | ||||
|             onClick={onClick} | ||||
|         > | ||||
|             <StyledListItemIcon> | ||||
|                 <ConditionallyRender | ||||
|                     condition={path === '/projects'} | ||||
|                     show={<StyledProjectIcon />} | ||||
|                     elseShow={<IconRenderer path={path} />} | ||||
|                 /> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {name} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| export const RecentlyVisitedProjectButton = ({ | ||||
|     projectId, | ||||
|     key, | ||||
| }: { projectId: string; key: string }) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
|     const { project, loading } = useProjectOverview(projectId); | ||||
|     const projectDeleted = !project.name && !loading; | ||||
| 
 | ||||
|     const onClick = () => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Projects', | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     if (projectDeleted) return null; | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             to={`/projects/${projectId}`} | ||||
|             sx={listItemButtonStyle} | ||||
|             onClick={onClick} | ||||
|         > | ||||
|             <StyledListItemIcon> | ||||
|                 <StyledProjectIcon /> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {project.name} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| export const RecentlyVisitedFeatureButton = ({ | ||||
|     key, | ||||
|     projectId, | ||||
|     featureId, | ||||
| }: { | ||||
|     key: string; | ||||
|     projectId: string; | ||||
|     featureId: string; | ||||
| }) => { | ||||
|     const onClick = () => { | ||||
|         const { trackEvent } = usePlausibleTracker(); | ||||
| 
 | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
|                 eventType: `click`, | ||||
|                 source: 'recently-visited', | ||||
|                 eventTarget: 'Flags', | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
|     return ( | ||||
|         <ListItemButton | ||||
|             key={key} | ||||
|             dense={true} | ||||
|             component={Link} | ||||
|             to={`/projects/${projectId}/features/${featureId}`} | ||||
|             sx={listItemButtonStyle} | ||||
|             onClick={onClick} | ||||
|         > | ||||
|             <StyledListItemIcon> | ||||
|                 <Icon>{'flag'}</Icon> | ||||
|             </StyledListItemIcon> | ||||
|             <StyledListItemText> | ||||
|                 <StyledButtonTypography color='textPrimary'> | ||||
|                     {featureId} | ||||
|                 </StyledButtonTypography> | ||||
|             </StyledListItemText> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| interface CommandResultGroupProps { | ||||
|     icon: string; | ||||
|     groupName: string; | ||||
|     items: CommandResultGroupItem[]; | ||||
|     items?: CommandResultGroupItem[]; | ||||
|     children?: React.ReactNode; | ||||
| } | ||||
| 
 | ||||
| export const CommandResultGroup = ({ | ||||
|     icon, | ||||
|     groupName, | ||||
|     items, | ||||
|     children, | ||||
| }: CommandResultGroupProps) => { | ||||
|     const { trackEvent } = usePlausibleTracker(); | ||||
|     const slicedItems = items.slice(0, 3); | ||||
| 
 | ||||
|     if (items.length === 0) { | ||||
|     if (!children && (!items || items.length === 0)) { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     const slicedItems = items?.slice(0, 3); | ||||
| 
 | ||||
|     const onClick = (item: CommandResultGroupItem) => { | ||||
|         trackEvent('command-bar', { | ||||
|             props: { | ||||
| @ -70,13 +209,15 @@ export const CommandResultGroup = ({ | ||||
|             }, | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <> | ||||
|         <StyledContainer> | ||||
|             <StyledTypography color='textSecondary'> | ||||
|                 {groupName} | ||||
|             </StyledTypography> | ||||
|             <List> | ||||
|                 {slicedItems.map((item, index) => ( | ||||
|                 {children} | ||||
|                 {slicedItems?.map((item, index) => ( | ||||
|                     <ListItemButton | ||||
|                         key={`command-result-group-${groupName}-${index}`} | ||||
|                         dense={true} | ||||
| @ -100,12 +241,14 @@ export const CommandResultGroup = ({ | ||||
|                             placement={'bottom-end'} | ||||
|                         > | ||||
|                             <StyledListItemText> | ||||
|                                 <Typography>{item.name}</Typography> | ||||
|                                 <StyledButtonTypography color='textPrimary'> | ||||
|                                     {item.name} | ||||
|                                 </StyledButtonTypography> | ||||
|                             </StyledListItemText> | ||||
|                         </TooltipResolver> | ||||
|                     </ListItemButton> | ||||
|                 ))} | ||||
|             </List> | ||||
|         </> | ||||
|         </StyledContainer> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user