Skip to content

Commit f5df726

Browse files
authored
Merge pull request DSpace#4121 from arvoConsultores/DS-4097
Store the state of the computed filters
2 parents 077467e + dc3e842 commit f5df726

File tree

2 files changed

+138
-19
lines changed

2 files changed

+138
-19
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<h3>{{"search.filters.head" | translate}}</h3>
22
<div *ngIf="(filters | async)?.hasSucceeded">
3-
<div [class.visually-hidden]="filtersWithComputedVisibility !== (filters | async)?.payload?.length"
4-
*ngFor="let filter of (filters | async)?.payload; trackBy: trackUpdate">
5-
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
6-
</div>
3+
<div [class.visually-hidden]="getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length"
4+
*ngFor="let filter of (filters | async)?.payload">
5+
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
6+
</div>
77
</div>
88

99

10-
<ng-container *ngIf="filtersWithComputedVisibility !== (filters | async)?.payload?.length">
10+
<ng-container *ngIf="getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length">
1111
<ngx-skeleton-loader [count]="defaultFilterCount"/>
1212
</ng-container>
1313
<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>

src/app/shared/search/search-filters/search-filters.component.ts

Lines changed: 133 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core';
22
import { Router } from '@angular/router';
33

44
import { BehaviorSubject, Observable } from 'rxjs';
5-
import { map, tap } from 'rxjs/operators';
5+
import { map, filter, take } from 'rxjs/operators';
66

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

6464
/**
65-
* Filters for which visibility has been computed
65+
* Keeps track of the filters computed for each configuration during the current rendering cycle
66+
* This array stores objects with configuration identifier and number of computed filters
6667
*/
67-
filtersWithComputedVisibility = 0;
68+
private currentFiltersComputed = [];
69+
70+
/**
71+
* Stores the final count of computed filters for each configuration
72+
* Used to determine when all filters for a configuration have been processed
73+
*/
74+
private finalFiltersComputed = [];
6875

6976
subs = [];
7077
defaultFilterCount: number;
@@ -88,16 +95,13 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
8895
}
8996

9097
ngOnInit(): void {
91-
this.router.events.subscribe(() => {
92-
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
93-
tap(() => this.filtersWithComputedVisibility = 0),
94-
map((filters) => {
95-
Object.keys(filters).forEach((f) => filters[f] = null);
96-
return filters;
97-
})
98-
);
99-
this.searchLink = this.getSearchLink();
100-
});
98+
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
99+
map((filters) => {
100+
Object.keys(filters).forEach((f) => filters[f] = null);
101+
return filters;
102+
})
103+
);
104+
this.searchLink = this.getSearchLink();
101105
}
102106

103107
/**
@@ -127,7 +131,122 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
127131

128132
countFiltersWithComputedVisibility(computed: boolean) {
129133
if (computed) {
130-
this.filtersWithComputedVisibility += 1;
134+
this.filters.pipe(
135+
// Get filter data and check if we need to increment the counter
136+
map(filtersData => {
137+
if (filtersData && filtersData.hasSucceeded && filtersData.payload) {
138+
const totalFilters = filtersData.payload.length;
139+
const currentComputed = this.getCurrentFiltersComputed(this.currentConfiguration);
140+
141+
// If we've already computed all filters for this configuration
142+
if (currentComputed >= totalFilters) {
143+
// Register in finalFiltersComputed if not already registered
144+
if (!this.findConfigInFinalFilters(this.currentConfiguration)) {
145+
this.updateFinalFiltersComputed(this.currentConfiguration, totalFilters);
146+
}
147+
return { shouldIncrement: false };
148+
}
149+
150+
// We haven't reached the total yet, proceed with increment
151+
return {
152+
shouldIncrement: true,
153+
totalFilters
154+
};
155+
}
156+
return { shouldIncrement: false };
157+
}),
158+
// Only continue if we need to increment the counter
159+
filter(result => result.shouldIncrement),
160+
// Increment the counter for the current configuration
161+
map(result => {
162+
const filterConfig = this.findConfigInCurrentFilters(this.currentConfiguration);
163+
164+
if (filterConfig) {
165+
// Update existing counter
166+
filterConfig.filtersComputed += 1;
167+
} else {
168+
// Create new counter entry
169+
this.currentFiltersComputed.push({
170+
configuration: this.currentConfiguration,
171+
filtersComputed: 1
172+
});
173+
}
174+
175+
// Pass along the total and updated count
176+
return {
177+
totalFilters: result.totalFilters,
178+
currentComputed: this.getCurrentFiltersComputed(this.currentConfiguration)
179+
};
180+
}),
181+
// Check if we've reached the total after incrementing
182+
map(result => {
183+
if (result.currentComputed === result.totalFilters) {
184+
// If we've reached the total, update final filters count
185+
this.updateFinalFiltersComputed(this.currentConfiguration, result.currentComputed);
186+
}
187+
return result;
188+
})
189+
).pipe(take(1)).subscribe(); // Execute the pipeline and immediately unsubscribe
131190
}
132191
}
192+
193+
/**
194+
* Finds a configuration entry in the currentFiltersComputed array
195+
* @param configuration The configuration identifier to search for
196+
* @returns The filter configuration object if found, otherwise undefined
197+
*/
198+
private findConfigInCurrentFilters(configuration: string) {
199+
return this.currentFiltersComputed.find(
200+
(configFilter) => configFilter.configuration === configuration
201+
);
202+
}
203+
204+
/**
205+
* Finds a configuration entry in the finalFiltersComputed array
206+
* @param configuration The configuration identifier to search for
207+
* @returns The filter configuration object if found, otherwise undefined
208+
*/
209+
private findConfigInFinalFilters(configuration: string) {
210+
return this.finalFiltersComputed.find(
211+
(configFilter) => configFilter.configuration === configuration
212+
);
213+
}
214+
215+
/**
216+
* Updates or adds a new entry in the finalFiltersComputed array
217+
* @param configuration The configuration identifier to update
218+
* @param count The number of computed filters to set for this configuration
219+
*/
220+
private updateFinalFiltersComputed(configuration: string, count: number) {
221+
const filterConfig = this.findConfigInFinalFilters(configuration);
222+
223+
if (filterConfig) {
224+
filterConfig.filtersComputed = count;
225+
} else {
226+
this.finalFiltersComputed.push({
227+
configuration,
228+
filtersComputed: count
229+
});
230+
}
231+
}
232+
233+
/**
234+
* Gets the current number of computed filters for a specific configuration
235+
* @param configuration The configuration identifier to get the count for
236+
* @returns The number of computed filters, or 0 if none found
237+
*/
238+
private getCurrentFiltersComputed(configuration: string) {
239+
const configFilter = this.findConfigInCurrentFilters(configuration);
240+
return configFilter?.filtersComputed || 0;
241+
}
242+
243+
/**
244+
* Gets the final number of computed filters for a specific configuration
245+
* @param configuration The configuration identifier to get the count for
246+
* @returns The number of computed filters in the final state, or 0 if none found
247+
*/
248+
getFinalFiltersComputed(configuration: string): number {
249+
const configFilter = this.findConfigInFinalFilters(configuration);
250+
return configFilter?.filtersComputed || 0;
251+
}
133252
}

0 commit comments

Comments
 (0)