Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ describe('getParsedSearchTermsByFieldType method', () => {
const input = 'world';
const result = getParsedSearchTermsByFieldType([input], FieldType.string);

expect(result).toBe(input);
expect(result).toEqual([input]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,46 @@ describe('executeStringFilterCondition method', () => {
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(true);
});

it('should return True when input value is in the range of search terms using 2 dots (..) notation', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', operator: 'EQ', cellValue: 'c', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(true);
});

it('should return True when input value is on the inclusive limit range of search terms using 2 dots (..) notation AND no operator provided except a defaultFilterRangeOperator is rangeInclusive', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeInclusive, cellValue: 'b', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(true);
});

it('should return False when input value is on the inclusive limit range of search terms using 2 dots (..) notation AND no operator provided except a defaultFilterRangeOperator is rangeExclusive', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeExclusive, cellValue: 'b', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(false);
});

it('should return False when input value is not in the range of search terms using 2 dots (..) notation', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', operator: 'EQ', cellValue: 'g', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(false);
});

it('should return True when input value equals the search terms min inclusive value and operator is set to "rangeInclusive" using 2 dots (..) notation', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', operator: 'RangeInclusive', cellValue: 'b', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(true);
});

it('should return False when input value equals the search terms min inclusive value and operator is set to "RangeExclusive" using 2 dots (..) notation', () => {
const searchTerms = ['b..e'];
const options = { dataKey: '', operator: 'RangeExclusive', cellValue: 'b', fieldType: FieldType.string, searchTerms } as FilterConditionOption;
const output = executeStringFilterCondition(options, getFilterParsedText(searchTerms));
expect(output).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const executeFilterConditionTest: FilterCondition = (options: FilterCondi
case 'text':
default:
// the parsedSearchTerms should be single value (result came from getFilterParsedText() method)
return executeStringFilterCondition(options, parsedSearchTerms as SearchTerm);
return executeStringFilterCondition(options, (parsedSearchTerms || []) as string[]);
}
};

Expand Down Expand Up @@ -67,7 +67,7 @@ export function getParsedSearchTermsByFieldType(inputSearchTerms: SearchTerm[] |
parsedSearchValues = getFilterParsedObjectResult(inputSearchTerms);
break;
case 'text':
parsedSearchValues = getFilterParsedText(inputSearchTerms);
parsedSearchValues = getFilterParsedText(inputSearchTerms) as SearchTerm[];
break;
}
return parsedSearchValues;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { FilterCondition, FilterConditionOption, OperatorType, SearchTerm } from '../models/index';
import { FilterCondition, FilterConditionOption, OperatorString, OperatorType, SearchTerm } from '../models/index';
import { testFilterCondition } from './filterUtilities';


/** Execute filter condition check on each cell */
export const executeStringFilterCondition: FilterCondition = ((options: FilterConditionOption, parsedSearchValue: string | undefined) => {
if (parsedSearchValue === undefined && !options.operator) {
export const executeStringFilterCondition: FilterCondition = ((options: FilterConditionOption, parsedSearchValues: string[]) => {
let [searchValue1, searchValue2] = parsedSearchValues;

if (searchValue1 === undefined && !options.operator) {
return true;
}

Expand All @@ -12,28 +15,64 @@ export const executeStringFilterCondition: FilterCondition = ((options: FilterCo

// make both the cell value and search value lower for case insensitive comparison
const cellValue = options.cellValue.toLowerCase();
if (typeof parsedSearchValue === 'string') {
parsedSearchValue = parsedSearchValue.toLowerCase();
if (typeof searchValue1 === 'string') {
searchValue1 = searchValue1.toLowerCase();
}
if (typeof searchValue2 === 'string') {
searchValue2 = searchValue2.toLowerCase();
}

if (options.operator === '*' || options.operator === OperatorType.endsWith) {
return cellValue.endsWith(parsedSearchValue);
} else if ((options.operator === '' && options.searchInputLastChar === '*') || options.operator === OperatorType.startsWith) {
return cellValue.startsWith(parsedSearchValue);
} else if (options.operator === '' || options.operator === OperatorType.contains) {
return (cellValue.indexOf(parsedSearchValue) > -1);
} else if (options.operator === '<>' || options.operator === OperatorType.notContains) {
return (cellValue.indexOf(parsedSearchValue) === -1);
if (searchValue1 !== undefined && searchValue2 !== undefined) {
let operator = options && options.operator || options.defaultFilterRangeOperator;
if (operator !== OperatorType.rangeInclusive && operator !== OperatorType.rangeExclusive) {
operator = options.defaultFilterRangeOperator;
}
const isInclusive = operator === OperatorType.rangeInclusive;
const searchResult1 = testStringCondition((isInclusive ? '>=' : '>'), cellValue, searchValue1, options.searchInputLastChar);
const searchResult2 = testStringCondition((isInclusive ? '<=' : '<'), cellValue, searchValue2, options.searchInputLastChar);
return searchResult1 && searchResult2;
}
return testFilterCondition(options.operator || '==', cellValue, parsedSearchValue);
const searchResult1 = testStringCondition(options.operator, cellValue, searchValue1, options.searchInputLastChar);
return searchResult1;
}) as FilterCondition;

/**
* From our search filter value(s), get the parsed value(s).
* This is called only once per filter before running the actual filter condition check on each cell
*/
export function getFilterParsedText(inputSearchTerms: SearchTerm[] | undefined): SearchTerm {
let parsedSearchValue = (Array.isArray(inputSearchTerms) && inputSearchTerms.length > 0) ? inputSearchTerms[0] : '';
parsedSearchValue = parsedSearchValue === undefined || parsedSearchValue === null ? '' : `${parsedSearchValue}`; // make sure it's a string
return parsedSearchValue;
export function getFilterParsedText(inputSearchTerms: SearchTerm[] | undefined): SearchTerm[] {
const defaultSearchTerm = ''; // when nothing is provided, we'll default to 0
const searchTerms = Array.isArray(inputSearchTerms) && inputSearchTerms || [defaultSearchTerm];
const parsedSearchValues: string[] = [];
let searchValue1;
let searchValue2;
if (searchTerms.length === 2 || (typeof searchTerms[0] === 'string' && (searchTerms[0] as string).indexOf('..') > 0)) {
const searchValues = (searchTerms.length === 2) ? searchTerms : (searchTerms[0] as string).split('..');
searchValue1 = `${Array.isArray(searchValues) ? searchValues[0] : ''}`;
searchValue2 = `${Array.isArray(searchValues) ? searchValues[1] : ''}`;
} else {
const parsedSearchValue = (Array.isArray(inputSearchTerms) && inputSearchTerms.length > 0) ? inputSearchTerms[0] : '';
searchValue1 = parsedSearchValue === undefined || parsedSearchValue === null ? '' : `${parsedSearchValue}`; // make sure it's a string
}

if (searchValue1 !== undefined && searchValue2 !== undefined) {
parsedSearchValues.push(searchValue1 as string, searchValue2 as string);
} else if (searchValue1 !== undefined) {
parsedSearchValues.push(searchValue1 as string);
}
return parsedSearchValues;
}

/** Execute the filter string test condition, returns a boolean */
function testStringCondition(operator: OperatorType | OperatorString, cellValue: string, searchValue: string, searchInputLastChar?: string): boolean {
if (operator === '*' || operator === OperatorType.endsWith) {
return cellValue.endsWith(searchValue);
} else if ((operator === '' && searchInputLastChar === '*') || operator === OperatorType.startsWith) {
return cellValue.startsWith(searchValue);
} else if (operator === '' || operator === OperatorType.contains) {
return (cellValue.indexOf(searchValue) > -1);
} else if (operator === '<>' || operator === OperatorType.notContains) {
return (cellValue.indexOf(searchValue) === -1);
}
return testFilterCondition(operator || '==', cellValue, searchValue);
}
Loading