@@ -11,17 +11,43 @@ import { useSnackMessage } from '../../hooks/useSnackMessage';
1111
1212const SEARCH_FETCH_TIMEOUT_MILLIS = 1000 ;
1313
14+ export type Paginated < T > = {
15+ content : T [ ] ;
16+ totalPages : number ;
17+ totalElements : number ;
18+ last : boolean ;
19+ size : number ;
20+ number : number ;
21+ sort : {
22+ sorted : boolean ;
23+ unsorted : boolean ;
24+ empty : boolean ;
25+ } ;
26+ first : boolean ;
27+ numberOfElements : number ;
28+ empty : boolean ;
29+ } ;
30+
1431interface UseElementSearch < T > {
15- fetchElements : ( newSearchTerm : string ) => Promise < T [ ] > ;
32+ fetchElements : ( newSearchTerm : string ) => Promise < Paginated < T > | T [ ] > ;
1633}
1734
18- const useElementSearch = < T , > ( props : UseElementSearch < T > ) => {
35+ const useElementSearch = < T , > (
36+ props : UseElementSearch < T >
37+ ) : {
38+ searchTerm : string ;
39+ updateSearchTerm : ( newSearchTerm : string ) => void ;
40+ elementsFound : T [ ] ;
41+ isLoading : boolean ;
42+ totalElements : number ;
43+ } => {
1944 const { fetchElements } = props ;
2045
2146 const { snackError } = useSnackMessage ( ) ;
2247 const [ isLoading , setIsLoading ] = useState ( false ) ;
2348 const [ searchTerm , setSearchTerm ] = useState ( '' ) ;
24- const [ elementsFound , setElementsFound ] = useState < T [ ] > ( [ ] ) ;
49+ const [ elementsFound , setElementsFound ] = useState < T [ ] > ( [ ] as T [ ] ) ;
50+ const [ totalElements , setTotalElements ] = useState ( 0 ) ;
2551 const lastSearchTermRef = useRef ( '' ) ;
2652
2753 const searchMatchingElements = useCallback (
@@ -31,17 +57,25 @@ const useElementSearch = <T,>(props: UseElementSearch<T>) => {
3157 }
3258
3359 lastSearchTermRef . current = newSearchTerm ;
60+
3461 fetchElements ( newSearchTerm )
3562 . then ( ( infos ) => {
3663 if ( newSearchTerm === lastSearchTermRef . current ) {
37- setElementsFound ( infos ) ;
64+ if ( Array . isArray ( infos ) ) {
65+ setElementsFound ( infos ) ;
66+ setTotalElements ( infos . length ) ;
67+ } else {
68+ setElementsFound ( infos . content ) ;
69+ setTotalElements ( infos . totalElements ) ;
70+ }
3871 setIsLoading ( false ) ;
3972 } // else ignore results of outdated fetch
4073 } )
4174 . catch ( ( error ) => {
4275 // else ignore errors of outdated fetch if changing "isLoading state"
4376 if ( newSearchTerm === lastSearchTermRef . current ) {
4477 setElementsFound ( [ ] ) ;
78+ setTotalElements ( 0 ) ;
4579 setIsLoading ( false ) ;
4680 snackError ( {
4781 messageTxt : error . message ,
@@ -50,7 +84,7 @@ const useElementSearch = <T,>(props: UseElementSearch<T>) => {
5084 }
5185 } ) ;
5286 } ,
53- [ snackError , fetchElements ]
87+ [ fetchElements , snackError ]
5488 ) ;
5589
5690 const debouncedSearchMatchingElements = useDebounce (
@@ -66,6 +100,7 @@ const useElementSearch = <T,>(props: UseElementSearch<T>) => {
66100 // still debouncing to cancel previous call, otherwise last call will still trigger
67101 if ( newSearchTerm . length === 0 ) {
68102 setElementsFound ( [ ] ) ;
103+ setTotalElements ( 0 ) ;
69104 setIsLoading ( false ) ;
70105 } else {
71106 setIsLoading ( true ) ;
@@ -76,7 +111,13 @@ const useElementSearch = <T,>(props: UseElementSearch<T>) => {
76111 [ debouncedSearchMatchingElements ]
77112 ) ;
78113
79- return { searchTerm, updateSearchTerm, elementsFound, isLoading } ;
114+ return {
115+ searchTerm,
116+ updateSearchTerm,
117+ elementsFound,
118+ isLoading,
119+ totalElements,
120+ } ;
80121} ;
81122
82123export default useElementSearch ;
0 commit comments