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

250 lines
7.3 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 DataCallback, getTRSFile,
2023-08-09 17:19:12 +03:00
patchConstituenta, patchDeleteConstituenta,
patchMoveConstituenta, patchResetAliases, patchRSForm,
patchUploadTRS, postClaimRSForm, postNewConstituenta
2023-08-09 17:19:12 +03:00
} from '../utils/backendAPI'
import {
IConstituentaList, IConstituentaMeta, ICstCreateData,
ICstMovetoData, ICstUpdateData, IRSForm,
IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
} from '../utils/models'
2023-07-25 20:27:29 +03:00
import { useAuth } from './AuthContext'
2023-07-15 17:46:19 +03:00
interface IRSFormContext {
schema?: IRSForm
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
2023-07-21 00:09:05 +03:00
toggleForceAdmin: () => void
toggleReadonly: () => void
2023-07-20 17:11:03 +03:00
toggleTracking: () => void
2023-07-28 01:37:26 +03:00
update: (data: IRSFormUpdateData, callback?: DataCallback<IRSFormMeta>) => void
claim: (callback?: DataCallback<IRSFormMeta>) => void
download: (callback: DataCallback<Blob>) => void
2023-07-27 22:04:25 +03:00
upload: (data: IRSFormUploadData, callback: () => void) => void
2023-07-27 22:04:25 +03:00
resetAliases: (callback: () => void) => void
cstCreate: (data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => void
cstUpdate: (data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => void
cstDelete: (data: IConstituentaList, callback?: () => void) => void
cstMoveTo: (data: ICstMovetoData, callback?: () => void) => 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-08-09 17:19:12 +03:00
const { user } = useAuth();
const { schema, reload, error, setError, setSchema, loading } = useRSFormDetails({ target: schemaID });
const [ processing, setProcessing ] = useState(false);
2023-07-15 17:46:19 +03:00
2023-08-09 17:19:12 +03:00
const [ isForceAdmin, setIsForceAdmin ] = useState(false);
const [ isReadonly, setIsReadonly ] = useState(false);
2023-07-20 17:11:03 +03:00
2023-08-09 17:19:12 +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 && !processing && !isReadonly &&
2023-07-25 20:27:29 +03:00
((isOwned || (isForceAdmin && user?.is_staff)) ?? false)
)
}, [user?.is_staff, isReadonly, isForceAdmin, isOwned, loading, processing])
const isTracking = useMemo(
2023-07-25 20:27:29 +03:00
() => {
return true
2023-08-09 17:19:12 +03:00
}, []);
2023-07-21 00:09:05 +03:00
const toggleTracking = useCallback(
2023-07-25 20:27:29 +03:00
() => {
2023-08-08 23:04:21 +03:00
toast.info('Отслеживание в разработке...')
2023-08-09 17:19:12 +03:00
}, []);
2023-07-20 17:11:03 +03:00
const update = useCallback(
2023-08-09 17:19:12 +03:00
(data: IRSFormUpdateData, callback?: DataCallback<IRSFormMeta>) => {
if (!schema) {
return;
}
setError(undefined)
patchRSForm(schemaID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: error => setError(error),
onSuccess: newData => {
setSchema(Object.assign(schema, newData));
if (callback) callback(newData);
}
2023-08-09 17:19:12 +03:00
});
}, [schemaID, setError, setSchema, schema]);
2023-07-27 22:04:25 +03:00
const upload = useCallback(
2023-08-09 17:19:12 +03:00
(data: IRSFormUploadData, callback?: () => void) => {
if (!schema) {
return;
}
setError(undefined)
patchUploadTRS(schemaID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: error => setError(error),
onSuccess: newData => {
setSchema(newData);
if (callback) callback();
2023-07-27 22:04:25 +03:00
}
2023-08-09 17:19:12 +03:00
});
}, [schemaID, setError, setSchema, schema]);
2023-07-15 17:46:19 +03:00
const claim = useCallback(
2023-08-09 17:19:12 +03:00
(callback?: DataCallback<IRSFormMeta>) => {
if (!schema || !user) {
return;
}
setError(undefined)
postClaimRSForm(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => setError(error),
onSuccess: newData => {
setSchema(Object.assign(schema, newData));
if (callback) callback(newData);
}
2023-08-09 17:19:12 +03:00
});
}, [schemaID, setError, schema, user, setSchema]);
2023-07-15 17:46:19 +03:00
2023-07-27 22:04:25 +03:00
const resetAliases = useCallback(
2023-08-09 17:19:12 +03:00
(callback?: () => void) => {
if (!schema || !user) {
return;
}
setError(undefined)
patchResetAliases(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: newData => {
setSchema(Object.assign(schema, newData));
if (callback) callback();
2023-07-27 22:04:25 +03:00
}
2023-08-09 17:19:12 +03:00
});
}, [schemaID, setError, schema, user, setSchema]);
2023-07-27 22:04:25 +03:00
const download = useCallback(
2023-08-09 17:19:12 +03:00
(callback: DataCallback<Blob>) => {
setError(undefined)
getTRSFile(schemaID, {
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: callback
});
}, [schemaID, setError]);
2023-07-16 22:25:23 +03:00
const cstCreate = useCallback(
2023-08-09 17:19:12 +03:00
(data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => {
setError(undefined)
postNewConstituenta(schemaID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: newData => {
setSchema(newData.schema);
if (callback) callback(newData.new_cst);
}
});
}, [schemaID, setError, setSchema]);
2023-07-18 14:55:40 +03:00
const cstDelete = useCallback(
2023-08-09 17:19:12 +03:00
(data: IConstituentaList, callback?: () => void) => {
setError(undefined)
patchDeleteConstituenta(schemaID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: newData => {
setSchema(newData);
if (callback) callback();
}
});
}, [schemaID, setError, setSchema]);
const cstUpdate = useCallback(
2023-08-09 17:19:12 +03:00
(data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => {
setError(undefined)
patchConstituenta(String(data.id), {
2023-08-09 17:19:12 +03:00
data: data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: newData => {
reload(setProcessing, () => { if (callback != null) callback(newData); })
}
});
}, [setError, reload]);
2023-07-25 20:27:29 +03:00
const cstMoveTo = useCallback(
2023-08-09 17:19:12 +03:00
(data: ICstMovetoData, callback?: () => void) => {
setError(undefined)
patchMoveConstituenta(schemaID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error) },
onSuccess: newData => {
setSchema(newData);
if (callback) callback();
}
});
}, [schemaID, setError, setSchema]);
2023-07-15 17:46:19 +03:00
return (
<RSFormContext.Provider value={{
2023-07-25 20:27:29 +03:00
schema,
2023-07-27 22:04:25 +03:00
error, loading, processing,
isForceAdmin, isReadonly, isOwned, isEditable,
isClaimable, isTracking,
2023-07-25 20:27:29 +03:00
toggleForceAdmin: () => { setIsForceAdmin(prev => !prev) },
toggleReadonly: () => { setIsReadonly(prev => !prev) },
toggleTracking,
update, download, upload, claim, resetAliases,
2023-07-27 22:04:25 +03:00
cstUpdate, cstCreate, cstDelete, cstMoveTo
2023-07-15 17:46:19 +03:00
}}>
{ children }
</RSFormContext.Provider>
2023-08-09 17:19:12 +03:00
);
2023-07-25 20:27:29 +03:00
}