ConceptPortal-public/rsconcept/frontend/src/features/oss/dialogs/DlgEditOperation/DlgEditOperation.tsx

193 lines
6.4 KiB
TypeScript
Raw Normal View History

2024-07-29 16:56:24 +03:00
'use client';
import clsx from 'clsx';
import { useCallback, useEffect, useState } from 'react';
2024-07-29 16:56:24 +03:00
import { ModalForm } from '@/components/Modal';
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
import { HelpTopic } from '@/features/help/models/helpTopic';
import { LibraryItemID } from '@/features/library/models/library';
import { useRSForms } from '@/features/rsform/backend/useRSForms';
import { ConstituentaID } from '@/features/rsform/models/rsform';
import { useDialogsStore } from '@/stores/dialogs';
2024-07-29 16:56:24 +03:00
import { IOperationUpdateDTO } from '../../backend/api';
import { ICstSubstitute, IOperation, IOperationSchema, OperationID, OperationType } from '../../models/oss';
import { SubstitutionValidator } from '../../models/ossAPI';
2024-07-29 16:56:24 +03:00
import TabArguments from './TabArguments';
import TabOperation from './TabOperation';
import TabSynthesis from './TabSynthesis';
export interface DlgEditOperationProps {
2024-07-29 16:56:24 +03:00
oss: IOperationSchema;
target: IOperation;
onSubmit: (data: IOperationUpdateDTO) => void;
2024-07-29 16:56:24 +03:00
}
export enum TabID {
CARD = 0,
ARGUMENTS = 1,
SUBSTITUTION = 2
}
function DlgEditOperation() {
const { oss, target, onSubmit } = useDialogsStore(state => state.props as DlgEditOperationProps);
2024-07-29 16:56:24 +03:00
const [activeTab, setActiveTab] = useState(TabID.CARD);
const [alias, setAlias] = useState(target.alias);
const [title, setTitle] = useState(target.title);
const [comment, setComment] = useState(target.comment);
2024-08-26 17:25:07 +03:00
const [isCorrect, setIsCorrect] = useState(true);
const [validationText, setValidationText] = useState('');
const initialInputs = oss.graph.expandInputs([target.id]);
const [inputs, setInputs] = useState<OperationID[]>(initialInputs);
const inputOperations = inputs.map(id => oss.operationByID.get(id)!);
2024-12-13 13:10:23 +03:00
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>(target.substitutions);
const [suggestions, setSuggestions] = useState<ICstSubstitute[]>([]);
const [schemasIDs, setSchemaIDs] = useState<LibraryItemID[]>([]);
const schemas = useRSForms(schemasIDs);
2024-07-29 16:56:24 +03:00
const isModified =
alias !== target.alias ||
title !== target.title ||
comment !== target.comment ||
JSON.stringify(initialInputs) !== JSON.stringify(inputs) ||
JSON.stringify(substitutions) !== JSON.stringify(target.substitutions);
const canSubmit = isModified && alias !== '';
2024-07-29 16:56:24 +03:00
2024-12-13 13:10:23 +03:00
const getSchemaByCst = useCallback(
(id: ConstituentaID) => {
for (const schema of schemas) {
2024-12-13 13:10:23 +03:00
const cst = schema.items.find(cst => cst.id === id);
if (cst) {
return schema;
}
}
return undefined;
},
[schemas]
2024-12-13 13:10:23 +03:00
);
useEffect(() => {
setSchemaIDs(inputOperations.map(operation => operation.result).filter(id => id !== null));
}, [inputOperations]);
useEffect(() => {
if (schemas.length !== schemasIDs.length || schemas.length === 0) {
return;
}
2024-08-19 12:33:04 +03:00
setSubstitutions(prev =>
prev.filter(sub => {
2024-12-13 13:10:23 +03:00
const original = getSchemaByCst(sub.original);
if (!original || !schemasIDs.includes(original.id)) {
return false;
}
2024-12-13 13:10:23 +03:00
const substitution = getSchemaByCst(sub.substitution);
if (!substitution || !schemasIDs.includes(substitution.id)) {
return false;
}
return true;
})
);
}, [schemasIDs, schemas, getSchemaByCst]);
useEffect(() => {
if (schemas.length !== schemasIDs.length || schemas.length === 0) {
2024-08-26 17:25:07 +03:00
return;
}
const validator = new SubstitutionValidator(schemas, substitutions);
setIsCorrect(validator.validate());
setValidationText(validator.msg);
setSuggestions(validator.suggestions);
}, [substitutions, schemas, schemasIDs.length]);
2024-08-26 17:25:07 +03:00
function handleSubmit() {
onSubmit({
2024-07-29 22:31:11 +03:00
target: target.id,
item_data: {
alias: alias,
title: title,
comment: comment
2024-07-29 22:31:11 +03:00
},
positions: [],
arguments: target.operation_type !== OperationType.SYNTHESIS ? undefined : inputs,
substitutions: target.operation_type !== OperationType.SYNTHESIS ? undefined : substitutions
});
2025-02-06 14:10:18 +03:00
return true;
}
2024-07-29 16:56:24 +03:00
return (
<ModalForm
2024-07-29 16:56:24 +03:00
header='Редактирование операции'
submitText='Сохранить'
2024-08-26 17:25:07 +03:00
canSubmit={canSubmit}
2024-07-29 16:56:24 +03:00
onSubmit={handleSubmit}
className='w-[40rem] px-6 h-[32rem]'
2024-10-29 12:06:43 +03:00
helpTopic={HelpTopic.UI_SUBSTITUTIONS}
hideHelpWhen={() => activeTab !== TabID.SUBSTITUTION}
2024-07-29 16:56:24 +03:00
>
<Tabs
selectedTabClassName='clr-selected'
className='flex flex-col'
selectedIndex={activeTab}
onSelect={setActiveTab}
>
2024-12-18 14:55:10 +03:00
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none', 'bg-prim-200')}>
2024-07-29 16:56:24 +03:00
<TabLabel title='Текстовые поля' label='Карточка' className='w-[8rem]' />
{target.operation_type === OperationType.SYNTHESIS ? (
<TabLabel title='Выбор аргументов операции' label='Аргументы' className='w-[8rem]' />
) : null}
{target.operation_type === OperationType.SYNTHESIS ? (
2024-08-26 17:25:07 +03:00
<TabLabel
titleHtml={'Таблица отождествлений' + (isCorrect ? '' : '<br/>(не прошла проверку)')}
label={isCorrect ? 'Отождествления' : 'Отождествления*'}
className='w-[8rem]'
/>
2024-07-29 16:56:24 +03:00
) : null}
</TabList>
<TabPanel>
<TabOperation
alias={alias}
onChangeAlias={setAlias}
comment={comment}
onChangeComment={setComment}
title={title}
onChangeTitle={setTitle}
/>
</TabPanel>
{target.operation_type === OperationType.SYNTHESIS ? (
<TabPanel>
<TabArguments
target={target.id} // prettier: split-lines
oss={oss}
inputs={inputs}
setInputs={setInputs}
/>
</TabPanel>
) : null}
{target.operation_type === OperationType.SYNTHESIS ? (
<TabPanel>
<TabSynthesis
schemas={schemas}
validationText={validationText}
isCorrect={isCorrect}
substitutions={substitutions}
setSubstitutions={setSubstitutions}
suggestions={suggestions}
/>
</TabPanel>
) : null}
2024-07-29 16:56:24 +03:00
</Tabs>
</ModalForm>
2024-07-29 16:56:24 +03:00
);
}
export default DlgEditOperation;