2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2023-12-18 12:25:39 +03:00
|
|
|
import clsx from 'clsx';
|
2023-11-26 02:24:16 +03:00
|
|
|
import { useLayoutEffect, useState } from 'react';
|
|
|
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
import ConceptTab from '@/components/Common/ConceptTab';
|
|
|
|
import Modal, { ModalProps } from '@/components/Common/Modal';
|
|
|
|
import Overlay from '@/components/Common/Overlay';
|
|
|
|
import HelpButton from '@/components/Help/HelpButton';
|
|
|
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
2023-12-26 14:23:51 +03:00
|
|
|
import { HelpTopic } from '@/models/miscellaneous';
|
2023-12-13 14:32:57 +03:00
|
|
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
2024-01-04 14:35:46 +03:00
|
|
|
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
2023-12-13 14:32:57 +03:00
|
|
|
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
2023-12-18 19:42:27 +03:00
|
|
|
import { classnames } from '@/utils/constants';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2023-11-26 02:24:16 +03:00
|
|
|
import ArgumentsTab, { IArgumentsState } from './ArgumentsTab';
|
|
|
|
import ConstituentaTab from './ConstituentaTab';
|
|
|
|
import TemplateTab, { ITemplateState } from './TemplateTab';
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
interface DlgConstituentaTemplateProps extends Pick<ModalProps, 'hideWindow'> {
|
|
|
|
schema: IRSForm;
|
|
|
|
onCreate: (data: ICstCreateData) => void;
|
|
|
|
insertAfter?: number;
|
2023-11-26 02:24:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
export enum TabID {
|
|
|
|
TEMPLATE = 0,
|
|
|
|
ARGUMENTS = 1,
|
|
|
|
CONSTITUENTA = 2
|
|
|
|
}
|
|
|
|
|
2023-11-30 02:14:24 +03:00
|
|
|
function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }: DlgConstituentaTemplateProps) {
|
2023-11-30 17:47:37 +03:00
|
|
|
const [validated, setValidated] = useState(false);
|
|
|
|
const [template, updateTemplate] = usePartialUpdate<ITemplateState>({});
|
|
|
|
const [substitutes, updateSubstitutes] = usePartialUpdate<IArgumentsState>({
|
2023-11-26 02:24:16 +03:00
|
|
|
definition: '',
|
|
|
|
arguments: []
|
|
|
|
});
|
|
|
|
const [constituenta, updateConstituenta] = usePartialUpdate<ICstCreateData>({
|
|
|
|
cst_type: CstType.TERM,
|
2023-11-30 02:14:24 +03:00
|
|
|
insert_after: insertAfter ?? null,
|
2023-11-26 02:24:16 +03:00
|
|
|
alias: '',
|
|
|
|
convention: '',
|
|
|
|
definition_formal: '',
|
|
|
|
definition_raw: '',
|
|
|
|
term_raw: '',
|
|
|
|
term_forms: []
|
|
|
|
});
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2023-12-01 22:50:43 +03:00
|
|
|
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
|
|
|
const handleSubmit = () => onCreate(constituenta);
|
2023-12-28 14:04:44 +03:00
|
|
|
|
|
|
|
useLayoutEffect(() => {
|
2024-01-04 14:35:46 +03:00
|
|
|
updateConstituenta({ alias: generateAlias(constituenta.cst_type, schema) });
|
2023-11-26 02:24:16 +03:00
|
|
|
}, [constituenta.cst_type, updateConstituenta, schema]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2024-01-04 14:35:46 +03:00
|
|
|
setValidated(validateNewAlias(constituenta.alias, constituenta.cst_type, schema));
|
2023-11-26 02:24:16 +03:00
|
|
|
}, [constituenta.alias, constituenta.cst_type, schema]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
if (!template.prototype) {
|
|
|
|
updateConstituenta({
|
|
|
|
definition_raw: '',
|
|
|
|
definition_formal: '',
|
|
|
|
term_raw: ''
|
|
|
|
});
|
|
|
|
updateSubstitutes({
|
|
|
|
definition: '',
|
|
|
|
arguments: []
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
updateConstituenta({
|
|
|
|
cst_type: template.prototype.cst_type,
|
|
|
|
definition_raw: template.prototype.definition_raw,
|
|
|
|
definition_formal: template.prototype.definition_formal,
|
2023-12-28 14:04:44 +03:00
|
|
|
term_raw: template.prototype.term_raw
|
2023-11-26 02:24:16 +03:00
|
|
|
});
|
|
|
|
updateSubstitutes({
|
|
|
|
definition: template.prototype.definition_formal,
|
2023-12-28 14:04:44 +03:00
|
|
|
arguments: template.prototype.parse.args.map(arg => ({
|
|
|
|
alias: arg.alias,
|
|
|
|
typification: arg.typification,
|
|
|
|
value: ''
|
|
|
|
}))
|
2023-11-26 02:24:16 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}, [template.prototype, updateConstituenta, updateSubstitutes]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
if (substitutes.arguments.length === 0 || !template.prototype) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const definition = substituteTemplateArgs(template.prototype.definition_formal, substitutes.arguments);
|
|
|
|
const type = inferTemplatedType(template.prototype.cst_type, substitutes.arguments);
|
|
|
|
updateConstituenta({
|
|
|
|
cst_type: type,
|
2023-12-28 14:04:44 +03:00
|
|
|
definition_formal: definition
|
2023-11-26 02:24:16 +03:00
|
|
|
});
|
|
|
|
updateSubstitutes({
|
2023-12-28 14:04:44 +03:00
|
|
|
definition: definition
|
2023-11-26 02:24:16 +03:00
|
|
|
});
|
|
|
|
}, [substitutes.arguments, template.prototype, updateConstituenta, updateSubstitutes]);
|
|
|
|
|
|
|
|
return (
|
2023-12-28 14:04:44 +03:00
|
|
|
<Modal
|
|
|
|
header='Создание конституенты из шаблона'
|
|
|
|
submitText='Создать'
|
|
|
|
className='w-[43rem] h-[36rem] px-6'
|
|
|
|
hideWindow={hideWindow}
|
|
|
|
canSubmit={validated}
|
|
|
|
onSubmit={handleSubmit}
|
2023-12-18 12:25:39 +03:00
|
|
|
>
|
2023-12-28 14:04:44 +03:00
|
|
|
<Overlay position='top-0 right-[6rem]'>
|
|
|
|
<HelpButton topic={HelpTopic.RSTEMPLATES} className='max-w-[35rem]' />
|
|
|
|
</Overlay>
|
|
|
|
<Tabs
|
|
|
|
forceRenderTabPanel
|
|
|
|
selectedTabClassName='clr-selected'
|
|
|
|
className='flex flex-col'
|
|
|
|
selectedIndex={activeTab}
|
|
|
|
onSelect={setActiveTab}
|
|
|
|
>
|
|
|
|
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none')}>
|
|
|
|
<ConceptTab label='Шаблон' title='Выбор шаблона выражения' className='w-[8rem]' />
|
|
|
|
<ConceptTab label='Аргументы' title='Подстановка аргументов шаблона' className='w-[8rem]' />
|
|
|
|
<ConceptTab label='Конституента' title='Редактирование атрибутов конституенты' className='w-[8rem]' />
|
|
|
|
</TabList>
|
|
|
|
|
|
|
|
<TabPanel style={{ display: activeTab === TabID.TEMPLATE ? '' : 'none' }}>
|
|
|
|
<TemplateTab state={template} partialUpdate={updateTemplate} />
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
<TabPanel style={{ display: activeTab === TabID.ARGUMENTS ? '' : 'none' }}>
|
|
|
|
<ArgumentsTab schema={schema} state={substitutes} partialUpdate={updateSubstitutes} />
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
<TabPanel className={classnames.flex_col} style={{ display: activeTab === TabID.CONSTITUENTA ? '' : 'none' }}>
|
|
|
|
<ConstituentaTab state={constituenta} partialUpdate={updateConstituenta} />
|
|
|
|
</TabPanel>
|
|
|
|
</Tabs>
|
|
|
|
</Modal>
|
|
|
|
);
|
2023-11-26 02:24:16 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
export default DlgConstituentaTemplate;
|