refactor filter models
This commit is contained in:
parent
3625e29516
commit
4004c4c8f9
@ -9,4 +9,5 @@ export * from './lib/utils/types/tooltip-positions.type';
|
||||
export * from './lib/filtering/filter.service';
|
||||
export * from './lib/filtering/filter-utils';
|
||||
export * from './lib/filtering/models/filter-group.model';
|
||||
export * from './lib/filtering/models/nested-filter.model';
|
||||
export * from './lib/filtering/models/filter.model';
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { FilterModel } from './models/filter.model';
|
||||
import { NestedFilter } from './models/nested-filter.model';
|
||||
import { FilterGroup } from './models/filter-group.model';
|
||||
import { Filter } from './models/filter.model';
|
||||
|
||||
export function processFilters(oldFilters: FilterModel[], newFilters: FilterModel[]) {
|
||||
export function processFilters(oldFilters: NestedFilter[], newFilters: NestedFilter[]) {
|
||||
copySettings(oldFilters, newFilters);
|
||||
if (newFilters) {
|
||||
newFilters.forEach(filter => {
|
||||
@ -11,33 +12,33 @@ export function processFilters(oldFilters: FilterModel[], newFilters: FilterMode
|
||||
return newFilters;
|
||||
}
|
||||
|
||||
function copySettings(oldFilters: FilterModel[], newFilters: FilterModel[]) {
|
||||
function copySettings(oldFilters: NestedFilter[], newFilters: NestedFilter[]) {
|
||||
if (oldFilters && newFilters) {
|
||||
for (const oldFilter of oldFilters) {
|
||||
const newFilter = newFilters.find(f => f.key === oldFilter.key);
|
||||
if (newFilter) {
|
||||
newFilter.checked = oldFilter.checked;
|
||||
newFilter.indeterminate = oldFilter.indeterminate;
|
||||
if (oldFilter.filters && newFilter.filters) copySettings(oldFilter.filters, newFilter.filters);
|
||||
if (oldFilter.children && newFilter.children) copySettings(oldFilter.children, newFilter.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function handleCheckedValue(filter: FilterModel) {
|
||||
if (filter.filters && filter.filters.length) {
|
||||
filter.checked = filter.filters.reduce<boolean>((acc, next) => acc && !!next.checked, true);
|
||||
export function handleCheckedValue(filter: NestedFilter) {
|
||||
if (filter.children && filter.children.length) {
|
||||
filter.checked = filter.children.reduce<boolean>((acc, next) => acc && !!next.checked, true);
|
||||
if (filter.checked) {
|
||||
filter.indeterminate = false;
|
||||
} else {
|
||||
filter.indeterminate = filter.filters.reduce<boolean>((acc, next) => acc || !!next.checked, false);
|
||||
filter.indeterminate = filter.children.reduce<boolean>((acc, next) => acc || !!next.checked, false);
|
||||
}
|
||||
} else {
|
||||
filter.indeterminate = false;
|
||||
}
|
||||
}
|
||||
|
||||
export function checkFilter(entity: any, filters: FilterModel[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
|
||||
export function checkFilter(entity: any, filters: NestedFilter[], validate: Function, validateArgs: any = [], matchAll: boolean = false) {
|
||||
const hasChecked = filters.find(f => f.checked);
|
||||
|
||||
if (validateArgs) {
|
||||
@ -65,7 +66,7 @@ export function checkFilter(entity: any, filters: FilterModel[], validate: Funct
|
||||
return filterMatched;
|
||||
}
|
||||
|
||||
export const keyChecker = (key: string) => (entity: any, filter: FilterModel) => entity[key] === filter.key;
|
||||
export const keyChecker = (key: string) => (entity: any, filter: NestedFilter) => entity[key] === filter.key;
|
||||
|
||||
export function getFilteredEntities<T>(entities: T[], filters: FilterGroup[]) {
|
||||
const filteredEntities: T[] = [];
|
||||
@ -80,3 +81,11 @@ export function getFilteredEntities<T>(entities: T[], filters: FilterGroup[]) {
|
||||
}
|
||||
return filteredEntities;
|
||||
}
|
||||
|
||||
export function flatChildren(filters: NestedFilter[]): Filter[] {
|
||||
return filters.reduce((acc: Filter[], f) => [...acc, ...(f?.children ?? [])], []);
|
||||
}
|
||||
|
||||
export function toFlatFilters(groups: FilterGroup[]): Filter[] {
|
||||
return groups.reduce((acc: Filter[], f) => [...acc, ...f.filters, ...flatChildren(f.filters)], []);
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { processFilters } from './filter-utils';
|
||||
import { processFilters, toFlatFilters } from './filter-utils';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { FilterGroup } from './models/filter-group.model';
|
||||
import { FilterModel } from './models/filter.model';
|
||||
import { NestedFilter } from './models/nested-filter.model';
|
||||
|
||||
@Injectable()
|
||||
export class FilterService {
|
||||
@ -21,7 +21,7 @@ export class FilterService {
|
||||
|
||||
private get _showResetFilters$(): Observable<boolean> {
|
||||
return this.filterGroups$.pipe(
|
||||
map(all => this._toFlatFilters(all)),
|
||||
map(toFlatFilters),
|
||||
map(f => !!f.find(el => el.checked)),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
@ -36,7 +36,7 @@ export class FilterService {
|
||||
if (!filters) return console.error(`Cannot find filter group "${filterGroupSlug}"`);
|
||||
|
||||
let found = filters.find(f => f.key === key);
|
||||
if (!found) found = filters.map(f => f.filters?.find(ff => ff.key === key))[0];
|
||||
if (!found) found = filters.map(f => f.children?.find(ff => ff.key === key))[0];
|
||||
if (!found) return console.error(`Cannot find filter with key "${key}" in group "${filterGroupSlug}"`);
|
||||
|
||||
found.checked = !found.checked;
|
||||
@ -56,7 +56,7 @@ export class FilterService {
|
||||
return this.filterGroups.find(group => group.slug === slug);
|
||||
}
|
||||
|
||||
getFilterModels$(filterGroupSlug: string): Observable<FilterModel[] | undefined> {
|
||||
getFilterModels$(filterGroupSlug: string): Observable<NestedFilter[] | undefined> {
|
||||
return this.getFilterGroup$(filterGroupSlug).pipe(map(f => f?.filters));
|
||||
}
|
||||
|
||||
@ -65,24 +65,14 @@ export class FilterService {
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.filterGroups.forEach(item => {
|
||||
item.filters.forEach(child => {
|
||||
child.checked = false;
|
||||
child.indeterminate = false;
|
||||
child.filters?.forEach(f => {
|
||||
f.checked = false;
|
||||
f.indeterminate = false;
|
||||
});
|
||||
this.filterGroups.forEach(group => {
|
||||
group.filters.forEach(filter => {
|
||||
filter.checked = false;
|
||||
filter.indeterminate = false;
|
||||
filter.children?.forEach(f => (f.checked = false));
|
||||
});
|
||||
});
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
private _toFlatFilters(entities: FilterGroup[]): FilterModel[] {
|
||||
const flatChildren = (filters: FilterModel[]) =>
|
||||
(filters ?? []).reduce((acc: FilterModel[], f) => [...acc, ...(f?.filters ?? [])], []);
|
||||
|
||||
return entities.reduce((acc: FilterModel[], f) => [...acc, ...f.filters, ...flatChildren(f.filters)], []);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { FilterModel } from './filter.model';
|
||||
import { NestedFilter } from './nested-filter.model';
|
||||
import { TemplateRef } from '@angular/core';
|
||||
|
||||
export interface FilterGroup {
|
||||
filters: FilterModel[];
|
||||
filters: NestedFilter[];
|
||||
readonly slug: string;
|
||||
readonly label?: string;
|
||||
readonly icon?: string;
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
export interface FilterModel {
|
||||
export interface Filter {
|
||||
readonly key: string;
|
||||
checked?: boolean;
|
||||
indeterminate?: boolean;
|
||||
expanded?: boolean;
|
||||
matches?: number;
|
||||
readonly label?: string;
|
||||
readonly label: string;
|
||||
readonly icon?: string;
|
||||
readonly topLevelFilter?: boolean;
|
||||
readonly filters?: FilterModel[];
|
||||
readonly checker?: (obj?: unknown) => boolean;
|
||||
readonly required?: boolean;
|
||||
}
|
||||
|
||||
7
src/lib/filtering/models/nested-filter.model.ts
Normal file
7
src/lib/filtering/models/nested-filter.model.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { Filter } from './filter.model';
|
||||
|
||||
export interface NestedFilter extends Filter {
|
||||
expanded?: boolean;
|
||||
indeterminate?: boolean;
|
||||
readonly children?: Filter[];
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"strict": true,
|
||||
"types": [],
|
||||
"lib": ["dom", "es2018"]
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user