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

100% Statements 45/45
88.89% Branches 16/18
100% Functions 13/13
100% Lines 36/36

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
    10216x

    16x
    16x

    16x

    135x
    135x

    93x

    93x
    93x
    93x
    93x
    93x
    93x
    93x

    93x

    77x
    66x

    66x
    66x
    66x
    66x
    260x
    204x

    66x

    66x
    66x
    66x
    132x
    85x

    8x

    204x

    141x

    85x

    16x

    81x

    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) => this.taskMessageService.getRunningText(task)).join(', ');
      }

      ngOnDestroy() {
        if (this.summaryDataSubscription) {
          this.summaryDataSubscription.unsubscribe();
        }
      }
    }