ConceptPortal-public/rsconcept/frontend/src/context/RSFormContext.tsx

241 lines
6.9 KiB
TypeScript
Raw Normal View History

2023-07-25 20:27:29 +03:00
import { createContext, useCallback, useContext, useMemo, useState } from 'react'
import { toast } from 'react-toastify'
import { type ErrorInfo } from '../components/BackendError'
import { useRSFormDetails } from '../hooks/useRSFormDetails'
import {
type BackendCallback, deleteRSForm, getTRSFile,
patchConstituenta, patchDeleteConstituenta, patchMoveConstituenta, patchRSForm,
postClaimRSForm, postNewConstituenta
} from '../utils/backendAPI'
import { type IConstituenta, type IRSForm } from '../utils/models'
import { useAuth } from './AuthContext'
2023-07-15 17:46:19 +03:00
interface IRSFormContext {
schema?: IRSForm
activeCst?: IConstituenta
activeID?: number
2023-07-15 17:46:19 +03:00
error: ErrorInfo
loading: boolean
processing: boolean
2023-07-21 00:09:05 +03:00
isOwned: boolean
2023-07-15 17:46:19 +03:00
isEditable: boolean
isClaimable: boolean
isReadonly: boolean
2023-07-20 17:11:03 +03:00
isTracking: boolean
isForceAdmin: boolean
2023-07-25 20:27:29 +03:00
setActiveID: React.Dispatch<React.SetStateAction<number | undefined>>
2023-07-21 00:09:05 +03:00
toggleForceAdmin: () => void
toggleReadonly: () => void
2023-07-20 17:11:03 +03:00
toggleTracking: () => void
2023-07-25 20:27:29 +03:00
update: (data: any, callback?: BackendCallback) => void
destroy: (callback?: BackendCallback) => void
claim: (callback?: BackendCallback) => void
download: (callback: BackendCallback) => void
2023-07-25 20:27:29 +03:00
cstUpdate: (data: any, callback?: BackendCallback) => void
cstCreate: (data: any, callback?: BackendCallback) => void
cstDelete: (data: any, callback?: BackendCallback) => void
cstMoveTo: (data: any, callback?: BackendCallback) => void
2023-07-15 17:46:19 +03:00
}
2023-07-25 20:27:29 +03:00
const RSFormContext = createContext<IRSFormContext | null>(null)
export const useRSForm = () => {
2023-07-25 20:27:29 +03:00
const context = useContext(RSFormContext)
if (context == null) {
throw new Error(
'useRSForm has to be used within <RSFormState.Provider>'
2023-07-25 20:27:29 +03:00
)
}
2023-07-25 20:27:29 +03:00
return context
}
2023-07-15 17:46:19 +03:00
interface RSFormStateProps {
schemaID: string
2023-07-15 17:46:19 +03:00
children: React.ReactNode
}
export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
2023-07-25 20:27:29 +03:00
const { user } = useAuth()
const { schema, reload, error, setError, setSchema, loading } = useRSFormDetails({ target: schemaID })
2023-07-15 17:46:19 +03:00
const [processing, setProcessing] = useState(false)
2023-07-25 20:27:29 +03:00
const [activeID, setActiveID] = useState<number | undefined>(undefined)
2023-07-15 17:46:19 +03:00
2023-07-25 20:27:29 +03:00
const [isForceAdmin, setIsForceAdmin] = useState(false)
const [isReadonly, setIsReadonly] = useState(false)
2023-07-20 17:11:03 +03:00
2023-07-25 20:27:29 +03:00
const isOwned = useMemo(() => user?.id === schema?.owner || false, [user, schema?.owner])
const isClaimable = useMemo(() => user?.id !== schema?.owner || false, [user, schema?.owner])
const isEditable = useMemo(
2023-07-25 20:27:29 +03:00
() => {
return (
!loading && !isReadonly &&
((isOwned || (isForceAdmin && user?.is_staff)) ?? false)
)
}, [user, isReadonly, isForceAdmin, isOwned, loading])
const activeCst = useMemo(
2023-07-25 20:27:29 +03:00
() => {
return schema?.items?.find((cst) => cst.id === activeID)
}, [schema?.items, activeID])
const isTracking = useMemo(
2023-07-25 20:27:29 +03:00
() => {
return true
}, [])
2023-07-21 00:09:05 +03:00
const toggleTracking = useCallback(
2023-07-25 20:27:29 +03:00
() => {
toast('not implemented yet')
}, [])
2023-07-20 17:11:03 +03:00
const update = useCallback(
2023-07-25 20:27:29 +03:00
(data: any, callback?: BackendCallback) => {
setError(undefined)
patchRSForm(schemaID, {
data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: (response) => {
reload()
.then(() => { if (callback != null) callback(response); })
.catch(console.error);
}
}).catch(console.error);
}, [schemaID, setError, reload])
2023-07-15 17:46:19 +03:00
const destroy = useCallback(
2023-07-25 20:27:29 +03:00
(callback?: BackendCallback) => {
setError(undefined)
deleteRSForm(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: callback
}).catch(console.error);
}, [schemaID, setError])
2023-07-15 17:46:19 +03:00
const claim = useCallback(
2023-07-25 20:27:29 +03:00
(callback?: BackendCallback) => {
if (!schema || !user) {
return;
}
2023-07-25 20:27:29 +03:00
setError(undefined)
postClaimRSForm(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: (response) => {
schema.owner = user.id
schema.time_update = response.data.time_update
setSchema(schema)
if (callback != null) callback(response)
}
}).catch(console.error);
}, [schemaID, setError, schema, user, setSchema])
2023-07-15 17:46:19 +03:00
const download = useCallback(
2023-07-25 20:27:29 +03:00
(callback: BackendCallback) => {
setError(undefined)
getTRSFile(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: callback
}).catch(console.error);
}, [schemaID, setError])
2023-07-16 22:25:23 +03:00
const cstUpdate = useCallback(
2023-07-25 20:27:29 +03:00
(data: any, callback?: BackendCallback) => {
setError(undefined)
patchConstituenta(String(activeID), {
data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: callback
}).catch(console.error);
}, [activeID, setError])
2023-07-18 14:55:40 +03:00
const cstCreate = useCallback(
2023-07-25 20:27:29 +03:00
(data: any, callback?: BackendCallback) => {
setError(undefined)
postNewConstituenta(schemaID, {
data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: (response) => {
setSchema(response.data.schema)
if (callback != null) callback(response)
}
}).catch(console.error);
}, [schemaID, setError, setSchema])
const cstDelete = useCallback(
2023-07-25 20:27:29 +03:00
(data: any, callback?: BackendCallback) => {
setError(undefined)
patchDeleteConstituenta(schemaID, {
2023-07-25 20:27:29 +03:00
data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSucccess: (response) => {
setSchema(response.data)
if (callback != null) callback(response)
}
}).catch(console.error);
}, [schemaID, setError, setSchema])
const cstMoveTo = useCallback(
(data: any, callback?: BackendCallback) => {
setError(undefined)
patchMoveConstituenta(schemaID, {
data,
showError: true,
setLoading: setProcessing,
2023-07-25 20:27:29 +03:00
onError: error => { setError(error) },
onSucccess: (response) => {
setSchema(response.data)
if (callback != null) callback(response)
}
2023-07-25 20:27:29 +03:00
}).catch(console.error);
}, [schemaID, setError, setSchema])
2023-07-15 17:46:19 +03:00
return (
<RSFormContext.Provider value={{
2023-07-25 20:27:29 +03:00
schema,
error,
loading,
processing,
activeID,
activeCst,
setActiveID,
2023-07-25 20:27:29 +03:00
isForceAdmin,
isReadonly,
toggleForceAdmin: () => { setIsForceAdmin(prev => !prev) },
toggleReadonly: () => { setIsReadonly(prev => !prev) },
isOwned,
isEditable,
isClaimable,
isTracking,
toggleTracking,
update,
download,
destroy,
claim,
cstUpdate,
cstCreate,
cstDelete,
cstMoveTo
2023-07-15 17:46:19 +03:00
}}>
{ children }
</RSFormContext.Provider>
2023-07-25 20:27:29 +03:00
)
}