import { Component, OnDestroy, OnInit, Output, EventEmitter } from '@angular/core'; import { Subject } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core'; import { takeUntil } from 'rxjs/operators'; import { SearchInput } from 'app/shared/model/search/search-input.model'; import { SearchService } from '../service/search-service'; import { faQuestion } from '@fortawesome/free-solid-svg-icons'; import { Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators'; import { IExerciseType, ILanguages } from 'app/shared/model/exercise.model'; interface LooseObject { [key: string]: any; } @Component({ selector: 'jhi-search-input', templateUrl: './search-input.component.html', styleUrls: ['./search-input.component.scss'], }) export class SearchInputComponent implements OnInit, OnDestroy { private static DEBOUNCE_TIME = 200; @Output() searchInputEvent = new EventEmitter<SearchInput>(); public pageSize = 4; typeValues = Object.keys(IExerciseType); languageValues = Object.keys(ILanguages); questionIcon = faQuestion; public paramGroup: QueryParamGroup; private componentDestroyed$ = new Subject<void>(); public searchInput: SearchInput; public showSearchUsage = false; constructor( protected activatedRoute: ActivatedRoute, private qpb: QueryParamBuilder, private searchService: SearchService ) { this.searchInput = new SearchInput(); const groupDef: LooseObject = { searchText: qpb.stringParam('q', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), page: qpb.numberParam('page', { emptyOn: 1, }), programmingLanguage: qpb.stringParam('pl', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), keyword: qpb.stringParam('kw', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), format: qpb.stringParam('f', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), author: qpb.stringParam('a', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), license: qpb.stringParam('l', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), parentId: qpb.stringParam('p', { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }), }; // add type checkbox support this.typeValues.forEach(function (type: string): void { const typeName = type.toString(); groupDef[typeName] = qpb.stringParam(typeName, { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }); }); // add type language checkbox support this.languageValues.forEach(language => { groupDef[language] = qpb.stringParam(language, { debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '', }); }); this.paramGroup = qpb.group(groupDef); this.paramGroup.valueChanges.pipe(takeUntil(this.componentDestroyed$)).subscribe(value => { this.searchInput.setValues(value); this.searchInputEvent.emit(this.searchInput); }); } getSelectedTypes(): string[] { const result: string[] = []; this.typeValues.forEach(type => { if (this.paramGroup.queryParams[type].value) result.push(type); }); return result; } getSelectedLanguages(): string[] { const result: string[] = []; this.languageValues.forEach(language => { if (this.paramGroup.queryParams[language].value) result.push(language); }); return result; } ngOnInit(): void {} ngOnDestroy(): void { this.componentDestroyed$.next(); this.componentDestroyed$.complete(); } public get pageParam(): QueryParam<number> { return this.paramGroup.get('page') as QueryParam<number>; } public onPageChange(page: number): void { this.pageParam.setValue(page); } /* public itemSelected(): void { this.searchInputEvent.emit(this.searchInput); } */ autoCompleteContributorCreator = (text$: Observable<string>) => text$.pipe( debounceTime(200), distinctUntilChanged(), switchMap(searchText => { if (searchText.length <= 2) return []; return this.searchService.getContributorCreatorAutoComplete(searchText, 10).pipe(map(ace => ace.map(ac => ac.target))); }) ); autoCompleteKeyWords = (text$: Observable<string>) => text$.pipe( debounceTime(200), distinctUntilChanged(), switchMap(searchText => this.searchService.getKeywordsAutoComplete(searchText, 10).pipe(map(ace => ace.map(ac => ac.target)))) ); autoCompleteFormats = (text$: Observable<string>) => text$.pipe( debounceTime(200), distinctUntilChanged(), switchMap(searchText => this.searchService.getFormatsAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target)))) ); autoCompleteProgrammingLanguage = (text$: Observable<string>) => text$.pipe( debounceTime(200), distinctUntilChanged(), switchMap(searchText => this.searchService.getProgrammingLanguageAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target)))) ); }