src/app/core/filter/filters/filters.ts
Generic configuration for a filter with different selectable FilterSelectionOption options.
This is a reusable format for any kind of dropdown or selection component that offers the user a choice to narrow down a list of data items. As the filter function is provided as part of each FilterSelectionOption an instance of this FilterSelection class can manage all filter selection logic.
Properties |
|
Methods |
|
constructor(name: string, options: FilterSelectionOption<T>[], label: string)
|
||||||||||||||||
Defined in src/app/core/filter/filters/filters.ts:93
|
||||||||||||||||
Create a FilterSelection with different options to be selected. (optional, defaults to the name of the selection)
Parameters :
|
Public label |
Type : string
|
Default value : name
|
Inherited from
Filter
|
Defined in
Filter:105
|
The user-friendly label describing this filter-selection
(optional, defaults to the name of the selection)
|
Public name |
Type : string
|
Inherited from
Filter
|
Defined in
Filter:103
|
The name or id describing this filter
|
Public options |
Type : FilterSelectionOption<T>[]
|
Defined in src/app/core/filter/filters/filters.ts:104
|
An array of different filtering variants to chose between
|
component |
Type : Type<any>
|
Default value : ListFilterComponent
|
Inherited from
Filter
|
Defined in
Filter:35
|
The component used to display filter option to the user. |
selectedOptionChange |
Default value : new EventEmitter<string[]>()
|
Inherited from
Filter
|
Defined in
Filter:45
|
Triggered when this filter changes value (e.g. when the user selects a new value in a FilterComponent). This is part of the filter object because dynamic filter components can't expose @Outputs |
Public selectedOptionValues |
Type : string[]
|
Default value : []
|
Inherited from
Filter
|
Defined in
Filter:37
|
Static generateOptions | ||||||||||||
generateOptions(valuesToMatchAsOptions: (string | number)[], attributeName: string)
|
||||||||||||
Defined in src/app/core/filter/filters/filters.ts:77
|
||||||||||||
Type parameters :
|
||||||||||||
Generate filter options dynamically from the given value to be matched. This is a utility function to make it easier to generate FilterSelectionOptions for standard cases if you simply want each option to filter items having the given attribute matching different values. If you have more sophisticated filtering needs, use the constructor to set FilterSelectionOptions that you created yourself. Example :
Parameters :
Returns :
FilterSelectionOption[]
|
Public getFilter |
getFilter()
|
Inherited from
Filter
|
Defined in
Filter:125
|
Get the filter query for the given option. If the given key is undefined or invalid, the returned filter matches any elements.
Returns :
DataFilter<T>
|
getOption | ||||||||
getOption(key: string)
|
||||||||
Defined in src/app/core/filter/filters/filters.ts:115
|
||||||||
Get the full filter option by its key.
Parameters :
Returns :
FilterSelectionOption | undefined
|
import { Entity } from "../../entity/model/entity";
import { MongoQuery } from "@casl/ability";
import { ListFilterComponent } from "../list-filter/list-filter.component";
import { EventEmitter, Type } from "@angular/core";
/**
* This filter can be used to filter an array of entities.
* It has to follow the MongoDB Query Syntax {@link https://www.mongodb.com/docs/manual/reference/operator/query/}.
*
* The filter is parsed using ucast {@link https://github.com/stalniy/ucast/tree/master/packages/mongo2js}
*/
export type DataFilter<T> = MongoQuery<T> | {};
export abstract class Filter<T extends Entity> {
/**
* The component used to display filter option to the user.
*/
component: Type<any> = ListFilterComponent;
public selectedOptionValues: string[] = [];
/**
* Triggered when this filter changes value
* (e.g. when the user selects a new value in a FilterComponent).
*
* This is part of the filter object because dynamic filter components can't expose @Outputs
*/
selectedOptionChange = new EventEmitter<string[]>();
protected constructor(
public name: string,
public label: string = name,
) {}
abstract getFilter(): DataFilter<T>;
}
/**
* Generic configuration for a filter with different selectable {@link FilterSelectionOption} options.
*
* This is a reusable format for any kind of dropdown or selection component that offers the user a choice
* to narrow down a list of data items.
* As the filter function is provided as part of each {@link FilterSelectionOption}
* an instance of this FilterSelection class can manage all filter selection logic.
*/
export class SelectableFilter<T extends Entity> extends Filter<T> {
/**
* Generate filter options dynamically from the given value to be matched.
*
* This is a utility function to make it easier to generate {@link FilterSelectionOption}s for standard cases
* if you simply want each option to filter items having the given attribute matching different values.
* If you have more sophisticated filtering needs, use the constructor to set {@link FilterSelectionOption}s that
* you created yourself.
*
* @param valuesToMatchAsOptions An array of values to be matched.
* A separate FilterSelectionOption is created for each value with a filter
* that is true of a data item's property exactly matches that value.
* @param attributeName The name of the property of a data item that is compared to the value in the filter function.
*/
public static generateOptions<T extends Entity>(
valuesToMatchAsOptions: (string | number)[],
attributeName: string,
): FilterSelectionOption<T>[] {
let keys = new Set();
return (
valuesToMatchAsOptions
.filter((k) => !!k)
.map((k) => ({
key: k.toString().toLowerCase(),
label: k.toString(),
filter: { [attributeName]: k } as DataFilter<T>,
}))
// remove duplicates:
.filter((value) => !keys.has(value.key) && keys.add(value.key))
);
}
/**
* Create a FilterSelection with different options to be selected.
* @param name The name or id describing this filter
* @param options An array of different filtering variants to chose between
* @param label The user-friendly label describing this filter-selection
* (optional, defaults to the name of the selection)
*/
constructor(
public override name: string,
public options: FilterSelectionOption<T>[],
public override label: string = name,
) {
super(name, label);
this.selectedOptionValues = [];
}
/**
* Get the full filter option by its key.
* @param key The identifier of the requested option
*/
getOption(key: string): FilterSelectionOption<T> | undefined {
return this.options.find((option: FilterSelectionOption<T>): boolean => {
return option.key === key;
});
}
/**
* Get the filter query for the given option.
* If the given key is undefined or invalid, the returned filter matches any elements.
*/
public getFilter(): DataFilter<T> {
const filters: DataFilter<T>[] = this.selectedOptionValues
.map((value: string) => this.getOption(value))
.filter((value: FilterSelectionOption<T>) => value !== undefined)
.map((previousValue: FilterSelectionOption<T>) => {
return previousValue.filter as DataFilter<T>;
});
if (filters.length === 0) {
return {} as DataFilter<T>;
}
return {
$or: [...filters],
} as unknown as DataFilter<T>;
}
}
/**
* Represents one specific option to filter data in a certain way.
* used by {@link SelectableFilter}
*/
export interface FilterSelectionOption<T> {
/** identifier for this option in the parent FilterSelection instance */
key: string;
/** label displayed for this option to the user in the UI */
label: string;
/** Optional color */
color?: string;
/**
* The filter query which should be used if this filter is selected
*/
filter: DataFilter<T>;
}