RED-6408, get UI to run without errors.

This commit is contained in:
George 2023-07-10 19:34:47 +03:00
parent 9e0c31992a
commit 41d19013ad
5 changed files with 35 additions and 63 deletions

View File

@ -1,4 +1,4 @@
<ng-container *ngIf="primaryFilterGroup$ | async as primaryGroup">
<ng-container *ngIf="primaryFilterGroup() as primaryGroup">
<iqser-input-with-action
*ngIf="primaryGroup.filterceptionPlaceholder"
[(value)]="searchService.searchValue"
@ -9,19 +9,19 @@
<ng-container *ngTemplateOutlet="filterHeader"></ng-container>
<div *ngIf="primaryFilters$ | async as filters" class="filter-content">
<div *ngIf="primaryFilters() as filters" class="filter-content">
<ng-container
*ngFor="let filter of filters"
[ngTemplateOutletContext]="{
filter: filter,
filterGroup: primaryGroup,
atLeastOneIsExpandable: atLeastOneFilterIsExpandable$ | async
atLeastOneIsExpandable: atLeastOneFilterIsExpandable()
}"
[ngTemplateOutlet]="defaultFilterTemplate"
></ng-container>
</div>
<div *ngIf="secondaryFilterGroup$ | async as secondaryGroup" class="filter-options">
<div *ngIf="secondaryFilterGroup() as secondaryGroup" class="filter-options">
<div class="filter-menu-options">
<div class="all-caps-label" translate="filter-menu.filter-options"></div>
</div>
@ -31,7 +31,7 @@
[ngTemplateOutletContext]="{
filter: filter,
filterGroup: secondaryGroup,
atLeastOneIsExpandable: atLeastOneSecondaryFilterIsExpandable$ | async
atLeastOneIsExpandable: atLeastOneSecondaryFilterIsExpandable()
}"
[ngTemplateOutlet]="defaultFilterTemplate"
></ng-container>
@ -44,7 +44,7 @@
<!--TODO: move to separate component-->
<ng-template #filterHeader>
<div *ngIf="primaryFilterGroup$ | async as primaryGroup" class="filter-menu-header">
<div *ngIf="primaryFilterGroup() as primaryGroup" class="filter-menu-header">
<div [translateParams]="{ count: primaryGroup.filters.length }" [translate]="primaryFiltersLabel" class="all-caps-label"></div>
<div class="actions">
<div

View File

@ -1,13 +1,9 @@
import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, Input, OnInit, TemplateRef } from '@angular/core';
import { Observable, pipe } from 'rxjs';
import { IFilter } from '../models/filter.model';
import { INestedFilter } from '../models/nested-filter.model';
import { IFilterGroup } from '../models/filter-group.model';
import { extractFilterValues, handleCheckedValue } from '../filter-utils';
import { FilterService } from '../filter.service';
import { SearchService } from '../../search';
import { map } from 'rxjs/operators';
import { shareDistinctLast } from '../../utils';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
import { toSignal } from '@angular/core/rxjs-interop';
@ -61,16 +57,16 @@ export class FilterCardComponent implements OnInit {
@Input() primaryFiltersLabel: string = _('filter-menu.filter-types');
@Input() minWidth = 350;
protected readonly searchService = inject(SearchService);
readonly #filterService = inject(FilterService);
readonly #searchService = inject(SearchService);
readonly #elementRef = inject(ElementRef);
readonly #searchValueChanged = toSignal(this.#searchService.valueChanges$);
readonly #searchValueChanged = toSignal(this.searchService.valueChanges$);
readonly primaryFilterGroup = computed(() => this.#filterService.getGroup(this.primaryFiltersSlug));
readonly secondaryFilterGroup = computed(() => this.#filterService.getGroup(this.secondaryFiltersSlug));
primaryFilters = computed(() => {
this.#searchValueChanged();
return this.#searchService.searchIn(this.primaryFilterGroup()?.filters ?? []);
return this.searchService.searchIn(this.primaryFilterGroup()?.filters ?? []);
});
atLeastOneFilterIsExpandable = computed(() => atLeastOneIsExpandable(this.primaryFilterGroup()));

View File

@ -1,32 +1,32 @@
<ng-container *ngIf="primaryFilterGroup$ | async as primaryGroup">
<ng-container *ngIf="primaryFilterGroup() as primaryGroup">
<ng-container *ngIf="primaryGroup.icon">
<iqser-icon-button
[attr.aria-expanded]="expanded$ | async"
[class.disabled]="primaryFiltersDisabled$ | async"
[disabled]="primaryFiltersDisabled$ | async"
[attr.aria-expanded]="expanded()"
[class.disabled]="primaryFiltersDisabled()"
[disabled]="primaryFiltersDisabled()"
[icon]="primaryGroup.icon"
[label]="primaryGroup.label?.capitalize() || ('filter-menu.label' | translate)"
[matMenuTriggerFor]="filterMenu"
[showDot]="hasActiveFilters$ | async"
[showDot]="hasActiveFilters()"
buttonId="{{ primaryGroup.slug }}"
></iqser-icon-button>
</ng-container>
<ng-container *ngIf="!primaryGroup.icon">
<iqser-chevron-button
[attr.aria-expanded]="expanded$ | async"
[class.disabled]="primaryFiltersDisabled$ | async"
[disabled]="primaryFiltersDisabled$ | async"
[attr.aria-expanded]="expanded()"
[class.disabled]="primaryFiltersDisabled()"
[disabled]="primaryFiltersDisabled()"
[label]="primaryGroup.label?.capitalize() || ('filter-menu.label' | translate)"
[matMenuTriggerFor]="filterMenu"
[showDot]="hasActiveFilters$ | async"
[showDot]="hasActiveFilters()"
></iqser-chevron-button>
</ng-container>
<mat-menu
#filterMenu="matMenu"
(close)="expanded.next(false)"
[class]="(secondaryFilterGroup$ | async)?.filters.length > 0 ? 'padding-bottom-0' : ''"
(close)="expanded.set(false)"
[class]="secondaryFilterGroup()?.filters.length > 0 ? 'padding-bottom-0' : ''"
xPosition="before"
>
<div id="workload-filters">

View File

@ -1,9 +1,5 @@
import { ChangeDetectionStrategy, Component, Input, OnInit, TemplateRef } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { delay, map } from 'rxjs/operators';
import { shareDistinctLast, shareLast, some } from '../../utils';
import { ChangeDetectionStrategy, Component, computed, inject, Input, OnInit, signal, Signal, TemplateRef } from '@angular/core';
import { FilterService } from '../filter.service';
import { IFilterGroup } from '../models/filter-group.model';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@Component({
@ -12,43 +8,22 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
styleUrls: ['./popup-filter.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PopupFilterComponent implements OnInit {
export class PopupFilterComponent {
@Input() primaryFiltersSlug!: string;
@Input() fileId?: string;
@Input() actionsTemplate?: TemplateRef<unknown>;
@Input() secondaryFiltersSlug = '';
@Input() primaryFiltersLabel: string = _('filter-menu.filter-types');
readonly expanded = new BehaviorSubject<boolean>(false);
readonly expanded$ = this.expanded.asObservable().pipe(delay(200));
readonly #filterService = inject(FilterService);
protected readonly expanded = signal(false);
hasActiveFilters$!: Observable<boolean>;
primaryFilterGroup$!: Observable<IFilterGroup | undefined>;
secondaryFilterGroup$!: Observable<IFilterGroup | undefined>;
primaryFiltersDisabled$!: Observable<boolean>;
constructor(readonly filterService: FilterService) {}
private get _hasActiveFilters$() {
return combineLatest([this.primaryFilterGroup$, this.secondaryFilterGroup$]).pipe(
map(([primary, secondary]) => [...(primary?.filters || []), ...(secondary?.filters || [])]),
some(f => f.checked || !!f.indeterminate),
shareDistinctLast(),
);
}
private get _primaryFiltersDisabled$(): Observable<boolean> {
return this.primaryFilterGroup$.pipe(
map(group => group?.filters?.length === 0),
shareDistinctLast(),
);
}
ngOnInit(): void {
this.primaryFilterGroup$ = this.filterService.getGroup$(this.primaryFiltersSlug).pipe(shareLast());
this.secondaryFilterGroup$ = this.filterService.getGroup$(this.secondaryFiltersSlug).pipe(shareLast());
this.hasActiveFilters$ = this._hasActiveFilters$;
this.primaryFiltersDisabled$ = this._primaryFiltersDisabled$;
}
protected readonly primaryFilterGroup = computed(() => this.#filterService.getGroup(this.primaryFiltersSlug));
protected readonly secondaryFilterGroup = computed(() => this.#filterService.getGroup(this.secondaryFiltersSlug));
protected readonly primaryFiltersDisabled = computed(() => this.primaryFilterGroup()?.filters?.length === 0);
protected readonly hasActiveFilters = computed(() =>
[...(this.primaryFilterGroup()?.filters || []), ...(this.secondaryFilterGroup()?.filters || [])].some(
f => f.checked || !!f.indeterminate,
),
);
}

View File

@ -7,6 +7,7 @@ import { Id, IListable } from '../models';
import { EntitiesService } from './entities.service';
import { getLength, shareDistinctLast, shareLast, some } from '../../utils';
import { SortingService } from '../../sorting';
import { toObservable } from '@angular/core/rxjs-interop';
@Injectable()
export class ListingService<Class extends IListable<PrimaryKey>, PrimaryKey extends Id = Class['id']> {
@ -60,10 +61,10 @@ export class ListingService<Class extends IListable<PrimaryKey>, PrimaryKey exte
}
private get _getDisplayed$(): Observable<Class[]> {
const { filterGroups$ } = this._filterService;
const { filterGroups } = this._filterService;
const { valueChanges$ } = this._searchService;
return combineLatest([this._entitiesService.all$, filterGroups$, valueChanges$]).pipe(
return combineLatest([this._entitiesService.all$, toObservable(filterGroups), valueChanges$]).pipe(
map(([entities, filterGroups]) => getFilteredEntities(entities, filterGroups)),
map(entities => this._searchService.searchIn(entities)),
tap(displayed => {