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,9 +60,7 @@ export const CommandPageSuggestions = ({
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <StyledContainer>
 | 
					        <CommandResultGroup icon='pages' groupName='Pages'>
 | 
				
			||||||
            <StyledTypography color='textSecondary'>Pages</StyledTypography>
 | 
					 | 
				
			||||||
            <List>
 | 
					 | 
				
			||||||
            {pageItems.map((item, index) => (
 | 
					            {pageItems.map((item, index) => (
 | 
				
			||||||
                <ListItemButton
 | 
					                <ListItemButton
 | 
				
			||||||
                    key={`recently-visited-${index}`}
 | 
					                    key={`recently-visited-${index}`}
 | 
				
			||||||
@ -109,7 +74,6 @@ export const CommandPageSuggestions = ({
 | 
				
			|||||||
                >
 | 
					                >
 | 
				
			||||||
                    <StyledListItemIcon
 | 
					                    <StyledListItemIcon
 | 
				
			||||||
                        sx={(theme) => ({
 | 
					                        sx={(theme) => ({
 | 
				
			||||||
                                color: theme.palette.primary.main,
 | 
					 | 
				
			||||||
                            fontSize: theme.fontSizes.smallBody,
 | 
					                            fontSize: theme.fontSizes.smallBody,
 | 
				
			||||||
                            minWidth: theme.spacing(0.5),
 | 
					                            minWidth: theme.spacing(0.5),
 | 
				
			||||||
                            margin: theme.spacing(0, 1, 0, 0),
 | 
					                            margin: theme.spacing(0, 1, 0, 0),
 | 
				
			||||||
@ -124,7 +88,6 @@ export const CommandPageSuggestions = ({
 | 
				
			|||||||
                    </StyledListItemText>
 | 
					                    </StyledListItemText>
 | 
				
			||||||
                </ListItemButton>
 | 
					                </ListItemButton>
 | 
				
			||||||
            ))}
 | 
					            ))}
 | 
				
			||||||
            </List>
 | 
					        </CommandResultGroup>
 | 
				
			||||||
        </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