Move query param logic from SearchBar to SearchPage
Signed-off-by: Camila Belo <camilaibs@gmail.com> Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
committed by
Eric Peterson
parent
c70139e732
commit
db6fd04d73
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
import { useQueryParamState } from '@backstage/core';
|
||||
import { Paper, InputBase, IconButton, makeStyles } from '@material-ui/core';
|
||||
import SearchIcon from '@material-ui/icons/Search';
|
||||
import ClearButton from '@material-ui/icons/Clear';
|
||||
@@ -32,23 +31,26 @@ const useStyles = makeStyles(() => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export const SearchBarNext = () => {
|
||||
type Props = {
|
||||
debounceTime?: number;
|
||||
};
|
||||
|
||||
export const SearchBarNext = ({ debounceTime = 200 }: Props) => {
|
||||
const classes = useStyles();
|
||||
const { term, setTerm, setPageCursor } = useSearch();
|
||||
|
||||
const [, setQueryString] = useQueryParamState<string>('query');
|
||||
const [value, setValue] = useState<string>(term);
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
setQueryString(term);
|
||||
setTerm(value);
|
||||
},
|
||||
200,
|
||||
[term],
|
||||
debounceTime,
|
||||
[value],
|
||||
);
|
||||
|
||||
const handleSearch = (event: React.ChangeEvent | React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
setTerm((event.target as HTMLInputElement).value as string);
|
||||
setValue((event.target as HTMLInputElement).value as string);
|
||||
};
|
||||
|
||||
const handleClearSearchBar = () => {
|
||||
@@ -57,22 +59,18 @@ export const SearchBarNext = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper
|
||||
component="form"
|
||||
onSubmit={e => handleSearch(e)}
|
||||
className={classes.root}
|
||||
>
|
||||
<Paper component="form" onSubmit={handleSearch} className={classes.root}>
|
||||
<IconButton disabled type="submit" aria-label="search">
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
<InputBase
|
||||
className={classes.input}
|
||||
placeholder="Search in Backstage"
|
||||
value={term}
|
||||
onChange={e => handleSearch(e)}
|
||||
value={value}
|
||||
onChange={handleSearch}
|
||||
inputProps={{ 'aria-label': 'search backstage' }}
|
||||
/>
|
||||
<IconButton aria-label="search" onClick={() => handleClearSearchBar()}>
|
||||
<IconButton aria-label="search" onClick={handleClearSearchBar}>
|
||||
<ClearButton />
|
||||
</IconButton>
|
||||
</Paper>
|
||||
|
||||
@@ -17,15 +17,38 @@
|
||||
import React from 'react';
|
||||
import qs from 'qs';
|
||||
import { Outlet, useLocation } from 'react-router';
|
||||
import { useQueryParamState } from '@backstage/core';
|
||||
import { SearchContextProvider } from '../SearchContext';
|
||||
import { SearchContextProvider, useSearch } from '../SearchContext';
|
||||
import { JsonObject } from '@backstage/config';
|
||||
|
||||
export const UrlUpdater = () => {
|
||||
const { term, types, pageCursor, filters } = useSearch();
|
||||
|
||||
const newParams = qs.stringify(
|
||||
{
|
||||
query: term,
|
||||
types,
|
||||
pageCursor,
|
||||
filters,
|
||||
},
|
||||
{ arrayFormat: 'brackets' },
|
||||
);
|
||||
const newUrl = `${window.location.pathname}?${newParams}`;
|
||||
|
||||
// We directly manipulate window history here in order to not re-render
|
||||
// infinitely (state => location => state => etc). The intention of this
|
||||
// code is just to ensure the right query/filters are loaded when a user
|
||||
// clicks the "back" button after clicking a result.
|
||||
window.history.replaceState(null, document.title, newUrl);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const SearchPageNext = () => {
|
||||
const location = useLocation();
|
||||
const [queryString] = useQueryParamState<string>('query');
|
||||
const filters = (qs.parse(location.search.substring(1), { arrayLimit: 0 })
|
||||
.filters || {}) as JsonObject;
|
||||
const query = qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};
|
||||
const filters = (query.filters as JsonObject) || {};
|
||||
const queryString = (query.query as string) || '';
|
||||
|
||||
const initialState = {
|
||||
term: queryString || '',
|
||||
types: [],
|
||||
@@ -35,6 +58,7 @@ export const SearchPageNext = () => {
|
||||
|
||||
return (
|
||||
<SearchContextProvider initialState={initialState}>
|
||||
<UrlUpdater />
|
||||
<Outlet />
|
||||
</SearchContextProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user