This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
search.component.ts 6.72 KiB
Newer Older
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';
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed

@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;
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed
  gitFilesPageDetails?: IGitFilesPageDetails;
  gitFilesAggregation?: IGitFilesAggregation;

  private selectedFiltersSubscription: Subscription = new Subscription();
  private selectedRepository: string | null = null;
  private selectedUniversity: string | null = null;
  private selectedFileFormat: string | null = null;
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed

  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
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed
  ) {
    this.searchInput = new SearchInput();
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed

    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))
    );
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed
  }

  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;
  }

Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed
  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();
    }
Lukas Kaltenbrunner's avatar
Lukas Kaltenbrunner committed
    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;
  }
}