mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Added more optimalisations and fixed tests
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="filters py-2">
|
<div class="filters py-2">
|
||||||
<ds-search-facet-selected-option *ngFor="let value of (selectedValues | async)" [selectedValue]="value" [filterConfig]="filterConfig"></ds-search-facet-selected-option>
|
<ds-search-facet-selected-option *ngFor="let value of (selectedValues$ | async)" [selectedValue]="value" [filterConfig]="filterConfig" [selectedValues$]="selectedValues$"></ds-search-facet-selected-option>
|
||||||
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
||||||
<div [@facetLoad]="animationState">
|
<div [@facetLoad]="animationState">
|
||||||
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value">
|
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value" [selectedValues$]="selectedValues$"></ds-search-facet-option>
|
||||||
</ds-search-facet-option>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div class="clearfix toggle-more-filters">
|
<div class="clearfix toggle-more-filters">
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<a *ngIf="isVisible" class="d-flex flex-row"
|
<script src="search-facet-option.component.ts"></script><a *ngIf="isVisible | async" class="d-flex flex-row"
|
||||||
[routerLink]="[getSearchLink()]"
|
[routerLink]="[getSearchLink()]"
|
||||||
[queryParams]="addQueryParams | async" queryParamsHandling="merge">
|
[queryParams]="addQueryParams" queryParamsHandling="merge">
|
||||||
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
|
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
|
||||||
<span class="filter-value px-1">{{filterValue.value}}</span>
|
<span class="filter-value px-1">{{filterValue.value}}</span>
|
||||||
<span class="float-right filter-value-count ml-auto">
|
<span class="float-right filter-value-count ml-auto">
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
import { Observable, of as observableOf } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, take } from 'rxjs/operators';
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { FacetValue } from '../../../../search-service/facet-value.model';
|
import { FacetValue } from '../../../../search-service/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
||||||
import { SearchService } from '../../../../search-service/search.service';
|
import { SearchService } from '../../../../search-service/search.service';
|
||||||
import { SearchFilterService } from '../../search-filter.service';
|
import { SearchFilterService } from '../../search-filter.service';
|
||||||
|
import { SearchConfigurationService } from '../../../../search-service/search-configuration.service';
|
||||||
|
import { hasValue } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-facet-option',
|
selector: 'ds-search-facet-option',
|
||||||
@@ -15,24 +17,22 @@ import { SearchFilterService } from '../../search-filter.service';
|
|||||||
/**
|
/**
|
||||||
* Represents a single option in a filter facet
|
* Represents a single option in a filter facet
|
||||||
*/
|
*/
|
||||||
export class SearchFacetOptionComponent implements OnInit {
|
export class SearchFacetOptionComponent implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* A single value for this component
|
* A single value for this component
|
||||||
*/
|
*/
|
||||||
@Input() filterValue: FacetValue;
|
@Input() filterValue: FacetValue;
|
||||||
@Input() filterConfig: SearchFilterConfig;
|
@Input() filterConfig: SearchFilterConfig;
|
||||||
|
@Input() selectedValues$: Observable<string[]>;
|
||||||
/**
|
|
||||||
* Emits the active values for this filter
|
|
||||||
*/
|
|
||||||
selectedValues$: Observable<string[]>;
|
|
||||||
|
|
||||||
isVisible: Observable<boolean>;
|
isVisible: Observable<boolean>;
|
||||||
|
|
||||||
addQueryParams;
|
addQueryParams;
|
||||||
|
sub: Subscription;
|
||||||
|
|
||||||
constructor(protected searchService: SearchService,
|
constructor(protected searchService: SearchService,
|
||||||
protected filterService: SearchFilterService,
|
protected filterService: SearchFilterService,
|
||||||
|
protected searchConfigService: SearchConfigurationService,
|
||||||
protected router: Router
|
protected router: Router
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -41,9 +41,11 @@ export class SearchFacetOptionComponent implements OnInit {
|
|||||||
* Initializes all observable instance variables and starts listening to them
|
* Initializes all observable instance variables and starts listening to them
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
|
||||||
this.isVisible = this.isChecked().pipe(map((checked: boolean) => !checked));
|
this.isVisible = this.isChecked().pipe(map((checked: boolean) => !checked));
|
||||||
this.addQueryParams = this.getAddParams();
|
this.sub = observableCombineLatest(this.selectedValues$, this.searchConfigService.searchOptions)
|
||||||
|
.subscribe(([selectedValues, searchOptions]) => {
|
||||||
|
this.updateAddParams(selectedValues)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,16 +65,17 @@ export class SearchFacetOptionComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* Calculates the parameters that should change if a given value for this filter would be added to the active filters
|
* Calculates the parameters that should change if a given value for this filter would be added to the active filters
|
||||||
* @param {string} value The value that is added for this filter
|
* @param {string} value The value that is added for this filter
|
||||||
* @returns {Observable<any>} The changed filter parameters
|
|
||||||
*/
|
*/
|
||||||
private getAddParams(): Observable<any> {
|
private updateAddParams(selectedValues: string[]): void {
|
||||||
return this.selectedValues$.pipe(map((selectedValues) => {
|
this.addQueryParams = {
|
||||||
return {
|
[this.filterConfig.paramName]: [...selectedValues, this.filterValue.value],
|
||||||
[this.filterConfig.paramName]: [...selectedValues, this.filterValue.value],
|
page: 1
|
||||||
page: 1
|
};
|
||||||
};
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (hasValue(this.sub)) {
|
||||||
|
this.sub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<a *ngIf="isVisible" class="d-flex flex-row"
|
<a *ngIf="isVisible | async" class="d-flex flex-row"
|
||||||
[routerLink]="[getSearchLink()]"
|
[routerLink]="[getSearchLink()]"
|
||||||
[queryParams]="changeQueryParams | async" queryParamsHandling="merge">
|
[queryParams]="changeQueryParams" queryParamsHandling="merge">
|
||||||
<span class="filter-value px-1">{{filterValue.value}}</span>
|
<span class="filter-value px-1">{{filterValue.value}}</span>
|
||||||
<span class="float-right filter-value-count ml-auto">
|
<span class="float-right filter-value-count ml-auto">
|
||||||
<span class="badge badge-secondary badge-pill">{{filterValue.count}}</span>
|
<span class="badge badge-secondary badge-pill">{{filterValue.count}}</span>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Observable, of as observableOf } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { FacetValue } from '../../../../search-service/facet-value.model';
|
import { FacetValue } from '../../../../search-service/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
RANGE_FILTER_MAX_SUFFIX,
|
RANGE_FILTER_MAX_SUFFIX,
|
||||||
RANGE_FILTER_MIN_SUFFIX
|
RANGE_FILTER_MIN_SUFFIX
|
||||||
} from '../../search-range-filter/search-range-filter.component';
|
} from '../../search-range-filter/search-range-filter.component';
|
||||||
|
import { SearchConfigurationService } from '../../../../search-service/search-configuration.service';
|
||||||
|
import { hasValue } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
const rangeDelimiter = '-';
|
const rangeDelimiter = '-';
|
||||||
|
|
||||||
@@ -21,24 +23,21 @@ const rangeDelimiter = '-';
|
|||||||
/**
|
/**
|
||||||
* Represents a single option in a filter facet
|
* Represents a single option in a filter facet
|
||||||
*/
|
*/
|
||||||
export class SearchFacetRangeOptionComponent implements OnInit {
|
export class SearchFacetRangeOptionComponent implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* A single value for this component
|
* A single value for this component
|
||||||
*/
|
*/
|
||||||
@Input() filterValue: FacetValue;
|
@Input() filterValue: FacetValue;
|
||||||
@Input() filterConfig: SearchFilterConfig;
|
@Input() filterConfig: SearchFilterConfig;
|
||||||
|
|
||||||
/**
|
|
||||||
* Emits the active values for this filter
|
|
||||||
*/
|
|
||||||
selectedValues$: Observable<string[]>;
|
|
||||||
|
|
||||||
isVisible: Observable<boolean>;
|
isVisible: Observable<boolean>;
|
||||||
|
|
||||||
changeQueryParams;
|
changeQueryParams;
|
||||||
|
sub: Subscription;
|
||||||
|
|
||||||
constructor(protected searchService: SearchService,
|
constructor(protected searchService: SearchService,
|
||||||
protected filterService: SearchFilterService,
|
protected filterService: SearchFilterService,
|
||||||
|
protected searchConfigService: SearchConfigurationService,
|
||||||
protected router: Router
|
protected router: Router
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -47,9 +46,10 @@ export class SearchFacetRangeOptionComponent implements OnInit {
|
|||||||
* Initializes all observable instance variables and starts listening to them
|
* Initializes all observable instance variables and starts listening to them
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
|
||||||
this.isVisible = this.isChecked().pipe(map((checked: boolean) => !checked));
|
this.isVisible = this.isChecked().pipe(map((checked: boolean) => !checked));
|
||||||
this.changeQueryParams = this.getChangeParams();
|
this.sub = this.searchConfigService.searchOptions.subscribe(() => {
|
||||||
|
this.updateChangeParams()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,23 +66,24 @@ export class SearchFacetRangeOptionComponent implements OnInit {
|
|||||||
return this.searchService.getSearchLink();
|
return this.searchService.getSearchLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the parameters that should change if a given values for this range filter would be changed
|
* Calculates the parameters that should change if a given values for this range filter would be changed
|
||||||
* @param {string} value The values that are changed for this filter
|
* @param {string} value The values that are changed for this filter
|
||||||
* @returns {Observable<any>} The changed filter parameters
|
|
||||||
*/
|
*/
|
||||||
getChangeParams() {
|
updateChangeParams(): void {
|
||||||
const parts = this.filterValue.value.split(rangeDelimiter);
|
const parts = this.filterValue.value.split(rangeDelimiter);
|
||||||
const min = parts.length > 1 ? parts[0].trim() : this.filterValue.value;
|
const min = parts.length > 1 ? parts[0].trim() : this.filterValue.value;
|
||||||
const max = parts.length > 1 ? parts[1].trim() : this.filterValue.value;
|
const max = parts.length > 1 ? parts[1].trim() : this.filterValue.value;
|
||||||
return observableOf(
|
this.changeQueryParams = {
|
||||||
{
|
[this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX]: [min],
|
||||||
[this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX]: [min],
|
[this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX]: [max],
|
||||||
[this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX]: [max],
|
page: 1
|
||||||
page: 1
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (hasValue(this.sub)) {
|
||||||
|
this.sub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<a class="d-flex flex-row"
|
<a class="d-flex flex-row"
|
||||||
[routerLink]="[getSearchLink()]"
|
[routerLink]="[getSearchLink()]"
|
||||||
[queryParams]="removeQueryParams | async" queryParamsHandling="merge">
|
[queryParams]="removeQueryParams" queryParamsHandling="merge">
|
||||||
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
|
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
|
||||||
<span class="filter-value pl-1">{{selectedValue}}</span>
|
<span class="filter-value pl-1">{{selectedValue}}</span>
|
||||||
</a>
|
</a>
|
@@ -1,11 +1,19 @@
|
|||||||
import { Observable, of as observableOf } from 'rxjs';
|
import {
|
||||||
import { map } from 'rxjs/operators';
|
combineLatest as observableCombineLatest,
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
Observable,
|
||||||
|
of as observableOf,
|
||||||
|
Subscription
|
||||||
|
} from 'rxjs';
|
||||||
|
import { delay, map } from 'rxjs/operators';
|
||||||
|
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { FacetValue } from '../../../../search-service/facet-value.model';
|
import { FacetValue } from '../../../../search-service/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../../../search-service/search-filter-config.model';
|
||||||
import { SearchService } from '../../../../search-service/search.service';
|
import { SearchService } from '../../../../search-service/search.service';
|
||||||
import { SearchFilterService } from '../../search-filter.service';
|
import { SearchFilterService } from '../../search-filter.service';
|
||||||
|
import { hasValue } from '../../../../../shared/empty.util';
|
||||||
|
import { SearchOptions } from '../../../../search-options.model';
|
||||||
|
import { SearchConfigurationService } from '../../../../search-service/search-configuration.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-facet-selected-option',
|
selector: 'ds-search-facet-selected-option',
|
||||||
@@ -15,7 +23,7 @@ import { SearchFilterService } from '../../search-filter.service';
|
|||||||
/**
|
/**
|
||||||
* Represents a single option in a filter facet
|
* Represents a single option in a filter facet
|
||||||
*/
|
*/
|
||||||
export class SearchFacetSelectedOptionComponent implements OnInit {
|
export class SearchFacetSelectedOptionComponent implements OnInit, OnDestroy {
|
||||||
/**
|
/**
|
||||||
* A single value for this component
|
* A single value for this component
|
||||||
*/
|
*/
|
||||||
@@ -25,12 +33,14 @@ export class SearchFacetSelectedOptionComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* Emits the active values for this filter
|
* Emits the active values for this filter
|
||||||
*/
|
*/
|
||||||
selectedValues$: Observable<string[]>;
|
@Input() selectedValues$: Observable<string[]>;
|
||||||
|
|
||||||
removeQueryParams;
|
removeQueryParams;
|
||||||
|
sub: Subscription;
|
||||||
|
|
||||||
constructor(protected searchService: SearchService,
|
constructor(protected searchService: SearchService,
|
||||||
protected filterService: SearchFilterService,
|
protected filterService: SearchFilterService,
|
||||||
|
protected searchConfigService: SearchConfigurationService,
|
||||||
protected router: Router
|
protected router: Router
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -39,8 +49,10 @@ export class SearchFacetSelectedOptionComponent implements OnInit {
|
|||||||
* Initializes all observable instance variables and starts listening to them
|
* Initializes all observable instance variables and starts listening to them
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
this.sub = observableCombineLatest(this.selectedValues$, this.searchConfigService.searchOptions)
|
||||||
this.removeQueryParams = this.getRemoveParams();
|
.subscribe(([selectedValues, searchOptions]) => {
|
||||||
|
this.updateRemoveParams(selectedValues)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,13 +67,16 @@ export class SearchFacetSelectedOptionComponent implements OnInit {
|
|||||||
* @param {string} value The value that is removed for this filter
|
* @param {string} value The value that is removed for this filter
|
||||||
* @returns {Observable<any>} The changed filter parameters
|
* @returns {Observable<any>} The changed filter parameters
|
||||||
*/
|
*/
|
||||||
private getRemoveParams(): Observable<any> {
|
private updateRemoveParams(selectedValues: string[]): void {
|
||||||
return this.selectedValues$.pipe(map((selectedValues) => {
|
this.removeQueryParams = {
|
||||||
return {
|
[this.filterConfig.paramName]: selectedValues.filter((v) => v !== this.selectedValue),
|
||||||
[this.filterConfig.paramName]: selectedValues.filter((v) => v !== this.selectedValue),
|
page: 1
|
||||||
page: 1
|
};
|
||||||
};
|
}
|
||||||
}));
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (hasValue(this.sub)) {
|
||||||
|
this.sub.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -120,20 +120,6 @@ describe('SearchFacetFilterComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the getAddParams method is called wih a value', () => {
|
|
||||||
it('should return the selectedValue list with the new parameter value', () => {
|
|
||||||
const result = comp.getAddParams(value3);
|
|
||||||
result.subscribe((r) => expect(r[mockFilterConfig.paramName]).toEqual([value1, value2, value3]));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the getRemoveParams method is called wih a value', () => {
|
|
||||||
it('should return the selectedValue list with the parameter value left out', () => {
|
|
||||||
const result = comp.getRemoveParams(value1);
|
|
||||||
result.subscribe((r) => expect(r[mockFilterConfig.paramName]).toEqual([value2]));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the showMore method is called', () => {
|
describe('when the showMore method is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(filterService, 'incrementPage');
|
spyOn(filterService, 'incrementPage');
|
||||||
|
@@ -22,6 +22,7 @@ import { FILTER_CONFIG, SearchFilterService } from '../search-filter.service';
|
|||||||
import { SearchConfigurationService } from '../../../search-service/search-configuration.service';
|
import { SearchConfigurationService } from '../../../search-service/search-configuration.service';
|
||||||
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||||
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
||||||
|
import { SearchOptions } from '../../../search-options.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-facet-filter',
|
selector: 'ds-search-facet-filter',
|
||||||
@@ -65,13 +66,14 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
/**
|
/**
|
||||||
* Emits the active values for this filter
|
* Emits the active values for this filter
|
||||||
*/
|
*/
|
||||||
selectedValues: Observable<string[]>;
|
selectedValues$: Observable<string[]>;
|
||||||
private collapseNextUpdate = true;
|
private collapseNextUpdate = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State of the requested facets used to time the animation
|
* State of the requested facets used to time the animation
|
||||||
*/
|
*/
|
||||||
animationState = 'loading';
|
animationState = 'loading';
|
||||||
|
searchOptions$: Observable<SearchOptions>;
|
||||||
|
|
||||||
constructor(protected searchService: SearchService,
|
constructor(protected searchService: SearchService,
|
||||||
protected filterService: SearchFilterService,
|
protected filterService: SearchFilterService,
|
||||||
@@ -85,15 +87,13 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
* Initializes all observable instance variables and starts listening to them
|
* Initializes all observable instance variables and starts listening to them
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
console.log('renderSearchFacetFilterComponent')
|
|
||||||
|
|
||||||
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().pipe(distinctUntilChanged());
|
this.currentPage = this.getCurrentPage().pipe(distinctUntilChanged());
|
||||||
|
|
||||||
this.selectedValues = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig);
|
||||||
const searchOptions = this.searchConfigService.searchOptions;
|
this.searchOptions$ = this.searchConfigService.searchOptions;
|
||||||
this.subs.push(this.searchConfigService.searchOptions.subscribe(() => this.updateFilterValueList()));
|
this.subs.push(this.searchOptions$.subscribe(() => this.updateFilterValueList()));
|
||||||
const facetValues = observableCombineLatest(searchOptions, this.currentPage).pipe(
|
const facetValues = observableCombineLatest(this.searchOptions$, this.currentPage).pipe(
|
||||||
map(([options, page]) => {
|
map(([options, page]) => {
|
||||||
return { options, page }
|
return { options, page }
|
||||||
}),
|
}),
|
||||||
@@ -193,8 +193,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
* @param data The string from the input field
|
* @param data The string from the input field
|
||||||
*/
|
*/
|
||||||
onSubmit(data: any) {
|
onSubmit(data: any) {
|
||||||
console.log('onsubmit');
|
this.selectedValues$.pipe(take(1)).subscribe((selectedValues) => {
|
||||||
this.selectedValues.pipe(take(1)).subscribe((selectedValues) => {
|
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
this.router.navigate([this.getSearchLink()], {
|
this.router.navigate([this.getSearchLink()], {
|
||||||
queryParams:
|
queryParams:
|
||||||
@@ -219,34 +218,6 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
return hasValue(o);
|
return hasValue(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the parameters that should change if a given value for this filter would be removed from the active filters
|
|
||||||
* @param {string} value The value that is removed for this filter
|
|
||||||
* @returns {Observable<any>} The changed filter parameters
|
|
||||||
*/
|
|
||||||
getRemoveParams(value: string): Observable<any> {
|
|
||||||
return this.selectedValues.pipe(map((selectedValues) => {
|
|
||||||
return {
|
|
||||||
[this.filterConfig.paramName]: selectedValues.filter((v) => v !== value),
|
|
||||||
page: 1
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the parameters that should change if a given value for this filter would be added to the active filters
|
|
||||||
* @param {string} value The value that is added for this filter
|
|
||||||
* @returns {Observable<any>} The changed filter parameters
|
|
||||||
*/
|
|
||||||
getAddParams(value: string): Observable<any> {
|
|
||||||
return this.selectedValues.pipe(map((selectedValues) => {
|
|
||||||
return {
|
|
||||||
[this.filterConfig.paramName]: [...selectedValues, value],
|
|
||||||
page: 1
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsubscribe from all subscriptions
|
* Unsubscribe from all subscriptions
|
||||||
*/
|
*/
|
||||||
@@ -263,7 +234,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
findSuggestions(data): void {
|
findSuggestions(data): void {
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
this.searchConfigService.searchOptions.pipe(take(1)).subscribe(
|
this.searchOptions$.pipe(take(1)).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())
|
||||||
.pipe(
|
.pipe(
|
||||||
@@ -295,7 +266,6 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
|
|||||||
return new EmphasizePipe().transform(facet.value, query) + ' (' + facet.count + ')';
|
return new EmphasizePipe().transform(facet.value, query) + ' (' + facet.count + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent unnecessary rerendering
|
* Prevent unnecessary rerendering
|
||||||
*/
|
*/
|
||||||
|
@@ -10,6 +10,7 @@ import { SearchService } from '../../search-service/search.service';
|
|||||||
import { SearchFilterComponent } from './search-filter.component';
|
import { SearchFilterComponent } from './search-filter.component';
|
||||||
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
||||||
import { FilterType } from '../../search-service/filter-type.model';
|
import { FilterType } from '../../search-service/filter-type.model';
|
||||||
|
import { SearchConfigurationService } from '../../search-service/search-configuration.service';
|
||||||
|
|
||||||
describe('SearchFilterComponent', () => {
|
describe('SearchFilterComponent', () => {
|
||||||
let comp: SearchFilterComponent;
|
let comp: SearchFilterComponent;
|
||||||
@@ -33,9 +34,7 @@ describe('SearchFilterComponent', () => {
|
|||||||
},
|
},
|
||||||
expand: (filter) => {
|
expand: (filter) => {
|
||||||
},
|
},
|
||||||
initialCollapse: (filter) => {
|
initializeFilter: (filter) => {
|
||||||
},
|
|
||||||
initialExpand: (filter) => {
|
|
||||||
},
|
},
|
||||||
getSelectedValuesForFilter: (filter) => {
|
getSelectedValuesForFilter: (filter) => {
|
||||||
return observableOf([filterName1, filterName2, filterName3])
|
return observableOf([filterName1, filterName2, filterName3])
|
||||||
@@ -55,6 +54,8 @@ describe('SearchFilterComponent', () => {
|
|||||||
getFacetValuesFor: (filter) => mockResults
|
getFacetValuesFor: (filter) => mockResults
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const searchConfigServiceStub = {};
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule],
|
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule],
|
||||||
@@ -65,6 +66,7 @@ describe('SearchFilterComponent', () => {
|
|||||||
provide: SearchFilterService,
|
provide: SearchFilterService,
|
||||||
useValue: mockFilterService
|
useValue: mockFilterService
|
||||||
},
|
},
|
||||||
|
{ provide: SearchConfigurationService, useValue: searchConfigServiceStub },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).overrideComponent(SearchFilterComponent, {
|
}).overrideComponent(SearchFilterComponent, {
|
||||||
@@ -91,32 +93,21 @@ describe('SearchFilterComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the initialCollapse method is triggered', () => {
|
describe('when the initializeFilter method is triggered', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(filterService, 'initialCollapse');
|
spyOn(filterService, 'initializeFilter');
|
||||||
comp.initialCollapse();
|
comp.initializeFilter();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call initialCollapse with the correct filter configuration name', () => {
|
it('should call initialCollapse with the correct filter configuration name', () => {
|
||||||
expect(filterService.initialCollapse).toHaveBeenCalledWith(mockFilterConfig.name)
|
expect(filterService.initializeFilter).toHaveBeenCalledWith(mockFilterConfig)
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the initialExpand method is triggered', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
spyOn(filterService, 'initialExpand');
|
|
||||||
comp.initialExpand();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call initialCollapse with the correct filter configuration name', () => {
|
|
||||||
expect(filterService.initialExpand).toHaveBeenCalledWith(mockFilterConfig.name)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when getSelectedValues is called', () => {
|
describe('when getSelectedValues is called', () => {
|
||||||
let valuesObservable: Observable<string[]>;
|
let valuesObservable: Observable<string[]>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
valuesObservable = comp.getSelectedValues();
|
valuesObservable = (comp as any).getSelectedValues();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an observable containing the existing filters', () => {
|
it('should return an observable containing the existing filters', () => {
|
||||||
@@ -141,7 +132,7 @@ describe('SearchFilterComponent', () => {
|
|||||||
let isActive: Observable<boolean>;
|
let isActive: Observable<boolean>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
filterService.isCollapsed = () => observableOf(true);
|
filterService.isCollapsed = () => observableOf(true);
|
||||||
isActive = comp.isCollapsed();
|
isActive = (comp as any).isCollapsed();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an observable containing true', () => {
|
it('should return an observable containing true', () => {
|
||||||
@@ -156,7 +147,7 @@ describe('SearchFilterComponent', () => {
|
|||||||
let isActive: Observable<boolean>;
|
let isActive: Observable<boolean>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
filterService.isCollapsed = () => observableOf(false);
|
filterService.isCollapsed = () => observableOf(false);
|
||||||
isActive = comp.isCollapsed();
|
isActive = (comp as any).isCollapsed();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an observable containing false', () => {
|
it('should return an observable containing false', () => {
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
import * as deepFreeze from 'deep-freeze';
|
import * as deepFreeze from 'deep-freeze';
|
||||||
import {
|
import {
|
||||||
SearchFilterCollapseAction, SearchFilterExpandAction, SearchFilterIncrementPageAction,
|
SearchFilterCollapseAction, SearchFilterExpandAction, SearchFilterIncrementPageAction,
|
||||||
SearchFilterInitialCollapseAction,
|
|
||||||
SearchFilterInitialExpandAction,
|
|
||||||
SearchFilterToggleAction,
|
SearchFilterToggleAction,
|
||||||
SearchFilterDecrementPageAction, SearchFilterResetPageAction
|
SearchFilterDecrementPageAction, SearchFilterResetPageAction, SearchFilterInitializeAction
|
||||||
} from './search-filter.actions';
|
} from './search-filter.actions';
|
||||||
import { filterReducer } from './search-filter.reducer';
|
import { filterReducer } from './search-filter.reducer';
|
||||||
|
|
||||||
@@ -98,35 +96,39 @@ describe('filterReducer', () => {
|
|||||||
filterReducer(state, action);
|
filterReducer(state, action);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set filterCollapsed to true in response to the INITIAL_COLLAPSE action when no state has been set for this filter', () => {
|
it('should set filterCollapsed to true in response to the INITIALIZE action with isOpenByDefault to false when no state has been set for this filter', () => {
|
||||||
const state = {};
|
const state = {};
|
||||||
state[filterName2] = { filterCollapsed: false, page: 1 };
|
state[filterName2] = { filterCollapsed: false, page: 1 };
|
||||||
const action = new SearchFilterInitialCollapseAction(filterName1);
|
const filterConfig = {isOpenByDefault: false, name: filterName1} as any;
|
||||||
|
const action = new SearchFilterInitializeAction(filterConfig);
|
||||||
const newState = filterReducer(state, action);
|
const newState = filterReducer(state, action);
|
||||||
|
|
||||||
expect(newState[filterName1].filterCollapsed).toEqual(true);
|
expect(newState[filterName1].filterCollapsed).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set filterCollapsed to true in response to the INITIAL_EXPAND action when no state has been set for this filter', () => {
|
it('should set filterCollapsed to false in response to the INITIALIZE action with isOpenByDefault to true when no state has been set for this filter', () => {
|
||||||
const state = {};
|
const state = {};
|
||||||
state[filterName2] = { filterCollapsed: true, page: 1 };
|
state[filterName2] = { filterCollapsed: true, page: 1 };
|
||||||
const action = new SearchFilterInitialExpandAction(filterName1);
|
const filterConfig = {isOpenByDefault: true, name: filterName1} as any;
|
||||||
|
const action = new SearchFilterInitializeAction(filterConfig);
|
||||||
const newState = filterReducer(state, action);
|
const newState = filterReducer(state, action);
|
||||||
expect(newState[filterName1].filterCollapsed).toEqual(false);
|
expect(newState[filterName1].filterCollapsed).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change the state in response to the INITIAL_COLLAPSE action when the state has already been set for this filter', () => {
|
it('should not change the state in response to the INITIALIZE action with isOpenByDefault to false when the state has already been set for this filter', () => {
|
||||||
const state = {};
|
const state = {};
|
||||||
state[filterName1] = { filterCollapsed: false, page: 1 };
|
state[filterName1] = { filterCollapsed: false, page: 1 };
|
||||||
const action = new SearchFilterInitialCollapseAction(filterName1);
|
const filterConfig = { isOpenByDefault: true, name: filterName1 } as any;
|
||||||
|
const action = new SearchFilterInitializeAction(filterConfig);
|
||||||
const newState = filterReducer(state, action);
|
const newState = filterReducer(state, action);
|
||||||
expect(newState).toEqual(state);
|
expect(newState).toEqual(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change the state in response to the INITIAL_EXPAND action when the state has already been set for this filter', () => {
|
it('should not change the state in response to the INITIALIZE action with isOpenByDefault to true when the state has already been set for this filter', () => {
|
||||||
const state = {};
|
const state = {};
|
||||||
state[filterName1] = { filterCollapsed: true, page: 1 };
|
state[filterName1] = { filterCollapsed: true, page: 1 };
|
||||||
const action = new SearchFilterInitialExpandAction(filterName1);
|
const filterConfig = { isOpenByDefault: false, name: filterName1 } as any;
|
||||||
|
const action = new SearchFilterInitializeAction(filterConfig);
|
||||||
const newState = filterReducer(state, action);
|
const newState = filterReducer(state, action);
|
||||||
expect(newState).toEqual(state);
|
expect(newState).toEqual(state);
|
||||||
});
|
});
|
||||||
|
@@ -71,7 +71,6 @@ describe('SearchFilterService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('when the collapse method is triggered', () => {
|
describe('when the collapse method is triggered', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.collapse(mockFilterConfig.name);
|
service.collapse(mockFilterConfig.name);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||||
import { Injectable, InjectionToken } from '@angular/core';
|
import { Injectable, InjectionToken } from '@angular/core';
|
||||||
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
|
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||||
import { SearchFiltersState, SearchFilterState } from './search-filter.reducer';
|
import { SearchFiltersState, SearchFilterState } from './search-filter.reducer';
|
||||||
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
@@ -16,9 +16,8 @@ import { hasValue, isNotEmpty, } from '../../../shared/empty.util';
|
|||||||
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
||||||
import { RouteService } from '../../../shared/services/route.service';
|
import { RouteService } from '../../../shared/services/route.service';
|
||||||
import { Params } from '@angular/router';
|
import { Params } from '@angular/router';
|
||||||
import { tag } from 'rxjs-spy/operators';
|
import { SearchOptions } from '../../search-options.model';
|
||||||
import { create, detect } from "rxjs-spy";
|
// const spy = create();
|
||||||
const spy = create();
|
|
||||||
const filterStateSelector = (state: SearchFiltersState) => state.searchFilter;
|
const filterStateSelector = (state: SearchFiltersState) => state.searchFilter;
|
||||||
|
|
||||||
export const FILTER_CONFIG: InjectionToken<SearchFilterConfig> = new InjectionToken<SearchFilterConfig>('filterConfig');
|
export const FILTER_CONFIG: InjectionToken<SearchFilterConfig> = new InjectionToken<SearchFilterConfig>('filterConfig');
|
||||||
@@ -59,17 +58,10 @@ export class SearchFilterService {
|
|||||||
* @returns {Observable<string[]>} Emits the active filters for the given filter configuration
|
* @returns {Observable<string[]>} Emits the active filters for the given filter configuration
|
||||||
*/
|
*/
|
||||||
getSelectedValuesForFilter(filterConfig: SearchFilterConfig): Observable<string[]> {
|
getSelectedValuesForFilter(filterConfig: SearchFilterConfig): Observable<string[]> {
|
||||||
const values$ = this.routeService.getQueryParameterValues(filterConfig.paramName).pipe(
|
const values$ = this.routeService.getQueryParameterValues(filterConfig.paramName);
|
||||||
tag("parameter")
|
|
||||||
);
|
|
||||||
const prefixValues$ = this.routeService.getQueryParamsWithPrefix(filterConfig.paramName + '.').pipe(
|
const prefixValues$ = this.routeService.getQueryParamsWithPrefix(filterConfig.paramName + '.').pipe(
|
||||||
map((params: Params) => [].concat(...Object.values(params))),
|
map((params: Params) => [].concat(...Object.values(params))),
|
||||||
tag("prefix-tag")
|
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
spy.log();
|
|
||||||
detect('prefix-tag');
|
|
||||||
|
|
||||||
return observableCombineLatest(values$, prefixValues$).pipe(
|
return observableCombineLatest(values$, prefixValues$).pipe(
|
||||||
map(([values, prefixValues]) => {
|
map(([values, prefixValues]) => {
|
||||||
|
@@ -1,15 +1,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="filters py-2">
|
<div class="filters py-2">
|
||||||
<a *ngFor="let value of (selectedValues | async)" class="d-flex flex-row"
|
<ds-search-facet-selected-option *ngFor="let value of (selectedValues$ | async)" [selectedValue]="value" [filterConfig]="filterConfig" [selectedValues$]="selectedValues$"></ds-search-facet-selected-option>
|
||||||
[routerLink]="[getSearchLink()]"
|
|
||||||
[queryParams]="getRemoveParams(value) | async" queryParamsHandling="merge">
|
|
||||||
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
|
|
||||||
<span class="filter-value pl-1">{{value}}</span>
|
|
||||||
</a>
|
|
||||||
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
||||||
<div [@facetLoad]="animationState">
|
<div [@facetLoad]="animationState">
|
||||||
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value">
|
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value" [selectedValues$]="selectedValues$"></ds-search-facet-option>
|
||||||
</ds-search-facet-option>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div class="clearfix toggle-more-filters">
|
<div class="clearfix toggle-more-filters">
|
||||||
|
@@ -24,9 +24,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
||||||
<div [@facetLoad]="animationState">
|
<div [@facetLoad]="animationState">
|
||||||
<ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
|
<ds-search-facet-range-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value"></ds-search-facet-range-option>
|
||||||
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -106,16 +106,6 @@ describe('SearchRangeFilterComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the getChangeParams method is called wih a value', () => {
|
|
||||||
it('should return the selectedValue list with the new parameter value', () => {
|
|
||||||
const result$ = comp.getChangeParams(value3);
|
|
||||||
result$.subscribe((result) => {
|
|
||||||
expect(result[mockFilterConfig.paramName + minSuffix]).toEqual(['1990']);
|
|
||||||
expect(result[mockFilterConfig.paramName + maxSuffix]).toEqual(['1992']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the onSubmit method is called with data', () => {
|
describe('when the onSubmit method is called with data', () => {
|
||||||
const searchUrl = '/search/path';
|
const searchUrl = '/search/path';
|
||||||
// const data = { [mockFilterConfig.paramName + minSuffix]: '1900', [mockFilterConfig.paramName + maxSuffix]: '1950' };
|
// const data = { [mockFilterConfig.paramName + minSuffix]: '1900', [mockFilterConfig.paramName + maxSuffix]: '1950' };
|
||||||
|
@@ -95,8 +95,6 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
|
|||||||
).subscribe((minmax) => this.range = minmax);
|
).subscribe((minmax) => this.range = minmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits new custom range values to the range filter from the widget
|
* Submits new custom range values to the range filter from the widget
|
||||||
*/
|
*/
|
||||||
|
@@ -1,19 +1,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="filters py-2">
|
<div class="filters py-2">
|
||||||
<a *ngFor="let value of (selectedValues | async)" class="d-flex flex-row"
|
<ds-search-facet-selected-option *ngFor="let value of (selectedValues$ | async)" [selectedValue]="value" [filterConfig]="filterConfig" [selectedValues$]="selectedValues$"></ds-search-facet-selected-option>
|
||||||
[routerLink]="[getSearchLink()]"
|
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
|
||||||
[queryParams]="getRemoveParams(value) | async" queryParamsHandling="merge">
|
|
||||||
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
|
|
||||||
<span class="filter-value pl-1">{{value}}</span>
|
|
||||||
</a>
|
|
||||||
<ng-container *ngVar="(filterValues$ | async) as filterValuesRD">
|
|
||||||
<div [@facetLoad]="animationState">
|
<div [@facetLoad]="animationState">
|
||||||
<ng-container *ngFor="let page of filterValuesRD?.payload">
|
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value" [selectedValues$]="selectedValues$"></ds-search-facet-option>
|
||||||
<ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
|
|
||||||
<ds-search-facet-option *ngFor="let value of page.page; trackBy: trackUpdate" [filterConfig]="filterConfig" [filterValue]="value">
|
|
||||||
</ds-search-facet-option>
|
|
||||||
</ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div class="clearfix toggle-more-filters">
|
<div class="clearfix toggle-more-filters">
|
||||||
|
@@ -117,7 +117,7 @@ describe('SearchConfigurationService', () => {
|
|||||||
|
|
||||||
describe('when subscribeToSearchOptions is called', () => {
|
describe('when subscribeToSearchOptions is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.subscribeToSearchOptions(defaults)
|
(service as any).subscribeToSearchOptions(defaults)
|
||||||
});
|
});
|
||||||
it('should call all getters it needs, but not call any others', () => {
|
it('should call all getters it needs, but not call any others', () => {
|
||||||
expect(service.getCurrentPagination).not.toHaveBeenCalled();
|
expect(service.getCurrentPagination).not.toHaveBeenCalled();
|
||||||
@@ -131,7 +131,7 @@ describe('SearchConfigurationService', () => {
|
|||||||
|
|
||||||
describe('when subscribeToPaginatedSearchOptions is called', () => {
|
describe('when subscribeToPaginatedSearchOptions is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service.subscribeToPaginatedSearchOptions(defaults);
|
(service as any).subscribeToPaginatedSearchOptions(defaults);
|
||||||
});
|
});
|
||||||
it('should call all getters it needs', () => {
|
it('should call all getters it needs', () => {
|
||||||
expect(service.getCurrentPagination).toHaveBeenCalled();
|
expect(service.getCurrentPagination).toHaveBeenCalled();
|
||||||
|
@@ -186,7 +186,7 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
* @param {SearchOptions} defaults Default values for when no parameters are available
|
* @param {SearchOptions} defaults Default values for when no parameters are available
|
||||||
* @returns {Subscription} The subscription to unsubscribe from
|
* @returns {Subscription} The subscription to unsubscribe from
|
||||||
*/
|
*/
|
||||||
subscribeToSearchOptions(defaults: SearchOptions): Subscription {
|
private subscribeToSearchOptions(defaults: SearchOptions): Subscription {
|
||||||
return observableMerge(
|
return observableMerge(
|
||||||
this.getScopePart(defaults.scope),
|
this.getScopePart(defaults.scope),
|
||||||
this.getQueryPart(defaults.query),
|
this.getQueryPart(defaults.query),
|
||||||
@@ -204,7 +204,7 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
* @param {PaginatedSearchOptions} defaults Default values for when no parameters are available
|
* @param {PaginatedSearchOptions} defaults Default values for when no parameters are available
|
||||||
* @returns {Subscription} The subscription to unsubscribe from
|
* @returns {Subscription} The subscription to unsubscribe from
|
||||||
*/
|
*/
|
||||||
subscribeToPaginatedSearchOptions(defaults: PaginatedSearchOptions): Subscription {
|
private subscribeToPaginatedSearchOptions(defaults: PaginatedSearchOptions): Subscription {
|
||||||
return observableMerge(
|
return observableMerge(
|
||||||
this.getPaginationPart(defaults.pagination),
|
this.getPaginationPart(defaults.pagination),
|
||||||
this.getSortPart(defaults.sort),
|
this.getSortPart(defaults.sort),
|
||||||
|
2
src/app/core/cache/object-cache.service.ts
vendored
2
src/app/core/cache/object-cache.service.ts
vendored
@@ -33,7 +33,7 @@ const entryFromSelfLinkSelector =
|
|||||||
(state: ObjectCacheState) => state[selfLink],
|
(state: ObjectCacheState) => state[selfLink],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service to interact with the object cache
|
* A service to interact with the object cache
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@@ -15,7 +15,6 @@ export class RouteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getQueryParameterValues(paramName: string): Observable<string[]> {
|
getQueryParameterValues(paramName: string): Observable<string[]> {
|
||||||
console.log('called');
|
|
||||||
return this.route.queryParamMap.pipe(
|
return this.route.queryParamMap.pipe(
|
||||||
map((params) => [...params.getAll(paramName)]),
|
map((params) => [...params.getAll(paramName)]),
|
||||||
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
|
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
|
||||||
@@ -46,7 +45,6 @@ export class RouteService {
|
|||||||
getQueryParamsWithPrefix(prefix: string): Observable<Params> {
|
getQueryParamsWithPrefix(prefix: string): Observable<Params> {
|
||||||
return this.route.queryParamMap.pipe(
|
return this.route.queryParamMap.pipe(
|
||||||
map((qparams) => {
|
map((qparams) => {
|
||||||
console.log('map');
|
|
||||||
const params = {};
|
const params = {};
|
||||||
qparams.keys
|
qparams.keys
|
||||||
.filter((key) => key.startsWith(prefix))
|
.filter((key) => key.startsWith(prefix))
|
||||||
@@ -55,8 +53,7 @@ export class RouteService {
|
|||||||
});
|
});
|
||||||
return params;
|
return params;
|
||||||
}),
|
}),
|
||||||
distinctUntilChanged((a, b) => { console.log('changed?', a, b, JSON.stringify(a) === JSON.stringify(b)); return JSON.stringify(a) === JSON.stringify(b)}),
|
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),
|
||||||
tap((t) => console.log('changed'))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,6 @@ import { BrowserAppModule } from './modules/app/browser-app.module';
|
|||||||
|
|
||||||
import { ENV_CONFIG } from './config';
|
import { ENV_CONFIG } from './config';
|
||||||
|
|
||||||
|
|
||||||
if (ENV_CONFIG.production) {
|
if (ENV_CONFIG.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user