<commit_before>import {
  Component,
  Input,
  OnInit
} from '@angular/core';

import { Environment } from '../models/environment';

import { cloneDeep } from 'lodash';
import { Observable } from 'rxjs';

import {
  Filter,
  FilterEvent,
  SortEvent,
  SortField
} from 'patternfly-ng';

@Component({
  selector: 'deployments-apps',
  templateUrl: 'deployments-apps.component.html'
})
export class DeploymentsAppsComponent implements OnInit {

  @Input() public applications: Observable<string[]>;
  @Input() public environments: Observable<Environment[]>;
  @Input() public spaceId: Observable<string>;

  public filteredApplicationsList: string[];
  public resultsCount: number = 0;

  private applicationsList: string[];
  private currentFilters: Filter[];
  private currentSortField: SortField;
  private isAscendingSort: boolean = true;

  public constructor() { }

  ngOnInit(): void {
    this.applications.subscribe(applications => {
      this.applicationsList = applications;
      this.applyFilters();
    });
  }

  filterChange($event: FilterEvent): void {
    this.currentFilters = $event.appliedFilters;
    this.applyFilters();
  }

  sortChange($event: SortEvent): void {
    this.currentSortField = $event.field;
    this.isAscendingSort = $event.isAscending;

    this.filteredApplicationsList.sort((a: string, b: string) => {
      let v: number = a.localeCompare(b);
      if (!this.isAscendingSort) {
        v = v * -1;
      }

      return v;
    });
  }

  applyFilters(): void {
    this.filteredApplicationsList = [];
    if (this.currentFilters && this.currentFilters.length > 0) {
      this.applicationsList.forEach((application: string) => {
        if (this.matchesFilters(application, this.currentFilters)) {
          this.filteredApplicationsList.push(application);
        }
      });
    } else {
      this.filteredApplicationsList = cloneDeep(this.applicationsList);
    }

    this.resultsCount = this.filteredApplicationsList.length;
  }

  matchesFilters(application: string, filters: Filter[]): boolean {
    let match: boolean = true;
    filters.forEach((filter: Filter) => {
      if (!this.matchesFilter(application, filter)) {
        match = false;
      }
    });

    return match;
  }

  matchesFilter(application: string, filter: Filter): boolean {
    let match: boolean = false;
    if (filter.field.id === 'applicationId') {
      match = application.match(filter.value) !== null;
    }

    return match;
  }
}
<commit_msg>fix(deployments): unsubscribe deployments-apps subscriptions on destroy<commit_after>import {
  Component,
  Input,
  OnDestroy,
  OnInit
} from '@angular/core';

import { Environment } from '../models/environment';

import { cloneDeep } from 'lodash';
import { Observable, Subscription } from 'rxjs';

import {
  Filter,
  FilterEvent,
  SortEvent,
  SortField
} from 'patternfly-ng';

@Component({
  selector: 'deployments-apps',
  templateUrl: 'deployments-apps.component.html'
})
export class DeploymentsAppsComponent implements OnInit, OnDestroy {

  @Input() public applications: Observable<string[]>;
  @Input() public environments: Observable<Environment[]>;
  @Input() public spaceId: Observable<string>;

  public filteredApplicationsList: string[];
  public resultsCount: number = 0;

  private applicationsList: string[];
  private currentFilters: Filter[];
  private currentSortField: SortField;
  private isAscendingSort: boolean = true;
  private subscriptions: Subscription[] = [];

  public constructor() { }

  ngOnInit(): void {
    this.subscriptions.push(this.applications.subscribe(applications => {
      this.applicationsList = applications;
      this.applyFilters();
    }));
  }

  ngOnDestroy(): void {
    this.subscriptions.forEach((sub: Subscription) => sub.unsubscribe());
  }

  filterChange($event: FilterEvent): void {
    this.currentFilters = $event.appliedFilters;
    this.applyFilters();
  }

  sortChange($event: SortEvent): void {
    this.currentSortField = $event.field;
    this.isAscendingSort = $event.isAscending;

    this.filteredApplicationsList.sort((a: string, b: string) => {
      let v: number = a.localeCompare(b);
      if (!this.isAscendingSort) {
        v = v * -1;
      }

      return v;
    });
  }

  applyFilters(): void {
    this.filteredApplicationsList = [];
    if (this.currentFilters && this.currentFilters.length > 0) {
      this.applicationsList.forEach((application: string) => {
        if (this.matchesFilters(application, this.currentFilters)) {
          this.filteredApplicationsList.push(application);
        }
      });
    } else {
      this.filteredApplicationsList = cloneDeep(this.applicationsList);
    }

    this.resultsCount = this.filteredApplicationsList.length;
  }

  matchesFilters(application: string, filters: Filter[]): boolean {
    let match: boolean = true;
    filters.forEach((filter: Filter) => {
      if (!this.matchesFilter(application, filter)) {
        match = false;
      }
    });

    return match;
  }

  matchesFilter(application: string, filter: Filter): boolean {
    let match: boolean = false;
    if (filter.field.id === 'applicationId') {
      match = application.match(filter.value) !== null;
    }

    return match;
  }
}

{'fraction_non_alphanumeric': 0.12872421695951108, 'fraction_numerical': 0.001145912910618793, 'mean_word_length': 3.5578764142732813, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 20, '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': '2370503', 'n_tokens_mistral': 1549, 'n_tokens_neox': 1503, 'n_words': 328}