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
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ describe('ExtensionService', () => {
expect(gridSpy).toHaveBeenCalled();
expect(getAddonSpy).toHaveBeenCalled();
expect(extSpy).toHaveBeenCalled();
expect(output.instance).toEqual(instance);
expect(output!.instance).toEqual(instance);
expect(output).toEqual({ name: ExtensionName.gridMenu, addon: instanceMock, instance: instanceMock, class: extensionGridMenuStub } as ExtensionModel);
});
});
Expand Down Expand Up @@ -259,7 +259,7 @@ describe('ExtensionService', () => {
expect(gridSpy).toHaveBeenCalled();
expect(getAddonSpy).toHaveBeenCalled();
expect(extSpy).toHaveBeenCalled();
expect(output.instance).toEqual(instance);
expect(output!.instance).toEqual(instance);
expect(output).toEqual({ name: ExtensionName.gridMenu, addon: instanceMock, instance: instanceMock, class: extensionGridMenuStub } as ExtensionModel);
});

Expand Down Expand Up @@ -448,7 +448,7 @@ describe('ExtensionService', () => {
});

describe('createExtensionsBeforeGridCreation method', () => {
let instanceMock;
let instanceMock: any;

beforeEach(() => {
instanceMock = { onColumnsChanged: () => { } };
Expand Down Expand Up @@ -703,36 +703,6 @@ describe('ExtensionService', () => {
expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock);
});

it('should re-register the Header Button when enable and method is called with new column definition collection provided as argument', () => {
const instanceMock = { onColumnsChanged: jest.fn() };
const extensionMock = { name: ExtensionName.headerButton, addon: null, instance: null, class: null } as ExtensionModel;
const expectedExtension = { name: ExtensionName.headerButton, instance: instanceMock as unknown, class: null } as ExtensionModel;
const gridOptionsMock = { enableHeaderButton: true } as GridOption;
const columnsMock = [
{ id: 'field1', field: 'field1', nameKey: 'HELLO' },
{ id: 'field2', field: 'field2', nameKey: 'WORLD' }
] as Column[];

jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock);
jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub);
const spyGetExt = jest.spyOn(service, 'getExtensionByName').mockReturnValue(extensionMock);
const spyGmDispose = jest.spyOn(extensionHeaderButtonStub, 'dispose');
const spyGmRegister = jest.spyOn(extensionHeaderButtonStub, 'register').mockReturnValue(instanceMock);
const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set');
const setColumnsSpy = jest.spyOn(gridStub, 'setColumns');

service.renderColumnHeaders(columnsMock);

expect(expectedExtension).toEqual(expectedExtension);
expect(spyGetExt).toHaveBeenCalled();
expect(expectedExtension).toEqual(expectedExtension);
expect(spyGetExt).toHaveBeenCalled();
expect(spyGmDispose).toHaveBeenCalled();
expect(spyGmRegister).toHaveBeenCalled();
expect(spyAllCols).toHaveBeenCalledWith(columnsMock);
expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock);
});

it('should re-register the Header Menu when enable and method is called with new column definition collection provided as argument', () => {
const instanceMock = { onColumnsChanged: jest.fn() };
const extensionMock = { name: ExtensionName.headerMenu, addon: null, instance: null, class: null } as ExtensionModel;
Expand Down Expand Up @@ -767,7 +737,7 @@ describe('ExtensionService', () => {

describe('without ngx-translate', () => {
beforeEach(() => {
translate = null;
(translate as any) = null;
service = new ExtensionService(
// extensions
extensionStub as unknown as AutoTooltipExtension,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,6 @@ export class ExtensionService {
this.recreateExternalAddon(this.gridMenuExtension, ExtensionName.gridMenu);
}

// recreate the Header Button when enabled
if (this.sharedService.gridOptions.enableHeaderButton) {
this.recreateExternalAddon(this.headerButtonExtension, ExtensionName.headerButton);
}

// recreate the Header Menu when enabled
if (this.sharedService.gridOptions.enableHeaderMenu) {
this.recreateExternalAddon(this.headerMenuExtension, ExtensionName.headerMenu);
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