diff --git a/package-lock.json b/package-lock.json index a6370641..7b63562a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,6 +63,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", + "use-debounce": "^10.0.4", "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" @@ -16895,6 +16896,17 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-debounce": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.4.tgz", + "integrity": "sha512-6Cf7Yr7Wk7Kdv77nnJMf6de4HuDE4dTxKij+RqE9rufDsI6zsbjyAxcH5y2ueJCQAnfgKbzXbZHYlkFwmBlWkw==", + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", @@ -30116,6 +30128,12 @@ "requires-port": "^1.0.0" } }, + "use-debounce": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.4.tgz", + "integrity": "sha512-6Cf7Yr7Wk7Kdv77nnJMf6de4HuDE4dTxKij+RqE9rufDsI6zsbjyAxcH5y2ueJCQAnfgKbzXbZHYlkFwmBlWkw==", + "requires": {} + }, "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", diff --git a/package.json b/package.json index 1137b308..20028869 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "redux-thunk": "^2.4.2", "resolve": "1.22.2", "simple-xpath-position": "^2.0.2", + "use-debounce": "^10.0.4", "uuid": "^10.0.0", "whatwg-fetch": "3.6.2", "whatwg-mimetype": "3.0.0" diff --git a/src/action/SearchActions.ts b/src/action/SearchActions.ts index ccd14ceb..ca661857 100644 --- a/src/action/SearchActions.ts +++ b/src/action/SearchActions.ts @@ -56,7 +56,6 @@ export function removeSearchListener() { * Timer to delay search requests as user is still typing. */ let updateSearchTimer: ReturnType | null = null; -const updateSearchDelay = 400; // ms /** * Change the search criteria and trigger a new search. @@ -85,7 +84,7 @@ export function updateSearchFilter(searchString: string) { updateSearchTimer = setTimeout(() => { updateSearchTimer = null; dispatch(searchEverything()); - }, updateSearchDelay); + }, Constants.SEARCH_DEBOUNCE_DELAY); return Promise.resolve(); } }; diff --git a/src/component/search/facet/FacetedSearch.tsx b/src/component/search/facet/FacetedSearch.tsx index 02b53734..fe6dfee9 100644 --- a/src/component/search/facet/FacetedSearch.tsx +++ b/src/component/search/facet/FacetedSearch.tsx @@ -19,6 +19,7 @@ import VocabularyFacet from "./VocabularyFacet"; import SimplePagination from "../../dashboard/widget/lastcommented/SimplePagination"; import Constants from "../../../util/Constants"; import TermStateFacet from "./TermStateFacet"; +import { useDebouncedCallback } from "use-debounce"; function aggregateSearchParams(params: { [key: string]: SearchParam }) { return Object.entries(params) @@ -62,19 +63,35 @@ const FacetedSearch: React.FC = () => { const dispatch: ThunkDispatch = useDispatch(); const [page, setPage] = useState(0); const [params, setParams] = useState(INITIAL_STATE); + const [results, setResults] = + React.useState(null); + const onChange = (value: SearchParam) => { const change = {}; change[value.property] = value; setParams({ ...params, ...change }); setPage(0); + if (value.matchType === MatchType.IRI || value.value[0].length === 0) { + runSearch({ ...params, ...change }, page); + } else { + debouncedSearch({ ...params, ...change }, page); + } + }; + const onPageChange = (page: number) => { + setPage(page); + runSearch(params, page); }; - const [results, setResults] = - React.useState(null); const runSearch = React.useCallback( - (params: SearchParam[]) => { + (params: {}, page: number) => { + const sp = aggregateSearchParams(params); + if (sp.length === 0) { + setPage(0); + setResults(null); + return; + } trackPromise( dispatch( - executeFacetedTermSearch(params, { + executeFacetedTermSearch(sp, { page, size: Constants.DEFAULT_PAGE_SIZE, }) @@ -82,17 +99,11 @@ const FacetedSearch: React.FC = () => { "faceted-search" ).then((res) => setResults(res)); }, - [page, dispatch, setResults] + [dispatch, setPage, setResults] ); - React.useEffect(() => { - const sp = aggregateSearchParams(params); - if (sp.length === 0) { - setPage(0); - setResults(null); - return; - } - runSearch(sp); - }, [params, runSearch]); + const debouncedSearch = useDebouncedCallback((params: {}, page: number) => { + runSearch(params, page); + }, Constants.SEARCH_DEBOUNCE_DELAY); return (