2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
import { type ErrorData } from '@/components/InfoError';
|
|
|
|
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
|
|
|
import { ILibraryItem } from '@/models/library';
|
|
|
|
import { ILibraryUpdateData } from '@/models/library';
|
2023-09-11 20:31:54 +03:00
|
|
|
import {
|
|
|
|
IConstituentaList, IConstituentaMeta, ICstCreateData,
|
|
|
|
ICstMovetoData, ICstRenameData, ICstUpdateData,
|
|
|
|
IRSForm, IRSFormUploadData
|
2023-12-13 14:32:57 +03:00
|
|
|
} from '@/models/rsform';
|
2023-07-25 20:27:29 +03:00
|
|
|
import {
|
2023-08-26 17:26:49 +03:00
|
|
|
type DataCallback, deleteUnsubscribe,
|
2023-12-13 14:32:57 +03:00
|
|
|
getTRSFile,
|
2023-08-23 01:36:17 +03:00
|
|
|
patchConstituenta, patchDeleteConstituenta,
|
2023-12-13 14:32:57 +03:00
|
|
|
patchLibraryItem,
|
2023-08-23 01:36:17 +03:00
|
|
|
patchMoveConstituenta, patchRenameConstituenta,
|
2023-12-13 14:32:57 +03:00
|
|
|
patchResetAliases, patchUploadTRS, postClaimLibraryItem, postNewConstituenta, postSubscribe
|
|
|
|
} from '@/utils/backendAPI';
|
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
import { useAuth } from './AuthContext';
|
|
|
|
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-12-13 14:32:57 +03:00
|
|
|
error: ErrorData
|
2023-07-15 17:46:19 +03:00
|
|
|
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
|
|
|
isClaimable: boolean
|
2023-12-16 19:20:26 +03:00
|
|
|
isSubscribed: boolean
|
2023-07-28 01:37:26 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
update: (data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => void
|
|
|
|
claim: (callback?: DataCallback<ILibraryItem>) => void
|
2023-08-26 17:26:49 +03:00
|
|
|
subscribe: (callback?: () => void) => void
|
|
|
|
unsubscribe: (callback?: () => void) => void
|
2023-07-26 23:11:00 +03:00
|
|
|
download: (callback: DataCallback<Blob>) => void
|
2023-07-27 22:04:25 +03:00
|
|
|
upload: (data: IRSFormUploadData, callback: () => void) => void
|
2023-08-11 19:28:12 +03:00
|
|
|
|
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
|
2023-08-23 01:36:17 +03:00
|
|
|
cstRename: (data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => void
|
2023-07-26 23:11:00 +03:00
|
|
|
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)
|
2023-08-22 20:29:07 +03:00
|
|
|
if (context === null) {
|
2023-12-05 01:22:44 +03:00
|
|
|
throw new Error('useRSForm has to be used within <RSFormState.Provider>');
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-12-05 01:22:44 +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-27 15:39:49 +03:00
|
|
|
const library = useLibrary();
|
2023-08-09 17:19:12 +03:00
|
|
|
const { user } = useAuth();
|
|
|
|
const { schema, reload, error, setError, setSchema, loading } = useRSFormDetails({ target: schemaID });
|
2023-12-05 01:22:44 +03:00
|
|
|
const [processing, setProcessing] = useState(false);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
const [toggleTracking, setToggleTracking] = useState(false);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
const isOwned = useMemo(
|
|
|
|
() => {
|
|
|
|
return user?.id === schema?.owner || false;
|
|
|
|
}, [user, schema?.owner]);
|
|
|
|
|
|
|
|
const isClaimable = useMemo(
|
|
|
|
() => {
|
|
|
|
return (user?.id !== schema?.owner && schema?.is_common && !schema?.is_canonical) ?? false;
|
|
|
|
}, [user, schema?.owner, schema?.is_common, schema?.is_canonical]);
|
|
|
|
|
2023-12-16 19:20:26 +03:00
|
|
|
const isSubscribed = useMemo(
|
2023-08-25 22:51:20 +03:00
|
|
|
() => {
|
2023-08-26 19:39:49 +03:00
|
|
|
if (!user || !schema || !user.id) {
|
2023-08-26 17:26:49 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return schema.subscribers.includes(user.id);
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [user, schema, toggleTracking]);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const update = useCallback(
|
2023-08-25 22:51:20 +03:00
|
|
|
(data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => {
|
2023-08-09 17:19:12 +03:00
|
|
|
if (!schema) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setError(undefined)
|
2023-08-25 22:51:20 +03:00
|
|
|
patchLibraryItem(schemaID, {
|
2023-08-09 17:19:12 +03:00
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateItem(newData);
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback(newData);
|
2023-07-26 23:11:00 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
2023-08-27 15:39:49 +03:00
|
|
|
}, [schemaID, setError, setSchema, schema, library]);
|
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);
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateItem(newData);
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback();
|
2023-07-27 22:04:25 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
2023-08-27 15:39:49 +03:00
|
|
|
}, [schemaID, setError, setSchema, schema, library]);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-23 21:38:04 +03:00
|
|
|
const claim = useCallback(
|
2023-08-25 22:51:20 +03:00
|
|
|
(callback?: DataCallback<ILibraryItem>) => {
|
2023-08-09 17:19:12 +03:00
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setError(undefined)
|
2023-08-25 22:51:20 +03:00
|
|
|
postClaimLibraryItem(schemaID, {
|
2023-08-09 17:19:12 +03:00
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateItem(newData);
|
|
|
|
if (!user.subscriptions.includes(newData.id)) {
|
|
|
|
user.subscriptions.push(newData.id);
|
2023-08-27 15:39:49 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback(newData);
|
2023-07-24 22:34:03 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
2023-08-27 15:39:49 +03:00
|
|
|
}, [schemaID, setError, schema, user, setSchema, library]);
|
2023-08-26 17:26:49 +03:00
|
|
|
|
|
|
|
const subscribe = useCallback(
|
|
|
|
(callback?: () => void) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setError(undefined)
|
|
|
|
postSubscribe(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: () => {
|
2023-08-26 19:39:49 +03:00
|
|
|
if (user.id && !schema.subscribers.includes(user.id)) {
|
2023-08-26 17:26:49 +03:00
|
|
|
schema.subscribers.push(user.id);
|
|
|
|
}
|
|
|
|
if (!user.subscriptions.includes(schema.id)) {
|
|
|
|
user.subscriptions.push(schema.id);
|
|
|
|
}
|
|
|
|
setToggleTracking(prev => !prev);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [schemaID, setError, schema, user]);
|
|
|
|
|
|
|
|
const unsubscribe = useCallback(
|
|
|
|
(callback?: () => void) => {
|
|
|
|
if (!schema || !user) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setError(undefined)
|
|
|
|
deleteUnsubscribe(schemaID, {
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: () => {
|
2023-08-26 19:39:49 +03:00
|
|
|
if (user.id && schema.subscribers.includes(user.id)) {
|
2023-08-26 17:26:49 +03:00
|
|
|
schema.subscribers.splice(schema.subscribers.indexOf(user.id), 1);
|
|
|
|
}
|
|
|
|
if (user.subscriptions.includes(schema.id)) {
|
|
|
|
user.subscriptions.splice(user.subscriptions.indexOf(schema.id), 1);
|
|
|
|
}
|
|
|
|
setToggleTracking(prev => !prev);
|
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [schemaID, setError, schema, user]);
|
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,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-09 17:19:12 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(Object.assign(schema, newData));
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(newData.id);
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback();
|
2023-07-27 22:04:25 +03:00
|
|
|
}
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [schemaID, setError, schema, library, 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,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-09 17:19:12 +03:00
|
|
|
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,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-09 17:19:12 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData.schema);
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(newData.schema.id);
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback(newData.new_cst);
|
|
|
|
}
|
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [schemaID, setError, library, 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,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-09 17:19:12 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData);
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(newData.id);
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [schemaID, setError, library, 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)
|
2023-08-22 22:38:27 +03:00
|
|
|
patchConstituenta(String(data.id), {
|
2023-08-09 17:19:12 +03:00
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-27 16:35:17 +03:00
|
|
|
onSuccess: newData => reload(setProcessing, () => {
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(Number(schemaID));
|
2023-08-27 16:35:17 +03:00
|
|
|
if (callback) callback(newData);
|
|
|
|
})
|
2023-08-09 17:19:12 +03:00
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [setError, schemaID, library, reload]);
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-08-23 01:36:17 +03:00
|
|
|
const cstRename = useCallback(
|
|
|
|
(data: ICstRenameData, callback?: DataCallback<IConstituentaMeta>) => {
|
|
|
|
setError(undefined)
|
|
|
|
patchRenameConstituenta(schemaID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: error => setError(error),
|
|
|
|
onSuccess: newData => {
|
2023-08-23 12:15:16 +03:00
|
|
|
setSchema(newData.schema);
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(newData.schema.id);
|
2023-08-23 12:15:16 +03:00
|
|
|
if (callback) callback(newData.new_cst);
|
2023-08-23 01:36:17 +03:00
|
|
|
}
|
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [setError, setSchema, library, schemaID]);
|
2023-08-23 01:36:17 +03:00
|
|
|
|
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,
|
2023-08-23 01:36:17 +03:00
|
|
|
onError: error => setError(error),
|
2023-08-09 17:19:12 +03:00
|
|
|
onSuccess: newData => {
|
|
|
|
setSchema(newData);
|
2023-11-23 18:23:26 +03:00
|
|
|
library.localUpdateTimestamp(Number(schemaID));
|
2023-08-09 17:19:12 +03:00
|
|
|
if (callback) callback();
|
|
|
|
}
|
|
|
|
});
|
2023-11-23 18:23:26 +03:00
|
|
|
}, [schemaID, setError, library, setSchema]);
|
2023-07-23 15:23:01 +03:00
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
return (
|
2023-12-05 01:22:44 +03:00
|
|
|
<RSFormContext.Provider value={{
|
|
|
|
schema,
|
|
|
|
error, loading, processing,
|
2023-12-16 19:20:26 +03:00
|
|
|
isOwned,
|
|
|
|
isClaimable, isSubscribed,
|
2023-12-05 01:22:44 +03:00
|
|
|
update, download, upload, claim, resetAliases, subscribe, unsubscribe,
|
|
|
|
cstUpdate, cstCreate, cstRename, cstDelete, cstMoveTo,
|
|
|
|
}}>
|
|
|
|
{ children }
|
|
|
|
</RSFormContext.Provider>);
|
2023-12-13 14:32:57 +03:00
|
|
|
}
|