import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subject, Subscription } from 'rxjs'; import { LoginModalService } from 'app/core/login/login-modal.service'; import { AccountService } from 'app/core/auth/account.service'; import { Account } from 'app/core/user/account.model'; import { HttpResponse } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core'; import { takeUntil } from 'rxjs/operators'; import { IFrequency } from 'app/shared/model/frequency.model'; import { IGitFilesPageDetails, GitFilesPageDetails } from 'app/shared/model/git-files-page-details.model'; import { IGitFilesAggregation } from 'app/shared/model/git-files-aggregation'; import { IGitFiles } from 'app/shared/model/git-files.model'; import { SearchInput } from 'app/shared/model/search-input.model'; import { SearchResultService } from 'app/search/search/search-result.service'; import { MessageService } from 'app/search/metadata-message.service'; @Component({ selector: 'jhi-search', templateUrl: './search.component.html', styleUrls: ['search.scss'], }) export class SearchComponent implements OnInit, OnDestroy { private static DEBOUNCE_TIME = 200; public pageSize = 4; account: Account | null = null; authSubscription?: Subscription; private gitFilesAllPages?: IGitFilesPageDetails; gitFilesPageDetails?: IGitFilesPageDetails; gitFilesAggregation?: IGitFilesAggregation; private selectedFiltersSubscription: Subscription = new Subscription(); private selectedRepository: string | null = null; private selectedUniversity: string | null = null; private selectedFileFormat: string | null = null; public paramGroup: QueryParamGroup; private componentDestroyed$ = new Subject<void>(); public searchInput: SearchInput; constructor( protected searchResultService: SearchResultService, private accountService: AccountService, private loginModalService: LoginModalService, protected activatedRoute: ActivatedRoute, private router: Router, private qpb: QueryParamBuilder, private filterSelectionService: MessageService ) { this.searchInput = new SearchInput(); this.paramGroup = qpb.group({ searchText: qpb.stringParam('q', { debounceTime: SearchComponent.DEBOUNCE_TIME, emptyOn: '', }), page: qpb.numberParam('page', { emptyOn: 1, }), programmingLanguage: qpb.stringParam('pl', { debounceTime: SearchComponent.DEBOUNCE_TIME, emptyOn: '', }), keywords: qpb.stringParam('kw', { debounceTime: SearchComponent.DEBOUNCE_TIME, emptyOn: '', }), author: qpb.stringParam('a', { debounceTime: SearchComponent.DEBOUNCE_TIME, emptyOn: '', }), license: qpb.stringParam('l', { debounceTime: SearchComponent.DEBOUNCE_TIME, emptyOn: '', }), }); this.paramGroup.valueChanges.pipe(takeUntil(this.componentDestroyed$)).subscribe(value => { this.searchInput.setValues(value); this.search(); }); } filter(): void { if (!this.gitFilesPageDetails?.hitCount || this.gitFilesPageDetails.hitCount <= 0) { return; } this.loadPageDetails(); } search(): void { if (this.searchInput.fulltextQuery === '') { this.gitFilesAggregation = undefined; this.gitFilesPageDetails = undefined; return; } this.loadAggregation(); this.loadPageDetails(); } ngOnInit(): void { this.loadAggregation(); this.loadPageDetails(); this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account)); this.selectedFiltersSubscription.add( this.filterSelectionService.filterSelection$.subscribe(filterSelection => this.updateSearchInfoFilter(filterSelection)) ); } loadAggregation(): void { if (this.searchInput.fulltextQuery) { this.searchResultService .searchAggregation({ query: this.searchInput.fulltextQuery, }) .subscribe((res: HttpResponse<IGitFilesAggregation>) => { this.gitFilesAggregation = res.body || undefined; }); } } loadPageDetails(): void { if (this.searchInput.fulltextQuery) { this.searchResultService.searchPageDetails(this.searchInput, this.pageSize).subscribe((res: HttpResponse<IGitFilesPageDetails>) => { if (res.body === null) { this.gitFilesAllPages = undefined; } else { this.gitFilesAllPages = new GitFilesPageDetails(res.body.gitFiles, res.body.gitFiles.length); this.updatePageDetails(); } }); } } private updatePageDetails(): void { if (this.gitFilesAllPages !== undefined) { const matchingResults = this.gitFilesAllPages.gitFiles.filter(element => this.matchesSelection(element)); if (matchingResults.length > 0) { this.gitFilesPageDetails = new GitFilesPageDetails(matchingResults, matchingResults.length); } else { this.gitFilesPageDetails = undefined; } } } public updateSearchInfoFilter(selectionUpdate: IFrequency<string>): void { if (this.selectedRepository === selectionUpdate.key) { this.selectedRepository = null; } else { this.selectedRepository = selectionUpdate.key; } this.updatePageDetails(); } matchesSelection(file: IGitFiles): boolean { if (this.selectedRepository) { return file.repository === this.selectedRepository; } return true; } isAuthenticated(): boolean { return this.accountService.isAuthenticated(); } login(): void { this.loginModalService.open(); } ngOnDestroy(): void { if (this.authSubscription) { this.authSubscription.unsubscribe(); } if (this.selectedFiltersSubscription) { this.selectedFiltersSubscription.unsubscribe(); } this.componentDestroyed$.next(); this.componentDestroyed$.complete(); } onClickMe(gitFiles: IGitFiles): void { window.location.href = gitFiles.gitUrl; } public get gitFiles(): IGitFiles[] { return this.gitFilesPageDetails?.gitFiles || []; } public get repos(): IFrequency<string>[] { return this.gitFilesAggregation?.repositories || []; } public get university(): IFrequency<string>[] { return this.gitFilesAggregation?.university || []; } public get fileFormat(): IFrequency<string>[] { return this.gitFilesAggregation?.fileFormat || []; } public get pageParam(): QueryParam<number> { return this.paramGroup.get('page') as QueryParam<number>; } public onPageChange(page: number): void { this.pageParam.setValue(page); } public get hitCount(): number { const hits = this.gitFilesPageDetails?.hitCount; return hits ? hits : 0; } }