Skip to content

Commit 9218c7c

Browse files
authored
Merge pull request #3307 from ProgrammeVitam/bug_15363
Bug #15363 && Bug #15398 - [Search + Collect] When saving a search with multiple filters, only one filter is retained && [Search] Default filter "Archives with objects" gets unchecked.
2 parents f38a6b7 + 6592642 commit 9218c7c

File tree

9 files changed

+100
-15
lines changed

9 files changed

+100
-15
lines changed

ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/additional-actions-search/management-rules/management-rules.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import {
6262
RuleCategoryAction,
6363
RuleSearchCriteriaDto,
6464
} from '../../../models/ruleAction.interface';
65+
import { Location } from '@angular/common';
6566

6667
const ARCHIVE_UNIT_HOLDING_UNIT = 'ARCHIVE_UNIT_HOLDING_UNIT';
6768

@@ -167,6 +168,7 @@ export class ManagementRulesComponent implements OnInit, OnChanges, OnDestroy {
167168
public dialog: MatDialog,
168169
private route: ActivatedRoute,
169170
private router: Router,
171+
private location: Location,
170172
private translate: TranslateService,
171173
private logger: Logger,
172174
private ruleService: RuleService,
@@ -662,7 +664,7 @@ export class ManagementRulesComponent implements OnInit, OnChanges, OnDestroy {
662664
.pipe(filter((result) => !!result))
663665
.subscribe(() => {
664666
this.initializeParameters();
665-
this.router.navigate(['/archive-search/tenant/', this.tenantIdentifier]);
667+
this.location.back();
666668
}),
667669
);
668670
}

ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* The fact that you are presently reading this means that you have had
3535
* knowledge of the CeCILL-C license and that you accept its terms.
3636
*/
37+
import { Location } from '@angular/common';
3738
import { provideHttpClientTesting } from '@angular/common/http/testing';
3839
import { NO_ERRORS_SCHEMA } from '@angular/core';
3940
import { ComponentFixture, TestBed } from '@angular/core/testing';
@@ -129,7 +130,13 @@ describe('ArchiveSearchComponent', () => {
129130
};
130131

131132
const setupTest = async (queryParams: Params) => {
132-
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
133+
const routerSpy = jasmine.createSpyObj('Router', ['navigate', 'createUrlTree', 'serializeUrl', 'parseUrl']);
134+
routerSpy.createUrlTree.and.returnValue({});
135+
routerSpy.serializeUrl.and.returnValue('/test-url');
136+
routerSpy.parseUrl.and.returnValue({ queryParams: {} });
137+
138+
const locationSpy = jasmine.createSpyObj('Location', ['replaceState', 'path']);
139+
locationSpy.path.and.returnValue('/test-url');
133140

134141
spyOn(archiveServiceStub, 'searchArchiveUnitsByCriteria').and.callThrough();
135142

@@ -157,6 +164,7 @@ describe('ArchiveSearchComponent', () => {
157164
{ provide: ArchiveUnitEliminationService, useValue: archiveUnitEliminationServiceMock },
158165
{ provide: BASE_URL, useValue: '/fake-api' },
159166
{ provide: ComputeInheritedRulesService, useValue: computeInheritedRulesServiceMock },
167+
{ provide: Location, useValue: locationSpy },
160168
{ provide: MatDialog, useValue: matDialogSpy },
161169
{ provide: Router, useValue: routerSpy },
162170
{ provide: SchemaService, useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } },

ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft
475475
this.searchCriteriaKeys = [];
476476
this.included = false;
477477
}
478-
this.applySearchCriteriaHistory(event);
478+
this.clearCriteria();
479+
setTimeout(() => this.applySearchCriteriaHistory(event));
479480
}
480481

481482
emitOrderChange() {
@@ -767,6 +768,9 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft
767768
this.subscribeResetNodesOnFilingHoldingNodesChanges();
768769
this.recursiveCheck(this.nodeArray, false);
769770

771+
// Collect all criteria to update URL at once
772+
const criteriaToAddToUrl: any[] = [];
773+
770774
storedSearchCriteriaHistory.searchCriteriaList.forEach((criteria: SearchCriteriaEltements) => {
771775
this.fillTreeNodeAsSearchCriteriaHistory(criteria);
772776

@@ -789,10 +793,29 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft
789793
category,
790794
criteria.valueTranslated,
791795
criteria.dataType,
792-
true,
796+
false,
793797
);
798+
799+
// Collect criteria for URL update (only FIELDS and NODES categories)
800+
if ([SearchCriteriaTypeEnum.FIELDS, SearchCriteriaTypeEnum.NODES].includes(category)) {
801+
criteriaToAddToUrl.push({
802+
keyElt: criteria.criteria,
803+
valueElt: value,
804+
labelElt: value.value,
805+
keyTranslated: criteria.keyTranslated,
806+
operator: criteria.operator,
807+
category,
808+
valueTranslated: criteria.valueTranslated,
809+
dataType: criteria.dataType,
810+
});
811+
}
794812
});
795813
});
814+
815+
// Update URL with all restored criteria at once
816+
if (criteriaToAddToUrl.length > 0) {
817+
this.archiveSharedDataService.addSimpleSearchCriteriaSubjects(criteriaToAddToUrl);
818+
}
796819
}
797820

798821
fillTreeNodeAsSearchCriteriaHistory(searchCriteriaList: SearchCriteriaEltements) {

ui/ui-frontend/projects/archive-search/src/app/archive/common-services/update-unit-management-rule.service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ export class UpdateUnitManagementRuleService {
165165
this.managementRulesSharedDataService.emitCriteriaSearchListToSave(criteriaSearchList);
166166
this.managementRulesSharedDataService.emitCriteriaSearchDSLQuery(criteriaSearchDSLQueryToSend);
167167

168-
router.navigate(['/archive-search/update-rules/tenant/', tenantIdentifier]);
168+
// Navigate preserving query params in URL to maintain browser history
169+
router.navigate(['/archive-search/update-rules/tenant/', tenantIdentifier], {
170+
queryParamsHandling: 'preserve',
171+
});
169172
}
170173
});
171174
}

ui/ui-frontend/projects/archive-search/src/app/core/archive-shared-data.service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ export class ArchiveSharedDataService {
237237
}
238238
this.simpleSearchCriteriaAddSubject.next(searchCriteria);
239239
});
240-
builder.navigate();
240+
241+
// Update URL with query params and create history entry
242+
builder.navigate({ replaceUrl: false });
241243
}
242244

243245
addSimpleSearchCriteriaSubject(searchCriteria: SearchCriteriaAddAction) {
@@ -304,7 +306,9 @@ export class ArchiveSharedDataService {
304306
: `${searchCriteriaAction.valueElt.value}/${searchCriteriaAction.valueElt.virtualNodeRealParentId}/${searchCriteriaAction.valueElt.virtualNodeRealParentTitle}`;
305307
builder.removeQueryParam(searchCriteriaAction.valueElt.id, valueToRemove);
306308
this.searchCriteriaRemoveFromChildSubject.next(searchCriteriaAction);
307-
builder.navigate();
309+
310+
// Update URL with query params and create history entry
311+
builder.navigate({ replaceUrl: false });
308312
}
309313

310314
receiveRemoveFromChildSearchCriteriaSubject(): Observable<SearchCriteriaRemoveAction> {

ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* The fact that you are presently reading this means that you have had
3535
* knowledge of the CeCILL-C license and that you accept its terms.
3636
*/
37+
import { Location } from '@angular/common';
3738
import { provideHttpClientTesting } from '@angular/common/http/testing';
3839
import { ComponentFixture, TestBed } from '@angular/core/testing';
3940
import { MatDialog } from '@angular/material/dialog';
@@ -134,7 +135,13 @@ describe('ArchiveSearchCollectComponent', () => {
134135
};
135136

136137
const setupTest = async (queryParams: Params, withSimpleCriteria = false) => {
137-
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
138+
const routerSpy = jasmine.createSpyObj('Router', ['navigate', 'createUrlTree', 'serializeUrl', 'parseUrl']);
139+
routerSpy.createUrlTree.and.returnValue({});
140+
routerSpy.serializeUrl.and.returnValue('/test-url');
141+
routerSpy.parseUrl.and.returnValue({ queryParams: {} });
142+
143+
const locationSpy = jasmine.createSpyObj('Location', ['replaceState', 'path']);
144+
locationSpy.path.and.returnValue('/test-url');
138145

139146
spyOn(archiveCollectServiceStub, 'searchArchiveUnitsByCriteria').and.callThrough();
140147

@@ -164,6 +171,7 @@ describe('ArchiveSearchCollectComponent', () => {
164171
{ provide: BASE_URL, useValue: '/fake-api' },
165172
{ provide: ConfigService, useValue: { config$: of() } },
166173
{ provide: ExternalParametersService, useValue: externalParametersServiceStub },
174+
{ provide: Location, useValue: locationSpy },
167175
{ provide: MatDialog, useValue: matDialogSpy },
168176
{ provide: Router, useValue: routerSpy },
169177
{ provide: SchemaService, useValue: { getDescriptiveSchemaTree: () => of(), getSchema: () => of([]) } },

ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,14 +1152,18 @@ export class ArchiveSearchCollectComponent extends SidenavPage<any> implements O
11521152
this.searchCriteriaKeys = [];
11531153
this.included = false;
11541154
}
1155-
this.applySearchCriteriaHistory(event);
1155+
this.clearCriteria();
1156+
setTimeout(() => this.applySearchCriteriaHistory(event));
11561157
}
11571158

11581159
private applySearchCriteriaHistory(storedSearchCriteriaHistory: SearchCriteriaHistory) {
11591160
// TODO : to uncomment when filing will be available
11601161
// this.setFilingHoldingScheme();
11611162
// this.checkAllNodes(false);
11621163

1164+
// Collect all criteria to update URL at once
1165+
const criteriaToAddToUrl: any[] = [];
1166+
11631167
storedSearchCriteriaHistory.searchCriteriaList.forEach((criteria: SearchCriteriaEltements) => {
11641168
this.fillTreeNodeAsSearchCriteriaHistory(criteria);
11651169

@@ -1182,10 +1186,29 @@ export class ArchiveSearchCollectComponent extends SidenavPage<any> implements O
11821186
category,
11831187
criteria.valueTranslated,
11841188
criteria.dataType,
1185-
true,
1189+
false,
11861190
);
1191+
1192+
// Collect criteria for URL update (only FIELDS and NODES categories)
1193+
if ([SearchCriteriaTypeEnum.FIELDS, SearchCriteriaTypeEnum.NODES].includes(category)) {
1194+
criteriaToAddToUrl.push({
1195+
keyElt: criteria.criteria,
1196+
valueElt: value,
1197+
labelElt: value.value,
1198+
keyTranslated: criteria.keyTranslated,
1199+
operator: criteria.operator,
1200+
category,
1201+
valueTranslated: criteria.valueTranslated,
1202+
dataType: criteria.dataType,
1203+
});
1204+
}
11871205
});
11881206
});
1207+
1208+
// Update URL with all restored criteria at once
1209+
if (criteriaToAddToUrl.length > 0) {
1210+
this.archiveSharedDataService.addSimpleSearchCriteriaSubjects(criteriaToAddToUrl);
1211+
}
11891212
}
11901213

11911214
fillTreeNodeAsSearchCriteriaHistory(searchCriteriaList: SearchCriteriaEltements) {

ui/ui-frontend/projects/collect/src/app/collect/core/archive-shared-data.service.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ export class ArchiveSharedDataService {
232232
}
233233
this.simpleSearchCriteriaAddSubject.next(searchCriteria);
234234
});
235-
builder.navigate();
235+
// Update URL with query params and create history entry
236+
builder.navigate({ replaceUrl: false });
236237
}
237238

238239
addSimpleSearchCriteriaSubject(searchCriteria: SearchCriteriaAddAction) {
@@ -271,7 +272,9 @@ export class ArchiveSharedDataService {
271272
: `${searchCriteriaAction.valueElt.value}/${searchCriteriaAction.valueElt.virtualNodeRealParentId}/${searchCriteriaAction.valueElt.virtualNodeRealParentTitle}`;
272273
builder.removeQueryParam(searchCriteriaAction.valueElt.id, valueToRemove);
273274
this.searchCriteriaRemoveFromChildSubject.next(searchCriteriaAction);
274-
builder.navigate();
275+
276+
// Update URL with query params and create history entry
277+
builder.navigate({ replaceUrl: false });
275278
}
276279

277280
receiveRemoveFromChildSearchCriteriaSubject(): Observable<SearchCriteriaRemoveAction> {

ui/ui-frontend/projects/vitamui-library/src/app/modules/url/query-params.service.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* knowledge of the CeCILL-C license and that you accept its terms.
3636
*/
3737
import { Injectable } from '@angular/core';
38+
import { Location } from '@angular/common';
3839
import { ActivatedRoute, NavigationExtras, Params, Router } from '@angular/router';
3940
import { Observable } from 'rxjs';
4041
import { fromPromise } from 'rxjs/internal/observable/innerFrom';
@@ -43,9 +44,14 @@ class QueryParamBuilder {
4344
#queryParams: Params = {};
4445
constructor(
4546
private router: Router,
46-
route: ActivatedRoute,
47+
private location: Location,
4748
) {
48-
this.#queryParams = { ...route.snapshot.queryParams };
49+
// Use location.path() to get current URL params instead of router.url
50+
// This ensures we get the most up-to-date params, even after Location.replaceState() calls
51+
// router.url is not updated by Location.replaceState(), but location.path() is
52+
const currentPath = this.location.path();
53+
const currentUrlTree = this.router.parseUrl(currentPath);
54+
this.#queryParams = { ...currentUrlTree.queryParams };
4955
}
5056

5157
addQueryParam(key: string, value: string): this {
@@ -62,6 +68,10 @@ class QueryParamBuilder {
6268
return this;
6369
}
6470

71+
getQueryParams(): Params {
72+
return { ...this.#queryParams };
73+
}
74+
6575
navigate(extras: NavigationExtras = {}): Observable<boolean> {
6676
return fromPromise(
6777
this.router.navigate([], {
@@ -79,6 +89,7 @@ export class QueryParamsService {
7989
constructor(
8090
private router: Router,
8191
private route: ActivatedRoute,
92+
private location: Location,
8293
) {}
8394

8495
setQueryParams(
@@ -97,7 +108,7 @@ export class QueryParamsService {
97108
}
98109

99110
builder() {
100-
return new QueryParamBuilder(this.router, this.route);
111+
return new QueryParamBuilder(this.router, this.location);
101112
}
102113

103114
getQueryParams(): Observable<Params> {

0 commit comments

Comments
 (0)