All files / src/app/shared/services task-list.service.ts

100% Statements 50/50
93.1% Branches 27/29
100% Functions 14/14
100% Lines 42/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 10716x         16x 16x     16x                       149x 149x                                     104x                 104x 104x 104x 104x 104x 104x 104x   104x 165x 80x 74x           74x 74x 74x 74x 274x 231x   74x     74x 74x 74x 143x 88x 88x 10x         231x 231x 165x   66x   88x 88x         16x 134x 91x     16x  
import { Injectable, OnDestroy } from '@angular/core';
 
import { Observable, Subscription } from 'rxjs';
 
import { ExecutingTask } from '../models/executing-task';
import { SummaryService } from './summary.service';
import { TaskMessageService } from './task-message.service';
 
@Injectable()
export class TaskListService implements OnDestroy {
  summaryDataSubscription: Subscription;
 
  getUpdate: () => Observable<object>;
  preProcessing: (_: any) => any[];
  setList: (_: any[]) => void;
  onFetchError: (error: any) => void;
  taskFilter: (task: ExecutingTask) => boolean;
  itemFilter: (item, task: ExecutingTask) => boolean;
  builders: object;
 
  constructor(
    private taskMessageService: TaskMessageService,
    private summaryService: SummaryService
  ) {}
 
  /**
   * @param {() => Observable<object>} getUpdate Method that calls the api and
   * returns that without subscribing.
   * @param {(_: any) => any[]} preProcessing Method executed before merging
   * Tasks with Items
   * @param {(_: any[]) => void} setList  Method used to update array of item in the component.
   * @param {(error: any) => void} onFetchError Method called when there were
   * problems while fetching data.
   * @param {(task: ExecutingTask) => boolean} taskFilter callback used in tasks_array.filter()
   * @param {(item, task: ExecutingTask) => boolean} itemFilter callback used in
   * items_array.filter()
   * @param {object} builders
   * object with builders for each type of task.
   * You can also use a 'default' one.
   * @memberof TaskListService
   */
  init(
    getUpdate: () => Observable<object>,
    preProcessing: (_: any) => any[],
    setList: (_: any[]) => void,
    onFetchError: (error: any) => void,
    taskFilter: (task: ExecutingTask) => boolean,
    itemFilter: (item, task: ExecutingTask) => boolean,
    builders: object
  ) {
    this.getUpdate = getUpdate;
    this.preProcessing = preProcessing;
    this.setList = setList;
    this.onFetchError = onFetchError;
    this.taskFilter = taskFilter;
    this.itemFilter = itemFilter;
    this.builders = builders || {};
 
    this.summaryDataSubscription = this.summaryService.subscribe((tasks: any) => {
      if (tasks) {
        this.getUpdate().subscribe((resp: any) => {
          this.updateData(resp, tasks.executing_tasks.filter(this.taskFilter));
        }, this.onFetchError);
      }
    }, this.onFetchError);
  }
 
  private updateData(resp: any, tasks: ExecutingTask[]) {
    const data: any[] = this.preProcessing ? this.preProcessing(resp) : resp;
    this.addMissing(data, tasks);
    data.forEach((item) => {
      const executingTasks = tasks.filter((task) => this.itemFilter(item, task));
      item.cdExecuting = this.getTaskAction(executingTasks);
    });
    this.setList(data);
  }
 
  private addMissing(data: any[], tasks: ExecutingTask[]) {
    const defaultBuilder = this.builders['default'] || {};
    tasks.forEach((task) => {
      const existing = data.find((item) => this.itemFilter(item, task));
      const builder = this.builders[task.name];
      if (!existing && (builder || defaultBuilder)) {
        data.push(builder ? builder(task.metadata) : defaultBuilder(task));
      }
    });
  }
 
  private getTaskAction(tasks: ExecutingTask[]): string {
    if (tasks.length === 0) {
      return;
    }
    return tasks
      .map((task) => {
        const progress = task.progress ? ` ${task.progress}%` : '';
        return this.taskMessageService.getRunningText(task) + '...' + progress;
      })
      .join(', ');
  }
 
  ngOnDestroy() {
    if (this.summaryDataSubscription) {
      this.summaryDataSubscription.unsubscribe();
    }
  }
}