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
|
|
|
|
2024-07-24 23:20:45 +03:00
|
|
|
import { DataCallback } from '@/backend/apiTransport';
|
2024-06-07 20:17:03 +03:00
|
|
|
import {
|
|
|
|
patchLibraryItem,
|
|
|
|
patchSetAccessPolicy,
|
2024-07-24 23:45:06 +03:00
|
|
|
patchSetEditors,
|
2024-06-07 20:17:03 +03:00
|
|
|
patchSetLocation,
|
2024-08-20 15:09:36 +03:00
|
|
|
patchSetOwner
|
2024-07-24 23:20:45 +03:00
|
|
|
} 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,
|
2024-08-01 20:10:58 +03:00
|
|
|
IOperationData,
|
2024-08-15 23:23:10 +03:00
|
|
|
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';
|
2024-08-16 12:44:09 +03:00
|
|
|
import { useGlobalOss } from './GlobalOssContext';
|
2024-06-07 20:17:03 +03:00
|
|
|
import { useLibrary } from './LibraryContext';
|
|
|
|
|
|
|
|
interface IOssContext {
|
|
|
|
schema?: IOperationSchema;
|
|
|
|
itemID: string;
|
|
|
|
|
|
|
|
loading: boolean;
|
2024-08-16 12:44:09 +03:00
|
|
|
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;
|
2024-08-01 20:10:58 +03:00
|
|
|
createOperation: (data: IOperationCreateData, callback?: DataCallback<IOperationData>) => void;
|
2024-08-15 23:23:10 +03:00
|
|
|
deleteOperation: (data: IOperationDeleteData, callback?: () => void) => void;
|
2024-07-28 00:37:33 +03:00
|
|
|
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();
|
2024-08-16 12:44:09 +03:00
|
|
|
const oss = useGlobalOss();
|
|
|
|
const model = oss.schema;
|
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(() => {
|
2024-08-16 12:44:09 +03:00
|
|
|
return user?.id === model?.owner || false;
|
|
|
|
}, [user, model?.owner]);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
2024-07-27 22:50:10 +03:00
|
|
|
useEffect(() => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setID(itemID);
|
2024-10-23 16:20:29 +03:00
|
|
|
}, [itemID, oss]);
|
2024-07-27 22:50:10 +03:00
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
const update = useCallback(
|
|
|
|
(data: ILibraryUpdateData, callback?: DataCallback<ILibraryItem>) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-06-07 20:17:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchLibraryItem(itemID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: newData => {
|
2024-08-16 12:44:09 +03:00
|
|
|
const fullData: IOperationSchemaData = Object.assign(model, newData);
|
|
|
|
oss.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
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library, oss]
|
2024-06-07 20:17:03 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const setOwner = useCallback(
|
|
|
|
(newOwner: UserID, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-06-07 20:17:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchSetOwner(itemID, {
|
|
|
|
data: {
|
|
|
|
user: newOwner
|
|
|
|
},
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: () => {
|
2024-08-16 12:44:09 +03:00
|
|
|
model.owner = newOwner;
|
2024-08-28 21:31:57 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-08-28 21:31:57 +03:00
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library]
|
2024-06-07 20:17:03 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const setAccessPolicy = useCallback(
|
|
|
|
(newPolicy: AccessPolicy, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-06-07 20:17:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchSetAccessPolicy(itemID, {
|
|
|
|
data: {
|
|
|
|
access_policy: newPolicy
|
|
|
|
},
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: () => {
|
2024-08-16 12:44:09 +03:00
|
|
|
model.access_policy = newPolicy;
|
2024-08-28 21:31:57 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-08-28 21:31:57 +03:00
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library]
|
2024-06-07 20:17:03 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const setLocation = useCallback(
|
|
|
|
(newLocation: string, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-06-07 20:17:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchSetLocation(itemID, {
|
|
|
|
data: {
|
|
|
|
location: newLocation
|
|
|
|
},
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: () => {
|
2024-08-16 12:44:09 +03:00
|
|
|
model.location = newLocation;
|
2024-08-28 21:31:57 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-08-28 21:31:57 +03:00
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library]
|
2024-06-07 20:17:03 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const setEditors = useCallback(
|
|
|
|
(newEditors: UserID[], callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-06-07 20:17:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
2024-07-24 23:45:06 +03:00
|
|
|
patchSetEditors(itemID, {
|
2024-06-07 20:17:03 +03:00
|
|
|
data: {
|
|
|
|
users: newEditors
|
|
|
|
},
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: () => {
|
2024-08-16 12:44:09 +03:00
|
|
|
model.editors = newEditors;
|
2024-08-28 21:31:57 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-08-28 21:31:57 +03:00
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, 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
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, library]
|
2024-07-23 23:03:58 +03:00
|
|
|
);
|
|
|
|
|
2024-07-20 18:26:32 +03:00
|
|
|
const createOperation = useCallback(
|
2024-08-01 20:10:58 +03:00
|
|
|
(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 => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.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
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, library, oss]
|
2024-07-20 18:26:32 +03:00
|
|
|
);
|
|
|
|
|
2024-07-23 23:03:58 +03:00
|
|
|
const deleteOperation = useCallback(
|
2024-08-15 23:23:10 +03:00
|
|
|
(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 => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setData(newData);
|
2024-09-04 14:35:03 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-09-04 14:35:03 +03:00
|
|
|
});
|
2024-07-23 23:03:58 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, library, oss]
|
2024-07-23 23:03:58 +03:00
|
|
|
);
|
|
|
|
|
2024-07-28 00:37:33 +03:00
|
|
|
const createInput = useCallback(
|
|
|
|
(data: ITargetOperation, callback?: DataCallback<ILibraryItem>) => {
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchCreateInput(itemID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: newData => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setData(newData.oss);
|
2024-07-28 00:37:33 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.(newData.new_schema);
|
2024-07-28 00:37:33 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, library, oss]
|
2024-07-28 00:37:33 +03:00
|
|
|
);
|
|
|
|
|
2024-07-28 21:29:46 +03:00
|
|
|
const setInput = useCallback(
|
|
|
|
(data: IOperationSetInputData, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-07-28 21:29:46 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchSetInput(itemID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: newData => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setData(newData);
|
2024-09-16 14:02:27 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-09-16 14:02:27 +03:00
|
|
|
});
|
2024-07-28 21:29:46 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library, oss]
|
2024-07-28 21:29:46 +03:00
|
|
|
);
|
|
|
|
|
2024-07-29 22:30:24 +03:00
|
|
|
const updateOperation = useCallback(
|
|
|
|
(data: IOperationUpdateData, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-07-29 22:30:24 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
patchUpdateOperation(itemID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: newData => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setData(newData);
|
2024-07-29 22:30:24 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-07-29 22:30:24 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library, oss]
|
2024-07-29 22:30:24 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
const executeOperation = useCallback(
|
|
|
|
(data: ITargetOperation, callback?: () => void) => {
|
2024-08-16 12:44:09 +03:00
|
|
|
if (!model) {
|
2024-07-29 22:30:24 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
postExecuteOperation(itemID, {
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: newData => {
|
2024-08-16 12:44:09 +03:00
|
|
|
oss.setData(newData);
|
2024-07-29 22:30:24 +03:00
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-07-29 22:30:24 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2024-10-23 16:20:29 +03:00
|
|
|
[itemID, model, library, oss]
|
2024-07-29 22:30:24 +03:00
|
|
|
);
|
|
|
|
|
2024-10-28 14:52:30 +03:00
|
|
|
const relocateConstituents = useCallback(
|
|
|
|
(data: ICstRelocateData, callback?: () => void) => {
|
|
|
|
if (!model) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
setProcessingError(undefined);
|
|
|
|
postRelocateConstituents({
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setProcessing,
|
|
|
|
onError: setProcessingError,
|
|
|
|
onSuccess: () => {
|
|
|
|
oss.reload();
|
|
|
|
library.reloadItems(() => {
|
2024-12-04 22:52:45 +03:00
|
|
|
callback?.();
|
2024-10-28 14:52:30 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[model, library, oss]
|
|
|
|
);
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
return (
|
|
|
|
<OssContext.Provider
|
|
|
|
value={{
|
2024-08-16 12:44:09 +03:00
|
|
|
schema: model,
|
2024-06-07 20:17:03 +03:00
|
|
|
itemID,
|
2024-08-16 12:44:09 +03:00
|
|
|
loading: oss.loading,
|
|
|
|
loadingError: oss.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,
|
2024-07-28 00:37:33 +03:00
|
|
|
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>
|
|
|
|
);
|
|
|
|
};
|