F: Add zod validation for backend responses for rsforms
This commit is contained in:
parent
483fc93b58
commit
75c0a6f848
|
@ -3,8 +3,10 @@
|
|||
*/
|
||||
import { toast } from 'react-toastify';
|
||||
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
|
||||
import { z, ZodError } from 'zod';
|
||||
|
||||
import { buildConstants } from '@/utils/buildConstants';
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
import { extractErrorMessage } from '@/utils/utils';
|
||||
|
||||
export { AxiosError } from 'axios';
|
||||
|
@ -41,23 +43,32 @@ export interface IAxiosRequest<RequestData, ResponseData> {
|
|||
endpoint: string;
|
||||
request?: IFrontRequest<RequestData, ResponseData>;
|
||||
options?: AxiosRequestConfig;
|
||||
schema?: z.ZodType;
|
||||
}
|
||||
|
||||
export interface IAxiosGetRequest {
|
||||
endpoint: string;
|
||||
options?: AxiosRequestConfig;
|
||||
signal?: AbortSignal;
|
||||
schema?: z.ZodType;
|
||||
}
|
||||
|
||||
// ================ Transport API calls ================
|
||||
export function axiosGet<ResponseData>({ endpoint, options }: IAxiosGetRequest) {
|
||||
export function axiosGet<ResponseData>({ endpoint, options, schema }: IAxiosGetRequest) {
|
||||
return axiosInstance
|
||||
.get<ResponseData>(endpoint, options)
|
||||
.then(response => response.data)
|
||||
.then(response => {
|
||||
schema?.parse(response.data);
|
||||
return response.data;
|
||||
})
|
||||
.catch((error: Error | AxiosError) => {
|
||||
// Note: Ignore cancellation errors
|
||||
if (error.name !== 'CanceledError') {
|
||||
// Note: Ignore cancellation errors
|
||||
toast.error(extractErrorMessage(error));
|
||||
if (error instanceof ZodError) {
|
||||
toast.error(errorMsg.invalidResponse);
|
||||
} else {
|
||||
toast.error(extractErrorMessage(error));
|
||||
}
|
||||
console.error(error);
|
||||
}
|
||||
throw error;
|
||||
|
@ -67,11 +78,13 @@ export function axiosGet<ResponseData>({ endpoint, options }: IAxiosGetRequest)
|
|||
export function axiosPost<RequestData, ResponseData = void>({
|
||||
endpoint,
|
||||
request,
|
||||
options
|
||||
options,
|
||||
schema
|
||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||
return axiosInstance
|
||||
.post<ResponseData>(endpoint, request?.data, options)
|
||||
.then(response => {
|
||||
schema?.parse(response.data);
|
||||
if (request?.successMessage) {
|
||||
if (typeof request.successMessage === 'string') {
|
||||
toast.success(request.successMessage);
|
||||
|
@ -81,8 +94,12 @@ export function axiosPost<RequestData, ResponseData = void>({
|
|||
}
|
||||
return response.data;
|
||||
})
|
||||
.catch((error: Error | AxiosError) => {
|
||||
toast.error(extractErrorMessage(error));
|
||||
.catch((error: Error | AxiosError | ZodError) => {
|
||||
if (error instanceof ZodError) {
|
||||
toast.error(errorMsg.invalidResponse);
|
||||
} else {
|
||||
toast.error(extractErrorMessage(error));
|
||||
}
|
||||
console.error(error);
|
||||
throw error;
|
||||
});
|
||||
|
@ -91,11 +108,13 @@ export function axiosPost<RequestData, ResponseData = void>({
|
|||
export function axiosDelete<RequestData, ResponseData = void>({
|
||||
endpoint,
|
||||
request,
|
||||
options
|
||||
options,
|
||||
schema
|
||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||
return axiosInstance
|
||||
.delete<ResponseData>(endpoint, options)
|
||||
.then(response => {
|
||||
schema?.parse(response.data);
|
||||
if (request?.successMessage) {
|
||||
if (typeof request.successMessage === 'string') {
|
||||
toast.success(request.successMessage);
|
||||
|
@ -105,8 +124,12 @@ export function axiosDelete<RequestData, ResponseData = void>({
|
|||
}
|
||||
return response.data;
|
||||
})
|
||||
.catch((error: Error | AxiosError) => {
|
||||
toast.error(extractErrorMessage(error));
|
||||
.catch((error: Error | AxiosError | ZodError) => {
|
||||
if (error instanceof ZodError) {
|
||||
toast.error(errorMsg.invalidResponse);
|
||||
} else {
|
||||
toast.error(extractErrorMessage(error));
|
||||
}
|
||||
console.error(error);
|
||||
throw error;
|
||||
});
|
||||
|
@ -115,11 +138,13 @@ export function axiosDelete<RequestData, ResponseData = void>({
|
|||
export function axiosPatch<RequestData, ResponseData = void>({
|
||||
endpoint,
|
||||
request,
|
||||
options
|
||||
options,
|
||||
schema
|
||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||
return axiosInstance
|
||||
.patch<ResponseData>(endpoint, request?.data, options)
|
||||
.then(response => {
|
||||
schema?.parse(response.data);
|
||||
if (request?.successMessage) {
|
||||
if (typeof request.successMessage === 'string') {
|
||||
toast.success(request.successMessage);
|
||||
|
@ -129,8 +154,12 @@ export function axiosPatch<RequestData, ResponseData = void>({
|
|||
}
|
||||
return response.data;
|
||||
})
|
||||
.catch((error: Error | AxiosError) => {
|
||||
toast.error(extractErrorMessage(error));
|
||||
.catch((error: Error | AxiosError | ZodError) => {
|
||||
if (error instanceof ZodError) {
|
||||
toast.error(errorMsg.invalidResponse);
|
||||
} else {
|
||||
toast.error(extractErrorMessage(error));
|
||||
}
|
||||
console.error(error);
|
||||
throw error;
|
||||
});
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import clsx from 'clsx';
|
||||
import { ZodError } from 'zod';
|
||||
|
||||
import { AxiosError, isAxiosError } from '@/backend/apiTransport';
|
||||
import { isResponseHtml } from '@/utils/utils';
|
||||
|
||||
import { PrettyJson } from './View';
|
||||
|
||||
export type ErrorData = string | Error | AxiosError | undefined | null;
|
||||
export type ErrorData = string | Error | AxiosError | ZodError | undefined | null;
|
||||
|
||||
interface InfoErrorProps {
|
||||
error: ErrorData;
|
||||
|
@ -16,6 +17,13 @@ function DescribeError({ error }: { error: ErrorData }) {
|
|||
return <p>Ошибки отсутствуют</p>;
|
||||
} else if (typeof error === 'string') {
|
||||
return <p>{error}</p>;
|
||||
} else if (error instanceof ZodError) {
|
||||
return (
|
||||
<div className='mt-6'>
|
||||
<p>Ошибка валидации данных</p>
|
||||
<PrettyJson data={JSON.parse(error.toString()) as unknown} />;
|
||||
</div>
|
||||
);
|
||||
} else if (!isAxiosError(error)) {
|
||||
return (
|
||||
<div className='mt-6'>
|
||||
|
|
|
@ -138,11 +138,11 @@ export const libraryApi = {
|
|||
successMessage: infoMsg.versionRestored
|
||||
}
|
||||
}),
|
||||
versionUpdate: (data: IVersionUpdateDTO) =>
|
||||
versionUpdate: (data: { itemID: number; version: IVersionUpdateDTO }) =>
|
||||
axiosPatch<IVersionUpdateDTO, IVersionInfo>({
|
||||
endpoint: `/api/versions/${data.id}`,
|
||||
endpoint: `/api/versions/${data.version.id}`,
|
||||
request: {
|
||||
data: data,
|
||||
data: data.version,
|
||||
successMessage: infoMsg.changesSaved
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -12,8 +12,8 @@ export const useVersionUpdate = () => {
|
|||
const mutation = useMutation({
|
||||
mutationKey: [libraryApi.baseKey, 'update-version'],
|
||||
mutationFn: libraryApi.versionUpdate,
|
||||
onSuccess: data => {
|
||||
client.setQueryData(KEYS.composite.rsItem({ itemID: data.item }), (prev: IRSFormDTO | undefined) =>
|
||||
onSuccess: (data, variables) => {
|
||||
client.setQueryData(KEYS.composite.rsItem({ itemID: variables.itemID }), (prev: IRSFormDTO | undefined) =>
|
||||
!prev
|
||||
? undefined
|
||||
: {
|
||||
|
@ -26,6 +26,6 @@ export const useVersionUpdate = () => {
|
|||
}
|
||||
});
|
||||
return {
|
||||
versionUpdate: (data: IVersionUpdateDTO) => mutation.mutateAsync(data)
|
||||
versionUpdate: (data: { itemID: number; version: IVersionUpdateDTO }) => mutation.mutateAsync(data)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ function DlgEditVersions() {
|
|||
if (!isDirty || isProcessing || !isValid) {
|
||||
return;
|
||||
}
|
||||
void versionUpdate(data).then(() => reset({ ...data }));
|
||||
void versionUpdate({ itemID: itemID, version: data }).then(() => reset({ ...data }));
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* Module: Models for LibraryItem.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Represents type of library items.
|
||||
*/
|
||||
|
@ -31,16 +33,17 @@ export enum LocationHead {
|
|||
|
||||
export const BASIC_SCHEMAS = '/L/Базовые';
|
||||
|
||||
export const schemaVersionInfo = z.object({
|
||||
id: z.coerce.number(),
|
||||
version: z.string(),
|
||||
description: z.string(),
|
||||
time_create: z.string()
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents library item version information.
|
||||
*/
|
||||
export interface IVersionInfo {
|
||||
id: number;
|
||||
item: number;
|
||||
version: string;
|
||||
description: string;
|
||||
time_create: string;
|
||||
}
|
||||
export type IVersionInfo = z.infer<typeof schemaVersionInfo>;
|
||||
|
||||
/**
|
||||
* Represents library item common data typical for all item types.
|
||||
|
@ -70,7 +73,10 @@ export interface ILibraryItemData extends ILibraryItem {
|
|||
/**
|
||||
* Represents {@link ILibraryItem} minimal reference data.
|
||||
*/
|
||||
export interface ILibraryItemReference extends Pick<ILibraryItem, 'id' | 'alias'> {}
|
||||
export interface ILibraryItemReference {
|
||||
id: number;
|
||||
alias: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents {@link ILibraryItem} extended data with versions.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { queryOptions } from '@tanstack/react-query';
|
||||
|
||||
import { IConstituentaReference, ITargetCst } from '@/features/rsform/models/rsform';
|
||||
import { ITargetCst } from '@/features/rsform/backend/types';
|
||||
import { IConstituentaReference } from '@/features/rsform/models/rsform';
|
||||
|
||||
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
|
||||
import { DELAYS, KEYS } from '@/backend/configuration';
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { useMutation } from '@tanstack/react-query';
|
||||
|
||||
import { ITargetCst } from '@/features/rsform/models/rsform';
|
||||
|
||||
import { ossApi } from './api';
|
||||
|
||||
export const useFindPredecessor = () => {
|
||||
|
@ -10,6 +8,6 @@ export const useFindPredecessor = () => {
|
|||
mutationFn: ossApi.getPredecessor
|
||||
});
|
||||
return {
|
||||
findPredecessor: (data: ITargetCst) => mutation.mutateAsync(data)
|
||||
findPredecessor: (target: number) => mutation.mutateAsync({ target: target })
|
||||
};
|
||||
};
|
||||
|
|
|
@ -19,13 +19,13 @@ import { IRSFormDTO } from './types';
|
|||
* based on the loaded data. It also establishes dependencies between concepts in the graph.
|
||||
*/
|
||||
export class RSFormLoader {
|
||||
private schema: IRSFormDTO;
|
||||
private schema: IRSForm;
|
||||
private graph: Graph = new Graph();
|
||||
private cstByAlias = new Map<string, IConstituenta>();
|
||||
private cstByID = new Map<number, IConstituenta>();
|
||||
|
||||
constructor(input: IRSFormDTO) {
|
||||
this.schema = input;
|
||||
this.schema = input as unknown as IRSForm;
|
||||
}
|
||||
|
||||
produceRSForm(): IRSForm {
|
||||
|
@ -33,7 +33,7 @@ export class RSFormLoader {
|
|||
this.createGraph();
|
||||
this.inferCstAttributes();
|
||||
|
||||
const result = this.schema as IRSForm;
|
||||
const result = this.schema;
|
||||
result.stats = this.calculateStats();
|
||||
result.graph = this.graph;
|
||||
result.cstByAlias = this.cstByAlias;
|
||||
|
@ -43,8 +43,8 @@ export class RSFormLoader {
|
|||
|
||||
private prepareLookups() {
|
||||
this.schema.items.forEach(cst => {
|
||||
this.cstByAlias.set(cst.alias, cst as IConstituenta);
|
||||
this.cstByID.set(cst.id, cst as IConstituenta);
|
||||
this.cstByAlias.set(cst.alias, cst);
|
||||
this.cstByID.set(cst.id, cst);
|
||||
this.graph.addNode(cst.id);
|
||||
});
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ export class RSFormLoader {
|
|||
sum + (cst.parse.status === ParsingStatus.VERIFIED && cst.parse.valueClass === ValueClass.INVALID ? 1 : 0),
|
||||
0
|
||||
),
|
||||
count_inherited: items.reduce((sum, cst) => sum + ((cst as IConstituenta).is_inherited ? 1 : 0), 0),
|
||||
count_inherited: items.reduce((sum, cst) => sum + (cst.is_inherited ? 1 : 0), 0),
|
||||
|
||||
count_text_term: items.reduce((sum, cst) => sum + (cst.term_raw ? 1 : 0), 0),
|
||||
count_definition: items.reduce((sum, cst) => sum + (cst.definition_raw ? 1 : 0), 0),
|
||||
|
|
|
@ -4,21 +4,28 @@ import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
|
|||
import { DELAYS, KEYS } from '@/backend/configuration';
|
||||
import { infoMsg } from '@/utils/labels';
|
||||
|
||||
import { IConstituentaList, IConstituentaMeta, ITargetCst } from '../models/rsform';
|
||||
import { IExpressionParse } from '../models/rslang';
|
||||
import { IConstituentaList } from '../models/rsform';
|
||||
|
||||
import {
|
||||
ICheckConstituentaDTO,
|
||||
IConstituentaBasicsDTO,
|
||||
ICstCreatedResponse,
|
||||
ICstCreateDTO,
|
||||
ICstMoveDTO,
|
||||
ICstRenameDTO,
|
||||
ICstSubstitutionsDTO,
|
||||
ICstUpdateDTO,
|
||||
IExpressionParseDTO,
|
||||
IInlineSynthesisDTO,
|
||||
IProduceStructureResponse,
|
||||
IRSFormDTO,
|
||||
IRSFormUploadDTO
|
||||
IRSFormUploadDTO,
|
||||
ITargetCst,
|
||||
schemaConstituentaBasics,
|
||||
schemaCstCreatedResponse,
|
||||
schemaExpressionParse,
|
||||
schemaProduceStructureResponse,
|
||||
schemaRSForm
|
||||
} from './types';
|
||||
|
||||
export const rsformsApi = {
|
||||
|
@ -32,6 +39,7 @@ export const rsformsApi = {
|
|||
!itemID
|
||||
? undefined
|
||||
: axiosGet<IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: version ? `/api/library/${itemID}/versions/${version}` : `/api/rsforms/${itemID}/details`,
|
||||
options: { signal: meta.signal }
|
||||
})
|
||||
|
@ -45,6 +53,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
upload: (data: IRSFormUploadDTO) =>
|
||||
axiosPatch<IRSFormUploadDTO, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${data.itemID}/load-trs`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -59,6 +68,7 @@ export const rsformsApi = {
|
|||
|
||||
cstCreate: ({ itemID, data }: { itemID: number; data: ICstCreateDTO }) =>
|
||||
axiosPost<ICstCreateDTO, ICstCreatedResponse>({
|
||||
schema: schemaCstCreatedResponse,
|
||||
endpoint: `/api/rsforms/${itemID}/create-cst`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -66,7 +76,8 @@ export const rsformsApi = {
|
|||
}
|
||||
}),
|
||||
cstUpdate: ({ itemID, data }: { itemID: number; data: ICstUpdateDTO }) =>
|
||||
axiosPatch<ICstUpdateDTO, IConstituentaMeta>({
|
||||
axiosPatch<ICstUpdateDTO, IConstituentaBasicsDTO>({
|
||||
schema: schemaConstituentaBasics,
|
||||
endpoint: `/api/rsforms/${itemID}/update-cst`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -75,6 +86,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
cstDelete: ({ itemID, data }: { itemID: number; data: IConstituentaList }) =>
|
||||
axiosPatch<IConstituentaList, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -83,6 +95,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
cstRename: ({ itemID, data }: { itemID: number; data: ICstRenameDTO }) =>
|
||||
axiosPatch<ICstRenameDTO, ICstCreatedResponse>({
|
||||
schema: schemaCstCreatedResponse,
|
||||
endpoint: `/api/rsforms/${itemID}/rename-cst`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -91,6 +104,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
cstSubstitute: ({ itemID, data }: { itemID: number; data: ICstSubstitutionsDTO }) =>
|
||||
axiosPatch<ICstSubstitutionsDTO, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${itemID}/substitute`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -99,12 +113,14 @@ export const rsformsApi = {
|
|||
}),
|
||||
cstMove: ({ itemID, data }: { itemID: number; data: ICstMoveDTO }) =>
|
||||
axiosPatch<ICstMoveDTO, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${itemID}/move-cst`,
|
||||
request: { data: data }
|
||||
}),
|
||||
|
||||
produceStructure: ({ itemID, data }: { itemID: number; data: ITargetCst }) =>
|
||||
axiosPatch<ITargetCst, IProduceStructureResponse>({
|
||||
schema: schemaProduceStructureResponse,
|
||||
endpoint: `/api/rsforms/${itemID}/produce-structure`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -113,6 +129,7 @@ export const rsformsApi = {
|
|||
}),
|
||||
inlineSynthesis: (data: IInlineSynthesisDTO) =>
|
||||
axiosPatch<IInlineSynthesisDTO, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/inline-synthesis`,
|
||||
request: {
|
||||
data: data,
|
||||
|
@ -121,17 +138,20 @@ export const rsformsApi = {
|
|||
}),
|
||||
restoreOrder: ({ itemID }: { itemID: number }) =>
|
||||
axiosPatch<undefined, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${itemID}/restore-order`,
|
||||
request: { successMessage: infoMsg.reorderComplete }
|
||||
}),
|
||||
resetAliases: ({ itemID }: { itemID: number }) =>
|
||||
axiosPatch<undefined, IRSFormDTO>({
|
||||
schema: schemaRSForm,
|
||||
endpoint: `/api/rsforms/${itemID}/reset-aliases`,
|
||||
request: { successMessage: infoMsg.reindexComplete }
|
||||
}),
|
||||
|
||||
checkConstituenta: ({ itemID, data }: { itemID: number; data: ICheckConstituentaDTO }) =>
|
||||
axiosPost<ICheckConstituentaDTO, IExpressionParse>({
|
||||
axiosPost<ICheckConstituentaDTO, IExpressionParseDTO>({
|
||||
schema: schemaExpressionParse,
|
||||
endpoint: `/api/rsforms/${itemID}/check-constituenta`,
|
||||
request: { data: data }
|
||||
})
|
||||
|
|
|
@ -1,37 +1,22 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
import { ILibraryItemReference, ILibraryItemVersioned } from '@/features/library/models/library';
|
||||
import { AccessPolicy, LibraryItemType, schemaVersionInfo } from '@/features/library/models/library';
|
||||
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
|
||||
import { CstType, IConstituentaMeta, IInheritanceInfo } from '../models/rsform';
|
||||
import { IArgumentInfo, ParsingStatus, ValueClass } from '../models/rslang';
|
||||
import { CstType } from '../models/rsform';
|
||||
import { ParsingStatus, RSErrorType, Syntax, TokenID, ValueClass } from '../models/rslang';
|
||||
|
||||
/**
|
||||
* Represents {@link IConstituenta} data from server.
|
||||
*/
|
||||
export interface IConstituentaDTO extends IConstituentaMeta {
|
||||
parse: {
|
||||
status: ParsingStatus;
|
||||
valueClass: ValueClass;
|
||||
typification: string;
|
||||
syntaxTree: string;
|
||||
args: IArgumentInfo[];
|
||||
};
|
||||
}
|
||||
/** Represents Constituenta basic persistent data. */
|
||||
export type IConstituentaBasicsDTO = z.infer<typeof schemaConstituentaBasics>;
|
||||
|
||||
/**
|
||||
* Represents data for {@link IRSForm} provided by backend.
|
||||
*/
|
||||
export interface IRSFormDTO extends ILibraryItemVersioned {
|
||||
items: IConstituentaDTO[];
|
||||
inheritance: IInheritanceInfo[];
|
||||
oss: ILibraryItemReference[];
|
||||
}
|
||||
/** Represents {@link IConstituenta} data from server. */
|
||||
export type IConstituentaDTO = z.infer<typeof schemaConstituenta>;
|
||||
|
||||
/**
|
||||
* Represents data, used for uploading {@link IRSForm} as file.
|
||||
*/
|
||||
/** Represents data for {@link IRSForm} provided by backend. */
|
||||
export type IRSFormDTO = z.infer<typeof schemaRSForm>;
|
||||
|
||||
/** Represents data, used for uploading {@link IRSForm} as file. */
|
||||
export interface IRSFormUploadDTO {
|
||||
itemID: number;
|
||||
load_metadata: boolean;
|
||||
|
@ -39,36 +24,128 @@ export interface IRSFormUploadDTO {
|
|||
fileName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents {@link IConstituenta} data, used in creation process.
|
||||
*/
|
||||
export const schemaCstCreate = z.object({
|
||||
cst_type: z.nativeEnum(CstType),
|
||||
alias: z.string().nonempty(errorMsg.requiredField),
|
||||
convention: z.string(),
|
||||
definition_formal: z.string(),
|
||||
definition_raw: z.string(),
|
||||
term_raw: z.string(),
|
||||
term_forms: z.array(z.object({ text: z.string(), tags: z.string() })),
|
||||
insert_after: z.number().nullable()
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents {@link IConstituenta} data, used in creation process.
|
||||
*/
|
||||
export type ICstCreateDTO = z.infer<typeof schemaCstCreate>;
|
||||
|
||||
/**
|
||||
* Represents data response when creating {@link IConstituenta}.
|
||||
*/
|
||||
export interface ICstCreatedResponse {
|
||||
new_cst: IConstituentaMeta;
|
||||
schema: IRSFormDTO;
|
||||
/** Represents target {@link IConstituenta}. */
|
||||
export interface ITargetCst {
|
||||
target: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data, used in updating persistent attributes in {@link IConstituenta}.
|
||||
*/
|
||||
/** Represents {@link IConstituenta} data, used in creation process. */
|
||||
export type ICstCreateDTO = z.infer<typeof schemaCstCreate>;
|
||||
|
||||
/** Represents data response when creating {@link IConstituenta}. */
|
||||
export type ICstCreatedResponse = z.infer<typeof schemaCstCreatedResponse>;
|
||||
|
||||
/** Represents data, used in updating persistent attributes in {@link IConstituenta}. */
|
||||
export type ICstUpdateDTO = z.infer<typeof schemaCstUpdate>;
|
||||
|
||||
/** Represents data, used in renaming {@link IConstituenta}. */
|
||||
export type ICstRenameDTO = z.infer<typeof schemaCstRename>;
|
||||
|
||||
/** Represents data, used in ordering a list of {@link IConstituenta}. */
|
||||
export interface ICstMoveDTO {
|
||||
items: number[];
|
||||
move_to: number; // Note: 0-base index
|
||||
}
|
||||
|
||||
/** Represents data response when creating producing structure of {@link IConstituenta}. */
|
||||
export type IProduceStructureResponse = z.infer<typeof schemaProduceStructureResponse>;
|
||||
|
||||
/** Represents data, used in merging single {@link IConstituenta}. */
|
||||
export type ICstSubstitute = z.infer<typeof schemaCstSubstitute>;
|
||||
|
||||
/** Represents input data for inline synthesis. */
|
||||
export type IInlineSynthesisDTO = z.infer<typeof schemaInlineSynthesis>;
|
||||
|
||||
/** Represents {@link IConstituenta} data, used for checking expression. */
|
||||
export interface ICheckConstituentaDTO {
|
||||
alias: string;
|
||||
cst_type: CstType;
|
||||
definition_formal: string;
|
||||
}
|
||||
|
||||
/** Represents data, used in merging multiple {@link IConstituenta}. */
|
||||
export type ICstSubstitutionsDTO = z.infer<typeof schemaCstSubstitutions>;
|
||||
|
||||
/** Represents parsing error description. */
|
||||
export type IRSErrorDescription = z.infer<typeof schemaRSErrorDescription>;
|
||||
|
||||
/** Represents results of expression parse in RSLang. */
|
||||
export type IExpressionParseDTO = z.infer<typeof schemaExpressionParse>;
|
||||
|
||||
// ========= SCHEMAS ========
|
||||
export const schemaConstituentaBasics = z.object({
|
||||
id: z.coerce.number(),
|
||||
alias: z.string().nonempty(errorMsg.requiredField),
|
||||
convention: z.string(),
|
||||
cst_type: z.nativeEnum(CstType),
|
||||
definition_formal: z.string(),
|
||||
definition_raw: z.string(),
|
||||
definition_resolved: z.string(),
|
||||
term_raw: z.string(),
|
||||
term_resolved: z.string(),
|
||||
term_forms: z.array(z.object({ text: z.string(), tags: z.string() }))
|
||||
});
|
||||
|
||||
export const schemaConstituenta = schemaConstituentaBasics.extend({
|
||||
parse: z.object({
|
||||
status: z.nativeEnum(ParsingStatus),
|
||||
valueClass: z.nativeEnum(ValueClass),
|
||||
typification: z.string(),
|
||||
syntaxTree: z.string(),
|
||||
args: z.array(z.object({ alias: z.string(), typification: z.string() }))
|
||||
})
|
||||
});
|
||||
|
||||
export const schemaRSForm = z.object({
|
||||
id: z.coerce.number(),
|
||||
item_type: z.nativeEnum(LibraryItemType),
|
||||
title: z.string(),
|
||||
alias: z.string(),
|
||||
comment: z.string(),
|
||||
visible: z.boolean(),
|
||||
read_only: z.boolean(),
|
||||
location: z.string(),
|
||||
access_policy: z.nativeEnum(AccessPolicy),
|
||||
time_create: z.string(),
|
||||
time_update: z.string(),
|
||||
|
||||
owner: z.coerce.number().nullable(),
|
||||
editors: z.array(z.coerce.number()),
|
||||
|
||||
version: z.coerce.number().optional(),
|
||||
versions: z.array(schemaVersionInfo),
|
||||
|
||||
items: z.array(schemaConstituenta),
|
||||
inheritance: z.array(
|
||||
z.object({
|
||||
child: z.coerce.number(),
|
||||
child_source: z.coerce.number(),
|
||||
parent: z.coerce.number(),
|
||||
parent_source: z.coerce.number()
|
||||
})
|
||||
),
|
||||
oss: z.array(z.object({ id: z.coerce.number(), alias: z.string() }))
|
||||
});
|
||||
|
||||
export const schemaCstCreate = schemaConstituentaBasics
|
||||
.pick({
|
||||
cst_type: true,
|
||||
alias: true,
|
||||
convention: true,
|
||||
definition_formal: true,
|
||||
definition_raw: true,
|
||||
term_raw: true,
|
||||
term_forms: true
|
||||
})
|
||||
.extend({
|
||||
insert_after: z.number().nullable()
|
||||
});
|
||||
|
||||
export const schemaCstCreatedResponse = z.object({
|
||||
new_cst: schemaConstituentaBasics,
|
||||
schema: schemaRSForm
|
||||
});
|
||||
|
||||
export const schemaCstUpdate = z.object({
|
||||
target: z.number(),
|
||||
item_data: z.object({
|
||||
|
@ -80,57 +157,26 @@ export const schemaCstUpdate = z.object({
|
|||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in updating persistent attributes in {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstUpdateDTO = z.infer<typeof schemaCstUpdate>;
|
||||
|
||||
/**
|
||||
* Represents data, used in renaming {@link IConstituenta}.
|
||||
*/
|
||||
export const schemaCstRename = z.object({
|
||||
target: z.number(),
|
||||
alias: z.string(),
|
||||
cst_type: z.nativeEnum(CstType)
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in renaming {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstRenameDTO = z.infer<typeof schemaCstRename>;
|
||||
export const schemaProduceStructureResponse = z.object({
|
||||
cst_list: z.array(z.number()),
|
||||
schema: schemaRSForm
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in ordering a list of {@link IConstituenta}.
|
||||
*/
|
||||
export interface ICstMoveDTO {
|
||||
items: number[];
|
||||
move_to: number; // Note: 0-base index
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data response when creating producing structure of {@link IConstituenta}.
|
||||
*/
|
||||
export interface IProduceStructureResponse {
|
||||
cst_list: number[];
|
||||
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>;
|
||||
export const schemaCstSubstitutions = z.object({
|
||||
substitutions: z.array(schemaCstSubstitute).min(1, { message: errorMsg.emptySubstitutions })
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents input data for inline synthesis.
|
||||
*/
|
||||
export const schemaInlineSynthesis = z.object({
|
||||
receiver: z.number(),
|
||||
source: z.number().nullable(),
|
||||
|
@ -138,28 +184,35 @@ export const schemaInlineSynthesis = z.object({
|
|||
substitutions: z.array(schemaCstSubstitute)
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents input data for inline synthesis.
|
||||
*/
|
||||
export type IInlineSynthesisDTO = z.infer<typeof schemaInlineSynthesis>;
|
||||
|
||||
/**
|
||||
* Represents {@link IConstituenta} data, used for checking expression.
|
||||
*/
|
||||
export interface ICheckConstituentaDTO {
|
||||
alias: string;
|
||||
cst_type: CstType;
|
||||
definition_formal: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data, used in renaming {@link IConstituenta}.
|
||||
*/
|
||||
export const schemaCstSubstitutions = z.object({
|
||||
substitutions: z.array(schemaCstSubstitute).min(1, { message: errorMsg.emptySubstitutions })
|
||||
export const schemaRSErrorDescription = z.object({
|
||||
errorType: z.nativeEnum(RSErrorType),
|
||||
position: z.number(),
|
||||
isCritical: z.boolean(),
|
||||
params: z.array(z.string())
|
||||
});
|
||||
|
||||
/**
|
||||
* Represents data, used in merging multiple {@link IConstituenta}.
|
||||
*/
|
||||
export type ICstSubstitutionsDTO = z.infer<typeof schemaCstSubstitutions>;
|
||||
export const schemaExpressionParse = z.object({
|
||||
parseResult: z.boolean(),
|
||||
prefixLen: z.number(),
|
||||
syntax: z.nativeEnum(Syntax),
|
||||
typification: z.string(),
|
||||
valueClass: z.nativeEnum(ValueClass),
|
||||
errors: z.array(schemaRSErrorDescription),
|
||||
astText: z.string(),
|
||||
ast: z.array(
|
||||
z.object({
|
||||
uid: z.number(),
|
||||
parent: z.number(),
|
||||
typeID: z.nativeEnum(TokenID),
|
||||
start: z.number(),
|
||||
finish: z.number(),
|
||||
data: z.object({ dataType: z.string(), value: z.unknown().refine(value => value !== undefined) })
|
||||
})
|
||||
),
|
||||
args: z.array(
|
||||
z.object({
|
||||
alias: z.string(),
|
||||
typification: z.string()
|
||||
})
|
||||
)
|
||||
});
|
||||
|
|
|
@ -4,9 +4,8 @@ import { useUpdateTimestamp } from '@/features/library';
|
|||
|
||||
import { KEYS } from '@/backend/configuration';
|
||||
|
||||
import { ITargetCst } from '../models/rsform';
|
||||
|
||||
import { rsformsApi } from './api';
|
||||
import { ITargetCst } from './types';
|
||||
|
||||
export const useProduceStructure = () => {
|
||||
const client = useQueryClient();
|
||||
|
|
|
@ -7,9 +7,9 @@ import { ModalForm } from '@/components/Modal';
|
|||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
|
||||
import { ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||
import { IConstituentaBasicsDTO, ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||
import { useCstCreate } from '../../backend/useCstCreate';
|
||||
import { IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||
import { IRSForm } from '../../models/rsform';
|
||||
import { validateNewAlias } from '../../models/rsformAPI';
|
||||
|
||||
import FormCreateCst from './FormCreateCst';
|
||||
|
@ -17,7 +17,7 @@ import FormCreateCst from './FormCreateCst';
|
|||
export interface DlgCreateCstProps {
|
||||
initial: ICstCreateDTO;
|
||||
schema: IRSForm;
|
||||
onCreate: (data: IConstituentaMeta) => void;
|
||||
onCreate: (data: IConstituentaBasicsDTO) => void;
|
||||
}
|
||||
|
||||
function DlgCreateCst() {
|
||||
|
@ -30,7 +30,7 @@ function DlgCreateCst() {
|
|||
});
|
||||
const alias = useWatch({ control: methods.control, name: 'alias' });
|
||||
const cst_type = useWatch({ control: methods.control, name: 'cst_type' });
|
||||
const isValid = alias !== initial.alias && validateNewAlias(alias, cst_type, schema);
|
||||
const isValid = validateNewAlias(alias, cst_type, schema);
|
||||
|
||||
function onSubmit(data: ICstCreateDTO) {
|
||||
return cstCreate({ itemID: schema.id, data }).then(onCreate);
|
||||
|
|
|
@ -12,9 +12,9 @@ import { ModalForm } from '@/components/Modal';
|
|||
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
|
||||
import { ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||
import { IConstituentaBasicsDTO, ICstCreateDTO, schemaCstCreate } from '../../backend/types';
|
||||
import { useCstCreate } from '../../backend/useCstCreate';
|
||||
import { CstType, IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||
import { CstType, IRSForm } from '../../models/rsform';
|
||||
import { generateAlias, validateNewAlias } from '../../models/rsformAPI';
|
||||
import FormCreateCst from '../DlgCreateCst/FormCreateCst';
|
||||
|
||||
|
@ -24,7 +24,7 @@ import { TemplateState } from './TemplateContext';
|
|||
|
||||
export interface DlgCstTemplateProps {
|
||||
schema: IRSForm;
|
||||
onCreate: (data: IConstituentaMeta) => void;
|
||||
onCreate: (data: IConstituentaBasicsDTO) => void;
|
||||
insertAfter?: number;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,10 @@
|
|||
import { PARAMETER } from '@/utils/constants';
|
||||
import { prepareTooltip } from '@/utils/utils';
|
||||
|
||||
import { IRSErrorDescription } from './backend/types';
|
||||
import { GramData, Grammeme, ReferenceType } from './models/language';
|
||||
import { CstClass, CstType, ExpressionStatus, IConstituenta, IRSForm } from './models/rsform';
|
||||
import {
|
||||
IArgumentInfo,
|
||||
IRSErrorDescription,
|
||||
ISyntaxTreeNode,
|
||||
ParsingStatus,
|
||||
RSErrorType,
|
||||
TokenID
|
||||
} from './models/rslang';
|
||||
import { IArgumentInfo, ISyntaxTreeNode, ParsingStatus, RSErrorType, TokenID } from './models/rslang';
|
||||
import { CstMatchMode, DependencyMode } from './stores/cstSearch';
|
||||
import { GraphColoring } from './stores/termGraph';
|
||||
|
||||
|
|
|
@ -56,9 +56,9 @@ export interface TermForm {
|
|||
}
|
||||
|
||||
/**
|
||||
* Represents Constituenta basic persistent data.
|
||||
* Represents Constituenta.
|
||||
*/
|
||||
export interface IConstituentaMeta {
|
||||
export interface IConstituenta {
|
||||
id: number;
|
||||
alias: string;
|
||||
convention: string;
|
||||
|
@ -69,19 +69,7 @@ export interface IConstituentaMeta {
|
|||
term_raw: string;
|
||||
term_resolved: string;
|
||||
term_forms: TermForm[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents target {@link IConstituenta}.
|
||||
*/
|
||||
export interface ITargetCst {
|
||||
target: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents Constituenta.
|
||||
*/
|
||||
export interface IConstituenta extends IConstituentaMeta {
|
||||
parse: {
|
||||
status: ParsingStatus;
|
||||
valueClass: ValueClass;
|
||||
|
@ -127,7 +115,10 @@ export interface IConstituenta extends IConstituentaMeta {
|
|||
/**
|
||||
* Represents {@link IConstituenta} reference.
|
||||
*/
|
||||
export interface IConstituentaReference extends Pick<IConstituenta, 'id' | 'schema'> {}
|
||||
export interface IConstituentaReference {
|
||||
id: number;
|
||||
schema: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents Constituenta list.
|
||||
|
@ -183,12 +174,3 @@ export interface IRSForm extends ILibraryItemVersioned {
|
|||
cstByAlias: Map<string, IConstituenta>;
|
||||
cstByID: Map<number, IConstituenta>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents single substitution for binary synthesis table.
|
||||
*/
|
||||
export interface IBinarySubstitution {
|
||||
leftCst: IConstituenta;
|
||||
rightCst: IConstituenta;
|
||||
deleteRight: boolean;
|
||||
}
|
||||
|
|
|
@ -34,16 +34,6 @@ export enum ParsingStatus {
|
|||
INCORRECT = 'incorrect'
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents parsing error description.
|
||||
*/
|
||||
export interface IRSErrorDescription {
|
||||
errorType: RSErrorType;
|
||||
position: number;
|
||||
isCritical: boolean;
|
||||
params: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents AST node.
|
||||
*/
|
||||
|
@ -86,21 +76,6 @@ export interface IArgumentValue extends IArgumentInfo {
|
|||
value?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents results of expression parse in RSLang.
|
||||
*/
|
||||
export interface IExpressionParse {
|
||||
parseResult: boolean;
|
||||
prefixLen: number;
|
||||
syntax: Syntax;
|
||||
typification: string;
|
||||
valueClass: ValueClass;
|
||||
errors: IRSErrorDescription[];
|
||||
astText: string;
|
||||
ast: SyntaxTree;
|
||||
args: IArgumentInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents RSLang token types.
|
||||
*/
|
||||
|
|
|
@ -7,8 +7,10 @@ import { Tree } from '@lezer/common';
|
|||
import { cursorNode } from '@/utils/codemirror';
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { IRSErrorDescription } from '../backend/types';
|
||||
|
||||
import { CstType } from './rsform';
|
||||
import { AliasMapping, IArgumentValue, IRSErrorDescription, RSErrorClass, RSErrorType, SyntaxTree } from './rslang';
|
||||
import { AliasMapping, IArgumentValue, RSErrorClass, RSErrorType, SyntaxTree } from './rslang';
|
||||
|
||||
// cspell:disable
|
||||
const LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\d*/g;
|
||||
|
|
|
@ -16,14 +16,14 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { useModificationStore } from '@/stores/modification';
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
|
||||
import { ICstUpdateDTO, schemaCstUpdate } from '../../../backend/types';
|
||||
import { ICstUpdateDTO, IExpressionParseDTO, schemaCstUpdate } from '../../../backend/types';
|
||||
import { useCstUpdate } from '../../../backend/useCstUpdate';
|
||||
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
|
||||
import { RefsInput } from '../../../components/RefsInput';
|
||||
import { labelCstTypification, labelTypification } from '../../../labels';
|
||||
import { CstType, IConstituenta, IRSForm } from '../../../models/rsform';
|
||||
import { isBaseSet, isBasicConcept, isFunctional } from '../../../models/rsformAPI';
|
||||
import { IExpressionParse, ParsingStatus } from '../../../models/rslang';
|
||||
import { ParsingStatus } from '../../../models/rslang';
|
||||
import EditorRSExpression from '../EditorRSExpression';
|
||||
|
||||
interface FormConstituentaProps {
|
||||
|
@ -50,7 +50,7 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen
|
|||
formState: { isDirty }
|
||||
} = useForm<ICstUpdateDTO>({ resolver: zodResolver(schemaCstUpdate) });
|
||||
|
||||
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
||||
const [localParse, setLocalParse] = useState<IExpressionParseDTO | undefined>(undefined);
|
||||
|
||||
const typification = useMemo(
|
||||
() =>
|
||||
|
|
|
@ -56,7 +56,7 @@ function ToolbarConstituenta({
|
|||
const isProcessing = useMutatingRSForm();
|
||||
|
||||
function viewPredecessor(target: number) {
|
||||
void findPredecessor({ target: target }).then(reference =>
|
||||
void findPredecessor(target).then(reference =>
|
||||
router.push(
|
||||
urls.schema_props({
|
||||
id: reference.schema,
|
||||
|
|
|
@ -5,6 +5,7 @@ import { toast } from 'react-toastify';
|
|||
import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
|
||||
|
||||
import { BadgeHelp, HelpTopic } from '@/features/help';
|
||||
import { IExpressionParseDTO } from '@/features/rsform/backend/types';
|
||||
|
||||
import { DataCallback } from '@/backend/apiTransport';
|
||||
import { Overlay } from '@/components/Container';
|
||||
|
@ -13,7 +14,7 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { usePreferencesStore } from '@/stores/preferences';
|
||||
import { errorMsg } from '@/utils/labels';
|
||||
|
||||
import { ICheckConstituentaDTO } from '../../../backend/types';
|
||||
import { ICheckConstituentaDTO, IRSErrorDescription } from '../../../backend/types';
|
||||
import { useCheckConstituenta } from '../../../backend/useCheckConstituenta';
|
||||
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
|
||||
import RSInput from '../../../components/RSInput';
|
||||
|
@ -21,7 +22,7 @@ import { parser as rslangParser } from '../../../components/RSInput/rslang/parse
|
|||
import { RSTextWrapper } from '../../../components/RSInput/textEditing';
|
||||
import { IConstituenta } from '../../../models/rsform';
|
||||
import { getDefinitionPrefix } from '../../../models/rsformAPI';
|
||||
import { IExpressionParse, IRSErrorDescription, TokenID } from '../../../models/rslang';
|
||||
import { TokenID } from '../../../models/rslang';
|
||||
import { transformAST } from '../../../models/rslangAPI';
|
||||
import { useRSEdit } from '../RSEditContext';
|
||||
|
||||
|
@ -42,7 +43,7 @@ interface EditorRSExpressionProps {
|
|||
disabled?: boolean;
|
||||
toggleReset?: boolean;
|
||||
|
||||
onChangeLocalParse: (typification: IExpressionParse | undefined) => void;
|
||||
onChangeLocalParse: (typification: IExpressionParseDTO | undefined) => void;
|
||||
onOpenEdit?: (cstID: number) => void;
|
||||
onShowTypeGraph: (event: CProps.EventMouse) => void;
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ function EditorRSExpression({
|
|||
|
||||
const [isModified, setIsModified] = useState(false);
|
||||
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
||||
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
|
||||
const [parseData, setParseData] = useState<IExpressionParseDTO | undefined>(undefined);
|
||||
|
||||
const isProcessing = useMutatingRSForm();
|
||||
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
||||
|
@ -70,7 +71,11 @@ function EditorRSExpression({
|
|||
|
||||
const { checkConstituenta: checkInternal, isPending } = useCheckConstituenta();
|
||||
|
||||
function checkConstituenta(expression: string, activeCst: IConstituenta, onSuccess?: DataCallback<IExpressionParse>) {
|
||||
function checkConstituenta(
|
||||
expression: string,
|
||||
activeCst: IConstituenta,
|
||||
onSuccess?: DataCallback<IExpressionParseDTO>
|
||||
) {
|
||||
const data: ICheckConstituentaDTO = {
|
||||
definition_formal: expression,
|
||||
alias: activeCst.alias,
|
||||
|
@ -92,7 +97,7 @@ function EditorRSExpression({
|
|||
setIsModified(newValue !== activeCst.definition_formal);
|
||||
}
|
||||
|
||||
function handleCheckExpression(callback?: (parse: IExpressionParse) => void) {
|
||||
function handleCheckExpression(callback?: (parse: IExpressionParseDTO) => void) {
|
||||
checkConstituenta(value, activeCst, parse => {
|
||||
onChangeLocalParse(parse);
|
||||
if (parse.errors.length > 0) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { IExpressionParseDTO, IRSErrorDescription } from '../../../backend/types';
|
||||
import { describeRSError } from '../../../labels';
|
||||
import { IExpressionParse, IRSErrorDescription } from '../../../models/rslang';
|
||||
import { getRSErrorPrefix } from '../../../models/rslangAPI';
|
||||
|
||||
interface ParsingResultProps {
|
||||
data: IExpressionParse | undefined;
|
||||
data: IExpressionParseDTO | undefined;
|
||||
disabled?: boolean;
|
||||
isOpen: boolean;
|
||||
onShowError: (error: IRSErrorDescription) => void;
|
||||
|
|
|
@ -8,16 +8,17 @@ import { APP_COLORS } from '@/styling/colors';
|
|||
import { globals } from '@/utils/constants';
|
||||
import { prepareTooltip } from '@/utils/utils';
|
||||
|
||||
import { IExpressionParseDTO } from '../../../backend/types';
|
||||
import { colorStatusBar } from '../../../colors';
|
||||
import { labelExpressionStatus } from '../../../labels';
|
||||
import { ExpressionStatus, IConstituenta } from '../../../models/rsform';
|
||||
import { inferStatus } from '../../../models/rsformAPI';
|
||||
import { IExpressionParse, ParsingStatus } from '../../../models/rslang';
|
||||
import { ParsingStatus } from '../../../models/rslang';
|
||||
|
||||
interface StatusBarProps {
|
||||
processing?: boolean;
|
||||
isModified?: boolean;
|
||||
parseData?: IExpressionParse;
|
||||
parseData?: IExpressionParseDTO;
|
||||
activeCst: IConstituenta;
|
||||
onAnalyze: () => void;
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ import { PARAMETER, prefixes } from '@/utils/constants';
|
|||
import { promptText } from '@/utils/labels';
|
||||
import { promptUnsaved } from '@/utils/utils';
|
||||
|
||||
import { ICstCreateDTO } from '../../backend/types';
|
||||
import { IConstituentaBasicsDTO, ICstCreateDTO } from '../../backend/types';
|
||||
import { useCstCreate } from '../../backend/useCstCreate';
|
||||
import { useCstMove } from '../../backend/useCstMove';
|
||||
import { useRSFormSuspense } from '../../backend/useRSForm';
|
||||
import { CstType, IConstituenta, IConstituentaMeta, IRSForm } from '../../models/rsform';
|
||||
import { CstType, IConstituenta, IRSForm } from '../../models/rsform';
|
||||
import { generateAlias } from '../../models/rsformAPI';
|
||||
|
||||
export enum RSTabID {
|
||||
|
@ -177,7 +177,7 @@ export const RSEditState = ({
|
|||
});
|
||||
}
|
||||
|
||||
function onCreateCst(newCst: IConstituentaMeta) {
|
||||
function onCreateCst(newCst: IConstituentaBasicsDTO) {
|
||||
setSelected([newCst.id]);
|
||||
navigateRSForm({ tab: activeTab, activeID: newCst.id });
|
||||
if (activeTab === RSTabID.CST_LIST) {
|
||||
|
|
|
@ -141,7 +141,8 @@ export const errorMsg = {
|
|||
invalidLocation: 'Некорректный формат пути',
|
||||
versionTaken: 'Версия с таким шифром уже существует',
|
||||
emptySubstitutions: 'Выберите хотя бы одно отождествление',
|
||||
aliasInvalid: 'Введите незанятое имя, соответствующее типу'
|
||||
aliasInvalid: 'Введите незанятое имя, соответствующее типу',
|
||||
invalidResponse: 'Некорректный ответ сервера'
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user