Update search component to work with 0.4.0 JS API

- Use new search (query) methods
- Allow search parameters to be overridden by component
- Fix up tests

Refs #555
This commit is contained in:
Will Abson
2016-11-04 14:21:19 +00:00
parent 903c313615
commit 0e127c26af
13 changed files with 172 additions and 65 deletions

View File

@@ -1,5 +1,12 @@
<alfresco-search-control *ngIf="isLoggedIn()" [searchTerm]="searchTerm" [autocomplete]="false" <alfresco-search-control *ngIf="isLoggedIn()"
(searchSubmit)="onSearchSubmit($event);" (searchChange)="onSearchTermChange($event);" (expand)="onExpandToggle($event);" (fileSelect)="onFileClicked($event)"></alfresco-search-control> [searchTerm]="searchTerm"
[autocomplete]="false"
[liveSearchResultType]="'cm:content'"
(searchSubmit)="onSearchSubmit($event);"
(searchChange)="onSearchTermChange($event);"
(expand)="onExpandToggle($event);"
(fileSelect)="onFileClicked($event)">
</alfresco-search-control>
<alfresco-viewer [(showViewer)]="fileShowed" <alfresco-viewer [(showViewer)]="fileShowed"
[fileNodeId]="fileNodeId" [fileNodeId]="fileNodeId"

View File

@@ -1,6 +1,6 @@
<div class="search-results-container"> <div class="search-results-container">
<h1>Search results</h1> <h1>Search results</h1>
<alfresco-search (preview)="onFileClicked($event)"></alfresco-search> <alfresco-search [resultType]="'cm:content'" (preview)="onFileClicked($event)"></alfresco-search>
</div> </div>
<alfresco-viewer [(showViewer)]="fileShowed" [fileNodeId]="fileNodeId" [overlayMode]="true"> <alfresco-viewer [(showViewer)]="fileShowed" [fileNodeId]="fileNodeId" [overlayMode]="true">

View File

@@ -180,9 +180,13 @@ bootstrap(SearchDemo, [
**searchTerm**: {string} (optional) default "". Search term to pre-populate the field with<br /> **searchTerm**: {string} (optional) default "". Search term to pre-populate the field with<br />
**inputType**: {string} (optional) default "text". Type of the input field to render, e.g. "search" or "text" (default)<br /> **inputType**: {string} (optional) default "text". Type of the input field to render, e.g. "search" or "text" (default)<br />
**expandable** {boolean} (optional) default true. Whether to use an expanding search control, if false then a regular input is used. **expandable** {boolean} (optional) default true. Whether to use an expanding search control, if false then a regular input is used.<br />
**autocomplete** {boolean} (optional) default true. Whether the browser should offer field auto-completion for the input field to the user. **autocomplete** {boolean} (optional) default true. Whether the browser should offer field auto-completion for the input field to the user.<br />
**autocompleteEnabled** {boolean} (optional) default true. Whether find-as-you-type suggestions should be offered for matching content items. Set to false to disable. **liveSearchEnabled** {boolean} (optional) default true. Whether find-as-you-type suggestions should be offered for matching content items. Set to false to disable.<br />
**liveSearchRoot** {boolean} (optional) default "-root-". NodeRef or node name where the search should start.<br />
**liveSearchResultType** {boolean} (optional) default (none). Node type to filter live search results by, e.g. 'cm:content'.<br />
**liveSearchMaxResults** {boolean} (optional) default 5. Maximum number of results to show in the live search.<br />
**liveSearchResultSort** {boolean} (optional) default (none). Criteria to sort live search results by, must be one of "name" , "modifiedAt" or "createdAt"
### Search results ### Search results
@@ -337,6 +341,10 @@ None
**searchTerm**: {string} (optional) default "". Search term to use when executing the search. Updating this value will **searchTerm**: {string} (optional) default "". Search term to use when executing the search. Updating this value will
run a new search and update the results.<br /> run a new search and update the results.<br />
**rootNodeId** {boolean} (optional) default "-root-". NodeRef or node name where the search should start.<br />
**resultType** {boolean} (optional) default (none). Node type to filter search results by, e.g. 'cm:content'.<br />
**maxResults** {boolean} (optional) default 20. Maximum number of results to show in the search.<br />
**resultSort** {boolean} (optional) default (none). Criteria to sort search results by, must be one of "name" , "modifiedAt" or "createdAt"
## Build from sources ## Build from sources

View File

@@ -56,8 +56,8 @@ export var fakeError = {
export var fakeApi = { export var fakeApi = {
core: { core: {
searchApi: { queriesApi: {
liveSearchNodes: (term, opts) => Promise.resolve(fakeSearch) findNodes: (term, opts) => Promise.resolve(fakeSearch)
} }
} }
}; };

View File

@@ -80,7 +80,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should clear results straight away when a new search term is entered', async(() => { it('should clear results straight away when a new search term is entered', async(() => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.searchTerm = 'searchTerm'; component.searchTerm = 'searchTerm';
@@ -97,7 +97,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should display the returned search results', (done) => { it('should display the returned search results', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -112,7 +112,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should limit the number of returned search results to the configured maximum', (done) => { it('should limit the number of returned search results to the configured maximum', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(results)); .and.returnValue(Promise.resolve(results));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -127,7 +127,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should display the correct thumbnail for result items', (done) => { it('should display the correct thumbnail for result items', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.baseComponentPath = 'http://localhost'; component.baseComponentPath = 'http://localhost';
@@ -150,7 +150,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should display no result if no result are returned', (done) => { it('should display no result if no result are returned', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(noResult)); .and.returnValue(Promise.resolve(noResult));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -170,7 +170,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
beforeEach(() => { beforeEach(() => {
searchService = fixture.debugElement.injector.get(AlfrescoSearchService); searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.reject(errorJson)); .and.returnValue(Promise.reject(errorJson));
}); });
@@ -215,7 +215,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should emit file select when file item clicked', (done) => { it('should emit file select when file item clicked', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -232,7 +232,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
it('should not emit preview if a non-file item is clicked', (done) => { it('should not emit preview if a non-file item is clicked', (done) => {
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(folderResult)); .and.returnValue(Promise.resolve(folderResult));
spyOn(component.fileSelect, 'emit'); spyOn(component.fileSelect, 'emit');
@@ -254,7 +254,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
beforeEach(() => { beforeEach(() => {
searchService = fixture.debugElement.injector.get(AlfrescoSearchService); searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(results)); .and.returnValue(Promise.resolve(results));
}); });
@@ -366,7 +366,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
beforeEach(() => { beforeEach(() => {
searchService = fixture.debugElement.injector.get(AlfrescoSearchService); searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
}); });

View File

@@ -16,7 +16,7 @@
*/ */
import { Component, ElementRef, EventEmitter, Input, OnInit, OnChanges, Output, ViewChild } from '@angular/core'; import { Component, ElementRef, EventEmitter, Input, OnInit, OnChanges, Output, ViewChild } from '@angular/core';
import { AlfrescoSearchService } from './../services/alfresco-search.service'; import { AlfrescoSearchService, SearchOptions } from './../services/alfresco-search.service';
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService } from 'ng2-alfresco-core';
@@ -43,6 +43,15 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
@Input() @Input()
maxResults: number = 5; maxResults: number = 5;
@Input()
resultSort: string = null;
@Input()
rootNodeId: string = '-root';
@Input()
resultType: string = null;
@Output() @Output()
fileSelect: EventEmitter<any> = new EventEmitter(); fileSelect: EventEmitter<any> = new EventEmitter();
@@ -84,9 +93,16 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
* @param searchTerm Search query entered by user * @param searchTerm Search query entered by user
*/ */
private displaySearchResults(searchTerm) { private displaySearchResults(searchTerm) {
let searchOpts: SearchOptions = {
include: ['path'],
rootNodeId: this.rootNodeId,
nodeType: this.resultType,
maxItems: this.maxResults,
orderBy: this.resultSort
};
if (searchTerm !== null && searchTerm !== '') { if (searchTerm !== null && searchTerm !== '') {
this.alfrescoSearchService this.alfrescoSearchService
.getLiveSearchResults(searchTerm) .getNodeQueryResults(searchTerm, searchOpts)
.subscribe( .subscribe(
results => { results => {
this.results = results.list.entries.slice(0, this.maxResults); this.results = results.list.entries.slice(0, this.maxResults);

View File

@@ -22,8 +22,13 @@
</div> </div>
</div> </div>
</form> </form>
<alfresco-search-autocomplete #autocomplete *ngIf="autocompleteEnabled" <alfresco-search-autocomplete #autocomplete *ngIf="liveSearchEnabled"
[searchTerm]="autocompleteSearchTerm" [ngClass]="{active: searchActive, valid: searchValid}" [searchTerm]="liveSearchTerm"
[rootNodeId]="liveSearchRoot"
[resultType]="liveSearchResultType"
[resultSort]="liveSearchResultSort"
[maxResults]="liveSearchMaxResults"
[ngClass]="{active: searchActive, valid: searchValid}"
(fileSelect)="onFileClicked($event)" (fileSelect)="onFileClicked($event)"
(searchFocus)="onAutoCompleteFocus($event)" (searchFocus)="onAutoCompleteFocus($event)"
(scrollBack)="onAutoCompleteReturn($event)" (scrollBack)="onAutoCompleteReturn($event)"

View File

@@ -176,7 +176,7 @@ describe('AlfrescoSearchControlComponent', () => {
it('should keep find-as-you-type control visible when user tabs into results', (done) => { it('should keep find-as-you-type control visible when user tabs into results', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
fixture.detectChanges(); fixture.detectChanges();
@@ -219,7 +219,7 @@ describe('AlfrescoSearchControlComponent', () => {
it('should select the first result in find-as-you-type when down arrow is pressed and FAYT is visible', (done) => { it('should select the first result in find-as-you-type when down arrow is pressed and FAYT is visible', (done) => {
fixture.detectChanges(); fixture.detectChanges();
spyOn(component.autocompleteComponent, 'focusResult'); spyOn(component.liveSearchComponent, 'focusResult');
fixture.detectChanges(); fixture.detectChanges();
inputEl.dispatchEvent(new Event('focus')); inputEl.dispatchEvent(new Event('focus'));
window.setTimeout(() => { // wait for debounce() to complete window.setTimeout(() => { // wait for debounce() to complete
@@ -228,7 +228,7 @@ describe('AlfrescoSearchControlComponent', () => {
key: 'ArrowDown' key: 'ArrowDown'
})); }));
fixture.detectChanges(); fixture.detectChanges();
expect(component.autocompleteComponent.focusResult).toHaveBeenCalled(); expect(component.liveSearchComponent.focusResult).toHaveBeenCalled();
done(); done();
}, 100); }, 100);
}); });
@@ -254,7 +254,7 @@ describe('AlfrescoSearchControlComponent', () => {
}); });
it('should NOT display a find-as-you-type control when configured not to', () => { it('should NOT display a find-as-you-type control when configured not to', () => {
fixture.componentInstance.autocompleteEnabled = false; fixture.componentInstance.liveSearchEnabled = false;
fixture.detectChanges(); fixture.detectChanges();
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete'); let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
expect(autocomplete).toBeNull(); expect(autocomplete).toBeNull();

View File

@@ -56,16 +56,29 @@ export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
searchControl: FormControl; searchControl: FormControl;
@ViewChild('searchInput', {}) searchInput: ElementRef; @ViewChild('searchInput', {})
searchInput: ElementRef;
@ViewChild('autocomplete') @ViewChild(AlfrescoSearchAutocompleteComponent)
autocompleteComponent: AlfrescoSearchAutocompleteComponent; liveSearchComponent: AlfrescoSearchAutocompleteComponent;
@Input() @Input()
autocompleteEnabled = true; liveSearchEnabled: boolean = true;
@Input() @Input()
autocompleteSearchTerm = ''; liveSearchTerm: string = '';
@Input()
liveSearchRoot: string = '-root-';
@Input()
liveSearchResultType: string = 'cm:content';
@Input()
liveSearchResultSort: string = null;
@Input()
liveSearchMaxResults: number = 5;
searchActive = false; searchActive = false;
@@ -99,7 +112,7 @@ export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
private onSearchTermChange(value: string): void { private onSearchTermChange(value: string): void {
this.setAutoCompleteDisplayed(true); this.setAutoCompleteDisplayed(true);
this.autocompleteSearchTerm = value; this.liveSearchTerm = value;
this.searchControl.setValue(value, true); this.searchControl.setValue(value, true);
this.searchValid = this.searchControl.valid; this.searchValid = this.searchControl.valid;
this.searchChange.emit({ this.searchChange.emit({
@@ -195,7 +208,7 @@ export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
onArrowDown(): void { onArrowDown(): void {
if (this.isAutoCompleteDisplayed()) { if (this.isAutoCompleteDisplayed()) {
this.autocompleteComponent.focusResult(); this.liveSearchComponent.focusResult();
} else { } else {
this.setAutoCompleteDisplayed(true); this.setAutoCompleteDisplayed(true);
} }

View File

@@ -154,17 +154,40 @@ describe('AlfrescoSearchComponent', () => {
expect(translationService.addTranslationFolder).toHaveBeenCalledWith('node_modules/ng2-alfresco-search/dist/src'); expect(translationService.addTranslationFolder).toHaveBeenCalledWith('node_modules/ng2-alfresco-search/dist/src');
}); });
describe('Rendering search results', () => { describe('Search results', () => {
it('should call search service with the correct parameters', (done) => {
let searchTerm = 'searchTerm63688', options = {
include: ['path'],
rootNodeId: '-my-',
nodeType: 'my:type',
maxItems: 20,
orderBy: null
};
component.searchTerm = searchTerm;
component.rootNodeId = '-my-';
component.resultType = 'my:type';
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result));
fixture.detectChanges();
component.resultsLoad.subscribe(() => {
fixture.detectChanges();
expect(searchService.getQueryNodesPromise).toHaveBeenCalledWith(searchTerm, options);
done();
});
});
it('should display search results when a search term is provided', (done) => { it('should display search results when a search term is provided', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(searchService.getSearchNodesPromise).toHaveBeenCalled(); expect(searchService.getQueryNodesPromise).toHaveBeenCalled();
expect(element.querySelector('#result_user_0')).not.toBeNull(); expect(element.querySelector('#result_user_0')).not.toBeNull();
expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe');
expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc');
@@ -178,7 +201,7 @@ describe('AlfrescoSearchComponent', () => {
it('should display no result if no result are returned', (done) => { it('should display no result if no result are returned', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(noResult)); .and.returnValue(Promise.resolve(noResult));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -194,7 +217,7 @@ describe('AlfrescoSearchComponent', () => {
it('should display an error if an error is encountered running the search', (done) => { it('should display an error if an error is encountered running the search', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.reject(errorJson)); .and.returnValue(Promise.reject(errorJson));
component.resultsLoad.subscribe(() => {}, () => { component.resultsLoad.subscribe(() => {}, () => {
@@ -214,12 +237,12 @@ describe('AlfrescoSearchComponent', () => {
it('should update search results when the search term input is changed', (done) => { it('should update search results when the search term input is changed', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(searchService.getSearchNodesPromise).toHaveBeenCalledWith('searchTerm2'); expect(searchService.getQueryNodesPromise.calls.mostRecent().args[0]).toBe('searchTerm2');
expect(element.querySelector('#result_user_0')).not.toBeNull(); expect(element.querySelector('#result_user_0')).not.toBeNull();
expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe'); expect(element.querySelector('#result_user_0').innerHTML).toBe('John Doe');
expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc'); expect(element.querySelector('#result_name_0').innerHTML).toBe('MyDoc');
@@ -235,7 +258,7 @@ describe('AlfrescoSearchComponent', () => {
it('should emit preview when file item clicked', (done) => { it('should emit preview when file item clicked', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(result)); .and.returnValue(Promise.resolve(result));
component.resultsLoad.subscribe(() => { component.resultsLoad.subscribe(() => {
@@ -254,7 +277,7 @@ describe('AlfrescoSearchComponent', () => {
it('should not emit preview when non-file item is clicked', (done) => { it('should not emit preview when non-file item is clicked', (done) => {
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService); let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
spyOn(searchService, 'getSearchNodesPromise') spyOn(searchService, 'getQueryNodesPromise')
.and.returnValue(Promise.resolve(folderResult)); .and.returnValue(Promise.resolve(folderResult));
spyOn(component.preview, 'emit'); spyOn(component.preview, 'emit');

View File

@@ -17,7 +17,7 @@
import { Component, EventEmitter, Input, Output, Optional, OnChanges, SimpleChanges, OnInit } from '@angular/core'; import { Component, EventEmitter, Input, Output, Optional, OnChanges, SimpleChanges, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { AlfrescoSearchService } from './../services/alfresco-search.service'; import { AlfrescoSearchService, SearchOptions } from './../services/alfresco-search.service';
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service'; import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService } from 'ng2-alfresco-core';
@@ -34,6 +34,18 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
@Input() @Input()
searchTerm: string = ''; searchTerm: string = '';
@Input()
maxResults: number = 20;
@Input()
resultSort: string = null;
@Input()
rootNodeId: string = '-root-';
@Input()
resultType: string = null;
@Output() @Output()
preview: EventEmitter<any> = new EventEmitter(); preview: EventEmitter<any> = new EventEmitter();
@@ -102,10 +114,17 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
* Loads and displays search results * Loads and displays search results
* @param searchTerm Search query entered by user * @param searchTerm Search query entered by user
*/ */
public displaySearchResults(searchTerm): void { private displaySearchResults(searchTerm): void {
if (searchTerm !== null && this.alfrescoSearchService !== null) { if (searchTerm && this.alfrescoSearchService) {
let searchOpts: SearchOptions = {
include: ['path'],
rootNodeId: this.rootNodeId,
nodeType: this.resultType,
maxItems: this.maxResults,
orderBy: this.resultSort
};
this.alfrescoSearchService this.alfrescoSearchService
.getLiveSearchResults(searchTerm) .getNodeQueryResults(searchTerm, searchOpts)
.subscribe( .subscribe(
results => { results => {
this.results = results.list.entries; this.results = results.list.entries;

View File

@@ -40,23 +40,34 @@ describe('AlfrescoSearchService', () => {
spyOn(authenticationService, 'getAlfrescoApi').and.returnValue(fakeApi); spyOn(authenticationService, 'getAlfrescoApi').and.returnValue(fakeApi);
}); });
it('should call search API with the correct parameters', (done) => { it('should call search API with no additional options', (done) => {
let searchTerm = 'searchTerm63688';
spyOn(fakeApi.core.queriesApi, 'findNodes').and.returnValue(Promise.resolve(fakeSearch));
service.getNodeQueryResults(searchTerm).subscribe(
() => {
expect(fakeApi.core.queriesApi.findNodes).toHaveBeenCalledWith(searchTerm, undefined);
done();
}
);
});
it('should call search API with additional options', (done) => {
let searchTerm = 'searchTerm63688', options = { let searchTerm = 'searchTerm63688', options = {
include: [ 'path' ], include: [ 'path' ],
rootNodeId: '-root-', rootNodeId: '-root-',
nodeType: 'cm:content' nodeType: 'cm:content'
}; };
spyOn(fakeApi.core.searchApi, 'liveSearchNodes').and.returnValue(Promise.resolve(fakeSearch)); spyOn(fakeApi.core.queriesApi, 'findNodes').and.returnValue(Promise.resolve(fakeSearch));
service.getLiveSearchResults(searchTerm).subscribe( service.getNodeQueryResults(searchTerm, options).subscribe(
() => { () => {
expect(fakeApi.core.searchApi.liveSearchNodes).toHaveBeenCalledWith(searchTerm, options); expect(fakeApi.core.queriesApi.findNodes).toHaveBeenCalledWith(searchTerm, options);
done(); done();
} }
); );
}); });
it('should return search results returned from the API', (done) => { it('should return search results returned from the API', (done) => {
service.getLiveSearchResults('').subscribe( service.getNodeQueryResults('').subscribe(
(res: any) => { (res: any) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
expect(res).toEqual(fakeSearch); expect(res).toEqual(fakeSearch);
@@ -66,8 +77,8 @@ describe('AlfrescoSearchService', () => {
}); });
it('should notify errors returned from the API', (done) => { it('should notify errors returned from the API', (done) => {
spyOn(fakeApi.core.searchApi, 'liveSearchNodes').and.returnValue(Promise.reject(fakeError)); spyOn(fakeApi.core.queriesApi, 'findNodes').and.returnValue(Promise.reject(fakeError));
service.getLiveSearchResults('').subscribe( service.getNodeQueryResults('').subscribe(
() => {}, () => {},
(res: any) => { (res: any) => {
expect(res).toBeDefined(); expect(res).toBeDefined();
@@ -78,8 +89,8 @@ describe('AlfrescoSearchService', () => {
}); });
it('should notify a general error if the API does not return a specific error', (done) => { it('should notify a general error if the API does not return a specific error', (done) => {
spyOn(fakeApi.core.searchApi, 'liveSearchNodes').and.returnValue(Promise.reject(null)); spyOn(fakeApi.core.queriesApi, 'findNodes').and.returnValue(Promise.reject(null));
service.getLiveSearchResults('').subscribe( service.getNodeQueryResults('').subscribe(
() => {}, () => {},
(res: any) => { (res: any) => {
expect(res).toBeDefined(); expect(res).toBeDefined();

View File

@@ -32,25 +32,30 @@ export class AlfrescoSearchService {
* Execute a search against the repository * Execute a search against the repository
* *
* @param term Search term * @param term Search term
* @param options Additional options passed to the search
* @returns {Observable<NodePaging>} Search results * @returns {Observable<NodePaging>} Search results
*/ */
public getLiveSearchResults(term: string): Observable<any> { public getNodeQueryResults(term: string, options?: SearchOptions): Observable<any> {
return Observable.fromPromise(this.getSearchNodesPromise(term)) return Observable.fromPromise(this.getQueryNodesPromise(term, options))
.map(res => <any> res) .map(res => <any> res)
.catch(this.handleError); .catch(this.handleError);
} }
private getSearchNodesPromise(term: string) { private getQueryNodesPromise(term: string, opts: SearchOptions) {
let nodeId = '-root-'; return this.authService.getAlfrescoApi().core.queriesApi.findNodes(term, opts);
let opts = {
include: ['path'],
rootNodeId: nodeId,
nodeType: 'cm:content'
};
return this.authService.getAlfrescoApi().core.searchApi.liveSearchNodes(term, opts);
} }
private handleError(error: any): Observable<any> { private handleError(error: any): Observable<any> {
return Observable.throw(error || 'Server error'); return Observable.throw(error || 'Server error');
} }
} }
export interface SearchOptions {
skipCount?: number;
maxItems?: number;
rootNodeId?: string;
nodeType?: string;
include?: string[];
orderBy?: string;
fields?: string[];
}