mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Update constituenta creation
This commit is contained in:
parent
99f9bdb856
commit
52b4953fc7
|
@ -1,76 +0,0 @@
|
||||||
'use client';
|
|
||||||
|
|
||||||
import RSInput from '@/components/RSInput';
|
|
||||||
import SelectSingle from '@/components/ui/SelectSingle';
|
|
||||||
import TextArea from '@/components/ui/TextArea';
|
|
||||||
import TextInput from '@/components/ui/TextInput';
|
|
||||||
import { CstType, ICstCreateData } from '@/models/rsform';
|
|
||||||
import { labelCstType } from '@/utils/labels';
|
|
||||||
import { SelectorCstType } from '@/utils/selectors';
|
|
||||||
|
|
||||||
interface ConstituentaTabProps {
|
|
||||||
state: ICstCreateData;
|
|
||||||
partialUpdate: React.Dispatch<Partial<ICstCreateData>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ConstituentaTab({ state, partialUpdate }: ConstituentaTabProps) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className='flex self-center gap-3 pr-2'>
|
|
||||||
<SelectSingle
|
|
||||||
id='dlg_cst_type'
|
|
||||||
className='min-w-[14rem]'
|
|
||||||
options={SelectorCstType}
|
|
||||||
placeholder='Выберите тип'
|
|
||||||
value={{ value: state.cst_type, label: labelCstType(state.cst_type) }}
|
|
||||||
onChange={data => partialUpdate({ cst_type: data?.value ?? CstType.TERM })}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
id='dlg_cst_alias'
|
|
||||||
dense
|
|
||||||
label='Имя'
|
|
||||||
className='w-[7rem]'
|
|
||||||
value={state.alias}
|
|
||||||
onChange={event => partialUpdate({ alias: event.target.value })}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_term'
|
|
||||||
spellCheck
|
|
||||||
label='Термин'
|
|
||||||
placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение'
|
|
||||||
rows={2}
|
|
||||||
value={state.term_raw}
|
|
||||||
onChange={event => partialUpdate({ term_raw: event.target.value })}
|
|
||||||
/>
|
|
||||||
<RSInput
|
|
||||||
id='dlg_cst_expression'
|
|
||||||
label='Формальное определение'
|
|
||||||
placeholder='Родоструктурное выражение, задающее формальное определение'
|
|
||||||
height='5.1rem'
|
|
||||||
value={state.definition_formal}
|
|
||||||
onChange={value => partialUpdate({ definition_formal: value })}
|
|
||||||
/>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_definition'
|
|
||||||
label='Текстовое определение'
|
|
||||||
placeholder='Лингвистическая интерпретация формального выражения'
|
|
||||||
rows={2}
|
|
||||||
value={state.definition_raw}
|
|
||||||
spellCheck
|
|
||||||
onChange={event => partialUpdate({ definition_raw: event.target.value })}
|
|
||||||
/>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_convention'
|
|
||||||
spellCheck
|
|
||||||
label='Конвенция / Комментарий'
|
|
||||||
placeholder='Договоренность об интерпретации или пояснение к схеме'
|
|
||||||
rows={2}
|
|
||||||
value={state.convention}
|
|
||||||
onChange={event => partialUpdate({ convention: event.target.value })}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ConstituentaTab;
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useLayoutEffect, useMemo, useState } from 'react';
|
import { useLayoutEffect, useState } from 'react';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
|
|
||||||
import HelpButton from '@/components/man/HelpButton';
|
import HelpButton from '@/components/man/HelpButton';
|
||||||
|
@ -11,11 +11,11 @@ import TabLabel from '@/components/ui/TabLabel';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
import { generateAlias } from '@/models/rsformAPI';
|
||||||
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
||||||
|
|
||||||
|
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
||||||
import ArgumentsTab, { IArgumentsState } from './ArgumentsTab';
|
import ArgumentsTab, { IArgumentsState } from './ArgumentsTab';
|
||||||
import ConstituentaTab from './ConstituentaTab';
|
|
||||||
import TemplateTab, { ITemplateState } from './TemplateTab';
|
import TemplateTab, { ITemplateState } from './TemplateTab';
|
||||||
|
|
||||||
interface DlgConstituentaTemplateProps extends Pick<ModalProps, 'hideWindow'> {
|
interface DlgConstituentaTemplateProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
|
@ -49,11 +49,7 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
|
||||||
term_forms: []
|
term_forms: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const validated = useMemo(
|
const [validated, setValidated] = useState(false);
|
||||||
() => validateNewAlias(constituenta.alias, constituenta.cst_type, schema),
|
|
||||||
[constituenta.alias, constituenta.cst_type, schema]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSubmit = () => onCreate(constituenta);
|
const handleSubmit = () => onCreate(constituenta);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -138,7 +134,12 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel className='cc-column' style={{ display: activeTab === TabID.CONSTITUENTA ? '' : 'none' }}>
|
<TabPanel className='cc-column' style={{ display: activeTab === TabID.CONSTITUENTA ? '' : 'none' }}>
|
||||||
<ConstituentaTab state={constituenta} partialUpdate={updateConstituenta} />
|
<FormCreateCst
|
||||||
|
state={constituenta}
|
||||||
|
partialUpdate={updateConstituenta}
|
||||||
|
schema={schema}
|
||||||
|
setValidated={setValidated}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
'use client';
|
|
||||||
|
|
||||||
import clsx from 'clsx';
|
|
||||||
import { useEffect, useLayoutEffect, useState } from 'react';
|
|
||||||
|
|
||||||
import RSInput from '@/components/RSInput';
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
|
||||||
import SelectSingle from '@/components/ui/SelectSingle';
|
|
||||||
import TextArea from '@/components/ui/TextArea';
|
|
||||||
import TextInput from '@/components/ui/TextInput';
|
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
|
||||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
|
||||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
|
||||||
import { labelCstType } from '@/utils/labels';
|
|
||||||
import { SelectorCstType } from '@/utils/selectors';
|
|
||||||
|
|
||||||
interface DlgCreateCstProps extends Pick<ModalProps, 'hideWindow'> {
|
|
||||||
initial?: ICstCreateData;
|
|
||||||
schema: IRSForm;
|
|
||||||
onCreate: (data: ICstCreateData) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) {
|
|
||||||
const [validated, setValidated] = useState(false);
|
|
||||||
const [cstData, updateCstData] = usePartialUpdate(
|
|
||||||
initial || {
|
|
||||||
cst_type: CstType.BASE,
|
|
||||||
insert_after: null,
|
|
||||||
alias: '',
|
|
||||||
convention: '',
|
|
||||||
definition_formal: '',
|
|
||||||
definition_raw: '',
|
|
||||||
term_raw: '',
|
|
||||||
term_forms: []
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSubmit = () => onCreate(cstData);
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
updateCstData({ alias: generateAlias(cstData.cst_type, schema) });
|
|
||||||
}, [cstData.cst_type, updateCstData, schema]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValidated(validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
|
||||||
}, [cstData.alias, cstData.cst_type, schema]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
header='Создание конституенты'
|
|
||||||
hideWindow={hideWindow}
|
|
||||||
canSubmit={validated}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
submitText='Создать'
|
|
||||||
className={clsx('cc-column', 'w-[35rem]', 'py-2 px-6')}
|
|
||||||
>
|
|
||||||
<div className='flex self-center gap-6'>
|
|
||||||
<SelectSingle
|
|
||||||
id='dlg_cst_type'
|
|
||||||
placeholder='Выберите тип'
|
|
||||||
className='min-w-[15rem]'
|
|
||||||
options={SelectorCstType}
|
|
||||||
value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }}
|
|
||||||
onChange={data => updateCstData({ cst_type: data?.value ?? CstType.BASE })}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
id='dlg_cst_alias'
|
|
||||||
dense
|
|
||||||
label='Имя'
|
|
||||||
className='w-[7rem]'
|
|
||||||
value={cstData.alias}
|
|
||||||
onChange={event => updateCstData({ alias: event.target.value })}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_term'
|
|
||||||
spellCheck
|
|
||||||
label='Термин'
|
|
||||||
placeholder='Обозначение, используемое в текстовых определениях'
|
|
||||||
rows={2}
|
|
||||||
value={cstData.term_raw}
|
|
||||||
onChange={event => updateCstData({ term_raw: event.target.value })}
|
|
||||||
/>
|
|
||||||
<RSInput
|
|
||||||
id='dlg_cst_expression'
|
|
||||||
label='Формальное определение'
|
|
||||||
placeholder='Родоструктурное выражение'
|
|
||||||
value={cstData.definition_formal}
|
|
||||||
onChange={value => updateCstData({ definition_formal: value })}
|
|
||||||
/>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_definition'
|
|
||||||
spellCheck
|
|
||||||
label='Текстовое определение'
|
|
||||||
placeholder='Текстовая интерпретация формального выражения'
|
|
||||||
rows={2}
|
|
||||||
value={cstData.definition_raw}
|
|
||||||
onChange={event => updateCstData({ definition_raw: event.target.value })}
|
|
||||||
/>
|
|
||||||
<TextArea
|
|
||||||
id='dlg_cst_convention'
|
|
||||||
spellCheck
|
|
||||||
label='Конвенция / Комментарий'
|
|
||||||
placeholder='Договоренность об интерпретации или пояснение'
|
|
||||||
rows={2}
|
|
||||||
value={cstData.convention}
|
|
||||||
onChange={event => updateCstData({ convention: event.target.value })}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DlgCreateCst;
|
|
57
rsconcept/frontend/src/dialogs/DlgCreateCst/DlgCreateCst.tsx
Normal file
57
rsconcept/frontend/src/dialogs/DlgCreateCst/DlgCreateCst.tsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import Modal, { ModalProps } from '@/components/ui/Modal';
|
||||||
|
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||||
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||||
|
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||||
|
|
||||||
|
import FormCreateCst from './FormCreateCst';
|
||||||
|
|
||||||
|
interface DlgCreateCstProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
|
initial?: ICstCreateData;
|
||||||
|
schema: IRSForm;
|
||||||
|
onCreate: (data: ICstCreateData) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) {
|
||||||
|
const [validated, setValidated] = useState(false);
|
||||||
|
const [cstData, updateCstData] = usePartialUpdate(
|
||||||
|
initial || {
|
||||||
|
cst_type: CstType.BASE,
|
||||||
|
insert_after: null,
|
||||||
|
alias: '',
|
||||||
|
convention: '',
|
||||||
|
definition_formal: '',
|
||||||
|
definition_raw: '',
|
||||||
|
term_raw: '',
|
||||||
|
term_forms: []
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmit = () => onCreate(cstData);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
updateCstData({ alias: generateAlias(cstData.cst_type, schema) });
|
||||||
|
}, [cstData.cst_type, updateCstData, schema]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValidated(validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
||||||
|
}, [cstData.alias, cstData.cst_type, schema]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
header='Создание конституенты'
|
||||||
|
hideWindow={hideWindow}
|
||||||
|
canSubmit={validated}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
submitText='Создать'
|
||||||
|
className='cc-column w-[35rem] h-[30rem] py-2 px-6'
|
||||||
|
>
|
||||||
|
<FormCreateCst schema={schema} state={cstData} partialUpdate={updateCstData} setValidated={setValidated} />
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DlgCreateCst;
|
123
rsconcept/frontend/src/dialogs/DlgCreateCst/FormCreateCst.tsx
Normal file
123
rsconcept/frontend/src/dialogs/DlgCreateCst/FormCreateCst.tsx
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { AnimatePresence } from 'framer-motion';
|
||||||
|
import { useLayoutEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import RSInput from '@/components/RSInput';
|
||||||
|
import SelectSingle from '@/components/ui/SelectSingle';
|
||||||
|
import TextArea from '@/components/ui/TextArea';
|
||||||
|
import TextInput from '@/components/ui/TextInput';
|
||||||
|
import AnimateFade from '@/components/wrap/AnimateFade';
|
||||||
|
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||||
|
import { generateAlias, isBaseSet, isBasicConcept, isFunctional, validateNewAlias } from '@/models/rsformAPI';
|
||||||
|
import { labelCstType } from '@/utils/labels';
|
||||||
|
import { SelectorCstType } from '@/utils/selectors';
|
||||||
|
|
||||||
|
interface FormCreateCstProps {
|
||||||
|
schema: IRSForm;
|
||||||
|
state: ICstCreateData;
|
||||||
|
|
||||||
|
partialUpdate: React.Dispatch<Partial<ICstCreateData>>;
|
||||||
|
setValidated: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreateCstProps) {
|
||||||
|
const [forceComment, setForceComment] = useState(false);
|
||||||
|
|
||||||
|
const isBasic = useMemo(() => isBasicConcept(state.cst_type), [state]);
|
||||||
|
const isElementary = useMemo(() => isBaseSet(state.cst_type), [state]);
|
||||||
|
const showConvention = useMemo(() => !!state.convention || forceComment || isBasic, [state, forceComment, isBasic]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
partialUpdate({ alias: generateAlias(state.cst_type, schema) });
|
||||||
|
setForceComment(false);
|
||||||
|
}, [state.cst_type, partialUpdate, schema]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
setValidated(validateNewAlias(state.alias, state.cst_type, schema));
|
||||||
|
}, [state.alias, state.cst_type, schema, setValidated]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimatePresence>
|
||||||
|
<div className='flex self-center gap-6'>
|
||||||
|
<SelectSingle
|
||||||
|
id='dlg_cst_type'
|
||||||
|
placeholder='Выберите тип'
|
||||||
|
className='w-[15rem]'
|
||||||
|
options={SelectorCstType}
|
||||||
|
value={{ value: state.cst_type, label: labelCstType(state.cst_type) }}
|
||||||
|
onChange={data => partialUpdate({ cst_type: data?.value ?? CstType.BASE })}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id='dlg_cst_alias'
|
||||||
|
dense
|
||||||
|
label='Имя'
|
||||||
|
className='w-[7rem]'
|
||||||
|
value={state.alias}
|
||||||
|
onChange={event => partialUpdate({ alias: event.target.value })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TextArea
|
||||||
|
id='dlg_cst_term'
|
||||||
|
spellCheck
|
||||||
|
label='Термин'
|
||||||
|
placeholder='Обозначение, используемое в текстовых определениях'
|
||||||
|
rows={2}
|
||||||
|
value={state.term_raw}
|
||||||
|
onChange={event => partialUpdate({ term_raw: event.target.value })}
|
||||||
|
/>
|
||||||
|
<AnimateFade hideContent={!state.definition_formal && isElementary}>
|
||||||
|
<RSInput
|
||||||
|
id='dlg_cst_expression'
|
||||||
|
label={
|
||||||
|
state.cst_type === CstType.STRUCTURED
|
||||||
|
? 'Область определения'
|
||||||
|
: isFunctional(state.cst_type)
|
||||||
|
? 'Определение функции'
|
||||||
|
: 'Формальное определение'
|
||||||
|
}
|
||||||
|
placeholder={
|
||||||
|
state.cst_type !== CstType.STRUCTURED
|
||||||
|
? 'Родоструктурное выражение'
|
||||||
|
: 'Определение множества, которому принадлежат элементы родовой структуры'
|
||||||
|
}
|
||||||
|
value={state.definition_formal}
|
||||||
|
onChange={value => partialUpdate({ definition_formal: value })}
|
||||||
|
/>
|
||||||
|
</AnimateFade>
|
||||||
|
<AnimateFade hideContent={!state.definition_raw && isElementary}>
|
||||||
|
<TextArea
|
||||||
|
id='dlg_cst_definition'
|
||||||
|
spellCheck
|
||||||
|
label='Текстовое определение'
|
||||||
|
placeholder='Текстовая интерпретация формального выражения'
|
||||||
|
rows={2}
|
||||||
|
value={state.definition_raw}
|
||||||
|
onChange={event => partialUpdate({ definition_raw: event.target.value })}
|
||||||
|
/>
|
||||||
|
</AnimateFade>
|
||||||
|
{!showConvention ? (
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='self-start cc-label clr-text-url hover:underline'
|
||||||
|
onClick={() => setForceComment(true)}
|
||||||
|
>
|
||||||
|
Добавить комментарий
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
<AnimateFade hideContent={!showConvention}>
|
||||||
|
<TextArea
|
||||||
|
id='dlg_cst_convention'
|
||||||
|
spellCheck
|
||||||
|
label={isBasic ? 'Конвенция' : 'Комментарий'}
|
||||||
|
placeholder={isBasic ? 'Договоренность об интерпретации' : 'Пояснение разработчика'}
|
||||||
|
rows={2}
|
||||||
|
value={state.convention}
|
||||||
|
onChange={event => partialUpdate({ convention: event.target.value })}
|
||||||
|
/>
|
||||||
|
</AnimateFade>
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormCreateCst;
|
1
rsconcept/frontend/src/dialogs/DlgCreateCst/index.tsx
Normal file
1
rsconcept/frontend/src/dialogs/DlgCreateCst/index.tsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './DlgCreateCst';
|
|
@ -121,7 +121,7 @@ function CreateRSFormPage() {
|
||||||
/>
|
/>
|
||||||
<TextArea
|
<TextArea
|
||||||
id='schema_comment'
|
id='schema_comment'
|
||||||
label='Комментарий'
|
label='Описание'
|
||||||
placeholder={file && 'Загрузить из файла'}
|
placeholder={file && 'Загрузить из файла'}
|
||||||
value={comment}
|
value={comment}
|
||||||
onChange={event => setComment(event.target.value)}
|
onChange={event => setComment(event.target.value)}
|
||||||
|
|
|
@ -105,7 +105,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
showList={showList}
|
showList={showList}
|
||||||
id={globals.constituenta_editor}
|
id={globals.constituenta_editor}
|
||||||
constituenta={activeCst}
|
state={activeCst}
|
||||||
isModified={isModified}
|
isModified={isModified}
|
||||||
toggleReset={toggleReset}
|
toggleReset={toggleReset}
|
||||||
onToggleList={() => setShowList(prev => !prev)}
|
onToggleList={() => setShowList(prev => !prev)}
|
||||||
|
|
|
@ -28,7 +28,7 @@ interface FormConstituentaProps {
|
||||||
showList: boolean;
|
showList: boolean;
|
||||||
|
|
||||||
id?: string;
|
id?: string;
|
||||||
constituenta?: IConstituenta;
|
state?: IConstituenta;
|
||||||
|
|
||||||
isModified: boolean;
|
isModified: boolean;
|
||||||
toggleReset: boolean;
|
toggleReset: boolean;
|
||||||
|
@ -43,7 +43,7 @@ function FormConstituenta({
|
||||||
disabled,
|
disabled,
|
||||||
showList,
|
showList,
|
||||||
id,
|
id,
|
||||||
constituenta,
|
state,
|
||||||
|
|
||||||
isModified,
|
isModified,
|
||||||
setIsModified,
|
setIsModified,
|
||||||
|
@ -61,33 +61,34 @@ function FormConstituenta({
|
||||||
const [expression, setExpression] = useState('');
|
const [expression, setExpression] = useState('');
|
||||||
const [convention, setConvention] = useState('');
|
const [convention, setConvention] = useState('');
|
||||||
const [typification, setTypification] = useState('N/A');
|
const [typification, setTypification] = useState('N/A');
|
||||||
|
|
||||||
const [forceComment, setForceComment] = useState(false);
|
const [forceComment, setForceComment] = useState(false);
|
||||||
|
|
||||||
const isBasic = useMemo(() => !!constituenta && isBasicConcept(constituenta.cst_type), [constituenta]);
|
const isBasic = useMemo(() => !!state && isBasicConcept(state.cst_type), [state]);
|
||||||
const isElementary = useMemo(() => !!constituenta && isBaseSet(constituenta.cst_type), [constituenta]);
|
const isElementary = useMemo(() => !!state && isBaseSet(state.cst_type), [state]);
|
||||||
const showConvention = useMemo(
|
const showConvention = useMemo(
|
||||||
() => !constituenta || !!constituenta.convention || forceComment || isBasic,
|
() => !state || !!state.convention || forceComment || isBasic,
|
||||||
[constituenta, forceComment, isBasic]
|
[state, forceComment, isBasic]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!constituenta) {
|
if (!state) {
|
||||||
setIsModified(false);
|
setIsModified(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsModified(
|
setIsModified(
|
||||||
constituenta.term_raw !== term ||
|
state.term_raw !== term ||
|
||||||
constituenta.definition_raw !== textDefinition ||
|
state.definition_raw !== textDefinition ||
|
||||||
constituenta.convention !== convention ||
|
state.convention !== convention ||
|
||||||
constituenta.definition_formal !== expression
|
state.definition_formal !== expression
|
||||||
);
|
);
|
||||||
return () => setIsModified(false);
|
return () => setIsModified(false);
|
||||||
}, [
|
}, [
|
||||||
constituenta,
|
state,
|
||||||
constituenta?.term_raw,
|
state?.term_raw,
|
||||||
constituenta?.definition_formal,
|
state?.definition_formal,
|
||||||
constituenta?.definition_raw,
|
state?.definition_raw,
|
||||||
constituenta?.convention,
|
state?.convention,
|
||||||
term,
|
term,
|
||||||
textDefinition,
|
textDefinition,
|
||||||
expression,
|
expression,
|
||||||
|
@ -96,26 +97,26 @@ function FormConstituenta({
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (constituenta) {
|
if (state) {
|
||||||
setAlias(constituenta.alias);
|
setAlias(state.alias);
|
||||||
setConvention(constituenta.convention || '');
|
setConvention(state.convention || '');
|
||||||
setTerm(constituenta.term_raw || '');
|
setTerm(state.term_raw || '');
|
||||||
setTextDefinition(constituenta.definition_raw || '');
|
setTextDefinition(state.definition_raw || '');
|
||||||
setExpression(constituenta.definition_formal || '');
|
setExpression(state.definition_formal || '');
|
||||||
setTypification(constituenta ? labelCstTypification(constituenta) : 'N/A');
|
setTypification(state ? labelCstTypification(state) : 'N/A');
|
||||||
setForceComment(false);
|
setForceComment(false);
|
||||||
}
|
}
|
||||||
}, [constituenta, schema, toggleReset]);
|
}, [state, schema, toggleReset]);
|
||||||
|
|
||||||
function handleSubmit(event?: React.FormEvent<HTMLFormElement>) {
|
function handleSubmit(event?: React.FormEvent<HTMLFormElement>) {
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
if (!constituenta || processing) {
|
if (!state || processing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ICstUpdateData = {
|
const data: ICstUpdateData = {
|
||||||
id: constituenta.id,
|
id: state.id,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
convention: convention,
|
convention: convention,
|
||||||
definition_formal: expression,
|
definition_formal: expression,
|
||||||
|
@ -131,7 +132,7 @@ function FormConstituenta({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
modified={isModified}
|
modified={isModified}
|
||||||
processing={processing}
|
processing={processing}
|
||||||
constituenta={constituenta}
|
constituenta={state}
|
||||||
onEditTerm={onEditTerm}
|
onEditTerm={onEditTerm}
|
||||||
onRename={onRename}
|
onRename={onRename}
|
||||||
/>
|
/>
|
||||||
|
@ -147,8 +148,8 @@ function FormConstituenta({
|
||||||
placeholder='Обозначение, используемое в текстовых определениях'
|
placeholder='Обозначение, используемое в текстовых определениях'
|
||||||
items={schema?.items}
|
items={schema?.items}
|
||||||
value={term}
|
value={term}
|
||||||
initialValue={constituenta?.term_raw ?? ''}
|
initialValue={state?.term_raw ?? ''}
|
||||||
resolved={constituenta?.term_resolved ?? ''}
|
resolved={state?.term_resolved ?? ''}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={newValue => setTerm(newValue)}
|
onChange={newValue => setTerm(newValue)}
|
||||||
/>
|
/>
|
||||||
|
@ -165,23 +166,23 @@ function FormConstituenta({
|
||||||
resize: 'none'
|
resize: 'none'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AnimateFade hideContent={!!constituenta && !constituenta?.definition_formal && isElementary}>
|
<AnimateFade hideContent={!!state && !state?.definition_formal && isElementary}>
|
||||||
<EditorRSExpression
|
<EditorRSExpression
|
||||||
id='cst_expression'
|
id='cst_expression'
|
||||||
label={
|
label={
|
||||||
constituenta?.cst_type === CstType.STRUCTURED
|
state?.cst_type === CstType.STRUCTURED
|
||||||
? 'Область определения'
|
? 'Область определения'
|
||||||
: !!constituenta && isFunctional(constituenta.cst_type)
|
: !!state && isFunctional(state.cst_type)
|
||||||
? 'Определение функции'
|
? 'Определение функции'
|
||||||
: 'Формальное определение'
|
: 'Формальное определение'
|
||||||
}
|
}
|
||||||
placeholder={
|
placeholder={
|
||||||
constituenta?.cst_type !== CstType.STRUCTURED
|
state?.cst_type !== CstType.STRUCTURED
|
||||||
? 'Родоструктурное выражение'
|
? 'Родоструктурное выражение'
|
||||||
: 'Определение множества, которому принадлежат элементы родовой структуры'
|
: 'Определение множества, которому принадлежат элементы родовой структуры'
|
||||||
}
|
}
|
||||||
value={expression}
|
value={expression}
|
||||||
activeCst={constituenta}
|
activeCst={state}
|
||||||
showList={showList}
|
showList={showList}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
toggleReset={toggleReset}
|
toggleReset={toggleReset}
|
||||||
|
@ -190,7 +191,7 @@ function FormConstituenta({
|
||||||
setTypification={setTypification}
|
setTypification={setTypification}
|
||||||
/>
|
/>
|
||||||
</AnimateFade>
|
</AnimateFade>
|
||||||
<AnimateFade hideContent={!!constituenta && !constituenta?.definition_raw && isElementary}>
|
<AnimateFade hideContent={!!state && !state?.definition_raw && isElementary}>
|
||||||
<RefsInput
|
<RefsInput
|
||||||
id='cst_definition'
|
id='cst_definition'
|
||||||
label='Текстовое определение'
|
label='Текстовое определение'
|
||||||
|
@ -198,8 +199,8 @@ function FormConstituenta({
|
||||||
height='3.8rem'
|
height='3.8rem'
|
||||||
items={schema?.items}
|
items={schema?.items}
|
||||||
value={textDefinition}
|
value={textDefinition}
|
||||||
initialValue={constituenta?.definition_raw ?? ''}
|
initialValue={state?.definition_raw ?? ''}
|
||||||
resolved={constituenta?.definition_resolved ?? ''}
|
resolved={state?.definition_resolved ?? ''}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={newValue => setTextDefinition(newValue)}
|
onChange={newValue => setTextDefinition(newValue)}
|
||||||
/>
|
/>
|
||||||
|
@ -210,7 +211,7 @@ function FormConstituenta({
|
||||||
spellCheck
|
spellCheck
|
||||||
className='h-[3.8rem]'
|
className='h-[3.8rem]'
|
||||||
label={isBasic ? 'Конвенция' : 'Комментарий'}
|
label={isBasic ? 'Конвенция' : 'Комментарий'}
|
||||||
placeholder='Договоренность об интерпретации или пояснение'
|
placeholder={isBasic ? 'Договоренность об интерпретации' : 'Пояснение разработчика'}
|
||||||
value={convention}
|
value={convention}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
rows={convention.length > 2 * ROW_SIZE_IN_CHARACTERS ? 3 : 2}
|
rows={convention.length > 2 * ROW_SIZE_IN_CHARACTERS ? 3 : 2}
|
||||||
|
|
|
@ -149,7 +149,7 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
|
||||||
</div>
|
</div>
|
||||||
<TextArea
|
<TextArea
|
||||||
id='schema_comment'
|
id='schema_comment'
|
||||||
label='Комментарий'
|
label='Описание'
|
||||||
rows={3}
|
rows={3}
|
||||||
value={comment}
|
value={comment}
|
||||||
disabled={!controller.isContentEditable || controller.isProcessing}
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user