-
-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #155 from kreneskyp/fast_api_cleanup
FastAPI hooks and cleanup
- Loading branch information
Showing
13 changed files
with
328 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useCallback, useState } from "react"; | ||
import axios from "axios"; | ||
|
||
const useCreateAPI = (url) => { | ||
const [isLoading, setIsLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
|
||
const create = useCallback( | ||
async (data) => { | ||
setIsLoading(true); | ||
try { | ||
const response = await axios.post(url, data); | ||
setIsLoading(false); | ||
return response.data; | ||
} catch (err) { | ||
setIsLoading(false); | ||
setError(err); | ||
throw err; | ||
} | ||
}, | ||
[url] | ||
); | ||
|
||
return { | ||
create, | ||
isLoading, | ||
error, | ||
}; | ||
}; | ||
|
||
export default useCreateAPI; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import useCreateAPI from "utils/hooks/useCreateAPI"; | ||
import useUpdateAPI from "utils/hooks/useUpdateAPI"; | ||
|
||
/** | ||
* Hook that encapsulates both create and update APIs into a single save function. | ||
* @param createURL | ||
* @param updateURL | ||
* @returns {{isLoading: boolean, save: ((function(*): Promise<any|undefined>)|*)}} | ||
*/ | ||
export const useCreateUpdateAPI = (createURL, updateURL) => { | ||
const { create, isLoading: isCreateLoading } = useCreateAPI(createURL); | ||
const { update, isLoading: isUpdateLoading } = useUpdateAPI(updateURL); | ||
|
||
const save = async (data) => { | ||
if (data.id) { | ||
return await update(data); | ||
} else { | ||
return await create(data); | ||
} | ||
}; | ||
|
||
return { | ||
save, | ||
isLoading: isCreateLoading || isUpdateLoading, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { useCallback, useState } from "react"; | ||
import axios from "axios"; | ||
|
||
export const useDeleteAPI = (endpoint) => { | ||
const [isLoading, setIsLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
|
||
const deleteData = useCallback(async () => { | ||
setIsLoading(true); | ||
try { | ||
await axios.delete(endpoint); | ||
} catch (err) { | ||
setError(err); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}, [endpoint]); | ||
|
||
return { | ||
call: deleteData, | ||
isLoading, | ||
error, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { useState, useEffect, useCallback } from "react"; | ||
import axios from "axios"; | ||
|
||
export const useDetailAPI = (endpoint, { load = true } = {}) => { | ||
const [data, setData] = useState(null); | ||
const [isLoading, setIsLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
|
||
const loadData = useCallback(async () => { | ||
setIsLoading(true); | ||
try { | ||
const response = await axios.get(endpoint); | ||
setData(response.data); | ||
} catch (err) { | ||
setError(err); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}, [endpoint]); | ||
|
||
useEffect(() => { | ||
if (load) { | ||
loadData(); | ||
} | ||
}, [endpoint, load]); | ||
|
||
return { | ||
data, | ||
load: loadData, | ||
isLoading, | ||
error, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { useEffect, useState } from "react"; | ||
import { v4 as uuid4 } from "uuid"; | ||
|
||
/** | ||
* Hook for handling the state of an object editor view. | ||
* state for handling whether how to load the data (new vs existing) | ||
* and when to reset the editor when opened. The cached state does not | ||
* reset when the url changes as protection against reloading when | ||
* creating new chains. This state tracks when to reset the cache. | ||
* | ||
* @param id - object id, or undefined/null if new | ||
* @param load - function to load the object when needed | ||
*/ | ||
export const useObjectEditorView = (id, load) => { | ||
const [idRef, setIdRef] = useState(null); | ||
const [isNew, setIsNew] = useState(null); | ||
const [wasCreated, setWasCreated] = useState(null); | ||
useEffect(() => { | ||
const firstRender = isNew === null; | ||
if (firstRender) { | ||
// first render caches whether this started as a new chain | ||
setIsNew(id === undefined); | ||
} else { | ||
// switch from existing to new | ||
if (id === undefined && !isNew) { | ||
setIsNew(true); | ||
setWasCreated(false); | ||
} | ||
// a new chain was created | ||
if (id !== undefined && isNew) { | ||
setWasCreated(true); | ||
} | ||
// switch from created to new | ||
if (id === undefined && wasCreated) { | ||
setIsNew(true); | ||
setWasCreated(false); | ||
setIdRef(uuid4()); | ||
} | ||
} | ||
}, [id]); | ||
|
||
useEffect(() => { | ||
// load chain if id is provided on view load | ||
// otherwise state will be handled internally by the editor | ||
if (isNew === false) { | ||
load(); | ||
setIdRef(id); | ||
} else { | ||
// create a uuid here to force a new editor. This helps detect | ||
// creating a new object after a new object was just created. | ||
setIdRef(uuid4()); | ||
} | ||
}, [isNew]); | ||
|
||
return { | ||
isNew, | ||
idRef, | ||
wasCreated, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { useCallback, useEffect, useState } from "react"; | ||
import axios from "axios"; | ||
|
||
export function usePaginatedAPI( | ||
endpoint, | ||
{ offset = 0, limit = 10, load = true, loadDependencies = [] } = {} | ||
) { | ||
const [page, setPage] = useState(null); | ||
const [isLoading, setIsLoading] = useState(true); | ||
|
||
const _load = useCallback( | ||
async ({ search } = {}) => { | ||
setIsLoading(true); | ||
const params = { limit, offset }; | ||
if (search) { | ||
params.search = search; | ||
} | ||
try { | ||
const response = await axios.get(endpoint, { | ||
params, | ||
}); | ||
setPage(response.data); | ||
} catch (error) { | ||
console.error("Failed to fetch data:", error); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}, | ||
[endpoint] | ||
); | ||
|
||
useEffect(() => { | ||
if (load) { | ||
_load(); | ||
} | ||
}, [_load, ...loadDependencies]); | ||
|
||
return { | ||
page, | ||
isLoading, | ||
load: _load, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useCallback, useState } from "react"; | ||
import axios from "axios"; | ||
|
||
const useUpdateAPI = (url, { onSuccess, onError } = {}) => { | ||
const [isLoading, setIsLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
|
||
const update = useCallback( | ||
async (data) => { | ||
setIsLoading(true); | ||
try { | ||
const response = await axios.put(url, data); | ||
setIsLoading(false); | ||
return response.data; | ||
} catch (err) { | ||
setIsLoading(false); | ||
setError(err); | ||
throw err; | ||
} | ||
}, | ||
[url] | ||
); | ||
|
||
return { | ||
update, | ||
isLoading, | ||
error, | ||
}; | ||
}; | ||
|
||
export default useUpdateAPI; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.