Skip to content

Commit

Permalink
fix(filters): Grid State filters should always include an operator (#676
Browse files Browse the repository at this point in the history
)

* fix(filters): Grid State filters should always include an operator
  • Loading branch information
ghiscoding authored Jan 19, 2021
1 parent 7da18ff commit 9ded204
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 26 deletions.
14 changes: 10 additions & 4 deletions src/app/modules/angular-slickgrid/models/filter.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ export interface Filter {
/** SlickGrid grid object */
grid: any;

/** Array of defined search terms to pre-load */
searchTerms?: SearchTerm[];
/** The default search operator for the filter when not provided */
defaultOperator?: OperatorString | OperatorType;

/** The search operator for the filter */
operator: OperatorType | OperatorString;

/** You can use "params" to pass any types of arguments to your Filter */
/** You can use "params" to pass any generic arguments to your Filter */
params?: any | any[];

/** Array of defined search terms to pre-load */
searchTerms?: SearchTerm[];

// --
// public functions

/** Filter class initialization, executed by the FilterService right after creating the Filter */
init: (args: FilterArguments, isFilterFirstRender?: boolean) => void;

Expand All @@ -42,5 +48,5 @@ export interface Filter {
getValues?: () => SearchTerm | SearchTerm[] | undefined;

/** Set value(s) on the DOM element */
setValues: (values: SearchTerm | SearchTerm[] | undefined) => void;
setValues: (values: SearchTerm | SearchTerm[] | undefined, operator?: OperatorType | OperatorString) => void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import { of, throwError } from 'rxjs';
import {
BackendService,
Column,
ColumnFilters,
CurrentFilter,
FieldType,
GridMenuItem,
GridOption,
FieldType,
MenuCommandItem,
SlickEventHandler,
} from '../../models';
import { Filters } from '../../filters';
import { FilterService } from '../filter.service';
import { FilterFactory } from '../../filters/filterFactory';
import { SharedService } from '../shared.service';
import { SlickgridConfig, CollectionService } from '../..';
import { CollectionService, SlickgridConfig } from '../../index';
import * as utilities from '../../services/backend-utilities';

const mockRefreshBackendDataset = jest.fn();
Expand Down Expand Up @@ -1361,11 +1362,11 @@ describe('FilterService', () => {
gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub);
gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub);

const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', searchTerms: ['map'] } };
const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', operator: 'Contains', searchTerms: ['map'] } };
service.updateFilters([{ columnId: 'file', operator: '', searchTerms: ['map'] }], true, true, true);
const output = service.customLocalFilter(mockItem1, { dataView: dataViewStub, grid: gridStub, columnFilters });

expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', searchTerms: ['map',] }]);
expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', operator: 'Contains', searchTerms: ['map',] }]);
expect(output).toBe(true);
expect(preFilterSpy).toHaveBeenCalledWith(dataset, columnFilters);
expect(preFilterSpy).toHaveReturnedWith([21, 4, 5]);
Expand All @@ -1385,11 +1386,11 @@ describe('FilterService', () => {
gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub);
gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub);

const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', searchTerms: ['map'] } };
const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', operator: 'Contains', searchTerms: ['map'] } };
service.updateFilters([{ columnId: 'file', operator: '', searchTerms: ['map'] }], true, true, true);
const output = service.customLocalFilter(mockItem1, { dataView: dataViewStub, grid: gridStub, columnFilters });

expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', searchTerms: ['map',] }]);
expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', operator: 'Contains', searchTerms: ['map',] }]);
expect(output).toBe(false);
expect(preFilterSpy).toHaveBeenCalledWith(dataset, columnFilters);
expect(preFilterSpy).toHaveReturnedWith([21, 4, 5]);
Expand All @@ -1409,13 +1410,13 @@ describe('FilterService', () => {
gridStub.onHeaderRowCellRendered.notify(mockArgs1, new Slick.EventData(), gridStub);
gridStub.onHeaderRowCellRendered.notify(mockArgs2, new Slick.EventData(), gridStub);

const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', searchTerms: ['unknown'] } };
const columnFilters = { file: { columnDef: mockColumn1, columnId: 'file', searchTerms: ['unknown'] } } as ColumnFilters;
service.updateFilters([{ columnId: 'file', operator: '', searchTerms: ['unknown'] }], true, true, true);
const output = service.customLocalFilter(mockItem1, { dataView: dataViewStub, grid: gridStub, columnFilters });

expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', searchTerms: ['unknown',] }]);
expect(spyRxjs).toHaveBeenCalledWith([{ columnId: 'file', operator: 'Contains', searchTerms: ['unknown',] }]);
expect(output).toBe(false);
expect(preFilterSpy).toHaveBeenCalledWith(dataset, columnFilters);
expect(preFilterSpy).toHaveBeenCalledWith(dataset, { ...columnFilters, file: { ...columnFilters.file, operator: 'Contains' } }); // it will use Contains by default
expect(preFilterSpy).toHaveReturnedWith([]);
});
});
Expand Down
15 changes: 7 additions & 8 deletions src/app/modules/angular-slickgrid/services/filter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
SlickEventHandler,
} from './../models/index';
import { executeBackendCallback, refreshBackendDataset } from './backend-utilities';
import { getDescendantProperty } from './utilities';
import { getDescendantProperty, mapOperatorByFieldType } from './utilities';
import { FilterConditions } from './../filter-conditions';
import { FilterFactory } from '../filters/filterFactory';
import { SharedService } from './shared.service';
Expand All @@ -43,7 +43,7 @@ export class FilterService {
private _eventHandler: SlickEventHandler;
private _isFilterFirstRender = true;
private _firstColumnIdRendered = '';
private _filtersMetadata: any[] = [];
protected _filtersMetadata: Array<Filter> = [];
private _columnFilters: ColumnFilters = {};
private _grid: any;
private _onSearchChange: SlickEvent | null;
Expand Down Expand Up @@ -130,7 +130,7 @@ export class FilterService {
if (Array.isArray(this._filtersMetadata)) {
this._filtersMetadata.forEach((filter) => {
if (filter && filter.destroy) {
filter.destroy(true);
filter.destroy();
}
});
}
Expand Down Expand Up @@ -228,7 +228,7 @@ export class FilterService {
}

// find the filter object and call its clear method with true (the argument tells the method it was called by a clear filter)
const colFilter: Filter = this._filtersMetadata.find((filter: Filter) => filter.columnDef.id === columnId);
const colFilter: Filter | undefined = this._filtersMetadata.find((filter: Filter) => filter.columnDef.id === columnId);
if (colFilter && colFilter.clear) {
colFilter.clear(true);
}
Expand Down Expand Up @@ -830,6 +830,7 @@ export class FilterService {
const searchTerms = (args.searchTerms && Array.isArray(args.searchTerms)) ? args.searchTerms : (searchTerm ? [searchTerm] : undefined);
const columnDef = args.columnDef || null;
const columnId = columnDef && columnDef.id || '';
const fieldType = columnDef && columnDef.filter && columnDef.filter.type || columnDef && columnDef.type || FieldType.string;
const operator = args.operator || undefined;
const hasSearchTerms = searchTerms && Array.isArray(searchTerms);
const termsCount = hasSearchTerms && searchTerms && searchTerms.length;
Expand All @@ -847,9 +848,7 @@ export class FilterService {
columnDef,
searchTerms,
};
if (operator) {
colFilter.operator = operator;
}
colFilter.operator = operator || mapOperatorByFieldType(fieldType);
this._columnFilters[colId] = colFilter;
}
}
Expand All @@ -868,7 +867,7 @@ export class FilterService {
columnId,
columnDef,
columnFilters: this._columnFilters,
operator,
operator: operator || mapOperatorByFieldType(fieldType),
searchTerms,
grid: this._grid
}, eventData);
Expand Down
2 changes: 1 addition & 1 deletion test/cypress/integration/example05.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ describe('Example 5 - OData Grid', () => {

cy.window().then((win) => {
expect(win.console.log).to.have.callCount(2);
expect(win.console.log).to.be.calledWith('Client sample, Grid State changed:: ', { newValues: [{ columnId: 'name', searchTerms: ['x'] }], type: 'filter' });
expect(win.console.log).to.be.calledWith('Client sample, Grid State changed:: ', { newValues: [{ columnId: 'name', operator: 'Contains', searchTerms: ['x'] }], type: 'filter' });
expect(win.console.log).to.be.calledWith('Client sample, Grid State changed:: ', { newValues: { pageNumber: 1, pageSize: 10 }, type: 'pagination' });
});
});
Expand Down
2 changes: 1 addition & 1 deletion test/cypress/integration/example08.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('Example 8 - Header Menu Plugin', () => {
cy.get('#grid8')
.find('.slick-row .slick-cell:nth(2)')
.each($row => {
expect(+$row.text()).to.be.greaterThan(80);
expect(+$row.text()).to.be.greaterThan(60);
});
});

Expand Down
6 changes: 3 additions & 3 deletions test/cypress/integration/example10.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ describe('Example 10 - Multiple Grids with Row Selection', () => {

cy.window().then((win) => {
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', searchTerms: ['3'] }], type: 'filter' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'] }], type: 'filter' });
});
});

Expand Down Expand Up @@ -678,7 +678,7 @@ describe('Example 10 - Multiple Grids with Row Selection', () => {
cy.window().then((win) => {
expect(win.console.log).to.have.callCount(4);
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', searchTerms: ['3'] }], type: 'filter' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'] }], type: 'filter' });
});
});

Expand Down Expand Up @@ -755,7 +755,7 @@ describe('Example 10 - Multiple Grids with Row Selection', () => {
cy.window().then((win) => {
expect(win.console.log).to.have.callCount(4);
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: { gridRowIndexes: [0, 1], dataContextIds: [3, 12, 13, 522, 1], filteredDataContextIds: [3, 13] }, type: 'rowSelection' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', searchTerms: ['3'] }], type: 'filter' });
expect(win.console.log).to.be.calledWith("Grid State changed:: ", { newValues: [{ columnId: 'title', operator: 'Contains', searchTerms: ['3'] }], type: 'filter' });
});
});
});
Expand Down

0 comments on commit 9ded204

Please sign in to comment.