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:
parent
3c56bfa992
commit
09d9676d66
@ -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={
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user