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