From 21088b745d641b6b5b3f3dc205107f6918bc3ed0 Mon Sep 17 00:00:00 2001 From: Jaanus Sellin Date: Wed, 12 Jun 2024 21:24:22 +0300 Subject: [PATCH] feat: search features from command bar (#7378) Now searching works in command bar 1. Currently piggybacking on the search hook, but I think it is not fast enough, and also it is using the query params as the global search. This causes some weird behaviour in UI. This probably means we will create separate endpoint for this. ![image](https://github.com/Unleash/unleash/assets/964450/a24f41ae-93d7-4ebe-a92b-c20dfe7cb666) --- .../src/component/commandBar/CommandBar.tsx | 21 ++++- .../RecentlyVisited/CommandResultGroup.tsx | 77 +++++++++++++++++++ .../useGlobalFeatureSearch.ts | 5 +- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx diff --git a/frontend/src/component/commandBar/CommandBar.tsx b/frontend/src/component/commandBar/CommandBar.tsx index 049b48002d..eaed089848 100644 --- a/frontend/src/component/commandBar/CommandBar.tsx +++ b/frontend/src/component/commandBar/CommandBar.tsx @@ -16,6 +16,11 @@ import { useOnClickOutside } from 'hooks/useOnClickOutside'; import { useOnBlur } from 'hooks/useOnBlur'; import { RecentlyVisited } from './RecentlyVisited/RecentlyVisited'; import { useRecentlyVisited } from 'hooks/useRecentlyVisited'; +import { useGlobalFeatureSearch } from '../feature/FeatureToggleList/useGlobalFeatureSearch'; +import { + CommandResultGroup, + type CommandResultGroupItem, +} from './RecentlyVisited/CommandResultGroup'; export const CommandResultsPaper = styled(Paper)(({ theme }) => ({ position: 'absolute', @@ -86,6 +91,7 @@ export const CommandBar = () => { const [value, setValue] = useState(''); const onSearchChange = (value: string) => { + setTableState({ query: value }); setValue(value); }; @@ -113,6 +119,13 @@ 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}`, + })); + return ( @@ -160,10 +173,14 @@ export const CommandBar = () => { -
search result
+ } elseShow={ diff --git a/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx new file mode 100644 index 0000000000..a42e02a040 --- /dev/null +++ b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx @@ -0,0 +1,77 @@ +import { + Icon, + List, + ListItemButton, + ListItemIcon, + ListItemText, + styled, + Typography, +} from '@mui/material'; +import { Link } from 'react-router-dom'; +import type { Theme } from '@mui/material/styles/createTheme'; + +const listItemButtonStyle = (theme: Theme) => ({ + borderRadius: theme.spacing(0.5), + borderLeft: `${theme.spacing(0.5)} solid transparent`, + '&.Mui-selected': { + borderLeft: `${theme.spacing(0.5)} solid ${theme.palette.primary.main}`, + }, +}); + +const StyledTypography = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.bodySize, + padding: theme.spacing(0, 3), +})); + +const StyledListItemIcon = styled(ListItemIcon)(({ theme }) => ({ + minWidth: theme.spacing(4), + margin: theme.spacing(0.25, 0), +})); + +const StyledListItemText = styled(ListItemText)(({ theme }) => ({ + margin: 0, +})); + +export interface CommandResultGroupItem { + name: string; + link: string; +} + +interface CommandResultGroupProps { + icon: string; + groupName: string; + items: CommandResultGroupItem[]; +} + +export const CommandResultGroup = ({ + icon, + groupName, + items, +}: CommandResultGroupProps) => { + const slicedItems = items.slice(0, 3); + return ( + <> + + {groupName} + + + {slicedItems.map((item, index) => ( + + + {icon} + + + {item.name} + + + ))} + + + ); +}; diff --git a/frontend/src/component/feature/FeatureToggleList/useGlobalFeatureSearch.ts b/frontend/src/component/feature/FeatureToggleList/useGlobalFeatureSearch.ts index 2ef3557371..9f99ea1895 100644 --- a/frontend/src/component/feature/FeatureToggleList/useGlobalFeatureSearch.ts +++ b/frontend/src/component/feature/FeatureToggleList/useGlobalFeatureSearch.ts @@ -15,10 +15,11 @@ import { import { usePersistentTableState } from 'hooks/usePersistentTableState'; import mapValues from 'lodash.mapvalues'; -export const useGlobalFeatureSearch = (storageKey = 'features-list-table') => { +export const useGlobalFeatureSearch = (pageLimit = DEFAULT_PAGE_LIMIT) => { + const storageKey = 'features-list-table'; const stateConfig = { offset: withDefault(NumberParam, 0), - limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT), + limit: withDefault(NumberParam, pageLimit), query: StringParam, favoritesFirst: withDefault(BooleansStringParam, true), sortBy: withDefault(StringParam, 'createdAt'),