Skip to content

Commit

Permalink
fix(filters): use defaultFilterOperator in range when none provided (#…
Browse files Browse the repository at this point in the history
…271)

- when using 2 dots notation (`2..5`), we should use `defaultFilterRangeOperator` when none is provided and/or isn't a range operator
  • Loading branch information
ghiscoding authored Feb 27, 2021
1 parent ffbd188 commit 993675f
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 7 deletions.
25 changes: 25 additions & 0 deletions examples/webpack-demo-vanilla-bundle/src/examples/example12.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,31 @@ export class Example12 {
massUpdate: true, minValue: 0, maxValue: 100,
},
},
// {
// id: 'percentComplete2', name: '% Complete', field: 'analysis.percentComplete', minWidth: 100,
// type: FieldType.number,
// sortable: true, filterable: true, columnGroup: 'Analysis',
// // filter: { model: Filters.compoundSlider, operator: '>=' },
// formatter: Formatters.complex,
// exportCustomFormatter: Formatters.complex, // without the Editing cell Formatter
// editor: {
// model: Editors.singleSelect,
// serializeComplexValueFormat: 'flat', // if we keep "object" as the default it will apply { value: 2, label: 2 } which is not what we want in this case
// collection: Array.from(Array(101).keys()).map(k => ({ value: k, label: k })),
// collectionOptions: {
// addCustomFirstEntry: { value: '', label: '--none--' }
// },
// collectionOverride: (_collectionInput, args) => {
// const originalCollection = args.originalCollections || [];
// const duration = args?.dataContext?.duration ?? args?.compositeEditorOptions?.formValues?.duration;
// if (duration === 10) {
// return originalCollection.filter(itemCollection => +itemCollection.value !== 1);
// }
// return originalCollection;
// },
// massUpdate: true, minValue: 0, maxValue: 100,
// },
// },
{
id: 'complexity', name: 'Complexity', field: 'complexity', minWidth: 100,
type: FieldType.number,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldType, SearchTerm } from '../../enums/index';
import { FieldType, OperatorType } from '../../enums/index';
import { FilterConditionOption } from '../../interfaces/index';
import { executeDateFilterCondition, getFilterParsedDates } from '../dateFilterCondition';
import { executeFilterConditionTest, getParsedSearchTermsByFieldType } from '../filterConditionProcesses';
Expand Down Expand Up @@ -99,6 +99,20 @@ describe('dateIsoFilterCondition method', () => {
});

describe('date range', () => {
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 = ['1993-12-01..1993-12-31'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeInclusive, cellValue: '1993-12-01', fieldType: FieldType.dateIso, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateIso));
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 = ['1993-12-01..1993-12-31'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeExclusive, cellValue: '1993-12-01', fieldType: FieldType.dateIso, searchTerms } as FilterConditionOption;
const output = executeFilterConditionTest(options, getFilterParsedDates(searchTerms, FieldType.dateIso));
expect(output).toBe(false);
});

it('should return True when input value is in the range of search terms', () => {
const searchTerms = ['1993-12-01..1993-12-31'];
const options = { dataKey: '', operator: 'EQ', cellValue: '1993-12-25', fieldType: FieldType.dateIso, searchTerms } as FilterConditionOption;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldType } from '../../enums/index';
import { FieldType, OperatorType } from '../../enums/index';
import { FilterConditionOption } from '../../interfaces/index';
import { executeFilterConditionTest } from '../filterConditionProcesses';
import { executeNumberFilterCondition, getFilterParsedNumbers } from '../numberFilterCondition';
Expand Down Expand Up @@ -116,6 +116,20 @@ describe('executeNumberFilterCondition method', () => {
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 = ['1..5'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeInclusive, cellValue: '1', fieldType: FieldType.number, searchTerms } as FilterConditionOption;
const output = executeNumberFilterCondition(options, getFilterParsedNumbers(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 = ['1..5'];
const options = { dataKey: '', defaultFilterRangeOperator: OperatorType.rangeExclusive, cellValue: '1', fieldType: FieldType.number, searchTerms } as FilterConditionOption;
const output = executeNumberFilterCondition(options, getFilterParsedNumbers(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 = ['1..5'];
const options = { dataKey: '', operator: 'EQ', cellValue: '15', fieldType: FieldType.number, searchTerms } as FilterConditionOption;
Expand Down
6 changes: 5 additions & 1 deletion packages/common/src/filter-conditions/dateFilterCondition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export function executeDateFilterCondition(options: FilterConditionOption, parse

// having 2 search dates, we assume that it's a date range filtering and we'll compare against both dates
if (searchDate1 && searchDate2) {
const isInclusive = options.operator && options.operator === OperatorType.rangeInclusive;
let operator = options?.operator ?? options.defaultFilterRangeOperator;
if (operator !== OperatorType.rangeInclusive && operator !== OperatorType.rangeExclusive) {
operator = options.defaultFilterRangeOperator;
}
const isInclusive = operator === OperatorType.rangeInclusive;
const resultCondition1 = testFilterCondition((isInclusive ? '>=' : '>'), dateCellTimestamp, searchDate1.valueOf());
const resultCondition2 = testFilterCondition((isInclusive ? '<=' : '<'), dateCellTimestamp, searchDate2.valueOf());
return (resultCondition1 && resultCondition2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export const executeNumberFilterCondition: FilterCondition = ((options: FilterCo
}

if (searchValue1 !== undefined && searchValue2 !== undefined) {
const isInclusive = options?.operator === OperatorType.rangeInclusive;
let operator = options?.operator ?? options.defaultFilterRangeOperator;
if (operator !== OperatorType.rangeInclusive && operator !== OperatorType.rangeExclusive) {
operator = options.defaultFilterRangeOperator;
}
const isInclusive = operator === OperatorType.rangeInclusive;
const resultCondition1 = testFilterCondition((isInclusive ? '>=' : '>'), cellValue, +searchValue1);
const resultCondition2 = testFilterCondition((isInclusive ? '<=' : '<'), cellValue, +searchValue2);
return (resultCondition1 && resultCondition2);
Expand All @@ -31,7 +35,6 @@ export function getFilterParsedNumbers(inputSearchTerms: SearchTerm[] | undefine
const parsedSearchValues: number[] = [];
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 = parseFloat(Array.isArray(searchValues) ? searchValues[0] as string : '');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { FieldType, OperatorString, SearchTerm } from '../enums/index';
import { FieldType, OperatorString, OperatorType, SearchTerm } from '../enums/index';

export interface FilterConditionOption {
/** optional object data key */
dataKey?: string;

/** pull the grid option default filter in case the "operator" provided is not a range operator or is simply undefined */
defaultFilterRangeOperator: OperatorType | OperatorString;

/** filter operator */
operator: OperatorString;

Expand Down
4 changes: 3 additions & 1 deletion packages/common/src/services/filter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ export class FilterService {
searchTerms: searchValues || [],
operator: operator as OperatorString,
searchInputLastChar: inputLastChar,
filterSearchType: columnDef.filterSearchType
filterSearchType: columnDef.filterSearchType,
defaultFilterRangeOperator: this._gridOptions.defaultFilterRangeOperator,
} as FilterConditionOption;
}

Expand Down Expand Up @@ -476,6 +477,7 @@ export class FilterService {
operator: operator as OperatorString,
searchInputLastChar: columnFilter.searchInputLastChar,
filterSearchType: columnDef.filterSearchType,
defaultFilterRangeOperator: this._gridOptions.defaultFilterRangeOperator,
} as FilterConditionOption;
}

Expand Down
Binary file not shown.

0 comments on commit 993675f

Please sign in to comment.