RED-6408, rewrite service from scratch.

This commit is contained in:
George 2023-07-12 14:12:49 +03:00
parent a8f5fb2e25
commit 4fede31e8c

View File

@ -0,0 +1,66 @@
import { computed, Injectable, signal } from '@angular/core';
const PARENT_PROPS = ['children', 'indeterminate', 'expanded'] as const;
const PARENT_FILTER_ID = 'parentFilterId';
type ParentProps = (typeof PARENT_PROPS)[number];
type ChildFilter = Omit<Filter, ParentProps> & { [PARENT_FILTER_ID]: string };
interface Filter {
id: string;
label: string;
expanded: boolean;
indeterminate: boolean;
checked: boolean;
disabled: boolean;
meta: Record<string, unknown> | undefined;
children: Record<string, ChildFilter> | undefined;
}
interface FilterGroup {
name: string;
label: string;
filters: Record<string, Filter>;
}
const safeObj = <T>(obj: T | undefined) => obj ?? ({} as T);
const getFiltersWithChildren = (filters: Filter[]) => filters.flatMap(filter => [filter, ...Object.values(safeObj(filter.children))]);
const isChild = (filter: Filter | ChildFilter): filter is ChildFilter => PARENT_FILTER_ID in filter;
@Injectable()
export class FilterService {
readonly #filterGroups = signal<Record<string, FilterGroup> | undefined>(undefined);
readonly filterGroups = this.#filterGroups.asReadonly();
addFilterGroup(newFilterGroup: FilterGroup) {
this.#filterGroups.update(filterGroups => ({ ...safeObj(filterGroups), [newFilterGroup.name]: newFilterGroup }));
}
updateFilterGroup(name: string, updates: Partial<Omit<FilterGroup, 'name'>>) {
this.#filterGroups.update(filterGroups => {
const current = safeObj(filterGroups)[name];
if (!current) {
console.warn('[Filter service] Cannot update non-existent group: ', name);
return filterGroups;
}
return { ...filterGroups, [name]: { ...current, ...updates } };
});
}
removeFilterGroup(name: string) {
this.#filterGroups.update(filterGroups => {
if (!filterGroups) return undefined;
const { [name]: _, ...rest } = filterGroups;
return Object.keys(rest) ? rest : undefined;
});
}
addFilterToGroup(groupName: string, filter: Filter) {
this.#filterGroups.update(filterGroups => {
const current = safeObj(filterGroups)[groupName];
if (!current) {
console.warn('[Filter service] Cannot add filter to non-existent group: ', groupName);
return filterGroups;
}
return { ...filterGroups, [groupName]: { ...current, filters: { ...current.filters, [filter.id]: filter } } };
});
}
}