Skip to content

Commit

Permalink
feat: added searchStringFilterFunction()
Browse files Browse the repository at this point in the history
  • Loading branch information
dereekb committed Jun 21, 2022
1 parent 9406bfc commit f91aaaf
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { FormlyFieldConfig } from '@ngx-formly/core';
import { Maybe } from '@dereekb/util';
import { Maybe, searchStringFilterFunction, SearchStringFilterFunction, caseInsensitiveFilterByIndexOfDecisionFactory } from '@dereekb/util';
import { Observable, of } from 'rxjs';
import { LabeledFieldConfig, formlyField, propsForFieldConfig } from '../../field';
import { PickableValueFieldDisplayValue } from './pickable';
import { PickableItemFieldItem, PickableValueFieldsFieldProps } from './pickable.field.directive';
export { PickableItemFieldItem };

export const filterPickableItemFieldValuesByLabelFilterFunction: SearchStringFilterFunction<PickableValueFieldDisplayValue<any>> = searchStringFilterFunction({
readStrings: (x) => [x.label],
decisionFactory: caseInsensitiveFilterByIndexOfDecisionFactory
});

export function filterPickableItemFieldValuesByLabel<T>(filterText: Maybe<string>, values: PickableValueFieldDisplayValue<T>[]): Observable<T[]> {
let filteredValues: PickableValueFieldDisplayValue<T>[];

if (filterText) {
const searchString = filterText.toLocaleLowerCase();
filteredValues = values.filter((x) => x.label.toLocaleLowerCase().indexOf(searchString) !== -1);
filteredValues = filterPickableItemFieldValuesByLabelFilterFunction(filterText, values);
} else {
filteredValues = values;
}
Expand Down
21 changes: 20 additions & 1 deletion packages/util/src/lib/array/array.string.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { containsAllStringsAnyCase, containsAnyStringAnyCase, containsStringAnyCase, findUniqueCaseInsensitiveStrings, findUniqueTransform, TransformSingleStringFunction } from './array.string';
import { containsAllStringsAnyCase, containsAnyStringAnyCase, containsStringAnyCase, findUniqueCaseInsensitiveStrings, findUniqueTransform, searchStringFilterFunction, TransformSingleStringFunction, caseInsensitiveFilterByIndexOfDecisionFactory } from './array.string';

describe('findUniqueCaseInsensitiveStrings', () => {
it('should return only the strings that are unique from the array.', () => {
Expand Down Expand Up @@ -137,3 +137,22 @@ describe('findUniqueTransform', () => {
});
});
});

describe('searchStringFilterFunction', () => {
describe('function', () => {
const filterFunction = searchStringFilterFunction<string>({
readStrings: (x: string) => [x],
decisionFactory: caseInsensitiveFilterByIndexOfDecisionFactory
});

it('should return the values that match the filter', () => {
const filterText = 'a';
const values = ['a', 'AA', 'b'];

const result = filterFunction(filterText, values);
expect(result).toContain('a');
expect(result).toContain('AA');
expect(result).not.toContain('b');
});
});
});
34 changes: 32 additions & 2 deletions packages/util/src/lib/array/array.string.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { flattenArray } from './array';
import { unique, findUnique } from './array.unique';
import { ReadKeyFunction } from '../key';
import { ReadKeyFunction, ReadKeysFunction } from '../key';
import { caseInsensitiveString } from '../string';
import { containsAllValues, containsAnyValue, hasDifferentValues } from '../set/set';
import { mapIterable } from '../iterable/iterable.map';
import { mapArrayFunction, MapFunction, mapIdentityFunction } from '../value';
import { DecisionFunction, DecisionFunctionFactory, mapArrayFunction, MapFunction, mapIdentityFunction } from '../value';

export function hasDifferentStringsNoCase(a: string[], b: string[]): boolean {
return hasDifferentValues(a.map(caseInsensitiveString), b.map(caseInsensitiveString));
Expand Down Expand Up @@ -97,3 +97,33 @@ export function findUniqueTransform(config: FindUniqueStringsTransformConfig): F
return (input: string[]) => Array.from(new Set(transform(input)));
}
}

// MARK: Search Strings
/**
* Filters values by the input filter text.
*/
export type SearchStringFilterFunction<T> = (filterText: string, values: T[]) => T[];

export interface SearchStringFilterConfig<T> {
readStrings: ReadKeysFunction<T, string>;
decisionFactory: DecisionFunctionFactory<string, string>;
}

export function searchStringFilterFunction<T>(config: SearchStringFilterConfig<T>): SearchStringFilterFunction<T> {
const { readStrings, decisionFactory } = config;

return (filterText: string, values: T[]) => {
const decision = decisionFactory(filterText);

return values.filter((value: T) => {
const strings = readStrings(value);
const keep = strings.findIndex(decision) !== -1;
return keep;
});
};
}

export const caseInsensitiveFilterByIndexOfDecisionFactory: DecisionFunctionFactory<string, string> = (filterText: string) => {
const searchString = filterText.toLocaleLowerCase();
return (string: string) => string.toLocaleLowerCase().indexOf(searchString) !== -1;
};
10 changes: 10 additions & 0 deletions packages/util/src/lib/value/decision.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FactoryWithRequiredInput } from '../getter/getter';
import { MapFunction, AsyncMapFunction } from './map';

/**
* A map function that derives a boolean from the input.
*/
export type DecisionFunction<I> = MapFunction<I, boolean>;
export type AsyncDecisionFunction<I> = AsyncMapFunction<DecisionFunction<I>>;

export type DecisionFunctionFactory<C, I> = FactoryWithRequiredInput<DecisionFunction<I>, C>;
1 change: 1 addition & 0 deletions packages/util/src/lib/value/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './build';
export * from './decision';
export * from './equal';
export * from './map';
export * from './maybe.type';
Expand Down
7 changes: 0 additions & 7 deletions packages/util/src/lib/value/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,3 @@ export function mapFunctionOutput<O extends object, I = unknown>(output: O, inpu
}
});
}

// MARK: MapTypes
/**
* A map function that derives a boolean from the input.
*/
export type DecisionFunction<I> = MapFunction<I, boolean>;
export type AsyncDecisionFunction<I> = AsyncMapFunction<DecisionFunction<I>>;
2 changes: 1 addition & 1 deletion setup/templates/components/app/project.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"projectType": "library",
"sourceRoot": "ANGULAR_COMPONENTS_FOLDER/src",
"prefix": "ANGULAR_APP_PREFIX",
"prefix": "APP_CODE_PREFIX_LOWER",
"targets": {
"build": {
"executor": "@nrwl/workspace:run-commands",
Expand Down

0 comments on commit f91aaaf

Please sign in to comment.