mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
latest fixes for search page
This commit is contained in:
@@ -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();
|
||||
|
@@ -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;
|
||||
|
@@ -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<FilterLabel[]> {
|
||||
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<any> {
|
||||
getCurrentFrontendFilters(): Observable<Params> {
|
||||
return this.routeService.getQueryParamsWithPrefix('f.');
|
||||
}
|
||||
|
||||
@@ -165,7 +150,14 @@ export class SearchFilterService {
|
||||
}
|
||||
|
||||
getSelectedValuesForFilter(filterConfig: SearchFilterConfig): Observable<string[]> {
|
||||
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<boolean> {
|
||||
|
@@ -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'
|
||||
});
|
||||
|
@@ -1,10 +1,12 @@
|
||||
<div class="row">
|
||||
<div class="labels col-sm-9 offset-sm-3">
|
||||
<a *ngFor="let label of (appliedFilters | async)" class="badge badge-primary mr-1"
|
||||
<ng-container *ngFor="let key of ((appliedFilters | async) | dsObjectKeys)">
|
||||
<a *ngFor="let values of (appliedFilters | async)[key]" class="badge badge-primary mr-1"
|
||||
[routerLink]="getSearchLink()"
|
||||
[queryParams]="(getRemoveParams(label) | async)" queryParamsHandling="merge">
|
||||
{{label.value}}
|
||||
[queryParams]="(getRemoveParams(key, values) | async)" queryParamsHandling="merge">
|
||||
{{values}}
|
||||
<span> ×</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -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<FilterLabel[]>;
|
||||
appliedFilters: Observable<Params>;
|
||||
|
||||
constructor(private searchService: SearchService, private filterService: SearchFilterService) {
|
||||
this.appliedFilters = this.filterService.getCurrentFilterLabels();
|
||||
this.appliedFilters = this.filterService.getCurrentFrontendFilters();
|
||||
}
|
||||
|
||||
getRemoveParams(filterLabel: FilterLabel): Observable<Params> {
|
||||
getRemoveParams(filterField: string, filterValue: string): Observable<Params> {
|
||||
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() {
|
||||
|
@@ -1,8 +0,0 @@
|
||||
export class FilterLabel {
|
||||
value: string;
|
||||
field: string;
|
||||
constructor(value: string, field: string) {
|
||||
this.value = value;
|
||||
this.field = field;
|
||||
}
|
||||
}
|
@@ -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';
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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 = [
|
||||
|
10
src/app/shared/utils/object-keys-pipe.ts
Normal file
10
src/app/shared/utils/object-keys-pipe.ts
Normal file
@@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user