mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactoring: miscellaneous functions
This commit is contained in:
parent
e22c38d9f4
commit
8d240d1360
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -32,6 +32,7 @@
|
|||
],
|
||||
"cSpell.words": [
|
||||
"ablt",
|
||||
"acconcept",
|
||||
"accs",
|
||||
"actv",
|
||||
"ADJF",
|
||||
|
@ -75,11 +76,13 @@
|
|||
"Litr",
|
||||
"loct",
|
||||
"moprho",
|
||||
"multiword",
|
||||
"mypy",
|
||||
"nomn",
|
||||
"nooverlap",
|
||||
"NPRO",
|
||||
"NUMR",
|
||||
"Opencorpora",
|
||||
"perfectivity",
|
||||
"ponomarev",
|
||||
"PRCL",
|
||||
|
@ -87,6 +90,7 @@
|
|||
"PRTS",
|
||||
"pssv",
|
||||
"pyconcept",
|
||||
"Pylance",
|
||||
"pylint",
|
||||
"pymorphy",
|
||||
"Quantor",
|
||||
|
@ -104,10 +108,13 @@
|
|||
"signup",
|
||||
"Slng",
|
||||
"SMALLPR",
|
||||
"tagset",
|
||||
"tailwindcss",
|
||||
"tanstack",
|
||||
"toastify",
|
||||
"tooltipic",
|
||||
"tsdoc",
|
||||
"unknwn",
|
||||
"Upvote",
|
||||
"Viewset",
|
||||
"viewsets",
|
||||
|
|
|
@ -23,7 +23,7 @@ function Root() {
|
|||
<NavigationState>
|
||||
<div className='min-w-[30rem] clr-app antialiased'>
|
||||
<ConceptToaster
|
||||
className='mt-[4rem] text-sm' //
|
||||
className='mt-[4rem] text-sm' // prettier: split lines
|
||||
autoClose={3000}
|
||||
draggable={false}
|
||||
pauseOnFocusLoss={false}
|
||||
|
|
|
@ -18,7 +18,7 @@ function NavigationButton({ icon, title, onClick, text }: NavigationButtonProps)
|
|||
data-tooltip-content={title}
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
'mr-1 h-full', //
|
||||
'mr-1 h-full', // prettier: split lines
|
||||
'flex items-center gap-1',
|
||||
'clr-btn-nav',
|
||||
'font-controls whitespace-nowrap',
|
||||
|
|
|
@ -10,7 +10,6 @@ interface RequireAuthProps {
|
|||
|
||||
function RequireAuth({ children }: RequireAuthProps) {
|
||||
const { user } = useAuth();
|
||||
|
||||
if (user) {
|
||||
return children;
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@ function ConstituentaBadge({ value, prefixID, theme }: ConstituentaBadgeProps) {
|
|||
<div
|
||||
id={`${prefixID}${value.alias}`}
|
||||
className={clsx(
|
||||
'min-w-[3.1rem] max-w-[3.1rem]', //
|
||||
'min-w-[3.1rem] max-w-[3.1rem]', // prettier: split lines
|
||||
'px-1',
|
||||
'border rounded-md',
|
||||
'text-center font-medium whitespace-nowrap'
|
||||
|
|
|
@ -16,7 +16,7 @@ function GrammemeBadge({ key, grammeme }: GrammemeBadgeProps) {
|
|||
<div
|
||||
key={key}
|
||||
className={clsx(
|
||||
'min-w-[3rem]', //
|
||||
'min-w-[3rem]', // prettier: split lines
|
||||
'px-1',
|
||||
'border rounded-md',
|
||||
'text-sm font-medium text-center whitespace-nowrap'
|
||||
|
|
|
@ -22,7 +22,7 @@ function InfoCstStatus({ title }: InfoCstStatusProps) {
|
|||
<p key={`${prefixes.cst_status_list}${index}`}>
|
||||
<span
|
||||
className={clsx(
|
||||
'inline-block', //
|
||||
'inline-block', // prettier: split lines
|
||||
'min-w-[7rem]',
|
||||
'px-1',
|
||||
'border',
|
||||
|
|
|
@ -11,9 +11,9 @@ import TextInput from '@/components/Common/TextInput';
|
|||
import { useLibrary } from '@/context/LibraryContext';
|
||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||
import { ILibraryItem } from '@/models/library';
|
||||
import { cloneTitle } from '@/models/libraryAPI';
|
||||
import { IRSFormCreateData } from '@/models/rsform';
|
||||
import { classnames } from '@/utils/constants';
|
||||
import { cloneTitle } from '@/utils/misc';
|
||||
|
||||
interface DlgCloneLibraryItemProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
base: ILibraryItem;
|
||||
|
|
|
@ -11,9 +11,9 @@ import HelpButton from '@/components/Help/HelpButton';
|
|||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||
import { HelpTopic } from '@/models/miscellaneous';
|
||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||
import { inferTemplatedType, substituteTemplateArgs } from '@/models/rslangAPI';
|
||||
import { classnames } from '@/utils/constants';
|
||||
import { createAliasFor, validateCstAlias } from '@/utils/misc';
|
||||
|
||||
import ArgumentsTab, { IArgumentsState } from './ArgumentsTab';
|
||||
import ConstituentaTab from './ConstituentaTab';
|
||||
|
@ -54,11 +54,11 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
|
|||
const handleSubmit = () => onCreate(constituenta);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
updateConstituenta({ alias: createAliasFor(constituenta.cst_type, schema) });
|
||||
updateConstituenta({ alias: generateAlias(constituenta.cst_type, schema) });
|
||||
}, [constituenta.cst_type, updateConstituenta, schema]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setValidated(validateCstAlias(constituenta.alias, constituenta.cst_type, schema));
|
||||
setValidated(validateNewAlias(constituenta.alias, constituenta.cst_type, schema));
|
||||
}, [constituenta.alias, constituenta.cst_type, schema]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
|
|
|
@ -10,9 +10,9 @@ import TextInput from '@/components/Common/TextInput';
|
|||
import RSInput from '@/components/RSInput';
|
||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||
import { CstType, ICstCreateData, IRSForm } from '@/models/rsform';
|
||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||
import { classnames } from '@/utils/constants';
|
||||
import { labelCstType } from '@/utils/labels';
|
||||
import { createAliasFor, validateCstAlias } from '@/utils/misc';
|
||||
import { SelectorCstType } from '@/utils/selectors';
|
||||
|
||||
interface DlgCreateCstProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -39,11 +39,11 @@ function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstPro
|
|||
const handleSubmit = () => onCreate(cstData);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
updateCstData({ alias: createAliasFor(cstData.cst_type, schema) });
|
||||
updateCstData({ alias: generateAlias(cstData.cst_type, schema) });
|
||||
}, [cstData.cst_type, updateCstData, schema]);
|
||||
|
||||
useEffect(() => {
|
||||
setValidated(validateCstAlias(cstData.alias, cstData.cst_type, schema));
|
||||
setValidated(validateNewAlias(cstData.alias, cstData.cst_type, schema));
|
||||
}, [cstData.alias, cstData.cst_type, schema]);
|
||||
|
||||
return (
|
||||
|
|
|
@ -53,7 +53,7 @@ function SyntacticTab({ initial, setIsValid, setReference }: SyntacticTabProps)
|
|||
onChange={event => setOffset(event.target.valueAsNumber)}
|
||||
/>
|
||||
<TextInput
|
||||
disabled //
|
||||
disabled // prettier: split lines
|
||||
dense
|
||||
noBorder
|
||||
label='Основная ссылка'
|
||||
|
|
|
@ -9,8 +9,8 @@ import TextInput from '@/components/Common/TextInput';
|
|||
import { useRSForm } from '@/context/RSFormContext';
|
||||
import usePartialUpdate from '@/hooks/usePartialUpdate';
|
||||
import { CstType, ICstRenameData } from '@/models/rsform';
|
||||
import { generateAlias, validateNewAlias } from '@/models/rsformAPI';
|
||||
import { labelCstType } from '@/utils/labels';
|
||||
import { createAliasFor, validateCstAlias } from '@/utils/misc';
|
||||
import { SelectorCstType } from '@/utils/selectors';
|
||||
|
||||
interface DlgRenameCstProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
|
@ -27,13 +27,13 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
|||
|
||||
useLayoutEffect(() => {
|
||||
if (schema && initial && cstData.cst_type !== initial.cst_type) {
|
||||
updateData({ alias: createAliasFor(cstData.cst_type, schema) });
|
||||
updateData({ alias: generateAlias(cstData.cst_type, schema) });
|
||||
}
|
||||
}, [initial, cstData.cst_type, updateData, schema]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setValidated(
|
||||
!!schema && cstData.alias !== initial.alias && validateCstAlias(cstData.alias, cstData.cst_type, schema)
|
||||
!!schema && cstData.alias !== initial.alias && validateNewAlias(cstData.alias, cstData.cst_type, schema)
|
||||
);
|
||||
}, [cstData.cst_type, cstData.alias, initial, schema]);
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import { useCallback, useState } from 'react';
|
|||
|
||||
import { type ErrorData } from '@/components/InfoError';
|
||||
import { CstType, IConstituenta, type IRSForm } from '@/models/rsform';
|
||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
|
||||
import { RSErrorType } from '@/models/rslang';
|
||||
import { DataCallback, postCheckExpression } from '@/utils/backendAPI';
|
||||
import { getCstExpressionPrefix } from '@/utils/misc';
|
||||
|
||||
const LOGIC_TYPIFICATION = 'LOGIC';
|
||||
|
||||
|
@ -27,7 +27,7 @@ function useCheckExpression({ schema }: { schema?: IRSForm }) {
|
|||
onError: error => setError(error),
|
||||
onSuccess: parse => {
|
||||
if (activeCst) {
|
||||
adjustResults(parse, expression.trim() === getCstExpressionPrefix(activeCst), activeCst.cst_type);
|
||||
adjustResults(parse, expression.trim() === getDefinitionPrefix(activeCst), activeCst.cst_type);
|
||||
}
|
||||
setParseData(parse);
|
||||
if (onSuccess) onSuccess(parse);
|
||||
|
|
|
@ -16,3 +16,14 @@ export function matchLibraryItem(target: ILibraryItem, query: string): boolean {
|
|||
const matcher = new TextMatcher(query);
|
||||
return matcher.test(target.alias) || matcher.test(target.title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate title for clone {@link ILibraryItem}.
|
||||
*/
|
||||
export function cloneTitle(target: ILibraryItem): string {
|
||||
if (!target.title.includes('[клон]')) {
|
||||
return target.title + ' [клон]';
|
||||
} else {
|
||||
return target.title + '+';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Module: Models for formal representation for systems of concepts.
|
||||
*/
|
||||
|
||||
import { Graph } from '@/utils/Graph';
|
||||
import { Graph } from '@/models/Graph';
|
||||
|
||||
import { ILibraryItemEx, ILibraryUpdateData } from './library';
|
||||
import { IArgumentInfo, ParsingStatus, ValueClass } from './rslang';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Module: API for formal representation for systems of concepts.
|
||||
*/
|
||||
|
||||
import { Graph } from '@/utils/Graph';
|
||||
import { Graph } from '@/models/Graph';
|
||||
import { TextMatcher } from '@/utils/utils';
|
||||
|
||||
import { CstMatchMode } from './miscellaneous';
|
||||
|
@ -169,23 +169,16 @@ export function inferClass(type: CstType, isTemplate: boolean): CstClass {
|
|||
if (isTemplate) {
|
||||
return CstClass.TEMPLATE;
|
||||
}
|
||||
// prettier-ignore
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,9 +220,58 @@ export function isMockCst(cst: IConstituenta) {
|
|||
}
|
||||
|
||||
/**
|
||||
* TODO: description
|
||||
* Apply filter based on start {@link IConstituenta} type.
|
||||
*/
|
||||
export function applyFilterCategory(start: IConstituenta, schema: IRSFormData): IConstituenta[] {
|
||||
const nextCategory = schema.items.find(cst => cst.order > start.order && cst.cst_type === CATEGORY_CST_TYPE);
|
||||
return schema.items.filter(cst => cst.order > start.order && (!nextCategory || cst.order <= nextCategory.order));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix for alias indicating {@link CstType}.
|
||||
*/
|
||||
export function getCstTypePrefix(type: CstType) {
|
||||
// prettier-ignore
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'X';
|
||||
case CstType.CONSTANT: return 'C';
|
||||
case CstType.STRUCTURED: return 'S';
|
||||
case CstType.AXIOM: return 'A';
|
||||
case CstType.TERM: return 'D';
|
||||
case CstType.FUNCTION: return 'F';
|
||||
case CstType.PREDICATE: return 'P';
|
||||
case CstType.THEOREM: return 'T';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate new alias against {@link CstType} and {@link IRSForm}.
|
||||
*/
|
||||
export function validateNewAlias(alias: string, type: CstType, schema: IRSForm): boolean {
|
||||
return alias.length >= 2 && alias[0] == getCstTypePrefix(type) && !schema.items.find(cst => cst.alias === alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition prefix for {@link IConstituenta}.
|
||||
*/
|
||||
export function getDefinitionPrefix(cst: IConstituenta): string {
|
||||
return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':==');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate alias for new {@link IConstituenta} of a given {@link CstType} for current {@link IRSForm}.
|
||||
*/
|
||||
export function generateAlias(type: CstType, schema: IRSForm): string {
|
||||
const prefix = getCstTypePrefix(type);
|
||||
if (!schema.items || schema.items.length <= 0) {
|
||||
return `${prefix}1`;
|
||||
}
|
||||
const index = schema.items.reduce((prev, cst, index) => {
|
||||
if (cst.cst_type !== type) {
|
||||
return prev;
|
||||
}
|
||||
index = Number(cst.alias.slice(1 - cst.alias.length)) + 1;
|
||||
return Math.max(prev, index);
|
||||
}, 1);
|
||||
return `${prefix}${index}`;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { applyPattern } from '@/utils/utils';
|
||||
|
||||
import { CstType } from './rsform';
|
||||
import { IArgumentValue, RSErrorClass, RSErrorType } from './rslang';
|
||||
import { IArgumentValue, IRSErrorDescription, RSErrorClass, RSErrorType } from './rslang';
|
||||
|
||||
const LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\d*/g;
|
||||
|
||||
|
@ -13,6 +13,7 @@ const LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\d*/g;
|
|||
* Extracts global variable names from a given expression.
|
||||
*/
|
||||
export function extractGlobals(expression: string): Set<string> {
|
||||
// cspell:disable-next-line
|
||||
return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []);
|
||||
}
|
||||
|
||||
|
@ -119,3 +120,17 @@ export function inferErrorClass(error: RSErrorType): RSErrorClass {
|
|||
return RSErrorClass.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate ErrorID label.
|
||||
*/
|
||||
export function getRSErrorPrefix(error: IRSErrorDescription): string {
|
||||
const id = error.errorType.toString(16);
|
||||
// prettier-ignore
|
||||
switch(inferErrorClass(error.errorType)) {
|
||||
case RSErrorClass.LEXER: return 'L' + id;
|
||||
case RSErrorClass.PARSER: return 'P' + id;
|
||||
case RSErrorClass.SEMANTIC: return 'S' + id;
|
||||
case RSErrorClass.UNKNOWN: return 'U' + id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,8 +109,8 @@ function CreateRSFormPage() {
|
|||
label='Сокращение'
|
||||
placeholder={file && 'Загрузить из файла'}
|
||||
className='w-[14rem]'
|
||||
pattern={patterns.alias}
|
||||
title={`не более ${limits.alias_len} символов`}
|
||||
pattern={patterns.library_alias}
|
||||
title={`не более ${limits.library_alias_len} символов`}
|
||||
value={alias}
|
||||
onChange={event => setAlias(event.target.value)}
|
||||
/>
|
||||
|
|
|
@ -46,7 +46,7 @@ function SearchPanel({ total, filtered, query, setQuery, strategy, setFilter }:
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'sticky top-0', //
|
||||
'sticky top-0', // prettier: split lines
|
||||
'w-full max-h-[2.3rem]',
|
||||
'pr-40 flex',
|
||||
'border-b',
|
||||
|
@ -55,7 +55,7 @@ function SearchPanel({ total, filtered, query, setQuery, strategy, setFilter }:
|
|||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'min-w-[10rem]', //
|
||||
'min-w-[10rem]', // prettier: split lines
|
||||
'px-2 self-center',
|
||||
'select-none',
|
||||
'whitespace-nowrap'
|
||||
|
|
|
@ -17,10 +17,10 @@ import DlgShowAST from '@/dialogs/DlgShowAST';
|
|||
import useCheckExpression from '@/hooks/useCheckExpression';
|
||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||
import { IConstituenta } from '@/models/rsform';
|
||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '@/models/rslang';
|
||||
import { TokenID } from '@/models/rslang';
|
||||
import { labelTypification } from '@/utils/labels';
|
||||
import { getCstExpressionPrefix } from '@/utils/misc';
|
||||
|
||||
import ParsingResult from './ParsingResult';
|
||||
import RSEditorControls from './RSEditControls';
|
||||
|
@ -78,7 +78,7 @@ function EditorRSExpression({
|
|||
if (!activeCst) {
|
||||
return;
|
||||
}
|
||||
const prefix = getCstExpressionPrefix(activeCst);
|
||||
const prefix = getDefinitionPrefix(activeCst);
|
||||
const expression = prefix + value;
|
||||
checkExpression(expression, activeCst, parse => {
|
||||
if (parse.errors.length > 0) {
|
||||
|
@ -103,7 +103,7 @@ function EditorRSExpression({
|
|||
if (!activeCst || !rsInput.current) {
|
||||
return;
|
||||
}
|
||||
const prefix = getCstExpressionPrefix(activeCst);
|
||||
const prefix = getDefinitionPrefix(activeCst);
|
||||
let errorPosition = error.position - prefix.length;
|
||||
if (errorPosition < 0) errorPosition = 0;
|
||||
rsInput.current?.view?.dispatch({
|
||||
|
@ -137,7 +137,7 @@ function EditorRSExpression({
|
|||
toast.error('Невозможно построить дерево разбора');
|
||||
} else {
|
||||
setSyntaxTree(parse.ast);
|
||||
setExpression(getCstExpressionPrefix(activeCst!) + value);
|
||||
setExpression(getDefinitionPrefix(activeCst!) + value);
|
||||
setShowAST(true);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,9 +4,9 @@ import clsx from 'clsx';
|
|||
import { motion } from 'framer-motion';
|
||||
|
||||
import { IExpressionParse, IRSErrorDescription } from '@/models/rslang';
|
||||
import { getRSErrorPrefix } from '@/models/rslangAPI';
|
||||
import { animateParseResults } from '@/utils/animations';
|
||||
import { describeRSError } from '@/utils/labels';
|
||||
import { getRSErrorPrefix } from '@/utils/misc';
|
||||
|
||||
interface ParsingResultProps {
|
||||
data: IExpressionParse | undefined;
|
||||
|
|
|
@ -98,8 +98,8 @@ function FormRSForm({ id, disabled, isModified, setIsModified }: FormRSFormProps
|
|||
required
|
||||
label='Сокращение'
|
||||
className='w-[14rem]'
|
||||
pattern={patterns.alias}
|
||||
title={`не более ${limits.alias_len} символов`}
|
||||
pattern={patterns.library_alias}
|
||||
title={`не более ${limits.library_alias_len} символов`}
|
||||
disabled={disabled}
|
||||
value={alias}
|
||||
onChange={event => setAlias(event.target.value)}
|
||||
|
|
|
@ -11,9 +11,9 @@ import HelpButton from '@/components/Help/HelpButton';
|
|||
import useDropdown from '@/hooks/useDropdown';
|
||||
import { HelpTopic } from '@/models/miscellaneous';
|
||||
import { CstType } from '@/models/rsform';
|
||||
import { getCstTypePrefix } from '@/models/rsformAPI';
|
||||
import { prefixes } from '@/utils/constants';
|
||||
import { labelCstType } from '@/utils/labels';
|
||||
import { getCstTypePrefix, getCstTypeShortcut } from '@/utils/misc';
|
||||
import { getCstTypeShortcut, labelCstType } from '@/utils/labels';
|
||||
|
||||
interface RSListToolbarProps {
|
||||
isMutable?: boolean;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useLayoutEffect, useMemo, useState } from 'react';
|
|||
|
||||
import { GraphFilterParams } from '@/models/miscellaneous';
|
||||
import { CstType, IRSForm } from '@/models/rsform';
|
||||
import { Graph } from '@/utils/Graph';
|
||||
import { Graph } from '@/models/Graph';
|
||||
|
||||
function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams, toggleUpdate: boolean) {
|
||||
const [filtered, setFiltered] = useState<Graph>(new Graph());
|
||||
|
|
|
@ -28,8 +28,8 @@ import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
|||
import useQueryStrings from '@/hooks/useQueryStrings';
|
||||
import { UserAccessMode } from '@/models/miscellaneous';
|
||||
import { IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData, TermForm } from '@/models/rsform';
|
||||
import { generateAlias } from '@/models/rsformAPI';
|
||||
import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants';
|
||||
import { createAliasFor } from '@/utils/misc';
|
||||
|
||||
import EditorConstituenta from './EditorConstituenta';
|
||||
import EditorRSForm from './EditorRSForm';
|
||||
|
@ -179,7 +179,7 @@ function RSTabs() {
|
|||
if (!schema?.items) {
|
||||
return;
|
||||
}
|
||||
data.alias = data.alias || createAliasFor(data.cst_type, schema);
|
||||
data.alias = data.alias || generateAlias(data.cst_type, schema);
|
||||
cstCreate(data, newCst => {
|
||||
toast.success(`Конституента добавлена: ${newCst.alias}`);
|
||||
navigateTab(activeTab, newCst.id);
|
||||
|
|
|
@ -193,7 +193,12 @@ export function domTooltipEntityReference(ref: IEntityReference, cst: IConstitue
|
|||
parseGrammemes(ref.form).forEach(gramStr => {
|
||||
const gram = document.createElement('div');
|
||||
gram.id = `tooltip-${gramStr}`;
|
||||
gram.className = clsx('min-w-[3rem]', 'px-1', 'border rounded-md', 'text-sm text-center whitespace-nowrap');
|
||||
gram.className = clsx(
|
||||
'min-w-[3rem]', // prettier: split lines
|
||||
'px-1',
|
||||
'border rounded-md',
|
||||
'text-sm text-center whitespace-nowrap'
|
||||
);
|
||||
gram.style.borderWidth = '1px';
|
||||
gram.style.borderColor = colorFgGrammeme(gramStr, colors);
|
||||
gram.style.color = colorFgGrammeme(gramStr, colors);
|
||||
|
|
|
@ -37,7 +37,7 @@ export const resources = {
|
|||
* Numeric limitations.
|
||||
*/
|
||||
export const limits = {
|
||||
alias_len: 12
|
||||
library_alias_len: 12
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ export const limits = {
|
|||
*/
|
||||
export const patterns = {
|
||||
login: '^[a-zA-Z][a-zA-Z0-9_\\-]{1,}[a-zA-Z0-9]$',
|
||||
alias: `.{1,${limits.alias_len}}`
|
||||
library_alias: `.{1,${limits.library_alias_len}}`
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -111,7 +111,25 @@ export function labelToken(id: TokenID): string {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates description for {@link TokenID}..
|
||||
* Return shortcut description for {@link CstType}.
|
||||
*/
|
||||
export function getCstTypeShortcut(type: CstType) {
|
||||
const prefix = labelCstType(type) + ' [Alt + ';
|
||||
// prettier-ignore
|
||||
switch (type) {
|
||||
case CstType.BASE: return prefix + '1]';
|
||||
case CstType.STRUCTURED: return prefix + '2]';
|
||||
case CstType.TERM: return prefix + '3]';
|
||||
case CstType.AXIOM: return prefix + '4]';
|
||||
case CstType.FUNCTION: return prefix + 'Q]';
|
||||
case CstType.PREDICATE: return prefix + 'W]';
|
||||
case CstType.CONSTANT: return prefix + '5]';
|
||||
case CstType.THEOREM: return prefix + '6]';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates description for {@link TokenID}.
|
||||
*/
|
||||
export function describeToken(id: TokenID): string {
|
||||
// prettier-ignore
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
* Module: miscellaneous static functions to generate UI resources.
|
||||
*/
|
||||
|
||||
import { ILibraryItem } from '@/models/library';
|
||||
import { CstType, IConstituenta, IRSForm } from '@/models/rsform';
|
||||
import { IRSErrorDescription, RSErrorClass } from '@/models/rslang';
|
||||
import { inferErrorClass } from '@/models/rslangAPI';
|
||||
|
||||
import { labelCstType } from './labels';
|
||||
|
||||
export function getCstTypePrefix(type: CstType) {
|
||||
// prettier-ignore
|
||||
switch (type) {
|
||||
case CstType.BASE: return 'X';
|
||||
case CstType.CONSTANT: return 'C';
|
||||
case CstType.STRUCTURED: return 'S';
|
||||
case CstType.AXIOM: return 'A';
|
||||
case CstType.TERM: return 'D';
|
||||
case CstType.FUNCTION: return 'F';
|
||||
case CstType.PREDICATE: return 'P';
|
||||
case CstType.THEOREM: return 'T';
|
||||
}
|
||||
}
|
||||
|
||||
export function validateCstAlias(alias: string, type: CstType, schema: IRSForm): boolean {
|
||||
return alias.length >= 2 && alias[0] == getCstTypePrefix(type) && !schema.items.find(cst => cst.alias === alias);
|
||||
}
|
||||
|
||||
export function getCstExpressionPrefix(cst: IConstituenta): string {
|
||||
return cst.alias + (cst.cst_type === CstType.STRUCTURED ? '::=' : ':==');
|
||||
}
|
||||
|
||||
export function getCstTypeShortcut(type: CstType) {
|
||||
const prefix = labelCstType(type) + ' [Alt + ';
|
||||
// prettier-ignore
|
||||
switch (type) {
|
||||
case CstType.BASE: return prefix + '1]';
|
||||
case CstType.STRUCTURED: return prefix + '2]';
|
||||
case CstType.TERM: return prefix + '3]';
|
||||
case CstType.AXIOM: return prefix + '4]';
|
||||
case CstType.FUNCTION: return prefix + 'Q]';
|
||||
case CstType.PREDICATE: return prefix + 'W]';
|
||||
case CstType.CONSTANT: return prefix + '5]';
|
||||
case CstType.THEOREM: return prefix + '6]';
|
||||
}
|
||||
}
|
||||
|
||||
export function createAliasFor(type: CstType, schema: IRSForm): string {
|
||||
const prefix = getCstTypePrefix(type);
|
||||
if (!schema.items || schema.items.length <= 0) {
|
||||
return `${prefix}1`;
|
||||
}
|
||||
const index = schema.items.reduce((prev, cst, index) => {
|
||||
if (cst.cst_type !== type) {
|
||||
return prev;
|
||||
}
|
||||
index = Number(cst.alias.slice(1 - cst.alias.length)) + 1;
|
||||
return Math.max(prev, index);
|
||||
}, 1);
|
||||
return `${prefix}${index}`;
|
||||
}
|
||||
|
||||
export function cloneTitle(target: ILibraryItem): string {
|
||||
if (!target.title.includes('[клон]')) {
|
||||
return target.title + ' [клон]';
|
||||
} else {
|
||||
return target.title + '+';
|
||||
}
|
||||
}
|
||||
|
||||
export function getRSErrorPrefix(error: IRSErrorDescription): string {
|
||||
const id = error.errorType.toString(16);
|
||||
// prettier-ignore
|
||||
switch(inferErrorClass(error.errorType)) {
|
||||
case RSErrorClass.LEXER: return 'L' + id;
|
||||
case RSErrorClass.PARSER: return 'P' + id;
|
||||
case RSErrorClass.SEMANTIC: return 'S' + id;
|
||||
case RSErrorClass.UNKNOWN: return 'U' + id;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Module: Mappings for selector UI elements.
|
||||
* Module: Mappings for selector UI elements. Do not confuse with html selectors
|
||||
*/
|
||||
import { LayoutTypes } from 'reagraph';
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user