From 4af12c21865bdab9a6ce9baf85518b2ce2a22331 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Wed, 19 Sep 2018 14:26:15 +0200 Subject: [PATCH] 55647: Related publications on person pages --- src/app/+item-page/item-page.module.ts | 4 ++- .../person/person-page-fields.component.html | 11 +++++--- .../person/person-page-fields.component.ts | 9 ++++++- .../filtered-search-page.component.ts | 18 ++++++++++++- .../search-fixed-filter.service.ts | 4 +++ .../+search-page/search-page.component.html | 6 ++--- src/app/+search-page/search-page.component.ts | 26 +++++++++++++++---- src/app/+search-page/search-page.module.ts | 3 +++ .../search-configuration.service.ts | 22 +++++++++++++--- 9 files changed, 84 insertions(+), 19 deletions(-) diff --git a/src/app/+item-page/item-page.module.ts b/src/app/+item-page/item-page.module.ts index ce859e0168..cbc8dde575 100644 --- a/src/app/+item-page/item-page.module.ts +++ b/src/app/+item-page/item-page.module.ts @@ -28,12 +28,14 @@ import { RelatedEntitiesComponent } from './simple/related-entities/related-enti import { JournalPageFieldsComponent } from './simple/entity-types/journal/journal-page-fields.component'; import { JournalIssuePageFieldsComponent } from './simple/entity-types/journal-issue/journal-issue-page-fields.component'; import { JournalVolumePageFieldsComponent } from './simple/entity-types/journal-volume/journal-volume-page-fields.component'; +import { SearchPageModule } from '../+search-page/search-page.module'; @NgModule({ imports: [ CommonModule, SharedModule, - ItemPageRoutingModule + ItemPageRoutingModule, + SearchPageModule ], declarations: [ ItemPageComponent, diff --git a/src/app/+item-page/simple/entity-types/person/person-page-fields.component.html b/src/app/+item-page/simple/entity-types/person/person-page-fields.component.html index d7cc3f1158..9b7d09a338 100644 --- a/src/app/+item-page/simple/entity-types/person/person-page-fields.component.html +++ b/src/app/+item-page/simple/entity-types/person/person-page-fields.component.html @@ -24,10 +24,6 @@
- - @@ -49,4 +45,11 @@ [label]="'person.page.firstname'">
+
+ + +
diff --git a/src/app/+item-page/simple/entity-types/person/person-page-fields.component.ts b/src/app/+item-page/simple/entity-types/person/person-page-fields.component.ts index 61b2d87389..71e1fe8640 100644 --- a/src/app/+item-page/simple/entity-types/person/person-page-fields.component.ts +++ b/src/app/+item-page/simple/entity-types/person/person-page-fields.component.ts @@ -9,6 +9,7 @@ import { EntityPageFieldsComponent, filterRelationsByTypeLabel, relationsToItems } from '../shared/entity-page-fields.component'; +import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service'; @rendersEntityType('Person', ElementViewMode.Full) @Component({ @@ -20,10 +21,13 @@ export class PersonPageFieldsComponent extends EntityPageFieldsComponent { publications$: Observable; projects$: Observable; orgUnits$: Observable; + fixedFilter$: Observable; + fixedFilterQuery: string; constructor( @Inject(ITEM) public item: Item, - private ids: ItemDataService + private ids: ItemDataService, + private fixedFilterService: SearchFixedFilterService ) { super(item); } @@ -44,5 +48,8 @@ export class PersonPageFieldsComponent extends EntityPageFieldsComponent { filterRelationsByTypeLabel('isOrgUnitOfPerson'), relationsToItems(this.item.id, this.ids) ); + + this.fixedFilterQuery = this.fixedFilterService.getQueryByRelations('isAuthorOfPublication', this.item.id); + this.fixedFilter$ = Observable.of('publication'); } } diff --git a/src/app/+search-page/filtered-search-page.component.ts b/src/app/+search-page/filtered-search-page.component.ts index e4a75e3481..5feae2171e 100644 --- a/src/app/+search-page/filtered-search-page.component.ts +++ b/src/app/+search-page/filtered-search-page.component.ts @@ -4,10 +4,15 @@ import { SearchFilterService } from './search-filters/search-filter/search-filte import { SearchService } from './search-service/search.service'; import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SearchPageComponent } from './search-page.component'; -import { ChangeDetectionStrategy, Component, Injectable } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Injectable, Input } from '@angular/core'; import { pushInOut } from '../shared/animations/push'; import { RouteService } from '../shared/services/route.service'; import { SearchConfigurationService } from './search-service/search-configuration.service'; +import { switchMap, tap } from 'rxjs/operators'; +import { getSucceededRemoteData } from '../core/shared/operators'; +import { Observable } from 'rxjs/Observable'; +import { PaginatedSearchOptions } from './paginated-search-options.model'; +import { isNotEmpty } from '../shared/empty.util'; /** * This component renders a simple item page. @@ -23,6 +28,12 @@ import { SearchConfigurationService } from './search-service/search-configuratio export class FilteredSearchPageComponent extends SearchPageComponent { + /** + * The actual query for the fixed filter. + * If empty, the query will be determined by the route parameter called 'filter' + */ + @Input() fixedFilterQuery: string; + constructor(protected service: SearchService, protected sidebarService: SearchSidebarService, protected windowService: HostWindowService, @@ -32,4 +43,9 @@ export class FilteredSearchPageComponent extends SearchPageComponent { super(service, sidebarService, windowService, filterService, searchConfigService, routeService); } + protected getSearchOptions(): Observable { + this.searchConfigService.updateFixedFilter(this.fixedFilterQuery); + return this.searchConfigService.paginatedSearchOptions; + } + } diff --git a/src/app/+search-page/search-filters/search-filter/search-fixed-filter.service.ts b/src/app/+search-page/search-filters/search-filter/search-fixed-filter.service.ts index 144bac98c4..66fc82023a 100644 --- a/src/app/+search-page/search-filters/search-filter/search-fixed-filter.service.ts +++ b/src/app/+search-page/search-filters/search-filter/search-fixed-filter.service.ts @@ -56,4 +56,8 @@ export class SearchFixedFilterService { return Observable.of(undefined); } + getQueryByRelations(relationType: string, itemUUID: string): string { + return `query=relation.${relationType}:${itemUUID}`; + } + } diff --git a/src/app/+search-page/search-page.component.html b/src/app/+search-page/search-page.component.html index aa7a117dcd..0dec357c07 100644 --- a/src/app/+search-page/search-page.component.html +++ b/src/app/+search-page/search-page.component.html @@ -4,13 +4,13 @@ id="search-sidebar" [resultCount]="(resultsRD$ | async)?.payload.totalElements">
- - +
+ [fixedFilter]="fixedFilter$ | async">
diff --git a/src/app/+search-page/search-page.component.ts b/src/app/+search-page/search-page.component.ts index c646318de3..6948653d18 100644 --- a/src/app/+search-page/search-page.component.ts +++ b/src/app/+search-page/search-page.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { flatMap, switchMap, } from 'rxjs/operators'; import { PaginatedList } from '../core/data/paginated-list'; @@ -12,7 +12,7 @@ import { SearchResult } from './search-result.model'; import { SearchService } from './search-service/search.service'; import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { Subscription } from 'rxjs/Subscription'; -import { hasValue } from '../shared/empty.util'; +import { hasValue, isNotEmpty } from '../shared/empty.util'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { SearchConfigurationService } from './search-service/search-configuration.service'; import { getSucceededRemoteData } from '../core/shared/operators'; @@ -62,7 +62,17 @@ export class SearchPageComponent implements OnInit { */ sub: Subscription; - fixedFilter; + /** + * Whether or not the search bar should be visible + */ + @Input() + searchEnabled = true; + + /** + * The currently applied filter (determines title of search) + */ + @Input() + fixedFilter$: Observable; constructor(protected service: SearchService, protected sidebarService: SearchSidebarService, @@ -81,7 +91,7 @@ export class SearchPageComponent implements OnInit { * If something changes, update the list of scopes for the dropdown */ ngOnInit(): void { - this.searchOptions$ = this.searchConfigService.paginatedSearchOptions; + this.searchOptions$ = this.getSearchOptions(); this.sub = this.searchOptions$ .switchMap((options) => this.service.search(options).pipe(getSucceededRemoteData())) .subscribe((results) => { @@ -90,7 +100,13 @@ export class SearchPageComponent implements OnInit { this.scopeListRD$ = this.searchConfigService.getCurrentScope('').pipe( switchMap((scopeId) => this.service.getScopes(scopeId)) ); - this.fixedFilter = this.routeService.getRouteParameterValue('filter'); + if (!isNotEmpty(this.fixedFilter$)) { + this.fixedFilter$ = this.routeService.getRouteParameterValue('filter'); + } + } + + protected getSearchOptions(): Observable { + return this.searchConfigService.paginatedSearchOptions; } /** diff --git a/src/app/+search-page/search-page.module.ts b/src/app/+search-page/search-page.module.ts index fd9c2e5adc..658c32d27e 100644 --- a/src/app/+search-page/search-page.module.ts +++ b/src/app/+search-page/search-page.module.ts @@ -89,6 +89,9 @@ const effects = [ SearchTextFilterComponent, SearchHierarchyFilterComponent, SearchBooleanFilterComponent, + ], + exports: [ + FilteredSearchPageComponent ] }) diff --git a/src/app/+search-page/search-service/search-configuration.service.ts b/src/app/+search-page/search-service/search-configuration.service.ts index edd30ac383..a3ebf6b860 100644 --- a/src/app/+search-page/search-service/search-configuration.service.ts +++ b/src/app/+search-page/search-service/search-configuration.service.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, Params } from '@angular/router'; import { PaginatedSearchOptions } from '../paginated-search-options.model'; import { Injectable, OnDestroy } from '@angular/core'; import { RouteService } from '../../shared/services/route.service'; -import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { hasNoValue, hasValue, isEmpty, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util'; import { RemoteData } from '../../core/data/remote-data'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Subscription } from 'rxjs/Subscription'; @@ -14,6 +14,7 @@ import { getSucceededRemoteData } from '../../core/shared/operators'; import { SearchFilter } from '../search-filter.model'; import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model'; import { SearchFixedFilterService } from '../search-filters/search-filter/search-fixed-filter.service'; +import { map } from 'rxjs/operators'; /** * Service that performs all actions that have to do with the current search configuration @@ -306,8 +307,21 @@ export class SearchConfigurationService implements OnDestroy { * @returns {Observable} Emits the current fixed filter as a partial SearchOptions object */ private getFixedFilterPart(): Observable { - return this.getCurrentFixedFilter().map((fixedFilter) => { - return { fixedFilter } - }); + return this.getCurrentFixedFilter().pipe( + isNotEmptyOperator(), + map((fixedFilter) => { + return { fixedFilter } + }) + ); + } + + public updateFixedFilter(fixedFilter: string) { + const currentPaginatedValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue(); + const updatedPaginatedValue: PaginatedSearchOptions = Object.assign(currentPaginatedValue, { fixedFilter: fixedFilter }); + this.paginatedSearchOptions.next(updatedPaginatedValue); + + const currentValue: SearchOptions = this.searchOptions.getValue(); + const updatedValue: SearchOptions = Object.assign(currentValue, { fixedFilter: fixedFilter }); + this.searchOptions.next(updatedValue); } }