]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
import ceph 14.2.5
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / services / task-list.service.ts
CommitLineData
11fdf7f2
TL
1import { Injectable, OnDestroy } from '@angular/core';
2
3import { Observable, Subscription } from 'rxjs';
4
5import { ExecutingTask } from '../models/executing-task';
6import { SummaryService } from './summary.service';
7import { TaskMessageService } from './task-message.service';
8
9@Injectable()
10export class TaskListService implements OnDestroy {
11 summaryDataSubscription: Subscription;
12
13 getUpdate: () => Observable<object>;
14 preProcessing: (_: any) => any[];
15 setList: (_: any[]) => void;
16 onFetchError: (error: any) => void;
17 taskFilter: (task: ExecutingTask) => boolean;
18 itemFilter: (item, task: ExecutingTask) => boolean;
19 builders: object;
20
21 constructor(
22 private taskMessageService: TaskMessageService,
23 private summaryService: SummaryService
24 ) {}
25
26 /**
27 * @param {() => Observable<object>} getUpdate Method that calls the api and
28 * returns that without subscribing.
29 * @param {(_: any) => any[]} preProcessing Method executed before merging
30 * Tasks with Items
31 * @param {(_: any[]) => void} setList Method used to update array of item in the component.
32 * @param {(error: any) => void} onFetchError Method called when there were
33 * problems while fetching data.
34 * @param {(task: ExecutingTask) => boolean} taskFilter callback used in tasks_array.filter()
35 * @param {(item, task: ExecutingTask) => boolean} itemFilter callback used in
36 * items_array.filter()
37 * @param {object} builders
38 * object with builders for each type of task.
39 * You can also use a 'default' one.
40 * @memberof TaskListService
41 */
42 init(
43 getUpdate: () => Observable<object>,
44 preProcessing: (_: any) => any[],
45 setList: (_: any[]) => void,
46 onFetchError: (error: any) => void,
47 taskFilter: (task: ExecutingTask) => boolean,
48 itemFilter: (item, task: ExecutingTask) => boolean,
49 builders: object
50 ) {
51 this.getUpdate = getUpdate;
52 this.preProcessing = preProcessing;
53 this.setList = setList;
54 this.onFetchError = onFetchError;
55 this.taskFilter = taskFilter;
56 this.itemFilter = itemFilter;
57 this.builders = builders || {};
58
59 this.summaryDataSubscription = this.summaryService.subscribe((tasks: any) => {
60 if (tasks) {
61 this.getUpdate().subscribe((resp: any) => {
62 this.updateData(resp, tasks.executing_tasks.filter(this.taskFilter));
63 }, this.onFetchError);
64 }
65 }, this.onFetchError);
66 }
67
68 private updateData(resp: any, tasks: ExecutingTask[]) {
69 const data: any[] = this.preProcessing ? this.preProcessing(resp) : resp;
70 this.addMissing(data, tasks);
71 data.forEach((item) => {
72 const executingTasks = tasks.filter((task) => this.itemFilter(item, task));
73 item.cdExecuting = this.getTaskAction(executingTasks);
74 });
75 this.setList(data);
76 }
77
78 private addMissing(data: any[], tasks: ExecutingTask[]) {
79 const defaultBuilder = this.builders['default'] || {};
80 tasks.forEach((task) => {
81 const existing = data.find((item) => this.itemFilter(item, task));
82 const builder = this.builders[task.name];
83 if (!existing && (builder || defaultBuilder)) {
84 data.push(builder ? builder(task.metadata) : defaultBuilder(task));
85 }
86 });
87 }
88
89 private getTaskAction(tasks: ExecutingTask[]): string {
90 if (tasks.length === 0) {
91 return;
92 }
eafe8130
TL
93 return tasks
94 .map((task) => {
95 const progress = task.progress ? ` ${task.progress}%` : '';
96 return this.taskMessageService.getRunningText(task) + '...' + progress;
97 })
98 .join(', ');
11fdf7f2
TL
99 }
100
101 ngOnDestroy() {
102 if (this.summaryDataSubscription) {
103 this.summaryDataSubscription.unsubscribe();
104 }
105 }
106}