diff --git a/src/app/shared/search/models/applied-filter.model.ts b/src/app/shared/search/models/applied-filter.model.ts new file mode 100644 index 0000000000..279e1c3201 --- /dev/null +++ b/src/app/shared/search/models/applied-filter.model.ts @@ -0,0 +1,17 @@ +import { autoserialize } from 'cerialize'; + +export class AppliedFilter { + + @autoserialize + filter: string; + + @autoserialize + operator: string; + + @autoserialize + value: string; + + @autoserialize + label: string; + +} diff --git a/src/app/shared/search/models/search-query-response.model.ts b/src/app/shared/search/models/search-query-response.model.ts index a436a7c045..31264d3557 100644 --- a/src/app/shared/search/models/search-query-response.model.ts +++ b/src/app/shared/search/models/search-query-response.model.ts @@ -1,6 +1,8 @@ -import { autoserialize } from 'cerialize'; +import { autoserialize, autoserializeAs } from 'cerialize'; import { PageInfo } from '../../../core/shared/page-info.model'; import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { AppliedFilter } from './applied-filter.model'; +import { SearchResultSorting } from './search-result-sorting.model'; /** * Class representing the response returned by the server when performing a search request @@ -21,14 +23,14 @@ export abstract class SearchQueryResponse extends PaginatedList { /** * The currently active filters used in the search request */ - @autoserialize - appliedFilters: any[]; // TODO + @autoserializeAs(AppliedFilter) + appliedFilters: AppliedFilter[]; /** * The sort parameters used in the search request */ - @autoserialize - sort: any; // TODO + @autoserializeAs(SearchResultSorting) + sort: SearchResultSorting; /** * The sort parameters used in the search request diff --git a/src/app/shared/search/models/search-result-sorting.model.ts b/src/app/shared/search/models/search-result-sorting.model.ts new file mode 100644 index 0000000000..e3560eefd4 --- /dev/null +++ b/src/app/shared/search/models/search-result-sorting.model.ts @@ -0,0 +1,11 @@ +import { autoserialize } from 'cerialize'; + +export class SearchResultSorting { + + @autoserialize + by: string; + + @autoserialize + order: string; + +} diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 2b2eb9b11a..3b94399a7d 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -2,14 +2,7 @@ import { animate, state, style, transition, trigger } from '@angular/animations' import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { - BehaviorSubject, - combineLatest as observableCombineLatest, - Observable, - of as observableOf, - Subject, - Subscription -} from 'rxjs'; +import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, of as observableOf, Subject, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map, mergeMap, switchMap, take, tap } from 'rxjs/operators'; import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service'; @@ -20,12 +13,7 @@ import { EmphasizePipe } from '../../../../utils/emphasize.pipe'; import { FacetValue } from '../../../models/facet-value.model'; import { SearchFilterConfig } from '../../../models/search-filter-config.model'; import { SearchService } from '../../../../../core/shared/search/search.service'; -import { - FILTER_CONFIG, - IN_PLACE_SEARCH, - REFRESH_FILTER, - SearchFilterService -} from '../../../../../core/shared/search/search-filter.service'; +import { FILTER_CONFIG, IN_PLACE_SEARCH, REFRESH_FILTER, SearchFilterService } from '../../../../../core/shared/search/search-filter.service'; import { SearchConfigurationService } from '../../../../../core/shared/search/search-configuration.service'; import { getFirstSucceededRemoteData } from '../../../../../core/shared/operators'; import { InputSuggestion } from '../../../../input-suggestions/input-suggestions.model'; @@ -35,6 +23,7 @@ import { currentPath } from '../../../../utils/route.utils'; import { getFacetValueForType, stripOperatorFromFilterValue } from '../../../search.utils'; import { createPendingRemoteDataObject } from '../../../../remote-data.utils'; import { FacetValues } from '../../../models/facet-values.model'; +import { AppliedFilter } from '../../../models/applied-filter.model'; @Component({ selector: 'ds-search-facet-filter', @@ -48,7 +37,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { /** * Emits an array of pages with values found for this facet */ - filterValues$: Subject[]>>; + filterValues$: Subject>; /** * Emits the current last shown page of this facet's values @@ -78,7 +67,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { /** * Emits the active values for this filter */ - selectedValues$: Observable; + selectedValues$: Observable; protected collapseNextUpdate = true; @@ -260,7 +249,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { queryParams: { [this.filterConfig.paramName]: [ - ...selectedValues.map((facet) => this.getFacetValue(facet)), + ...selectedValues.map((appliedFilter: AppliedFilter) => appliedFilter.value), data ] }, @@ -280,12 +269,9 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { return getFacetValueForType(facet, this.filterConfig); } - protected retrieveFilterValues(useCachedVersionIfAvailable = true): Observable[]>> { - const facetValues$ = observableCombineLatest([this.searchOptions$, this.currentPage]).pipe( - map(([options, page]) => { - return { options, page }; - }), - switchMap(({ options, page }) => { + protected retrieveFilterValues(useCachedVersionIfAvailable = true): Observable> { + const facetValues$: Observable<{ values: Observable>, page: number}> = observableCombineLatest([this.searchOptions$, this.currentPage]).pipe( + switchMap(([options, page]: [SearchOptions, number]) => { return this.searchService.getFacetValuesFor(this.filterConfig, page, options, null, useCachedVersionIfAvailable) .pipe( getFirstSucceededRemoteData(), @@ -301,9 +287,9 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { }) ); - let filterValues = []; + let filterValues: Observable>[] = []; return facetValues$.pipe( - mergeMap((facetOutcome) => { + mergeMap((facetOutcome: { values: Observable>, page: number}) => { const newValues$ = facetOutcome.values; if (this.collapseNextUpdate) { @@ -319,22 +305,16 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { return this.rdbs.aggregate(filterValues); }), - tap((rd: RemoteData[]>) => { + tap((rd: RemoteData) => { + const appliedFilters: AppliedFilter[] = [].concat(...rd.payload.map((facetValues: FacetValues) => facetValues.appliedFilters)) + .filter((appliedFilter: AppliedFilter) => hasValue(appliedFilter)); this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig).pipe( - map((selectedValues) => { + map((selectedValues: string[]) => { return selectedValues.map((value: string) => { - const fValue = [].concat(...rd.payload.map((page) => page.page)) - .find((facetValue: FacetValue) => this.getFacetValue(facetValue) === value); - if (hasValue(fValue)) { - return fValue; - } - const filterValue = stripOperatorFromFilterValue(value); - return Object.assign(new FacetValue(), { label: filterValue, value: filterValue }); - }); - }) + return appliedFilters.find((appliedFilter: AppliedFilter) => appliedFilter.value === stripOperatorFromFilterValue(value)); + }).filter((appliedFilter: AppliedFilter) => hasValue(appliedFilter)); + }), ); - }), - tap((rd: RemoteData[]>) => { this.animationState = 'ready'; this.filterValues$.next(rd); })