diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts index a440652fe52..838178ea81d 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts @@ -1,7 +1,7 @@ -import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core'; +import { Component, Inject, Input, OnInit } from '@angular/core'; -import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; -import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; +import { BehaviorSubject, distinctUntilChanged, Observable, of as observableOf } from 'rxjs'; +import { filter, map, switchMap, take } from 'rxjs/operators'; import { SearchFilterConfig } from '../../models/search-filter-config.model'; import { SearchFilterService } from '../../../../core/shared/search/search-filter.service'; @@ -43,8 +43,6 @@ export class SearchFilterComponent implements OnInit { */ @Input() scope: string; - @Output() isVisibilityComputed = new EventEmitter(); - /** * True when the filter is 100% collapsed in the UI */ @@ -93,9 +91,7 @@ export class SearchFilterComponent implements OnInit { */ ngOnInit() { this.selectedValues$ = this.getSelectedValues(); - this.active$ = this.isActive().pipe( - startWith(true) - ); + this.active$ = this.isActive(); this.collapsed$ = this.isCollapsed(); this.initializeFilter(); this.selectedValues$.pipe(take(1)).subscribe((selectedValues) => { @@ -103,9 +99,6 @@ export class SearchFilterComponent implements OnInit { this.filterService.expand(this.filter.name); } }); - this.isActive().pipe(take(1)).subscribe(() => { - this.isVisibilityComputed.emit(true); - }); } /** @@ -177,6 +170,7 @@ export class SearchFilterComponent implements OnInit { */ private isActive(): Observable { return this.selectedValues$.pipe( + distinctUntilChanged(), switchMap((isActive) => { if (isNotEmpty(isActive)) { return observableOf(true); diff --git a/src/app/shared/search/search-filters/search-filters.component.html b/src/app/shared/search/search-filters/search-filters.component.html index e1e54c683dd..81e6fc13a9a 100644 --- a/src/app/shared/search/search-filters/search-filters.component.html +++ b/src/app/shared/search/search-filters/search-filters.component.html @@ -2,7 +2,7 @@

{{"search.filters.head" | translate}}

- +
diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 831c32d76cd..150d1f903a5 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -1,7 +1,16 @@ -import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { + AfterViewInit, + Component, + Inject, + Input, + OnDestroy, + OnInit, + QueryList, + ViewChildren +} from '@angular/core'; import { Router } from '@angular/router'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, combineLatest, distinctUntilChanged, Observable, startWith, switchMap } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { SearchService } from '../../../core/shared/search/search.service'; @@ -13,6 +22,7 @@ import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.co import { currentPath } from '../../utils/route.utils'; import { hasValue } from '../../empty.util'; import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; +import { SearchFilterComponent } from './search-filter/search-filter.component'; @Component({ selector: 'ds-search-filters', @@ -24,7 +34,7 @@ import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; /** * This component represents the part of the search sidebar that contains filters. */ -export class SearchFiltersComponent implements OnInit, OnDestroy { +export class SearchFiltersComponent implements OnInit, OnDestroy, AfterViewInit { /** * An observable containing configuration about which filters are shown and how they are shown */ @@ -56,6 +66,11 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { */ @Input() refreshFilters: BehaviorSubject; + /** + * List of children filters + */ + @ViewChildren(SearchFilterComponent) childrenFilters!: QueryList; + /** * Link to the search page */ @@ -88,16 +103,14 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.router.events.subscribe(() => { - this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe( - tap(() => this.filtersWithComputedVisibility = 0), - map((filters) => { - Object.keys(filters).forEach((f) => filters[f] = null); - return filters; - }) - ); - this.searchLink = this.getSearchLink(); - }); + this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe( + tap(() => this.filtersWithComputedVisibility = 0), + map((filters) => { + Object.keys(filters).forEach((f) => filters[f] = null); + return filters; + }) + ); + this.searchLink = this.getSearchLink(); } /** @@ -117,6 +130,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { return config ? config.name : undefined; } + ngOnDestroy() { this.subs.forEach((sub) => { if (hasValue(sub)) { @@ -125,9 +139,17 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { }); } - countFiltersWithComputedVisibility(computed: boolean) { - if (computed) { - this.filtersWithComputedVisibility += 1; - } + ngAfterViewInit() { + this.subs.push( + this.childrenFilters.changes.pipe( + startWith(this.childrenFilters), + switchMap(() => + combineLatest(this.childrenFilters.map(child => child.active$)) + ), + distinctUntilChanged() + ).subscribe((visibilityValues) => { + this.filtersWithComputedVisibility = visibilityValues.filter(visible => !!visible).length; + }) + ); } }