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
…705)

- 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 committed Feb 27, 2021
1 parent 7219249 commit a176037
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldType, FilterConditionOption } from '../../models/index';
import { FieldType, FilterConditionOption, OperatorType, SearchTerm } from '../../models/index';
import { executeDateFilterCondition, getFilterParsedDates } from '../dateFilterCondition';
import { executeFilterConditionTest, getParsedSearchTermsByFieldType } from '../filterConditionProcesses';

Expand Down Expand Up @@ -98,6 +98,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 Expand Up @@ -140,14 +154,14 @@ describe('dateIsoFilterCondition method', () => {
it('should return False when no cell value is provided, neither search terms', () => {
const searchTerms = [undefined];
const options = { dataKey: '', operator: 'EQ', fieldType: FieldType.dateIso, cellValue: '' } as FilterConditionOption;
const output = executeDateFilterCondition(options, getParsedSearchTermsByFieldType(searchTerms, FieldType.dateIso) as any[]);
const output = executeDateFilterCondition(options, getParsedSearchTermsByFieldType(searchTerms as unknown as SearchTerm[], FieldType.dateIso) as any[]);
expect(output).toBe(false);
});

it('should return False when any cell value is provided without any search terms', () => {
const searchTerms = [undefined];
const options = { dataKey: '', operator: 'EQ', fieldType: FieldType.dateIso, cellValue: '2000-12-25' } as FilterConditionOption;
const output = executeDateFilterCondition(options, getParsedSearchTermsByFieldType(searchTerms, FieldType.dateIso) as any[]);
const output = executeDateFilterCondition(options, getParsedSearchTermsByFieldType(searchTerms as unknown as SearchTerm[], FieldType.dateIso) as any[]);
expect(output).toBe(false);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldType, FilterConditionOption } from '../../models/index';
import { FieldType, FilterConditionOption, OperatorType, SearchTerm } from '../../models/index';
import { executeFilterConditionTest } from '../filterConditionProcesses';
import { executeNumberFilterCondition, getFilterParsedNumbers } from '../numberFilterCondition';

Expand All @@ -20,12 +20,12 @@ describe('executeNumberFilterCondition method', () => {
it('should return True when first searchTerm is undefined provided neither an operator when executing "executeFilterConditionTest" method', () => {
const searchTerms = [undefined];
const options = { dataKey: '', cellValue: 0, fieldType: FieldType.number } as FilterConditionOption;
const output = executeFilterConditionTest(options, searchTerms);
const output = executeFilterConditionTest(options, searchTerms as unknown as SearchTerm[]);
expect(output).toBe(true);
});

it('should return False when any cell value is provided without any search terms', () => {
const searchTerms = [];
const searchTerms: SearchTerm[] = [];
const options = { dataKey: '', operator: 'EQ', cellValue: 'foo', fieldType: FieldType.number } as FilterConditionOption;
const output = executeNumberFilterCondition(options, getFilterParsedNumbers(searchTerms));
expect(output).toBe(false);
Expand Down Expand Up @@ -115,6 +115,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
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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 && 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 @@ -12,7 +12,11 @@ export const executeNumberFilterCondition: FilterCondition = ((options: FilterCo
}

if (searchValue1 !== undefined && searchValue2 !== undefined) {
const isInclusive = (options && options.operator) === OperatorType.rangeInclusive;
let operator = options && 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 Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { FieldType } from './fieldType.enum';
import { OperatorString } from './operatorString';
import { OperatorType } from './operatorType.enum';
import { SearchTerm } from './searchTerm.type';

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 src/app/modules/angular-slickgrid/services/filter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,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 @@ -489,6 +490,7 @@ export class FilterService {
operator: operator as OperatorString,
searchInputLastChar: columnFilter.searchInputLastChar,
filterSearchType: columnDef.filterSearchType,
defaultFilterRangeOperator: this._gridOptions.defaultFilterRangeOperator,
} as FilterConditionOption;
}

Expand Down
9 changes: 4 additions & 5 deletions test/cypress/integration/example12.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,9 @@ describe('Example 12: Localization (i18n)', () => {
.find('.slick-custom-footer')
.find('.right-footer')
.should($span => {
const now = new Date();
const dateTime = moment().format('YYYY-MM-DD, hh:mm a');
const text = removeExtraSpaces($span.text()); // remove all white spaces
const dateFormatted = moment(now).format('YYYY-MM-DD, hh:mm a');
expect(text).to.eq(`Dernière mise à jour ${dateFormatted} | 1500 de 1500 éléments`);
expect(text).to.eq(`Dernière mise à jour ${dateTime} | 1500 de 1500 éléments`);
});
});

Expand Down Expand Up @@ -270,14 +269,14 @@ describe('Example 12: Localization (i18n)', () => {

it('should have some metrics shown in the grid footer', () => {
const now = new Date();
const dateFormatted = moment(now).format('YYYY-MM-DD, hh:mm a');

cy.get('#slickGridContainer-grid12')
.find('.slick-custom-footer')
.find('.right-footer')
.should($span => {
const dateTime = moment().format('YYYY-MM-DD, hh:mm a');
const text = removeExtraSpaces($span.text()); // remove all white spaces
expect(text).to.eq(`Last Update ${dateFormatted} | 447 of 1500 items`);
expect(text).to.eq(`Last Update ${dateTime} | 447 of 1500 items`);
});
});

Expand Down

0 comments on commit a176037

Please sign in to comment.