Added debounce, fixed error handling for search results, fixed bug in paginated lists

This commit is contained in:
lotte
2019-03-19 16:22:16 +01:00
parent f160196cf3
commit 6d64326238
4 changed files with 24 additions and 8 deletions

View File

@@ -23,7 +23,7 @@ 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 { import {
configureRequest, configureRequest, filterSuccessfulResponses,
getResponseFromEntry, getResponseFromEntry,
getSucceededRemoteData getSucceededRemoteData
} from '../../core/shared/operators'; } from '../../core/shared/operators';
@@ -104,7 +104,7 @@ export class SearchService implements OnDestroy {
// get search results from response cache // get search results from response cache
const sqrObs: Observable<SearchQueryResponse> = requestEntryObs.pipe( const sqrObs: Observable<SearchQueryResponse> = requestEntryObs.pipe(
getResponseFromEntry(), filterSuccessfulResponses(),
map((response: SearchSuccessResponse) => response.results) map((response: SearchSuccessResponse) => response.results)
); );

View File

@@ -1,5 +1,5 @@
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { hasValue } from '../../shared/empty.util'; import { hasNoValue, hasValue } from '../../shared/empty.util';
export class PaginatedList<T> { export class PaginatedList<T> {
@@ -22,6 +22,9 @@ export class PaginatedList<T> {
if (hasValue(this.pageInfo) && hasValue(this.pageInfo.totalElements)) { if (hasValue(this.pageInfo) && hasValue(this.pageInfo.totalElements)) {
return this.pageInfo.totalElements; return this.pageInfo.totalElements;
} }
if (hasNoValue(this.page)) {
return 0;
}
return this.page.length; return this.page.length;
} }

View File

@@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { DSOSelectorComponent } from './dso-selector.component'; import { DSOSelectorComponent } from './dso-selector.component';
@@ -21,7 +21,12 @@ describe('DSOSelectorComponent', () => {
const type = DSpaceObjectType.ITEM; const type = DSpaceObjectType.ITEM;
const searchResult = new ItemSearchResult(); const searchResult = new ItemSearchResult();
const item = new Item(); const item = new Item();
item.metadata = { 'dc.title': [Object.assign(new MetadataValue(), { value: 'Item title', language: undefined })] }; item.metadata = {
'dc.title': [Object.assign(new MetadataValue(), {
value: 'Item title',
language: undefined
})]
};
searchResult.dspaceObject = item; searchResult.dspaceObject = item;
searchResult.hitHighlights = {}; searchResult.hitHighlights = {};
const searchService = jasmine.createSpyObj('searchService', { const searchService = jasmine.createSpyObj('searchService', {
@@ -46,6 +51,7 @@ describe('DSOSelectorComponent', () => {
debugElement = fixture.debugElement; debugElement = fixture.debugElement;
component.currentDSOId = currentDSOId; component.currentDSOId = currentDSOId;
component.type = type; component.type = type;
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -59,7 +65,9 @@ describe('DSOSelectorComponent', () => {
dsoType: type, dsoType: type,
pagination: (component as any).defaultPagination pagination: (component as any).defaultPagination
}); });
expect(searchService.search).toHaveBeenCalledWith(searchOptions); expect(searchService.search).toHaveBeenCalledWith(searchOptions);
}); });
}); })
;

View File

@@ -1,5 +1,4 @@
import { import {
AfterViewInit,
Component, Component,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
@@ -12,7 +11,7 @@ import {
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map, startWith, switchMap, take } from 'rxjs/operators'; import { debounceTime, startWith, switchMap } from 'rxjs/operators';
import { SearchService } from '../../../+search-page/search-service/search.service'; import { SearchService } from '../../../+search-page/search-service/search.service';
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
@@ -68,6 +67,11 @@ export class DSOSelectorComponent implements OnInit {
*/ */
@ViewChildren('listEntryElement') listElements: QueryList<ElementRef>; @ViewChildren('listEntryElement') listElements: QueryList<ElementRef>;
/**
* Time to wait before sending a search request to the server when a user types something
*/
debounceTime = 500;
constructor(private searchService: SearchService) { constructor(private searchService: SearchService) {
} }
@@ -79,6 +83,7 @@ export class DSOSelectorComponent implements OnInit {
this.input.setValue(this.currentDSOId); this.input.setValue(this.currentDSOId);
this.listEntries$ = this.input.valueChanges this.listEntries$ = this.input.valueChanges
.pipe( .pipe(
debounceTime(this.debounceTime),
startWith(this.currentDSOId), startWith(this.currentDSOId),
switchMap((query) => { switchMap((query) => {
return this.searchService.search( return this.searchService.search(