mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
F: Rework cst create and template dialogs
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
This commit is contained in:
parent
4853884251
commit
91184f798a
|
@ -4,7 +4,7 @@ import { ILibraryItemReference, ILibraryItemVersioned } from '@/features/library
|
||||||
|
|
||||||
import { errorMsg } from '@/utils/labels';
|
import { errorMsg } from '@/utils/labels';
|
||||||
|
|
||||||
import { CstType, IConstituentaMeta, IInheritanceInfo, TermForm } from '../models/rsform';
|
import { CstType, IConstituentaMeta, IInheritanceInfo } from '../models/rsform';
|
||||||
import { IArgumentInfo, ParsingStatus, ValueClass } from '../models/rslang';
|
import { IArgumentInfo, ParsingStatus, ValueClass } from '../models/rslang';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,17 +42,21 @@ export interface IRSFormUploadDTO {
|
||||||
/**
|
/**
|
||||||
* Represents {@link IConstituenta} data, used in creation process.
|
* Represents {@link IConstituenta} data, used in creation process.
|
||||||
*/
|
*/
|
||||||
export interface ICstCreateDTO {
|
export const schemaCstCreate = z.object({
|
||||||
alias: string;
|
cst_type: z.nativeEnum(CstType),
|
||||||
cst_type: CstType;
|
alias: z.string().nonempty(errorMsg.requiredField),
|
||||||
definition_raw: string;
|
convention: z.string(),
|
||||||
term_raw: string;
|
definition_formal: z.string(),
|
||||||
convention: string;
|
definition_raw: z.string(),
|
||||||
definition_formal: string;
|
term_raw: z.string(),
|
||||||
term_forms: TermForm[];
|
term_forms: z.array(z.object({ text: z.string(), tags: z.string() })),
|
||||||
|
insert_after: z.number().nullable()
|
||||||
|
});
|
||||||
|
|
||||||
insert_after: number | null;
|
/**
|
||||||
}
|
* Represents {@link IConstituenta} data, used in creation process.
|
||||||
|
*/
|
||||||
|
export type ICstCreateDTO = z.infer<typeof schemaCstCreate>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents data response when creating {@link IConstituenta}.
|
* Represents data response when creating {@link IConstituenta}.
|
||||||
|
|
|
@ -1,54 +1,53 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { FormProvider, useForm, useWatch } from 'react-hook-form';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
|
||||||
import { ModalForm } from '@/components/Modal';
|
import { ModalForm } from '@/components/Modal';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
import { errorMsg } from '@/utils/labels';
|
||||||
|
|
||||||
import { ICstCreateDTO } from '../../backend/types';
|
import { ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||||
import { CstType, IRSForm } from '../../models/rsform';
|
import { useCstCreate } from '../../backend/useCstCreate';
|
||||||
import { generateAlias } from '../../models/rsformAPI';
|
import { IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||||
|
import { validateNewAlias } from '../../models/rsformAPI';
|
||||||
|
|
||||||
import FormCreateCst from './FormCreateCst';
|
import FormCreateCst from './FormCreateCst';
|
||||||
|
|
||||||
export interface DlgCreateCstProps {
|
export interface DlgCreateCstProps {
|
||||||
initial?: ICstCreateDTO;
|
initial: ICstCreateDTO;
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
onCreate: (data: ICstCreateDTO) => void;
|
onCreate: (data: IConstituentaMeta) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgCreateCst() {
|
function DlgCreateCst() {
|
||||||
const { initial, schema, onCreate } = useDialogsStore(state => state.props as DlgCreateCstProps);
|
const { initial, schema, onCreate } = useDialogsStore(state => state.props as DlgCreateCstProps);
|
||||||
|
const { cstCreate } = useCstCreate();
|
||||||
|
|
||||||
const [validated, setValidated] = useState(false);
|
const methods = useForm<ICstCreateDTO>({
|
||||||
const [cstData, updateCstData] = usePartialUpdate(
|
resolver: zodResolver(schemaCstCreate),
|
||||||
initial || {
|
defaultValues: { ...initial }
|
||||||
cst_type: CstType.BASE,
|
});
|
||||||
insert_after: null,
|
const alias = useWatch({ control: methods.control, name: 'alias' });
|
||||||
alias: generateAlias(CstType.BASE, schema),
|
const cst_type = useWatch({ control: methods.control, name: 'cst_type' });
|
||||||
convention: '',
|
const isValid = alias !== initial.alias && validateNewAlias(alias, cst_type, schema);
|
||||||
definition_formal: '',
|
|
||||||
definition_raw: '',
|
function onSubmit(data: ICstCreateDTO) {
|
||||||
term_raw: '',
|
return cstCreate({ itemID: schema.id, data }).then(onCreate);
|
||||||
term_forms: []
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
onCreate(cstData);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalForm
|
<ModalForm
|
||||||
header='Создание конституенты'
|
header='Создание конституенты'
|
||||||
canSubmit={validated}
|
canSubmit={isValid}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
|
||||||
|
submitInvalidTooltip={errorMsg.aliasInvalid}
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
className='cc-column w-[35rem] max-h-[30rem] py-2 px-6'
|
className='cc-column w-[35rem] max-h-[30rem] py-2 px-6'
|
||||||
>
|
>
|
||||||
<FormCreateCst schema={schema} state={cstData} partialUpdate={updateCstData} setValidated={setValidated} />
|
<FormProvider {...methods}>
|
||||||
|
<FormCreateCst schema={schema} />
|
||||||
|
</FormProvider>
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { BadgeHelp, HelpTopic } from '@/features/help';
|
import { BadgeHelp, HelpTopic } from '@/features/help';
|
||||||
|
@ -12,48 +13,45 @@ import { ICstCreateDTO } from '../../backend/types';
|
||||||
import RSInput from '../../components/RSInput';
|
import RSInput from '../../components/RSInput';
|
||||||
import { SelectCstType } from '../../components/SelectCstType';
|
import { SelectCstType } from '../../components/SelectCstType';
|
||||||
import { CstType, IRSForm } from '../../models/rsform';
|
import { CstType, IRSForm } from '../../models/rsform';
|
||||||
import { generateAlias, isBaseSet, isBasicConcept, isFunctional, validateNewAlias } from '../../models/rsformAPI';
|
import { generateAlias, isBaseSet, isBasicConcept, isFunctional } from '../../models/rsformAPI';
|
||||||
|
|
||||||
interface FormCreateCstProps {
|
interface FormCreateCstProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
state: ICstCreateDTO;
|
|
||||||
|
|
||||||
partialUpdate: React.Dispatch<Partial<ICstCreateDTO>>;
|
|
||||||
setValidated?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreateCstProps) {
|
function FormCreateCst({ schema }: FormCreateCstProps) {
|
||||||
|
const {
|
||||||
|
setValue,
|
||||||
|
register,
|
||||||
|
control,
|
||||||
|
formState: { errors }
|
||||||
|
} = useFormContext<ICstCreateDTO>();
|
||||||
const [forceComment, setForceComment] = useState(false);
|
const [forceComment, setForceComment] = useState(false);
|
||||||
|
|
||||||
const isBasic = isBasicConcept(state.cst_type);
|
const cst_type = useWatch({ control, name: 'cst_type' });
|
||||||
const isElementary = isBaseSet(state.cst_type);
|
const convention = useWatch({ control, name: 'convention' });
|
||||||
const showConvention = !!state.convention || forceComment || isBasic;
|
const isBasic = isBasicConcept(cst_type);
|
||||||
|
const isElementary = isBaseSet(cst_type);
|
||||||
useEffect(() => {
|
const isFunction = isFunctional(cst_type);
|
||||||
setForceComment(false);
|
const showConvention = !!convention || forceComment || isBasic;
|
||||||
}, [state.cst_type, partialUpdate, schema]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (setValidated) {
|
|
||||||
setValidated(validateNewAlias(state.alias, state.cst_type, schema));
|
|
||||||
}
|
|
||||||
}, [state.alias, state.cst_type, schema, setValidated]);
|
|
||||||
|
|
||||||
function handleTypeChange(target: CstType) {
|
function handleTypeChange(target: CstType) {
|
||||||
return partialUpdate({ cst_type: target, alias: generateAlias(target, schema) });
|
setValue('cst_type', target);
|
||||||
|
setValue('alias', generateAlias(target, schema));
|
||||||
|
setForceComment(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='flex items-center self-center gap-3'>
|
<div className='flex items-center self-center gap-3'>
|
||||||
<SelectCstType id='dlg_cst_type' className='w-[16rem]' value={state.cst_type} onChange={handleTypeChange} />
|
<SelectCstType id='dlg_cst_type' className='w-[16rem]' value={cst_type} onChange={handleTypeChange} />
|
||||||
<TextInput
|
<TextInput
|
||||||
id='dlg_cst_alias'
|
id='dlg_cst_alias'
|
||||||
dense
|
dense
|
||||||
label='Имя'
|
label='Имя'
|
||||||
className='w-[7rem]'
|
className='w-[7rem]'
|
||||||
value={state.alias}
|
{...register('alias')}
|
||||||
onChange={event => partialUpdate({ alias: event.target.value })}
|
error={errors.alias}
|
||||||
/>
|
/>
|
||||||
<BadgeHelp
|
<BadgeHelp
|
||||||
topic={HelpTopic.CC_CONSTITUENTA}
|
topic={HelpTopic.CC_CONSTITUENTA}
|
||||||
|
@ -69,31 +67,43 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
|
||||||
label='Термин'
|
label='Термин'
|
||||||
placeholder='Обозначение для текстовых определений'
|
placeholder='Обозначение для текстовых определений'
|
||||||
className='max-h-[3.6rem]'
|
className='max-h-[3.6rem]'
|
||||||
value={state.term_raw}
|
{...register('term_raw')}
|
||||||
onChange={event => partialUpdate({ term_raw: event.target.value })}
|
error={errors.term_raw}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!!state.definition_formal || !isElementary ? (
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name='definition_formal'
|
||||||
|
render={({ field }) =>
|
||||||
|
!!field.value || !isElementary ? (
|
||||||
<RSInput
|
<RSInput
|
||||||
id='dlg_cst_expression'
|
id='dlg_cst_expression'
|
||||||
noTooltip
|
noTooltip
|
||||||
label={
|
label={
|
||||||
state.cst_type === CstType.STRUCTURED
|
cst_type === CstType.STRUCTURED
|
||||||
? 'Область определения'
|
? 'Область определения'
|
||||||
: isFunctional(state.cst_type)
|
: isFunction
|
||||||
? 'Определение функции'
|
? 'Определение функции'
|
||||||
: 'Формальное определение'
|
: 'Формальное определение'
|
||||||
}
|
}
|
||||||
placeholder={
|
placeholder={
|
||||||
state.cst_type !== CstType.STRUCTURED ? 'Родоструктурное выражение' : 'Типизация родовой структуры'
|
cst_type !== CstType.STRUCTURED ? 'Родоструктурное выражение' : 'Типизация родовой структуры'
|
||||||
}
|
}
|
||||||
value={state.definition_formal}
|
value={field.value}
|
||||||
onChange={value => partialUpdate({ definition_formal: value })}
|
onChange={field.onChange}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
{!!state.definition_raw || !isElementary ? (
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name='definition_raw'
|
||||||
|
render={({ field }) =>
|
||||||
|
!!field.value || !isElementary ? (
|
||||||
<TextArea
|
<TextArea
|
||||||
id='dlg_cst_definition'
|
id='dlg_cst_definition'
|
||||||
spellCheck
|
spellCheck
|
||||||
|
@ -101,10 +111,14 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
|
||||||
label='Текстовое определение'
|
label='Текстовое определение'
|
||||||
placeholder='Текстовая интерпретация формального выражения'
|
placeholder='Текстовая интерпретация формального выражения'
|
||||||
className='max-h-[3.6rem]'
|
className='max-h-[3.6rem]'
|
||||||
value={state.definition_raw}
|
value={field.value}
|
||||||
onChange={event => partialUpdate({ definition_raw: event.target.value })}
|
onChange={field.onChange}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
) : null}
|
|
||||||
|
|
||||||
{!showConvention ? (
|
{!showConvention ? (
|
||||||
<button
|
<button
|
||||||
|
@ -124,8 +138,7 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
|
||||||
label={isBasic ? 'Конвенция' : 'Комментарий'}
|
label={isBasic ? 'Конвенция' : 'Комментарий'}
|
||||||
placeholder={isBasic ? 'Договоренность об интерпретации' : 'Пояснение разработчика'}
|
placeholder={isBasic ? 'Договоренность об интерпретации' : 'Пояснение разработчика'}
|
||||||
className='max-h-[5.4rem]'
|
className='max-h-[5.4rem]'
|
||||||
value={state.convention}
|
{...register('convention')}
|
||||||
onChange={event => partialUpdate({ convention: event.target.value })}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Suspense, useEffect, useState } from 'react';
|
import { Suspense, useState } from 'react';
|
||||||
|
import { FormProvider, useForm, useWatch } from 'react-hook-form';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { HelpTopic } from '@/features/help';
|
import { HelpTopic } from '@/features/help';
|
||||||
|
@ -8,23 +10,21 @@ import { HelpTopic } from '@/features/help';
|
||||||
import { Loader } from '@/components/Loader';
|
import { Loader } from '@/components/Loader';
|
||||||
import { ModalForm } from '@/components/Modal';
|
import { ModalForm } from '@/components/Modal';
|
||||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
||||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { promptText } from '@/utils/labels';
|
|
||||||
|
|
||||||
import { ICstCreateDTO } from '../../backend/types';
|
import { ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||||
import { useRSForm } from '../../backend/useRSForm';
|
import { useCstCreate } from '../../backend/useCstCreate';
|
||||||
import { CstType, IRSForm } from '../../models/rsform';
|
import { CstType, IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||||
import { generateAlias, validateNewAlias } from '../../models/rsformAPI';
|
import { generateAlias, validateNewAlias } from '../../models/rsformAPI';
|
||||||
import { inferTemplatedType, substituteTemplateArgs } from '../../models/rslangAPI';
|
|
||||||
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
||||||
|
|
||||||
import TabArguments, { IArgumentsState } from './TabArguments';
|
import TabArguments from './TabArguments';
|
||||||
import TabTemplate, { ITemplateState } from './TabTemplate';
|
import TabTemplate from './TabTemplate';
|
||||||
|
import { TemplateState } from './TemplateContext';
|
||||||
|
|
||||||
export interface DlgCstTemplateProps {
|
export interface DlgCstTemplateProps {
|
||||||
schema: IRSForm;
|
schema: IRSForm;
|
||||||
onCreate: (data: ICstCreateDTO) => void;
|
onCreate: (data: IConstituentaMeta) => void;
|
||||||
insertAfter?: number;
|
insertAfter?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,15 +36,11 @@ export enum TabID {
|
||||||
|
|
||||||
function DlgCstTemplate() {
|
function DlgCstTemplate() {
|
||||||
const { schema, onCreate, insertAfter } = useDialogsStore(state => state.props as DlgCstTemplateProps);
|
const { schema, onCreate, insertAfter } = useDialogsStore(state => state.props as DlgCstTemplateProps);
|
||||||
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
|
const { cstCreate } = useCstCreate();
|
||||||
|
|
||||||
const [template, updateTemplate] = usePartialUpdate<ITemplateState>({});
|
const methods = useForm<ICstCreateDTO>({
|
||||||
const { schema: templateSchema } = useRSForm({ itemID: template.templateID });
|
resolver: zodResolver(schemaCstCreate),
|
||||||
const [substitutes, updateSubstitutes] = usePartialUpdate<IArgumentsState>({
|
defaultValues: {
|
||||||
definition: '',
|
|
||||||
arguments: []
|
|
||||||
});
|
|
||||||
const [constituenta, updateConstituenta] = usePartialUpdate<ICstCreateDTO>({
|
|
||||||
cst_type: CstType.TERM,
|
cst_type: CstType.TERM,
|
||||||
insert_after: insertAfter ?? null,
|
insert_after: insertAfter ?? null,
|
||||||
alias: generateAlias(CstType.TERM, schema),
|
alias: generateAlias(CstType.TERM, schema),
|
||||||
|
@ -53,81 +49,25 @@ function DlgCstTemplate() {
|
||||||
definition_raw: '',
|
definition_raw: '',
|
||||||
term_raw: '',
|
term_raw: '',
|
||||||
term_forms: []
|
term_forms: []
|
||||||
});
|
|
||||||
|
|
||||||
const [validated, setValidated] = useState(false);
|
|
||||||
|
|
||||||
function handleSubmit() {
|
|
||||||
onCreate(constituenta);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
const alias = useWatch({ control: methods.control, name: 'alias' });
|
||||||
|
const cst_type = useWatch({ control: methods.control, name: 'cst_type' });
|
||||||
|
const isValid = validateNewAlias(alias, cst_type, schema);
|
||||||
|
|
||||||
function handlePrompt(): boolean {
|
const [activeTab, setActiveTab] = useState(TabID.TEMPLATE);
|
||||||
const definedSomeArgs = substitutes.arguments.some(arg => !!arg.value);
|
|
||||||
if (!definedSomeArgs && !window.confirm(promptText.templateUndefined)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
function onSubmit(data: ICstCreateDTO) {
|
||||||
if (!template.prototype) {
|
return cstCreate({ itemID: schema.id, data }).then(onCreate);
|
||||||
updateConstituenta({
|
|
||||||
definition_raw: '',
|
|
||||||
definition_formal: '',
|
|
||||||
term_raw: ''
|
|
||||||
});
|
|
||||||
updateSubstitutes({
|
|
||||||
definition: '',
|
|
||||||
arguments: []
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
updateConstituenta({
|
|
||||||
cst_type: template.prototype.cst_type,
|
|
||||||
alias: generateAlias(template.prototype.cst_type, schema),
|
|
||||||
definition_raw: template.prototype.definition_raw,
|
|
||||||
definition_formal: template.prototype.definition_formal,
|
|
||||||
term_raw: template.prototype.term_raw
|
|
||||||
});
|
|
||||||
updateSubstitutes({
|
|
||||||
definition: template.prototype.definition_formal,
|
|
||||||
arguments: template.prototype.parse.args.map(arg => ({
|
|
||||||
alias: arg.alias,
|
|
||||||
typification: arg.typification,
|
|
||||||
value: ''
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [template.prototype, updateConstituenta, updateSubstitutes, schema]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
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,
|
|
||||||
alias: generateAlias(type, schema),
|
|
||||||
definition_formal: definition
|
|
||||||
});
|
|
||||||
updateSubstitutes({
|
|
||||||
definition: definition
|
|
||||||
});
|
|
||||||
}, [substitutes.arguments, template.prototype, updateConstituenta, updateSubstitutes, schema]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setValidated(!!template.prototype && validateNewAlias(constituenta.alias, constituenta.cst_type, schema));
|
|
||||||
}, [constituenta.alias, constituenta.cst_type, schema, template.prototype]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalForm
|
<ModalForm
|
||||||
header='Создание конституенты из шаблона'
|
header='Создание конституенты из шаблона'
|
||||||
submitText='Создать'
|
submitText='Создать'
|
||||||
className='w-[43rem] h-[35rem] px-6'
|
className='w-[43rem] h-[35rem] px-6'
|
||||||
canSubmit={validated}
|
canSubmit={isValid}
|
||||||
beforeSubmit={handlePrompt}
|
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
|
||||||
onSubmit={handleSubmit}
|
|
||||||
helpTopic={HelpTopic.RSL_TEMPLATES}
|
helpTopic={HelpTopic.RSL_TEMPLATES}
|
||||||
>
|
>
|
||||||
<Tabs
|
<Tabs
|
||||||
|
@ -142,21 +82,25 @@ function DlgCstTemplate() {
|
||||||
<TabLabel label='Конституента' title='Редактирование конституенты' className='w-[8rem]' />
|
<TabLabel label='Конституента' title='Редактирование конституенты' className='w-[8rem]' />
|
||||||
</TabList>
|
</TabList>
|
||||||
|
|
||||||
|
<FormProvider {...methods}>
|
||||||
|
<TemplateState>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Suspense fallback={<Loader />}>
|
<Suspense fallback={<Loader />}>
|
||||||
<TabTemplate state={template} partialUpdate={updateTemplate} templateSchema={templateSchema} />
|
<TabTemplate />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<TabArguments schema={schema} state={substitutes} partialUpdate={updateSubstitutes} />
|
<TabArguments />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<div className='cc-fade-in cc-column'>
|
<div className='cc-fade-in cc-column'>
|
||||||
<FormCreateCst state={constituenta} partialUpdate={updateConstituenta} schema={schema} />
|
<FormCreateCst schema={schema} />
|
||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
</TemplateState>
|
||||||
|
</FormProvider>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useFormContext, useWatch } from 'react-hook-form';
|
||||||
import { createColumnHelper } from '@tanstack/react-table';
|
import { createColumnHelper } from '@tanstack/react-table';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
@ -8,37 +9,32 @@ import { MiniButton } from '@/components/Control';
|
||||||
import DataTable, { IConditionalStyle } from '@/components/DataTable';
|
import DataTable, { IConditionalStyle } from '@/components/DataTable';
|
||||||
import { IconAccept, IconRemove, IconReset } from '@/components/Icons';
|
import { IconAccept, IconRemove, IconReset } from '@/components/Icons';
|
||||||
import { NoData } from '@/components/View';
|
import { NoData } from '@/components/View';
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { APP_COLORS } from '@/styling/colors';
|
import { APP_COLORS } from '@/styling/colors';
|
||||||
|
|
||||||
|
import { ICstCreateDTO } from '../../backend/types';
|
||||||
import { PickConstituenta } from '../../components/PickConstituenta';
|
import { PickConstituenta } from '../../components/PickConstituenta';
|
||||||
import RSInput from '../../components/RSInput';
|
import RSInput from '../../components/RSInput';
|
||||||
import { IConstituenta, IRSForm } from '../../models/rsform';
|
import { IConstituenta } from '../../models/rsform';
|
||||||
import { IArgumentValue } from '../../models/rslang';
|
import { IArgumentValue } from '../../models/rslang';
|
||||||
|
|
||||||
interface TabArgumentsProps {
|
import { DlgCstTemplateProps } from './DlgCstTemplate';
|
||||||
state: IArgumentsState;
|
import { useTemplateContext } from './TemplateContext';
|
||||||
schema: IRSForm;
|
|
||||||
partialUpdate: React.Dispatch<Partial<IArgumentsState>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IArgumentsState {
|
|
||||||
arguments: IArgumentValue[];
|
|
||||||
definition: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const argumentsHelper = createColumnHelper<IArgumentValue>();
|
const argumentsHelper = createColumnHelper<IArgumentValue>();
|
||||||
|
|
||||||
function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
function TabArguments() {
|
||||||
const [selectedCst, setSelectedCst] = useState<IConstituenta | undefined>(undefined);
|
const { schema } = useDialogsStore(state => state.props as DlgCstTemplateProps);
|
||||||
const [selectedArgument, setSelectedArgument] = useState<IArgumentValue | undefined>(undefined);
|
const { control } = useFormContext<ICstCreateDTO>();
|
||||||
const [argumentValue, setArgumentValue] = useState('');
|
const { args, onChangeArguments } = useTemplateContext();
|
||||||
const isModified = selectedArgument && argumentValue !== selectedArgument.value;
|
const definition = useWatch({ control, name: 'definition_formal' });
|
||||||
|
|
||||||
useEffect(() => {
|
const [selectedCst, setSelectedCst] = useState<IConstituenta | undefined>(undefined);
|
||||||
if (!selectedArgument && state.arguments.length > 0) {
|
const [selectedArgument, setSelectedArgument] = useState<IArgumentValue | undefined>(
|
||||||
setSelectedArgument(state.arguments[0]);
|
args.length > 0 ? args[0] : undefined
|
||||||
}
|
);
|
||||||
}, [state.arguments, selectedArgument]);
|
|
||||||
|
const [argumentValue, setArgumentValue] = useState('');
|
||||||
|
|
||||||
function handleSelectArgument(arg: IArgumentValue) {
|
function handleSelectArgument(arg: IArgumentValue) {
|
||||||
setSelectedArgument(arg);
|
setSelectedArgument(arg);
|
||||||
|
@ -54,9 +50,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
|
|
||||||
function handleClearArgument(target: IArgumentValue) {
|
function handleClearArgument(target: IArgumentValue) {
|
||||||
const newArg = { ...target, value: '' };
|
const newArg = { ...target, value: '' };
|
||||||
partialUpdate({
|
onChangeArguments(args.map(arg => (arg.alias !== target.alias ? arg : newArg)));
|
||||||
arguments: state.arguments.map(arg => (arg.alias !== target.alias ? arg : newArg))
|
|
||||||
});
|
|
||||||
setSelectedArgument(newArg);
|
setSelectedArgument(newArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +58,9 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
setArgumentValue(selectedArgument?.value ?? '');
|
setArgumentValue(selectedArgument?.value ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAssignArgument(target: IArgumentValue, value: string) {
|
function handleAssignArgument(target: IArgumentValue, argValue: string) {
|
||||||
const newArg = { ...target, value: value };
|
const newArg = { ...target, value: argValue };
|
||||||
partialUpdate({
|
onChangeArguments(args.map(arg => (arg.alias !== target.alias ? arg : newArg)));
|
||||||
arguments: state.arguments.map(arg => (arg.alias !== target.alias ? arg : newArg))
|
|
||||||
});
|
|
||||||
setSelectedArgument(newArg);
|
setSelectedArgument(newArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +131,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
'border',
|
'border',
|
||||||
'select-none'
|
'select-none'
|
||||||
)}
|
)}
|
||||||
data={state.arguments}
|
data={args}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
conditionalRowStyles={conditionalRowStyles}
|
conditionalRowStyles={conditionalRowStyles}
|
||||||
noDataComponent={<NoData className='min-h-[3.6rem]'>Аргументы отсутствуют</NoData>}
|
noDataComponent={<NoData className='min-h-[3.6rem]'>Аргументы отсутствуют</NoData>}
|
||||||
|
@ -179,7 +171,6 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
title='Очистить поле'
|
title='Очистить поле'
|
||||||
noHover
|
noHover
|
||||||
className='py-0'
|
className='py-0'
|
||||||
disabled={!isModified}
|
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
icon={<IconReset size='1.5rem' className='icon-primary' />}
|
icon={<IconReset size='1.5rem' className='icon-primary' />}
|
||||||
/>
|
/>
|
||||||
|
@ -201,7 +192,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
|
||||||
placeholder='Итоговое определение'
|
placeholder='Итоговое определение'
|
||||||
className='mt-[1.2rem]'
|
className='mt-[1.2rem]'
|
||||||
height='5.1rem'
|
height='5.1rem'
|
||||||
value={state.definition}
|
value={definition}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,36 +1,44 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Dispatch, useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
import { useTemplatesSuspense } from '@/features/library';
|
import { useTemplatesSuspense } from '@/features/library';
|
||||||
|
|
||||||
import { SelectSingle, TextArea } from '@/components/Input';
|
import { SelectSingle, TextArea } from '@/components/Input';
|
||||||
|
|
||||||
|
import { useRSForm } from '../../backend/useRSForm';
|
||||||
import { PickConstituenta } from '../../components/PickConstituenta';
|
import { PickConstituenta } from '../../components/PickConstituenta';
|
||||||
import RSInput from '../../components/RSInput';
|
import RSInput from '../../components/RSInput';
|
||||||
import { CATEGORY_CST_TYPE, IConstituenta, IRSForm } from '../../models/rsform';
|
import { CATEGORY_CST_TYPE } from '../../models/rsform';
|
||||||
import { applyFilterCategory } from '../../models/rsformAPI';
|
import { applyFilterCategory } from '../../models/rsformAPI';
|
||||||
|
|
||||||
export interface ITemplateState {
|
import { useTemplateContext } from './TemplateContext';
|
||||||
templateID?: number;
|
|
||||||
prototype?: IConstituenta;
|
|
||||||
filterCategory?: IConstituenta;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TabTemplateProps {
|
function TabTemplate() {
|
||||||
state: ITemplateState;
|
const {
|
||||||
partialUpdate: Dispatch<Partial<ITemplateState>>;
|
templateID, //
|
||||||
templateSchema?: IRSForm;
|
filterCategory,
|
||||||
}
|
prototype,
|
||||||
|
onChangePrototype,
|
||||||
|
onChangeTemplateID,
|
||||||
|
onChangeFilterCategory
|
||||||
|
} = useTemplateContext();
|
||||||
|
|
||||||
function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps) {
|
|
||||||
const { templates } = useTemplatesSuspense();
|
const { templates } = useTemplatesSuspense();
|
||||||
|
const { schema: templateSchema } = useRSForm({ itemID: templateID });
|
||||||
|
|
||||||
const [filteredData, setFilteredData] = useState<IConstituenta[]>([]);
|
if (!templateID) {
|
||||||
|
onChangeTemplateID(templates[0].id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const prototypeInfo = !state.prototype
|
const filteredData = !templateSchema
|
||||||
|
? []
|
||||||
|
: !filterCategory
|
||||||
|
? templateSchema.items
|
||||||
|
: applyFilterCategory(filterCategory, templateSchema);
|
||||||
|
|
||||||
|
const prototypeInfo = !prototype
|
||||||
? ''
|
? ''
|
||||||
: `${state.prototype?.term_raw}${state.prototype?.definition_raw ? ` — ${state.prototype?.definition_raw}` : ''}`;
|
: `${prototype?.term_raw}${prototype?.definition_raw ? ` — ${prototype?.definition_raw}` : ''}`;
|
||||||
|
|
||||||
const templateSelector = templates.map(template => ({
|
const templateSelector = templates.map(template => ({
|
||||||
value: template.id,
|
value: template.id,
|
||||||
|
@ -46,23 +54,6 @@ function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps)
|
||||||
label: cst.term_raw
|
label: cst.term_raw
|
||||||
}));
|
}));
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (templates.length > 0 && !state.templateID) {
|
|
||||||
partialUpdate({ templateID: templates[0].id });
|
|
||||||
}
|
|
||||||
}, [templates, state.templateID, partialUpdate]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!templateSchema) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data = templateSchema.items;
|
|
||||||
if (state.filterCategory) {
|
|
||||||
data = applyFilterCategory(state.filterCategory, templateSchema);
|
|
||||||
}
|
|
||||||
setFilteredData(data);
|
|
||||||
}, [state.filterCategory, templateSchema]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='cc-fade-in'>
|
<div className='cc-fade-in'>
|
||||||
<div className='flex border-t border-x rounded-t-md clr-input'>
|
<div className='flex border-t border-x rounded-t-md clr-input'>
|
||||||
|
@ -71,12 +62,8 @@ function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps)
|
||||||
placeholder='Источник'
|
placeholder='Источник'
|
||||||
className='w-[12rem]'
|
className='w-[12rem]'
|
||||||
options={templateSelector}
|
options={templateSelector}
|
||||||
value={
|
value={templateID ? { value: templateID, label: templates.find(item => item.id == templateID)!.title } : null}
|
||||||
state.templateID
|
onChange={data => onChangeTemplateID(data ? data.value : undefined)}
|
||||||
? { value: state.templateID, label: templates.find(item => item.id == state.templateID)!.title }
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
onChange={data => partialUpdate({ templateID: data ? data.value : undefined })}
|
|
||||||
/>
|
/>
|
||||||
<SelectSingle
|
<SelectSingle
|
||||||
noBorder
|
noBorder
|
||||||
|
@ -85,24 +72,22 @@ function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps)
|
||||||
className='flex-grow ml-1 border-none'
|
className='flex-grow ml-1 border-none'
|
||||||
options={categorySelector}
|
options={categorySelector}
|
||||||
value={
|
value={
|
||||||
state.filterCategory && templateSchema
|
filterCategory && templateSchema
|
||||||
? {
|
? {
|
||||||
value: state.filterCategory.id,
|
value: filterCategory.id,
|
||||||
label: state.filterCategory.term_raw
|
label: filterCategory.term_raw
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
onChange={data =>
|
onChange={data => onChangeFilterCategory(data ? templateSchema?.cstByID.get(data?.value) : undefined)}
|
||||||
partialUpdate({ filterCategory: data ? templateSchema?.cstByID.get(data?.value) : undefined })
|
|
||||||
}
|
|
||||||
isClearable
|
isClearable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<PickConstituenta
|
<PickConstituenta
|
||||||
id='dlg_template_picker'
|
id='dlg_template_picker'
|
||||||
value={state.prototype}
|
value={prototype}
|
||||||
items={filteredData}
|
items={filteredData}
|
||||||
onChange={cst => partialUpdate({ prototype: cst })}
|
onChange={onChangePrototype}
|
||||||
className='rounded-t-none'
|
className='rounded-t-none'
|
||||||
rows={8}
|
rows={8}
|
||||||
/>
|
/>
|
||||||
|
@ -121,7 +106,7 @@ function TabTemplate({ state, partialUpdate, templateSchema }: TabTemplateProps)
|
||||||
disabled
|
disabled
|
||||||
placeholder='Выберите шаблон из списка'
|
placeholder='Выберите шаблон из списка'
|
||||||
height='5.1rem'
|
height='5.1rem'
|
||||||
value={state.prototype?.definition_formal}
|
value={prototype?.definition_formal}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { createContext, useContext, useState } from 'react';
|
||||||
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
|
||||||
|
import { ICstCreateDTO } from '../../backend/types';
|
||||||
|
import { IConstituenta } from '../../models/rsform';
|
||||||
|
import { generateAlias } from '../../models/rsformAPI';
|
||||||
|
import { IArgumentValue } from '../../models/rslang';
|
||||||
|
import { inferTemplatedType, substituteTemplateArgs } from '../../models/rslangAPI';
|
||||||
|
|
||||||
|
import { DlgCstTemplateProps } from './DlgCstTemplate';
|
||||||
|
|
||||||
|
export interface ITemplateContext {
|
||||||
|
args: IArgumentValue[];
|
||||||
|
prototype?: IConstituenta;
|
||||||
|
templateID?: number;
|
||||||
|
filterCategory?: IConstituenta;
|
||||||
|
|
||||||
|
onChangeArguments: (newArgs: IArgumentValue[]) => void;
|
||||||
|
onChangePrototype: (newPrototype: IConstituenta) => void;
|
||||||
|
onChangeTemplateID: (newTemplateID: number | undefined) => void;
|
||||||
|
onChangeFilterCategory: (newFilterCategory: IConstituenta | undefined) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TemplateContext = createContext<ITemplateContext | null>(null);
|
||||||
|
export const useTemplateContext = () => {
|
||||||
|
const context = useContext(TemplateContext);
|
||||||
|
if (context === null) {
|
||||||
|
throw new Error('useTemplateContext has to be used within <TemplateState>');
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TemplateState = ({ children }: React.PropsWithChildren) => {
|
||||||
|
const { schema } = useDialogsStore(state => state.props as DlgCstTemplateProps);
|
||||||
|
const { setValue } = useFormContext<ICstCreateDTO>();
|
||||||
|
const [templateID, setTemplateID] = useState<number | undefined>(undefined);
|
||||||
|
const [args, setArguments] = useState<IArgumentValue[]>([]);
|
||||||
|
const [prototype, setPrototype] = useState<IConstituenta | undefined>(undefined);
|
||||||
|
const [filterCategory, setFilterCategory] = useState<IConstituenta | undefined>(undefined);
|
||||||
|
|
||||||
|
function onChangeArguments(newArgs: IArgumentValue[]) {
|
||||||
|
setArguments(newArgs);
|
||||||
|
if (newArgs.length === 0 || !prototype) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newType = inferTemplatedType(prototype.cst_type, newArgs);
|
||||||
|
setValue('definition_formal', substituteTemplateArgs(prototype.definition_formal, newArgs));
|
||||||
|
setValue('cst_type', newType);
|
||||||
|
setValue('alias', generateAlias(newType, schema));
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangePrototype(newPrototype: IConstituenta) {
|
||||||
|
setPrototype(newPrototype);
|
||||||
|
setArguments(
|
||||||
|
newPrototype.parse.args.map(arg => ({
|
||||||
|
alias: arg.alias,
|
||||||
|
typification: arg.typification,
|
||||||
|
value: ''
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
setValue('cst_type', newPrototype.cst_type);
|
||||||
|
setValue('alias', generateAlias(newPrototype.cst_type, schema));
|
||||||
|
setValue('definition_formal', newPrototype.definition_formal);
|
||||||
|
setValue('term_raw', newPrototype.term_raw);
|
||||||
|
setValue('definition_raw', newPrototype.definition_raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeTemplateID(newTemplateID: number | undefined) {
|
||||||
|
setTemplateID(newTemplateID);
|
||||||
|
setPrototype(undefined);
|
||||||
|
setArguments([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TemplateContext
|
||||||
|
value={{
|
||||||
|
templateID,
|
||||||
|
prototype,
|
||||||
|
filterCategory,
|
||||||
|
args,
|
||||||
|
onChangeArguments,
|
||||||
|
onChangePrototype,
|
||||||
|
onChangeFilterCategory: setFilterCategory,
|
||||||
|
onChangeTemplateID
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</TemplateContext>
|
||||||
|
);
|
||||||
|
};
|
|
@ -18,7 +18,7 @@ import { ICstCreateDTO } from '../../backend/types';
|
||||||
import { useCstCreate } from '../../backend/useCstCreate';
|
import { useCstCreate } from '../../backend/useCstCreate';
|
||||||
import { useCstMove } from '../../backend/useCstMove';
|
import { useCstMove } from '../../backend/useCstMove';
|
||||||
import { useRSFormSuspense } from '../../backend/useRSForm';
|
import { useRSFormSuspense } from '../../backend/useRSForm';
|
||||||
import { CstType, IConstituenta, IRSForm } from '../../models/rsform';
|
import { CstType, IConstituenta, IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||||
import { generateAlias } from '../../models/rsformAPI';
|
import { generateAlias } from '../../models/rsformAPI';
|
||||||
|
|
||||||
export enum RSTabID {
|
export enum RSTabID {
|
||||||
|
@ -177,9 +177,7 @@ export const RSEditState = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCreateCst(data: ICstCreateDTO) {
|
function onCreateCst(newCst: IConstituentaMeta) {
|
||||||
data.alias = data.alias || generateAlias(data.cst_type, schema);
|
|
||||||
void cstCreate({ itemID: itemID, data }).then(newCst => {
|
|
||||||
setSelected([newCst.id]);
|
setSelected([newCst.id]);
|
||||||
navigateRSForm({ tab: activeTab, activeID: newCst.id });
|
navigateRSForm({ tab: activeTab, activeID: newCst.id });
|
||||||
if (activeTab === RSTabID.CST_LIST) {
|
if (activeTab === RSTabID.CST_LIST) {
|
||||||
|
@ -194,7 +192,6 @@ export const RSEditState = ({
|
||||||
}
|
}
|
||||||
}, PARAMETER.refreshTimeout);
|
}, PARAMETER.refreshTimeout);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveUp() {
|
function moveUp() {
|
||||||
|
@ -258,9 +255,9 @@ export const RSEditState = ({
|
||||||
term_forms: []
|
term_forms: []
|
||||||
};
|
};
|
||||||
if (skipDialog) {
|
if (skipDialog) {
|
||||||
handleCreateCst(data);
|
void cstCreate({ itemID: schema.id, data }).then(onCreateCst);
|
||||||
} else {
|
} else {
|
||||||
showCreateCst({ schema: schema, onCreate: handleCreateCst, initial: data });
|
showCreateCst({ schema: schema, onCreate: onCreateCst, initial: data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +265,9 @@ export const RSEditState = ({
|
||||||
if (!activeCst) {
|
if (!activeCst) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ICstCreateDTO = {
|
void cstCreate({
|
||||||
|
itemID: schema.id,
|
||||||
|
data: {
|
||||||
insert_after: activeCst.id,
|
insert_after: activeCst.id,
|
||||||
cst_type: activeCst.cst_type,
|
cst_type: activeCst.cst_type,
|
||||||
alias: generateAlias(activeCst.cst_type, schema),
|
alias: generateAlias(activeCst.cst_type, schema),
|
||||||
|
@ -277,8 +276,8 @@ export const RSEditState = ({
|
||||||
definition_raw: activeCst.definition_raw,
|
definition_raw: activeCst.definition_raw,
|
||||||
convention: activeCst.convention,
|
convention: activeCst.convention,
|
||||||
term_forms: activeCst.term_forms
|
term_forms: activeCst.term_forms
|
||||||
};
|
}
|
||||||
handleCreateCst(data);
|
}).then(onCreateCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
function promptDeleteCst() {
|
function promptDeleteCst() {
|
||||||
|
@ -299,11 +298,12 @@ export const RSEditState = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function promptTemplate() {
|
function promptTemplate() {
|
||||||
if (isModified && !promptUnsaved()) {
|
if (isModified && !promptUnsaved()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showCstTemplate({ schema: schema, onCreate: handleCreateCst, insertAfter: activeCst?.id });
|
showCstTemplate({ schema: schema, onCreate: onCreateCst, insertAfter: activeCst?.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -140,7 +140,8 @@ export const errorMsg = {
|
||||||
loginFormat: 'Имя пользователя должно содержать только буквы и цифры',
|
loginFormat: 'Имя пользователя должно содержать только буквы и цифры',
|
||||||
invalidLocation: 'Некорректный формат пути',
|
invalidLocation: 'Некорректный формат пути',
|
||||||
versionTaken: 'Версия с таким шифром уже существует',
|
versionTaken: 'Версия с таким шифром уже существует',
|
||||||
emptySubstitutions: 'Выберите хотя бы одно отождествление'
|
emptySubstitutions: 'Выберите хотя бы одно отождествление',
|
||||||
|
aliasInvalid: 'Введите незанятое имя, соответствующее типу'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,7 +163,6 @@ export const promptText = {
|
||||||
'Внимание!!\nУдаление операционной схемы приведет к удалению всех операций и собственных концептуальных схем.\nДанное действие нельзя отменить.\nВы уверены, что хотите удалить данную ОСС?',
|
'Внимание!!\nУдаление операционной схемы приведет к удалению всех операций и собственных концептуальных схем.\nДанное действие нельзя отменить.\nВы уверены, что хотите удалить данную ОСС?',
|
||||||
generateWordforms: 'Данное действие приведет к перезаписи словоформ при совпадении граммем. Продолжить?',
|
generateWordforms: 'Данное действие приведет к перезаписи словоформ при совпадении граммем. Продолжить?',
|
||||||
restoreArchive: 'При восстановлении архивной версии актуальная схему будет заменена. Продолжить?',
|
restoreArchive: 'При восстановлении архивной версии актуальная схему будет заменена. Продолжить?',
|
||||||
templateUndefined: 'Вы уверены, что хотите создать шаблонную конституенту не фиксируя аргументы?',
|
|
||||||
ownerChange:
|
ownerChange:
|
||||||
'Вы уверены, что хотите изменить владельца? Вы потеряете право управления данной схемой. Данное действие отменить нельзя'
|
'Вы уверены, что хотите изменить владельца? Вы потеряете право управления данной схемой. Данное действие отменить нельзя'
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user