/*! * @license * Copyright 2016 Alfresco Software, Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { SearchService } from '@alfresco/adf-core'; import { AfterContentInit, Component, ContentChild, ElementRef, EventEmitter, Input, OnChanges, Output, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { NodePaging, QueryBody } from 'alfresco-js-api'; import { Subject } from 'rxjs/Subject'; @Component({ selector: 'adf-search', templateUrl: './search.component.html', styleUrls: ['./search.component.scss'], encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, exportAs: 'searchAutocomplete', host: { 'class': 'adf-search' } }) export class SearchComponent implements AfterContentInit, OnChanges { @ViewChild('panel') panel: ElementRef; @ContentChild(TemplateRef) template: TemplateRef; @Input() displayWith: ((value: any) => string) | null = null; @Input() maxResults: number = 20; @Input() skipResults: number = 0; /** @deprecated in 2.1.0 */ @Input() queryBody: QueryBody; @Input() searchTerm: string = ''; @Input('class') set classList(classList: string) { if (classList && classList.length) { classList.split(' ').forEach(className => this._classList[className.trim()] = true); this._elementRef.nativeElement.className = ''; } } @Output() resultLoaded: EventEmitter = new EventEmitter(); @Output() error: EventEmitter = new EventEmitter(); showPanel: boolean = false; results: NodePaging; get isOpen(): boolean { return this._isOpen && this.showPanel; } set isOpen(value: boolean) { this._isOpen = value; } _isOpen: boolean = false; keyPressedStream: Subject = new Subject(); _classList: { [key: string]: boolean } = {}; constructor(private searchService: SearchService, private _elementRef: ElementRef) { this.keyPressedStream.asObservable() .debounceTime(200) .subscribe((searchedWord: string) => { this.loadSearchResults(searchedWord); }); } ngAfterContentInit() { this.setVisibility(); } ngOnChanges(changes) { if (changes.queryBody && this.hasDifferentQueryBody(changes.queryBody.previousValue, changes.queryBody.currentValue)) { this.loadSearchResults(); } if (changes.searchTerm && changes.searchTerm.currentValue) { this.loadSearchResults(changes.searchTerm.currentValue); } } resetResults() { this.cleanResults(); this.setVisibility(); } reload() { this.loadSearchResults(this.searchTerm); } private hasDifferentQueryBody(previousQueryBody: QueryBody, currentQueryBody: QueryBody) { return JSON.stringify(previousQueryBody) !== JSON.stringify(currentQueryBody); } private cleanResults() { if (this.results) { this.results = {}; } } private loadSearchResults(searchTerm?: string) { this.resetResults(); if (searchTerm) { let search$; if (this.queryBody) { search$ = this.searchService.searchByQueryBody(this.queryBody); } else { search$ = this.searchService .search(searchTerm, this.maxResults.toString(), this.skipResults.toString()); } search$.subscribe( results => { this.results = results; this.resultLoaded.emit(this.results); this.isOpen = true; this.setVisibility(); }, error => { if (error.status !== 400) { this.results = null; this.error.emit(error); } }); } else { this.cleanResults(); } } hidePanel() { if (this.isOpen) { this._classList['adf-search-show'] = false; this._classList['adf-search-hide'] = true; this.isOpen = false; } } setVisibility() { this.showPanel = !!this.results && !!this.results.list; this._classList['adf-search-show'] = this.showPanel; this._classList['adf-search-hide'] = !this.showPanel; } }