From 3e416564b554ce5b538c70b894ecb474e8796865 Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Mon, 11 Sep 2023 20:31:54 +0300 Subject: [PATCH] Restructure models files --- .../frontend/src/components/Help/HelpMain.tsx | 2 +- .../src/components/Help/InfoConstituenta.tsx | 2 +- .../components/Navigation/UserDropdown.tsx | 2 +- .../frontend/src/components/RSInput/index.tsx | 2 +- .../src/components/RSInput/textEditing.ts | 2 +- .../src/components/RSInput/tooltip.ts | 2 +- .../frontend/src/context/AuthContext.tsx | 7 +- .../frontend/src/context/LibraryContext.tsx | 5 +- .../frontend/src/context/RSFormContext.tsx | 12 +- .../src/context/UserProfileContext.tsx | 3 +- .../frontend/src/context/UsersContext.tsx | 2 +- .../frontend/src/hooks/useCheckExpression.ts | 5 +- .../frontend/src/hooks/useRSFormDetails.ts | 4 +- .../frontend/src/hooks/useResolveText.ts | 3 +- rsconcept/frontend/src/models/language.ts | 42 +++ rsconcept/frontend/src/models/library.ts | 65 ++++ rsconcept/frontend/src/models/miscelanious.ts | 80 ++++ .../src/{utils/models.ts => models/rsform.ts} | 344 +++--------------- rsconcept/frontend/src/models/rslang.ts | 245 +++++++++++++ .../frontend/src/pages/CreateRSFormPage.tsx | 3 +- .../src/pages/LibraryPage/PickerStrategy.tsx | 2 +- .../src/pages/LibraryPage/SearchPanel.tsx | 3 +- .../src/pages/LibraryPage/ViewLibrary.tsx | 2 +- .../frontend/src/pages/LibraryPage/index.tsx | 3 +- rsconcept/frontend/src/pages/LoginPage.tsx | 2 +- .../src/pages/ManualsPage/TopicsList.tsx | 2 +- .../src/pages/ManualsPage/ViewTopic.tsx | 2 +- .../frontend/src/pages/ManualsPage/index.tsx | 2 +- .../src/pages/RSFormPage/DlgCloneRSForm.tsx | 2 +- .../src/pages/RSFormPage/DlgCreateCst.tsx | 2 +- .../src/pages/RSFormPage/DlgEditTerm.tsx | 48 +++ .../src/pages/RSFormPage/DlgGraphOptions.tsx | 2 +- .../src/pages/RSFormPage/DlgRenameCst.tsx | 2 +- .../src/pages/RSFormPage/DlgShowAST.tsx | 2 +- .../src/pages/RSFormPage/DlgUploadRSForm.tsx | 2 +- .../pages/RSFormPage/EditorConstituenta.tsx | 44 ++- .../src/pages/RSFormPage/EditorItems.tsx | 2 +- .../pages/RSFormPage/EditorRSExpression.tsx | 5 +- .../src/pages/RSFormPage/EditorRSForm.tsx | 3 +- .../src/pages/RSFormPage/EditorTermGraph.tsx | 2 +- .../frontend/src/pages/RSFormPage/RSTabs.tsx | 48 ++- .../elements/ConstituentaTooltip.tsx | 2 +- .../elements/DependencyModePicker.tsx | 43 ++- .../RSFormPage/elements/MatchModePicker.tsx | 2 +- .../RSFormPage/elements/ParsingResult.tsx | 2 +- .../pages/RSFormPage/elements/RSFormStats.tsx | 2 +- .../RSFormPage/elements/RSLocalButton.tsx | 2 +- .../RSFormPage/elements/RSTokenButton.tsx | 2 +- .../pages/RSFormPage/elements/StatusBar.tsx | 4 +- .../elements/ViewSideConstituents.tsx | 5 +- rsconcept/frontend/src/pages/RegisterPage.tsx | 2 +- .../pages/UserProfilePage/EditorPassword.tsx | 2 +- .../pages/UserProfilePage/EditorProfile.tsx | 2 +- .../UserProfilePage/ViewSubscriptions.tsx | 2 +- rsconcept/frontend/src/utils/backendAPI.ts | 19 +- rsconcept/frontend/src/utils/enums.ts | 179 --------- rsconcept/frontend/src/utils/staticUI.ts | 166 ++++----- 57 files changed, 790 insertions(+), 660 deletions(-) create mode 100644 rsconcept/frontend/src/models/language.ts create mode 100644 rsconcept/frontend/src/models/library.ts create mode 100644 rsconcept/frontend/src/models/miscelanious.ts rename rsconcept/frontend/src/{utils/models.ts => models/rsform.ts} (59%) create mode 100644 rsconcept/frontend/src/models/rslang.ts create mode 100644 rsconcept/frontend/src/pages/RSFormPage/DlgEditTerm.tsx delete mode 100644 rsconcept/frontend/src/utils/enums.ts diff --git a/rsconcept/frontend/src/components/Help/HelpMain.tsx b/rsconcept/frontend/src/components/Help/HelpMain.tsx index 536f20ab..3ba827e8 100644 --- a/rsconcept/frontend/src/components/Help/HelpMain.tsx +++ b/rsconcept/frontend/src/components/Help/HelpMain.tsx @@ -1,5 +1,5 @@ +import { LibraryFilterStrategy } from '../../models/miscelanious'; import { urls } from '../../utils/constants'; -import { LibraryFilterStrategy } from '../../utils/models'; import TextURL from '../Common/TextURL'; function HelpMain() { diff --git a/rsconcept/frontend/src/components/Help/InfoConstituenta.tsx b/rsconcept/frontend/src/components/Help/InfoConstituenta.tsx index 6dc228b5..ce1b816a 100644 --- a/rsconcept/frontend/src/components/Help/InfoConstituenta.tsx +++ b/rsconcept/frontend/src/components/Help/InfoConstituenta.tsx @@ -1,4 +1,4 @@ -import { IConstituenta } from '../../utils/models'; +import { IConstituenta } from '../../models/rsform'; import { getCstTypificationLabel } from '../../utils/staticUI'; interface InfoConstituentaProps diff --git a/rsconcept/frontend/src/components/Navigation/UserDropdown.tsx b/rsconcept/frontend/src/components/Navigation/UserDropdown.tsx index e91d8e8e..a1aa22c1 100644 --- a/rsconcept/frontend/src/components/Navigation/UserDropdown.tsx +++ b/rsconcept/frontend/src/components/Navigation/UserDropdown.tsx @@ -1,7 +1,7 @@ import { useAuth } from '../../context/AuthContext'; import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptTheme } from '../../context/ThemeContext'; -import { LibraryFilterStrategy } from '../../utils/models'; +import { LibraryFilterStrategy } from '../../models/miscelanious'; import Dropdown from '../Common/Dropdown'; import DropdownButton from '../Common/DropdownButton'; diff --git a/rsconcept/frontend/src/components/RSInput/index.tsx b/rsconcept/frontend/src/components/RSInput/index.tsx index f8dfef1b..6a9f4fd8 100644 --- a/rsconcept/frontend/src/components/RSInput/index.tsx +++ b/rsconcept/frontend/src/components/RSInput/index.tsx @@ -8,7 +8,7 @@ import { RefObject, useCallback, useMemo, useRef } from 'react'; import { useRSForm } from '../../context/RSFormContext'; import { useConceptTheme } from '../../context/ThemeContext'; -import { TokenID } from '../../utils/enums'; +import { TokenID } from '../../models/rslang'; import Label from '../Common/Label'; import { ccBracketMatching } from './bracketMatching'; import { RSLanguage } from './rslang'; diff --git a/rsconcept/frontend/src/components/RSInput/textEditing.ts b/rsconcept/frontend/src/components/RSInput/textEditing.ts index 5926b1b3..bb8ce496 100644 --- a/rsconcept/frontend/src/components/RSInput/textEditing.ts +++ b/rsconcept/frontend/src/components/RSInput/textEditing.ts @@ -2,7 +2,7 @@ import { ReactCodeMirrorRef } from '@uiw/react-codemirror'; -import { TokenID } from '../../utils/enums'; +import { TokenID } from '../../models/rslang'; export function getSymbolSubstitute(keyCode: string, shiftPressed: boolean): string | undefined { if (shiftPressed) { diff --git a/rsconcept/frontend/src/components/RSInput/tooltip.ts b/rsconcept/frontend/src/components/RSInput/tooltip.ts index df1b9bc2..e645d98e 100644 --- a/rsconcept/frontend/src/components/RSInput/tooltip.ts +++ b/rsconcept/frontend/src/components/RSInput/tooltip.ts @@ -1,7 +1,7 @@ import { Extension } from '@codemirror/state'; import { hoverTooltip } from '@codemirror/view'; -import { IConstituenta } from '../../utils/models'; +import { IConstituenta } from '../../models/rsform'; import { getCstTypificationLabel } from '../../utils/staticUI'; function createTooltipFor(cst: IConstituenta) { diff --git a/rsconcept/frontend/src/context/AuthContext.tsx b/rsconcept/frontend/src/context/AuthContext.tsx index 735470ff..228df7ba 100644 --- a/rsconcept/frontend/src/context/AuthContext.tsx +++ b/rsconcept/frontend/src/context/AuthContext.tsx @@ -2,8 +2,13 @@ import { createContext, useCallback, useContext, useLayoutEffect, useState } fro import { type ErrorInfo } from '../components/BackendError'; import useLocalStorage from '../hooks/useLocalStorage'; +import { IUserLoginData } from '../models/library'; +import { ICurrentUser } from '../models/library'; +import { IUserSignupData } from '../models/library'; +import { IUserProfile } from '../models/library'; +import { IUserInfo } from '../models/library'; +import { IUserUpdatePassword } from '../models/library'; import { type DataCallback, getAuth, patchPassword,postLogin, postLogout, postSignup } from '../utils/backendAPI'; -import { ICurrentUser, IUserInfo, IUserLoginData, IUserProfile, IUserSignupData, IUserUpdatePassword } from '../utils/models'; import { useUsers } from './UsersContext'; interface IAuthContext { diff --git a/rsconcept/frontend/src/context/LibraryContext.tsx b/rsconcept/frontend/src/context/LibraryContext.tsx index db4b3ae0..9a5436bf 100644 --- a/rsconcept/frontend/src/context/LibraryContext.tsx +++ b/rsconcept/frontend/src/context/LibraryContext.tsx @@ -1,8 +1,11 @@ import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { ErrorInfo } from '../components/BackendError'; +import { ILibraryFilter } from '../models/miscelanious'; +import { IRSFormCreateData, IRSFormData } from '../models/rsform'; +import { matchLibraryItem } from '../models/library'; +import { ILibraryItem } from '../models/library'; import { DataCallback, deleteLibraryItem, getLibrary, postCloneLibraryItem, postNewRSForm } from '../utils/backendAPI'; -import { ILibraryFilter, ILibraryItem, IRSFormCreateData, IRSFormData, matchLibraryItem } from '../utils/models'; import { useAuth } from './AuthContext'; interface ILibraryContext { diff --git a/rsconcept/frontend/src/context/RSFormContext.tsx b/rsconcept/frontend/src/context/RSFormContext.tsx index 990a3305..5a22dea5 100644 --- a/rsconcept/frontend/src/context/RSFormContext.tsx +++ b/rsconcept/frontend/src/context/RSFormContext.tsx @@ -2,6 +2,13 @@ import { createContext, useCallback, useContext, useMemo, useState } from 'react import { type ErrorInfo } from '../components/BackendError' import { useRSFormDetails } from '../hooks/useRSFormDetails' +import { ILibraryItem } from '../models/library' +import { + IConstituentaList, IConstituentaMeta, ICstCreateData, + ICstMovetoData, ICstRenameData, ICstUpdateData, + IRSForm, IRSFormUploadData +} from '../models/rsform' +import { ILibraryUpdateData } from '../models/library' import { type DataCallback, deleteUnsubscribe, getTRSFile, @@ -9,11 +16,6 @@ getTRSFile, patchLibraryItem, patchMoveConstituenta, patchRenameConstituenta, patchResetAliases, patchUploadTRS, postClaimLibraryItem, postNewConstituenta, postSubscribe} from '../utils/backendAPI' -import { - IConstituentaList, IConstituentaMeta, ICstCreateData, - ICstMovetoData, ICstRenameData, ICstUpdateData, ILibraryItem, - ILibraryUpdateData, IRSForm, IRSFormUploadData -} from '../utils/models' import { useAuth } from './AuthContext' import { useLibrary } from './LibraryContext' diff --git a/rsconcept/frontend/src/context/UserProfileContext.tsx b/rsconcept/frontend/src/context/UserProfileContext.tsx index ad67b40f..3bfa5d36 100644 --- a/rsconcept/frontend/src/context/UserProfileContext.tsx +++ b/rsconcept/frontend/src/context/UserProfileContext.tsx @@ -1,8 +1,9 @@ import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { ErrorInfo } from '../components/BackendError'; +import { IUserProfile } from '../models/library'; +import { IUserUpdateData } from '../models/library'; import { DataCallback, getProfile, patchProfile } from '../utils/backendAPI'; -import { IUserProfile, IUserUpdateData } from '../utils/models'; import { useUsers } from './UsersContext'; interface IUserProfileContext { diff --git a/rsconcept/frontend/src/context/UsersContext.tsx b/rsconcept/frontend/src/context/UsersContext.tsx index aa093f5e..c8fd1ee2 100644 --- a/rsconcept/frontend/src/context/UsersContext.tsx +++ b/rsconcept/frontend/src/context/UsersContext.tsx @@ -1,7 +1,7 @@ import { createContext, useCallback, useContext, useEffect, useState } from 'react'; +import { type IUserInfo } from '../models/library'; import { getActiveUsers } from '../utils/backendAPI'; -import { type IUserInfo } from '../utils/models'; interface IUsersContext { users: IUserInfo[] diff --git a/rsconcept/frontend/src/hooks/useCheckExpression.ts b/rsconcept/frontend/src/hooks/useCheckExpression.ts index aa2646ea..736688d8 100644 --- a/rsconcept/frontend/src/hooks/useCheckExpression.ts +++ b/rsconcept/frontend/src/hooks/useCheckExpression.ts @@ -1,9 +1,10 @@ import { useCallback, useState } from 'react' import { type ErrorInfo } from '../components/BackendError'; +import { CstType, IConstituenta, type IRSForm } from '../models/rsform'; +import { IExpressionParse, IFunctionArg } from '../models/rslang'; +import { RSErrorType } from '../models/rslang'; import { DataCallback, postCheckExpression } from '../utils/backendAPI'; -import { RSErrorType } from '../utils/enums'; -import { CstType, IConstituenta, IExpressionParse, IFunctionArg, type IRSForm } from '../utils/models'; import { getCstExpressionPrefix } from '../utils/staticUI'; const LOGIC_TYPIIFCATION = 'LOGIC'; diff --git a/rsconcept/frontend/src/hooks/useRSFormDetails.ts b/rsconcept/frontend/src/hooks/useRSFormDetails.ts index 9b5e1d50..d5ac56be 100644 --- a/rsconcept/frontend/src/hooks/useRSFormDetails.ts +++ b/rsconcept/frontend/src/hooks/useRSFormDetails.ts @@ -1,8 +1,8 @@ import { useCallback, useEffect, useState } from 'react' import { type ErrorInfo } from '../components/BackendError'; +import { IRSForm, IRSFormData,loadRSFormData } from '../models/rsform' import { getRSFormDetails } from '../utils/backendAPI'; -import { IRSForm, IRSFormData,LoadRSFormData } from '../utils/models' export function useRSFormDetails({ target }: { target?: string }) { const [schema, setInnerSchema] = useState(undefined); @@ -14,7 +14,7 @@ export function useRSFormDetails({ target }: { target?: string }) { setInnerSchema(undefined); return; } - const schema = LoadRSFormData(data); + const schema = loadRSFormData(data); setInnerSchema(schema); } diff --git a/rsconcept/frontend/src/hooks/useResolveText.ts b/rsconcept/frontend/src/hooks/useResolveText.ts index 90d38c86..b1b42bc4 100644 --- a/rsconcept/frontend/src/hooks/useResolveText.ts +++ b/rsconcept/frontend/src/hooks/useResolveText.ts @@ -1,8 +1,9 @@ import { useCallback, useState } from 'react' import { ErrorInfo } from '../components/BackendError'; +import { IReferenceData } from '../models/language'; +import { IRSForm } from '../models/rsform'; import { DataCallback, postResolveText } from '../utils/backendAPI'; -import { IReferenceData,IRSForm } from '../utils/models'; function useResolveText({ schema }: { schema?: IRSForm }) { const [loading, setLoading] = useState(false); diff --git a/rsconcept/frontend/src/models/language.ts b/rsconcept/frontend/src/models/language.ts new file mode 100644 index 00000000..361ec30c --- /dev/null +++ b/rsconcept/frontend/src/models/language.ts @@ -0,0 +1,42 @@ +// Module: Natural language model declarations. + + +// ====== Text morphology ======== + + +// ====== Reference resolution ===== +export interface IRefsText { + text: string +} + +export enum ReferenceType { + ENTITY = 'entity', + SYNTACTIC = 'syntax' +} +export interface IEntityReference { + entity: string + form: string +} + +export interface ISyntacticReference { + offset: number + nominal: string +} + +export interface ITextPosition { + start: number + finish: number +} + +export interface IResolvedReference { + type: ReferenceType + data: IEntityReference | ISyntacticReference + pos_input: ITextPosition + pos_output: ITextPosition +} + +export interface IReferenceData { + input: string + output: string + refs: IResolvedReference[] +} diff --git a/rsconcept/frontend/src/models/library.ts b/rsconcept/frontend/src/models/library.ts new file mode 100644 index 00000000..d18a025c --- /dev/null +++ b/rsconcept/frontend/src/models/library.ts @@ -0,0 +1,65 @@ +// Module: Schema library models. + +// ========= Users =========== +export interface IUser { + id: number | null + username: string + is_staff: boolean + email: string + first_name: string + last_name: string +} +export interface ICurrentUser extends Pick { + subscriptions: number[] +} +export interface IUserLoginData extends Pick { + password: string +} +export interface IUserSignupData extends Omit { + password: string + password2: string +} +export interface IUserUpdateData extends Omit { } + +export interface IUserProfile extends Omit { } +export interface IUserInfo extends Omit { } +export interface IUserUpdatePassword { + old_password: string + new_password: string +} + +// ========== LibraryItem ============ +export enum LibraryItemType { + RSFORM = 'rsform', + OPERATIONS_SCHEMA = 'oss' +} + +export interface ILibraryItem { + id: number + item_type: LibraryItemType + title: string + alias: string + comment: string + is_common: boolean + is_canonical: boolean + time_create: string + time_update: string + owner: number | null +} + +export interface ILibraryUpdateData + extends Omit { +} + +// ============= API =============== +export function matchLibraryItem(query: string, target: ILibraryItem): boolean { + const queryI = query.toUpperCase() + if (target.alias.toUpperCase().match(queryI)) { + return true + } else if (target.title.toUpperCase().match(queryI)) { + return true + } else { + return false + } +} + diff --git a/rsconcept/frontend/src/models/miscelanious.ts b/rsconcept/frontend/src/models/miscelanious.ts new file mode 100644 index 00000000..82d0d467 --- /dev/null +++ b/rsconcept/frontend/src/models/miscelanious.ts @@ -0,0 +1,80 @@ +// Module: Miscellanious frontend model types. + +import { IConstituenta, IRSForm } from './rsform' + +// Constituenta edit mode +export enum EditMode { + TEXT = 'text', + RSLANG = 'rslang' +} + +// Dependency mode for schema analysis +export enum DependencyMode { + ALL = 0, + EXPRESSION, + OUTPUTS, + INPUTS, + EXPAND_OUTPUTS, + EXPAND_INPUTS +} + +// Help manual topic compare mode +export enum HelpTopic { + MAIN = 'main', + RSLANG = 'rslang', + LIBRARY = 'library', + RSFORM = 'rsform', + CSTLIST = 'cstlist', + CONSTITUENTA = 'constituenta', + GRAPH_TERM = 'graph-term', + EXTEOR = 'exteor', + API = 'api' +} + +// Constituent compare mode +export enum CstMatchMode { + ALL = 1, + EXPR, + TERM, + TEXT, + NAME +} + +export interface ILibraryFilter { + query?: string + is_personal?: boolean + is_owned?: boolean + is_common?: boolean + is_canonical?: boolean + is_subscribed?: boolean +} + +// Library premade filters +export enum LibraryFilterStrategy { + MANUAL = 'manual', + PERSONAL = 'personal', + COMMON = 'common', + SUBSCRIBE = 'subscribe', + CANONICAL = 'canonical', + OWNED = 'owned' +} + +// ================== API ==================== +export function applyGraphFilter(schema: IRSForm, start: number, mode: DependencyMode): IConstituenta[] { + if (mode === DependencyMode.ALL) { + return schema.items + } + let ids: number[] | undefined = undefined + switch (mode) { + case DependencyMode.OUTPUTS: { ids = schema.graph.nodes.get(start)?.outputs; break} + case DependencyMode.INPUTS: { ids = schema.graph.nodes.get(start)?.inputs; break} + case DependencyMode.EXPAND_OUTPUTS: { ids = schema.graph.expandOutputs([start]); break} + case DependencyMode.EXPAND_INPUTS: { ids = schema.graph.expandInputs([start]); break} + } + if (!ids) { + return schema.items + } else { + return schema.items.filter(cst => ids!.find(id => id === cst.id)) + } +} + diff --git a/rsconcept/frontend/src/utils/models.ts b/rsconcept/frontend/src/models/rsform.ts similarity index 59% rename from rsconcept/frontend/src/utils/models.ts rename to rsconcept/frontend/src/models/rsform.ts index 332cef82..597ae5fa 100644 --- a/rsconcept/frontend/src/utils/models.ts +++ b/rsconcept/frontend/src/models/rsform.ts @@ -1,135 +1,9 @@ -import { RSErrorType, TokenID } from './enums' -import { Graph } from './Graph' +import { Graph } from '../utils/Graph' +import { ILibraryUpdateData } from './library' +import { ILibraryItem } from './library' +import { CstMatchMode } from './miscelanious' +import { IFunctionArg, ParsingStatus, ValueClass } from './rslang' -// ========= Users =========== -export interface IUser { - id: number | null - username: string - is_staff: boolean - email: string - first_name: string - last_name: string -} - -export interface ICurrentUser extends Pick { - subscriptions: number[] -} - -export interface IUserLoginData extends Pick { - password: string -} - -export interface IUserSignupData extends Omit { - password: string - password2: string -} -export interface IUserUpdateData extends Omit {} -export interface IUserProfile extends Omit {} -export interface IUserInfo extends Omit {} - -export interface IUserUpdatePassword { - old_password: string - new_password: string -} - -// ======== RS Parsing ============ -export interface IRSExpression { - expression: string -} - -export enum Syntax { - UNDEF = 'undefined', - ASCII = 'ascii', - MATH = 'math' -} - -export enum ValueClass { - INVALID = 'invalid', - VALUE = 'value', - PROPERTY = 'property' -} - -export enum ParsingStatus { - UNDEF = 'undefined', - VERIFIED = 'verified', - INCORRECT = 'incorrect' -} - -export interface IRSErrorDescription { - errorType: RSErrorType - position: number - isCritical: boolean - params: string[] -} - -export interface ISyntaxTreeNode { - uid: number - parent: number - typeID: TokenID - start: number - finish: number - data: { - dataType: string, - value: unknown - } -} -export type SyntaxTree = ISyntaxTreeNode[] - -export interface IFunctionArg { - alias: string - typification: string -} - -export interface IExpressionParse { - parseResult: boolean - syntax: Syntax - typification: string - valueClass: ValueClass - errors: IRSErrorDescription[] - astText: string - ast: SyntaxTree - args: IFunctionArg[] -} - -// ====== Reference resolution ===== -export interface IRefsText { - text: string -} - -export enum ReferenceType { - ENTITY = 'entity', - SYNTACTIC = 'syntax' -} - -export interface IEntityReference { - entity: string - form: string -} - -export interface ISyntacticReference { - offset: number - nominal: string -} - -export interface ITextPosition { - start: number - finish: number -} - -export interface IResolvedReference { - type: ReferenceType - data: IEntityReference | ISyntacticReference - pos_input: ITextPosition - pos_output: ITextPosition -} - -export interface IReferenceData { - input: string - output: string - refs: IResolvedReference[] -} - -// ====== Constituenta ========== export enum CstType { BASE = 'basic', STRUCTURED = 'structure', @@ -148,11 +22,22 @@ export enum CstClass { TEMPLATE = 'template' } +// Constituenta expression status +export enum ExpressionStatus { + UNDEFINED = 'undefined', + UNKNOWN = 'unknown', + INCORRECT = 'incorrect', + INCALCULABLE = 'incalculable', + PROPERTY = 'property', + VERIFIED = 'verified' +} + export interface TermForm { text: string tags: string } +// ====== Constituenta ========== export interface IConstituentaMeta { id: number schema: number @@ -207,29 +92,6 @@ export interface ICstCreatedResponse { schema: IRSFormData } -// ========== LibraryItem ============ -export enum LibraryItemType { - RSFORM = 'rsform', - OPERATIONS_SCHEMA = 'oss' -} - -export interface ILibraryItem { - id: number - item_type: LibraryItemType - title: string - alias: string - comment: string - is_common: boolean - is_canonical: boolean - time_create: string - time_update: string - owner: number | null -} - -export interface ILibraryUpdateData -extends Omit {} - - // ========== RSForm ============ export interface IRSFormStats { count_all: number @@ -273,120 +135,12 @@ export interface IRSFormUploadData { fileName: string } -// ========== Library ===== -export enum LibraryFilterStrategy { - MANUAL = 'manual', - PERSONAL = 'personal', - COMMON = 'common', - SUBSCRIBE = 'subscribe', - CANONICAL = 'canonical', - OWNED = 'owned' -} - -export interface ILibraryFilter { - query?: string - is_personal?: boolean - is_owned?: boolean - is_common?: boolean - is_canonical?: boolean - is_subscribed?: boolean -} - -// ================ Misc types ================ -// Constituenta edit mode -export enum EditMode { - TEXT = 'text', - RSLANG = 'rslang' -} - -// RSExpression status -export enum ExpressionStatus { - UNDEFINED = 'undefined', - UNKNOWN = 'unknown', - INCORRECT = 'incorrect', - INCALCULABLE = 'incalculable', - PROPERTY = 'property', - VERIFIED = 'verified' -} - -// Dependency mode for schema analysis -export enum DependencyMode { - ALL = 0, - EXPRESSION, - OUTPUTS, - INPUTS, - EXPAND_OUTPUTS, - EXPAND_INPUTS -} - -// Constituent compare mode -export enum CstMatchMode { - ALL = 1, - EXPR, - TERM, - TEXT, - NAME -} - -// Help manual topic compare mode -export enum HelpTopic { - MAIN = 'main', - RSLANG = 'rslang', - LIBRARY = 'library', - RSFORM = 'rsform', - CSTLIST = 'cstlist', - CONSTITUENTA = 'constituenta', - GRAPH_TERM = 'graph-term', - EXTEOR = 'exteor', - API = 'api' -} - -// ========== Model functions ================= -export function inferStatus(parse?: ParsingStatus, value?: ValueClass): ExpressionStatus { - if (!parse || !value) { - return ExpressionStatus.UNDEFINED; - } - if (parse === ParsingStatus.UNDEF) { - return ExpressionStatus.UNKNOWN; - } - if (parse === ParsingStatus.INCORRECT) { - return ExpressionStatus.INCORRECT; - } - if (value === ValueClass.INVALID) { - return ExpressionStatus.INCALCULABLE; - } - if (value === ValueClass.PROPERTY) { - return ExpressionStatus.PROPERTY; - } - return ExpressionStatus.VERIFIED; -} - -export function inferTemplate(expression: string): boolean { - const match = expression.match(/R\d+/g); - return (match && match?.length > 0) ?? false; -} - -export function inferClass(type: CstType, isTemplate: boolean): CstClass { - if (isTemplate) { - return CstClass.TEMPLATE; - } - switch (type) { - case CstType.BASE: return CstClass.BASIC; - case CstType.CONSTANT: return CstClass.BASIC; - case CstType.STRUCTURED: return CstClass.BASIC; - case CstType.TERM: return CstClass.DERIVED; - case CstType.FUNCTION: return CstClass.DERIVED; - case CstType.AXIOM: return CstClass.STATEMENT; - case CstType.PREDICATE: return CstClass.DERIVED; - case CstType.THEOREM: return CstClass.STATEMENT; - } -} - +// ========== API ================= export function extractGlobals(expression: string): Set { return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []); } -export function LoadRSFormData(schema: IRSFormData): IRSForm { +export function loadRSFormData(schema: IRSFormData): IRSForm { const result = schema as IRSForm result.graph = new Graph; if (!result.items) { @@ -480,31 +234,43 @@ export function matchConstituenta(query: string, target: IConstituenta, mode: Cs return false; } -export function matchLibraryItem(query: string, target: ILibraryItem): boolean { - const queryI = query.toUpperCase(); - if (target.alias.toUpperCase().match(queryI)) { - return true; - } else if (target.title.toUpperCase().match(queryI)) { - return true; - } else { - return false; +export function inferStatus(parse?: ParsingStatus, value?: ValueClass): ExpressionStatus { + if (!parse || !value) { + return ExpressionStatus.UNDEFINED; + } + if (parse === ParsingStatus.UNDEF) { + return ExpressionStatus.UNKNOWN; + } + if (parse === ParsingStatus.INCORRECT) { + return ExpressionStatus.INCORRECT; + } + if (value === ValueClass.INVALID) { + return ExpressionStatus.INCALCULABLE; + } + if (value === ValueClass.PROPERTY) { + return ExpressionStatus.PROPERTY; + } + return ExpressionStatus.VERIFIED; +} + +export function inferTemplate(expression: string): boolean { + const match = expression.match(/R\d+/g); + return (match && match?.length > 0) ?? false; +} + +export function inferClass(type: CstType, isTemplate: boolean): CstClass { + if (isTemplate) { + return CstClass.TEMPLATE; + } + switch (type) { + case CstType.BASE: return CstClass.BASIC; + case CstType.CONSTANT: return CstClass.BASIC; + case CstType.STRUCTURED: return CstClass.BASIC; + case CstType.TERM: return CstClass.DERIVED; + case CstType.FUNCTION: return CstClass.DERIVED; + case CstType.AXIOM: return CstClass.STATEMENT; + case CstType.PREDICATE: return CstClass.DERIVED; + case CstType.THEOREM: return CstClass.STATEMENT; } } -export function applyGraphFilter(schema: IRSForm, start: number, mode: DependencyMode): IConstituenta[] { - if (mode === DependencyMode.ALL) { - return schema.items; - } - let ids: number[] | undefined = undefined - switch (mode) { - case DependencyMode.OUTPUTS: { ids = schema.graph.nodes.get(start)?.outputs; break; } - case DependencyMode.INPUTS: { ids = schema.graph.nodes.get(start)?.inputs; break; } - case DependencyMode.EXPAND_OUTPUTS: { ids = schema.graph.expandOutputs([start]) ; break; } - case DependencyMode.EXPAND_INPUTS: { ids = schema.graph.expandInputs([start]) ; break; } - } - if (!ids) { - return schema.items; - } else { - return schema.items.filter(cst => ids!.find(id => id === cst.id)); - } -} \ No newline at end of file diff --git a/rsconcept/frontend/src/models/rslang.ts b/rsconcept/frontend/src/models/rslang.ts new file mode 100644 index 00000000..79bfb581 --- /dev/null +++ b/rsconcept/frontend/src/models/rslang.ts @@ -0,0 +1,245 @@ +// Module: RSLang model types + +// ======== RS Parsing ============ +export interface IRSExpression { + expression: string +} + +export enum Syntax { + UNDEF = 'undefined', + ASCII = 'ascii', + MATH = 'math' +} + +export enum ValueClass { + INVALID = 'invalid', + VALUE = 'value', + PROPERTY = 'property' +} + +export enum ParsingStatus { + UNDEF = 'undefined', + VERIFIED = 'verified', + INCORRECT = 'incorrect' +} + +export interface IRSErrorDescription { + errorType: RSErrorType + position: number + isCritical: boolean + params: string[] +} + +export interface ISyntaxTreeNode { + uid: number + parent: number + typeID: TokenID + start: number + finish: number + data: { + dataType: string + value: unknown + } +} +export type SyntaxTree = ISyntaxTreeNode[] + +export interface IFunctionArg { + alias: string + typification: string +} + +export interface IExpressionParse { + parseResult: boolean + syntax: Syntax + typification: string + valueClass: ValueClass + errors: IRSErrorDescription[] + astText: string + ast: SyntaxTree + args: IFunctionArg[] +} + +//! RS language token types enumeration +export enum TokenID { + // Global, local IDs and literals + ID_LOCAL = 258, + ID_GLOBAL, + ID_FUNCTION, + ID_PREDICATE, + ID_RADICAL, + LIT_INTEGER, + LIT_INTSET, + LIT_EMPTYSET, + + // Aithmetic + PLUS, + MINUS, + MULTIPLY, + + // Integer predicate symbols + GREATER, + LESSER, + GREATER_OR_EQ, + LESSER_OR_EQ, + + // Equality comparison + EQUAL, + NOTEQUAL, + + // Logic predicate symbols + FORALL, + EXISTS, + NOT, + EQUIVALENT, + IMPLICATION, + OR, + AND, + + // Set theory predicate symbols + IN, + NOTIN, + SUBSET, + SUBSET_OR_EQ, + NOTSUBSET, + + // Set theory operators + DECART, + UNION, + INTERSECTION, + SET_MINUS, + SYMMINUS, + BOOLEAN, + + // Structure operations + BIGPR, + SMALLPR, + FILTER, + CARD, + BOOL, + DEBOOL, + REDUCE, + + // Term constructions prefixes + DECLARATIVE, + RECURSIVE, + IMPERATIVE, + + // Punctuation + PUNC_DEFINE, + PUNC_STRUCT, + PUNC_ASSIGN, + PUNC_ITERATE, + PUNC_PL, + PUNC_PR, + PUNC_CL, + PUNC_CR, + PUNC_SL, + PUNC_SR, + PUNC_BAR, + PUNC_COMMA, + PUNC_SEMICOLON, + + // ======= Non-terminal tokens ========= + NT_ENUM_DECL, + NT_TUPLE, + NT_ENUMERATION, + NT_TUPLE_DECL, + NT_ARG_DECL, + + NT_FUNC_DEFINITION, + NT_ARGUMENTS, + NT_FUNC_CALL, + + NT_DECLARATIVE_EXPR, + NT_IMPERATIVE_EXPR, + NT_RECURSIVE_FULL, + NT_RECURSIVE_SHORT, + + NT_IMP_DECLARE, + NT_IMP_ASSIGN, + NT_IMP_LOGIC, + + + // ======= Helper tokens ======== + INTERRUPT, + END +} + +export enum RSErrorType { + syntax = 33792, + missingParanthesis = 33798, + missingCurlyBrace = 33799, + invalidQuantifier = 33800, + expectedArgDeclaration = 33812, + expectedLocal = 33813, + localDoubleDeclare = 10241, + localNotUsed = 10242, + + localUndeclared = 34817, + localShadowing = 34818, + + typesNotEqual = 34819, + globalNotTyped = 34820, + invalidDecart = 34821, + invalidBoolean = 34822, + invalidTypeOperation = 34823, + invalidCard = 34824, + invalidDebool = 34825, + globalFuncMissing = 34826, + globalFuncWithoutArgs = 34827, + invalidReduce = 34832, + invalidProjectionTuple = 34833, + invalidProjectionSet = 34834, + invalidEnumeration = 34835, + ivalidBinding = 34836, + localOutOfScope = 34837, + invalidElementPredicat = 34838, + invalidArgsArtity = 34840, + invalidArgumentType = 34841, + invalidEqualsEmpty = 34842, + globalStructure = 34844, + globalExpectedFunction = 34847, + emptySetUsage = 34848, + radicalUsage = 34849, + invalidFilterArgumentType = 34850, + invalidFilterArity = 34851, + arithmeticNotSupported = 34852, + typesNotCompatible = 34853, + orderingNotSupported = 34854, + + + // !!!! Добавлены по сравнению с ConceptCore !!!!! + globalNonemptyBase = 34855, + globalUnexpectedType = 34856, + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + globalNoValue = 34880, + invalidPropertyUsage = 34881, + globalMissingAST = 34882, + globalFuncNoInterpretation = 34883 +} + +// Error handling +export enum RSErrorClass { + LEXER, + PARSER, + SEMANTIC, + UNKNOWN +} + +const ERRCODE_LEXER_MASK = 512; +const ERRCODE_PARSER_MASK = 1024; +const ERRCODE_TYPE_MASK = 2048; + +export function resolveErrorClass(error: RSErrorType): RSErrorClass { + if ((error & ERRCODE_LEXER_MASK) !== 0) { + return RSErrorClass.LEXER; + } else if ((error & ERRCODE_PARSER_MASK) !== 0) { + return RSErrorClass.PARSER; + } else if ((error & ERRCODE_TYPE_MASK) !== 0) { + return RSErrorClass.SEMANTIC; + } else { + return RSErrorClass.UNKNOWN; + } +} diff --git a/rsconcept/frontend/src/pages/CreateRSFormPage.tsx b/rsconcept/frontend/src/pages/CreateRSFormPage.tsx index 2cb13bdf..9faee7b6 100644 --- a/rsconcept/frontend/src/pages/CreateRSFormPage.tsx +++ b/rsconcept/frontend/src/pages/CreateRSFormPage.tsx @@ -15,8 +15,9 @@ import { UploadIcon } from '../components/Icons'; import RequireAuth from '../components/RequireAuth'; import { useLibrary } from '../context/LibraryContext'; import { useConceptNavigation } from '../context/NagivationContext'; +import { LibraryItemType } from '../models/library'; +import { IRSFormCreateData } from '../models/rsform'; import { EXTEOR_TRS_FILE } from '../utils/constants'; -import { IRSFormCreateData, LibraryItemType } from '../utils/models'; function CreateRSFormPage() { const location = useLocation(); diff --git a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx index 9b7e74f3..c2007bee 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/PickerStrategy.tsx @@ -6,7 +6,7 @@ import DropdownCheckbox from '../../components/Common/DropdownCheckbox'; import { FilterCogIcon } from '../../components/Icons'; import { useAuth } from '../../context/AuthContext'; import useDropdown from '../../hooks/useDropdown'; -import { LibraryFilterStrategy } from '../../utils/models'; +import { LibraryFilterStrategy } from '../../models/miscelanious'; interface PickerStrategyProps { value: LibraryFilterStrategy diff --git a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx index 19e5d456..bb7d0716 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/SearchPanel.tsx @@ -5,7 +5,8 @@ import { MagnifyingGlassIcon } from '../../components/Icons'; import { useAuth } from '../../context/AuthContext'; import { useConceptNavigation } from '../../context/NagivationContext'; import useLocalStorage from '../../hooks/useLocalStorage'; -import { ILibraryFilter, LibraryFilterStrategy } from '../../utils/models'; +import { ILibraryFilter } from '../../models/miscelanious'; +import { LibraryFilterStrategy } from '../../models/miscelanious'; import PickerStrategy from './PickerStrategy'; diff --git a/rsconcept/frontend/src/pages/LibraryPage/ViewLibrary.tsx b/rsconcept/frontend/src/pages/LibraryPage/ViewLibrary.tsx index 29226b04..e3f9b690 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/ViewLibrary.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/ViewLibrary.tsx @@ -10,8 +10,8 @@ import { useAuth } from '../../context/AuthContext'; import { useConceptNavigation } from '../../context/NagivationContext'; import { useUsers } from '../../context/UsersContext'; import useLocalStorage from '../../hooks/useLocalStorage'; +import { ILibraryItem } from '../../models/library'; import { prefixes } from '../../utils/constants'; -import { ILibraryItem } from '../../utils/models'; interface ViewLibraryProps { items: ILibraryItem[] diff --git a/rsconcept/frontend/src/pages/LibraryPage/index.tsx b/rsconcept/frontend/src/pages/LibraryPage/index.tsx index 26de66bc..83ea9eb1 100644 --- a/rsconcept/frontend/src/pages/LibraryPage/index.tsx +++ b/rsconcept/frontend/src/pages/LibraryPage/index.tsx @@ -4,7 +4,8 @@ import BackendError from '../../components/BackendError' import { ConceptLoader } from '../../components/Common/ConceptLoader' import { useLibrary } from '../../context/LibraryContext'; import { useConceptTheme } from '../../context/ThemeContext'; -import { ILibraryFilter, ILibraryItem } from '../../utils/models'; +import { ILibraryItem } from '../../models/library'; +import { ILibraryFilter } from '../../models/miscelanious'; import SearchPanel from './SearchPanel'; import ViewLibrary from './ViewLibrary'; diff --git a/rsconcept/frontend/src/pages/LoginPage.tsx b/rsconcept/frontend/src/pages/LoginPage.tsx index 3a88df9b..ee7e7856 100644 --- a/rsconcept/frontend/src/pages/LoginPage.tsx +++ b/rsconcept/frontend/src/pages/LoginPage.tsx @@ -10,7 +10,7 @@ import TextURL from '../components/Common/TextURL'; import { useAuth } from '../context/AuthContext'; import { useConceptNavigation } from '../context/NagivationContext'; import { useConceptTheme } from '../context/ThemeContext'; -import { IUserLoginData } from '../utils/models'; +import { IUserLoginData } from '../models/library'; function ProcessError({error}: {error: ErrorInfo}): React.ReactElement { if (axios.isAxiosError(error) && error.response && error.response.status === 400) { diff --git a/rsconcept/frontend/src/pages/ManualsPage/TopicsList.tsx b/rsconcept/frontend/src/pages/ManualsPage/TopicsList.tsx index 0575a182..64bc62ed 100644 --- a/rsconcept/frontend/src/pages/ManualsPage/TopicsList.tsx +++ b/rsconcept/frontend/src/pages/ManualsPage/TopicsList.tsx @@ -1,5 +1,5 @@ +import { HelpTopic } from '../../models/miscelanious'; import { prefixes } from '../../utils/constants'; -import { HelpTopic } from '../../utils/models'; import { mapTopicInfo } from '../../utils/staticUI'; interface TopicsListProps { diff --git a/rsconcept/frontend/src/pages/ManualsPage/ViewTopic.tsx b/rsconcept/frontend/src/pages/ManualsPage/ViewTopic.tsx index f4893cfb..73268bc3 100644 --- a/rsconcept/frontend/src/pages/ManualsPage/ViewTopic.tsx +++ b/rsconcept/frontend/src/pages/ManualsPage/ViewTopic.tsx @@ -7,7 +7,7 @@ import HelpRSFormItems from '../../components/Help/HelpRSFormItems'; import HelpRSFormMeta from '../../components/Help/HelpRSFormMeta'; import HelpRSLang from '../../components/Help/HelpRSLang'; import HelpTermGraph from '../../components/Help/HelpTermGraph'; -import { HelpTopic } from '../../utils/models'; +import { HelpTopic } from '../../models/miscelanious'; interface ViewTopicProps { topic: HelpTopic diff --git a/rsconcept/frontend/src/pages/ManualsPage/index.tsx b/rsconcept/frontend/src/pages/ManualsPage/index.tsx index a0d3a186..3bf88c91 100644 --- a/rsconcept/frontend/src/pages/ManualsPage/index.tsx +++ b/rsconcept/frontend/src/pages/ManualsPage/index.tsx @@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom'; import { useConceptNavigation } from '../../context/NagivationContext'; import { useConceptTheme } from '../../context/ThemeContext'; -import { HelpTopic } from '../../utils/models'; +import { HelpTopic } from '../../models/miscelanious'; import TopicsList from './TopicsList'; import ViewTopic from './ViewTopic'; diff --git a/rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx b/rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx index dbfe369e..f01fbc16 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx @@ -8,7 +8,7 @@ import TextInput from '../../components/Common/TextInput'; import { useLibrary } from '../../context/LibraryContext'; import { useConceptNavigation } from '../../context/NagivationContext'; import { useRSForm } from '../../context/RSFormContext'; -import { IRSFormCreateData } from '../../utils/models'; +import { IRSFormCreateData } from '../../models/rsform'; import { getCloneTitle } from '../../utils/staticUI'; interface DlgCloneRSFormProps diff --git a/rsconcept/frontend/src/pages/RSFormPage/DlgCreateCst.tsx b/rsconcept/frontend/src/pages/RSFormPage/DlgCreateCst.tsx index ffa6d5df..64a2640e 100644 --- a/rsconcept/frontend/src/pages/RSFormPage/DlgCreateCst.tsx +++ b/rsconcept/frontend/src/pages/RSFormPage/DlgCreateCst.tsx @@ -4,7 +4,7 @@ import ConceptSelectSingle from '../../components/Common/ConceptSelectSingle'; import Modal, { ModalProps } from '../../components/Common/Modal'; import TextArea from '../../components/Common/TextArea'; import RSInput from '../../components/RSInput'; -import { CstType,ICstCreateData } from '../../utils/models'; +import { CstType,ICstCreateData } from '../../models/rsform'; import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI'; interface DlgCreateCstProps diff --git a/rsconcept/frontend/src/pages/RSFormPage/DlgEditTerm.tsx b/rsconcept/frontend/src/pages/RSFormPage/DlgEditTerm.tsx new file mode 100644 index 00000000..77caf28f --- /dev/null +++ b/rsconcept/frontend/src/pages/RSFormPage/DlgEditTerm.tsx @@ -0,0 +1,48 @@ +import { useLayoutEffect, useState } from 'react'; + +import Modal from '../../components/Common/Modal'; +import TextArea from '../../components/Common/TextArea'; +import { IConstituenta } from '../../models/rsform'; + +interface DlgEditTermProps { + hideWindow: () => void + target: IConstituenta + onSave: () => void +} + +function DlgEditTerm({ hideWindow, target, onSave }: DlgEditTermProps) { + const [term, setTerm] = useState(''); + + // function getData() { + // return { + + // }; + // } + + const handleSubmit = () => onSave(); // getData() + + useLayoutEffect( + () => { + setTerm(target.term_resolved); + }, [target]); + + return ( + +