Applied feedback and other fixes

This commit is contained in:
Lotte Hofstede
2018-04-13 15:18:35 +02:00
parent c9e7cdcf9a
commit e56ea2aff8
20 changed files with 107 additions and 83 deletions

View File

@@ -80,7 +80,8 @@
"search_dspace": "Search DSpace" "search_dspace": "Search DSpace"
}, },
"results": { "results": {
"head": "Search Results" "head": "Search Results",
"no-results": "There were no results for this search"
}, },
"sidebar": { "sidebar": {
"close": "Back to results", "close": "Back to results",

View File

@@ -20,7 +20,7 @@
</ng-container> </ng-container>
</ng-container> </ng-container>
<div class="clearfix toggle-more-filters"> <div class="clearfix toggle-more-filters">
<a class="float-left" *ngIf="!(isLastPage() | async)" <a class="float-left" *ngIf="!(isLastPage$ | async)"
(click)="showMore()">{{"search.filters.filter.show-more" (click)="showMore()">{{"search.filters.filter.show-more"
| translate}}</a> | translate}}</a>
<a class="float-right" *ngIf="(currentPage | async) > 1" <a class="float-right" *ngIf="(currentPage | async) > 1"

View File

@@ -18,6 +18,7 @@ import { SearchOptions } from '../../../search-options.model';
import { RouterStub } from '../../../../shared/testing/router-stub'; import { RouterStub } from '../../../../shared/testing/router-stub';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { PageInfo } from '../../../../core/shared/page-info.model';
describe('SearchFacetFilterComponent', () => { describe('SearchFacetFilterComponent', () => {
let comp: SearchFacetFilterComponent; let comp: SearchFacetFilterComponent;
@@ -56,7 +57,7 @@ describe('SearchFacetFilterComponent', () => {
let router; let router;
const page = Observable.of(0); const page = Observable.of(0);
const mockValues = Observable.of(new RemoteData(false, false, true, null, new PaginatedList(null, values))); const mockValues = Observable.of(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule], imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
@@ -121,14 +122,14 @@ describe('SearchFacetFilterComponent', () => {
}); });
describe('when the getAddParams method is called wih a value', () => { describe('when the getAddParams method is called wih a value', () => {
it('should return the selectedValueq list with the new parameter value', () => { it('should return the selectedValue list with the new parameter value', () => {
const result = comp.getAddParams(value3); const result = comp.getAddParams(value3);
expect(result).toEqual({ [mockFilterConfig.paramName]: [value1, value2, value3] }); expect(result).toEqual({ [mockFilterConfig.paramName]: [value1, value2, value3] });
}); });
}); });
describe('when the getRemoveParams method is called wih a value', () => { describe('when the getRemoveParams method is called wih a value', () => {
it('should return the selectedValueq list with the parameter value left out', () => { it('should return the selectedValue list with the parameter value left out', () => {
const result = comp.getRemoveParams(value1); const result = comp.getRemoveParams(value1);
expect(result).toEqual({ [mockFilterConfig.paramName]: [value2] }); expect(result).toEqual({ [mockFilterConfig.paramName]: [value2] });
}); });

View File

@@ -4,7 +4,7 @@ import { SearchFilterConfig } from '../../../search-service/search-filter-config
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SearchFilterService } from '../search-filter.service'; import { SearchFilterService } from '../search-filter.service';
import { hasValue, isNotEmpty } from '../../../../shared/empty.util'; import { hasNoValue, hasValue, isNotEmpty } from '../../../../shared/empty.util';
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { PaginatedList } from '../../../../core/data/paginated-list'; import { PaginatedList } from '../../../../core/data/paginated-list';
import { SearchService } from '../../../search-service/search.service'; import { SearchService } from '../../../search-service/search.service';
@@ -30,6 +30,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
filterValues: Array<Observable<RemoteData<PaginatedList<FacetValue>>>> = []; filterValues: Array<Observable<RemoteData<PaginatedList<FacetValue>>>> = [];
filterValues$: BehaviorSubject<any> = new BehaviorSubject(this.filterValues); filterValues$: BehaviorSubject<any> = new BehaviorSubject(this.filterValues);
currentPage: Observable<number>; currentPage: Observable<number>;
isLastPage$: BehaviorSubject<boolean> = new BehaviorSubject(false);
filter: string; filter: string;
pageChange = false; pageChange = false;
sub: Subscription; sub: Subscription;
@@ -50,12 +51,12 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
this.pageChange = false; this.pageChange = false;
this.unsubscribe(); this.unsubscribe();
this.sub = this.currentPage.distinctUntilChanged().map((page) => { this.sub = this.currentPage.distinctUntilChanged().map((page) => {
return this.searchService.getFacetValuesFor(this.filterConfig, page, options); return this.searchService.getFacetValuesFor(this.filterConfig, page, options);
}).subscribe((newValues$) => { }).subscribe((newValues$) => {
this.filterValues = [...this.filterValues, newValues$]; this.filterValues = [...this.filterValues, newValues$];
this.filterValues$.next(this.filterValues); this.filterValues$.next(this.filterValues);
newValues$.first().subscribe((rd) => this.isLastPage$.next(hasNoValue(rd.payload.next)));
}); });
} }
@@ -98,18 +99,6 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
hasValue(o: any): boolean { hasValue(o: any): boolean {
return hasValue(o); return hasValue(o);
} }
isLastPage(): Observable<boolean> {
return this.filterValues$.flatMap((map) => {
if (isNotEmpty(map)) {
return map.pop().map((rd: RemoteData<PaginatedList<FacetValue>>) => rd.payload.currentPage >= rd.payload.totalPages);
} else {
return false;
}
});
}
getRemoveParams(value: string) { getRemoveParams(value: string) {
return { [this.filterConfig.paramName]: this.selectedValues.filter((v) => v !== value) }; return { [this.filterConfig.paramName]: this.selectedValues.filter((v) => v !== value) };
} }
@@ -123,7 +112,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
} }
unsubscribe(): void { unsubscribe(): void {
if (this.sub !== undefined) { if (hasValue(this.sub)) {
this.sub.unsubscribe(); this.sub.unsubscribe();
} }
} }

View File

@@ -36,6 +36,4 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -65,6 +65,8 @@ export class SearchPageComponent implements OnInit {
this.resultsRD$ = this.searchOptions$.pipe( this.resultsRD$ = this.searchOptions$.pipe(
flatMap((searchOptions) => this.service.search(searchOptions)) flatMap((searchOptions) => this.service.search(searchOptions))
); );
this.resultsRD$.subscribe((t) => console.log(t));
} }
public closeSidebar(): void { public closeSidebar(): void {

View File

@@ -1,10 +1,11 @@
<h2>{{ 'search.results.head' | translate }}</h2>
<div *ngIf="searchResults?.hasSucceeded && !searchResults?.isLoading" @fadeIn> <div *ngIf="searchResults?.hasSucceeded && !searchResults?.isLoading" @fadeIn>
<h2 *ngIf="searchResults?.payload ?.length > 0">{{ 'search.results.head' | translate }}</h2>
<ds-viewable-collection <ds-viewable-collection
[config]="searchConfig.pagination" [config]="searchConfig.pagination"
[sortConfig]="searchConfig.sort" [sortConfig]="searchConfig.sort"
[objects]="searchResults" [objects]="searchResults"
[hideGear]="true"> [hideGear]="true">
</ds-viewable-collection></div> </ds-viewable-collection></div>
<ds-loading *ngIf="searchResults?.isLoading" message="{{'loading.search-results' | translate}}"></ds-loading> <ds-loading *ngIf="!searchResults || searchResults?.isLoading" message="{{'loading.search-results' | translate}}"></ds-loading>
<ds-error *ngIf="searchResults?.hasFailed" message="{{'error.search-results' | translate}}"></ds-error> <ds-error *ngIf="searchResults?.hasFailed" message="{{'error.search-results' | translate}}"></ds-error>
<ds-error *ngIf="searchResults?.payload?.page.length == 0" message="{{'search.results.no-results' | translate}}"></ds-error>

View File

@@ -5,6 +5,7 @@ import { fadeIn, fadeInOut } from '../../shared/animations/fade';
import { SearchOptions, ViewMode } from '../search-options.model'; import { SearchOptions, ViewMode } from '../search-options.model';
import { SortOptions } from '../../core/cache/models/sort-options.model'; import { SortOptions } from '../../core/cache/models/sort-options.model';
import { SearchResult } from '../search-result.model'; import { SearchResult } from '../search-result.model';
import { PaginatedList } from '../../core/data/paginated-list';
/** /**
* This component renders a simple item page. * This component renders a simple item page.
@@ -20,7 +21,7 @@ import { SearchResult } from '../search-result.model';
] ]
}) })
export class SearchResultsComponent { export class SearchResultsComponent {
@Input() searchResults: RemoteData<Array<SearchResult<DSpaceObject>>>; @Input() searchResults: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>;
@Input() searchConfig: SearchOptions; @Input() searchConfig: SearchOptions;
@Input() sortConfig: SortOptions; @Input() sortConfig: SortOptions;
@Input() viewMode: ViewMode; @Input() viewMode: ViewMode;

View File

@@ -10,7 +10,7 @@ import { ViewMode } from '../../+search-page/search-options.model';
import { RouteService } from '../../shared/route.service'; import { RouteService } from '../../shared/route.service';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router, UrlTree } from '@angular/router';
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { ResponseCacheService } from '../../core/cache/response-cache.service'; import { ResponseCacheService } from '../../core/cache/response-cache.service';
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
@@ -79,7 +79,8 @@ describe('SearchService', () => {
const halService = { const halService = {
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
getEndpoint: () => {} getEndpoint: () => {
}
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}; };
@@ -118,6 +119,8 @@ describe('SearchService', () => {
], ],
}); });
searchService = TestBed.get(SearchService); searchService = TestBed.get(SearchService);
const urlTree = Object.assign(new UrlTree(), { root: { children: { primary: 'search' } } });
router.parseUrl.and.returnValue(urlTree);
}); });
it('should call the navigate method on the Router with view mode list parameter as a parameter when setViewMode is called', () => { it('should call the navigate method on the Router with view mode list parameter as a parameter when setViewMode is called', () => {
@@ -160,7 +163,8 @@ describe('SearchService', () => {
spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint));
(searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry));
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
searchService.search(searchOptions).subscribe((t) => {}); // subscribe to make sure all methods are called searchService.search(searchOptions).subscribe((t) => {
}); // subscribe to make sure all methods are called
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}); });
@@ -189,7 +193,8 @@ describe('SearchService', () => {
spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint));
(searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry));
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
searchService.getConfig(null).subscribe((t) => {}); // subscribe to make sure all methods are called searchService.getConfig(null).subscribe((t) => {
}); // subscribe to make sure all methods are called
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}); });
@@ -220,7 +225,8 @@ describe('SearchService', () => {
spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint)); spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(Observable.of(endPoint));
(searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry)); (searchService as any).responseCache.get.and.returnValue(Observable.of(responseEntry));
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
searchService.getConfig(scope).subscribe((t) => {}); // subscribe to make sure all methods are called searchService.getConfig(scope).subscribe((t) => {
}); // subscribe to make sure all methods are called
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}); });

View File

@@ -1,5 +1,8 @@
import { Injectable, OnDestroy } from '@angular/core'; import { Injectable, OnDestroy } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; import {
ActivatedRoute, NavigationExtras, PRIMARY_OUTLET, Router,
UrlSegmentGroup
} from '@angular/router';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { flatMap, map, tap } from 'rxjs/operators'; import { flatMap, map, tap } from 'rxjs/operators';
import { ViewMode } from '../../+search-page/search-options.model'; import { ViewMode } from '../../+search-page/search-options.model';
@@ -21,13 +24,12 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { GenericConstructor } from '../../core/shared/generic-constructor'; import { GenericConstructor } from '../../core/shared/generic-constructor';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { URLCombiner } from '../../core/url-combiner/url-combiner';
import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { NormalizedSearchResult } from '../normalized-search-result.model'; import { NormalizedSearchResult } from '../normalized-search-result.model';
import { SearchOptions } from '../search-options.model'; import { SearchOptions } from '../search-options.model';
import { SearchResult } from '../search-result.model'; import { SearchResult } from '../search-result.model';
import { FacetValue } from './facet-value.model'; import { FacetValue } from './facet-value.model';
import { FilterType } from './filter-type.model';
import { SearchFilterConfig } from './search-filter-config.model'; import { SearchFilterConfig } from './search-filter-config.model';
import { SearchResponseParsingService } from '../../core/data/search-response-parsing.service'; import { SearchResponseParsingService } from '../../core/data/search-response-parsing.service';
import { SearchQueryResponse } from './search-query-response.model'; import { SearchQueryResponse } from './search-query-response.model';
@@ -37,48 +39,16 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-o
import { FacetValueResponseParsingService } from '../../core/data/facet-value-response-parsing.service'; import { FacetValueResponseParsingService } from '../../core/data/facet-value-response-parsing.service';
import { FacetConfigResponseParsingService } from '../../core/data/facet-config-response-parsing.service'; import { FacetConfigResponseParsingService } from '../../core/data/facet-config-response-parsing.service';
import { PaginatedSearchOptions } from '../paginated-search-options.model'; import { PaginatedSearchOptions } from '../paginated-search-options.model';
import { observable } from 'rxjs/symbol/observable';
@Injectable() @Injectable()
export class SearchService implements OnDestroy { export class SearchService implements OnDestroy {
private searchLinkPath = 'discover/search/objects'; private searchLinkPath = 'discover/search/objects';
private facetValueLinkPath = 'discover/search/facets';
private facetValueLinkPathPrefix = 'discover/facets/'; private facetValueLinkPathPrefix = 'discover/facets/';
private facetConfigLinkPath = 'discover/facets'; private facetConfigLinkPath = 'discover/facets';
private sub; private sub;
uiSearchRoute = '/search';
config: SearchFilterConfig[] = [
// Object.assign(new SearchFilterConfig(),
// {
// name: 'scope',
// type: FilterType.hierarchical,
// hasFacets: true,
// isOpenByDefault: true
// }),
Object.assign(new SearchFilterConfig(),
{
name: 'author',
type: FilterType.text,
hasFacets: true,
isOpenByDefault: false
}),
Object.assign(new SearchFilterConfig(),
{
name: 'dateIssued',
type: FilterType.date,
hasFacets: true,
isOpenByDefault: false
}),
Object.assign(new SearchFilterConfig(),
{
name: 'subject',
type: FilterType.text,
hasFacets: false,
isOpenByDefault: false
})
];
// searchOptions: BehaviorSubject<SearchOptions>;
searchOptions: SearchOptions; searchOptions: SearchOptions;
constructor(private router: Router, constructor(private router: Router,
@@ -96,7 +66,6 @@ export class SearchService implements OnDestroy {
} }
search(searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>> { search(searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>> {
// this.halService.getEndpoint(this.searchLinkPath).subscribe((t) => console.log(t));
const requestObs = this.halService.getEndpoint(this.searchLinkPath).pipe( const requestObs = this.halService.getEndpoint(this.searchLinkPath).pipe(
map((url: string) => { map((url: string) => {
if (hasValue(searchOptions)) { if (hasValue(searchOptions)) {
@@ -136,7 +105,8 @@ export class SearchService implements OnDestroy {
); );
// Create search results again with the correct dso objects linked to each result // Create search results again with the correct dso objects linked to each result
const tDomainListObs: Observable<Array<SearchResult<DSpaceObject>>> = Observable.combineLatest(sqrObs, dsoObs, (sqr: SearchQueryResponse, dsos: RemoteData<DSpaceObject[]>) => { const tDomainListObs = Observable.combineLatest(sqrObs, dsoObs, (sqr: SearchQueryResponse, dsos: RemoteData<DSpaceObject[]>) => {
return sqr.objects.map((object: NormalizedSearchResult, index: number) => { return sqr.objects.map((object: NormalizedSearchResult, index: number) => {
let co = DSpaceObject; let co = DSpaceObject;
if (dsos.payload[index]) { if (dsos.payload[index]) {
@@ -150,7 +120,7 @@ export class SearchService implements OnDestroy {
} }
}); });
}); });
const pageInfoObs: Observable<PageInfo> = responseCacheObs.pipe( const pageInfoObs: Observable<PageInfo> = responseCacheObs.pipe(
map((entry: ResponseCacheEntry) => entry.response), map((entry: ResponseCacheEntry) => entry.response),
map((response: FacetValueSuccessResponse) => response.pageInfo) map((response: FacetValueSuccessResponse) => response.pageInfo)
@@ -262,11 +232,13 @@ export class SearchService implements OnDestroy {
queryParamsHandling: 'merge' queryParamsHandling: 'merge'
}; };
this.router.navigate([this.uiSearchRoute], navigationExtras); this.router.navigate([this.getSearchLink()], navigationExtras);
} }
getSearchLink() { getSearchLink() {
return this.uiSearchRoute; const urlTree = this.router.parseUrl(this.router.url);
const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
return '/' + g.toString();
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@@ -4,7 +4,7 @@ import { map, tap } from 'rxjs/operators';
import { NormalizedSearchResult } from '../../../+search-page/normalized-search-result.model'; import { NormalizedSearchResult } from '../../../+search-page/normalized-search-result.model';
import { SearchResult } from '../../../+search-page/search-result.model'; import { SearchResult } from '../../../+search-page/search-result.model';
import { SearchQueryResponse } from '../../../+search-page/search-service/search-query-response.model'; import { SearchQueryResponse } from '../../../+search-page/search-service/search-query-response.model';
import { hasValue, isNotEmpty } from '../../../shared/empty.util'; import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
import { PaginatedList } from '../../data/paginated-list'; import { PaginatedList } from '../../data/paginated-list';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import { RemoteDataError } from '../../data/remote-data-error'; import { RemoteDataError } from '../../data/remote-data-error';
@@ -200,6 +200,11 @@ export class RemoteDataBuildService {
} }
aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> { aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> {
if (isEmpty(input)) {
return Observable.of(new RemoteData(false, false, true, null, []));
}
return Observable.combineLatest( return Observable.combineLatest(
...input, ...input,
(...arr: Array<RemoteData<T>>) => { (...arr: Array<RemoteData<T>>) => {

View File

@@ -117,8 +117,9 @@ export abstract class BaseResponseParsingService {
this.objectCache.add(co, this.EnvConfig.cache.msToLive, requestHref); this.objectCache.add(co, this.EnvConfig.cache.msToLive, requestHref);
} }
processPageInfo(pageObj: any): PageInfo { processPageInfo(payload: any): PageInfo {
if (isNotEmpty(pageObj)) { if (isNotEmpty(payload.page)) {
const pageObj = Object.assign({}, payload.page, {_links: payload._links});
const pageInfoObject = new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj); const pageInfoObject = new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj);
if (pageInfoObject.currentPage >= 0) { if (pageInfoObject.currentPage >= 0) {
Object.assign(pageInfoObject, { currentPage: pageInfoObject.currentPage + 1 }); Object.assign(pageInfoObject, { currentPage: pageInfoObject.currentPage + 1 });

View File

@@ -29,7 +29,7 @@ export class ConfigResponseParsingService extends BaseResponseParsingService imp
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && data.statusCode === '200') { if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && data.statusCode === '200') {
const configDefinition = this.process<ConfigObject,ConfigType>(data.payload, request.href); const configDefinition = this.process<ConfigObject,ConfigType>(data.payload, request.href);
return new ConfigSuccessResponse(configDefinition[Object.keys(configDefinition)[0]], data.statusCode, this.processPageInfo(data.payload.page)); return new ConfigSuccessResponse(configDefinition[Object.keys(configDefinition)[0]], data.statusCode, this.processPageInfo(data.payload));
} else { } else {
return new ErrorResponse( return new ErrorResponse(
Object.assign( Object.assign(

View File

@@ -28,7 +28,7 @@ export class DSOResponseParsingService extends BaseResponseParsingService implem
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const processRequestDTO = this.process<NormalizedObject,ResourceType>(data.payload, request.href); const processRequestDTO = this.process<NormalizedObject,ResourceType>(data.payload, request.href);
const selfLinks = this.flattenSingleKeyObject(processRequestDTO).map((no) => no.self); const selfLinks = this.flattenSingleKeyObject(processRequestDTO).map((no) => no.self);
return new DSOSuccessResponse(selfLinks, data.statusCode, this.processPageInfo(data.payload.page)) return new DSOSuccessResponse(selfLinks, data.statusCode, this.processPageInfo(data.payload))
} }
} }

View File

@@ -37,7 +37,7 @@ export class FacetValueMapResponseParsingService extends BaseResponseParsingServ
payload._embedded.facets.map((facet) => { payload._embedded.facets.map((facet) => {
const values = facet._embedded.values.map((value) => {value.search = value._links.search.href; return value;}); const values = facet._embedded.values.map((value) => {value.search = value._links.search.href; return value;});
const facetValues = serializer.deserializeArray(values); const facetValues = serializer.deserializeArray(values);
const valuesResponse = new FacetValueSuccessResponse(facetValues, data.statusCode, this.processPageInfo(data.payload.page)); const valuesResponse = new FacetValueSuccessResponse(facetValues, data.statusCode, this.processPageInfo(data.payload));
facetMap[facet.name] = valuesResponse; facetMap[facet.name] = valuesResponse;
}); });

View File

@@ -30,9 +30,9 @@ export class FacetValueResponseParsingService extends BaseResponseParsingService
const payload = data.payload; const payload = data.payload;
const serializer = new DSpaceRESTv2Serializer(FacetValue); const serializer = new DSpaceRESTv2Serializer(FacetValue);
const values = payload._embedded.values.map((value) => {value.search = value._links.search.href; return value;}); // const values = payload._embedded.values.map((value) => {value.search = value._links.search.href; return value;});
const facetValues = serializer.deserializeArray(values); const facetValues = serializer.deserializeArray(payload._embedded.values);
return new FacetValueSuccessResponse(facetValues, data.statusCode, this.processPageInfo(data.payload.page)); return new FacetValueSuccessResponse(facetValues, data.statusCode, this.processPageInfo(data.payload));
} }
} }

View File

@@ -45,10 +45,44 @@ export class PaginatedList<T> {
return this.pageInfo.currentPage; return this.pageInfo.currentPage;
} }
return 1; return 1;
} }
set currentPage(value: number) { set currentPage(value: number) {
this.pageInfo.currentPage = value; this.pageInfo.currentPage = value;
} }
get first(): string {
return this.pageInfo.first;
}
set first(first: string) {
this.pageInfo.first = first;
}
get prev(): string {
return this.pageInfo.prev;
}
set prev(prev: string) {
this.pageInfo.prev = prev;
}
get next(): string {
return this.pageInfo.next;
}
set next(next: string) {
this.pageInfo.next = next;
}
get last(): string {
return this.pageInfo.last;
}
set last(last: string) {
this.pageInfo.last = last;
}
} }

View File

@@ -56,6 +56,6 @@ export class SearchResponseParsingService implements ResponseParsingService {
})); }));
payload.objects = objects; payload.objects = objects;
const deserialized = new DSpaceRESTv2Serializer(SearchQueryResponse).deserialize(payload); const deserialized = new DSpaceRESTv2Serializer(SearchQueryResponse).deserialize(payload);
return new SearchSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload.page)); return new SearchSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload));
} }
} }

View File

@@ -28,4 +28,15 @@ export class PageInfo {
@autoserializeAs(Number, 'number') @autoserializeAs(Number, 'number')
currentPage: number; currentPage: number;
@autoserialize
last: string;
@autoserialize
next: string;
@autoserialize
prev: string;
@autoserialize
first: string;
} }

View File

@@ -1,7 +1,9 @@
export class RouterStub { export class RouterStub {
url: string; url: string;
//noinspection TypeScriptUnresolvedFunction //noinspection TypeScriptUnresolvedFunction
navigate = jasmine.createSpy('navigate'); navigate = jasmine.createSpy('navigate');
parseUrl = jasmine.createSpy('parseUrl');
navigateByUrl(url): void { navigateByUrl(url): void {
this.url = url; this.url = url;
} }