From 234d5a3dc1f6ac910e9a2d1fe62bcda44de1737c Mon Sep 17 00:00:00 2001 From: Jonas Van Goolen Date: Wed, 9 Aug 2017 15:12:09 +0200 Subject: [PATCH 1/5] Addition of SearchService that mocks an array SearchResult objects --- src/app/search/search.service.ts | 75 ++++++++++++++++++++++++++++ src/app/search/searchresult.model.ts | 15 ++++++ 2 files changed, 90 insertions(+) create mode 100644 src/app/search/search.service.ts create mode 100644 src/app/search/searchresult.model.ts diff --git a/src/app/search/search.service.ts b/src/app/search/search.service.ts new file mode 100644 index 0000000000..07cdbef285 --- /dev/null +++ b/src/app/search/search.service.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@angular/core'; +import { RemoteData } from '../core/data/remote-data'; +import { Observable } from 'rxjs/Observable'; +import { SearchResult } from './searchresult.model'; +import { ItemDataService } from '../core/data/item-data.service'; +import { PageInfo } from '../core/shared/page-info.model'; +import { DSpaceObject } from '../core/shared/dspace-object.model'; + +@Injectable() +export class SearchService { + + idsToMock: string[] = new Array( + 'ed5d5f21-1ce4-4b06-b7c2-a7272835ade0', + '0ec7ff22-f211-40ab-a69e-c819b0b1f357', + '9f3288b2-f2ad-454f-9f4c-70325646dcee', + 'fdf0175b-6b0c-421f-9266-28b04341b940', + 'dbe26193-2fa0-4d6c-9f52-edd3572b65a0', + '6212604b-c778-42b3-88e4-cc3b1262ad28', + 'a352a28f-fd5f-4c7b-81bb-06a28b4ea780', + '55a24a8a-1a2f-4fee-b5e8-ca07826d9ff3', + '75664e4e-0000-48e5-b2b6-fbe51ad05f92', + '848e4058-d7b2-482a-b481-e681e7c4016b', + ); + + constructor(private itemDataService: ItemDataService) { + } + + search(query: string, scopeId: string): RemoteData[]> { + const self = `https://dspace7.4science.it/dspace-spring-rest/api/search?query=${query}&scope=${scopeId}`; + const requestPending = Observable.of(false); + const responsePending = Observable.of(false); + const isSuccessFul = Observable.of(true); + const errorMessage = Observable.of(undefined); + const statusCode = Observable.of('200'); + const pageInfo = Observable.of(new PageInfo()); + + let mockSearchResults: SearchResult[] = []; + let dsoObsArr = []; + this.idsToMock = this.idsToMock + + this.idsToMock.forEach(id => { + let remoteObject: RemoteData = this.itemDataService.findById(id); + + let dsoObs = remoteObject.payload.take(1); + dsoObsArr.push(dsoObs); + dsoObs.subscribe((dso: DSpaceObject) => { + let mockResult: SearchResult = new SearchResult(); + mockResult.result = dso; + // Just return the first metadatum as a "highlight" + mockResult.hitHiglights = dso.metadata.slice(0, 1); + mockSearchResults.push(mockResult); + }); + }); + + // combineLatest ->Merges observables. When this is done, put the "mockSearchResults" as a payload + const payload = Observable.combineLatest(...dsoObsArr + , () => { + // Shuffle the searchresult to mimick a changed in the query + let randomization: number[] = new Array(-1, 0, 1); + let number = randomization[ Math.floor(Math.random() * randomization.length) ]; + return mockSearchResults.sort(() => number); + }); + + return new RemoteData( + self, + requestPending, + responsePending, + isSuccessFul, + errorMessage, + statusCode, + pageInfo, + payload + ) + } +} diff --git a/src/app/search/searchresult.model.ts b/src/app/search/searchresult.model.ts new file mode 100644 index 0000000000..8eb1da57e5 --- /dev/null +++ b/src/app/search/searchresult.model.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { DSpaceObject } from '../core/shared/dspace-object.model'; +import { Metadatum } from '../core/shared/metadatum.model'; +import { Observable } from 'rxjs/Observable'; + +@NgModule({ + +}) + +export class SearchResult{ + + result: T; + hitHiglights : Metadatum[]; + +} From 0c22914f904f3c90baf768225fe65f58d5749aa9 Mon Sep 17 00:00:00 2001 From: Jonas Van Goolen Date: Wed, 9 Aug 2017 16:42:40 +0200 Subject: [PATCH 2/5] Addition of pageInfo to returned RemoteData --- src/app/search/search.models.ts | 7 +++++++ src/app/search/search.service.ts | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/app/search/search.models.ts diff --git a/src/app/search/search.models.ts b/src/app/search/search.models.ts new file mode 100644 index 0000000000..4ce3b2e39d --- /dev/null +++ b/src/app/search/search.models.ts @@ -0,0 +1,7 @@ +import { SortOptions } from '../core/cache/models/sort-options.model'; + +export class SearchOptions { + elementsPerPage?: number; + currentPage?: number; + sort?: SortOptions; +} diff --git a/src/app/search/search.service.ts b/src/app/search/search.service.ts index 07cdbef285..85e7f2e8e2 100644 --- a/src/app/search/search.service.ts +++ b/src/app/search/search.service.ts @@ -5,10 +5,13 @@ import { SearchResult } from './searchresult.model'; import { ItemDataService } from '../core/data/item-data.service'; import { PageInfo } from '../core/shared/page-info.model'; import { DSpaceObject } from '../core/shared/dspace-object.model'; +import { SearchOptions } from './search.models'; +import { hasValue } from '../shared/empty.util'; @Injectable() export class SearchService { + totalPages : number = 5; idsToMock: string[] = new Array( 'ed5d5f21-1ce4-4b06-b7c2-a7272835ade0', '0ec7ff22-f211-40ab-a69e-c819b0b1f357', @@ -25,14 +28,23 @@ export class SearchService { constructor(private itemDataService: ItemDataService) { } - search(query: string, scopeId: string): RemoteData[]> { - const self = `https://dspace7.4science.it/dspace-spring-rest/api/search?query=${query}&scope=${scopeId}`; + search(query: string, scopeId: string, searchOptions: SearchOptions): RemoteData[]> { + let self = `https://dspace7.4science.it/dspace-spring-rest/api/search?query=${query}&scope=${scopeId}`; + if(hasValue(searchOptions.currentPage)){ + self+=`¤tPage=${searchOptions.currentPage}`; + } const requestPending = Observable.of(false); const responsePending = Observable.of(false); const isSuccessFul = Observable.of(true); const errorMessage = Observable.of(undefined); const statusCode = Observable.of('200'); - const pageInfo = Observable.of(new PageInfo()); + let returningPageInfo = new PageInfo(); + + returningPageInfo.elementsPerPage = searchOptions.elementsPerPage; + returningPageInfo.currentPage = searchOptions.currentPage; + returningPageInfo.totalPages = this.totalPages; + returningPageInfo.totalElements= this.idsToMock.length*this.totalPages; + const pageInfo = Observable.of(returningPageInfo); let mockSearchResults: SearchResult[] = []; let dsoObsArr = []; From 09920419de7eeedbb14fe03d5edbdb8291b1e481 Mon Sep 17 00:00:00 2001 From: Jonas Van Goolen Date: Thu, 10 Aug 2017 11:29:55 +0200 Subject: [PATCH 3/5] Use actual highlighted (using tag) metadata based on the loop index --- src/app/search/search.service.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/app/search/search.service.ts b/src/app/search/search.service.ts index 85e7f2e8e2..deb589ac29 100644 --- a/src/app/search/search.service.ts +++ b/src/app/search/search.service.ts @@ -7,6 +7,7 @@ import { PageInfo } from '../core/shared/page-info.model'; import { DSpaceObject } from '../core/shared/dspace-object.model'; import { SearchOptions } from './search.models'; import { hasValue } from '../shared/empty.util'; +import { Metadatum } from '../core/shared/metadatum.model'; @Injectable() export class SearchService { @@ -25,6 +26,20 @@ export class SearchService { '848e4058-d7b2-482a-b481-e681e7c4016b', ); + mockedHighlights: string[] = new Array( + 'This is a sample abstract.', + 'This is a sample abstract. But, to fill up some space, here\'s "Hello" in several different languages : ', + 'This is a Sample HTML webpage including several images and styles (CSS).', + 'This is really just a sample abstract. But, Í’vé thrown ïn a cõuple of spëciâl charactèrs för êxtrå fuñ!', + 'This abstract is really quite great', + 'The solution structure of the bee venom neurotoxin', + 'BACKGROUND: The Open Archive Initiative (OAI) refers to a movement started around the \'90 s to guarantee free access to scientific information', + 'The collision fault detection of a XXY stage is proposed for the first time in this paper', + 'This was blank in the actual item, no abstract', + 'The QSAR DataBank (QsarDB) repository', + ); + + constructor(private itemDataService: ItemDataService) { } @@ -50,7 +65,7 @@ export class SearchService { let dsoObsArr = []; this.idsToMock = this.idsToMock - this.idsToMock.forEach(id => { + this.idsToMock.forEach((id,index) => { let remoteObject: RemoteData = this.itemDataService.findById(id); let dsoObs = remoteObject.payload.take(1); @@ -58,8 +73,13 @@ export class SearchService { dsoObs.subscribe((dso: DSpaceObject) => { let mockResult: SearchResult = new SearchResult(); mockResult.result = dso; - // Just return the first metadatum as a "highlight" - mockResult.hitHiglights = dso.metadata.slice(0, 1); + + // Use a mocked highlight based on the index of the loop + let highlight = new Metadatum(); + highlight.key = 'dc.description.abstract'; + highlight.value = this.mockedHighlights[index]; + mockResult.hitHiglights = new Array(highlight); + mockSearchResults.push(mockResult); }); }); From 88a6f8220fce1932dba43b4e508ea68e51b22357 Mon Sep 17 00:00:00 2001 From: Jonas Van Goolen Date: Thu, 10 Aug 2017 14:21:01 +0200 Subject: [PATCH 4/5] Separate module for searchservice + different retrieval of mock items --- ...result.model.ts => search-result.model.ts} | 10 +-- src/app/search/search.module.ts | 17 ++++ src/app/search/search.service.ts | 86 +++++++------------ 3 files changed, 52 insertions(+), 61 deletions(-) rename src/app/search/{searchresult.model.ts => search-result.model.ts} (55%) create mode 100644 src/app/search/search.module.ts diff --git a/src/app/search/searchresult.model.ts b/src/app/search/search-result.model.ts similarity index 55% rename from src/app/search/searchresult.model.ts rename to src/app/search/search-result.model.ts index 8eb1da57e5..9901aa212e 100644 --- a/src/app/search/searchresult.model.ts +++ b/src/app/search/search-result.model.ts @@ -1,15 +1,9 @@ -import { NgModule } from '@angular/core'; import { DSpaceObject } from '../core/shared/dspace-object.model'; import { Metadatum } from '../core/shared/metadatum.model'; -import { Observable } from 'rxjs/Observable'; - -@NgModule({ - -}) export class SearchResult{ - result: T; - hitHiglights : Metadatum[]; + dspaceObject: T; + hitHighlights: Metadatum[]; } diff --git a/src/app/search/search.module.ts b/src/app/search/search.module.ts new file mode 100644 index 0000000000..5808568986 --- /dev/null +++ b/src/app/search/search.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CoreModule } from '../core/core.module'; +import { SearchService } from './search.service'; + +@NgModule({ + imports: [ + CoreModule + ], + declarations: [ + ], + exports: [ + ], + providers: [ + SearchService + ] +}) +export class SearchModule {} diff --git a/src/app/search/search.service.ts b/src/app/search/search.service.ts index deb589ac29..f35d90488f 100644 --- a/src/app/search/search.service.ts +++ b/src/app/search/search.service.ts @@ -1,31 +1,19 @@ import { Injectable } from '@angular/core'; import { RemoteData } from '../core/data/remote-data'; import { Observable } from 'rxjs/Observable'; -import { SearchResult } from './searchresult.model'; +import { SearchResult } from './search-result.model'; import { ItemDataService } from '../core/data/item-data.service'; import { PageInfo } from '../core/shared/page-info.model'; import { DSpaceObject } from '../core/shared/dspace-object.model'; import { SearchOptions } from './search.models'; -import { hasValue } from '../shared/empty.util'; +import { hasValue, isNotEmpty } from '../shared/empty.util'; import { Metadatum } from '../core/shared/metadatum.model'; +import { Item } from '../core/shared/item.model'; @Injectable() export class SearchService { - totalPages : number = 5; - idsToMock: string[] = new Array( - 'ed5d5f21-1ce4-4b06-b7c2-a7272835ade0', - '0ec7ff22-f211-40ab-a69e-c819b0b1f357', - '9f3288b2-f2ad-454f-9f4c-70325646dcee', - 'fdf0175b-6b0c-421f-9266-28b04341b940', - 'dbe26193-2fa0-4d6c-9f52-edd3572b65a0', - '6212604b-c778-42b3-88e4-cc3b1262ad28', - 'a352a28f-fd5f-4c7b-81bb-06a28b4ea780', - '55a24a8a-1a2f-4fee-b5e8-ca07826d9ff3', - '75664e4e-0000-48e5-b2b6-fbe51ad05f92', - '848e4058-d7b2-482a-b481-e681e7c4016b', - ); - + totalPages = 5; mockedHighlights: string[] = new Array( 'This is a sample abstract.', 'This is a sample abstract. But, to fill up some space, here\'s "Hello" in several different languages : ', @@ -39,60 +27,52 @@ export class SearchService { 'The QSAR DataBank (QsarDB) repository', ); - constructor(private itemDataService: ItemDataService) { } - search(query: string, scopeId: string, searchOptions: SearchOptions): RemoteData[]> { - let self = `https://dspace7.4science.it/dspace-spring-rest/api/search?query=${query}&scope=${scopeId}`; - if(hasValue(searchOptions.currentPage)){ - self+=`¤tPage=${searchOptions.currentPage}`; + search(query: string, scopeId?: string, searchOptions?: SearchOptions): RemoteData>> { + let self = `https://dspace7.4science.it/dspace-spring-rest/api/search?query=${query}`; + if (hasValue(scopeId)) { + self += `&scope=${scopeId}`; + } + if (isNotEmpty(searchOptions) && hasValue(searchOptions.currentPage)) { + self += `&page=${searchOptions.currentPage}`; } const requestPending = Observable.of(false); const responsePending = Observable.of(false); const isSuccessFul = Observable.of(true); const errorMessage = Observable.of(undefined); const statusCode = Observable.of('200'); - let returningPageInfo = new PageInfo(); + const returningPageInfo = new PageInfo(); - returningPageInfo.elementsPerPage = searchOptions.elementsPerPage; - returningPageInfo.currentPage = searchOptions.currentPage; + if (isNotEmpty(searchOptions)) { + returningPageInfo.elementsPerPage = searchOptions.elementsPerPage; + returningPageInfo.currentPage = searchOptions.currentPage; + } else { + returningPageInfo.elementsPerPage = 10; + returningPageInfo.currentPage = 1; + } returningPageInfo.totalPages = this.totalPages; - returningPageInfo.totalElements= this.idsToMock.length*this.totalPages; + returningPageInfo.totalElements = 10 * this.totalPages; const pageInfo = Observable.of(returningPageInfo); - let mockSearchResults: SearchResult[] = []; - let dsoObsArr = []; - this.idsToMock = this.idsToMock - - this.idsToMock.forEach((id,index) => { - let remoteObject: RemoteData = this.itemDataService.findById(id); - - let dsoObs = remoteObject.payload.take(1); - dsoObsArr.push(dsoObs); - dsoObs.subscribe((dso: DSpaceObject) => { - let mockResult: SearchResult = new SearchResult(); - mockResult.result = dso; - - // Use a mocked highlight based on the index of the loop - let highlight = new Metadatum(); + const itemsRD = this.itemDataService.findAll({ + scopeID: '8e0928a0-047a-4369-8883-12669f32dd64', + currentPage: returningPageInfo.currentPage, + elementsPerPage: returningPageInfo.elementsPerPage + }); + const payload = itemsRD.payload.map((items: Item[]) => { + return items.map((item: Item, index: number) => { + const mockResult: SearchResult = new SearchResult(); + mockResult.dspaceObject = item; + const highlight = new Metadatum(); highlight.key = 'dc.description.abstract'; - highlight.value = this.mockedHighlights[index]; - mockResult.hitHiglights = new Array(highlight); - - mockSearchResults.push(mockResult); + highlight.value = this.mockedHighlights[index % this.mockedHighlights.length]; + mockResult.hitHighlights = new Array(highlight); + return mockResult; }); }); - // combineLatest ->Merges observables. When this is done, put the "mockSearchResults" as a payload - const payload = Observable.combineLatest(...dsoObsArr - , () => { - // Shuffle the searchresult to mimick a changed in the query - let randomization: number[] = new Array(-1, 0, 1); - let number = randomization[ Math.floor(Math.random() * randomization.length) ]; - return mockSearchResults.sort(() => number); - }); - return new RemoteData( self, requestPending, From 9e5ebce3fd87355d9a3bce73534a91f5ec39252a Mon Sep 17 00:00:00 2001 From: Jonas Van Goolen Date: Thu, 10 Aug 2017 14:41:48 +0200 Subject: [PATCH 5/5] Add randomized sort again --- src/app/search/search.service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/search/search.service.ts b/src/app/search/search.service.ts index f35d90488f..5562056ad2 100644 --- a/src/app/search/search.service.ts +++ b/src/app/search/search.service.ts @@ -62,7 +62,11 @@ export class SearchService { elementsPerPage: returningPageInfo.elementsPerPage }); const payload = itemsRD.payload.map((items: Item[]) => { - return items.map((item: Item, index: number) => { + return items.sort(()=>{ + const values = [-1, 0, 1]; + return values[Math.floor(Math.random() * values.length)]; + }) + .map((item: Item, index: number) => { const mockResult: SearchResult = new SearchResult(); mockResult.dspaceObject = item; const highlight = new Metadatum();