2021-05-20 10:16:01 +00:00
|
|
|
import { useCallback, useEffect, useState } from "react"
|
2021-05-19 17:56:41 +00:00
|
|
|
import useBackendRequest from "./useBackendRequest"
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An hook which allows access to a full REST resource (retrieve, edit, delete).
|
|
|
|
*
|
|
|
|
* @param resourcePath - The path of the resource file.
|
|
|
|
* @param allowViews - An object with maps views to a boolean detailing if they're allowed in the viewset or not.
|
|
|
|
*/
|
2021-05-20 10:16:01 +00:00
|
|
|
export default function useBackendResource(
|
|
|
|
resourcePath,
|
|
|
|
{
|
|
|
|
retrieve: allowRetrieve = true,
|
|
|
|
edit: allowEdit = true,
|
|
|
|
destroy: allowDestroy = true,
|
|
|
|
action: allowAction = false,
|
|
|
|
} = {},
|
|
|
|
) {
|
2021-05-19 17:56:41 +00:00
|
|
|
|
2021-05-20 10:16:01 +00:00
|
|
|
const { abort, running, apiRequest } = useBackendRequest()
|
2021-05-19 17:56:41 +00:00
|
|
|
|
|
|
|
const [firstLoad, setFirstLoad] = useState(false)
|
|
|
|
const [resource, setResource] = useState(null)
|
|
|
|
const [error, setError] = useState(null)
|
|
|
|
|
|
|
|
const apiRetrieve = useCallback(
|
|
|
|
async (init) => {
|
2021-05-20 10:16:01 +00:00
|
|
|
if(!allowRetrieve) {
|
|
|
|
throw new ViewNotAllowedError("retrieve")
|
|
|
|
}
|
2021-05-23 16:22:30 +00:00
|
|
|
return apiRequest("GET", `${resourcePath}`, undefined, init)
|
2021-05-19 17:56:41 +00:00
|
|
|
},
|
|
|
|
[apiRequest, allowRetrieve, resourcePath],
|
|
|
|
)
|
|
|
|
|
|
|
|
const apiEdit = useCallback(
|
|
|
|
async (data, init) => {
|
2021-05-20 10:16:01 +00:00
|
|
|
if(!allowEdit) {
|
|
|
|
throw new ViewNotAllowedError("edit")
|
|
|
|
}
|
2021-05-23 16:22:30 +00:00
|
|
|
return apiRequest("PUT", `${resourcePath}`, data, init)
|
2021-05-19 17:56:41 +00:00
|
|
|
},
|
|
|
|
[apiRequest, allowEdit, resourcePath],
|
|
|
|
)
|
|
|
|
|
|
|
|
const apiDestroy = useCallback(
|
|
|
|
async (init) => {
|
2021-05-20 10:16:01 +00:00
|
|
|
if(!allowDestroy) {
|
|
|
|
throw new ViewNotAllowedError("destroy")
|
|
|
|
}
|
2021-05-23 16:22:30 +00:00
|
|
|
return apiRequest("DELETE", `${resourcePath}`, undefined, init)
|
2021-05-19 17:56:41 +00:00
|
|
|
},
|
|
|
|
[apiRequest, allowDestroy, resourcePath],
|
|
|
|
)
|
|
|
|
|
|
|
|
const apiAction = useCallback(
|
|
|
|
async (method, command, data, init) => {
|
2021-05-20 10:16:01 +00:00
|
|
|
if(!allowAction) {
|
|
|
|
throw new ViewNotAllowedError("action")
|
|
|
|
}
|
2021-05-23 16:22:30 +00:00
|
|
|
return apiRequest(method, `${resourcePath}/${command}`, data, init)
|
2021-05-19 17:56:41 +00:00
|
|
|
},
|
2021-05-20 10:16:01 +00:00
|
|
|
[apiRequest, allowAction, resourcePath],
|
2021-05-19 17:56:41 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const retrieveResource = useCallback(
|
|
|
|
async (pk) => {
|
|
|
|
let refreshedResource
|
|
|
|
try {
|
|
|
|
refreshedResource = await apiRetrieve(pk)
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
setError(e)
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
setError(null)
|
|
|
|
setResource(refreshedResource)
|
|
|
|
return refreshedResource
|
|
|
|
},
|
|
|
|
[apiRetrieve],
|
|
|
|
)
|
|
|
|
|
|
|
|
const editResource = useCallback(
|
|
|
|
async (pk, data) => {
|
|
|
|
let editedResource
|
|
|
|
try {
|
|
|
|
editedResource = await apiEdit(pk, data)
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
setError(e)
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
setError(null)
|
|
|
|
setResource(editedResource)
|
|
|
|
return editedResource
|
|
|
|
},
|
|
|
|
[apiEdit],
|
|
|
|
)
|
|
|
|
|
|
|
|
const destroyResource = useCallback(
|
|
|
|
async (pk) => {
|
|
|
|
try {
|
|
|
|
await apiDestroy(pk)
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
setError(e)
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
setError(null)
|
|
|
|
setResource(null)
|
|
|
|
return null
|
|
|
|
},
|
|
|
|
[apiDestroy],
|
|
|
|
)
|
|
|
|
|
|
|
|
useEffect(
|
|
|
|
async () => {
|
|
|
|
if(allowRetrieve && !firstLoad && !running) {
|
|
|
|
// noinspection JSIgnoredPromiseFromCall
|
|
|
|
await retrieveResource()
|
|
|
|
setFirstLoad(true)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[retrieveResource, firstLoad, running, allowRetrieve],
|
|
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
|
|
abort,
|
|
|
|
resource,
|
|
|
|
running,
|
|
|
|
firstLoad,
|
|
|
|
error,
|
|
|
|
apiRequest,
|
|
|
|
allowRetrieve,
|
|
|
|
apiRetrieve,
|
|
|
|
retrieveResource,
|
|
|
|
allowEdit,
|
|
|
|
apiEdit,
|
|
|
|
editResource,
|
|
|
|
allowDestroy,
|
|
|
|
apiDestroy,
|
|
|
|
destroyResource,
|
|
|
|
apiAction,
|
|
|
|
}
|
|
|
|
}
|