import { useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; import ConceptTooltip from '../../components/Common/ConceptTooltip'; import MiniButton from '../../components/Common/MiniButton'; import ReferenceInput from '../../components/Common/ReferenceInput'; import SubmitButton from '../../components/Common/SubmitButton'; import TextArea from '../../components/Common/TextArea'; import HelpConstituenta from '../../components/Help/HelpConstituenta'; import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons'; import { useRSForm } from '../../context/RSFormContext'; import useModificationPrompt from '../../hooks/useModificationPrompt'; import { CstType, EditMode, ICstCreateData, ICstRenameData, ICstUpdateData, SyntaxTree } from '../../utils/models'; import { getCstTypificationLabel } from '../../utils/staticUI'; import EditorRSExpression from './EditorRSExpression'; import ViewSideConstituents from './elements/ViewSideConstituents'; // Max height of content for left enditor pane const UNFOLDED_HEIGHT = '59.1rem'; interface EditorConstituentaProps { activeID?: number onOpenEdit: (cstID: number) => void onShowAST: (expression: string, ast: SyntaxTree) => void onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void onRenameCst: (initial: ICstRenameData) => void onDeleteCst: (selected: number[], callback?: (items: number[]) => void) => void } function EditorConstituenta({ activeID, onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst }: EditorConstituentaProps) { const { schema, processing, isEditable, cstUpdate } = useRSForm(); const activeCst = useMemo( () => { return schema?.items?.find((cst) => cst.id === activeID); }, [schema?.items, activeID]); const { isModified, setIsModified } = useModificationPrompt(); const [editMode, setEditMode] = useState(EditMode.TEXT); const [alias, setAlias] = useState(''); const [term, setTerm] = useState(''); const [textDefinition, setTextDefinition] = useState(''); const [expression, setExpression] = useState(''); const [convention, setConvention] = useState(''); const [typification, setTypification] = useState('N/A'); const isEnabled = useMemo(() => activeCst && isEditable, [activeCst, isEditable]); useLayoutEffect( () => { if (!activeCst) { setIsModified(false); return; } setIsModified( activeCst.term.raw !== term || activeCst.definition.text.raw !== textDefinition || activeCst.convention !== convention || activeCst.definition.formal !== expression ); }, [activeCst, activeCst?.term, activeCst?.definition.formal, activeCst?.definition.text.raw, activeCst?.convention, term, textDefinition, expression, convention, setIsModified]); useLayoutEffect( () => { if (activeCst) { setAlias(activeCst.alias); setConvention(activeCst.convention ?? ''); setTerm(activeCst.term?.raw ?? ''); setTextDefinition(activeCst.definition?.text?.raw ?? ''); setExpression(activeCst.definition?.formal ?? ''); setTypification(activeCst ? getCstTypificationLabel(activeCst) : 'N/A'); } }, [activeCst, onOpenEdit, schema]); function handleSubmit(event?: React.FormEvent) { if (event) { event.preventDefault(); } if (!activeID || processing) { return; } const data: ICstUpdateData = { id: activeID, alias: alias, convention: convention, definition_formal: expression, definition_raw: textDefinition, term_raw: term }; cstUpdate(data, () => toast.success('Изменения сохранены')); } function handleDelete() { if (!schema || !activeID) { return; } onDeleteCst([activeID]); } function handleCreateCst() { if (!activeID || !schema) { return; } const data: ICstCreateData = { insert_after: activeID, cst_type: activeCst?.cstType ?? CstType.BASE, alias: '', term_raw: '', definition_formal: '', definition_raw: '', convention: '', }; onCreateCst(data); } function handleRename() { if (!activeID || !activeCst) { return; } const data: ICstRenameData = { id: activeID, alias: activeCst?.alias, cst_type: activeCst.cstType }; onRenameCst(data); } return (
} onClick={() => handleSubmit()} >
} /> } />
Конституента {alias}
} />
setTerm(event.target.value)} onFocus={() => setEditMode(EditMode.TEXT)} />