<commit_before>import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';

import { fromEvent } from 'rxjs/observable/fromEvent';
import { Observable } from 'rxjs/Rx';

import { ICategory } from '../category/category';
import { IFile } from './file';
import { ITag } from '../tag/tag';
import { FileService } from './file.service';
import { TagService } from '../tag/tag.service';
import { CategoryService } from '../category/category.service';


@Component({
  template: `
  <div class="container">
    <div class="row">
      <div class="col-sm-offset-2 col-sm-12">
        <br>
        <br>
        <input class="form-control" placeholder="search..." #search>
        <br>
      </div>
    </div>
  </div>
  <div class="container-fluid" infiniteScroll (scrolled)="onScroll()">
    <div class="row">
      <div class="col-sm-2" *ngFor="let file of files">
        <file [file]="file"></file>
      </div>
    </div>
  </div>`,
})
export class FileListComponent implements AfterViewInit, OnInit {
  files: IFile[] = [];
  allFiles: IFile[] = [];
  matchingFiles: IFile[] = [];
  categories: ICategory[] = [];
  tags: ITag[] = [];

  private increment: number = 100;
  private nb: number = 100;

  private inputValue: Observable<string>;

  @ViewChild('search') input: ElementRef;

  constructor(private route: ActivatedRoute, private categoryService: CategoryService, private fileService: FileService, public tagService: TagService) {}


  ngAfterViewInit() {
    this.inputValue = fromEvent(this.input.nativeElement, 'input', ($event) => $event.target.value);


    this.inputValue.debounceTime(400).subscribe((value: string) => {
      const re = new RegExp(value, 'i');

      let matchingTags = this.tags.filter((tag: ITag) => re.test(tag.name));

      this.categories
           .filter((category: ICategory) => re.test(category.name))
           .map((category: ICategory) => category.tags.filter((t: ITag) => {
             if (matchingTags.indexOf(t) === -1) {
               matchingTags.push(t);
             }
           }));

      this.matchingFiles = this.allFiles.filter((file: IFile) => {
        return this.fileMatch(re, file, matchingTags.map((tag: ITag) => tag.id));
      });
      this.nb = this.increment;
      this.files = this.matchingFiles.slice(0, this.nb);
    });
  };

  fileMatch(re: RegExp, file: IFile, matchingTagIds: number[]) {
    if (re.test(file.rel_path)) {
      return true;
    }

    for(let tag of file.tags) {
      if (matchingTagIds.indexOf(tag.id) !== -1) {
        return true;
      }
    }
  }

  ngOnInit() {
    this.tagService.getTags(true).subscribe((tags: ITag[]) => {
      this.tags = tags;
    });
    this.categoryService.getCategories(true).subscribe((categories: ICategory[]) => {
      this.categories = categories;
    });

    this.route.paramMap
      .switchMap((params: ParamMap) => this.fileService.getFiles(+params.get('id')))
      .subscribe((files: IFile[]) => {
        this.nb = this.increment;
        this.allFiles = files;
        this.matchingFiles = files;
        this.files = files.slice(0, this.nb);
    });
  }

  onScroll() {
    this.nb += this.increment;
    this.files = this.matchingFiles.slice(0, this.nb);
  }
}
<commit_msg>Empty the search value when changing group<commit_after>import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';

import { fromEvent } from 'rxjs/observable/fromEvent';
import { Observable } from 'rxjs/Rx';

import { ICategory } from '../category/category';
import { IFile } from './file';
import { ITag } from '../tag/tag';
import { FileService } from './file.service';
import { TagService } from '../tag/tag.service';
import { CategoryService } from '../category/category.service';


@Component({
  template: `
  <div class="container">
    <div class="row">
      <div class="col-sm-offset-2 col-sm-12">
        <br>
        <br>
        <input class="form-control" placeholder="search..." #search>
        <br>
      </div>
    </div>
  </div>
  <div class="container-fluid" infiniteScroll (scrolled)="onScroll()">
    <div class="row">
      <div class="col-sm-2" *ngFor="let file of files">
        <file [file]="file"></file>
      </div>
    </div>
  </div>`,
})
export class FileListComponent implements AfterViewInit, OnInit {
  files: IFile[] = [];
  allFiles: IFile[] = [];
  matchingFiles: IFile[] = [];
  categories: ICategory[] = [];
  tags: ITag[] = [];

  private increment: number = 100;
  private nb: number = 100;

  private inputValue: Observable<string>;

  @ViewChild('search') input: ElementRef;

  constructor(private route: ActivatedRoute, private categoryService: CategoryService, private fileService: FileService, public tagService: TagService) {}


  ngAfterViewInit() {
    this.inputValue = fromEvent(this.input.nativeElement, 'input', ($event) => $event.target.value);


    this.inputValue.debounceTime(400).subscribe((value: string) => {
      const re = new RegExp(value, 'i');

      let matchingTags = this.tags.filter((tag: ITag) => re.test(tag.name));

      this.categories
           .filter((category: ICategory) => re.test(category.name))
           .map((category: ICategory) => category.tags.filter((t: ITag) => {
             if (matchingTags.indexOf(t) === -1) {
               matchingTags.push(t);
             }
           }));

      this.matchingFiles = this.allFiles.filter((file: IFile) => {
        return this.fileMatch(re, file, matchingTags.map((tag: ITag) => tag.id));
      });
      this.nb = this.increment;
      this.files = this.matchingFiles.slice(0, this.nb);
    });
  };

  fileMatch(re: RegExp, file: IFile, matchingTagIds: number[]) {
    if (re.test(file.rel_path)) {
      return true;
    }

    for(let tag of file.tags) {
      if (matchingTagIds.indexOf(tag.id) !== -1) {
        return true;
      }
    }
  }

  ngOnInit() {
    this.tagService.getTags(true).subscribe((tags: ITag[]) => {
      this.tags = tags;
    });
    this.categoryService.getCategories(true).subscribe((categories: ICategory[]) => {
      this.categories = categories;
    });

    this.route.paramMap
      .switchMap((params: ParamMap) => this.fileService.getFiles(+params.get('id')))
      .subscribe((files: IFile[]) => {
        // Empty the search
        this.input.nativeElement.value = '';
        this.nb = this.increment;
        this.allFiles = files;
        this.matchingFiles = files;
        this.files = files.slice(0, this.nb);
    });
  }

  onScroll() {
    this.nb += this.increment;
    this.files = this.matchingFiles.slice(0, this.nb);
  }
}

{'fraction_non_alphanumeric': 0.16830357142857144, 'fraction_numerical': 0.005357142857142857, 'mean_word_length': 2.937316930287053, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3095651', 'n_tokens_mistral': 2150, 'n_tokens_neox': 2082, 'n_words': 442}