mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[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:
parent
a52c3e463b
commit
8045e17c28
@ -191,6 +191,7 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"aca:triggeredOnChange": false,
|
||||||
"filterQueries": [
|
"filterQueries": [
|
||||||
{ "query": "+TYPE:'cm:folder' OR +TYPE:'cm:content'" },
|
{ "query": "+TYPE:'cm:folder' OR +TYPE:'cm:content'" },
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
mat-icon-button
|
mat-icon-button
|
||||||
id="app-search-button"
|
id="app-search-button"
|
||||||
class="app-search-button"
|
class="app-search-button"
|
||||||
|
(click)="searchSubmit(searchTerm)"
|
||||||
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
|
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
|
||||||
>
|
>
|
||||||
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"
|
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
class="app-search-container searchMenuTrigger"
|
class="app-search-container searchMenuTrigger"
|
||||||
[matMenuTriggerFor]="searchOptionsMenu"
|
[matMenuTriggerFor]="searchOptionsMenu"
|
||||||
(menuOpened)="onMenuOpened()"
|
(menuOpened)="onMenuOpened()"
|
||||||
|
(menuClosed)="syncInputValues()"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
class="app-search-button"
|
class="app-search-button"
|
||||||
|
(click)="searchByOption()"
|
||||||
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
|
[title]="'SEARCH.BUTTON.TOOLTIP' | translate"
|
||||||
>
|
>
|
||||||
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"
|
<mat-icon [attr.aria-label]="'SEARCH.BUTTON.ARIA-LABEL' | translate"
|
||||||
|
@ -48,6 +48,8 @@ import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
|||||||
import { ContentManagementService } from '../../../services/content-management.service';
|
import { ContentManagementService } from '../../../services/content-management.service';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service';
|
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 {
|
export enum SearchOptionIds {
|
||||||
Files = 'content',
|
Files = 'content',
|
||||||
@ -67,6 +69,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
hasNewChange = false;
|
hasNewChange = false;
|
||||||
navigationTimer: any;
|
navigationTimer: any;
|
||||||
has400LibraryError = false;
|
has400LibraryError = false;
|
||||||
|
searchOnChange;
|
||||||
|
|
||||||
searchedWord = null;
|
searchedWord = null;
|
||||||
searchOptions: Array<any> = [
|
searchOptions: Array<any> = [
|
||||||
@ -93,13 +96,22 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
@ViewChild('searchInputControl')
|
@ViewChild('searchInputControl')
|
||||||
searchInputControl: SearchInputControlComponent;
|
searchInputControl: SearchInputControlComponent;
|
||||||
|
|
||||||
|
@ViewChild(MatMenuTrigger)
|
||||||
|
trigger: MatMenuTrigger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private queryBuilder: SearchQueryBuilderService,
|
private queryBuilder: SearchQueryBuilderService,
|
||||||
private queryLibrariesBuilder: SearchLibrariesQueryBuilderService,
|
private queryLibrariesBuilder: SearchLibrariesQueryBuilderService,
|
||||||
|
private config: AppConfigService,
|
||||||
private content: ContentManagementService,
|
private content: ContentManagementService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private store: Store<AppStore>
|
private store: Store<AppStore>
|
||||||
) {}
|
) {
|
||||||
|
this.searchOnChange = this.config.get<boolean>(
|
||||||
|
'search.aca:triggeredOnChange',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.showInputValue();
|
this.showInputValue();
|
||||||
@ -122,20 +134,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
showInputValue() {
|
showInputValue() {
|
||||||
this.has400LibraryError = false;
|
this.has400LibraryError = false;
|
||||||
this.searchedWord = '';
|
this.searchedWord = this.getUrlSearchTerm();
|
||||||
|
|
||||||
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'])
|
|
||||||
: '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.searchInputControl) {
|
if (this.searchInputControl) {
|
||||||
this.searchInputControl.searchTerm = this.searchedWord;
|
this.searchInputControl.searchTerm = this.searchedWord;
|
||||||
@ -157,17 +156,23 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
*
|
*
|
||||||
* @param event Parameters relating to the search
|
* @param event Parameters relating to the search
|
||||||
*/
|
*/
|
||||||
onSearchSubmit(event: KeyboardEvent) {
|
onSearchSubmit(event: any) {
|
||||||
this.has400LibraryError = false;
|
const searchTerm = event.target
|
||||||
const searchTerm = (event.target as HTMLInputElement).value;
|
? (event.target as HTMLInputElement).value
|
||||||
|
: event;
|
||||||
if (searchTerm) {
|
if (searchTerm) {
|
||||||
this.searchedWord = searchTerm;
|
this.searchedWord = searchTerm;
|
||||||
|
|
||||||
this.searchByOption();
|
this.searchByOption();
|
||||||
}
|
}
|
||||||
|
this.trigger.closeMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearchChange(searchTerm: string) {
|
onSearchChange(searchTerm: string) {
|
||||||
|
if (!this.searchOnChange) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.has400LibraryError = false;
|
this.has400LibraryError = false;
|
||||||
this.searchedWord = searchTerm;
|
this.searchedWord = searchTerm;
|
||||||
|
|
||||||
@ -193,14 +198,15 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchByOption() {
|
searchByOption() {
|
||||||
|
this.syncInputValues();
|
||||||
this.has400LibraryError = false;
|
this.has400LibraryError = false;
|
||||||
if (this.isLibrariesChecked()) {
|
if (this.isLibrariesChecked()) {
|
||||||
if (this.searchedWord && !this.onLibrariesSearchResults) {
|
if (this.onLibrariesSearchResults && this.isSameSearchTerm()) {
|
||||||
|
this.queryLibrariesBuilder.update();
|
||||||
|
} else if (this.searchedWord) {
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
new SearchByTermAction(this.searchedWord, this.searchOptions)
|
new SearchByTermAction(this.searchedWord, this.searchOptions)
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
this.queryLibrariesBuilder.update();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.isFoldersChecked() && !this.isFilesChecked()) {
|
if (this.isFoldersChecked() && !this.isFilesChecked()) {
|
||||||
@ -211,7 +217,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
this.removeContentFilters();
|
this.removeContentFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.onSearchResults) {
|
if (this.onSearchResults && this.isSameSearchTerm()) {
|
||||||
this.queryBuilder.update();
|
this.queryBuilder.update();
|
||||||
} else if (this.searchedWord) {
|
} else if (this.searchedWord) {
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
@ -277,4 +283,37 @@ export class SearchInputComponent implements OnInit, OnDestroy {
|
|||||||
`+TYPE:'cm:${SearchOptionIds.Folders}'`
|
`+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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user