mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 15:33:04 +00:00
Added debounce, fixed error handling for search results, fixed bug in paginated lists
This commit is contained in:
@@ -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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
})
|
||||||
|
;
|
||||||
|
@@ -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(
|
||||||
|
Reference in New Issue
Block a user