github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/lib/hooks/api.jsx (about) 1 import {useEffect, useState} from 'react'; 2 import {AuthenticationError} from "../api"; 3 import {useRouter} from "./router"; 4 5 const initialPaginationState = { 6 loading: true, 7 error: null, 8 nextPage: null, 9 results: [] 10 }; 11 12 export const useAPIWithPagination = (promise, deps = []) => { 13 const [pagination, setPagination] = useState(initialPaginationState); 14 15 // do the actual API request 16 // we do this if pagination changed, or if we reset to an initial state 17 const {response, error, loading} = useAPI(() => { 18 setPagination({...initialPaginationState}); 19 return promise(); 20 }, [...deps, initialPaginationState]); 21 22 useEffect(() => { 23 if (loading) { 24 setPagination({results: [], loading: true}); 25 return; 26 } 27 28 if (!!error || !response) { 29 setPagination({error, loading: false}); 30 return; 31 } 32 33 // calculate current state on API response 34 setPagination({ 35 error: null, 36 nextPage: (!!response.pagination && response.pagination.has_more) ? response.pagination.next_offset : null, 37 loading: false, 38 results: response.results 39 }); 40 }, [response, loading, error]); 41 42 return pagination; 43 } 44 45 const initialAPIState = { 46 loading: true, 47 error: null, 48 response: null, 49 responseHeaders: null, 50 }; 51 52 export const useAPI = (promise, deps = []) => { 53 const router = useRouter(); 54 const [request, setRequest] = useState(initialAPIState); 55 const [login, setLogin] = useState(false); 56 57 useEffect(() => { 58 if (login) { 59 const loginPathname = '/auth/login'; 60 if (router.route === loginPathname) { 61 return; 62 } 63 router.push({ 64 pathname: loginPathname, 65 query: {next: router.route, redirected: true}, 66 }); 67 setLogin(false); 68 } 69 }, [login, router]) 70 71 useEffect(() => { 72 let isMounted = true; 73 setRequest(initialAPIState); 74 const execute = async () => { 75 try { 76 const response = await promise(); 77 setRequest({ 78 loading: false, 79 error: null, 80 response, 81 }); 82 } catch (error) { 83 if (error instanceof AuthenticationError) { 84 if (isMounted) { 85 setLogin(true); 86 } 87 return; 88 } 89 setRequest({ 90 loading: false, 91 error, 92 response: null, 93 }); 94 } 95 }; 96 execute(); 97 return () => isMounted = false; 98 }, deps); 99 return {...request}; 100 }