Skip to content

Commit f942979

Browse files
committed
Auto-submit search, update empty search results message
1 parent 23ae5ec commit f942979

File tree

2 files changed

+66
-27
lines changed

2 files changed

+66
-27
lines changed

cypress/e2e/organizations/pagination.cy.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,9 @@ describe('Organization page', () => {
196196
cy.get('[data-cy=org-members-table-pagination]').contains(
197197
'Showing 1-10 of 20'
198198
)
199+
200+
// Check empty results message after timeout
201+
cy.get('[data-cy=org-members-table-search-input]').clear().type('aaaa')
202+
cy.get('[data-cy=org-members-table]').contains('Search returned no results')
199203
})
200204
})

src/components/tables/users.js

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,71 @@
11
import T from 'prop-types'
22
import Table from './table'
33
import { useFetchList } from '../../hooks/use-fetch-list'
4-
import { useState } from 'react'
4+
import { useEffect, useRef, useState } from 'react'
55
import Pagination from '../pagination'
66
import qs from 'qs'
7-
import { Field, Form, Formik } from 'formik'
7+
import { Field, Form, Formik, useFormikContext } from 'formik'
88
import Button from '../button'
99

10-
const SearchInput = ({ onSearch, 'data-cy': dataCy }) => (
11-
<Formik
12-
initialValues={{ search: '' }}
13-
onSubmit={({ search }) => onSearch(search)}
14-
>
15-
<Form className='form-control justify-start'>
16-
<Field
17-
data-cy={`${dataCy}-search-input`}
18-
type='search'
19-
name='search'
20-
id='search'
21-
placeholder='Search username...'
22-
style={{ width: '12rem' }}
23-
/>
24-
<Button
25-
data-cy={`${dataCy}-search-submit`}
26-
type='submit'
27-
variant='submit'
28-
>
29-
Search
30-
</Button>
31-
</Form>
32-
</Formik>
33-
)
10+
/**
11+
* This is a helper component to auto-submit search values after a timeout
12+
*/
13+
const AutoSubmitSearch = () => {
14+
const timerRef = useRef(null)
15+
16+
const { values, touched, submitForm } = useFormikContext()
17+
18+
useEffect(() => {
19+
// If search is touched
20+
if (touched.search) {
21+
// Clear previous timeout, if exists
22+
if (timerRef.current) {
23+
clearTimeout(timerRef.current)
24+
}
25+
// Define new timeout
26+
timerRef.current = setTimeout(submitForm, 1000)
27+
}
28+
29+
// Clear timeout on unmount
30+
return () => timerRef.current && clearTimeout(timerRef.current)
31+
}, [values, touched, submitForm])
32+
33+
return null
34+
}
35+
36+
/**
37+
* The search input
38+
*/
39+
const SearchInput = ({ onSearch, 'data-cy': dataCy }) => {
40+
return (
41+
<Formik
42+
initialValues={{ search: '' }}
43+
onSubmit={({ search }) => onSearch(search)}
44+
>
45+
<Form className='form-control justify-start'>
46+
<Field
47+
data-cy={`${dataCy}-search-input`}
48+
type='search'
49+
name='search'
50+
id='search'
51+
placeholder='Search username...'
52+
style={{ width: '12rem' }}
53+
/>
54+
<Button
55+
data-cy={`${dataCy}-search-submit`}
56+
type='submit'
57+
variant='submit'
58+
>
59+
Search
60+
</Button>
61+
<AutoSubmitSearch />
62+
</Form>
63+
</Formik>
64+
)
65+
}
3466

3567
function UsersTable({ type, orgId, onRowClick, isSearchable }) {
3668
const [page, setPage] = useState(1)
37-
3869
const [search, setSearch] = useState(null)
3970

4071
let apiBasePath
@@ -70,6 +101,10 @@ function UsersTable({ type, orgId, onRowClick, isSearchable }) {
70101
isLoading,
71102
} = useFetchList(`${apiBasePath}?${querystring}`)
72103

104+
if (!isLoading && search?.length > 0) {
105+
emptyMessage = 'Search returned no results.'
106+
}
107+
73108
return (
74109
<>
75110
{isSearchable && (

0 commit comments

Comments
 (0)