diff --git a/frontend/src/component/commandBar/CommandBar.tsx b/frontend/src/component/commandBar/CommandBar.tsx index eaed089848..388b6fd38a 100644 --- a/frontend/src/component/commandBar/CommandBar.tsx +++ b/frontend/src/component/commandBar/CommandBar.tsx @@ -21,6 +21,8 @@ import { CommandResultGroup, type CommandResultGroupItem, } from './RecentlyVisited/CommandResultGroup'; +import { useAsyncDebounce } from 'react-table'; +import useProjects from 'hooks/api/getters/useProjects/useProjects'; export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ position: 'absolute', @@ -83,6 +85,9 @@ export const CommandBar = () => { const searchInputRef = useRef(null); const searchContainerRef = useRef(null); const [showSuggestions, setShowSuggestions] = useState(false); + const [searchedProjects, setSearchedProjects] = useState< + CommandResultGroupItem[] + >([]); const { lastVisited } = useRecentlyVisited(); const hideSuggestions = () => { setShowSuggestions(false); @@ -90,8 +95,26 @@ export const CommandBar = () => { const [value, setValue] = useState(''); + 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) => { - setTableState({ query: value }); + debouncedSetSearchState(value); setValue(value); }; @@ -119,8 +142,6 @@ export const CommandBar = () => { useOnClickOutside([searchContainerRef], hideSuggestions); useOnBlur(searchContainerRef, hideSuggestions); - const { features, setTableState } = useGlobalFeatureSearch(3); - const flags: CommandResultGroupItem[] = features.map((feature) => ({ name: feature.name, link: `/projects/${feature.project}/features/${feature.name}`, @@ -181,6 +202,11 @@ export const CommandBar = () => { icon={'flag'} items={flags} /> + } elseShow={ diff --git a/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx index a42e02a040..6ae58c1376 100644 --- a/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx +++ b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx @@ -9,6 +9,8 @@ import { } from '@mui/material'; import { Link } from 'react-router-dom'; 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) => ({ borderRadius: theme.spacing(0.5), @@ -49,6 +51,10 @@ export const CommandResultGroup = ({ items, }: CommandResultGroupProps) => { const slicedItems = items.slice(0, 3); + + if (items.length === 0) { + return null; + } return ( <> @@ -64,7 +70,11 @@ export const CommandResultGroup = ({ sx={listItemButtonStyle} > - {icon} + } + elseShow={{icon}} + /> {item.name}