mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Fix regexp filtering errors
This commit is contained in:
parent
ce513eeb90
commit
09c95cb81f
|
@ -1,5 +1,7 @@
|
||||||
// Module: Schema library models.
|
// Module: Schema library models.
|
||||||
|
|
||||||
|
import { TextMatcher } from '../utils/utils'
|
||||||
|
|
||||||
// ========= Users ===========
|
// ========= Users ===========
|
||||||
export interface IUser {
|
export interface IUser {
|
||||||
id: number | null
|
id: number | null
|
||||||
|
@ -53,13 +55,7 @@ export interface ILibraryUpdateData
|
||||||
|
|
||||||
// ============= API ===============
|
// ============= API ===============
|
||||||
export function matchLibraryItem(query: string, target: ILibraryItem): boolean {
|
export function matchLibraryItem(query: string, target: ILibraryItem): boolean {
|
||||||
const queryI = query.toUpperCase()
|
const matcher = new TextMatcher(query);
|
||||||
if (target.alias.toUpperCase().match(queryI)) {
|
return matcher.test(target.alias) || matcher.test(target.title);
|
||||||
return true
|
|
||||||
} else if (target.title.toUpperCase().match(queryI)) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Graph } from '../utils/Graph'
|
import { Graph } from '../utils/Graph'
|
||||||
|
import { TextMatcher } from '../utils/utils'
|
||||||
import { ILibraryUpdateData } from './library'
|
import { ILibraryUpdateData } from './library'
|
||||||
import { ILibraryItem } from './library'
|
import { ILibraryItem } from './library'
|
||||||
import { CstMatchMode } from './miscelanious'
|
import { CstMatchMode } from './miscelanious'
|
||||||
|
@ -215,21 +216,22 @@ export function loadRSFormData(schema: IRSFormData): IRSForm {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function matchConstituenta(query: string, target: IConstituenta, mode: CstMatchMode) {
|
export function matchConstituenta(query: string, target: IConstituenta, mode: CstMatchMode): boolean {
|
||||||
|
const matcher = new TextMatcher(query);
|
||||||
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.NAME) &&
|
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.NAME) &&
|
||||||
target.alias.match(query)) {
|
matcher.test(target.alias)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.TERM) &&
|
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.TERM) &&
|
||||||
target.term_resolved.match(query)) {
|
matcher.test(target.term_resolved)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.EXPR) &&
|
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.EXPR) &&
|
||||||
target.definition_formal.match(query)) {
|
matcher.test(target.definition_formal)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.TEXT)) {
|
if ((mode === CstMatchMode.ALL || mode === CstMatchMode.TEXT)) {
|
||||||
return (target.definition_resolved.match(query) || target.convention.match(query));
|
return (matcher.test(target.definition_resolved) || matcher.test(target.convention));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,7 @@ export enum TokenID {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RSErrorType {
|
export enum RSErrorType {
|
||||||
|
unknownSymbol = 33283,
|
||||||
syntax = 33792,
|
syntax = 33792,
|
||||||
missingParanthesis = 33798,
|
missingParanthesis = 33798,
|
||||||
missingCurlyBrace = 33799,
|
missingCurlyBrace = 33799,
|
||||||
|
|
|
@ -74,6 +74,7 @@ function DlgCreateCst({ hideWindow, initial, onCreate }: DlgCreateCstProps) {
|
||||||
onChange={event => setTerm(event.target.value)}
|
onChange={event => setTerm(event.target.value)}
|
||||||
/>
|
/>
|
||||||
<RSInput id='expression' label='Формальное выражение'
|
<RSInput id='expression' label='Формальное выражение'
|
||||||
|
placeholder='Родоструктурное выражение, задающее формальное определение'
|
||||||
editable
|
editable
|
||||||
height='5.5rem'
|
height='5.5rem'
|
||||||
value={expression}
|
value={expression}
|
||||||
|
|
|
@ -240,7 +240,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
spellCheck
|
spellCheck
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className='text-sm mt-4 mb-2 font-semibold'>
|
<div className='mt-4 mb-2 text-sm font-semibold'>
|
||||||
Параметры словоформы
|
Параметры словоформы
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-start justify-between'>
|
<div className='flex justify-between flex-start'>
|
||||||
<div className='flex items-center justify-start'>
|
<div className='flex items-center justify-start'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
tooltip='Внести словоформу'
|
tooltip='Внести словоформу'
|
||||||
|
@ -304,7 +304,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
|
||||||
onClick={handleGenerateLexeme}
|
onClick={handleGenerateLexeme}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='text-sm mt-2 mb-1 font-semibold w-full text-center'>
|
<div className='w-full mt-2 mb-1 text-sm font-semibold text-center'>
|
||||||
Заданные вручную словоформы: [{forms.length}]
|
Заданные вручную словоформы: [{forms.length}]
|
||||||
</div>
|
</div>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
|
|
@ -92,6 +92,7 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
filtered = applyGraphFilter(schema, activeID, filterSource);
|
filtered = applyGraphFilter(schema, activeID, filterSource);
|
||||||
}
|
}
|
||||||
if (filterText) {
|
if (filterText) {
|
||||||
|
console.log(filterText);
|
||||||
filtered = filtered.filter((cst) => matchConstituenta(filterText, cst, filterMatch));
|
filtered = filtered.filter((cst) => matchConstituenta(filterText, cst, filterMatch));
|
||||||
}
|
}
|
||||||
setFilteredData(filtered);
|
setFilteredData(filtered);
|
||||||
|
@ -141,9 +142,9 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
columnHelper.accessor(cst => describeConstituenta(cst), {
|
columnHelper.accessor(cst => describeConstituenta(cst), {
|
||||||
id: 'description',
|
id: 'description',
|
||||||
header: 'Описание',
|
header: 'Описание',
|
||||||
size: 500,
|
size: 1000,
|
||||||
minSize: 350,
|
minSize: 350,
|
||||||
maxSize: 500,
|
maxSize: 1000,
|
||||||
cell: props =>
|
cell: props =>
|
||||||
<div style={{
|
<div style={{
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
@ -155,9 +156,9 @@ function ViewSideConstituents({ expression, baseHeight, activeID, onOpenEdit }:
|
||||||
columnHelper.accessor('definition_formal', {
|
columnHelper.accessor('definition_formal', {
|
||||||
id: 'expression',
|
id: 'expression',
|
||||||
header: 'Выражение',
|
header: 'Выражение',
|
||||||
size: 1000,
|
size: 2000,
|
||||||
minSize: 0,
|
minSize: 0,
|
||||||
maxSize: 1000,
|
maxSize: 2000,
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
cell: props =>
|
cell: props =>
|
||||||
<div style={{
|
<div style={{
|
||||||
|
|
|
@ -438,6 +438,8 @@ export function labelGrammeme(gram: GramData): string {
|
||||||
|
|
||||||
export function describeRSError(error: IRSErrorDescription): string {
|
export function describeRSError(error: IRSErrorDescription): string {
|
||||||
switch (error.errorType) {
|
switch (error.errorType) {
|
||||||
|
case RSErrorType.unknownSymbol:
|
||||||
|
return `Неизвестный символ: ${error.params[0]}`;
|
||||||
case RSErrorType.syntax:
|
case RSErrorType.syntax:
|
||||||
return 'Неопределенная синтаксическая ошибка';
|
return 'Неопределенная синтаксическая ошибка';
|
||||||
case RSErrorType.missingParanthesis:
|
case RSErrorType.missingParanthesis:
|
||||||
|
|
|
@ -15,3 +15,31 @@ export function trimString(target: string, maxLen: number): string {
|
||||||
return target.substring(0, maxLen) + '...';
|
return target.substring(0, maxLen) + '...';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class for generalized text matching.
|
||||||
|
*
|
||||||
|
* If possible create regexp, otherwise use symbol matching.
|
||||||
|
*/
|
||||||
|
export class TextMatcher {
|
||||||
|
protected query: RegExp | string
|
||||||
|
|
||||||
|
constructor(query: string, isPlainText?: boolean, isCaseSensitive?: boolean) {
|
||||||
|
if (isPlainText) {
|
||||||
|
query = query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.query = new RegExp(query, isCaseSensitive ? '' : 'i');
|
||||||
|
} catch(exception: unknown) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test(text: string): boolean {
|
||||||
|
if (typeof this.query === 'string') {
|
||||||
|
return text.indexOf(this.query) !== -1;
|
||||||
|
} else {
|
||||||
|
return !!text.match(this.query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user