From cef2ea827b76cfeb2f3d320b07645d6247534401 Mon Sep 17 00:00:00 2001 From: lotte <lotte_hofstede@hotmail.com> Date: Fri, 6 Jul 2018 13:59:02 +0200 Subject: [PATCH] finished entity search endpoints --- resources/i18n/en.json | 18 +++++++++++++++ .../filtered-search-page.guard.ts | 18 +++++++++++++++ .../search-filter.service.spec.ts | 9 +++++++- .../search-fixed-filter.service.ts | 3 +++ .../search-page-routing.module.ts | 3 ++- .../+search-page/search-page.component.html | 2 +- src/app/+search-page/search-page.component.ts | 3 ++- src/app/+search-page/search-page.module.ts | 4 +++- src/app/+search-page/search-result.model.ts | 1 - .../search-results.component.html | 2 +- .../search-results.component.ts | 12 +++++++++- src/app/core/core.module.ts | 2 ++ ...discovery-page-response-parsing.service.ts | 2 ++ src/app/shared/route.service.spec.ts | 9 ++++++-- src/app/shared/route.service.ts | 22 ++++++++++++++++--- 15 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 src/app/+search-page/filtered-search-page.guard.ts diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 5e30d08ed0..afd1c48e94 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -145,6 +145,24 @@ } }, "search": { + "journal": { + "title": "DSpace Angular :: Journal Search", + "results": { + "head": "Journal Search Results" + } + }, + "person": { + "title": "DSpace Angular :: Person Search", + "results": { + "head": "Person Search Results" + } + }, + "publication": { + "title": "DSpace Angular :: Publication Search", + "results": { + "head": "Publication Search Results" + } + }, "title": "DSpace Angular :: Search", "description": "", "form": { diff --git a/src/app/+search-page/filtered-search-page.guard.ts b/src/app/+search-page/filtered-search-page.guard.ts new file mode 100644 index 0000000000..7d022b81da --- /dev/null +++ b/src/app/+search-page/filtered-search-page.guard.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; +import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; + +@Injectable() + +export class FilteredSearchPageGuard implements CanActivate { + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + const filter = route.params.filter; + + const newTitle = route.data.title + filter + '.title'; + + route.data = { title: newTitle }; + return true; + } +} 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 26eb961c53..6a112fef1c 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 @@ -10,6 +10,7 @@ import { import { SearchFiltersState } from './search-filter.reducer'; import { SearchFilterConfig } from '../../search-service/search-filter-config.model'; import { FilterType } from '../../search-service/filter-type.model'; +import { SearchFixedFilterService } from './search-fixed-filter.service'; describe('SearchFilterService', () => { let service: SearchFilterService; @@ -21,6 +22,12 @@ describe('SearchFilterService', () => { isOpenByDefault: false, pageSize: 2 }); + + const mockFixedFilterService: SearchFixedFilterService = { + getQueryByFilterName: (filter: string) => { + return Observable.of(undefined) + } + } as SearchFixedFilterService const value1 = 'random value'; // const value2 = 'another value'; const store: Store<SearchFiltersState> = jasmine.createSpyObj('store', { @@ -50,7 +57,7 @@ describe('SearchFilterService', () => { }; beforeEach(() => { - service = new SearchFilterService(store, routeServiceStub); + service = new SearchFilterService(store, routeServiceStub, mockFixedFilterService); }); describe('when the initialCollapse method is triggered', () => { 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 252e4b101e..fe46417e59 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 @@ -12,6 +12,7 @@ import { ResponseParsingService } from '../../../core/data/parsing.service'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { FilteredDiscoveryPageResponseParsingService } from '../../../core/data/filtered-discovery-page-response-parsing.service'; import { hasValue } from '../../../shared/empty.util'; +import { configureRequest } from '../../../core/shared/operators'; @Injectable() export class SearchFixedFilterService { @@ -30,12 +31,14 @@ export class SearchFixedFilterService { map((url: string) => { url += ('/' + filterName); const request = new GetRequest(this.requestService.generateRequestId(), url); + console.log(url); return Object.assign(request, { getResponseParser(): GenericConstructor<ResponseParsingService> { return FilteredDiscoveryPageResponseParsingService; } }); }), + configureRequest(this.requestService) ); const responseCacheObs = requestObs.pipe( diff --git a/src/app/+search-page/search-page-routing.module.ts b/src/app/+search-page/search-page-routing.module.ts index 84cb0c31bb..8c138c0d52 100644 --- a/src/app/+search-page/search-page-routing.module.ts +++ b/src/app/+search-page/search-page-routing.module.ts @@ -3,12 +3,13 @@ import { RouterModule } from '@angular/router'; import { SearchPageComponent } from './search-page.component'; import { FilteredSearchPageComponent } from './filtered-search-page.component'; +import { FilteredSearchPageGuard } from './filtered-search-page.guard'; @NgModule({ imports: [ RouterModule.forChild([ { path: '', component: SearchPageComponent, data: { title: 'search.title' } }, - { path: ':filter', component: FilteredSearchPageComponent, data: { title: 'search.title.:filter' } } + { path: ':filter', component: FilteredSearchPageComponent, canActivate: [FilteredSearchPageGuard], data: { title: 'search.' }} ]) ] }) diff --git a/src/app/+search-page/search-page.component.html b/src/app/+search-page/search-page.component.html index 1a1f379920..478403388e 100644 --- a/src/app/+search-page/search-page.component.html +++ b/src/app/+search-page/search-page.component.html @@ -30,7 +30,7 @@ </button> </div> <ds-search-results [searchResults]="resultsRD$ | async" - [searchConfig]="searchOptions$ | async" [sortConfig]="sortConfig"></ds-search-results> + [searchConfig]="searchOptions$ | async" [sortConfig]="sortConfig" [fixedFilter]="fixedFilter | async"></ds-search-results> </div> </div> </div> diff --git a/src/app/+search-page/search-page.component.ts b/src/app/+search-page/search-page.component.ts index b38386d44c..e347688072 100644 --- a/src/app/+search-page/search-page.component.ts +++ b/src/app/+search-page/search-page.component.ts @@ -47,7 +47,7 @@ export class SearchPageComponent implements OnInit { query: '', scope: '' }; - title; + fixedFilter; constructor(protected service: SearchService, protected communityService: CommunityDataService, @@ -68,6 +68,7 @@ export class SearchPageComponent implements OnInit { this.resultsRD$ = this.searchOptions$.pipe( flatMap((searchOptions) => this.service.search(searchOptions)) ); + this.fixedFilter = this.routeService.getRouteParameterValue('filter'); } public closeSidebar(): void { diff --git a/src/app/+search-page/search-page.module.ts b/src/app/+search-page/search-page.module.ts index 206d18267d..25d4b561c3 100644 --- a/src/app/+search-page/search-page.module.ts +++ b/src/app/+search-page/search-page.module.ts @@ -23,6 +23,7 @@ import { SearchFacetFilterComponent } from './search-filters/search-filter/searc import { SearchFilterService } from './search-filters/search-filter/search-filter.service'; import { FilteredSearchPageComponent } from './filtered-search-page.component'; import { SearchFixedFilterService } from './search-filters/search-filter/search-fixed-filter.service'; +import { FilteredSearchPageGuard } from './filtered-search-page.guard'; const effects = [ SearchSidebarEffects @@ -57,7 +58,8 @@ const effects = [ SearchService, SearchSidebarService, SearchFilterService, - SearchFixedFilterService + SearchFixedFilterService, + FilteredSearchPageGuard ], entryComponents: [ ItemSearchResultListElementComponent, diff --git a/src/app/+search-page/search-result.model.ts b/src/app/+search-page/search-result.model.ts index 2298f453e1..cc2bd8cd58 100644 --- a/src/app/+search-page/search-result.model.ts +++ b/src/app/+search-page/search-result.model.ts @@ -1,6 +1,5 @@ import { DSpaceObject } from '../core/shared/dspace-object.model'; import { Metadatum } from '../core/shared/metadatum.model'; -import { hasNoValue, isEmpty } from '../shared/empty.util'; import { ListableObject } from '../shared/object-collection/shared/listable-object.model'; export class SearchResult<T extends DSpaceObject> implements ListableObject { diff --git a/src/app/+search-page/search-results/search-results.component.html b/src/app/+search-page/search-results/search-results.component.html index ed6fc18d9c..a9b54a4601 100644 --- a/src/app/+search-page/search-results/search-results.component.html +++ b/src/app/+search-page/search-results/search-results.component.html @@ -1,4 +1,4 @@ -<h2>{{ 'search.results.head' | translate }}</h2> +<h2>{{ getTitleKey() | translate }}</h2> <div *ngIf="searchResults?.hasSucceeded && !searchResults?.isLoading && searchResults?.payload?.page.length > 0" @fadeIn> <ds-viewable-collection [config]="searchConfig.pagination" diff --git a/src/app/+search-page/search-results/search-results.component.ts b/src/app/+search-page/search-results/search-results.component.ts index 976f422a38..409a866ce8 100644 --- a/src/app/+search-page/search-results/search-results.component.ts +++ b/src/app/+search-page/search-results/search-results.component.ts @@ -3,10 +3,11 @@ import { RemoteData } from '../../core/data/remote-data'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { fadeIn, fadeInOut } from '../../shared/animations/fade'; import { SetViewMode } from '../../shared/view-mode'; -import { SearchOptions} from '../search-options.model'; +import { SearchOptions } from '../search-options.model'; import { SortOptions } from '../../core/cache/models/sort-options.model'; import { SearchResult } from '../search-result.model'; import { PaginatedList } from '../../core/data/paginated-list'; +import { hasValue, isNotEmpty } from '../../shared/empty.util'; /** * This component renders a simple item page. @@ -26,4 +27,13 @@ export class SearchResultsComponent { @Input() searchConfig: SearchOptions; @Input() sortConfig: SortOptions; @Input() viewMode: SetViewMode; + @Input() fixedFilter: string; + + getTitleKey() { + if (isNotEmpty(this.fixedFilter)) { + return 'search.' + this.fixedFilter + '.results.head' + } else { + return 'search.results.head'; + } + } } diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index be99f376da..39771393e2 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -46,6 +46,7 @@ import { FacetValueResponseParsingService } from './data/facet-value-response-pa import { FacetValueMapResponseParsingService } from './data/facet-value-map-response-parsing.service'; import { FacetConfigResponseParsingService } from './data/facet-config-response-parsing.service'; import { NotificationsService } from '../shared/notifications/notifications.service'; +import { FilteredDiscoveryPageResponseParsingService } from './data/filtered-discovery-page-response-parsing.service'; const IMPORTS = [ CommonModule, @@ -93,6 +94,7 @@ const PROVIDERS = [ SubmissionSectionsConfigService, UUIDService, NotificationsService, + FilteredDiscoveryPageResponseParsingService, { provide: NativeWindowService, useFactory: NativeWindowFactory } ]; diff --git a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts index ee87230214..ec1f2fbe2c 100644 --- a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts +++ b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts @@ -18,6 +18,8 @@ export class FilteredDiscoveryPageResponseParsingService extends BaseResponsePar ) { super(); } parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { + console.log('test'); + const query = data.payload['discovery-query']; return new FilteredDiscoveryQueryResponse(query, data.statusCode); } diff --git a/src/app/shared/route.service.spec.ts b/src/app/shared/route.service.spec.ts index b134771b3e..744ee372fe 100644 --- a/src/app/shared/route.service.spec.ts +++ b/src/app/shared/route.service.spec.ts @@ -1,7 +1,9 @@ import { RouteService } from './route.service'; import { async, TestBed } from '@angular/core/testing'; -import { ActivatedRoute, convertToParamMap, Params } from '@angular/router'; +import { ActivatedRoute, convertToParamMap, Params, Router } from '@angular/router'; import { Observable } from 'rxjs/Observable'; +import { MockRouter } from './mocks/mock-router'; +import { RouterStub } from './testing/router-stub'; describe('RouteService', () => { let service: RouteService; @@ -28,12 +30,15 @@ describe('RouteService', () => { queryParamMap: Observable.of(convertToParamMap(paramObject)) }, }, + { + provide: Router, useClass: RouterStub + } ] }); })); beforeEach(() => { - service = new RouteService(TestBed.get(ActivatedRoute)); + service = new RouteService(TestBed.get(ActivatedRoute), TestBed.get(Router)); }); describe('hasQueryParam', () => { diff --git a/src/app/shared/route.service.ts b/src/app/shared/route.service.ts index 3eb629e60c..f374f63432 100644 --- a/src/app/shared/route.service.ts +++ b/src/app/shared/route.service.ts @@ -1,11 +1,15 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; -import { ActivatedRoute, Params, } from '@angular/router'; +import { ActivatedRoute, NavigationEnd, Params, Router, } from '@angular/router'; +import { filter } from 'rxjs/operators'; @Injectable() export class RouteService { + params: Observable<Params>; + + constructor(private route: ActivatedRoute, private router: Router) { + this.subscribeToRouterParams(); - constructor(private route: ActivatedRoute) { } getQueryParameterValues(paramName: string): Observable<string[]> { @@ -25,7 +29,7 @@ export class RouteService { } getRouteParameterValue(paramName: string): Observable<string> { - return this.route.params.map((params) => params[paramName]).distinctUntilChanged(); + return this.params.map((params) => params[paramName]).distinctUntilChanged(); } getRouteDataValue(datafield: string): Observable<any> { @@ -44,4 +48,16 @@ export class RouteService { return params; }).distinctUntilChanged(); } + + subscribeToRouterParams() { + this.router.events.pipe( + filter((event) => event instanceof NavigationEnd)) + .subscribe(() => { + let active = this.route; + while (active.firstChild) { + active = active.firstChild; + } + this.params = active.params; + }); + } } -- GitLab