Portal/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx

226 lines
6.3 KiB
TypeScript
Raw Normal View History

2024-06-07 20:17:03 +03:00
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
2024-06-07 20:17:03 +03:00
import { urls, useConceptNavigation } from '@/app';
import { useAuthSuspense } from '@/features/auth';
2025-02-26 00:16:22 +03:00
import { useLibrarySearchStore } from '@/features/library';
import { useDeleteItem } from '@/features/library/backend/useDeleteItem';
import { RSTabID } from '@/features/rsform/pages/RSFormPage/RSEditContext';
2025-02-12 15:12:59 +03:00
import { useRoleStore, UserRole } from '@/features/users';
2025-02-12 21:36:03 +03:00
import { useDialogsStore } from '@/stores/dialogs';
import { usePreferencesStore } from '@/stores/preferences';
import { promptText } from '@/utils/labels';
2024-06-07 20:17:03 +03:00
2025-02-20 20:22:05 +03:00
import { type IOperationPosition, OperationType } from '../../backend/types';
import { useOssSuspense } from '../../backend/useOSS';
2025-02-20 20:22:05 +03:00
import { type IOperationSchema } from '../../models/oss';
2025-01-26 22:24:34 +03:00
export enum OssTabID {
CARD = 0,
GRAPH = 1
}
2024-08-02 11:17:27 +03:00
export interface ICreateOperationPrompt {
2024-09-16 19:38:24 +03:00
defaultX: number;
defaultY: number;
2025-02-17 15:11:32 +03:00
inputs: number[];
2024-08-02 11:17:27 +03:00
positions: IOperationPosition[];
2025-02-17 15:11:32 +03:00
callback: (newID: number) => void;
2024-08-02 11:17:27 +03:00
}
export interface IOssEditContext {
2025-01-26 22:24:34 +03:00
schema: IOperationSchema;
2025-02-17 15:11:32 +03:00
selected: number[];
2024-06-07 20:17:03 +03:00
2025-01-23 19:41:31 +03:00
isOwned: boolean;
2024-06-07 20:17:03 +03:00
isMutable: boolean;
2024-07-26 00:33:22 +03:00
2025-01-26 22:24:34 +03:00
navigateTab: (tab: OssTabID) => void;
2025-02-17 15:11:32 +03:00
navigateOperationSchema: (target: number) => void;
2024-06-07 20:17:03 +03:00
2025-01-26 22:24:34 +03:00
deleteSchema: () => void;
2025-02-17 15:11:32 +03:00
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
2024-07-23 23:03:58 +03:00
2025-02-17 15:11:32 +03:00
canDelete: (target: number) => boolean;
2025-01-26 22:24:34 +03:00
promptCreateOperation: (props: ICreateOperationPrompt) => void;
2025-02-17 15:11:32 +03:00
promptDeleteOperation: (target: number, positions: IOperationPosition[]) => void;
promptEditInput: (target: number, positions: IOperationPosition[]) => void;
promptEditOperation: (target: number, positions: IOperationPosition[]) => void;
promptRelocateConstituents: (target: number | undefined, positions: IOperationPosition[]) => void;
2024-06-07 20:17:03 +03:00
}
const OssEditContext = createContext<IOssEditContext | null>(null);
export const useOssEdit = () => {
const context = useContext(OssEditContext);
if (context === null) {
2024-12-12 21:58:07 +03:00
throw new Error('useOssEdit has to be used within <OssEditState>');
2024-06-07 20:17:03 +03:00
}
return context;
};
interface OssEditStateProps {
2025-02-12 15:12:59 +03:00
itemID: number;
2024-06-07 20:17:03 +03:00
}
2025-01-26 22:24:34 +03:00
export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEditStateProps>) => {
2024-07-24 18:11:28 +03:00
const router = useConceptNavigation();
const adminMode = usePreferencesStore(state => state.adminMode);
2025-01-15 23:03:23 +03:00
const role = useRoleStore(state => state.role);
const adjustRole = useRoleStore(state => state.adjustRole);
const setSearchLocation = useLibrarySearchStore(state => state.setLocation);
const searchLocation = useLibrarySearchStore(state => state.location);
const { user } = useAuthSuspense();
2025-01-26 22:24:34 +03:00
const { schema } = useOssSuspense({ itemID: itemID });
2025-01-23 19:41:31 +03:00
const isOwned = !!user.id && user.id === schema.owner;
2025-01-26 22:24:34 +03:00
const isMutable = role > UserRole.READER && !schema.read_only;
2024-06-07 20:17:03 +03:00
2025-02-17 15:11:32 +03:00
const [selected, setSelected] = useState<number[]>([]);
2024-08-02 11:17:27 +03:00
const showEditInput = useDialogsStore(state => state.showChangeInputSchema);
const showEditOperation = useDialogsStore(state => state.showEditOperation);
const showDeleteOperation = useDialogsStore(state => state.showDeleteOperation);
const showRelocateConstituents = useDialogsStore(state => state.showRelocateConstituents);
const showCreateOperation = useDialogsStore(state => state.showCreateOperation);
2025-01-26 22:24:34 +03:00
const { deleteItem } = useDeleteItem();
2024-07-20 18:26:32 +03:00
useEffect(
2024-06-07 20:17:03 +03:00
() =>
2025-01-15 23:03:23 +03:00
adjustRole({
2025-01-26 22:24:34 +03:00
isOwner: isOwned,
isEditor: !!user.id && schema.editors.includes(user.id),
isStaff: user.is_staff,
2025-01-15 23:03:23 +03:00
adminMode: adminMode
2024-06-07 20:17:03 +03:00
}),
2025-01-26 22:24:34 +03:00
[schema, adjustRole, isOwned, user, adminMode]
2024-06-07 20:17:03 +03:00
);
2025-01-26 22:24:34 +03:00
function navigateTab(tab: OssTabID) {
const url = urls.oss_props({
id: schema.id,
tab: tab
});
router.push(url);
}
2024-06-07 20:17:03 +03:00
2025-02-17 15:11:32 +03:00
function navigateOperationSchema(target: number) {
const node = schema.operationByID.get(target);
if (!node?.result) {
return;
}
router.push(urls.schema_props({ id: node.result, tab: RSTabID.CST_LIST }));
}
2024-07-24 18:11:28 +03:00
2025-01-26 22:24:34 +03:00
function deleteSchema() {
if (!window.confirm(promptText.deleteOSS)) {
2025-01-26 22:24:34 +03:00
return;
}
2025-02-11 20:15:34 +03:00
void deleteItem(schema.id).then(() => {
if (searchLocation === schema.location) {
setSearchLocation('');
}
router.push(urls.library);
});
2025-01-26 22:24:34 +03:00
}
function promptCreateOperation({ defaultX, defaultY, inputs, positions, callback }: ICreateOperationPrompt) {
showCreateOperation({
oss: schema,
2025-02-11 12:34:28 +03:00
defaultX: defaultX,
defaultY: defaultY,
positions: positions,
initialInputs: inputs,
onCreate: callback
2025-01-26 22:24:34 +03:00
});
}
2025-02-17 15:11:32 +03:00
function canDelete(target: number) {
2025-01-26 22:24:34 +03:00
const operation = schema.operationByID.get(target);
if (!operation) {
return false;
}
if (operation.operation_type === OperationType.INPUT) {
return true;
}
return schema.graph.expandOutputs([target]).length === 0;
}
2025-02-17 15:11:32 +03:00
function promptEditOperation(target: number, positions: IOperationPosition[]) {
2025-01-26 22:24:34 +03:00
const operation = schema.operationByID.get(target);
if (!operation) {
return;
}
showEditOperation({
oss: schema,
target: operation,
2025-02-12 00:14:18 +03:00
positions: positions
2025-01-26 22:24:34 +03:00
});
}
2025-02-17 15:11:32 +03:00
function promptDeleteOperation(target: number, positions: IOperationPosition[]) {
2025-01-26 22:24:34 +03:00
const operation = schema.operationByID.get(target);
if (!operation) {
return;
}
showDeleteOperation({
oss: schema,
positions: positions,
target: operation
2025-01-26 22:24:34 +03:00
});
}
2025-02-17 15:11:32 +03:00
function promptEditInput(target: number, positions: IOperationPosition[]) {
2025-01-26 22:24:34 +03:00
const operation = schema.operationByID.get(target);
if (!operation) {
return;
}
showEditInput({
oss: schema,
target: operation,
2025-02-10 13:27:55 +03:00
positions: positions
2025-01-26 22:24:34 +03:00
});
}
2025-02-17 15:11:32 +03:00
function promptRelocateConstituents(target: number | undefined, positions: IOperationPosition[]) {
2025-01-26 22:24:34 +03:00
const operation = target ? schema.operationByID.get(target) : undefined;
showRelocateConstituents({
oss: schema,
initialTarget: operation,
2025-02-10 15:48:58 +03:00
positions: positions
2025-01-26 22:24:34 +03:00
});
}
2024-06-07 20:17:03 +03:00
return (
2024-12-12 21:58:07 +03:00
<OssEditContext
2024-06-07 20:17:03 +03:00
value={{
2025-01-26 22:24:34 +03:00
schema,
2024-07-23 23:03:58 +03:00
selected,
2025-01-26 22:24:34 +03:00
navigateTab,
deleteSchema,
2025-01-23 19:41:31 +03:00
isOwned,
2024-06-07 20:17:03 +03:00
isMutable,
2024-07-23 23:03:58 +03:00
setSelected,
2024-07-20 18:26:32 +03:00
2025-01-26 22:24:34 +03:00
navigateOperationSchema,
2024-07-23 23:03:58 +03:00
promptCreateOperation,
canDelete,
promptDeleteOperation,
2024-07-29 16:55:48 +03:00
promptEditInput,
2024-07-29 22:30:24 +03:00
promptEditOperation,
2024-10-23 15:18:46 +03:00
promptRelocateConstituents
2024-06-07 20:17:03 +03:00
}}
>
{children}
2024-12-12 21:58:07 +03:00
</OssEditContext>
2024-06-07 20:17:03 +03:00
);
};