1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-11-22 21:14:18 +00:00
pds-2021-g2-nest/nest_frontend/hooks/useBackendViewset.js

195 lines
No EOL
5.8 KiB
JavaScript

import { useCallback, useEffect, useState } from "react"
import useBackendRequest from "./useBackendRequest"
/**
* An hook which allows access to a full REST viewset (list, create, retrieve, edit, delete).
*
* @param resourcesPath - The path of the resource directory.
* @param pkName - The name of the primary key attribute of the elements.
* @param allowViews - An object with maps views to a boolean detailing if they're allowed in the viewset or not.
*/
export default function useBackendViewset(resourcesPath, pkName,
{
list: allowList = true,
create: allowCreate = true,
retrieve: allowRetrieve = true,
edit: allowEdit = true,
destroy: allowDestroy = true,
command: allowCommand = false,
action: allowAction = false,
} = {},
) {
const { abort, running, apiRequest } = useBackendRequest()
const [firstLoad, setFirstLoad] = useState(false)
const [resources, setResources] = useState([])
const [error, setError] = useState(null)
const apiList = useCallback(
async (init) => {
if(!allowList) {
throw new ViewNotAllowedError("list")
}
return apiRequest("GET", `${resourcesPath}`, undefined, init)
},
[apiRequest, allowList, resourcesPath],
)
const apiRetrieve = useCallback(
async (id, init) => {
if(!allowRetrieve) {
throw new ViewNotAllowedError("retrieve")
}
return apiRequest("GET", `${resourcesPath}${id}`, undefined, init)
},
[apiRequest, allowRetrieve, resourcesPath],
)
const apiCreate = useCallback(
async (data, init) => {
if(!allowCreate) {
throw new ViewNotAllowedError("create")
}
return apiRequest("POST", `${resourcesPath}`, data, init)
},
[apiRequest, allowCreate, resourcesPath],
)
const apiEdit = useCallback(
async (id, data, init) => {
if(!allowEdit) {
throw new ViewNotAllowedError("edit")
}
return apiRequest("PUT", `${resourcesPath}${id}`, data, init)
},
[apiRequest, allowEdit, resourcesPath],
)
const apiDestroy = useCallback(
async (id, init) => {
if(!allowDestroy) {
throw new ViewNotAllowedError("destroy")
}
return apiRequest("DELETE", `${resourcesPath}${id}`, undefined, init)
},
[apiRequest, allowDestroy, resourcesPath],
)
const apiCommand = useCallback(
async (method, command, data, init) => {
if(!allowCommand) {
throw new ViewNotAllowedError("command")
}
return apiRequest(method, `${resourcesPath}${command}`, data, init)
},
[apiRequest, allowCommand, resourcesPath],
)
const apiAction = useCallback(
async (method, id, command, data, init) => {
if(!allowAction) {
throw new ViewNotAllowedError("action")
}
return apiRequest(method, `${resourcesPath}${id}/${command}`, data, init)
},
[apiRequest, allowAction, resourcesPath],
)
const listResources = useCallback(
async () => {
try {
setResources(await apiList())
}
catch(e) {
setError(e)
throw e
}
setError(null)
return {}
},
[apiList],
)
const retrieveResource = useCallback(
async (pk) => {
const refreshedResource = await apiRetrieve(pk)
setResources(res => res.map(resource => {
if(resource[pkName] === pk) {
return refreshedResource
}
return resource
}))
return refreshedResource
},
[apiRetrieve, pkName],
)
const createResource = useCallback(
async (data) => {
const newResource = await apiCreate(data)
setResources(res => [...res, newResource])
return newResource
},
[apiCreate],
)
const editResource = useCallback(
async (pk, data) => {
const editedResource = await apiEdit(pk, data)
setResources(res => res.map(resource => {
if(resource[pkName] === pk) {
return editedResource
}
return resource
}))
return editedResource
},
[apiEdit, pkName],
)
const destroyResource = useCallback(
async (pk) => {
await apiDestroy(pk)
setResources(res => res.filter(resource => resource[pkName] !== pk))
return null
},
[apiDestroy, pkName],
)
useEffect(
async () => {
if(allowList && !firstLoad && !running) {
await listResources()
setFirstLoad(true)
}
},
[listResources, firstLoad, running, allowList],
)
return {
abort,
resources,
firstLoad,
running,
error,
apiRequest,
allowList,
apiList,
listResources,
allowRetrieve,
apiRetrieve,
retrieveResource,
allowCreate,
apiCreate,
createResource,
allowEdit,
apiEdit,
editResource,
allowDestroy,
apiDestroy,
destroyResource,
apiCommand,
apiAction,
}
}