mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
tests for SearchConfigurationService
This commit is contained in:
@@ -66,7 +66,7 @@ describe('SearchFacetFilterComponent', () => {
|
|||||||
{ provide: Router, useValue: new RouterStub() },
|
{ provide: Router, useValue: new RouterStub() },
|
||||||
{ provide: FILTER_CONFIG, useValue: new SearchFilterConfig() },
|
{ provide: FILTER_CONFIG, useValue: new SearchFilterConfig() },
|
||||||
{ provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} },
|
{ provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} },
|
||||||
{ provide: SearchConfigurationService, useValue: {getSearchOptions: () => Observable.of({})} },
|
{ provide: SearchConfigurationService, useValue: {searchOptions: Observable.of({})} },
|
||||||
{
|
{
|
||||||
provide: SearchFilterService, useValue: {
|
provide: SearchFilterService, useValue: {
|
||||||
getSelectedValuesForFilter: () => Observable.of(selectedValues),
|
getSelectedValuesForFilter: () => Observable.of(selectedValues),
|
||||||
|
@@ -82,14 +82,18 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
this.filterValues$ = new BehaviorSubject(new RemoteData(true, false, undefined, undefined, undefined));
|
this.filterValues$ = new BehaviorSubject(new RemoteData(true, false, undefined, undefined, undefined));
|
||||||
this.currentPage = this.getCurrentPage().distinctUntilChanged();
|
this.currentPage = this.getCurrentPage().distinctUntilChanged();
|
||||||
this.selectedValues = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
this.selectedValues = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
||||||
const searchOptions = this.searchConfigService.getSearchOptions().distinctUntilChanged();
|
const searchOptions = this.searchConfigService.searchOptions;
|
||||||
this.subs.push(searchOptions.subscribe((options) => this.updateFilterValueList()));
|
this.subs.push(this.searchConfigService.searchOptions.subscribe(() => this.updateFilterValueList()));
|
||||||
|
|
||||||
const facetValues = Observable.combineLatest(searchOptions, this.currentPage, (options, page) => {
|
const facetValues = Observable.combineLatest(searchOptions, this.currentPage, (options, page) => {
|
||||||
return {
|
return { options, page }
|
||||||
values: this.searchService.getFacetValuesFor(this.filterConfig, page, options),
|
}).switchMap(({ options, page }) => {
|
||||||
page: page
|
return this.searchService.getFacetValuesFor(this.filterConfig, page, options).map((results) => {
|
||||||
};
|
return {
|
||||||
|
values: Observable.of(results),
|
||||||
|
page: page
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
let filterValues = [];
|
let filterValues = [];
|
||||||
this.subs.push(facetValues.subscribe((facetOutcome) => {
|
this.subs.push(facetValues.subscribe((facetOutcome) => {
|
||||||
@@ -242,7 +246,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
findSuggestions(data): void {
|
findSuggestions(data): void {
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
this.searchConfigService.getSearchOptions().first().subscribe(
|
this.searchConfigService.searchOptions.first().subscribe(
|
||||||
(options) => {
|
(options) => {
|
||||||
this.filterSearchResults = this.searchService.getFacetValuesFor(this.filterConfig, 1, options, data.toLowerCase())
|
this.filterSearchResults = this.searchService.getFacetValuesFor(this.filterConfig, 1, options, data.toLowerCase())
|
||||||
.first()
|
.first()
|
||||||
|
@@ -74,7 +74,7 @@ describe('SearchRangeFilterComponent', () => {
|
|||||||
{ provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} },
|
{ provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} },
|
||||||
{ provide: RouteService, useValue: {getQueryParameterValue: () => Observable.of({})} },
|
{ provide: RouteService, useValue: {getQueryParameterValue: () => Observable.of({})} },
|
||||||
{ provide: SearchConfigurationService, useValue: {
|
{ provide: SearchConfigurationService, useValue: {
|
||||||
getSearchOptions: () => Observable.of({}) }
|
searchOptions: Observable.of({}) }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: SearchFilterService, useValue: {
|
provide: SearchFilterService, useValue: {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<h3>{{"search.filters.head" | translate}}</h3>
|
<h3>{{"search.filters.head" | translate}}</h3>
|
||||||
<div *ngIf="(filters | async)?.hasSucceeded">
|
<div *ngIf="(filters | async)?.hasSucceeded">
|
||||||
<div *ngFor="let filter of (filters | async).payload">
|
<div *ngFor="let filter of (filters | async)?.payload">
|
||||||
<ds-search-filter class="d-block mb-3 p-3" [filter]="filter"></ds-search-filter>
|
<ds-search-filter class="d-block mb-3 p-3" [filter]="filter"></ds-search-filter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -20,6 +20,7 @@ import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
|
|||||||
import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
|
import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
|
||||||
import { SearchFilterService } from './search-filters/search-filter/search-filter.service';
|
import { SearchFilterService } from './search-filters/search-filter/search-filter.service';
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
||||||
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
|
|
||||||
describe('SearchPageComponent', () => {
|
describe('SearchPageComponent', () => {
|
||||||
let comp: SearchPageComponent;
|
let comp: SearchPageComponent;
|
||||||
@@ -36,7 +37,7 @@ describe('SearchPageComponent', () => {
|
|||||||
pagination.currentPage = 1;
|
pagination.currentPage = 1;
|
||||||
pagination.pageSize = 10;
|
pagination.pageSize = 10;
|
||||||
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
|
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
|
||||||
const mockResults = Observable.of(['test', 'data']);
|
const mockResults = Observable.of(new RemoteData(false, false, true, null,['test', 'data']));
|
||||||
const searchServiceStub = jasmine.createSpyObj('SearchService', {
|
const searchServiceStub = jasmine.createSpyObj('SearchService', {
|
||||||
search: mockResults,
|
search: mockResults,
|
||||||
getSearchLink: '/search',
|
getSearchLink: '/search',
|
||||||
@@ -45,11 +46,11 @@ describe('SearchPageComponent', () => {
|
|||||||
const queryParam = 'test query';
|
const queryParam = 'test query';
|
||||||
const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f';
|
const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f';
|
||||||
const paginatedSearchOptions = {
|
const paginatedSearchOptions = {
|
||||||
query: queryParam,
|
query: queryParam,
|
||||||
scope: scopeParam,
|
scope: scopeParam,
|
||||||
pagination,
|
pagination,
|
||||||
sort
|
sort
|
||||||
};
|
};
|
||||||
const activatedRouteStub = {
|
const activatedRouteStub = {
|
||||||
queryParams: Observable.of({
|
queryParams: Observable.of({
|
||||||
query: queryParam,
|
query: queryParam,
|
||||||
@@ -91,17 +92,14 @@ describe('SearchPageComponent', () => {
|
|||||||
{
|
{
|
||||||
provide: SearchFilterService,
|
provide: SearchFilterService,
|
||||||
useValue: {}
|
useValue: {}
|
||||||
},{
|
}, {
|
||||||
provide: SearchConfigurationService,
|
provide: SearchConfigurationService,
|
||||||
useValue: jasmine.createSpyObj('SearchConfigurationService', {
|
useValue: {
|
||||||
getPaginatedSearchOptions: hot('a', {
|
paginatedSearchOptions: hot('a', {
|
||||||
a: paginatedSearchOptions
|
a: paginatedSearchOptions
|
||||||
}),
|
}),
|
||||||
getCurrentScope: hot('a', {
|
getCurrentScope: (a) => Observable.of('test-id')
|
||||||
a: 'test-id'
|
}
|
||||||
}),
|
|
||||||
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
@@ -180,4 +178,5 @@ describe('SearchPageComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { flatMap, } from 'rxjs/operators';
|
import { flatMap, } from 'rxjs/operators';
|
||||||
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
|
||||||
import { PaginatedList } from '../core/data/paginated-list';
|
import { PaginatedList } from '../core/data/paginated-list';
|
||||||
import { RemoteData } from '../core/data/remote-data';
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||||
@@ -77,11 +76,16 @@ export class SearchPageComponent implements OnInit {
|
|||||||
* If something changes, update the list of scopes for the dropdown
|
* If something changes, update the list of scopes for the dropdown
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchOptions$ = this.searchConfigService.getPaginatedSearchOptions();
|
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
|
||||||
this.sub = this.searchOptions$.subscribe((searchOptions) =>
|
let subscription;
|
||||||
this.service.search(searchOptions).filter((rd) => !rd.isLoading).first().subscribe((results) => this.resultsRD$.next(results)));
|
this.sub = this.searchOptions$.subscribe((searchOptions) => {
|
||||||
|
if (hasValue(subscription)) {
|
||||||
this.scopeListRD$ = this.searchConfigService.getCurrentScope().pipe(
|
/** Make sure no race condition is possible with a previous result coming back from the server later */
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
subscription = this.service.search(searchOptions).filter((rd) => !rd.isLoading).first().subscribe((results) => this.resultsRD$.next(results))
|
||||||
|
});
|
||||||
|
this.scopeListRD$ = this.searchConfigService.getCurrentScope('').pipe(
|
||||||
flatMap((scopeId) => this.service.getScopes(scopeId))
|
flatMap((scopeId) => this.service.getScopes(scopeId))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,12 @@ import { SearchConfigurationService } from './search-configuration.service';
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
|
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { fakeAsync, tick } from '@angular/core/testing';
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
|
import { PaginatedSearchOptions } from '../paginated-search-options.model';
|
||||||
|
import { cold, hot } from 'jasmine-marbles';
|
||||||
|
|
||||||
describe('SearchConfigurationService', () => {
|
fdescribe('SearchConfigurationService', () => {
|
||||||
let service: SearchConfigurationService;
|
let service: SearchConfigurationService;
|
||||||
const value1 = 'random value';
|
const value1 = 'random value';
|
||||||
const value2 = 'another value';
|
const value2 = 'another value';
|
||||||
@@ -13,13 +16,17 @@ describe('SearchConfigurationService', () => {
|
|||||||
'f.date.min': ['2013'],
|
'f.date.min': ['2013'],
|
||||||
'f.date.max': ['2018']
|
'f.date.max': ['2018']
|
||||||
};
|
};
|
||||||
const defaults = Observable.of(new RemoteData(false, false, true, null, {}))
|
const defaults = Object.assign(new PaginatedSearchOptions(), {
|
||||||
|
pagination: Object.assign(new PaginationComponentOptions(), { currentPage: 1, pageSize: 20 }),
|
||||||
|
sort: new SortOptions('score', SortDirection.DESC),
|
||||||
|
query: '',
|
||||||
|
scope: ''
|
||||||
|
});
|
||||||
const backendFilters = { 'f.author': ['another value'], 'f.date': ['[2013 TO 2018]'] };
|
const backendFilters = { 'f.author': ['another value'], 'f.date': ['[2013 TO 2018]'] };
|
||||||
|
|
||||||
const spy = jasmine.createSpyObj('SearchConfigurationService', {
|
const spy = jasmine.createSpyObj('RouteService', {
|
||||||
getQueryParameterValue: Observable.of([value1, value2])
|
getQueryParameterValue: cold('a', {a: [value1, value2]}),
|
||||||
,
|
getQueryParamsWithPrefix: cold('a', {a: prefixFilter}),
|
||||||
getQueryParamsWithPrefix: Observable.of(prefixFilter)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const activatedRoute: any = new ActivatedRouteStub();
|
const activatedRoute: any = new ActivatedRouteStub();
|
||||||
@@ -28,9 +35,9 @@ describe('SearchConfigurationService', () => {
|
|||||||
service = new SearchConfigurationService(spy, activatedRoute);
|
service = new SearchConfigurationService(spy, activatedRoute);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when getCurrentScope is called', () => {
|
describe('when the scope is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.getCurrentScope();
|
service.getCurrentScope('');
|
||||||
});
|
});
|
||||||
it('should call getQueryParameterValue on the routeService with parameter name \'scope\'', () => {
|
it('should call getQueryParameterValue on the routeService with parameter name \'scope\'', () => {
|
||||||
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('scope');
|
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('scope');
|
||||||
@@ -39,7 +46,7 @@ describe('SearchConfigurationService', () => {
|
|||||||
|
|
||||||
describe('when getCurrentQuery is called', () => {
|
describe('when getCurrentQuery is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.getCurrentQuery();
|
service.getCurrentQuery('');
|
||||||
});
|
});
|
||||||
it('should call getQueryParameterValue on the routeService with parameter name \'query\'', () => {
|
it('should call getQueryParameterValue on the routeService with parameter name \'query\'', () => {
|
||||||
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('query');
|
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('query');
|
||||||
@@ -81,7 +88,7 @@ describe('SearchConfigurationService', () => {
|
|||||||
});
|
});
|
||||||
describe('when getCurrentPagination is called', () => {
|
describe('when getCurrentPagination is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.getCurrentPagination({});
|
service.getCurrentPagination({ currentPage: 1, pageSize: 10 } as any);
|
||||||
});
|
});
|
||||||
it('should call getQueryParameterValue on the routeService with parameter name \'page\'', () => {
|
it('should call getQueryParameterValue on the routeService with parameter name \'page\'', () => {
|
||||||
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('page');
|
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('page');
|
||||||
@@ -90,41 +97,38 @@ describe('SearchConfigurationService', () => {
|
|||||||
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('pageSize');
|
expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('pageSize');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fdescribe('when getPaginatedSearchOptions or getSearchOptions is called', () => {
|
fdescribe('when updateSearchOptions or updatePaginatedSearchOptions is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(service, 'getCurrentPagination');
|
spyOn(service, 'getPaginationPart');
|
||||||
spyOn(service, 'getCurrentSort');
|
spyOn(service, 'getSortPart');
|
||||||
spyOn(service, 'getCurrentScope');
|
spyOn(service, 'getScopePart');
|
||||||
spyOn(service, 'getCurrentQuery');
|
spyOn(service, 'getQueryPart');
|
||||||
spyOn(service, 'getCurrentFilters');
|
spyOn(service, 'getFiltersPart');
|
||||||
});
|
});
|
||||||
describe('when getPaginatedSearchOptions is called', () => {
|
describe('when getPaginatedSearchOptions is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.getPaginatedSearchOptions(defaults);
|
service.subscribeToSearchOptions(defaults);
|
||||||
});
|
|
||||||
it('should call all getters it needs', fakeAsync(() => {
|
|
||||||
defaults.subscribe(() => {
|
|
||||||
tick();
|
|
||||||
expect(service.getCurrentPagination).toHaveBeenCalled();
|
|
||||||
expect(service.getCurrentSort).toHaveBeenCalled();
|
|
||||||
expect(service.getCurrentScope).toHaveBeenCalled();
|
|
||||||
expect(service.getCurrentQuery).toHaveBeenCalled();
|
|
||||||
expect(service.getCurrentFilters).toHaveBeenCalled();
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
describe('when getSearchOptions is called', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
service.getSearchOptions();
|
|
||||||
});
|
});
|
||||||
it('should call all getters it needs', () => {
|
it('should call all getters it needs', () => {
|
||||||
expect(service.getCurrentPagination).not.toHaveBeenCalled();
|
|
||||||
expect(service.getCurrentSort).not.toHaveBeenCalled();
|
// expect(service.getCurrentPagination).toHaveBeenCalled();
|
||||||
expect(service.getCurrentScope).toHaveBeenCalled();
|
// expect(service.getCurrentSort).toHaveBeenCalled();
|
||||||
expect(service.getCurrentQuery).toHaveBeenCalled();
|
expect(service.getScopePart).toHaveBeenCalled();
|
||||||
expect(service.getCurrentFilters).toHaveBeenCalled();
|
expect(service.getQueryPart).toHaveBeenCalled();
|
||||||
|
expect(service.getFiltersPart).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// describe('when searchOptions is called', () => {
|
||||||
|
// beforeEach(() => {
|
||||||
|
// service.searchOptions;
|
||||||
|
// });
|
||||||
|
// it('should call all getters it needs', () => {
|
||||||
|
// expect(service.getCurrentPagination).not.toHaveBeenCalled();
|
||||||
|
// expect(service.getCurrentSort).not.toHaveBeenCalled();
|
||||||
|
// expect(service.getCurrentScope).toHaveBeenCalled();
|
||||||
|
// expect(service.getCurrentQuery).toHaveBeenCalled();
|
||||||
|
// expect(service.getCurrentFilters).toHaveBeenCalled();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -5,53 +5,73 @@ import { distinctUntilChanged, map } from 'rxjs/operators';
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { PaginatedSearchOptions } from '../paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../paginated-search-options.model';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable, OnDestroy } from '@angular/core';
|
||||||
import { RouteService } from '../../shared/services/route.service';
|
import { RouteService } from '../../shared/services/route.service';
|
||||||
import { hasNoValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
import { hasNoValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that performs all actions that have to do with the current search configuration
|
* Service that performs all actions that have to do with the current search configuration
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchConfigurationService {
|
export class SearchConfigurationService implements OnDestroy {
|
||||||
private defaultPagination = { id: 'search-page-configuration', pageSize: 10 };
|
private defaultPagination = Object.assign(new PaginationComponentOptions(), { id: 'search-page-configuration', pageSize: 10, currentPage: 1 });
|
||||||
|
|
||||||
private defaultSort = new SortOptions('score', SortDirection.DESC);
|
private defaultSort = new SortOptions('score', SortDirection.DESC);
|
||||||
|
|
||||||
private defaultScope = '';
|
private defaultScope = '';
|
||||||
|
|
||||||
|
private defaultQuery = '';
|
||||||
|
|
||||||
private _defaults;
|
private _defaults;
|
||||||
|
|
||||||
|
public searchOptions: BehaviorSubject<SearchOptions>;
|
||||||
|
public paginatedSearchOptions: BehaviorSubject<PaginatedSearchOptions>;
|
||||||
|
private subs: Subscription[] = new Array();
|
||||||
|
|
||||||
constructor(private routeService: RouteService,
|
constructor(private routeService: RouteService,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute) {
|
||||||
|
this.defaults.first().subscribe((defRD) => {
|
||||||
|
const defs = defRD.payload;
|
||||||
|
this.paginatedSearchOptions = new BehaviorSubject<SearchOptions>(defs);
|
||||||
|
this.searchOptions = new BehaviorSubject<PaginatedSearchOptions>(defs);
|
||||||
|
|
||||||
|
this.subs.push(this.subscribeToSearchOptions(defs));
|
||||||
|
this.subs.push(this.subscribeToPaginatedSearchOptions(defs));
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<string>} Emits the current scope's identifier
|
* @returns {Observable<string>} Emits the current scope's identifier
|
||||||
*/
|
*/
|
||||||
getCurrentScope() {
|
getCurrentScope(defaultScope: string) {
|
||||||
return this.routeService.getQueryParameterValue('scope');
|
return this.routeService.getQueryParameterValue('scope').map((scope) => {
|
||||||
|
return scope || defaultScope;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<string>} Emits the current query string
|
* @returns {Observable<string>} Emits the current query string
|
||||||
*/
|
*/
|
||||||
getCurrentQuery() {
|
getCurrentQuery(defaultQuery: string) {
|
||||||
return this.routeService.getQueryParameterValue('query');
|
return this.routeService.getQueryParameterValue('query').map((query) => {
|
||||||
|
return query || defaultQuery;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<string>} Emits the current pagination settings
|
* @returns {Observable<string>} Emits the current pagination settings
|
||||||
*/
|
*/
|
||||||
getCurrentPagination(pagination: any = {}): Observable<PaginationComponentOptions> {
|
getCurrentPagination(defaultPagination: PaginationComponentOptions): Observable<PaginationComponentOptions> {
|
||||||
const page$ = this.routeService.getQueryParameterValue('page');
|
const page$ = this.routeService.getQueryParameterValue('page');
|
||||||
const size$ = this.routeService.getQueryParameterValue('pageSize');
|
const size$ = this.routeService.getQueryParameterValue('pageSize');
|
||||||
return Observable.combineLatest(page$, size$, (page, size) => {
|
return Observable.combineLatest(page$, size$, (page, size) => {
|
||||||
return Object.assign(new PaginationComponentOptions(), pagination, {
|
return Object.assign(new PaginationComponentOptions(), defaultPagination, {
|
||||||
currentPage: page || 1,
|
currentPage: page || defaultPagination.currentPage,
|
||||||
pageSize: size || pagination.pageSize
|
pageSize: size || defaultPagination.pageSize
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -70,7 +90,7 @@ export class SearchConfigurationService {
|
|||||||
const direction = SortDirection[sortDirection] || defaultSort.direction;
|
const direction = SortDirection[sortDirection] || defaultSort.direction;
|
||||||
return new SortOptions(field, direction)
|
return new SortOptions(field, direction)
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,77 +118,106 @@ export class SearchConfigurationService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Observable<Params>} Emits the current active filters with their values as they are displayed in the frontend URL
|
* @returns {Observable<Params>} Emits the current active filters with their values as they are displayed in the frontend URL
|
||||||
*/
|
*/
|
||||||
getCurrentFrontendFilters(): Observable<Params> {
|
getCurrentFrontendFilters(): Observable<Params> {
|
||||||
return this.routeService.getQueryParamsWithPrefix('f.');
|
return this.routeService.getQueryParamsWithPrefix('f.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
subscribeToSearchOptions(defaults: SearchOptions): Subscription {
|
||||||
* @param defaults The default values for the search options, that will be used if nothing is explicitly set
|
console.log('scope: ', this.getScopePart(defaults.scope));
|
||||||
* @returns {Observable<PaginatedSearchOptions>} Emits the current paginated search options
|
console.log('query: ', this.getQueryPart(defaults.query));
|
||||||
*/
|
console.log('filters: ', this.getFiltersPart());
|
||||||
getPaginatedSearchOptions(defaults: Observable<RemoteData<any>> = this.defaults): Observable<PaginatedSearchOptions> {
|
this.getScopePart(defaults.scope).subscribe((y) => console.log('scope: ' + JSON.stringify(y)));
|
||||||
return defaults.flatMap((defaultConfig) => {
|
this.getQueryPart(defaults.query).subscribe((y) => console.log('query: ' + JSON.stringify(y)));
|
||||||
const defaultValues = defaultConfig.payload;
|
this.getFiltersPart().subscribe((y) => console.log('filters: ' + JSON.stringify(y)));
|
||||||
return Observable.combineLatest(
|
return Observable.merge(
|
||||||
this.getCurrentPagination(defaultValues.pagination),
|
this.getScopePart(defaults.scope),
|
||||||
this.getCurrentSort(defaultValues.sort),
|
this.getQueryPart(defaults.query),
|
||||||
this.getCurrentScope(),
|
this.getFiltersPart()
|
||||||
this.getCurrentQuery(),
|
).subscribe((update) => {
|
||||||
this.getCurrentFilters()).pipe(
|
const currentValue: SearchOptions = this.searchOptions.getValue();
|
||||||
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),
|
const updatedValue: SearchOptions = Object.assign(new SearchOptions(), currentValue, update);
|
||||||
map(([pagination, sort, scope, query, filters]) => {
|
this.searchOptions.next(updatedValue);
|
||||||
return Object.assign(new PaginatedSearchOptions(),
|
|
||||||
defaults,
|
|
||||||
{
|
|
||||||
pagination: pagination,
|
|
||||||
sort: sort,
|
|
||||||
scope: scope || defaultValues.scope,
|
|
||||||
query: query,
|
|
||||||
filters: filters
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
subscribeToPaginatedSearchOptions(defaults: PaginatedSearchOptions): Subscription {
|
||||||
* @param defaults The default values for the search options, that will be used if nothing is explicitly set
|
return Observable.merge(
|
||||||
* @returns {Observable<PaginatedSearchOptions>} Emits the current search options
|
this.getPaginationPart(defaults.pagination),
|
||||||
*/
|
this.getSortPart(defaults.sort),
|
||||||
getSearchOptions(defaults: Observable<RemoteData<any>> = this.defaults): Observable<SearchOptions> {
|
this.getScopePart(defaults.scope),
|
||||||
return defaults.flatMap((defaultConfig) => {
|
this.getQueryPart(defaults.query),
|
||||||
const defaultValues = defaultConfig.payload;
|
this.getFiltersPart()
|
||||||
return Observable.combineLatest(
|
).subscribe((update) => {
|
||||||
this.getCurrentScope(),
|
const currentValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue();
|
||||||
this.getCurrentQuery(),
|
const updatedValue: PaginatedSearchOptions = Object.assign(new PaginatedSearchOptions(), currentValue, update);
|
||||||
this.getCurrentFilters(),
|
this.paginatedSearchOptions.next(updatedValue);
|
||||||
(scope, query, filters) => {
|
|
||||||
return Object.assign(new SearchOptions(),
|
|
||||||
{
|
|
||||||
scope: scope || defaultValues.scope,
|
|
||||||
query: query,
|
|
||||||
filters: filters
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default values for the Search Options
|
* Default values for the Search Options
|
||||||
*/
|
*/
|
||||||
get defaults() {
|
get defaults(): Observable<RemoteData<PaginatedSearchOptions>> {
|
||||||
if (hasNoValue(this._defaults)) {
|
if (hasNoValue(this._defaults)) {
|
||||||
const options = {
|
const options = Object.assign(new PaginatedSearchOptions(), {
|
||||||
pagination: this.defaultPagination,
|
pagination: this.defaultPagination,
|
||||||
sort: this.defaultSort,
|
sort: this.defaultSort,
|
||||||
scope: this.defaultScope
|
scope: this.defaultScope,
|
||||||
};
|
query: this.defaultQuery
|
||||||
|
});
|
||||||
this._defaults = Observable.of(new RemoteData(false, false, true, null, options));
|
this._defaults = Observable.of(new RemoteData(false, false, true, null, options));
|
||||||
}
|
}
|
||||||
return this._defaults;
|
return this._defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subs.forEach((sub) => {
|
||||||
|
sub.unsubscribe();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getScopePart(defaultScope: string): Observable<any> {
|
||||||
|
return this.getCurrentScope(defaultScope).map((scope) => {
|
||||||
|
return { scope }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<string>} Emits the current query string
|
||||||
|
*/
|
||||||
|
getQueryPart(defaultQuery: string): Observable<any> {
|
||||||
|
return this.getCurrentQuery(defaultQuery).map((query) => {
|
||||||
|
return { query }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<string>} Emits the current pagination settings
|
||||||
|
*/
|
||||||
|
getPaginationPart(defaultPagination: PaginationComponentOptions): Observable<any> {
|
||||||
|
return this.getCurrentPagination(defaultPagination).map((pagination) => {
|
||||||
|
return { pagination }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<string>} Emits the current sorting settings
|
||||||
|
*/
|
||||||
|
getSortPart(defaultSort: SortOptions): Observable<any> {
|
||||||
|
return this.getCurrentSort(defaultSort).map((sort) => {
|
||||||
|
return { sort }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<Params>} Emits the current active filters with their values as they are sent to the backend
|
||||||
|
*/
|
||||||
|
getFiltersPart(): Observable<any> {
|
||||||
|
return this.getCurrentFilters().map((filters) => {
|
||||||
|
return { filters }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,15 +73,14 @@ describe('SearchSettingsComponent', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: SearchConfigurationService,
|
provide: SearchConfigurationService,
|
||||||
useValue: jasmine.createSpyObj('SearchConfigurationService', {
|
useValue: {
|
||||||
getPaginatedSearchOptions: hot('a', {
|
paginatedSearchOptions: hot('a', {
|
||||||
a: paginatedSearchOptions
|
a: paginatedSearchOptions
|
||||||
}),
|
}),
|
||||||
getCurrentScope: hot('a', {
|
getCurrentScope: hot('a', {
|
||||||
a: 'test-id'
|
a: 'test-id'
|
||||||
}),
|
}),
|
||||||
|
}
|
||||||
})
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
@@ -38,7 +38,7 @@ export class SearchSettingsComponent implements OnInit {
|
|||||||
* Initialize paginated search options
|
* Initialize paginated search options
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchOptions$ = this.searchConfigurationService.getPaginatedSearchOptions();
|
this.searchOptions$ = this.searchConfigurationService.paginatedSearchOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,6 +50,7 @@ export class SearchSettingsComponent implements OnInit {
|
|||||||
const navigationExtras: NavigationExtras = {
|
const navigationExtras: NavigationExtras = {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageSize: value,
|
pageSize: value,
|
||||||
|
page: 1
|
||||||
},
|
},
|
||||||
queryParamsHandling: 'merge'
|
queryParamsHandling: 'merge'
|
||||||
};
|
};
|
||||||
@@ -65,7 +66,8 @@ export class SearchSettingsComponent implements OnInit {
|
|||||||
const navigationExtras: NavigationExtras = {
|
const navigationExtras: NavigationExtras = {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
sortDirection: values[1],
|
sortDirection: values[1],
|
||||||
sortField: values[0]
|
sortField: values[0],
|
||||||
|
page: 1
|
||||||
},
|
},
|
||||||
queryParamsHandling: 'merge'
|
queryParamsHandling: 'merge'
|
||||||
};
|
};
|
||||||
|
@@ -17,6 +17,7 @@ export class RouteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getQueryParameterValue(paramName: string): Observable<string> {
|
getQueryParameterValue(paramName: string): Observable<string> {
|
||||||
|
this.route.queryParamMap.map((map) => map.get(paramName)).distinctUntilChanged().subscribe((t) => console.log('paramName: ' + paramName + 'values: ' + t));
|
||||||
return this.route.queryParamMap.map((map) => map.get(paramName)).distinctUntilChanged();
|
return this.route.queryParamMap.map((map) => map.get(paramName)).distinctUntilChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ export class RouteService {
|
|||||||
params[key] = [...map.getAll(key)];
|
params[key] = [...map.getAll(key)];
|
||||||
});
|
});
|
||||||
return params;
|
return params;
|
||||||
}).distinctUntilChanged();
|
})
|
||||||
|
.distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,10 @@ export class ActivatedRouteStub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test parameters
|
// Test parameters
|
||||||
get testParams() { return this._testParams; }
|
get testParams() {
|
||||||
|
return this._testParams;
|
||||||
|
}
|
||||||
|
|
||||||
set testParams(params: {}) {
|
set testParams(params: {}) {
|
||||||
this._testParams = params;
|
this._testParams = params;
|
||||||
this.subject.next(params);
|
this.subject.next(params);
|
||||||
@@ -29,6 +32,9 @@ export class ActivatedRouteStub {
|
|||||||
|
|
||||||
// ActivatedRoute.snapshot.params
|
// ActivatedRoute.snapshot.params
|
||||||
get snapshot() {
|
get snapshot() {
|
||||||
return { params: this.testParams };
|
return {
|
||||||
|
params: this.testParams,
|
||||||
|
queryParamMap: convertToParamMap(this.testParams)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user