All files / src/app/linqpad-review-pages/common/search search.component.ts

100% Statements 57/57
100% Branches 12/12
100% Functions 15/15
100% Lines 51/51
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 1071x 1x 1x 1x       1x 1x   1x                                       1x   1x 1x     11x 11x         11x 11x 11x     1x 22x 22x 22x     1x 10x 3x     7x 7x 7x   7x 7x     1x 22x 22x 22x 22x     7x 7x   23x 12x   7x 6x   1x         1x 23x 2x   21x 21x     7x 7x 7x   7x 7x 7x       1x  
import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { Location } from '@angular/common';
import { select } from '@angular-redux/store';
import { Observable } from 'rxjs/Observable';
 
import { IAppState } from '../../../store/state/AppState';
import { IFileInfo } from '../../../model/fileInfo.model';
import { SearchResultsModalComponent } from './search-results.modal';
import { SearchActions } from './search.actions';
import { } from '../../../store/selector-helpers/selector-helpers';
import { Computed } from '../../../store/computed/computed-properties';
 
@Component({
  selector: 'mwb-search',
  template: `
    <form id="searchForm" #searchForm="ngForm" (ngSubmit)="search(searchTerm)" novalidate class="form-horizontal" role="form">
      <div class="input-group">
          <input [(ngModel)]="searchTerm" name="searchTerm" id="searchTerm" required type="text" class="form-control input-sm"
            [disabled]="searchDisabled" [placeholder]="searchDisabled ? 'Search not available' : 'Search for text'" >
        <span class="input-group-btn">
          <button class="btn btn-sm btn-outline-info" [disabled]="searchForm.controls.searchTerm?.invalid || searchDisabled">
            Search
          </button>
        </span>
      </div>
    </form>
    <search-results-modal></search-results-modal>
  `,
  styles: ['div.input-group { width: 250px; }']
})
export class SearchComponent implements OnInit {
 
  @ViewChild(SearchResultsModalComponent) searchResultsModal: SearchResultsModalComponent;
  @select(['search']) search$: Observable<any>;
 
  public searchTerm;
  public searchDisabled = false;
  private readonly searchablePages = ['validations', 'referentials', 'clinics'];
  private page: string;
  private isSearchable: boolean;
 
  constructor(
    public location: Location,
    private searchActions: SearchActions,
    private computed: Computed
  ) {}
 
  ngOnInit() {
    const pageType = this.getPage();
    this.page = pageType.page;
    this.isSearchable = pageType.isSearchable;
  }
 
  search(searchTerm: string) {
    if (!searchTerm || !this.isSearchable) {
      return;
    }
 
    this.searchTerm = searchTerm;
    this.searchActions.resetResults();
    this.searchActions.setSearchTerm(this.searchTerm);
 
    this.getResults(this.searchTerm);
    this.openModal();
  }
 
  private getPage(): { page: string, isSearchable: boolean} {
    const page = this.location.path().replace('/', '');
    const isSearchable = this.searchablePages.indexOf(page) > -1;
    this.searchActions.setPage(page, isSearchable);
    return {page, isSearchable};
  }
 
  private getResults(searchTerm) {
    this.computed.visibleFiles$(this.page)
      .take(1)
      .map(files => files.filter(file => this.seachFileInfo(file, searchTerm)) )
      .map(files => files.map(file => file.name))
      .subscribe(results => {
        if (results.length > 0) {
          this.searchActions.setResultsSuccess(results);
        } else {
          this.searchActions.setResultsFailed();
        }
      });
  }
 
  private seachFileInfo(file, searchTerm): boolean {
    if (!file || !file.content) {
      return false;
    }
    const index = file.content.toLocaleLowerCase().indexOf(searchTerm.toLocaleLowerCase());
    return (index > -1);
  }
 
  private openModal() {
    this.search$
      .waitForWithCondition$((search) => !!search.results && search.results.length > 0)
      .subscribe(search => {
        this.searchResultsModal.searchTerm = search.searchTerm;
        this.searchResultsModal.results = search.results;
        this.searchResultsModal.show();
      });
  }
 
}