F: Update substitute UI with nominal cst
Some checks are pending
Backend CI / build (3.12) (push) Waiting to run
Backend CI / notify-failure (push) Blocked by required conditions
Frontend CI / build (22.x) (push) Waiting to run
Frontend CI / notify-failure (push) Blocked by required conditions

This commit is contained in:
Ivan 2025-08-12 17:59:28 +03:00
parent c63144e78b
commit 593b483936
5 changed files with 36 additions and 6 deletions

View File

@ -217,6 +217,7 @@
"неитерируемого", "неитерируемого",
"Никанорова", "Никанорова",
"Номеноид", "Номеноид",
"номеноида",
"Номеноиды", "Номеноиды",
"операционализации", "операционализации",
"операционализированных", "операционализированных",

View File

@ -42,6 +42,8 @@ export function describeSubstitutionError(error: RO<ISubstitutionErrorDescriptio
return `Ошибка ${error.params[0]} -> ${error.params[1]}: замена структурного понятия базисным множеством`; return `Ошибка ${error.params[0]} -> ${error.params[1]}: замена структурного понятия базисным множеством`;
case SubstitutionErrorType.invalidConstant: case SubstitutionErrorType.invalidConstant:
return `Ошибка ${error.params[0]} -> ${error.params[1]}: подстановка константного множества возможна только вместо другого константного`; return `Ошибка ${error.params[0]} -> ${error.params[1]}: подстановка константного множества возможна только вместо другого константного`;
case SubstitutionErrorType.invalidNominal:
return `Ошибка ${error.params[0]} -> ${error.params[1]}: подстановка номеноида возможна только вместо другого номеноида`;
case SubstitutionErrorType.invalidClasses: case SubstitutionErrorType.invalidClasses:
return `Ошибка ${error.params[0]} -> ${error.params[1]}: классы конституент не совпадают`; return `Ошибка ${error.params[0]} -> ${error.params[1]}: классы конституент не совпадают`;
case SubstitutionErrorType.typificationCycle: case SubstitutionErrorType.typificationCycle:

View File

@ -183,8 +183,18 @@ export class SubstitutionValidator {
return this.reportError(SubstitutionErrorType.incorrectCst, [substitution.alias, original.alias]); return this.reportError(SubstitutionErrorType.incorrectCst, [substitution.alias, original.alias]);
} }
switch (substitution.cst_type) { switch (substitution.cst_type) {
case CstType.NOMINAL: {
if (original.cst_type !== CstType.NOMINAL) {
return this.reportError(SubstitutionErrorType.invalidNominal, [substitution.alias, original.alias]);
}
break;
}
case CstType.BASE: { case CstType.BASE: {
if (original.cst_type !== CstType.BASE && original.cst_type !== CstType.CONSTANT) { if (
original.cst_type !== CstType.BASE &&
original.cst_type !== CstType.CONSTANT &&
original.cst_type !== CstType.NOMINAL
) {
return this.reportError(SubstitutionErrorType.invalidBasic, [substitution.alias, original.alias]); return this.reportError(SubstitutionErrorType.invalidBasic, [substitution.alias, original.alias]);
} }
break; break;
@ -295,7 +305,11 @@ export class SubstitutionValidator {
} }
for (const item of this.substitutions) { for (const item of this.substitutions) {
const original = this.cstByID.get(item.original)!; const original = this.cstByID.get(item.original)!;
if (original.cst_type === CstType.BASE || original.cst_type === CstType.CONSTANT) { if (
original.cst_type === CstType.BASE ||
original.cst_type === CstType.CONSTANT ||
original.cst_type === CstType.NOMINAL
) {
continue; continue;
} }
const substitution = this.cstByID.get(item.substitution)!; const substitution = this.cstByID.get(item.substitution)!;

View File

@ -112,7 +112,8 @@ export const SubstitutionErrorType = {
unequalTypification: 7, unequalTypification: 7,
unequalExpressions: 8, unequalExpressions: 8,
unequalArgsCount: 9, unequalArgsCount: 9,
unequalArgs: 10 unequalArgs: 10,
invalidNominal: 11
} as const; } as const;
export type SubstitutionErrorType = (typeof SubstitutionErrorType)[keyof typeof SubstitutionErrorType]; export type SubstitutionErrorType = (typeof SubstitutionErrorType)[keyof typeof SubstitutionErrorType];

View File

@ -1,11 +1,13 @@
'use client'; 'use client';
import { Controller, useForm } from 'react-hook-form'; import { Controller, useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help'; import { HelpTopic } from '@/features/help';
import { SubstitutionValidator } from '@/features/oss/models/oss-api';
import { ErrorField } from '@/components/input'; import { ErrorField, TextArea } from '@/components/input';
import { ModalForm } from '@/components/modal'; import { ModalForm } from '@/components/modal';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
@ -34,6 +36,10 @@ export function DlgSubstituteCst() {
}, },
mode: 'onChange' mode: 'onChange'
}); });
const substitutions = useWatch({ control, name: 'substitutions' });
const validator = new SubstitutionValidator([schema], substitutions);
const isCorrect = validator.validate();
function onSubmit(data: ISubstitutionsDTO) { function onSubmit(data: ISubstitutionsDTO) {
return cstSubstitute({ itemID: schema.id, data: data }).then(() => onSubstitute(data)); return cstSubstitute({ itemID: schema.id, data: data }).then(() => onSubstitute(data));
@ -62,7 +68,13 @@ export function DlgSubstituteCst() {
/> />
)} )}
/> />
<ErrorField className='mt-2' error={errors.substitutions} /> <ErrorField className='-mt-6 px-3' error={errors.substitutions} />
<TextArea
disabled
value={validator.msg}
rows={4}
className={clsx('mt-3', isCorrect ? '' : 'border-(--acc-fg-red) border-2')}
/>
</ModalForm> </ModalForm>
); );
} }