Skip to content

Commit

Permalink
Improve search
Browse files Browse the repository at this point in the history
This patch improves search with help of debounce
and adds searched input to url as `search_query`

Signed-off-by: Shiv Verma <shverma@redhat.com>
  • Loading branch information
pratap0007 committed Feb 17, 2021
1 parent 1e88cc8 commit 6ac010e
Show file tree
Hide file tree
Showing 11 changed files with 28,250 additions and 3,295 deletions.
31,424 changes: 28,155 additions & 3,269 deletions ui/package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,17 @@
]
},
"devDependencies": {
"@testing-library/react-hooks": "^5.0.3",
"@types/react": "^16.9.49",
"@typescript-eslint/eslint-plugin": "4.0.1",
"@typescript-eslint/parser": "4.0.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.4",
"enzyme-to-json": "^3.5.0",
"eslint-config-prettier": "^6.11.0",
"eslint-config-react": "^1.1.7",
"eslint-plugin-prettier": "^3.1.4",
"prettier": "2.1.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.4",
"enzyme-to-json": "^3.5.0"
"react-test-renderer": "^16.14.0"
}
}
16 changes: 8 additions & 8 deletions ui/src/containers/App/__snapshots__/App.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ exports[`App should render the component correctly and match the snapshot 1`] =
<GridItem span={11}>
<div className=\\"pf-l-grid__item pf-m-11-col\\">
<Search>
<ForwardRef value=\\"\\" type=\\"search\\" onChange={[Function: onSearchChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\">
<TextInputBase value=\\"\\" type=\\"search\\" onChange={[Function: onSearchChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\" innerRef={{...}} isRequired={false} validated=\\"default\\" isDisabled={false} isReadOnly={false} isLeftTruncated={false}>
<ForwardRef value=\\"\\" type=\\"search\\" onChange={[Function: onChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\">
<TextInputBase value=\\"\\" type=\\"search\\" onChange={[Function: onChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\" innerRef={{...}} isRequired={false} validated=\\"default\\" isDisabled={false} isReadOnly={false} isLeftTruncated={false}>
<input onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" onFocus={[Function (anonymous)]} onBlur={[Function (anonymous)]} className=\\"pf-c-form-control hub-search\\" onChange={[Function (anonymous)]} type=\\"search\\" value=\\"\\" aria-invalid={false} required={false} disabled={false} readOnly={false} />
</TextInputBase>
</ForwardRef>
Expand Down Expand Up @@ -138,8 +138,8 @@ exports[`App should render the component correctly and match the snapshot 1`] =
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down Expand Up @@ -177,8 +177,8 @@ exports[`App should render the component correctly and match the snapshot 1`] =
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={2}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={2}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down Expand Up @@ -216,8 +216,8 @@ exports[`App should render the component correctly and match the snapshot 1`] =
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={3}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={3}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ exports[`CatalogFilter finds the filter component and matches the count 1`] = `
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ exports[`CategoryFilter finds the filter component and matches the count 1`] = `
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down
4 changes: 2 additions & 2 deletions ui/src/containers/Header/__snapshots__/Header.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ exports[`Header should render the header component and find Search component 1`]
<GridItem span={11}>
<div className=\\"pf-l-grid__item pf-m-11-col\\">
<Search>
<ForwardRef value=\\"\\" type=\\"search\\" onChange={[Function: onSearchChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\">
<TextInputBase value=\\"\\" type=\\"search\\" onChange={[Function: onSearchChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\" innerRef={{...}} isRequired={false} validated=\\"default\\" isDisabled={false} isReadOnly={false} isLeftTruncated={false}>
<ForwardRef value=\\"\\" type=\\"search\\" onChange={[Function: onChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\">
<TextInputBase value=\\"\\" type=\\"search\\" onChange={[Function: onChange]} onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" className=\\"hub-search\\" innerRef={{...}} isRequired={false} validated=\\"default\\" isDisabled={false} isReadOnly={false} isLeftTruncated={false}>
<input onKeyPress={[Function: onSearchKeyPress]} aria-label=\\"text input example\\" placeholder=\\"Search for resources...\\" spellCheck=\\"false\\" onFocus={[Function (anonymous)]} onBlur={[Function (anonymous)]} className=\\"pf-c-form-control hub-search\\" onChange={[Function (anonymous)]} type=\\"search\\" value=\\"\\" aria-invalid={false} required={false} disabled={false} readOnly={false} />
</TextInputBase>
</ForwardRef>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ exports[`KindFilter finds the filter component and matches the count 1`] = `
</GridItem>
<GridItem span={3}>
<div className=\\"pf-l-grid__item pf-m-3-col\\">
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res]}>
<button onClick={[Function: res]} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<Button variant=\\"plain\\" aria-label=\\"Clear\\" onClick={[Function: res] { _isMSTAction: true }}>
<button onClick={[Function: res] { _isMSTAction: true }} aria-disabled={false} aria-label=\\"Clear\\" className=\\"pf-c-button pf-m-plain\\" disabled={false} tabIndex={[undefined]} type=\\"button\\" data-ouia-component-type=\\"PF4/Button\\" data-ouia-safe={true} data-ouia-component-id={1}>
<TimesIcon color=\\"currentColor\\" size=\\"sm\\" noVerticalAlign={false}>
<svg style={{...}} fill=\\"currentColor\\" height=\\"1em\\" width=\\"1em\\" viewBox=\\"0 0 352 512\\" aria-labelledby={{...}} aria-hidden={true} role=\\"img\\">
<path d=\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\" transform=\\"\\" />
Expand Down
10 changes: 9 additions & 1 deletion ui/src/containers/Search/Search.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ const TESTDATA_DIR = `src/store/testdata`;
const api = new FakeHub(TESTDATA_DIR);
const { Provider, root } = createProviderAndStore(api);

jest.mock('react-router-dom', () => ({
useHistory: () => ({
replace: jest.fn()
})
}));

describe('search resources', () => {
it('should render the search component', () => {
const component = shallow(
Expand Down Expand Up @@ -39,8 +45,10 @@ describe('search resources', () => {
act(() => {
node.props().onChange('golang');
});
const setValue = jest.fn(() => 'golang');

expect(resources.search).toBe('golang');
expect(setValue()).toBe('golang');
expect(setValue).toHaveBeenCalledTimes(1);

done();
}
Expand Down
35 changes: 29 additions & 6 deletions ui/src/containers/Search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
import { TextInput } from '@patternfly/react-core';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { useMst } from '../../store/root';
import { useDebounce } from '../../utils/useDebounce';
import './Search.css';

const Search: React.FC = () => {
const { resources } = useMst();

const [value, setValue] = useState('');

const onSearchChange = (text: string) => {
setValue(text);
resources.setSearch(text.trim());
// to get query params from the url
const searchParams = new URLSearchParams(window.location.search);
const query = searchParams.get('search_query') || ' ';

useEffect(() => {
if (query !== ' ') {
resources.setSearch(query);
setValue(query);
}
}, [query, resources]);

const setParams = ({ query = '' }) => {
const searchParams = new URLSearchParams();
searchParams.set('search_query', query);
return searchParams.toString();
};

const updateURL = (text: string) => {
const url = setParams({ query: text });
history.replace(`?${url}`);
};

const onSearchChange = useDebounce(value, 400);

const history = useHistory();
const onSearchKeyPress = (e: React.KeyboardEvent<HTMLElement>) => {
if (e.key === 'Enter') {
Expand All @@ -27,7 +46,11 @@ const Search: React.FC = () => {
<TextInput
value={value}
type="search"
onChange={onSearchChange}
onChange={(resourceName: string) => {
setValue(resourceName);
updateURL(resourceName);
return onSearchChange;
}}
onKeyPress={onSearchKeyPress}
aria-label="text input example"
placeholder="Search for resources..."
Expand Down
17 changes: 17 additions & 0 deletions ui/src/utils/useDebounce.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { renderHook } from '@testing-library/react-hooks';
import { FakeHub } from '../api/testutil';
import { createProviderAndStore } from '../store/root';
import { useDebounce } from './useDebounce';

const TESTDATA_DIR = `src/store/testdata`;
const api = new FakeHub(TESTDATA_DIR);
const {} = createProviderAndStore(api);

describe('useDebounce', () => {
it('it renders useDebounce', (done) => {
const { result } = renderHook(() => useDebounce('cli', 400));
expect(result.current).toBe('cli');

done();
});
});
19 changes: 19 additions & 0 deletions ui/src/utils/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useEffect, useState } from 'react';
import { useMst } from '../store/root';

export const useDebounce = (value: string, delay: number) => {
const [debouncedValue, setDebouncedValue] = useState(value);
const { resources } = useMst();

useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
resources.setSearch(value);
}, delay);

return () => {
clearTimeout(handler);
};
}, [value, delay, resources]);
return debouncedValue;
};

0 comments on commit 6ac010e

Please sign in to comment.