refactor(plugins/search): make components more stylable

Signed-off-by: Camila Belo <camilaibs@gmail.com>
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Camila Belo
2021-05-27 11:47:57 +02:00
committed by Eric Peterson
parent 109e186b5f
commit 6b8d6ccd13
3 changed files with 127 additions and 98 deletions
@@ -15,67 +15,88 @@
*/
import React from 'react';
import { Content, Header, Lifecycle, Page } from '@backstage/core';
import { Grid, List, Card, CardContent } from '@material-ui/core';
import {
SearchBarNext,
SearchResultNext,
DefaultResultListItem,
SearchFilterNext,
} from '@backstage/plugin-search';
import { CatalogResultListItem } from '@backstage/plugin-catalog';
import { makeStyles, Theme, Grid, List, Paper } from '@material-ui/core';
export const searchPage = (
<Page themeId="home">
<Header title="Search" subtitle={<Lifecycle alpha />} />
<Content>
<Grid container direction="row">
<Grid item xs={12}>
<SearchBarNext debounceTime={100} />
</Grid>
<Grid item xs={3}>
<Card>
<CardContent>
<SearchFilterNext.Select
import { Content, Header, Lifecycle, Page } from '@backstage/core';
import { CatalogResultListItem } from '@backstage/plugin-catalog';
import {
SearchBarNext as SearchBar,
SearchFilterNext as SearchFilter,
SearchResultNext as SearchResult,
DefaultResultListItem,
} from '@backstage/plugin-search';
const useStyles = makeStyles((theme: Theme) => ({
bar: {
padding: theme.spacing(1, 0),
},
filters: {
padding: theme.spacing(2),
},
filter: {
'& + &': {
marginTop: theme.spacing(2.5),
},
},
}));
const SearchPage = () => {
const classes = useStyles();
return (
<Page themeId="home">
<Header title="Search" subtitle={<Lifecycle alpha />} />
<Content>
<Grid container direction="row">
<Grid item xs={12}>
<Paper className={classes.bar}>
<SearchBar debounceTime={100} />
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.filters}>
<SearchFilter.Select
className={classes.filter}
name="kind"
values={['Component', 'Template']}
/>
</CardContent>
<CardContent>
<SearchFilterNext.Checkbox
<SearchFilter.Checkbox
className={classes.filter}
name="lifecycle"
values={['experimental', 'production']}
/>
</CardContent>
</Card>
</Paper>
</Grid>
<Grid item xs={9}>
<SearchResult>
{({ results }) => (
<List>
{results.map(({ type, document }) => {
switch (type) {
case 'software-catalog':
return (
<CatalogResultListItem
key={document.location}
result={document}
/>
);
default:
return (
<DefaultResultListItem
key={document.location}
result={document}
/>
);
}
})}
</List>
)}
</SearchResult>
</Grid>
</Grid>
<Grid item xs={9}>
<SearchResultNext>
{({ results }) => (
<List>
{results.map(result => {
switch (result.type) {
case 'software-catalog':
return (
<CatalogResultListItem
key={result.document.location}
result={result.document}
/>
);
default:
return (
<DefaultResultListItem
key={result.document.location}
result={result.document}
/>
);
}
})}
</List>
)}
</SearchResultNext>
</Grid>
</Grid>
</Content>
</Page>
);
</Content>
</Page>
);
};
export const searchPage = <SearchPage />;
@@ -16,64 +16,52 @@
import React, { ChangeEvent, useState } from 'react';
import { useDebounce } from 'react-use';
import {
Theme,
Paper,
InputBase,
InputAdornment,
IconButton,
makeStyles,
} from '@material-ui/core';
import { InputBase, InputAdornment, IconButton } from '@material-ui/core';
import SearchIcon from '@material-ui/icons/Search';
import ClearButton from '@material-ui/icons/Clear';
import { useSearch } from '../SearchContext';
const useStyles = makeStyles((theme: Theme) => ({
root: {
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 0, 0, 1.5),
},
input: {
flex: 1,
},
}));
type Props = {
className?: string;
debounceTime?: number;
};
export const SearchBarNext = ({ debounceTime = 0 }: Props) => {
const classes = useStyles();
export const SearchBarNext = ({ className, debounceTime = 0 }: Props) => {
const { term, setTerm } = useSearch();
const [value, setValue] = useState<string>(term);
useDebounce(() => setTerm(value), debounceTime, [value]);
const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
const handleQuery = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
};
const handleClear = () => setValue('');
return (
<Paper component="form" className={classes.root}>
<InputBase
className={classes.input}
placeholder="Search in Backstage"
value={value}
onChange={handleSearch}
inputProps={{ 'aria-label': 'Search term' }}
startAdornment={
<InputAdornment position="start">
<InputBase
className={className}
data-testid="search-bar-next"
fullWidth
placeholder="Search in Backstage"
value={value}
onChange={handleQuery}
inputProps={{ 'aria-label': 'Search term' }}
startAdornment={
<InputAdornment position="start">
<IconButton aria-label="Query term" disabled>
<SearchIcon />
</InputAdornment>
}
/>
<IconButton aria-label="Clear term" onClick={handleClear}>
<ClearButton />
</IconButton>
</Paper>
</IconButton>
</InputAdornment>
}
endAdornment={
<InputAdornment position="end">
<IconButton aria-label="Clear term" onClick={handleClear}>
<ClearButton />
</IconButton>
</InputAdornment>
}
/>
);
};
@@ -35,6 +35,7 @@ const useStyles = makeStyles({
});
export type Component = {
className?: string;
name: string;
values?: string[];
defaultValue?: string[] | string | null;
@@ -45,7 +46,12 @@ export type Props = Component & {
debug?: boolean;
};
const CheckboxFilter = ({ name, defaultValue, values = [] }: Component) => {
const CheckboxFilter = ({
className,
name,
defaultValue,
values = [],
}: Component) => {
const classes = useStyles();
const { filters, setFilters } = useSearch();
@@ -72,7 +78,11 @@ const CheckboxFilter = ({ name, defaultValue, values = [] }: Component) => {
};
return (
<FormControl>
<FormControl
className={className}
fullWidth
data-testid="search-checkboxfilter-next"
>
<FormLabel className={classes.label}>{name}</FormLabel>
{values.map((value: string) => (
<FormControlLabel
@@ -95,7 +105,12 @@ const CheckboxFilter = ({ name, defaultValue, values = [] }: Component) => {
);
};
const SelectFilter = ({ name, defaultValue, values = [] }: Component) => {
const SelectFilter = ({
className,
name,
defaultValue,
values = [],
}: Component) => {
const classes = useStyles();
const { filters, setFilters } = useSearch();
@@ -120,7 +135,12 @@ const SelectFilter = ({ name, defaultValue, values = [] }: Component) => {
};
return (
<FormControl variant="filled" fullWidth>
<FormControl
className={className}
variant="filled"
fullWidth
data-testid="search-selectfilter-next"
>
<InputLabel className={classes.label} margin="dense">
{name}
</InputLabel>