Skip to content

Commit

Permalink
fix(presets): compound filters operator not working correctly w/prese…
Browse files Browse the repository at this point in the history
…ts (#373)

- grid presets should work with short/long operator names, basically StartsWith/EndsWith were not working correctly while a*/*z were working correctly, both options should work
  • Loading branch information
ghiscoding committed Jun 25, 2020
1 parent 5909dea commit 27b8c21
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/aurelia-slickgrid/filters/compoundDateFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ export class CompoundDateFilter implements Filter {
this.$filterInputElm.data('columnId', columnId);

if (this.operator) {
this.$selectOperatorElm.val(this.operator);
const operatorShorthand = mapOperatorToShorthandDesignation(this.operator);
this.$selectOperatorElm.val(operatorShorthand);
}

// if there's a search term, we will add the "filled" class for styling purposes
Expand Down
3 changes: 2 additions & 1 deletion src/aurelia-slickgrid/filters/compoundInputFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ export class CompoundInputFilter implements Filter {
this.$filterInputElm.data('columnId', columnId);

if (this.operator) {
this.$selectOperatorElm.val(this.operator);
const operatorShorthand = mapOperatorToShorthandDesignation(this.operator);
this.$selectOperatorElm.val(operatorShorthand);
}

// if there's a search term, we will add the "filled" class for styling purposes
Expand Down
3 changes: 2 additions & 1 deletion src/aurelia-slickgrid/filters/compoundSliderFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ export class CompoundSliderFilter implements Filter {
this.$filterInputElm.data('columnId', columnId);

if (this.operator) {
this.$selectOperatorElm.val(this.operator);
const operatorShorthand = mapOperatorToShorthandDesignation(this.operator);
this.$selectOperatorElm.val(operatorShorthand);
}

// if there's a search term, we will add the "filled" class for styling purposes
Expand Down
28 changes: 28 additions & 0 deletions src/aurelia-slickgrid/services/__tests__/graphql.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,20 @@ describe('GraphqlService', () => {
expect(removeSpaces(query)).toBe(removeSpaces(expectation));
});

it('should return a query with search having the operator EndsWith when the Column Filter was provided as EndsWith', () => {
const expectation = `query{users(first:10, offset:0, filterBy:[{field:gender, operator:EndsWith, value:"le"}]) { totalCount,nodes{ id,company,gender,name } }}`;
const mockColumn = { id: 'gender', field: 'gender', filter: { operator: 'EndsWith' } } as Column;
const mockColumnFilters = {
gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: ['le'] },
} as ColumnFilters;

service.init(serviceOptions, paginationOptions, gridStub);
service.updateFilters(mockColumnFilters, false);
const query = service.buildQuery();

expect(removeSpaces(query)).toBe(removeSpaces(expectation));
});

it('should return a query with search having the operator StartsWith when the operator was provided as a*', () => {
const expectation = `query{users(first:10, offset:0, filterBy:[{field:gender, operator:StartsWith, value:"le"}]) { totalCount,nodes{ id,company,gender,name } }}`;
const mockColumn = { id: 'gender', field: 'gender' } as Column;
Expand All @@ -799,6 +813,20 @@ describe('GraphqlService', () => {
expect(removeSpaces(query)).toBe(removeSpaces(expectation));
});

it('should return a query with search having the operator StartsWith when the operator was provided as StartsWith', () => {
const expectation = `query{users(first:10, offset:0, filterBy:[{field:gender, operator:StartsWith, value:"le"}]) { totalCount,nodes{ id,company,gender,name } }}`;
const mockColumn = { id: 'gender', field: 'gender' } as Column;
const mockColumnFilters = {
gender: { columnId: 'gender', columnDef: mockColumn, searchTerms: ['le'], operator: 'StartsWith' },
} as ColumnFilters;

service.init(serviceOptions, paginationOptions, gridStub);
service.updateFilters(mockColumnFilters, false);
const query = service.buildQuery();

expect(removeSpaces(query)).toBe(removeSpaces(expectation));
});

it('should return a query with search having a range of exclusive numbers when the search value contains 2 (..) to represent a range of numbers', () => {
const expectation = `query{users(first:10, offset:0, filterBy:[{field:duration, operator:GT, value:"2"}, {field:duration, operator:LT, value:"33"}]) { totalCount,nodes{ id,company,gender,name } }}`;
const mockColumn = { id: 'duration', field: 'duration' } as Column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,13 @@ describe('GridOdataService', () => {
});

it('should return a query with a new filter when previous filters exists', () => {
const expectation = `$top=10&$filter=(Gender eq 'female' and FirstName eq 'John')`;
const expectation = `$top=10&$filter=(Gender eq 'female' and endswith(FirstName, 'John'))`;
const querySpy = jest.spyOn(service.odataService, 'buildQuery');
const resetSpy = jest.spyOn(service, 'resetPaginationOptions');
const mockColumn = { id: 'gender', field: 'gender' } as Column;
const mockColumnName = { id: 'firstName', field: 'firstName' } as Column;
const mockColumnFilter = { columnDef: mockColumn, columnId: 'gender', operator: 'EQ', searchTerms: ['female'] } as ColumnFilter;
const mockColumnFilterName = { columnDef: mockColumnName, columnId: 'firstName', operator: 'StartsWith', searchTerms: ['John'] } as ColumnFilter;
const mockColumnFilterName = { columnDef: mockColumnName, columnId: 'firstName', operator: 'EndsWith', searchTerms: ['John'] } as ColumnFilter;
const mockFilterChangedArgs = {
columnDef: mockColumn,
columnId: 'gender',
Expand All @@ -323,7 +323,7 @@ describe('GridOdataService', () => {
expect(resetSpy).toHaveBeenCalled();
expect(currentFilters).toEqual([
{ columnId: 'gender', operator: 'EQ', searchTerms: ['female'] },
{ columnId: 'firstName', operator: 'StartsWith', searchTerms: ['John'] }
{ columnId: 'firstName', operator: 'EndsWith', searchTerms: ['John'] }
]);
});

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

it('should return a query with a new filter when previous filters exists when "enablePagination" is set to False', () => {
const expectation = `$filter=(Gender eq 'female' and FirstName eq 'John')`;
const expectation = `$filter=(Gender eq 'female' and startswith(FirstName, 'John'))`;
const querySpy = jest.spyOn(service.odataService, 'buildQuery');
const resetSpy = jest.spyOn(service, 'resetPaginationOptions');
const mockColumn = { id: 'gender', field: 'gender' } as Column;
Expand Down
6 changes: 3 additions & 3 deletions src/aurelia-slickgrid/services/grid-odata.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export class GridOdataService implements BackendService {
const matches = fieldSearchValue.match(/^([<>!=\*]{0,2})(.*[^<>!=\*])([\*]?)$/); // group 1: Operator, 2: searchValue, 3: last char is '*' (meaning starts with, ex.: abc*)
let operator = columnFilter.operator || ((matches) ? matches[1] : '');
let searchValue = (!!matches) ? matches[2] : '';
const lastValueChar = (!!matches) ? matches[3] : (operator === '*z' ? '*' : '');
const lastValueChar = (!!matches) ? matches[3] : (operator === '*z' || operator === OperatorType.endsWith) ? '*' : '';
const bypassOdataQuery = columnFilter.bypassBackendQuery || false;

// no need to query if search value is empty
Expand Down Expand Up @@ -350,9 +350,9 @@ export class GridOdataService implements BackendService {
searchBy = `(${searchBy})`;
}
}
} else if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*') {
} else if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*' || operator === OperatorType.startsWith || operator === OperatorType.endsWith) {
// first/last character is a '*' will be a startsWith or endsWith
searchBy = (operator === '*' || operator === '*z') ? `endswith(${fieldName}, '${searchValue}')` : `startswith(${fieldName}, '${searchValue}')`;
searchBy = (operator === '*' || operator === '*z' || operator === OperatorType.endsWith) ? `endswith(${fieldName}, '${searchValue}')` : `startswith(${fieldName}, '${searchValue}')`;
} else if (fieldType === FieldType.string) {
// string field needs to be in single quotes
if (operator === '' || operator === OperatorType.contains || operator === OperatorType.notContains) {
Expand Down

0 comments on commit 27b8c21

Please sign in to comment.