Merge pull request #27544 from backstage/search-page-filter-updates
Use core Select instead of Checkbox for filters on Search page
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-search-react': patch
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Use Select from core-components and update Lifecycle filter to use Select instead checkboxes.
|
||||
@@ -117,7 +117,7 @@ const SearchPage = () => {
|
||||
name="kind"
|
||||
values={['Component', 'Template']}
|
||||
/>
|
||||
<SearchFilter.Checkbox
|
||||
<SearchFilter.Select
|
||||
className={classes.filter}
|
||||
label="Lifecycle"
|
||||
name="lifecycle"
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
"@material-ui/lab": "4.0.0-alpha.61",
|
||||
"lodash": "^4.17.21",
|
||||
"qs": "^6.9.4",
|
||||
"react-use": "^17.3.2"
|
||||
"react-use": "^17.3.2",
|
||||
"uuid": "^11.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
|
||||
@@ -289,12 +289,14 @@ describe('SearchFilter', () => {
|
||||
expect(screen.getByRole('listbox')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[0] }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[1] }),
|
||||
).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[0] }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole('option', { name: values[1] }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('Renders correctly based on filter state', async () => {
|
||||
|
||||
@@ -14,16 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactElement, ChangeEvent } from 'react';
|
||||
import React, { ReactElement, ChangeEvent, useRef } from 'react';
|
||||
import { capitalize } from 'lodash';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import Checkbox from '@material-ui/core/Checkbox';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import FormLabel from '@material-ui/core/FormLabel';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { Select, SelectedItems } from '@backstage/core-components';
|
||||
|
||||
import { useSearch } from '../../context';
|
||||
import {
|
||||
@@ -161,7 +160,6 @@ export const SelectFilter = (props: SearchFilterComponentProps) => {
|
||||
values: givenValues,
|
||||
valuesDebounceMs,
|
||||
} = props;
|
||||
const classes = useStyles();
|
||||
useDefaultFilterValue(name, defaultValue);
|
||||
const asyncValues =
|
||||
typeof givenValues === 'function' ? givenValues : undefined;
|
||||
@@ -173,19 +171,21 @@ export const SelectFilter = (props: SearchFilterComponentProps) => {
|
||||
defaultValues,
|
||||
valuesDebounceMs,
|
||||
);
|
||||
const allOptionValue = useRef(uuid());
|
||||
const allOption = { value: allOptionValue.current, label: 'All' };
|
||||
const { filters, setFilters } = useSearch();
|
||||
|
||||
const handleChange = (e: ChangeEvent<{ value: unknown }>) => {
|
||||
const {
|
||||
target: { value },
|
||||
} = e;
|
||||
|
||||
const handleChange = (value: SelectedItems) => {
|
||||
setFilters(prevFilters => {
|
||||
const { [name]: filter, ...others } = prevFilters;
|
||||
return value ? { ...others, [name]: value as string } : others;
|
||||
return value !== allOptionValue.current
|
||||
? { ...others, [name]: value as string }
|
||||
: others;
|
||||
});
|
||||
};
|
||||
|
||||
const items = [allOption, ...values.map(value => ({ value, label: value }))];
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
disabled={loading}
|
||||
@@ -194,27 +194,12 @@ export const SelectFilter = (props: SearchFilterComponentProps) => {
|
||||
fullWidth
|
||||
data-testid="search-selectfilter-next"
|
||||
>
|
||||
{label ? (
|
||||
<InputLabel className={classes.label} margin="dense">
|
||||
{label}
|
||||
</InputLabel>
|
||||
) : null}
|
||||
<Select
|
||||
variant="outlined"
|
||||
value={filters[name] || ''}
|
||||
label={label ?? capitalize(name)}
|
||||
selected={(filters[name] || allOptionValue.current) as string}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<MenuItem value="">
|
||||
<em>All</em>
|
||||
</MenuItem>
|
||||
{values.map((value: string) => (
|
||||
<MenuItem key={value} value={value}>
|
||||
<Typography variant="inherit" noWrap>
|
||||
{value}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
items={items}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -143,7 +143,7 @@ export const SearchTypeAccordion = (props: SearchTypeAccordionProps) => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="body2" component="h3">
|
||||
<Typography variant="body2" component="h2">
|
||||
{name}
|
||||
</Typography>
|
||||
<Accordion
|
||||
|
||||
@@ -7797,6 +7797,7 @@ __metadata:
|
||||
react-dom: ^18.0.2
|
||||
react-router-dom: ^6.3.0
|
||||
react-use: ^17.3.2
|
||||
uuid: ^11.0.2
|
||||
peerDependencies:
|
||||
"@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.13.1 || ^17.0.0 || ^18.0.0
|
||||
@@ -44204,7 +44205,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uuid@npm:^11.0.0":
|
||||
"uuid@npm:^11.0.0, uuid@npm:^11.0.2":
|
||||
version: 11.0.3
|
||||
resolution: "uuid@npm:11.0.3"
|
||||
bin:
|
||||
|
||||
Reference in New Issue
Block a user