From cfc448332daf4d85f753868a82bd2b0addabfd33 Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 19 Jul 2018 13:44:38 +0200 Subject: [PATCH] latest fixes for search page --- .../search-filter/search-filter.component.ts | 5 ++-- .../search-filter.service.spec.ts | 1 - .../search-filter/search-filter.service.ts | 30 +++++++------------ .../search-range-filter.component.ts | 23 ++++++++++++-- .../search-labels.component.html | 18 ++++++----- .../search-labels/search-labels.component.ts | 20 +++++-------- .../search-service/filter-label.model.ts | 8 ----- .../search-service/search.service.ts | 2 -- .../search-settings.component.ts | 13 ++++---- src/app/shared/shared.module.ts | 4 ++- src/app/shared/utils/object-keys-pipe.ts | 10 +++++++ 11 files changed, 72 insertions(+), 62 deletions(-) delete mode 100644 src/app/+search-page/search-service/filter-label.model.ts create mode 100644 src/app/shared/utils/object-keys-pipe.ts diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts index ed0e8d934a..badb1c9516 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts @@ -3,6 +3,7 @@ import { SearchFilterConfig } from '../../search-service/search-filter-config.mo import { SearchFilterService } from './search-filter.service'; import { Observable } from 'rxjs/Observable'; import { slide } from '../../../shared/animations/slide'; +import { isNotEmpty } from '../../../shared/empty.util'; /** * This component renders a simple item page. @@ -25,8 +26,8 @@ export class SearchFilterComponent implements OnInit { } ngOnInit() { - this.filterService.isFilterActive(this.filter.paramName).first().subscribe((isActive) => { - if (this.filter.isOpenByDefault || isActive) { + this.getSelectedValues().first().subscribe((isActive) => { + if (this.filter.isOpenByDefault || isNotEmpty(isActive)) { this.initialExpand(); } else { this.initialCollapse(); diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.service.spec.ts b/src/app/+search-page/search-filters/search-filter/search-filter.service.spec.ts index c8cc970cd0..8a7b3eddb0 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.service.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.service.spec.ts @@ -11,7 +11,6 @@ import { SearchFiltersState } from './search-filter.reducer'; import { SearchFilterConfig } from '../../search-service/search-filter-config.model'; import { FilterType } from '../../search-service/filter-type.model'; import { ActivatedRouteStub } from '../../../shared/testing/active-router-stub'; -import { ActivatedRoute } from '@angular/router'; describe('SearchFilterService', () => { let service: SearchFilterService; diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts index bfd5fc3e80..ff5b3325b7 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts @@ -21,7 +21,6 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio import { SearchOptions } from '../../search-options.model'; import { PaginatedSearchOptions } from '../../paginated-search-options.model'; import { ActivatedRoute, Params } from '@angular/router'; -import { FilterLabel } from '../../search-service/filter-label.model'; const filterStateSelector = (state: SearchFiltersState) => state.searchFilter; @@ -85,8 +84,8 @@ export class SearchFilterService { if (key.endsWith('.min') || key.endsWith('.max')) { const realKey = key.slice(0, -4); if (isEmpty(params[realKey])) { - const min = filterParams[realKey + '.min'][0] || '*'; - const max = filterParams[realKey + '.max'][0] || '*'; + const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*'; + const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*'; params[realKey] = ['[' + min + ' TO ' + max + ']']; } } else { @@ -99,21 +98,7 @@ export class SearchFilterService { }); } - getCurrentFilterLabels(): Observable { - return this.getCurrentFilters().pipe( - map((params: Params) => { - const filterLabels: FilterLabel[] = []; - Object.keys(params).forEach((key) => { - params[key].forEach((p: string) => { - filterLabels.push(new FilterLabel(p, key)); - }); - }); - return filterLabels; - }) - ); - } - - getCurrentFrontendFilters(): Observable { + getCurrentFrontendFilters(): Observable { return this.routeService.getQueryParamsWithPrefix('f.'); } @@ -165,7 +150,14 @@ export class SearchFilterService { } getSelectedValuesForFilter(filterConfig: SearchFilterConfig): Observable { - return this.routeService.getQueryParameterValues(filterConfig.paramName); + const values$ = this.routeService.getQueryParameterValues(filterConfig.paramName); + const prefixValues$ = this.routeService.getQueryParamsWithPrefix(filterConfig.paramName + '.').map((params: Params) => [].concat(...Object.values(params))); + return Observable.combineLatest(values$, prefixValues$, (values, prefixValues) => { + if (isNotEmpty(values)) { + return values; + } + return prefixValues; + }) } isCollapsed(filterName: string): Observable { diff --git a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index 056a4bb2e1..c910b3e54f 100644 --- a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -1,5 +1,5 @@ import { isPlatformBrowser } from '@angular/common'; -import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core'; +import { Component, Inject, OnChanges, OnInit, PLATFORM_ID } from '@angular/core'; import { FilterType } from '../../../search-service/filter-type.model'; import { renderFacetFor } from '../search-filter-type-decorator'; import { SearchFacetFilterComponent } from '../search-facet-filter/search-facet-filter.component'; @@ -51,6 +51,8 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple } + + getAddParams(value: string) { const parts = value.split(rangeDelimiter); const min = parts.length > 1 ? parts[0].trim() : value; @@ -70,12 +72,27 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple }; } + getRemoveMaxParam() { + return { + [this.filterConfig.paramName + maxSuffix]: null, + page: 1 + }; + } + getRemoveMinParam() { + return { + [this.filterConfig.paramName + minSuffix]: null, + page: 1 + }; + } + onSubmit() { + const newMin = this.range[0] !== this.min ? [this.range[0]] : null; + const newMax = this.range[1] !== this.max ? [this.range[1]] : null; this.router.navigate([this.getSearchLink()], { queryParams: { - [this.filterConfig.paramName + minSuffix]: [this.range[0]], - [this.filterConfig.paramName + maxSuffix]: [this.range[1]] + [this.filterConfig.paramName + minSuffix]: newMin, + [this.filterConfig.paramName + maxSuffix]: newMax }, queryParamsHandling: 'merge' }); diff --git a/src/app/+search-page/search-labels/search-labels.component.html b/src/app/+search-page/search-labels/search-labels.component.html index 003e920017..e6d77c0e64 100644 --- a/src/app/+search-page/search-labels/search-labels.component.html +++ b/src/app/+search-page/search-labels/search-labels.component.html @@ -1,10 +1,12 @@ diff --git a/src/app/+search-page/search-labels/search-labels.component.ts b/src/app/+search-page/search-labels/search-labels.component.ts index 51aa4ce26c..e0dac304d1 100644 --- a/src/app/+search-page/search-labels/search-labels.component.ts +++ b/src/app/+search-page/search-labels/search-labels.component.ts @@ -2,9 +2,9 @@ import { Component } from '@angular/core'; import { SearchService } from '../search-service/search.service'; import { Observable } from 'rxjs/Observable'; import { Params } from '@angular/router'; -import { FilterLabel } from '../search-service/filter-label.model'; import { map } from 'rxjs/operators'; import { SearchFilterService } from '../search-filters/search-filter/search-filter.service'; +import { hasValue, isNotEmpty } from '../../shared/empty.util'; @Component({ selector: 'ds-search-labels', @@ -12,27 +12,23 @@ import { SearchFilterService } from '../search-filters/search-filter/search-filt }) export class SearchLabelsComponent { - appliedFilters: Observable; + appliedFilters: Observable; constructor(private searchService: SearchService, private filterService: SearchFilterService) { - this.appliedFilters = this.filterService.getCurrentFilterLabels(); + this.appliedFilters = this.filterService.getCurrentFrontendFilters(); } - getRemoveParams(filterLabel: FilterLabel): Observable { + getRemoveParams(filterField: string, filterValue: string): Observable { return this.appliedFilters.pipe( map((filters) => { - const values = []; - filters.forEach((filter) => { - if (filter.field === filterLabel.field && filter.value !== filterLabel.value) { - values.push(filter.value); - } - }); + const field: string = Object.keys(filters).find((f) => f === filterField); + const newValues = hasValue(filters[field]) ? filters[field].filter((v) => v !== filterValue) : null; return { - [filterLabel.field]: values, + [field]: isNotEmpty(newValues) ? newValues : null, page: 1 }; }) - ); + ) } getSearchLink() { diff --git a/src/app/+search-page/search-service/filter-label.model.ts b/src/app/+search-page/search-service/filter-label.model.ts deleted file mode 100644 index dea351d1c2..0000000000 --- a/src/app/+search-page/search-service/filter-label.model.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class FilterLabel { - value: string; - field: string; - constructor(value: string, field: string) { - this.value = value; - this.field = field; - } -} diff --git a/src/app/+search-page/search-service/search.service.ts b/src/app/+search-page/search-service/search.service.ts index e176c96bc7..de1197e40c 100644 --- a/src/app/+search-page/search-service/search.service.ts +++ b/src/app/+search-page/search-service/search.service.ts @@ -40,8 +40,6 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-o import { FacetValueResponseParsingService } from '../../core/data/facet-value-response-parsing.service'; import { FacetConfigResponseParsingService } from '../../core/data/facet-config-response-parsing.service'; import { PaginatedSearchOptions } from '../paginated-search-options.model'; -import { FilterLabel } from './filter-label.model'; -import { combineLatest } from 'rxjs/observable/combineLatest'; import { Community } from '../../core/shared/community.model'; import { CommunityDataService } from '../../core/data/community-data.service'; import { CollectionDataService } from '../../core/data/collection-data.service'; diff --git a/src/app/+search-page/search-settings/search-settings.component.ts b/src/app/+search-page/search-settings/search-settings.component.ts index a0431b50d9..56e2793b01 100644 --- a/src/app/+search-page/search-settings/search-settings.component.ts +++ b/src/app/+search-page/search-settings/search-settings.component.ts @@ -49,22 +49,23 @@ export class SearchSettingsComponent implements OnInit { } ngOnInit(): void { - this.searchOptions = this.service.searchOptions; - this.pageSize = this.searchOptions.pagination.pageSize; - this.pageSizeOptions = this.searchOptions.pagination.pageSizeOptions; this.filterService.getPaginatedSearchOptions(this.defaults).first().subscribe((options) => { this.direction = options.sort.direction; this.field = options.sort.field; this.pageSize = options.pagination.pageSize; + this.searchOptions = options; + this.pageSize = options.pagination.pageSize; + this.pageSizeOptions = options.pagination.pageSizeOptions }) } reloadRPP(event: Event) { const value = (event.target as HTMLInputElement).value; const navigationExtras: NavigationExtras = { - queryParams: Object.assign({}, this.currentParams, { - pageSize: value - }) + queryParams: { + pageSize: value, + }, + queryParamsHandling: 'merge' }; this.router.navigate([ '/search' ], navigationExtras); } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index df311cfc70..ffb8a7b46c 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -55,6 +55,7 @@ import { EmphasizePipe } from './utils/emphasize.pipe'; import { InputSuggestionsComponent } from './input-suggestions/input-suggestions.component'; import { CapitalizePipe } from './utils/capitalize.pipe'; import { MomentModule } from 'angular2-moment'; +import { ObjectKeysPipe } from './utils/object-keys-pipe'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -76,7 +77,8 @@ const PIPES = [ SafeUrlPipe, TruncatePipe, EmphasizePipe, - CapitalizePipe + CapitalizePipe, + ObjectKeysPipe ]; const COMPONENTS = [ diff --git a/src/app/shared/utils/object-keys-pipe.ts b/src/app/shared/utils/object-keys-pipe.ts new file mode 100644 index 0000000000..ce554a0ca1 --- /dev/null +++ b/src/app/shared/utils/object-keys-pipe.ts @@ -0,0 +1,10 @@ +import { PipeTransform, Pipe } from '@angular/core'; + +@Pipe({name: 'dsObjectKeys'}) +export class ObjectKeysPipe implements PipeTransform { + transform(value, args:string[]): any { + const keys = []; + Object.keys(value).forEach((k) => keys.push(k)); + return keys; + } +}