[ACA-2261] improve UX on search input (#1004)

* Remove search on change

- search call would be triggered only on submit or on option change

* clicking search icon triggers search

* caches user changes for a possible future search

* caches non-empty user changes for a possible future search

* close search options menu on submit

* update queryBuilder and navigate to new search url

* add setting to enable/disable searching after typing on search input

* fix double search call

* Apply suggestions from code review

- custom name to distinguish between ADF and ACA settings

Co-Authored-By: suzanadirla <dirla.silvia.suzana@gmail.com>
This commit is contained in:
Suzana Dirla 2019-03-11 16:13:44 +02:00 committed by Denys Vuika
parent a52c3e463b
commit 8045e17c28
4 changed files with 65 additions and 22 deletions

View File

@ -191,6 +191,7 @@
}
]
},
"aca:triggeredOnChange": false,
"filterQueries": [
{ "query": "+TYPE:'cm:folder' OR +TYPE:'cm:content'" },
{

View File

@ -3,6 +3,7 @@
mat-icon-button
id="app-search-button"
class="app-search-button"
(click)="searchSubmit(searchTerm)"
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
>
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"

View File

@ -2,10 +2,12 @@
class="app-search-container searchMenuTrigger"
[matMenuTriggerFor]="searchOptionsMenu"
(menuOpened)="onMenuOpened()"
(menuClosed)="syncInputValues()"
>
<button
mat-icon-button
class="app-search-button"
(click)="searchByOption()"
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
>
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"

View File

@ -48,6 +48,8 @@ import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../../services/content-management.service';
import { Subject } from 'rxjs';
import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service';
import { MatMenuTrigger } from '@angular/material';
import { AppConfigService } from '@alfresco/adf-core';
export enum SearchOptionIds {
Files = 'content',
@ -67,6 +69,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
hasNewChange = false;
navigationTimer: any;
has400LibraryError = false;
searchOnChange;
searchedWord = null;
searchOptions: Array<any> = [
@ -93,13 +96,22 @@ export class SearchInputComponent implements OnInit, OnDestroy {
@ViewChild('searchInputControl')
searchInputControl: SearchInputControlComponent;
@ViewChild(MatMenuTrigger)
trigger: MatMenuTrigger;
constructor(
private queryBuilder: SearchQueryBuilderService,
private queryLibrariesBuilder: SearchLibrariesQueryBuilderService,
private config: AppConfigService,
private content: ContentManagementService,
private router: Router,
private store: Store<AppStore>
) {}
) {
this.searchOnChange = this.config.get<boolean>(
'search.aca:triggeredOnChange',
true
);
}
ngOnInit() {
this.showInputValue();
@ -122,20 +134,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
showInputValue() {
this.has400LibraryError = false;
this.searchedWord = '';
if (this.onSearchResults || this.onLibrariesSearchResults) {
const urlTree: UrlTree = this.router.parseUrl(this.router.url);
const urlSegmentGroup: UrlSegmentGroup =
urlTree.root.children[PRIMARY_OUTLET];
if (urlSegmentGroup) {
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
this.searchedWord = urlSegments[0].parameters['q']
? decodeURIComponent(urlSegments[0].parameters['q'])
: '';
}
}
this.searchedWord = this.getUrlSearchTerm();
if (this.searchInputControl) {
this.searchInputControl.searchTerm = this.searchedWord;
@ -157,17 +156,23 @@ export class SearchInputComponent implements OnInit, OnDestroy {
*
* @param event Parameters relating to the search
*/
onSearchSubmit(event: KeyboardEvent) {
this.has400LibraryError = false;
const searchTerm = (event.target as HTMLInputElement).value;
onSearchSubmit(event: any) {
const searchTerm = event.target
? (event.target as HTMLInputElement).value
: event;
if (searchTerm) {
this.searchedWord = searchTerm;
this.searchByOption();
}
this.trigger.closeMenu();
}
onSearchChange(searchTerm: string) {
if (!this.searchOnChange) {
return;
}
this.has400LibraryError = false;
this.searchedWord = searchTerm;
@ -193,14 +198,15 @@ export class SearchInputComponent implements OnInit, OnDestroy {
}
searchByOption() {
this.syncInputValues();
this.has400LibraryError = false;
if (this.isLibrariesChecked()) {
if (this.searchedWord && !this.onLibrariesSearchResults) {
if (this.onLibrariesSearchResults && this.isSameSearchTerm()) {
this.queryLibrariesBuilder.update();
} else if (this.searchedWord) {
this.store.dispatch(
new SearchByTermAction(this.searchedWord, this.searchOptions)
);
} else {
this.queryLibrariesBuilder.update();
}
} else {
if (this.isFoldersChecked() && !this.isFilesChecked()) {
@ -211,7 +217,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
this.removeContentFilters();
}
if (this.onSearchResults) {
if (this.onSearchResults && this.isSameSearchTerm()) {
this.queryBuilder.update();
} else if (this.searchedWord) {
this.store.dispatch(
@ -277,4 +283,37 @@ export class SearchInputComponent implements OnInit, OnDestroy {
`+TYPE:'cm:${SearchOptionIds.Folders}'`
);
}
syncInputValues() {
if (this.searchInputControl.searchTerm !== this.searchedWord) {
if (this.searchInputControl.searchTerm) {
this.searchedWord = this.searchInputControl.searchTerm;
} else {
this.searchInputControl.searchTerm = this.searchedWord;
}
}
}
getUrlSearchTerm(): string {
let searchTerm = '';
if (this.onSearchResults || this.onLibrariesSearchResults) {
const urlTree: UrlTree = this.router.parseUrl(this.router.url);
const urlSegmentGroup: UrlSegmentGroup =
urlTree.root.children[PRIMARY_OUTLET];
if (urlSegmentGroup) {
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
searchTerm = urlSegments[0].parameters['q']
? decodeURIComponent(urlSegments[0].parameters['q'])
: '';
}
}
return searchTerm;
}
isSameSearchTerm(): boolean {
const urlSearchTerm = this.getUrlSearchTerm();
return this.searchedWord === urlSearchTerm;
}
}