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

feat: command bar search projects (#7388)

Now can search for projects.
Also adding debounce to not spam backend with requests. Also the UI is
less flickery.
This commit is contained in:
Jaanus Sellin 2024-06-13 14:47:34 +03:00 committed by GitHub
parent 3c56bfa992
commit 09d9676d66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 4 deletions

View File

@ -21,6 +21,8 @@ import {
CommandResultGroup, CommandResultGroup,
type CommandResultGroupItem, type CommandResultGroupItem,
} from './RecentlyVisited/CommandResultGroup'; } from './RecentlyVisited/CommandResultGroup';
import { useAsyncDebounce } from 'react-table';
import useProjects from 'hooks/api/getters/useProjects/useProjects';
export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ export const CommandResultsPaper = styled(Paper)(({ theme }) => ({
position: 'absolute', position: 'absolute',
@ -83,6 +85,9 @@ export const CommandBar = () => {
const searchInputRef = useRef<HTMLInputElement>(null); const searchInputRef = useRef<HTMLInputElement>(null);
const searchContainerRef = useRef<HTMLInputElement>(null); const searchContainerRef = useRef<HTMLInputElement>(null);
const [showSuggestions, setShowSuggestions] = useState(false); const [showSuggestions, setShowSuggestions] = useState(false);
const [searchedProjects, setSearchedProjects] = useState<
CommandResultGroupItem[]
>([]);
const { lastVisited } = useRecentlyVisited(); const { lastVisited } = useRecentlyVisited();
const hideSuggestions = () => { const hideSuggestions = () => {
setShowSuggestions(false); setShowSuggestions(false);
@ -90,8 +95,26 @@ export const CommandBar = () => {
const [value, setValue] = useState<string>(''); const [value, setValue] = useState<string>('');
const { features, setTableState } = useGlobalFeatureSearch(3);
const { projects } = useProjects();
const debouncedSetSearchState = useAsyncDebounce((query) => {
setTableState({ query });
const filteredProjects = projects.filter((project) =>
project.name.toLowerCase().includes(query.toLowerCase()),
);
const mappedProjects = filteredProjects.map((project) => ({
name: project.name,
link: `/projects/${project.id}`,
}));
setSearchedProjects(mappedProjects);
}, 200);
const onSearchChange = (value: string) => { const onSearchChange = (value: string) => {
setTableState({ query: value }); debouncedSetSearchState(value);
setValue(value); setValue(value);
}; };
@ -119,8 +142,6 @@ export const CommandBar = () => {
useOnClickOutside([searchContainerRef], hideSuggestions); useOnClickOutside([searchContainerRef], hideSuggestions);
useOnBlur(searchContainerRef, hideSuggestions); useOnBlur(searchContainerRef, hideSuggestions);
const { features, setTableState } = useGlobalFeatureSearch(3);
const flags: CommandResultGroupItem[] = features.map((feature) => ({ const flags: CommandResultGroupItem[] = features.map((feature) => ({
name: feature.name, name: feature.name,
link: `/projects/${feature.project}/features/${feature.name}`, link: `/projects/${feature.project}/features/${feature.name}`,
@ -181,6 +202,11 @@ export const CommandBar = () => {
icon={'flag'} icon={'flag'}
items={flags} items={flags}
/> />
<CommandResultGroup
groupName={'Projects'}
icon={'flag'}
items={searchedProjects}
/>
</CommandResultsPaper> </CommandResultsPaper>
} }
elseShow={ elseShow={

View File

@ -9,6 +9,8 @@ import {
} from '@mui/material'; } from '@mui/material';
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 { StyledProjectIcon } from '../../layout/MainLayout/NavigationSidebar/IconRenderer';
const listItemButtonStyle = (theme: Theme) => ({ const listItemButtonStyle = (theme: Theme) => ({
borderRadius: theme.spacing(0.5), borderRadius: theme.spacing(0.5),
@ -49,6 +51,10 @@ export const CommandResultGroup = ({
items, items,
}: CommandResultGroupProps) => { }: CommandResultGroupProps) => {
const slicedItems = items.slice(0, 3); const slicedItems = items.slice(0, 3);
if (items.length === 0) {
return null;
}
return ( return (
<> <>
<StyledTypography color='textSecondary'> <StyledTypography color='textSecondary'>
@ -64,7 +70,11 @@ export const CommandResultGroup = ({
sx={listItemButtonStyle} sx={listItemButtonStyle}
> >
<StyledListItemIcon> <StyledListItemIcon>
<Icon>{icon}</Icon> <ConditionallyRender
condition={groupName === 'Projects'}
show={<StyledProjectIcon />}
elseShow={<Icon>{icon}</Icon>}
/>
</StyledListItemIcon> </StyledListItemIcon>
<StyledListItemText> <StyledListItemText>
<Typography>{item.name}</Typography> <Typography>{item.name}</Typography>