mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-27 01:19:00 +02: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