mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
Merge pull request #1006 from Alfresco/dev-wabson-555
Update search component to work with 0.4.0 JS API
This commit is contained in:
commit
bc823b829b
@ -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"
|
||||||
|
@ -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">
|
||||||
|
@ -173,16 +173,20 @@ bootstrap(SearchDemo, [
|
|||||||
|
|
||||||
**searchChange**: Emitted when the search term is changed. The search term is provided in the 'value' property of the returned object. If the term is at less than three characters in length then the term is truncated to an empty string.<br />
|
**searchChange**: Emitted when the search term is changed. The search term is provided in the 'value' property of the returned object. If the term is at less than three characters in length then the term is truncated to an empty string.<br />
|
||||||
**searchSubmit**: Emitted when the search form is submitted. The search term is provided in the 'value' property of the returned object.<br />
|
**searchSubmit**: Emitted when the search form is submitted. The search term is provided in the 'value' property of the returned object.<br />
|
||||||
**fileSelect**: Emitted when a file item from the list of find-as-you-type results is selected
|
**fileSelect**: Emitted when a file item from the list of find-as-you-type results is selected<br />
|
||||||
**expand**: Emitted when the expanded state of the control changes based on focus events and the content of the input control
|
**expand**: Emitted when the expanded state of the control changes based on focus events and the content of the input control
|
||||||
|
|
||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
**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
|
||||||
|
|
||||||
@ -331,12 +335,17 @@ bootstrap(SearchDemo, [
|
|||||||
|
|
||||||
#### Events
|
#### Events
|
||||||
|
|
||||||
None
|
**preview**: Emitted when a file result is clicked/selected<br />
|
||||||
|
**resultsLoad**: Emitted when search results have fully loaded
|
||||||
|
|
||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
**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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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)"
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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');
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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[];
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user