<commit_before>import 'rxjs/add/operator/combineLatest';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';

import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { LangChangeEvent, TranslateService } from 'ng2-translate';

import { BehaviorSubject } from 'rxjs';
import { EditLogApiOptions } from './EditLogApiOptions.class';
import { IsariDataService } from './../isari-data.service';
import { Observable } from 'rxjs/Observable';
import { ToasterService } from 'angular2-toaster';
import flattenDeep from 'lodash/flattenDeep';
import keyBy from 'lodash/keyBy';
import uniq from 'lodash/uniq';

@Component({
  selector: 'isari-logs',
  templateUrl: './isari-logs.component.html'
  // styleUrls: ['./isari-layout.component.css']
})
export class IsariLogsComponent implements OnInit {
  feature: string;
  options: EditLogApiOptions = { skip: 0, limit: 5 };
  options$: BehaviorSubject<EditLogApiOptions>;
  details$: BehaviorSubject<boolean>;
  logs$: Observable<{ count: number; logs: Array<any> }>;
  labs$: Observable<any[]>;

  constructor(
    private route: ActivatedRoute,
    private isariDataService: IsariDataService,
    private translate: TranslateService,
    private router: Router,
    private toasterService: ToasterService
  ) {}

  ngOnInit() {
    this.options$ = new BehaviorSubject(this.options);
    this.details$ = new BehaviorSubject(false);
    this.logs$ = Observable.combineLatest([
      this.route.paramMap,
      this.options$,
      this.translate.onLangChange
        .map((event: LangChangeEvent) => event.lang)
        .startWith(this.translate.currentLang)
    ])
      .switchMap(([paramMap, options, lang]) => {
        this.feature = (<ParamMap>paramMap).get('feature');
        this.options = Object.assign(
          {},
          {
            itemID: (<ParamMap>paramMap).get('itemID')
          },
          options
        );

        return this.isariDataService
          .getHistory(this.feature, this.options, lang)
          .catch(err => {
            if (err.status === 401) {
              this.translate
                .get('error.' + err.status)
                .subscribe(translated => {
                  this.toasterService.pop('error', '', translated);
                  this.router.navigate(['/', this.feature], {
                    preserveQueryParams: true
                  });
                });
            }
            return Observable.throw(err);
          })
          .combineLatest(this.details$);
      })
      .map(([{ count, logs }, details]) => {
        this.labs$ = this.isariDataService
          .getForeignLabel(
            'Organization',
            uniq(
              flattenDeep(logs.map(log => log.who.roles.map(role => role.lab)))
            )
          )
          .map(labs => keyBy(labs, 'id'));

        if (details && this.options['path']) {
          return {
            count,
            logs: logs.map(log =>
              Object.assign({}, log, {
                _open: true,
                diff: log.diff.filter(
                  diff => diff.path[0] === this.options['path']
                )
              })
            )
          };
        }

        return {
          count,
          logs: logs.map(log => Object.assign({}, log, { _open: details }))
        };
      });
  }

  changeOpt(options) {
    this.options = options;
    this.options$.next(options);
  }

  toggleDetails() {
    this.details$.next(!this.details$.value);
  }

  exportLogs({ logs, filetype }) {
    this.isariDataService.exportLogs(
      logs,
      this.feature,
      this.labs$,
      this.translate,
      this.details$.value,
      filetype
    );
  }
}
<commit_msg>add global editLogs resilience when editor has been deleted, still no name yet  relates #511<commit_after>import 'rxjs/add/operator/combineLatest';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';

import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { LangChangeEvent, TranslateService } from 'ng2-translate';

import { BehaviorSubject } from 'rxjs';
import { EditLogApiOptions } from './EditLogApiOptions.class';
import { IsariDataService } from './../isari-data.service';
import { Observable } from 'rxjs/Observable';
import { ToasterService } from 'angular2-toaster';
import flattenDeep from 'lodash/flattenDeep';
import keyBy from 'lodash/keyBy';
import uniq from 'lodash/uniq';

@Component({
  selector: 'isari-logs',
  templateUrl: './isari-logs.component.html'
  // styleUrls: ['./isari-layout.component.css']
})
export class IsariLogsComponent implements OnInit {
  feature: string;
  options: EditLogApiOptions = { skip: 0, limit: 5 };
  options$: BehaviorSubject<EditLogApiOptions>;
  details$: BehaviorSubject<boolean>;
  logs$: Observable<{ count: number; logs: Array<any> }>;
  labs$: Observable<any[]>;

  constructor(
    private route: ActivatedRoute,
    private isariDataService: IsariDataService,
    private translate: TranslateService,
    private router: Router,
    private toasterService: ToasterService
  ) {}

  ngOnInit() {
    this.options$ = new BehaviorSubject(this.options);
    this.details$ = new BehaviorSubject(false);
    this.logs$ = Observable.combineLatest([
      this.route.paramMap,
      this.options$,
      this.translate.onLangChange
        .map((event: LangChangeEvent) => event.lang)
        .startWith(this.translate.currentLang)
    ])
      .switchMap(([paramMap, options, lang]) => {
        this.feature = (<ParamMap>paramMap).get('feature');
        this.options = Object.assign(
          {},
          {
            itemID: (<ParamMap>paramMap).get('itemID')
          },
          options
        );

        return this.isariDataService
          .getHistory(this.feature, this.options, lang)
          .catch(err => {
            if (err.status === 401) {
              this.translate
                .get('error.' + err.status)
                .subscribe(translated => {
                  this.toasterService.pop('error', '', translated);
                  this.router.navigate(['/', this.feature], {
                    preserveQueryParams: true
                  });
                });
            }
            return Observable.throw(err);
          })
          .combineLatest(this.details$);
      })
      .map(([{ count, logs }, details]) => {
        this.labs$ = this.isariDataService
          .getForeignLabel(
            'Organization',
            uniq(
              flattenDeep(logs.map(log => log.who.roles ? log.who.roles.map(role => role.lab):[]))
            )
          )
          .map(labs => keyBy(labs, 'id'));

        if (details && this.options['path']) {
          return {
            count,
            logs: logs.map(log =>
              Object.assign({}, log, {
                _open: true,
                diff: log.diff.filter(
                  diff => diff.path[0] === this.options['path']
                )
              })
            )
          };
        }

        return {
          count,
          logs: logs.map(log => Object.assign({}, log, { _open: details }))
        };
      });
  }

  changeOpt(options) {
    this.options = options;
    this.options$.next(options);
  }

  toggleDetails() {
    this.details$.next(!this.details$.value);
  }

  exportLogs({ logs, filetype }) {
    this.isariDataService.exportLogs(
      logs,
      this.feature,
      this.labs$,
      this.translate,
      this.details$.value,
      filetype
    );
  }
}

{'fraction_non_alphanumeric': 0.13876478318002627, 'fraction_numerical': 0.0024967148488830486, 'mean_word_length': 2.158091286307054, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 39, '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': '6338830', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2187, 'n_words': 425}