[MNT-25408]: updates changing search config logic; exposes stream for active filters (#11386)

* [MNT-25408]: fixes execution sequence

* [MNT-25408]: adds getter

* [MNT-25408]: reverts getter for property access proxy

* [MNT-25408]: adds tests

* [MNT-25408]: minor fixes

* [MNT-25408]: minor fixes
This commit is contained in:
Anton Ramanovich
2025-12-09 09:57:55 +01:00
committed by GitHub
parent 6567c02220
commit 8fa3e6acdf
2 changed files with 97 additions and 2 deletions

View File

@@ -73,20 +73,44 @@ export abstract class BaseQueryBuilderService {
/* Stream that emits the initial value for some or all search filters */
populateFilters = new BehaviorSubject<{ [key: string]: any }>({});
/* Stream that emits every time queryFragments change */
queryFragmentsUpdate = new BehaviorSubject<{ [key: string]: any }>({});
/* Stream that emits every time userFacetBuckets change */
userFacetBucketsUpdate = new BehaviorSubject<{ [key: string]: FacetFieldBucket[] }>({});
categories: SearchCategory[] = [];
queryFragments: { [id: string]: string } = {};
filterQueries: FilterQuery[] = [];
filterRawParams: { [key: string]: any } = {};
paging: { maxItems?: number; skipCount?: number } = null;
sorting: SearchSortingDefinition[] = [];
sortingOptions: SearchSortingDefinition[] = [];
private encodedQuery: string;
private scope: RequestScope;
private selectedConfiguration: number;
private _userQuery = '';
private _queryFragments: { [id: string]: string } = {};
private readonly queryFragmentsHandler: ProxyHandler<{ [key: string]: any }> = {
set: (target: { [key: string]: any }, property: string, value: any) => {
target[property as keyof typeof target] = value;
this.queryFragmentsUpdate.next(this._queryFragments);
return true;
}
};
protected userFacetBuckets: { [key: string]: FacetFieldBucket[] } = {};
get queryFragments(): { [key: string]: any } {
return this._queryFragments;
}
set queryFragments(value: { [key: string]: any }) {
this._queryFragments = this.createQueryFragmentsProxy(value);
this.queryFragmentsUpdate.next(this._queryFragments);
}
get userQuery(): string {
return this._userQuery;
}
@@ -108,6 +132,7 @@ export abstract class BaseQueryBuilderService {
protected readonly alfrescoApiService: AlfrescoApiService
) {
this.resetToDefaults();
this._queryFragments = this.createQueryFragmentsProxy({});
}
public abstract loadConfiguration(): SearchConfiguration | SearchConfiguration[];
@@ -146,10 +171,10 @@ export abstract class BaseQueryBuilderService {
const currentConfig = this.loadConfiguration();
if (Array.isArray(currentConfig) && currentConfig[index] !== undefined) {
this.selectedConfiguration = index;
this.configUpdated.next(currentConfig[index]);
this.searchForms.next(this.getSearchFormDetails());
this.resetSearchOptions();
this.setUpSearchConfiguration(currentConfig[index]);
this.configUpdated.next(currentConfig[index]);
this.update();
}
}
@@ -216,6 +241,7 @@ export abstract class BaseQueryBuilderService {
buckets.push(bucket);
}
this.userFacetBuckets[field] = buckets;
this.userFacetBucketsUpdate.next(this.userFacetBuckets);
}
}
@@ -239,6 +265,7 @@ export abstract class BaseQueryBuilderService {
if (field && bucket) {
const buckets = this.userFacetBuckets[field] || [];
this.userFacetBuckets[field] = buckets.filter((facetBucket) => facetBucket.label !== bucket.label);
this.userFacetBucketsUpdate.next(this.userFacetBuckets);
}
}
@@ -615,4 +642,8 @@ export abstract class BaseQueryBuilderService {
queryParamsHandling: 'merge'
});
}
private createQueryFragmentsProxy(target: { [key: string]: any }): { [key: string]: any } {
return new Proxy(target, this.queryFragmentsHandler);
}
}

View File

@@ -24,6 +24,7 @@ import { TestBed } from '@angular/core/testing';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { ADF_SEARCH_CONFIGURATION } from '../search-configuration.token';
import { ActivatedRoute, Router } from '@angular/router';
import { skip } from 'rxjs/operators';
const buildConfig = (searchSettings = {}): AppConfigService => {
let config: AppConfigService;
@@ -840,4 +841,67 @@ describe('SearchQueryBuilder', () => {
});
});
});
describe('userFacetBucketsUpdate', () => {
it('should emit updated list of UserFacetBuckets on adding the bucket', (done) => {
const service = TestBed.inject(SearchQueryBuilderService);
service.userFacetBucketsUpdate.pipe(skip(1)).subscribe((buckets) => {
expect(buckets).toEqual({ test: [{ checked: true, filterQuery: 'f1-q1', label: 'f1-q1', count: 1 }] });
done();
});
const currentBuckets = service.getUserFacetBuckets('test');
expect(currentBuckets).toEqual([]);
service.addUserFacetBucket('test', { checked: true, filterQuery: 'f1-q1', label: 'f1-q1', count: 1 });
});
it('should emit updated list of UserFacetBuckets on removing the bucket', (done) => {
const service = TestBed.inject(SearchQueryBuilderService);
service.addUserFacetBucket('test', { checked: true, filterQuery: 'f1-q1', label: 'toStay', count: 1 });
service.addUserFacetBucket('test', { checked: true, filterQuery: 'f1-q1', label: 'toLeave', count: 1 });
service.userFacetBucketsUpdate.pipe(skip(1)).subscribe((buckets) => {
expect(buckets).toEqual({ test: [{ checked: true, filterQuery: 'f1-q1', label: 'toStay', count: 1 }] });
done();
});
const currentBuckets = service.getUserFacetBuckets('test');
expect(currentBuckets).toEqual([
{ checked: true, filterQuery: 'f1-q1', label: 'toStay', count: 1 },
{ checked: true, filterQuery: 'f1-q1', label: 'toLeave', count: 1 }
]);
service.removeUserFacetBucket('test', { checked: true, filterQuery: 'f1-q1', label: 'toLeave', count: 1 });
});
});
describe('queryFragments proxy set up', () => {
it('should emit queryFragmentsUpdate when proxy property is set', (done) => {
const service = TestBed.inject(SearchQueryBuilderService);
service.queryFragmentsUpdate.pipe(skip(1)).subscribe((fragments) => {
expect(fragments).toEqual({ test: 'test_fragment' });
done();
});
const currentFragments = service.queryFragments;
expect(currentFragments).toEqual({});
service.queryFragments['test'] = 'test_fragment';
});
it('should emit queryFragmentsUpdate when setter replaces the proxy', (done) => {
const service = TestBed.inject(SearchQueryBuilderService);
service.queryFragments['test'] = 'test_fragment';
const currentFragments = service.queryFragments;
expect(currentFragments).toEqual({ test: 'test_fragment' });
service.queryFragmentsUpdate.pipe(skip(1)).subscribe((fragments) => {
expect(fragments).toEqual({});
done();
});
service.queryFragments = {};
});
});
});