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 { SEARCH_INPUT } from 'utils/testIds'; | ||||||
| import { useOnClickOutside } from 'hooks/useOnClickOutside'; | import { useOnClickOutside } from 'hooks/useOnClickOutside'; | ||||||
| import { useOnBlur } from 'hooks/useOnBlur'; | import { useOnBlur } from 'hooks/useOnBlur'; | ||||||
| import { CommandRecent } from './CommandRecent'; |  | ||||||
| import { useRecentlyVisited } from 'hooks/useRecentlyVisited'; | import { useRecentlyVisited } from 'hooks/useRecentlyVisited'; | ||||||
| import { | import { | ||||||
|     CommandResultGroup, |     CommandResultGroup, | ||||||
| @ -26,6 +25,8 @@ import { useAsyncDebounce } from 'react-table'; | |||||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||||
| import { CommandFeatures } from './CommandFeatures'; | import { CommandFeatures } from './CommandFeatures'; | ||||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||||
|  | import { CommandRecent } from './CommandRecent'; | ||||||
|  | import { CommandPages } from './CommandPages'; | ||||||
| 
 | 
 | ||||||
| export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ | export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ | ||||||
|     position: 'absolute', |     position: 'absolute', | ||||||
| @ -259,11 +260,7 @@ export const CommandBar = () => { | |||||||
|                             icon={'flag'} |                             icon={'flag'} | ||||||
|                             items={searchedProjects} |                             items={searchedProjects} | ||||||
|                         /> |                         /> | ||||||
|                         <CommandResultGroup |                         <CommandPages items={searchedPages} /> | ||||||
|                             groupName={'Pages'} |  | ||||||
|                             icon={'flag'} |  | ||||||
|                             items={searchedPages} |  | ||||||
|                         /> |  | ||||||
|                     </CommandResultsPaper> |                     </CommandResultsPaper> | ||||||
|                 } |                 } | ||||||
|                 elseShow={ |                 elseShow={ | ||||||
|  | |||||||
| @ -1,49 +1,16 @@ | |||||||
| import { | import { | ||||||
|     List, |     CommandResultGroup, | ||||||
|     ListItemButton, |     listItemButtonStyle, | ||||||
|     ListItemIcon, |     StyledButtonTypography, | ||||||
|     ListItemText, |     StyledListItemIcon, | ||||||
|     styled, |     StyledListItemText, | ||||||
|     Typography, | } from './RecentlyVisited/CommandResultGroup'; | ||||||
| } from '@mui/material'; | import { ListItemButton } from '@mui/material'; | ||||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||||
| import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; | ||||||
| import type { Theme } from '@mui/material/styles/createTheme'; |  | ||||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||||
| import type { JSX } from 'react'; | 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 { | interface IPageSuggestionItem { | ||||||
|     icon: JSX.Element; |     icon: JSX.Element; | ||||||
|     name: string; |     name: string; | ||||||
| @ -93,38 +60,34 @@ export const CommandPageSuggestions = ({ | |||||||
|         }); |         }); | ||||||
|     }; |     }; | ||||||
|     return ( |     return ( | ||||||
|         <StyledContainer> |         <CommandResultGroup icon='pages' groupName='Pages'> | ||||||
|             <StyledTypography color='textSecondary'>Pages</StyledTypography> |             {pageItems.map((item, index) => ( | ||||||
|             <List> |                 <ListItemButton | ||||||
|                 {pageItems.map((item, index) => ( |                     key={`recently-visited-${index}`} | ||||||
|                     <ListItemButton |                     dense={true} | ||||||
|                         key={`recently-visited-${index}`} |                     component={Link} | ||||||
|                         dense={true} |                     to={item.path} | ||||||
|                         component={Link} |                     onClick={() => { | ||||||
|                         to={item.path} |                         onClick(item); | ||||||
|                         onClick={() => { |                     }} | ||||||
|                             onClick(item); |                     sx={listItemButtonStyle} | ||||||
|                         }} |                 > | ||||||
|                         sx={listItemButtonStyle} |                     <StyledListItemIcon | ||||||
|  |                         sx={(theme) => ({ | ||||||
|  |                             fontSize: theme.fontSizes.smallBody, | ||||||
|  |                             minWidth: theme.spacing(0.5), | ||||||
|  |                             margin: theme.spacing(0, 1, 0, 0), | ||||||
|  |                         })} | ||||||
|                     > |                     > | ||||||
|                         <StyledListItemIcon |                         {item.icon} | ||||||
|                             sx={(theme) => ({ |                     </StyledListItemIcon> | ||||||
|                                 color: theme.palette.primary.main, |                     <StyledListItemText> | ||||||
|                                 fontSize: theme.fontSizes.smallBody, |                         <StyledButtonTypography color='textPrimary'> | ||||||
|                                 minWidth: theme.spacing(0.5), |                             {item.name} | ||||||
|                                 margin: theme.spacing(0, 1, 0, 0), |                         </StyledButtonTypography> | ||||||
|                             })} |                     </StyledListItemText> | ||||||
|                         > |                 </ListItemButton> | ||||||
|                             {item.icon} |             ))} | ||||||
|                         </StyledListItemIcon> |         </CommandResultGroup> | ||||||
|                         <StyledListItemText> |  | ||||||
|                             <StyledButtonTypography color='textPrimary'> |  | ||||||
|                                 {item.name} |  | ||||||
|                             </StyledButtonTypography> |  | ||||||
|                         </StyledListItemText> |  | ||||||
|                     </ListItemButton> |  | ||||||
|                 ))} |  | ||||||
|             </List> |  | ||||||
|         </StyledContainer> |  | ||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										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 { | import { | ||||||
|     Icon, |     CommandResultGroup, | ||||||
|     List, |     RecentlyVisitedFeatureButton, | ||||||
|     ListItemButton, |     RecentlyVisitedPathButton, | ||||||
|     ListItemIcon, |     RecentlyVisitedProjectButton, | ||||||
|     ListItemText, | } from './RecentlyVisited/CommandResultGroup'; | ||||||
|     styled, | import { List } from '@mui/material'; | ||||||
|     Typography, |  | ||||||
| } from '@mui/material'; |  | ||||||
| import { Link } from 'react-router-dom'; |  | ||||||
| import { |  | ||||||
|     IconRenderer, |  | ||||||
|     StyledProjectIcon, |  | ||||||
| } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; |  | ||||||
| import type { LastViewedPage } from 'hooks/useRecentlyVisited'; | 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 = ( | const toListItemButton = ( | ||||||
|     item: LastViewedPage, |     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 = ({ | export const CommandRecent = ({ | ||||||
|     lastVisited, |     lastVisited, | ||||||
|     routes, |     routes, | ||||||
| @ -218,11 +48,8 @@ export const CommandRecent = ({ | |||||||
|         toListItemButton(item, routes, index), |         toListItemButton(item, routes, index), | ||||||
|     ); |     ); | ||||||
|     return ( |     return ( | ||||||
|         <StyledContainer> |         <CommandResultGroup icon='default' groupName='Quick suggestions'> | ||||||
|             <StyledTypography color='textSecondary'> |  | ||||||
|                 Recently visited |  | ||||||
|             </StyledTypography> |  | ||||||
|             <List>{buttons}</List> |             <List>{buttons}</List> | ||||||
|         </StyledContainer> |         </CommandResultGroup> | ||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -10,30 +10,43 @@ import { | |||||||
| import { Link } from 'react-router-dom'; | import { Link } from 'react-router-dom'; | ||||||
| import type { Theme } from '@mui/material/styles/createTheme'; | import type { Theme } from '@mui/material/styles/createTheme'; | ||||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | 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 { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver'; | ||||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||||
|  | import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview'; | ||||||
| 
 | 
 | ||||||
| const listItemButtonStyle = (theme: Theme) => ({ | export const listItemButtonStyle = (theme: Theme) => ({ | ||||||
|     borderRadius: theme.spacing(0.5), |     border: `1px solid transparent`, | ||||||
|     borderLeft: `${theme.spacing(0.5)} 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}`, |         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, |     fontSize: theme.fontSizes.bodySize, | ||||||
|     padding: theme.spacing(0, 3), |     padding: theme.spacing(0, 2.5), | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | export const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ | ||||||
|     minWidth: theme.spacing(4), |     minWidth: theme.spacing(0.5), | ||||||
|     margin: theme.spacing(0.25, 0), |     margin: theme.spacing(0, 1, 0, 0), | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | export const StyledListItemText = styled(ListItemText)(({ theme }) => ({ | ||||||
|     margin: 0, |     margin: 0, | ||||||
|  |     fontSize: theme.fontSizes.bodySize, | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | export const StyledButtonTypography = styled(Typography)(({ theme }) => ({ | ||||||
|  |     fontSize: theme.fontSizes.bodySize, | ||||||
| })); | })); | ||||||
| 
 | 
 | ||||||
| export interface CommandResultGroupItem { | export interface CommandResultGroupItem { | ||||||
| @ -42,24 +55,150 @@ export interface CommandResultGroupItem { | |||||||
|     description?: string | null; |     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 { | interface CommandResultGroupProps { | ||||||
|     icon: string; |     icon: string; | ||||||
|     groupName: string; |     groupName: string; | ||||||
|     items: CommandResultGroupItem[]; |     items?: CommandResultGroupItem[]; | ||||||
|  |     children?: React.ReactNode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const CommandResultGroup = ({ | export const CommandResultGroup = ({ | ||||||
|     icon, |     icon, | ||||||
|     groupName, |     groupName, | ||||||
|     items, |     items, | ||||||
|  |     children, | ||||||
| }: CommandResultGroupProps) => { | }: CommandResultGroupProps) => { | ||||||
|     const { trackEvent } = usePlausibleTracker(); |     const { trackEvent } = usePlausibleTracker(); | ||||||
|     const slicedItems = items.slice(0, 3); |     if (!children && (!items || items.length === 0)) { | ||||||
| 
 |  | ||||||
|     if (items.length === 0) { |  | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const slicedItems = items?.slice(0, 3); | ||||||
|  | 
 | ||||||
|     const onClick = (item: CommandResultGroupItem) => { |     const onClick = (item: CommandResultGroupItem) => { | ||||||
|         trackEvent('command-bar', { |         trackEvent('command-bar', { | ||||||
|             props: { |             props: { | ||||||
| @ -70,13 +209,15 @@ export const CommandResultGroup = ({ | |||||||
|             }, |             }, | ||||||
|         }); |         }); | ||||||
|     }; |     }; | ||||||
|  | 
 | ||||||
|     return ( |     return ( | ||||||
|         <> |         <StyledContainer> | ||||||
|             <StyledTypography color='textSecondary'> |             <StyledTypography color='textSecondary'> | ||||||
|                 {groupName} |                 {groupName} | ||||||
|             </StyledTypography> |             </StyledTypography> | ||||||
|             <List> |             <List> | ||||||
|                 {slicedItems.map((item, index) => ( |                 {children} | ||||||
|  |                 {slicedItems?.map((item, index) => ( | ||||||
|                     <ListItemButton |                     <ListItemButton | ||||||
|                         key={`command-result-group-${groupName}-${index}`} |                         key={`command-result-group-${groupName}-${index}`} | ||||||
|                         dense={true} |                         dense={true} | ||||||
| @ -100,12 +241,14 @@ export const CommandResultGroup = ({ | |||||||
|                             placement={'bottom-end'} |                             placement={'bottom-end'} | ||||||
|                         > |                         > | ||||||
|                             <StyledListItemText> |                             <StyledListItemText> | ||||||
|                                 <Typography>{item.name}</Typography> |                                 <StyledButtonTypography color='textPrimary'> | ||||||
|  |                                     {item.name} | ||||||
|  |                                 </StyledButtonTypography> | ||||||
|                             </StyledListItemText> |                             </StyledListItemText> | ||||||
|                         </TooltipResolver> |                         </TooltipResolver> | ||||||
|                     </ListItemButton> |                     </ListItemButton> | ||||||
|                 ))} |                 ))} | ||||||
|             </List> |             </List> | ||||||
|         </> |         </StyledContainer> | ||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user