'use client'; import clsx from 'clsx'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { TabList, TabPanel, Tabs } from 'react-tabs'; import Modal from '@/components/ui/Modal'; import TabLabel from '@/components/ui/TabLabel'; import useRSFormCache from '@/hooks/useRSFormCache'; import { HelpTopic } from '@/models/miscellaneous'; import { ICstSubstitute, IOperation, IOperationSchema, IOperationUpdateData, OperationID, OperationType } from '@/models/oss'; import { SubstitutionValidator } from '@/models/ossAPI'; import TabArguments from './TabArguments'; import TabOperation from './TabOperation'; import TabSynthesis from './TabSynthesis'; interface DlgEditOperationProps { hideWindow: () => void; oss: IOperationSchema; target: IOperation; onSubmit: (data: IOperationUpdateData) => void; } export enum TabID { CARD = 0, ARGUMENTS = 1, SUBSTITUTION = 2 } function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperationProps) { const [activeTab, setActiveTab] = useState(TabID.CARD); const [alias, setAlias] = useState(target.alias); const [title, setTitle] = useState(target.title); const [comment, setComment] = useState(target.comment); const [isCorrect, setIsCorrect] = useState(true); const [validationText, setValidationText] = useState(''); const initialInputs = useMemo(() => oss.graph.expandInputs([target.id]), [oss.graph, target.id]); const [inputs, setInputs] = useState(initialInputs); const inputOperations = useMemo(() => inputs.map(id => oss.operationByID.get(id)!), [inputs, oss.operationByID]); const schemasIDs = useMemo( () => inputOperations.map(operation => operation.result).filter(id => id !== null), [inputOperations] ); const [substitutions, setSubstitutions] = useState(target.substitutions); const [suggestions, setSuggestions] = useState([]); const cache = useRSFormCache(); const schemas = useMemo( () => schemasIDs.map(id => cache.getSchema(id)).filter(item => item !== undefined), // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps [schemasIDs, cache.getSchema] ); const isModified = useMemo( () => alias !== target.alias || title !== target.title || comment !== target.comment || JSON.stringify(initialInputs) !== JSON.stringify(inputs) || JSON.stringify(substitutions) !== JSON.stringify(target.substitutions), [ alias, title, comment, target.alias, target.title, target.comment, initialInputs, inputs, substitutions, target.substitutions ] ); const canSubmit = useMemo(() => isModified && alias !== '', [isModified, alias]); useEffect(() => { cache.preload(schemasIDs); // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [schemasIDs]); useEffect(() => { if (cache.loading || schemas.length !== schemasIDs.length) { return; } setSubstitutions(prev => prev.filter(sub => { const original = cache.getSchemaByCst(sub.original); if (!original || !schemasIDs.includes(original.id)) { return false; } const substitution = cache.getSchemaByCst(sub.substitution); if (!substitution || !schemasIDs.includes(substitution.id)) { return false; } return true; }) ); // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [schemasIDs, schemas, cache.loading]); useEffect(() => { if (cache.loading || schemas.length !== schemasIDs.length) { return; } const validator = new SubstitutionValidator(schemas, substitutions); setIsCorrect(validator.validate()); setValidationText(validator.msg); setSuggestions(validator.suggestions); }, [substitutions, cache.loading, schemas, schemasIDs.length]); const handleSubmit = useCallback(() => { const data: IOperationUpdateData = { target: target.id, item_data: { alias: alias, title: title, comment: comment }, positions: [], arguments: target.operation_type !== OperationType.SYNTHESIS ? undefined : inputs, substitutions: target.operation_type !== OperationType.SYNTHESIS ? undefined : substitutions }; onSubmit(data); }, [alias, comment, title, inputs, substitutions, target, onSubmit]); const cardPanel = useMemo( () => ( ), [alias, comment, title, setAlias] ); const argumentsPanel = useMemo( () => ( ), [oss, target, inputs, setInputs] ); const synthesisPanel = useMemo( () => ( ), [cache.loading, cache.error, substitutions, suggestions, schemas, validationText, isCorrect] ); return ( activeTab !== TabID.SUBSTITUTION} > {target.operation_type === OperationType.SYNTHESIS ? ( ) : null} {target.operation_type === OperationType.SYNTHESIS ? ( (не прошла проверку)')} label={isCorrect ? 'Отождествления' : 'Отождествления*'} className='w-[8rem]' /> ) : null} {cardPanel} {target.operation_type === OperationType.SYNTHESIS ? argumentsPanel : null} {target.operation_type === OperationType.SYNTHESIS ? synthesisPanel : null} ); } export default DlgEditOperation;