diff --git a/src/app/modules/angular-slickgrid/filter-conditions/__tests__/collectionSearchFilterCondition.spec.ts b/src/app/modules/angular-slickgrid/filter-conditions/__tests__/collectionSearchFilterCondition.spec.ts index fcd3bae4d..b866695bc 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/__tests__/collectionSearchFilterCondition.spec.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/__tests__/collectionSearchFilterCondition.spec.ts @@ -93,4 +93,76 @@ describe('executeCollectionSearchFilterCondition method', () => { expect(output1).toBe(false); expect(output2).toBe(false); }); + + it('should return True when input value is found when using "InCollection" searchTerms content (string)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: ['Task2', 'Task3'], fieldType: FieldType.string, searchTerms: ['Task2', 'Task3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return True when input value is found when using "InCollection" searchTerms content (number)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: [2, 3], fieldType: FieldType.number, searchTerms: ['2', '3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return True when input value is found when using "InCollection" searchTerms content (boolean)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: [true], fieldType: FieldType.boolean, searchTerms: ['true', 'false'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return False when input value is not found when using "InCollection" searchTerms content (string)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: ['Task11', 'Task22', 'Task33'], fieldType: FieldType.string, searchTerms: ['Task1', 'Task2', 'Task3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); + + it('should return False when input value is not found when using "InCollection" searchTerms content (number)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: [2, 3], fieldType: FieldType.number, searchTerms: ['4', '5'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); + + it('should return False when input value is not found when using "InCollection" searchTerms content (boolean)', () => { + const options = { dataKey: '', operator: 'IN_COLLECTION', cellValue: [true], fieldType: FieldType.boolean, searchTerms: ['false'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); + + it('should return True when input value is not found when using "NotInCollection" searchTerms content (string)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: ['Task22', 'Task33'], fieldType: FieldType.string, searchTerms: ['Task2', 'Task3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return True when input value is not found when using "NotInCollection" searchTerms content (number)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: [22, 33], fieldType: FieldType.number, searchTerms: ['2', '3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return True when input value is not found when using "NotInCollection" searchTerms content (boolean)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: [true], fieldType: FieldType.boolean, searchTerms: ['false'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(true); + }); + + it('should return False when input value is found when using "NotInCollection" searchTerms content (string)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: ['Task2', 'Task3'], fieldType: FieldType.string, searchTerms: ['Task2', 'Task3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); + + it('should return False when input value is found when using "NotInCollection" searchTerms content (number)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: [2, 3], fieldType: FieldType.number, searchTerms: ['2', '3'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); + + it('should return False when input value is found when using "NotInCollection" searchTerms content (boolean)', () => { + const options = { dataKey: '', operator: 'NOT_IN_COLLECTION', cellValue: [true, false], fieldType: FieldType.boolean, searchTerms: ['true', 'false'] } as FilterConditionOption; + const output = executeCollectionSearchFilterCondition(options); + expect(output).toBe(false); + }); }); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/__tests__/filterUtilities.spec.ts b/src/app/modules/angular-slickgrid/filter-conditions/__tests__/filterUtilities.spec.ts index 8043442ce..912982f0d 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/__tests__/filterUtilities.spec.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/__tests__/filterUtilities.spec.ts @@ -217,5 +217,50 @@ describe('filterUtilities', () => { const output = testFilterCondition('NOT_IN_CONTAINS', 'Task2,Task3', 'Task2'); expect(output).toBeFalsy(); }); + + it('should return True when some of value1 is "IN_COLLECTION" of value2 collection', () => { + const output = testFilterCondition('IN_COLLECTION', ['Task2', 'Task3'], ['Task2']); + expect(output).toBeTruthy(); + }); + + it('should return True when both of value1 is "IN_COLLECTION" of value2 collection', () => { + const output = testFilterCondition('IN_COLLECTION', ['Task2', 'Task3'], ['Task2', 'Task3']); + expect(output).toBeTruthy(); + }); + + it('should return False when none of value1 is "IN_COLLECTION" of value2 collection', () => { + const output = testFilterCondition('IN_COLLECTION', ['Task11', 'Task4'], ['Task 1', 'Task2', 'Task3']); + expect(output).toBeFalsy(); + }); + + it('should return False when is value1 not a collection', () => { + const output = testFilterCondition('IN_COLLECTION', 'Task1,Task4', ['Task2']); + expect(output).toBeFalsy(); + }); + + it('should return False when value2 is not a collection', () => { + const output = testFilterCondition('IN_COLLECTION', ['Task2', 'Task3'], 'Task2'); + expect(output).toBeFalsy(); + }); + + it('should return True when none of value1 is "NOT_IN_COLLECTION" of value2 collection', () => { + const output1 = testFilterCondition('NOT_IN_COLLECTION', ['Task11', 'Task4'], ['Task1', 'Task2', 'Task3']); + expect(output1).toBeTruthy(); + }); + + it('should return False when value1 is not "NOT_IN_COLLECTION" value2 collection', () => { + const output1 = testFilterCondition('NOT_IN_COLLECTION', ['Task2', 'Task3'], ['Task2', 'Task3']); + expect(output1).toBeFalsy(); + }); + + it('should return False when value1 is not a collection', () => { + const output = testFilterCondition('NOT_IN_COLLECTION', 'Task2, Task3', ['Task2']); + expect(output).toBeFalsy(); + }); + + it('should return False when value2 is not a collection', () => { + const output = testFilterCondition('NOT_IN_COLLECTION', ['Task2', 'Task3'], 'Task2'); + expect(output).toBeFalsy(); + }); }); }); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/collectionSearchFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/collectionSearchFilterCondition.ts index 5efb77b54..fe0b6080d 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/collectionSearchFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/collectionSearchFilterCondition.ts @@ -7,7 +7,13 @@ import { testFilterCondition } from './filterUtilities'; */ export const executeCollectionSearchFilterCondition: FilterCondition = (options: FilterConditionOption) => { // multiple-select will always return text, so we should make our cell values text as well - const cellValue = (options.cellValue === undefined || options.cellValue === null) ? '' : `${options.cellValue}`; + const filterOperator = options.operator; + let cellValue: string | string[]; + if (Array.isArray(options.cellValue) && (filterOperator === 'IN_COLLECTION' || filterOperator === 'NOT_IN_COLLECTION')) { + cellValue = (!!options.cellValue.length ? options.cellValue.map(value => `${value}`) : []); + } else { + cellValue = (options.cellValue === undefined || options.cellValue === null) ? '' : `${options.cellValue}`; + } - return testFilterCondition(options.operator || 'IN', cellValue, options.searchTerms || []); + return testFilterCondition(filterOperator || 'IN', cellValue, options.searchTerms || []); }; diff --git a/src/app/modules/angular-slickgrid/filter-conditions/filterUtilities.ts b/src/app/modules/angular-slickgrid/filter-conditions/filterUtilities.ts index 9baf37a89..2645ac1e3 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/filterUtilities.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/filterUtilities.ts @@ -37,6 +37,8 @@ export function isCollectionOperator(operator: OperatorString): boolean { case 'IN_CONTAINS': case 'NIN_CONTAINS': case 'NOT_IN_CONTAINS': + case 'IN_COLLECTION': + case 'NOT_IN_COLLECTION': return true; default: return false; @@ -82,6 +84,16 @@ export const testFilterCondition = (operator: OperatorString, value1: any, value return !value2.some(item => value1.split(/[\s,]+/).includes(item)); } return false; + case 'IN_COLLECTION': + if (value1 && value2 && Array.isArray(value1) && Array.isArray(value2)) { + return value2.some(item => value1.includes(item)); + } + return false; + case 'NOT_IN_COLLECTION': + if (value1 && value2 && Array.isArray(value1) && Array.isArray(value2)) { + return !value2.some(item => value1.includes(item)); + } + return false; } return true; }; diff --git a/src/app/modules/angular-slickgrid/models/operatorString.ts b/src/app/modules/angular-slickgrid/models/operatorString.ts index 4dbe9f939..2a626eda1 100644 --- a/src/app/modules/angular-slickgrid/models/operatorString.ts +++ b/src/app/modules/angular-slickgrid/models/operatorString.ts @@ -1 +1 @@ -export type OperatorString = '' | '<>' | '!=' | '=' | '==' | '>' | '>=' | '<' | '<=' | '*' | 'a*' | '*z' | 'EQ' | 'GE' | 'GT' | 'NE' | 'LE' | 'LT' | 'IN' | 'NIN' | 'NOT_IN' | 'IN_CONTAINS' | 'NIN_CONTAINS' | 'NOT_IN_CONTAINS' | 'NOT_CONTAINS' | 'Not_Contains' | 'CONTAINS' | 'Contains' | 'EndsWith' | 'StartsWith' | 'RangeInclusive' | 'RangeExclusive'; +export type OperatorString = '' | '<>' | '!=' | '=' | '==' | '>' | '>=' | '<' | '<=' | '*' | 'a*' | '*z' | 'EQ' | 'GE' | 'GT' | 'NE' | 'LE' | 'LT' | 'IN' | 'NIN' | 'NOT_IN' | 'IN_CONTAINS' | 'NIN_CONTAINS' | 'NOT_IN_CONTAINS' | 'NOT_CONTAINS' | 'Not_Contains' | 'CONTAINS' | 'Contains' | 'EndsWith' | 'StartsWith' | 'RangeInclusive' | 'RangeExclusive' | 'IN_COLLECTION' | 'NOT_IN_COLLECTION'; diff --git a/src/app/modules/angular-slickgrid/models/operatorType.enum.ts b/src/app/modules/angular-slickgrid/models/operatorType.enum.ts index 22e359b7f..e2db6404d 100644 --- a/src/app/modules/angular-slickgrid/models/operatorType.enum.ts +++ b/src/app/modules/angular-slickgrid/models/operatorType.enum.ts @@ -59,4 +59,10 @@ export enum OperatorType { /** Inversed (Not In) of substring contained inside a collection */ notInContains = 'NOT_IN_CONTAINS', + + /** Find a value from within a collection inside another collection */ + inCollection = 'IN_COLLECTION', + + /** Inversed (Not In) of looking for a value from a collection inside another collection */ + notInCollection = 'NOT_IN_COLLECTION', }