Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<h3>{{"search.filters.head" | translate}}</h3>
<div *ngIf="(filters | async)?.hasSucceeded">
<div [class.visually-hidden]="filtersWithComputedVisibility !== (filters | async)?.payload?.length"
*ngFor="let filter of (filters | async)?.payload; trackBy: trackUpdate">
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
</div>
<div [class.visually-hidden]="getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length"
*ngFor="let filter of (filters | async)?.payload">
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
</div>
</div>


<ng-container *ngIf="filtersWithComputedVisibility !== (filters | async)?.payload?.length">
<ng-container *ngIf="getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length">
<ngx-skeleton-loader [count]="defaultFilterCount"/>
</ng-container>
<a class="btn btn-primary" [routerLink]="[searchLink]" [queryParams]="clearParams | async" queryParamsHandling="merge" role="button"><i class="fas fa-undo"></i> {{"search.filters.reset" | translate}}</a>
131 changes: 126 additions & 5 deletions src/app/shared/search/search-filters/search-filters.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { BehaviorSubject, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { map, filter } from 'rxjs/operators';

import { SearchService } from '../../../core/shared/search/search.service';
import { RemoteData } from '../../../core/data/remote-data';
Expand Down Expand Up @@ -62,9 +62,16 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
searchLink: string;

/**
* Filters for which visibility has been computed
* Keeps track of the filters computed for each configuration during the current rendering cycle
* This array stores objects with configuration identifier and number of computed filters
*/
filtersWithComputedVisibility = 0;
private currentFiltersComputed = [];

/**
* Stores the final count of computed filters for each configuration
* Used to determine when all filters for a configuration have been processed
*/
private finalFiltersComputed = [];

subs = [];
defaultFilterCount: number;
Expand All @@ -90,7 +97,6 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.router.events.subscribe(() => {
Comment thread
sergius02 marked this conversation as resolved.
Outdated
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
tap(() => this.filtersWithComputedVisibility = 0),
map((filters) => {
Object.keys(filters).forEach((f) => filters[f] = null);
return filters;
Expand Down Expand Up @@ -127,7 +133,122 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {

countFiltersWithComputedVisibility(computed: boolean) {
if (computed) {
this.filtersWithComputedVisibility += 1;
this.filters.pipe(
// Get filter data and check if we need to increment the counter
map(filtersData => {
if (filtersData && filtersData.hasSucceeded && filtersData.payload) {
const totalFilters = filtersData.payload.length;
const currentComputed = this.getCurrentFiltersComputed(this.currentConfiguration);

// If we've already computed all filters for this configuration
if (currentComputed >= totalFilters) {
// Register in finalFiltersComputed if not already registered
if (!this.findConfigInFinalFilters(this.currentConfiguration)) {
this.updateFinalFiltersComputed(this.currentConfiguration, totalFilters);
}
return { shouldIncrement: false };
}

// We haven't reached the total yet, proceed with increment
return {
shouldIncrement: true,
totalFilters
};
}
return { shouldIncrement: false };
}),
// Only continue if we need to increment the counter
filter(result => result.shouldIncrement),
// Increment the counter for the current configuration
map(result => {
const filterConfig = this.findConfigInCurrentFilters(this.currentConfiguration);

if (filterConfig) {
// Update existing counter
filterConfig.filtersComputed += 1;
} else {
// Create new counter entry
this.currentFiltersComputed.push({
configuration: this.currentConfiguration,
filtersComputed: 1
});
}

// Pass along the total and updated count
return {
totalFilters: result.totalFilters,
currentComputed: this.getCurrentFiltersComputed(this.currentConfiguration)
};
}),
// Check if we've reached the total after incrementing
map(result => {
if (result.currentComputed === result.totalFilters) {
// If we've reached the total, update final filters count
this.updateFinalFiltersComputed(this.currentConfiguration, result.currentComputed);
}
return result;
})
).subscribe().unsubscribe(); // Execute the pipeline and immediately unsubscribe
Comment thread
sergius02 marked this conversation as resolved.
Outdated
}
}

/**
* Finds a configuration entry in the currentFiltersComputed array
* @param configuration The configuration identifier to search for
* @returns The filter configuration object if found, otherwise undefined
*/
private findConfigInCurrentFilters(configuration: string) {
return this.currentFiltersComputed.find(
(configFilter) => configFilter.configuration === configuration
);
}

/**
* Finds a configuration entry in the finalFiltersComputed array
* @param configuration The configuration identifier to search for
* @returns The filter configuration object if found, otherwise undefined
*/
private findConfigInFinalFilters(configuration: string) {
return this.finalFiltersComputed.find(
(configFilter) => configFilter.configuration === configuration
);
}

/**
* Updates or adds a new entry in the finalFiltersComputed array
* @param configuration The configuration identifier to update
* @param count The number of computed filters to set for this configuration
*/
private updateFinalFiltersComputed(configuration: string, count: number) {
const filterConfig = this.findConfigInFinalFilters(configuration);

if (filterConfig) {
filterConfig.filtersComputed = count;
} else {
this.finalFiltersComputed.push({
configuration,
filtersComputed: count
});
}
}

/**
* Gets the current number of computed filters for a specific configuration
* @param configuration The configuration identifier to get the count for
* @returns The number of computed filters, or 0 if none found
*/
private getCurrentFiltersComputed(configuration: string) {
const configFilter = this.findConfigInCurrentFilters(configuration);
return configFilter?.filtersComputed || 0;
}

/**
* Gets the final number of computed filters for a specific configuration
* @param configuration The configuration identifier to get the count for
* @returns The number of computed filters in the final state, or 0 if none found
*/
getFinalFiltersComputed(configuration: string): number {
const configFilter = this.findConfigInFinalFilters(configuration);
return configFilter?.filtersComputed || 0;
}
}