R: Refactor model types. Separate transport and model

This commit is contained in:
Ivan 2025-01-30 19:55:38 +03:00
parent 2b08a5a966
commit 728eb61f91
25 changed files with 153 additions and 159 deletions

View File

@ -1,5 +1,4 @@
import { axiosPost } from '@/backend/apiTransport'; import { axiosPost } from '@/backend/apiTransport';
import { ILexemeData, IWordFormPlain } from '@/models/language';
/** /**
* Represents API result for text output. * Represents API result for text output.
@ -8,11 +7,26 @@ export interface ITextResult {
result: string; result: string;
} }
/**
* Represents wordform data used for backend communication.
*/
export interface IWordFormDTO {
text: string;
grams: string;
}
/**
* Represents lexeme response containing multiple {@link Wordform}s.
*/
export interface ILexemeResponse {
items: IWordFormDTO[];
}
export const cctextApi = { export const cctextApi = {
baseKey: 'cctext', baseKey: 'cctext',
inflectText: (data: IWordFormPlain) => inflectText: (data: IWordFormDTO) =>
axiosPost<IWordFormPlain, ITextResult>({ axiosPost<IWordFormDTO, ITextResult>({
endpoint: '/api/cctext/inflect', endpoint: '/api/cctext/inflect',
request: { data: data } request: { data: data }
}), }),
@ -22,7 +36,7 @@ export const cctextApi = {
request: { data: data } request: { data: data }
}), }),
generateLexeme: (data: { text: string }) => generateLexeme: (data: { text: string }) =>
axiosPost<{ text: string }, ILexemeData>({ axiosPost<{ text: string }, ILexemeResponse>({
endpoint: '/api/cctext/generate-lexeme', endpoint: '/api/cctext/generate-lexeme',
request: { data: data } request: { data: data }
}) })

View File

@ -1,9 +1,8 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport'; import { DataCallback } from '@/backend/apiTransport';
import { ILexemeData } from '@/models/language';
import { cctextApi } from './api'; import { cctextApi, ILexemeResponse } from './api';
export const useGenerateLexeme = () => { export const useGenerateLexeme = () => {
const mutation = useMutation({ const mutation = useMutation({
@ -13,7 +12,7 @@ export const useGenerateLexeme = () => {
return { return {
generateLexeme: ( generateLexeme: (
data: { text: string }, // data: { text: string }, //
onSuccess?: DataCallback<ILexemeData> onSuccess?: DataCallback<ILexemeResponse>
) => mutation.mutate(data, { onSuccess }) ) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,9 +1,8 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport'; import { DataCallback } from '@/backend/apiTransport';
import { IWordFormPlain } from '@/models/language';
import { cctextApi, ITextResult } from './api'; import { cctextApi, ITextResult, IWordFormDTO } from './api';
export const useInflectText = () => { export const useInflectText = () => {
const mutation = useMutation({ const mutation = useMutation({
@ -12,7 +11,7 @@ export const useInflectText = () => {
}); });
return { return {
inflectText: ( inflectText: (
data: IWordFormPlain, // data: IWordFormDTO, //
onSuccess?: DataCallback<ITextResult> onSuccess?: DataCallback<ITextResult>
) => mutation.mutate(data, { onSuccess }) ) => mutation.mutate(data, { onSuccess })
}; };

View File

@ -3,7 +3,7 @@ import { queryOptions } from '@tanstack/react-query';
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { ossApi } from '@/backend/oss/api'; import { ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/backend/rsform/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { import {
AccessPolicy, AccessPolicy,
ILibraryItem, ILibraryItem,
@ -13,7 +13,7 @@ import {
LibraryItemType, LibraryItemType,
VersionID VersionID
} from '@/models/library'; } from '@/models/library';
import { ConstituentaID, IRSFormData } from '@/models/rsform'; import { ConstituentaID } from '@/models/rsform';
import { UserID } from '@/models/user'; import { UserID } from '@/models/user';
import { information } from '@/utils/labels'; import { information } from '@/utils/labels';
@ -60,7 +60,7 @@ export interface IVersionCreateDTO {
*/ */
export interface IVersionCreatedResponse { export interface IVersionCreatedResponse {
version: number; version: number;
schema: IRSFormData; schema: IRSFormDTO;
} }
export const libraryApi = { export const libraryApi = {
@ -157,7 +157,7 @@ export const libraryApi = {
} }
}), }),
cloneItem: (data: IRSFormCloneDTO) => cloneItem: (data: IRSFormCloneDTO) =>
axiosPost<IRSFormCloneDTO, IRSFormData>({ axiosPost<IRSFormCloneDTO, IRSFormDTO>({
endpoint: `/api/library/${data.id}/clone`, endpoint: `/api/library/${data.id}/clone`,
request: { request: {
data: data, data: data,
@ -182,7 +182,7 @@ export const libraryApi = {
} }
}), }),
versionRestore: ({ versionID }: { versionID: VersionID }) => versionRestore: ({ versionID }: { versionID: VersionID }) =>
axiosPatch<undefined, IRSFormData>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/versions/${versionID}/restore`, endpoint: `/api/versions/${versionID}/restore`,
request: { request: {
successMessage: information.versionRestored successMessage: information.versionRestored

View File

@ -1,8 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport'; import { DataCallback } from '@/backend/apiTransport';
import { IRSFormData } from '@/models/rsform';
import { IRSFormDTO } from '../rsform/api';
import { IRSFormCloneDTO, libraryApi } from './api'; import { IRSFormCloneDTO, libraryApi } from './api';
export const useCloneItem = () => { export const useCloneItem = () => {
@ -15,7 +15,7 @@ export const useCloneItem = () => {
return { return {
cloneItem: ( cloneItem: (
data: IRSFormCloneDTO, // data: IRSFormCloneDTO, //
onSuccess?: DataCallback<IRSFormData> onSuccess?: DataCallback<IRSFormDTO>
) => mutation.mutate(data, { onSuccess }) ) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,9 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/backend/oss/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/backend/rsform/api'; import { rsformsApi } from '@/backend/rsform/api';
import { AccessPolicy, ILibraryItem, LibraryItemID } from '@/models/library'; import { AccessPolicy, ILibraryItem, LibraryItemID } from '@/models/library';
import { IOperationSchemaData } from '@/models/oss';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -14,7 +13,7 @@ export const useSetAccessPolicy = () => {
mutationFn: libraryApi.setAccessPolicy, mutationFn: libraryApi.setAccessPolicy,
onSuccess: (_, variables) => { onSuccess: (_, variables) => {
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey; const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey); const ossData: IOperationSchemaDTO | undefined = client.getQueryData(ossKey);
if (ossData) { if (ossData) {
client.setQueryData(ossKey, { ...ossData, access_policy: variables.policy }); client.setQueryData(ossKey, { ...ossData, access_policy: variables.policy });
return Promise.allSettled([ return Promise.allSettled([

View File

@ -1,9 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/backend/oss/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/backend/rsform/api'; import { rsformsApi } from '@/backend/rsform/api';
import { ILibraryItem, LibraryItemID } from '@/models/library'; import { ILibraryItem, LibraryItemID } from '@/models/library';
import { IOperationSchemaData } from '@/models/oss';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -14,7 +13,7 @@ export const useSetLocation = () => {
mutationFn: libraryApi.setLocation, mutationFn: libraryApi.setLocation,
onSuccess: (_, variables) => { onSuccess: (_, variables) => {
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey; const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey); const ossData: IOperationSchemaDTO | undefined = client.getQueryData(ossKey);
if (ossData) { if (ossData) {
client.setQueryData(ossKey, { ...ossData, location: variables.location }); client.setQueryData(ossKey, { ...ossData, location: variables.location });
return Promise.allSettled([ return Promise.allSettled([

View File

@ -1,9 +1,8 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/backend/oss/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { rsformsApi } from '@/backend/rsform/api'; import { rsformsApi } from '@/backend/rsform/api';
import { ILibraryItem, LibraryItemID } from '@/models/library'; import { ILibraryItem, LibraryItemID } from '@/models/library';
import { IOperationSchemaData } from '@/models/oss';
import { UserID } from '@/models/user'; import { UserID } from '@/models/user';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -15,7 +14,7 @@ export const useSetOwner = () => {
mutationFn: libraryApi.setOwner, mutationFn: libraryApi.setOwner,
onSuccess: (_, variables) => { onSuccess: (_, variables) => {
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey; const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey); const ossData: IOperationSchemaDTO | undefined = client.getQueryData(ossKey);
if (ossData) { if (ossData) {
client.setQueryData(ossKey, { ...ossData, owner: variables.owner }); client.setQueryData(ossKey, { ...ossData, owner: variables.owner });
return Promise.allSettled([ return Promise.allSettled([

View File

@ -1,10 +1,9 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/backend/oss/api'; import { IOperationSchemaDTO, ossApi } from '@/backend/oss/api';
import { ILibraryItem, LibraryItemType } from '@/models/library'; import { ILibraryItem, LibraryItemType } from '@/models/library';
import { IOperationSchemaData } from '@/models/oss';
import { IRSFormData } from '@/models/rsform';
import { IRSFormDTO } from '../rsform/api';
import { ILibraryUpdateDTO, libraryApi } from './api'; import { ILibraryUpdateDTO, libraryApi } from './api';
export const useUpdateItem = () => { export const useUpdateItem = () => {
@ -17,11 +16,11 @@ export const useUpdateItem = () => {
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) => client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
prev?.map(item => (item.id === data.id ? data : item)) prev?.map(item => (item.id === data.id ? data : item))
); );
client.setQueryData(itemKey, (prev: IRSFormData | IOperationSchemaData | undefined) => client.setQueryData(itemKey, (prev: IRSFormDTO | IOperationSchemaDTO | undefined) =>
!prev ? undefined : { ...prev, ...data } !prev ? undefined : { ...prev, ...data }
); );
if (data.item_type === LibraryItemType.RSFORM) { if (data.item_type === LibraryItemType.RSFORM) {
const schema: IRSFormData | undefined = client.getQueryData(itemKey); const schema: IRSFormDTO | undefined = client.getQueryData(itemKey);
if (schema) { if (schema) {
return Promise.allSettled( return Promise.allSettled(
schema.oss.map(item => schema.oss.map(item =>

View File

@ -1,8 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { rsformsApi } from '@/backend/rsform/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { LibraryItemID, VersionID } from '@/models/library'; import { LibraryItemID, VersionID } from '@/models/library';
import { IRSFormData } from '@/models/rsform';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -14,7 +13,7 @@ export const useVersionDelete = () => {
onSuccess: (_, variables) => { onSuccess: (_, variables) => {
client.setQueryData( client.setQueryData(
rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey,
(prev: IRSFormData | undefined) => (prev: IRSFormDTO | undefined) =>
!prev !prev
? undefined ? undefined
: { : {

View File

@ -1,8 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { rsformsApi } from '@/backend/rsform/api'; import { IRSFormDTO, rsformsApi } from '@/backend/rsform/api';
import { IVersionData, VersionID } from '@/models/library'; import { IVersionData, VersionID } from '@/models/library';
import { IRSFormData } from '@/models/rsform';
import { libraryApi } from './api'; import { libraryApi } from './api';
@ -14,7 +13,7 @@ export const useVersionUpdate = () => {
onSuccess: data => { onSuccess: data => {
client.setQueryData( client.setQueryData(
rsformsApi.getRSFormQueryOptions({ itemID: data.item }).queryKey, rsformsApi.getRSFormQueryOptions({ itemID: data.item }).queryKey,
(prev: IRSFormData | undefined) => (prev: IRSFormDTO | undefined) =>
!prev !prev
? undefined ? undefined
: { : {

View File

@ -2,29 +2,24 @@
* Module: OSS data loading and processing. * Module: OSS data loading and processing.
*/ */
import { Graph } from './Graph'; import { Graph } from '@/models/Graph';
import { ILibraryItem, LibraryItemID } from './library'; import { ILibraryItem, LibraryItemID } from '@/models/library';
import { import { IOperation, IOperationSchema, IOperationSchemaStats, OperationID, OperationType } from '@/models/oss';
IOperation,
IOperationSchema, import { IOperationSchemaDTO } from './api';
IOperationSchemaData,
IOperationSchemaStats,
OperationID,
OperationType
} from './oss';
/** /**
* Loads data into an {@link IOperationSchema} based on {@link IOperationSchemaData}. * Loads data into an {@link IOperationSchema} based on {@link IOperationSchemaDTO}.
* *
*/ */
export class OssLoader { export class OssLoader {
private oss: IOperationSchemaData; private oss: IOperationSchemaDTO;
private graph: Graph = new Graph(); private graph: Graph = new Graph();
private operationByID = new Map<OperationID, IOperation>(); private operationByID = new Map<OperationID, IOperation>();
private schemaIDs: LibraryItemID[] = []; private schemaIDs: LibraryItemID[] = [];
private items: ILibraryItem[]; private items: ILibraryItem[];
constructor(input: IOperationSchemaData, items: ILibraryItem[]) { constructor(input: IOperationSchemaDTO, items: ILibraryItem[]) {
this.oss = input; this.oss = input;
this.items = items; this.items = items;
} }

View File

@ -2,18 +2,33 @@ import { queryOptions } from '@tanstack/react-query';
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { ILibraryItem, LibraryItemID } from '@/models/library'; import { ILibraryItem, ILibraryItemData, LibraryItemID } from '@/models/library';
import { import {
IArgument,
ICstSubstitute, ICstSubstitute,
IOperationData, ICstSubstituteEx,
IOperation,
IOperationPosition, IOperationPosition,
IOperationSchemaData,
OperationID, OperationID,
OperationType OperationType
} from '@/models/oss'; } from '@/models/oss';
import { ConstituentaID, IConstituentaReference, ITargetCst } from '@/models/rsform'; import { ConstituentaID, IConstituentaReference, ITargetCst } from '@/models/rsform';
import { information } from '@/utils/labels'; import { information } from '@/utils/labels';
/**
* Represents {@link IOperation} data from server.
*/
export interface IOperationDTO extends Omit<IOperation, 'substitutions' | 'arguments'> {}
/**
* Represents backend data for {@link IOperationSchema}.
*/
export interface IOperationSchemaDTO extends ILibraryItemData {
items: IOperationDTO[];
arguments: IArgument[];
substitutions: ICstSubstituteEx[];
}
/** /**
* Represents {@link IOperation} data, used in creation process. * Represents {@link IOperation} data, used in creation process.
*/ */
@ -36,8 +51,8 @@ export interface IOperationCreateDTO {
* Represents data response when creating {@link IOperation}. * Represents data response when creating {@link IOperation}.
*/ */
export interface IOperationCreatedResponse { export interface IOperationCreatedResponse {
new_operation: IOperationData; new_operation: IOperationDTO;
oss: IOperationSchemaData; oss: IOperationSchemaDTO;
} }
/** /**
@ -61,7 +76,7 @@ export interface IOperationDeleteDTO extends ITargetOperation {
*/ */
export interface IInputCreatedResponse { export interface IInputCreatedResponse {
new_schema: ILibraryItem; new_schema: ILibraryItem;
oss: IOperationSchemaData; oss: IOperationSchemaDTO;
} }
/** /**
@ -102,7 +117,7 @@ export const ossApi = {
queryFn: meta => queryFn: meta =>
!itemID !itemID
? undefined ? undefined
: axiosGet<IOperationSchemaData>({ : axiosGet<IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/details`, endpoint: `/api/oss/${itemID}/details`,
options: { signal: meta.signal } options: { signal: meta.signal }
}) })
@ -135,7 +150,7 @@ export const ossApi = {
} }
}), }),
operationDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationDeleteDTO }) => operationDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationDeleteDTO }) =>
axiosDelete<IOperationDeleteDTO, IOperationSchemaData>({ axiosDelete<IOperationDeleteDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/delete-operation`, endpoint: `/api/oss/${itemID}/delete-operation`,
request: { request: {
data: data, data: data,
@ -151,7 +166,7 @@ export const ossApi = {
} }
}), }),
inputUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IInputUpdateDTO }) => inputUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IInputUpdateDTO }) =>
axiosPatch<IInputUpdateDTO, IOperationSchemaData>({ axiosPatch<IInputUpdateDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/set-input`, endpoint: `/api/oss/${itemID}/set-input`,
request: { request: {
data: data, data: data,
@ -159,7 +174,7 @@ export const ossApi = {
} }
}), }),
operationUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationUpdateDTO }) => operationUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationUpdateDTO }) =>
axiosPatch<IOperationUpdateDTO, IOperationSchemaData>({ axiosPatch<IOperationUpdateDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/update-operation`, endpoint: `/api/oss/${itemID}/update-operation`,
request: { request: {
data: data, data: data,
@ -167,7 +182,7 @@ export const ossApi = {
} }
}), }),
operationExecute: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) => operationExecute: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) =>
axiosPost<ITargetOperation, IOperationSchemaData>({ axiosPost<ITargetOperation, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/execute-operation`, endpoint: `/api/oss/${itemID}/execute-operation`,
request: { request: {
data: data, data: data,
@ -176,7 +191,7 @@ export const ossApi = {
}), }),
relocateConstituents: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRelocateDTO }) => relocateConstituents: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRelocateDTO }) =>
axiosPost<ICstRelocateDTO, IOperationSchemaData>({ axiosPost<ICstRelocateDTO, IOperationSchemaDTO>({
endpoint: `/api/oss/${itemID}/relocate-constituents`, endpoint: `/api/oss/${itemID}/relocate-constituents`,
request: { request: {
data: data, data: data,

View File

@ -1,8 +1,8 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary'; import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary';
import { OssLoader } from '@/backend/oss/OssLoader';
import { LibraryItemID } from '@/models/library'; import { LibraryItemID } from '@/models/library';
import { OssLoader } from '@/models/OssLoader';
import { queryClient } from '../queryClient'; import { queryClient } from '../queryClient';
import { ossApi } from './api'; import { ossApi } from './api';

View File

@ -3,9 +3,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import { DataCallback } from '@/backend/apiTransport'; import { DataCallback } from '@/backend/apiTransport';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { LibraryItemID } from '@/models/library'; import { LibraryItemID } from '@/models/library';
import { IOperationData } from '@/models/oss';
import { IOperationCreateDTO, ossApi } from './api'; import { IOperationCreateDTO, IOperationDTO, ossApi } from './api';
export const useOperationCreate = () => { export const useOperationCreate = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -24,7 +23,7 @@ export const useOperationCreate = () => {
itemID: LibraryItemID; // itemID: LibraryItemID; //
data: IOperationCreateDTO; data: IOperationCreateDTO;
}, },
onSuccess?: DataCallback<IOperationData> onSuccess?: DataCallback<IOperationDTO>
) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.new_operation) }) ) => mutation.mutate(data, { onSuccess: response => onSuccess?.(response.new_operation) })
}; };
}; };

View File

@ -2,27 +2,29 @@
* Module: RSForm data loading and processing. * Module: RSForm data loading and processing.
*/ */
import { Graph } from './Graph'; import { Graph } from '@/models/Graph';
import { LibraryItemID } from './library'; import { LibraryItemID } from '@/models/library';
import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormData, IRSFormStats } from './rsform'; import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormStats } from '@/models/rsform';
import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from './rsformAPI'; import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from '@/models/rsformAPI';
import { ParsingStatus, ValueClass } from './rslang'; import { ParsingStatus, ValueClass } from '@/models/rslang';
import { extractGlobals, isSimpleExpression, splitTemplateDefinition } from './rslangAPI'; import { extractGlobals, isSimpleExpression, splitTemplateDefinition } from '@/models/rslangAPI';
import { IRSFormDTO } from './api';
/** /**
* Loads data into an {@link IRSForm} based on {@link IRSFormData}. * Loads data into an {@link IRSForm} based on {@link IRSFormDTO}.
* *
* @remarks * @remarks
* This function processes the provided input, initializes the IRSForm, and calculates statistics * This function processes the provided input, initializes the IRSForm, and calculates statistics
* based on the loaded data. It also establishes dependencies between concepts in the graph. * based on the loaded data. It also establishes dependencies between concepts in the graph.
*/ */
export class RSFormLoader { export class RSFormLoader {
private schema: IRSFormData; private schema: IRSFormDTO;
private graph: Graph = new Graph(); private graph: Graph = new Graph();
private cstByAlias = new Map<string, IConstituenta>(); private cstByAlias = new Map<string, IConstituenta>();
private cstByID = new Map<ConstituentaID, IConstituenta>(); private cstByID = new Map<ConstituentaID, IConstituenta>();
constructor(input: IRSFormData) { constructor(input: IRSFormDTO) {
this.schema = input; this.schema = input;
} }
@ -159,7 +161,8 @@ export class RSFormLoader {
} else if (sources.size !== 1) { } else if (sources.size !== 1) {
return false; return false;
} else { } else {
const base = this.cstByID.get(sources.values().next().value!)!; const cstID = sources.values().next().value!;
const base = this.cstByID.get(cstID)!;
return !isFunctional(base.cst_type) || splitTemplateDefinition(base.definition_formal).head !== expression.head; return !isFunctional(base.cst_type) || splitTemplateDefinition(base.definition_formal).head !== expression.head;
} }
}; };

View File

@ -2,20 +2,42 @@ import { queryOptions } from '@tanstack/react-query';
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { LibraryItemID, VersionID } from '@/models/library'; import { ILibraryItemReference, ILibraryItemVersioned, LibraryItemID, VersionID } from '@/models/library';
import { ICstSubstitute, ICstSubstitutions } from '@/models/oss'; import { ICstSubstitute, ICstSubstitutions } from '@/models/oss';
import { import {
ConstituentaID, ConstituentaID,
CstType, CstType,
IConstituentaList, IConstituentaList,
IConstituentaMeta, IConstituentaMeta,
IRSFormData, IInheritanceInfo,
ITargetCst, ITargetCst,
TermForm TermForm
} from '@/models/rsform'; } from '@/models/rsform';
import { IExpressionParse } from '@/models/rslang'; import { IArgumentInfo, IExpressionParse, ParsingStatus, ValueClass } from '@/models/rslang';
import { information } from '@/utils/labels'; import { information } from '@/utils/labels';
/**
* Represents {@link IConstituenta} data from server.
*/
export interface IConstituentaDTO extends IConstituentaMeta {
parse: {
status: ParsingStatus;
valueClass: ValueClass;
typification: string;
syntaxTree: string;
args: IArgumentInfo[];
};
}
/**
* Represents data for {@link IRSForm} provided by backend.
*/
export interface IRSFormDTO extends ILibraryItemVersioned {
items: IConstituentaDTO[];
inheritance: IInheritanceInfo[];
oss: ILibraryItemReference[];
}
/** /**
* Represents data, used for uploading {@link IRSForm} as file. * Represents data, used for uploading {@link IRSForm} as file.
*/ */
@ -46,7 +68,7 @@ export interface ICstCreateDTO {
*/ */
export interface ICstCreatedResponse { export interface ICstCreatedResponse {
new_cst: IConstituentaMeta; new_cst: IConstituentaMeta;
schema: IRSFormData; schema: IRSFormDTO;
} }
/** /**
@ -85,7 +107,7 @@ export interface ICstMoveDTO {
*/ */
export interface IProduceStructureResponse { export interface IProduceStructureResponse {
cst_list: ConstituentaID[]; cst_list: ConstituentaID[];
schema: IRSFormData; schema: IRSFormDTO;
} }
/** /**
@ -117,7 +139,7 @@ export const rsformsApi = {
queryFn: meta => queryFn: meta =>
!itemID !itemID
? undefined ? undefined
: axiosGet<IRSFormData>({ : axiosGet<IRSFormDTO>({
endpoint: version ? `/api/library/${itemID}/versions/${version}` : `/api/rsforms/${itemID}/details`, endpoint: version ? `/api/library/${itemID}/versions/${version}` : `/api/rsforms/${itemID}/details`,
options: { signal: meta.signal } options: { signal: meta.signal }
}) })
@ -130,7 +152,7 @@ export const rsformsApi = {
options: { responseType: 'blob' } options: { responseType: 'blob' }
}), }),
upload: (data: IRSFormUploadDTO) => upload: (data: IRSFormUploadDTO) =>
axiosPatch<IRSFormUploadDTO, IRSFormData>({ axiosPatch<IRSFormUploadDTO, IRSFormDTO>({
endpoint: `/api/rsforms/${data.itemID}/load-trs`, endpoint: `/api/rsforms/${data.itemID}/load-trs`,
request: { request: {
data: data, data: data,
@ -160,7 +182,7 @@ export const rsformsApi = {
} }
}), }),
cstDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IConstituentaList }) => cstDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IConstituentaList }) =>
axiosDelete<IConstituentaList, IRSFormData>({ axiosDelete<IConstituentaList, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`, endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`,
request: { request: {
data: data, data: data,
@ -176,7 +198,7 @@ export const rsformsApi = {
} }
}), }),
cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutions }) => cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutions }) =>
axiosPatch<ICstSubstitutions, IRSFormData>({ axiosPatch<ICstSubstitutions, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/substitute`, endpoint: `/api/rsforms/${itemID}/substitute`,
request: { request: {
data: data, data: data,
@ -184,7 +206,7 @@ export const rsformsApi = {
} }
}), }),
cstMove: ({ itemID, data }: { itemID: LibraryItemID; data: ICstMoveDTO }) => cstMove: ({ itemID, data }: { itemID: LibraryItemID; data: ICstMoveDTO }) =>
axiosPatch<ICstMoveDTO, IRSFormData>({ axiosPatch<ICstMoveDTO, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/move-cst`, endpoint: `/api/rsforms/${itemID}/move-cst`,
request: { data: data } request: { data: data }
}), }),
@ -198,7 +220,7 @@ export const rsformsApi = {
} }
}), }),
inlineSynthesis: ({ itemID, data }: { itemID: LibraryItemID; data: IInlineSynthesisDTO }) => inlineSynthesis: ({ itemID, data }: { itemID: LibraryItemID; data: IInlineSynthesisDTO }) =>
axiosPost<IInlineSynthesisDTO, IRSFormData>({ axiosPost<IInlineSynthesisDTO, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/inline-synthesis`, endpoint: `/api/rsforms/${itemID}/inline-synthesis`,
request: { request: {
data: data, data: data,
@ -206,12 +228,12 @@ export const rsformsApi = {
} }
}), }),
restoreOrder: ({ itemID }: { itemID: LibraryItemID }) => restoreOrder: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormData>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/restore-order`, endpoint: `/api/rsforms/${itemID}/restore-order`,
request: { successMessage: information.reorderComplete } request: { successMessage: information.reorderComplete }
}), }),
resetAliases: ({ itemID }: { itemID: LibraryItemID }) => resetAliases: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormData>({ axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/reset-aliases`, endpoint: `/api/rsforms/${itemID}/reset-aliases`,
request: { successMessage: information.reindexComplete } request: { successMessage: information.reindexComplete }
}), }),

View File

@ -4,9 +4,8 @@ import { DataCallback } from '@/backend/apiTransport';
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp'; import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
import { ossApi } from '@/backend/oss/api'; import { ossApi } from '@/backend/oss/api';
import { LibraryItemID } from '@/models/library'; import { LibraryItemID } from '@/models/library';
import { IRSFormData } from '@/models/rsform';
import { IInlineSynthesisDTO, rsformsApi } from './api'; import { IInlineSynthesisDTO, IRSFormDTO, rsformsApi } from './api';
export const useInlineSynthesis = () => { export const useInlineSynthesis = () => {
const client = useQueryClient(); const client = useQueryClient();
@ -33,7 +32,7 @@ export const useInlineSynthesis = () => {
itemID: LibraryItemID; // itemID: LibraryItemID; //
data: IInlineSynthesisDTO; data: IInlineSynthesisDTO;
}, },
onSuccess?: DataCallback<IRSFormData> onSuccess?: DataCallback<IRSFormDTO>
) => mutation.mutate(data, { onSuccess }) ) => mutation.mutate(data, { onSuccess })
}; };
}; };

View File

@ -1,7 +1,7 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { LibraryItemID, VersionID } from '@/models/library'; import { LibraryItemID, VersionID } from '@/models/library';
import { RSFormLoader } from '@/models/RSFormLoader'; import { RSFormLoader } from '@/backend/rsform/RSFormLoader';
import { queryClient } from '../queryClient'; import { queryClient } from '../queryClient';
import { rsformsApi } from './api'; import { rsformsApi } from './api';

View File

@ -1,7 +1,7 @@
import { useQueries } from '@tanstack/react-query'; import { useQueries } from '@tanstack/react-query';
import { LibraryItemID } from '@/models/library'; import { LibraryItemID } from '@/models/library';
import { RSFormLoader } from '@/models/RSFormLoader'; import { RSFormLoader } from '@/backend/rsform/RSFormLoader';
import { DELAYS } from '../configuration'; import { DELAYS } from '../configuration';
import { rsformsApi } from './api'; import { rsformsApi } from './api';

View File

@ -13,7 +13,7 @@ import Label from '@/components/ui/Label';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Modal from '@/components/ui/Modal'; import Modal from '@/components/ui/Modal';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
import { Grammeme, IWordForm, IWordFormPlain } from '@/models/language'; import { Grammeme, IWordForm } from '@/models/language';
import { parseGrammemes, wordFormEquals } from '@/models/languageAPI'; import { parseGrammemes, wordFormEquals } from '@/models/languageAPI';
import { HelpTopic } from '@/models/miscellaneous'; import { HelpTopic } from '@/models/miscellaneous';
import { IConstituenta, TermForm } from '@/models/rsform'; import { IConstituenta, TermForm } from '@/models/rsform';
@ -79,11 +79,13 @@ function DlgEditWordForms() {
} }
function handleInflect() { function handleInflect() {
const data: IWordFormPlain = { inflectText(
{
text: term, text: term,
grams: inputGrams.map(gram => gram.value).join(',') grams: inputGrams.map(gram => gram.value).join(',')
}; },
inflectText(data, response => setInputText(response.result)); response => setInputText(response.result)
);
} }
function handleParse() { function handleParse() {

View File

@ -214,21 +214,6 @@ export interface IWordForm {
grams: GramData[]; grams: GramData[];
} }
/**
* Represents wordform data used for backend communication.
*/
export interface IWordFormPlain {
text: string;
grams: string;
}
/**
* Represents lexeme response containing multiple {@link Wordform}s.
*/
export interface ILexemeData {
items: IWordFormPlain[];
}
// ====== Reference resolution ===== // ====== Reference resolution =====
/** /**
@ -270,11 +255,3 @@ export interface IReference {
type: ReferenceType; type: ReferenceType;
data: IEntityReference | ISyntacticReference; data: IEntityReference | ISyntacticReference;
} }
/**
* Represents single resolved reference data.
*/
export interface IResolvedReference extends IReference {
pos_input: ITextPosition;
pos_output: ITextPosition;
}

View File

@ -42,11 +42,6 @@ export interface IOperation {
arguments: OperationID[]; arguments: OperationID[];
} }
/**
* Represents {@link IOperation} data from server.
*/
export interface IOperationData extends Omit<IOperation, 'substitutions' | 'arguments'> {}
/** /**
* Represents {@link IOperation} position. * Represents {@link IOperation} position.
*/ */
@ -115,20 +110,14 @@ export interface IOperationSchemaStats {
count_owned: number; count_owned: number;
} }
/**
* Represents backend data for {@link IOperationSchema}.
*/
export interface IOperationSchemaData extends ILibraryItemData {
items: IOperationData[];
arguments: IArgument[];
substitutions: ICstSubstituteEx[];
}
/** /**
* Represents OperationSchema. * Represents OperationSchema.
*/ */
export interface IOperationSchema extends IOperationSchemaData { export interface IOperationSchema extends ILibraryItemData {
items: IOperation[]; items: IOperation[];
arguments: IArgument[];
substitutions: ICstSubstituteEx[];
graph: Graph; graph: Graph;
schemas: LibraryItemID[]; schemas: LibraryItemID[];
stats: IOperationSchemaStats; stats: IOperationSchemaStats;

View File

@ -2,6 +2,7 @@
* Module: API for OperationSystem. * Module: API for OperationSystem.
*/ */
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from '@/models/rsform';
import { limits } from '@/utils/constants'; import { limits } from '@/utils/constants';
import { describeSubstitutionError, information } from '@/utils/labels'; import { describeSubstitutionError, information } from '@/utils/labels';
import { TextMatcher } from '@/utils/utils'; import { TextMatcher } from '@/utils/utils';
@ -9,7 +10,6 @@ import { TextMatcher } from '@/utils/utils';
import { Graph } from './Graph'; import { Graph } from './Graph';
import { ILibraryItem, LibraryItemID } from './library'; import { ILibraryItem, LibraryItemID } from './library';
import { ICstSubstitute, IOperation, IOperationSchema, OperationID, SubstitutionErrorType } from './oss'; import { ICstSubstitute, IOperation, IOperationSchema, OperationID, SubstitutionErrorType } from './oss';
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from './rsform';
import { AliasMapping, ParsingStatus } from './rslang'; import { AliasMapping, ParsingStatus } from './rslang';
import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI'; import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI';
@ -49,7 +49,6 @@ export function sortItemsForOSS(oss: IOperationSchema, items: ILibraryItem[]): I
type CrossMapping = Map<LibraryItemID, AliasMapping>; type CrossMapping = Map<LibraryItemID, AliasMapping>;
// TODO: test validator
/** /**
* Validator for Substitution table. * Validator for Substitution table.
*/ */
@ -459,7 +458,6 @@ export function getRelocateCandidates(
const original = oss.substitutions.find(sub => sub.substitution === parent)?.original; const original = oss.substitutions.find(sub => sub.substitution === parent)?.original;
if (original) { if (original) {
continue; continue;
// TODO: test if original schema is destination schema
} }
} }
unreachableBases.push(cst.id); unreachableBases.push(cst.id);

View File

@ -83,9 +83,9 @@ export interface ITargetCst {
} }
/** /**
* Represents {@link IConstituenta} data from server. * Represents Constituenta.
*/ */
export interface IConstituentaData extends IConstituentaMeta { export interface IConstituenta extends IConstituentaMeta {
parse: { parse: {
status: ParsingStatus; status: ParsingStatus;
valueClass: ValueClass; valueClass: ValueClass;
@ -93,12 +93,7 @@ export interface IConstituentaData extends IConstituentaMeta {
syntaxTree: string; syntaxTree: string;
args: IArgumentInfo[]; args: IArgumentInfo[];
}; };
}
/**
* Represents Constituenta.
*/
export interface IConstituenta extends IConstituentaData {
/** {@link LibraryItemID} of this {@link IConstituenta}. */ /** {@link LibraryItemID} of this {@link IConstituenta}. */
schema: LibraryItemID; schema: LibraryItemID;
@ -172,27 +167,21 @@ export interface IRSFormStats {
/** /**
* Represents inheritance data for {@link IRSForm}. * Represents inheritance data for {@link IRSForm}.
*/ */
export interface IInheritanceData { export interface IInheritanceInfo {
child: ConstituentaID; child: ConstituentaID;
child_source: LibraryItemID; child_source: LibraryItemID;
parent: ConstituentaID; parent: ConstituentaID;
parent_source: LibraryItemID; parent_source: LibraryItemID;
} }
/**
* Represents data for {@link IRSForm} provided by backend.
*/
export interface IRSFormData extends ILibraryItemVersioned {
items: IConstituentaData[];
inheritance: IInheritanceData[];
oss: ILibraryItemReference[];
}
/** /**
* Represents formal explication for set of concepts. * Represents formal explication for set of concepts.
*/ */
export interface IRSForm extends IRSFormData { export interface IRSForm extends ILibraryItemVersioned {
items: IConstituenta[]; items: IConstituenta[];
inheritance: IInheritanceInfo[];
oss: ILibraryItemReference[];
stats: IRSFormStats; stats: IRSFormStats;
graph: Graph; graph: Graph;
cstByAlias: Map<string, IConstituenta>; cstByAlias: Map<string, IConstituenta>;