R: Upgrade SubstituteCst dialog
This commit is contained in:
parent
8346850cf6
commit
acf0f4e9f6
|
@ -4,14 +4,8 @@ import { z } from 'zod';
|
|||
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
|
||||
import { DELAYS } from '@/backend/configuration';
|
||||
import { ILibraryItem, ILibraryItemData, LibraryItemID } from '@/features/library/models/library';
|
||||
import {
|
||||
IArgument,
|
||||
ICstSubstituteEx,
|
||||
IOperation,
|
||||
OperationID,
|
||||
OperationType,
|
||||
schemaCstSubstitute
|
||||
} from '@/features/oss/models/oss';
|
||||
import { IArgument, ICstSubstituteEx, IOperation, OperationID, OperationType } from '@/features/oss/models/oss';
|
||||
import { schemaCstSubstitute } from '@/features/rsform/backend/api';
|
||||
import { IConstituentaReference, ITargetCst } from '@/features/rsform/models/rsform';
|
||||
import { infoMsg } from '@/utils/labels';
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
/**
|
||||
* Module: Schema of Synthesis Operations.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ILibraryItem, ILibraryItemData, LibraryItemID } from '@/features/library/models/library';
|
||||
import { ICstSubstitute } from '@/features/rsform/backend/api';
|
||||
import { IConstituenta } from '@/features/rsform/models/rsform';
|
||||
|
||||
import { Graph } from '../../../models/Graph';
|
||||
|
@ -53,26 +51,6 @@ export interface IArgument {
|
|||
argument: OperationID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data, used in merging single {@link IConstituenta}.
|
||||
*/
|
||||
export const schemaCstSubstitute = z.object({
|
||||
original: z.number(),
|
||||
substitution: z.number()
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in merging single {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstSubstitute = z.infer<typeof schemaCstSubstitute>;
|
||||
|
||||
/**
|
||||
* Represents data, used in merging multiple {@link IConstituenta}.
|
||||
*/
|
||||
export interface ICstSubstitutions {
|
||||
substitutions: ICstSubstitute[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents substitution for multi synthesis table.
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
import { ILibraryItem, LibraryItemID } from '@/features/library/models/library';
|
||||
import { ICstSubstitute } from '@/features/rsform/backend/api';
|
||||
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from '@/features/rsform/models/rsform';
|
||||
import { AliasMapping, ParsingStatus } from '@/features/rsform/models/rslang';
|
||||
import {
|
||||
|
@ -18,7 +19,7 @@ import { TextMatcher } from '@/utils/utils';
|
|||
import { Graph } from '../../../models/Graph';
|
||||
import { IOperationPosition } from '../backend/api';
|
||||
import { describeSubstitutionError } from '../labels';
|
||||
import { ICstSubstitute, IOperation, IOperationSchema, OperationID, OperationType, SubstitutionErrorType } from './oss';
|
||||
import { IOperation, IOperationSchema, OperationID, OperationType, SubstitutionErrorType } from './oss';
|
||||
import { Position2D } from './ossLayout';
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,8 +9,7 @@ import {
|
|||
LibraryItemID,
|
||||
VersionID
|
||||
} from '@/features/library/models/library';
|
||||
import { ICstSubstitute, ICstSubstitutions } from '@/features/oss/models/oss';
|
||||
import { infoMsg } from '@/utils/labels';
|
||||
import { errorMsg, infoMsg } from '@/utils/labels';
|
||||
|
||||
import {
|
||||
ConstituentaID,
|
||||
|
@ -127,6 +126,19 @@ export interface IProduceStructureResponse {
|
|||
schema: IRSFormDTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data, used in merging single {@link IConstituenta}.
|
||||
*/
|
||||
export const schemaCstSubstitute = z.object({
|
||||
original: z.number(),
|
||||
substitution: z.number()
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in merging single {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstSubstitute = z.infer<typeof schemaCstSubstitute>;
|
||||
|
||||
/**
|
||||
* Represents input data for inline synthesis.
|
||||
*/
|
||||
|
@ -146,6 +158,18 @@ export interface ICheckConstituentaDTO {
|
|||
definition_formal: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data, used in renaming {@link IConstituenta}.
|
||||
*/
|
||||
export const schemaCstSubstitutions = z.object({
|
||||
substitutions: z.array(schemaCstSubstitute).min(1, { message: errorMsg.emptySubstitutions })
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in merging multiple {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstSubstitutionsDTO = z.infer<typeof schemaCstSubstitutions>;
|
||||
|
||||
export const rsformsApi = {
|
||||
baseKey: 'rsform',
|
||||
|
||||
|
@ -214,8 +238,8 @@ export const rsformsApi = {
|
|||
successMessage: infoMsg.changesSaved
|
||||
}
|
||||
}),
|
||||
cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutions }) =>
|
||||
axiosPatch<ICstSubstitutions, IRSFormDTO>({
|
||||
cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutionsDTO }) =>
|
||||
axiosPatch<ICstSubstitutionsDTO, IRSFormDTO>({
|
||||
endpoint: `/api/rsforms/${itemID}/substitute`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -229,7 +253,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
|
||||
produceStructure: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetCst }) =>
|
||||
axiosPost<ITargetCst, IProduceStructureResponse>({
|
||||
axiosPatch<ITargetCst, IProduceStructureResponse>({
|
||||
endpoint: `/api/rsforms/${itemID}/produce-structure`,
|
||||
request: {
|
||||
data: data,
|
||||
|
|
|
@ -3,9 +3,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|||
import { useUpdateTimestamp } from '@/features/library/backend/useUpdateTimestamp';
|
||||
import { LibraryItemID } from '@/features/library/models/library';
|
||||
import { ossApi } from '@/features/oss/backend/api';
|
||||
import { ICstSubstitutions } from '@/features/oss/models/oss';
|
||||
|
||||
import { rsformsApi } from './api';
|
||||
import { ICstSubstitutionsDTO, rsformsApi } from './api';
|
||||
|
||||
export const useCstSubstitute = () => {
|
||||
const client = useQueryClient();
|
||||
|
@ -27,6 +26,6 @@ export const useCstSubstitute = () => {
|
|||
}
|
||||
});
|
||||
return {
|
||||
cstSubstitute: (data: { itemID: LibraryItemID; data: ICstSubstitutions }) => mutation.mutateAsync(data)
|
||||
cstSubstitute: (data: { itemID: LibraryItemID; data: ICstSubstitutionsDTO }) => mutation.mutateAsync(data)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,10 +11,11 @@ import { CProps } from '@/components/props';
|
|||
import { NoData } from '@/components/View';
|
||||
import SelectLibraryItem from '@/features/library/components/SelectLibraryItem';
|
||||
import { ILibraryItem } from '@/features/library/models/library';
|
||||
import { ICstSubstitute, IMultiSubstitution } from '@/features/oss/models/oss';
|
||||
import { IMultiSubstitution } from '@/features/oss/models/oss';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
|
||||
import { ICstSubstitute } from '../backend/api';
|
||||
import { ConstituentaID, IConstituenta, IRSForm } from '../models/rsform';
|
||||
import BadgeConstituenta from './BadgeConstituenta';
|
||||
import SelectConstituenta from './SelectConstituenta';
|
||||
|
|
|
@ -7,11 +7,10 @@ import { Loader } from '@/components/Loader';
|
|||
import { ModalForm } from '@/components/Modal';
|
||||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
||||
import { LibraryItemID } from '@/features/library/models/library';
|
||||
import { ICstSubstitute } from '@/features/oss/models/oss';
|
||||
import { useRSForm } from '@/features/rsform/backend/useRSForm';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { IInlineSynthesisDTO } from '../../backend/api';
|
||||
import { ICstSubstitute, IInlineSynthesisDTO } from '../../backend/api';
|
||||
import { ConstituentaID, IRSForm } from '../../models/rsform';
|
||||
import TabConstituents from './TabConstituents';
|
||||
import TabSource from './TabSource';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'use client';
|
||||
|
||||
import { LibraryItemID } from '@/features/library/models/library';
|
||||
import { ICstSubstitute } from '@/features/oss/models/oss';
|
||||
|
||||
import { ICstSubstitute } from '../../backend/api';
|
||||
import { useRSFormSuspense } from '../../backend/useRSForm';
|
||||
import PickSubstitutions from '../../components/PickSubstitutions';
|
||||
import { ConstituentaID, IRSForm } from '../../models/rsform';
|
||||
|
|
|
@ -1,29 +1,42 @@
|
|||
'use client';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import clsx from 'clsx';
|
||||
import { useState } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
|
||||
import { ErrorField } from '@/components/Input';
|
||||
import { ModalForm } from '@/components/Modal';
|
||||
import { HelpTopic } from '@/features/help/models/helpTopic';
|
||||
import { ICstSubstitute, ICstSubstitutions } from '@/features/oss/models/oss';
|
||||
import PickSubstitutions from '@/features/rsform/components/PickSubstitutions';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { ICstSubstitutionsDTO, schemaCstSubstitutions } from '../backend/api';
|
||||
import { useCstSubstitute } from '../backend/useCstSubstitute';
|
||||
import PickSubstitutions from '../components/PickSubstitutions';
|
||||
import { IRSForm } from '../models/rsform';
|
||||
|
||||
export interface DlgSubstituteCstProps {
|
||||
schema: IRSForm;
|
||||
onSubstitute: (data: ICstSubstitutions) => void;
|
||||
onSubstitute: (data: ICstSubstitutionsDTO) => void;
|
||||
}
|
||||
|
||||
function DlgSubstituteCst() {
|
||||
const { onSubstitute, schema } = useDialogsStore(state => state.props as DlgSubstituteCstProps);
|
||||
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>([]);
|
||||
const canSubmit = substitutions.length > 0;
|
||||
const { cstSubstitute } = useCstSubstitute();
|
||||
|
||||
function handleSubmit() {
|
||||
onSubstitute({ substitutions: substitutions });
|
||||
return true;
|
||||
const {
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors, isValid }
|
||||
} = useForm<ICstSubstitutionsDTO>({
|
||||
resolver: zodResolver(schemaCstSubstitutions),
|
||||
defaultValues: {
|
||||
substitutions: []
|
||||
},
|
||||
mode: 'onChange'
|
||||
});
|
||||
|
||||
function onSubmit(data: ICstSubstitutionsDTO) {
|
||||
return cstSubstitute({ itemID: schema.id, data: data }).then(() => onSubstitute(data));
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -31,18 +44,25 @@ function DlgSubstituteCst() {
|
|||
header='Отождествление'
|
||||
submitText='Отождествить'
|
||||
submitInvalidTooltip='Выберите две различные конституенты'
|
||||
canSubmit={canSubmit}
|
||||
onSubmit={handleSubmit}
|
||||
canSubmit={isValid}
|
||||
onSubmit={event => void handleSubmit(onSubmit)(event)}
|
||||
className={clsx('w-[40rem]', 'px-6 pb-3')}
|
||||
helpTopic={HelpTopic.UI_SUBSTITUTIONS}
|
||||
>
|
||||
<Controller
|
||||
control={control}
|
||||
name='substitutions'
|
||||
render={({ field }) => (
|
||||
<PickSubstitutions
|
||||
allowSelfSubstitution
|
||||
value={substitutions}
|
||||
onChange={setSubstitutions}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
rows={6}
|
||||
schemas={[schema]}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<ErrorField className='mt-2' error={errors.substitutions} />
|
||||
</ModalForm>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
|||
import { describeAccessMode, labelAccessMode, tooltipText } from '@/utils/labels';
|
||||
import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils';
|
||||
|
||||
import { useCstSubstitute } from '../../backend/useCstSubstitute';
|
||||
import { useDownloadRSForm } from '../../backend/useDownloadRSForm';
|
||||
import { useInlineSynthesis } from '../../backend/useInlineSynthesis';
|
||||
import { useMutatingRSForm } from '../../backend/useMutatingRSForm';
|
||||
|
@ -66,7 +65,6 @@ function MenuRSTabs() {
|
|||
const { restoreOrder } = useRestoreOrder();
|
||||
const { produceStructure } = useProduceStructure();
|
||||
const { inlineSynthesis } = useInlineSynthesis();
|
||||
const { cstSubstitute } = useCstSubstitute();
|
||||
const { download } = useDownloadRSForm();
|
||||
|
||||
const showInlineSynthesis = useDialogsStore(state => state.showInlineSynthesis);
|
||||
|
@ -167,9 +165,7 @@ function MenuRSTabs() {
|
|||
showSubstituteCst({
|
||||
schema: controller.schema,
|
||||
onSubstitute: data =>
|
||||
void cstSubstitute({ itemID: controller.schema.id, data }).then(() =>
|
||||
controller.setSelected(prev => prev.filter(id => !data.substitutions.find(sub => sub.original === id)))
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,8 @@ export const errorMsg = {
|
|||
privacyNotAccepted: 'Примите политику обработки персональных данных',
|
||||
loginFormat: 'Имя пользователя должно содержать только буквы и цифры',
|
||||
invalidLocation: 'Некорректный формат пути',
|
||||
versionTaken: 'Версия с таким шифром уже существует'
|
||||
versionTaken: 'Версия с таким шифром уже существует',
|
||||
emptySubstitutions: 'Выберите хотя бы одно отождествление'
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user