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 {
|
2023-07-26 23:11:00 +03:00
|
|
|
type DataCallback, deleteRSForm, getTRSFile,
|
2023-08-09 17:19:12 +03:00
|
|
|
patchConstituenta, patchDeleteConstituenta,
|
|
|
|
patchMoveConstituenta, patchResetAliases, patchRSForm,
|
|
|
|
patchUploadTRS, postClaimRSForm, postCloneRSForm, postNewConstituenta
|
|
|
|
} from '../utils/backendAPI'
|
2023-07-26 23:11:00 +03:00
|
|
|
import {
|
2023-08-02 18:24:17 +03:00
|
|
|
IConstituentaList, IConstituentaMeta, ICstCreateData,
|
2023-08-09 17:19:12 +03:00
|
|
|
ICstMovetoData, ICstUpdateData, IRSForm, IRSFormCreateData,
|
|
|
|
IRSFormData, IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
|
2023-07-26 23:11:00 +03:00
|
|
|
} from '../utils/models'
|
2023-07-25 20:27:29 +03:00
|
|
|
import { useAuth } from './AuthContext'
|
2023-08-09 17:19:12 +03:00
|
|
|
import { useLibrary } from './LibraryContext'
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface IRSFormContext {
|
|
|
|
schema?: IRSForm
|
2023-07-24 22:34:03 +03:00
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
error: ErrorInfo
|
|
|
|
loading: boolean
|
|
|
|
processing: boolean
|
2023-07-24 22:34:03 +03:00
|
|
|
|
2023-07-21 00:09:05 +03:00
|
|
|
isOwned: boolean
|
2023-07-15 17:46:19 +03:00
|
|
|
isEditable: boolean
|
|
|
|
isClaimable: boolean
|
2023-07-24 22:34:03 +03:00
|
|
|
isReadonly: boolean
|
2023-07-20 17:11:03 +03:00
|
|
|
isTracking: boolean
|
2023-07-24 22:34:03 +03:00
|
|
|
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
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
update: (data: IRSFormUpdateData, callback?: DataCallback<IRSFormMeta>) => void
|
2023-07-27 22:04:25 +03:00
|
|
|
destroy: (callback?: () => void) => void
|
2023-07-26 23:11:00 +03:00
|
|
|
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-28 01:37:26 +03:00
|
|
|
clone: (data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => void
|
2023-07-27 22:04:25 +03:00
|
|
|
resetAliases: (callback: () => void) => void
|
2023-07-23 21:38:04 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
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)
|
2023-07-24 22:34:03 +03:00
|
|
|
export const useRSForm = () => {
|
2023-07-25 20:27:29 +03:00
|
|
|
const context = useContext(RSFormContext)
|
|
|
|
if (context == null) {
|
2023-07-24 22:34:03 +03:00
|
|
|
throw new Error(
|
|
|
|
'useRSForm has to be used within <RSFormState.Provider>'
|
2023-07-25 20:27:29 +03:00
|
|
|
)
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-07-25 20:27:29 +03:00
|
|
|
return context
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface RSFormStateProps {
|
2023-07-23 15:23:01 +03:00
|
|
|
schemaID: string
|
2023-07-15 17:46:19 +03:00
|
|
|
children: React.ReactNode
|
|
|
|
}
|
|
|
|
|
2023-07-23 15:23:01 +03:00
|
|
|
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);
|
|
|
|
const library = useLibrary();
|
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]);
|
2023-07-23 21:38:04 +03:00
|
|
|
const isEditable = useMemo(
|
2023-07-25 20:27:29 +03:00
|
|
|
() => {
|
|
|
|
return (
|
|
|
|
!loading && !isReadonly &&
|
|
|
|
((isOwned || (isForceAdmin && user?.is_staff)) ?? false)
|
|
|
|
)
|
2023-07-26 23:11:00 +03:00
|
|
|
}, [user?.is_staff, isReadonly, isForceAdmin, isOwned, loading])
|
2023-07-24 22:34:03 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
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
|
|
|
|
2023-07-23 21:38:04 +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
|
|
|
|
2023-07-23 21:38:04 +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-07-26 23:11:00 +03:00
|
|
|
}
|
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
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const destroy = useCallback(
|
2023-08-09 17:19:12 +03:00
|
|
|
(callback?: () => void) => {
|
|
|
|
setError(undefined)
|
|
|
|
deleteRSForm(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: () => {
|
|
|
|
setSchema(undefined);
|
|
|
|
library.reload();
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [schemaID, setError, setSchema, library]);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-23 21:38:04 +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-07-24 22:34:03 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
|
|
|
}, [schemaID, setError, schema, user, setSchema]);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-28 01:37:26 +03:00
|
|
|
const clone = useCallback(
|
2023-08-09 17:19:12 +03:00
|
|
|
(data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setError(undefined)
|
|
|
|
postCloneRSForm(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: newSchema => {
|
|
|
|
library.reload();
|
|
|
|
if (callback) callback(newSchema);
|
2023-07-28 01:37:26 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
|
|
|
}, [schemaID, setError, schema, user, library]);
|
2023-07-28 01:37:26 +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
|
|
|
|
2023-07-23 21:38:04 +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
|
|
|
|
2023-07-26 23:11:00 +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
|
|
|
|
2023-07-26 23:11:00 +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]);
|
2023-07-23 21:38:04 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const cstUpdate = useCallback(
|
2023-08-09 17:19:12 +03:00
|
|
|
(data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => {
|
|
|
|
setError(undefined)
|
|
|
|
patchConstituenta(String(data.id), {
|
|
|
|
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-23 15:23:01 +03:00
|
|
|
|
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,
|
2023-07-28 01:37:26 +03:00
|
|
|
update, download, upload, destroy, claim, resetAliases, clone,
|
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
|
|
|
}
|