Portal/rsconcept/frontend/src/context/OssContext.tsx

391 lines
10 KiB
TypeScript
Raw Normal View History

2024-06-07 20:17:03 +03:00
'use client';
2024-07-27 22:50:10 +03:00
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
2024-06-07 20:17:03 +03:00
import { DataCallback } from '@/backend/apiTransport';
2024-06-07 20:17:03 +03:00
import {
patchLibraryItem,
patchSetAccessPolicy,
patchSetEditors,
2024-06-07 20:17:03 +03:00
patchSetLocation,
patchSetOwner
} from '@/backend/library';
2024-07-28 21:29:46 +03:00
import {
patchCreateInput,
patchDeleteOperation,
patchSetInput,
2024-07-29 22:30:24 +03:00
patchUpdateOperation,
2024-07-28 21:29:46 +03:00
patchUpdatePositions,
2024-07-29 22:30:24 +03:00
postCreateOperation,
2024-10-28 14:52:30 +03:00
postExecuteOperation,
postRelocateConstituents
2024-07-28 21:29:46 +03:00
} from '@/backend/oss';
2024-06-07 20:17:03 +03:00
import { type ErrorData } from '@/components/info/InfoError';
import { AccessPolicy, ILibraryItem } from '@/models/library';
import { ILibraryUpdateData } from '@/models/library';
2024-07-27 22:50:10 +03:00
import {
2024-10-28 14:52:30 +03:00
ICstRelocateData,
2024-07-27 22:50:10 +03:00
IOperationCreateData,
IOperationData,
IOperationDeleteData,
2024-07-27 22:50:10 +03:00
IOperationSchema,
IOperationSchemaData,
2024-07-28 21:29:46 +03:00
IOperationSetInputData,
2024-07-29 22:30:24 +03:00
IOperationUpdateData,
2024-07-27 22:50:10 +03:00
IPositionsData,
ITargetOperation
} from '@/models/oss';
2024-06-07 20:17:03 +03:00
import { UserID } from '@/models/user';
import { contextOutsideScope } from '@/utils/labels';
import { useAuth } from './AuthContext';
import { useGlobalOss } from './GlobalOssContext';
2024-06-07 20:17:03 +03:00
import { useLibrary } from './LibraryContext';
interface IOssContext {
schema?: IOperationSchema;
itemID: string;
loading: boolean;
loadingError: ErrorData;
2024-06-07 20:17:03 +03:00
processing: boolean;
processingError: ErrorData;
isOwned: boolean;
update: (data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => void;
setOwner: (newOwner: UserID, callback?: () => void) => void;
setAccessPolicy: (newPolicy: AccessPolicy, callback?: () => void) => void;
setLocation: (newLocation: string, callback?: () => void) => void;
setEditors: (newEditors: UserID[], callback?: () => void) => void;
2024-07-20 18:26:32 +03:00
2024-07-23 23:03:58 +03:00
savePositions: (data: IPositionsData, callback?: () => void) => void;
createOperation: (data: IOperationCreateData, callback?: DataCallback<IOperationData>) => void;
deleteOperation: (data: IOperationDeleteData, callback?: () => void) => void;
createInput: (data: ITargetOperation, callback?: DataCallback<ILibraryItem>) => void;
2024-07-28 21:29:46 +03:00
setInput: (data: IOperationSetInputData, callback?: () => void) => void;
2024-07-29 22:30:24 +03:00
updateOperation: (data: IOperationUpdateData, callback?: () => void) => void;
executeOperation: (data: ITargetOperation, callback?: () => void) => void;
2024-10-28 14:52:30 +03:00
relocateConstituents: (data: ICstRelocateData, callback?: () => void) => void;
2024-06-07 20:17:03 +03:00
}
const OssContext = createContext<IOssContext | null>(null);
export const useOSS = () => {
const context = useContext(OssContext);
if (context === null) {
throw new Error(contextOutsideScope('useOSS', 'OssState'));
}
return context;
};
interface OssStateProps {
itemID: string;
}
2024-09-19 17:48:48 +03:00
export const OssState = ({ itemID, children }: React.PropsWithChildren<OssStateProps>) => {
2024-06-07 20:17:03 +03:00
const library = useLibrary();
const ossData = useGlobalOss();
2024-06-07 20:17:03 +03:00
const { user } = useAuth();
const [processing, setProcessing] = useState(false);
const [processingError, setProcessingError] = useState<ErrorData>(undefined);
const isOwned = useMemo(() => {
return user?.id === ossData.schema?.owner || false;
}, [user, ossData.schema?.owner]);
2024-06-07 20:17:03 +03:00
2024-07-27 22:50:10 +03:00
useEffect(() => {
ossData.setID(itemID);
}, [itemID, ossData]);
2024-07-27 22:50:10 +03:00
2024-06-07 20:17:03 +03:00
const update = useCallback(
(data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => {
if (!ossData.schema) {
2024-06-07 20:17:03 +03:00
return;
}
setProcessingError(undefined);
patchLibraryItem(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
const fullData: IOperationSchemaData = Object.assign(ossData.schema!, newData);
ossData.setData(fullData);
2024-06-07 20:17:03 +03:00
library.localUpdateItem(newData);
2024-12-04 22:52:45 +03:00
callback?.(newData);
2024-06-07 20:17:03 +03:00
}
});
},
[itemID, library, ossData]
2024-06-07 20:17:03 +03:00
);
const setOwner = useCallback(
(newOwner: UserID, callback?: () => void) => {
if (!ossData.schema) {
2024-06-07 20:17:03 +03:00
return;
}
setProcessingError(undefined);
patchSetOwner(itemID, {
data: { user: newOwner },
2024-06-07 20:17:03 +03:00
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
ossData.partialUpdate({ owner: newOwner });
library.reloadItems(callback);
2024-06-07 20:17:03 +03:00
}
});
},
[itemID, ossData, library]
2024-06-07 20:17:03 +03:00
);
const setAccessPolicy = useCallback(
(newPolicy: AccessPolicy, callback?: () => void) => {
if (!ossData.schema) {
2024-06-07 20:17:03 +03:00
return;
}
setProcessingError(undefined);
patchSetAccessPolicy(itemID, {
data: {
access_policy: newPolicy
},
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
ossData.partialUpdate({ access_policy: newPolicy });
library.reloadItems(callback);
2024-06-07 20:17:03 +03:00
}
});
},
[itemID, ossData, library]
2024-06-07 20:17:03 +03:00
);
const setLocation = useCallback(
(newLocation: string, callback?: () => void) => {
if (!ossData.schema) {
2024-06-07 20:17:03 +03:00
return;
}
setProcessingError(undefined);
patchSetLocation(itemID, {
data: {
location: newLocation
},
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
ossData.partialUpdate({ location: newLocation });
library.reloadItems(callback);
2024-06-07 20:17:03 +03:00
}
});
},
[itemID, ossData, library]
2024-06-07 20:17:03 +03:00
);
const setEditors = useCallback(
(newEditors: UserID[], callback?: () => void) => {
if (!ossData.schema) {
2024-06-07 20:17:03 +03:00
return;
}
setProcessingError(undefined);
patchSetEditors(itemID, {
2024-06-07 20:17:03 +03:00
data: {
users: newEditors
},
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
ossData.partialUpdate({ editors: newEditors });
library.reloadItems(callback);
2024-06-07 20:17:03 +03:00
}
});
},
[itemID, ossData, library]
2024-06-07 20:17:03 +03:00
);
2024-07-23 23:03:58 +03:00
const savePositions = useCallback(
(data: IPositionsData, callback?: () => void) => {
setProcessingError(undefined);
patchUpdatePositions(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
library.localUpdateTimestamp(Number(itemID));
2024-12-04 22:52:45 +03:00
callback?.();
2024-07-23 23:03:58 +03:00
}
});
},
[itemID, library]
2024-07-23 23:03:58 +03:00
);
2024-07-20 18:26:32 +03:00
const createOperation = useCallback(
(data: IOperationCreateData, callback?: DataCallback<IOperationData>) => {
2024-07-20 18:26:32 +03:00
setProcessingError(undefined);
postCreateOperation(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData.oss);
2024-07-20 18:26:32 +03:00
library.localUpdateTimestamp(newData.oss.id);
2024-12-04 22:52:45 +03:00
callback?.(newData.new_operation);
2024-07-20 18:26:32 +03:00
}
});
},
[itemID, library, ossData]
2024-07-20 18:26:32 +03:00
);
2024-07-23 23:03:58 +03:00
const deleteOperation = useCallback(
(data: IOperationDeleteData, callback?: () => void) => {
2024-07-23 23:03:58 +03:00
setProcessingError(undefined);
patchDeleteOperation(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData);
library.reloadItems(callback);
2024-07-23 23:03:58 +03:00
}
});
},
[itemID, library, ossData]
2024-07-23 23:03:58 +03:00
);
const createInput = useCallback(
(data: ITargetOperation, callback?: DataCallback<ILibraryItem>) => {
setProcessingError(undefined);
patchCreateInput(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData.oss);
library.reloadItems(() => {
2024-12-04 22:52:45 +03:00
callback?.(newData.new_schema);
});
}
});
},
[itemID, library, ossData]
);
2024-07-28 21:29:46 +03:00
const setInput = useCallback(
(data: IOperationSetInputData, callback?: () => void) => {
if (!ossData.schema) {
2024-07-28 21:29:46 +03:00
return;
}
setProcessingError(undefined);
patchSetInput(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData);
library.reloadItems(callback);
2024-07-28 21:29:46 +03:00
}
});
},
[itemID, ossData, library]
2024-07-28 21:29:46 +03:00
);
2024-07-29 22:30:24 +03:00
const updateOperation = useCallback(
(data: IOperationUpdateData, callback?: () => void) => {
if (!ossData.schema) {
2024-07-29 22:30:24 +03:00
return;
}
setProcessingError(undefined);
patchUpdateOperation(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData);
library.reloadItems(callback);
2024-07-29 22:30:24 +03:00
}
});
},
[itemID, library, ossData]
2024-07-29 22:30:24 +03:00
);
const executeOperation = useCallback(
(data: ITargetOperation, callback?: () => void) => {
if (!ossData.schema) {
2024-07-29 22:30:24 +03:00
return;
}
setProcessingError(undefined);
postExecuteOperation(itemID, {
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: newData => {
ossData.setData(newData);
library.reloadItems(callback);
2024-07-29 22:30:24 +03:00
}
});
},
[itemID, library, ossData]
2024-07-29 22:30:24 +03:00
);
2024-10-28 14:52:30 +03:00
const relocateConstituents = useCallback(
(data: ICstRelocateData, callback?: () => void) => {
if (!ossData.schema) {
2024-10-28 14:52:30 +03:00
return;
}
setProcessingError(undefined);
postRelocateConstituents({
data: data,
showError: true,
setLoading: setProcessing,
onError: setProcessingError,
onSuccess: () => {
ossData.reload();
library.reloadItems(callback);
2024-10-28 14:52:30 +03:00
}
});
},
[library, ossData]
2024-10-28 14:52:30 +03:00
);
2024-06-07 20:17:03 +03:00
return (
<OssContext.Provider
value={{
schema: ossData.schema,
2024-06-07 20:17:03 +03:00
itemID,
loading: ossData.loading,
loadingError: ossData.loadingError,
2024-06-07 20:17:03 +03:00
processing,
processingError,
isOwned,
update,
setOwner,
setEditors,
setAccessPolicy,
2024-07-20 18:26:32 +03:00
setLocation,
2024-07-23 23:03:58 +03:00
savePositions,
createOperation,
deleteOperation,
2024-07-28 21:29:46 +03:00
createInput,
2024-07-29 22:30:24 +03:00
setInput,
updateOperation,
2024-10-28 14:52:30 +03:00
executeOperation,
relocateConstituents
2024-06-07 20:17:03 +03:00
}}
>
{children}
</OssContext.Provider>
);
};