Refactor dialogs using partialUpdate hook for states

This commit is contained in:
IRBorisov 2023-11-01 20:14:50 +03:00
parent e1d82d4b3a
commit 90c8303ee7
7 changed files with 142 additions and 220 deletions

View File

@ -5,9 +5,10 @@ import SelectSingle from '../components/Common/SelectSingle';
import TextArea from '../components/Common/TextArea'; import TextArea from '../components/Common/TextArea';
import TextInput from '../components/Common/TextInput'; import TextInput from '../components/Common/TextInput';
import RSInput from '../components/RSInput'; import RSInput from '../components/RSInput';
import usePartialUpdate from '../hooks/usePartialUpdate';
import { CstType,ICstCreateData, IRSForm } from '../models/rsform'; import { CstType,ICstCreateData, IRSForm } from '../models/rsform';
import { labelCstType } from '../utils/labels'; import { labelCstType } from '../utils/labels';
import { createAliasFor, getCstTypePrefix } from '../utils/misc'; import { createAliasFor, validateCstAlias } from '../utils/misc';
import { SelectorCstType } from '../utils/selectors'; import { SelectorCstType } from '../utils/selectors';
interface DlgCreateCstProps interface DlgCreateCstProps
@ -19,53 +20,31 @@ extends Pick<ModalProps, 'hideWindow'> {
function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) { function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) {
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
const [selectedType, setSelectedType] = useState<CstType>(CstType.BASE);
const [alias, setAlias] = useState('');
const [term, setTerm] = useState(''); const [cstData, updateCstData] = usePartialUpdate(
const [textDefinition, setTextDefinition] = useState(''); initial || {
const [expression, setExpression] = useState(''); cst_type: CstType.BASE,
const [convention, setConvention] = useState(''); insert_after: null,
alias: '',
function getData(): ICstCreateData { convention: '',
return { definition_formal: '',
cst_type: selectedType, definition_raw: '',
insert_after: initial?.insert_after ?? null, term_raw: '',
alias: alias,
convention: convention,
definition_formal: expression,
definition_raw: textDefinition,
term_raw: term,
term_forms: [] term_forms: []
};
} }
);
const handleSubmit = () => onCreate(getData()); const handleSubmit = () => onCreate(cstData);
useLayoutEffect(() => {
if (initial) {
setSelectedType(initial.cst_type);
setTerm(initial.term_raw);
setTextDefinition(initial.definition_raw);
setExpression(initial.definition_formal);
setConvention(initial.convention);
setAlias(initial.alias);
}
}, [initial]);
useLayoutEffect( useLayoutEffect(
() => { () => {
setAlias(createAliasFor(selectedType, schema)); updateCstData({ alias: createAliasFor(cstData.cst_type, schema) });
}, [selectedType, schema]); }, [cstData.cst_type, updateCstData, schema]);
useEffect( useEffect(
() => { () => {
if(alias.length < 2 || alias[0] !== getCstTypePrefix(selectedType)) { setValidated(validateCstAlias(cstData.alias, cstData.cst_type, schema));
setValidated(false); }, [cstData.alias, cstData.cst_type, schema]);
} else {
setValidated(!schema.items.find(cst => cst.alias === alias))
}
}, [alias, selectedType, schema]);
return ( return (
<Modal <Modal
@ -81,43 +60,43 @@ function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstPro
className='my-2 min-w-[15rem] self-center' className='my-2 min-w-[15rem] self-center'
options={SelectorCstType} options={SelectorCstType}
placeholder='Выберите тип' placeholder='Выберите тип'
value={selectedType ? { value: selectedType, label: labelCstType(selectedType) } : null} value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }}
onChange={data => setSelectedType(data?.value ?? CstType.BASE)} onChange={data => updateCstData({ cst_type: data?.value ?? CstType.BASE})}
/> />
<TextInput id='alias' label='Имя' <TextInput id='alias' label='Имя'
dense dense
dimensions='w-[7rem]' dimensions='w-[7rem]'
value={alias} value={cstData.alias}
onChange={event => setAlias(event.target.value)} onChange={event => updateCstData({ alias: event.target.value})}
/> />
</div> </div>
<TextArea id='term' label='Термин' <TextArea id='term' label='Термин'
placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение' placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение'
rows={2} rows={2}
value={term} value={cstData.term_raw}
spellCheck spellCheck
onChange={event => setTerm(event.target.value)} onChange={event => updateCstData({ term_raw: event.target.value })}
/> />
<RSInput id='expression' label='Формальное выражение' <RSInput id='expression' label='Формальное выражение'
placeholder='Родоструктурное выражение, задающее формальное определение' placeholder='Родоструктурное выражение, задающее формальное определение'
editable editable
height='4.8rem' height='4.8rem'
value={expression} value={cstData.definition_formal}
onChange={value => setExpression(value)} onChange={value => updateCstData({definition_formal: value})}
/> />
<TextArea id='definition' label='Текстовое определение' <TextArea id='definition' label='Текстовое определение'
placeholder='Лингвистическая интерпретация формального выражения' placeholder='Лингвистическая интерпретация формального выражения'
rows={2} rows={2}
value={textDefinition} value={cstData.definition_raw}
spellCheck spellCheck
onChange={event => setTextDefinition(event.target.value)} onChange={event => updateCstData({ definition_raw: event.target.value })}
/> />
<TextArea id='convention' label='Конвенция / Комментарий' <TextArea id='convention' label='Конвенция / Комментарий'
placeholder='Договоренность об интерпретации неопределяемого понятия&#x000D;&#x000A;Комментарий к производному понятию' placeholder='Договоренность об интерпретации неопределяемого понятия&#x000D;&#x000A;Комментарий к производному понятию'
rows={2} rows={2}
value={convention} value={cstData.convention}
spellCheck spellCheck
onChange={event => setConvention(event.target.value)} onChange={event => updateCstData({ convention: event.target.value })}
/> />
</div> </div>
</Modal> </Modal>

View File

@ -1,7 +1,6 @@
import { useLayoutEffect, useState } from 'react';
import Checkbox from '../components/Common/Checkbox'; import Checkbox from '../components/Common/Checkbox';
import Modal, { ModalProps } from '../components/Common/Modal'; import Modal, { ModalProps } from '../components/Common/Modal';
import usePartialUpdate from '../hooks/usePartialUpdate';
import { GraphEditorParams } from '../models/miscelanious'; import { GraphEditorParams } from '../models/miscelanious';
import { CstType } from '../models/rsform'; import { CstType } from '../models/rsform';
import { labelCstType } from '../utils/labels'; import { labelCstType } from '../utils/labels';
@ -12,60 +11,14 @@ extends Pick<ModalProps, 'hideWindow'> {
onConfirm: (params: GraphEditorParams) => void onConfirm: (params: GraphEditorParams) => void
} }
function DlgGraphOptions({ hideWindow, initial, onConfirm }:DlgGraphOptionsProps) { function DlgGraphOptions({ hideWindow, initial, onConfirm } : DlgGraphOptionsProps) {
const [ noHermits, setNoHermits ] = useState(true); const [params, updateParams] = usePartialUpdate(initial);
const [ noTransitive, setNoTransitive ] = useState(false);
const [ noTemplates, setNoTemplates ] = useState(true);
const [ noTerms, setNoTerms ] = useState(true);
const [ allowBase, setAllowBase ] = useState(true);
const [ allowStruct, setAllowStruct ] = useState(true);
const [ allowTerm, setAllowTerm ] = useState(true);
const [ allowAxiom, setAllowAxiom ] = useState(true);
const [ allowFunction, setAllowFunction ] = useState(true);
const [ allowPredicate, setAllowPredicate ] = useState(true);
const [ allowConstant, setAllowConstant ] = useState(true);
const [ allowTheorem, setAllowTheorem ] = useState(true);
function getParams() {
return {
noHermits: noHermits,
noTransitive: noTransitive,
noTemplates: noTemplates,
noTerms: noTerms,
allowBase: allowBase,
allowStruct: allowStruct,
allowTerm: allowTerm,
allowAxiom: allowAxiom,
allowFunction: allowFunction,
allowPredicate: allowPredicate,
allowConstant: allowConstant,
allowTheorem: allowTheorem
}
}
const handleSubmit = () => { const handleSubmit = () => {
hideWindow(); hideWindow();
onConfirm(getParams()); onConfirm(params);
}; };
useLayoutEffect(() => {
setNoHermits(initial.noHermits);
setNoTransitive(initial.noTransitive);
setNoTemplates(initial.noTemplates);
setNoTerms(initial.noTerms);
setAllowBase(initial.allowBase);
setAllowStruct(initial.allowStruct);
setAllowTerm(initial.allowTerm);
setAllowAxiom(initial.allowAxiom);
setAllowFunction(initial.allowFunction);
setAllowPredicate(initial.allowPredicate);
setAllowConstant(initial.allowConstant);
setAllowTheorem(initial.allowTheorem);
}, [initial]);
return ( return (
<Modal <Modal
hideWindow={hideWindow} hideWindow={hideWindow}
@ -80,69 +33,69 @@ function DlgGraphOptions({ hideWindow, initial, onConfirm }:DlgGraphOptionsProps
<Checkbox <Checkbox
label='Скрыть текст' label='Скрыть текст'
tooltip='Не отображать термины' tooltip='Не отображать термины'
value={noTerms} value={params.noTerms}
setValue={ value => setNoTerms(value) } setValue={ value => updateParams({noTerms: value}) }
/> />
<Checkbox <Checkbox
label='Скрыть несвязанные' label='Скрыть несвязанные'
tooltip='Неиспользуемые конституенты' tooltip='Неиспользуемые конституенты'
value={noHermits} value={params.noHermits}
setValue={ value => setNoHermits(value) } setValue={ value => updateParams({ noHermits: value}) }
/> />
<Checkbox <Checkbox
label='Скрыть шаблоны' label='Скрыть шаблоны'
tooltip='Терм-функции и предикат-функции с параметризованными аргументами' tooltip='Терм-функции и предикат-функции с параметризованными аргументами'
value={noTemplates} value={params.noTemplates}
setValue={ value => setNoTemplates(value) } setValue={ value => updateParams({ noTemplates: value}) }
/> />
<Checkbox <Checkbox
label='Транзитивная редукция' label='Транзитивная редукция'
tooltip='Удалить связи, образующие транзитивные пути в графе' tooltip='Удалить связи, образующие транзитивные пути в графе'
value={noTransitive} value={params.noTransitive}
setValue={ value => setNoTransitive(value) } setValue={ value => updateParams({ noTransitive: value}) }
/> />
</div> </div>
<div className='flex flex-col gap-1'> <div className='flex flex-col gap-1'>
<h1>Типы конституент</h1> <h1>Типы конституент</h1>
<Checkbox <Checkbox
label={labelCstType(CstType.BASE)} label={labelCstType(CstType.BASE)}
value={allowBase} value={params.allowBase}
setValue={ value => setAllowBase(value) } setValue={ value => updateParams({ allowBase: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.STRUCTURED)} label={labelCstType(CstType.STRUCTURED)}
value={allowStruct} value={params.allowStruct}
setValue={ value => setAllowStruct(value) } setValue={ value => updateParams({ allowStruct: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.TERM)} label={labelCstType(CstType.TERM)}
value={allowTerm} value={params.allowTerm}
setValue={ value => setAllowTerm(value) } setValue={ value => updateParams({ allowTerm: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.AXIOM)} label={labelCstType(CstType.AXIOM)}
value={allowAxiom} value={params.allowAxiom}
setValue={ value => setAllowAxiom(value) } setValue={ value => updateParams({ allowAxiom: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.FUNCTION)} label={labelCstType(CstType.FUNCTION)}
value={allowFunction} value={params.allowFunction}
setValue={ value => setAllowFunction(value) } setValue={ value => updateParams({ allowFunction: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.PREDICATE)} label={labelCstType(CstType.PREDICATE)}
value={allowPredicate} value={params.allowPredicate}
setValue={ value => setAllowPredicate(value) } setValue={ value => updateParams({ allowPredicate: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.CONSTANT)} label={labelCstType(CstType.CONSTANT)}
value={allowConstant} value={params.allowConstant}
setValue={ value => setAllowConstant(value) } setValue={ value => updateParams({ allowConstant: value}) }
/> />
<Checkbox <Checkbox
label={labelCstType(CstType.THEOREM)} label={labelCstType(CstType.THEOREM)}
value={allowTheorem} value={params.allowTheorem}
setValue ={ value => setAllowTheorem(value) } setValue ={ value => updateParams({ allowTheorem: value}) }
/> />
</div> </div>
</div> </div>

View File

@ -4,60 +4,40 @@ import Modal, { ModalProps } from '../components/Common/Modal';
import SelectSingle from '../components/Common/SelectSingle'; import SelectSingle from '../components/Common/SelectSingle';
import TextInput from '../components/Common/TextInput'; import TextInput from '../components/Common/TextInput';
import { useRSForm } from '../context/RSFormContext'; import { useRSForm } from '../context/RSFormContext';
import usePartialUpdate from '../hooks/usePartialUpdate';
import { CstType, ICstRenameData } from '../models/rsform'; import { CstType, ICstRenameData } from '../models/rsform';
import { labelCstType } from '../utils/labels'; import { labelCstType } from '../utils/labels';
import { createAliasFor, getCstTypePrefix } from '../utils/misc'; import { createAliasFor, validateCstAlias } from '../utils/misc';
import { SelectorCstType } from '../utils/selectors'; import { SelectorCstType } from '../utils/selectors';
interface DlgRenameCstProps interface DlgRenameCstProps
extends Pick<ModalProps, 'hideWindow'> { extends Pick<ModalProps, 'hideWindow'> {
initial?: ICstRenameData initial: ICstRenameData
onRename: (data: ICstRenameData) => void onRename: (data: ICstRenameData) => void
} }
function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) { function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
const { schema } = useRSForm(); const { schema } = useRSForm();
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
const [cstType, setCstType] = useState<CstType>(CstType.BASE); const [cstData, updateData] = usePartialUpdate(initial);
const [cstID, setCstID] = useState(0)
const [alias, setAlias] = useState('');
function getData(): ICstRenameData { const handleSubmit = () => onRename(cstData);
return {
cst_type: cstType,
alias: alias,
id: cstID
}
}
const handleSubmit = () => onRename(getData());
useLayoutEffect( useLayoutEffect(
() => { () => {
if (schema && initial && cstType !== initial.cst_type) { if (schema && initial && cstData.cst_type !== initial.cst_type) {
setAlias(createAliasFor(cstType, schema)); updateData({ alias: createAliasFor(cstData.cst_type, schema)});
} }
}, [initial, cstType, schema]); }, [initial, cstData.cst_type, updateData, schema]);
useLayoutEffect( useLayoutEffect(
() => { () => {
if (initial) { setValidated(
setCstType(initial.cst_type); !!schema &&
setAlias(initial.alias); cstData.alias !== initial.alias &&
setCstID(initial.id); validateCstAlias(cstData.alias, cstData.cst_type, schema)
} );
}, [initial]); }, [cstData.cst_type, cstData.alias, initial, schema]);
useLayoutEffect(
() => {
if (!initial || !schema) {
setValidated(false);
} else if(alias === initial.alias || alias.length < 2 || alias[0] !== getCstTypePrefix(cstType)) {
setValidated(false);
} else {
setValidated(!schema.items.find(cst => cst.alias === alias))
}
}, [cstType, alias, initial, schema]);
return ( return (
<Modal <Modal
@ -73,15 +53,15 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
className='min-w-[14rem] self-center z-modal-top' className='min-w-[14rem] self-center z-modal-top'
options={SelectorCstType} options={SelectorCstType}
placeholder='Выберите тип' placeholder='Выберите тип'
value={cstType ? { value: cstType, label: labelCstType(cstType) } : null} value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }}
onChange={data => setCstType(data?.value ?? CstType.BASE)} onChange={data => updateData({cst_type: data?.value ?? CstType.BASE})}
/> />
<div> <div>
<TextInput id='alias' label='Имя' <TextInput id='alias' label='Имя'
dense dense
dimensions='w-[7rem]' dimensions='w-[7rem]'
value={alias} value={cstData.alias}
onChange={event => setAlias(event.target.value)} onChange={event => updateData({alias: event.target.value})}
/> />
</div> </div>
</div> </div>

View File

@ -1,18 +1,19 @@
import { useEffect, useLayoutEffect, useState } from 'react'; import { useEffect, useLayoutEffect, useState } from 'react';
import ConceptTooltip from '../components/Common/ConceptTooltip'; import ConceptTooltip from '../../components/Common/ConceptTooltip';
import Modal, { ModalProps } from '../components/Common/Modal'; import Modal, { ModalProps } from '../../components/Common/Modal';
import SelectSingle from '../components/Common/SelectSingle'; import SelectSingle from '../../components/Common/SelectSingle';
import SwitchButton from '../components/Common/SwitchButton'; import SwitchButton from '../../components/Common/SwitchButton';
import TextArea from '../components/Common/TextArea'; import TextArea from '../../components/Common/TextArea';
import TextInput from '../components/Common/TextInput'; import TextInput from '../../components/Common/TextInput';
import HelpRSTemplates from '../components/Help/HelpRSTemplates'; import HelpRSTemplates from '../../components/Help/HelpRSTemplates';
import { HelpIcon } from '../components/Icons'; import { HelpIcon } from '../../components/Icons';
import RSInput from '../components/RSInput'; import RSInput from '../../components/RSInput';
import { CstType,ICstCreateData, IRSForm } from '../models/rsform'; import usePartialUpdate from '../../hooks/usePartialUpdate';
import { labelCstType } from '../utils/labels'; import { CstType,ICstCreateData, IRSForm } from '../../models/rsform';
import { createAliasFor, getCstTypePrefix } from '../utils/misc'; import { labelCstType } from '../../utils/labels';
import { SelectorCstType } from '../utils/selectors'; import { createAliasFor, validateCstAlias } from '../../utils/misc';
import { SelectorCstType } from '../../utils/selectors';
interface DlgTemplatesProps interface DlgTemplatesProps
extends Pick<ModalProps, 'hideWindow'> { extends Pick<ModalProps, 'hideWindow'> {
@ -22,44 +23,30 @@ extends Pick<ModalProps, 'hideWindow'> {
function DlgTemplates({ hideWindow, schema, onCreate }: DlgTemplatesProps) { function DlgTemplates({ hideWindow, schema, onCreate }: DlgTemplatesProps) {
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
const [selectedType, setSelectedType] = useState<CstType>(CstType.TERM); const [cstData, updateCstData] = usePartialUpdate({
const [alias, setAlias] = useState(''); cst_type: CstType.TERM,
insert_after: null,
const [term, setTerm] = useState(''); alias: '',
const [textDefinition, setTextDefinition] = useState(''); convention: '',
const [expression, setExpression] = useState(''); definition_formal: '',
const [convention, setConvention] = useState(''); definition_raw: '',
term_raw: '',
term_forms: []
});
const [ showAttributes, setShowAttributes ] = useState(false); const [ showAttributes, setShowAttributes ] = useState(false);
function getData(): ICstCreateData { const handleSubmit = () => onCreate(cstData);
return {
cst_type: selectedType,
insert_after: null,
alias: alias,
convention: convention,
definition_formal: expression,
definition_raw: textDefinition,
term_raw: term,
term_forms: []
};
}
const handleSubmit = () => onCreate(getData());
useLayoutEffect( useLayoutEffect(
() => { () => {
setAlias(createAliasFor(selectedType, schema)); updateCstData({ alias: createAliasFor(cstData.cst_type, schema) });
}, [selectedType, schema]); }, [cstData.cst_type, updateCstData, schema]);
useEffect( useEffect(
() => { () => {
if(alias.length < 2 || alias[0] !== getCstTypePrefix(selectedType)) { setValidated(validateCstAlias(cstData.alias, cstData.cst_type, schema));
setValidated(false); }, [cstData.alias, cstData.cst_type, schema]);
} else {
setValidated(!schema.items.find(cst => cst.alias === alias))
}
}, [alias, selectedType, schema]);
return ( return (
<Modal <Modal
@ -111,43 +98,43 @@ function DlgTemplates({ hideWindow, schema, onCreate }: DlgTemplatesProps) {
className='my-2 min-w-[15rem] self-center' className='my-2 min-w-[15rem] self-center'
options={SelectorCstType} options={SelectorCstType}
placeholder='Выберите тип' placeholder='Выберите тип'
value={selectedType ? { value: selectedType, label: labelCstType(selectedType) } : null} value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }}
onChange={data => setSelectedType(data?.value ?? CstType.BASE)} onChange={data => updateCstData({ cst_type: data?.value ?? CstType.TERM})}
/> />
<TextInput id='alias' label='Имя' <TextInput id='alias' label='Имя'
dense dense
dimensions='w-[7rem]' dimensions='w-[7rem]'
value={alias} value={cstData.alias}
onChange={event => setAlias(event.target.value)} onChange={event => updateCstData({ alias: event.target.value})}
/> />
</div> </div>
<TextArea id='term' label='Термин' <TextArea id='term' label='Термин'
placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение' placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение'
rows={2} rows={2}
value={term} value={cstData.term_raw}
spellCheck spellCheck
onChange={event => setTerm(event.target.value)} onChange={event => updateCstData({ term_raw: event.target.value })}
/> />
<RSInput id='expression' label='Формальное выражение' <RSInput id='expression' label='Формальное выражение'
placeholder='Родоструктурное выражение, задающее формальное определение' placeholder='Родоструктурное выражение, задающее формальное определение'
editable editable
height='4.8rem' height='4.8rem'
value={expression} value={cstData.definition_formal}
onChange={value => setExpression(value)} onChange={value => updateCstData({definition_formal: value})}
/> />
<TextArea id='definition' label='Текстовое определение' <TextArea id='definition' label='Текстовое определение'
placeholder='Лингвистическая интерпретация формального выражения' placeholder='Лингвистическая интерпретация формального выражения'
rows={2} rows={2}
value={textDefinition} value={cstData.definition_raw}
spellCheck spellCheck
onChange={event => setTextDefinition(event.target.value)} onChange={event => updateCstData({ definition_raw: event.target.value })}
/> />
<TextArea id='convention' label='Конвенция / Комментарий' <TextArea id='convention' label='Конвенция / Комментарий'
placeholder='Договоренность об интерпретации неопределяемого понятия&#x000D;&#x000A;Комментарий к производному понятию' placeholder='Договоренность об интерпретации неопределяемого понятия&#x000D;&#x000A;Комментарий к производному понятию'
rows={2} rows={2}
value={convention} value={cstData.convention}
spellCheck spellCheck
onChange={event => setConvention(event.target.value)} onChange={event => updateCstData({ convention: event.target.value })}
/> />
</div>} </div>}
</div> </div>

View File

@ -0,0 +1,15 @@
import { useReducer } from 'react';
function usePartialUpdate<ValueType>(initialValue: ValueType) {
const [value, updateValue] = useReducer(
(data: ValueType, newData: Partial<ValueType>) => ({
...data,
...newData,
}),
initialValue
);
return [value, updateValue] as [ValueType, typeof updateValue];
}
export default usePartialUpdate;

View File

@ -360,7 +360,7 @@ function RSTabs() {
<DlgRenameCst <DlgRenameCst
hideWindow={() => setShowRenameCst(false)} hideWindow={() => setShowRenameCst(false)}
onRename={handleRenameCst} onRename={handleRenameCst}
initial={renameInitialData} initial={renameInitialData!}
/>} />}
{showDeleteCst && {showDeleteCst &&
<DlgDeleteCst <DlgDeleteCst

View File

@ -19,6 +19,14 @@ export function getCstTypePrefix(type: CstType) {
} }
} }
export function validateCstAlias(alias: string, type: CstType, schema: IRSForm): boolean {
return (
alias.length >= 2 &&
alias[0] == getCstTypePrefix(type) &&
!schema.items.find(cst => cst.alias === alias)
);
}
export function getCstExpressionPrefix(cst: IConstituenta): string { export function getCstExpressionPrefix(cst: IConstituenta): string {
return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':=='); return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':==');
} }