summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts')
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
new file mode 100644
index 000000000..321454753
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts
@@ -0,0 +1,111 @@
+import { Injectable, OnDestroy } from '@angular/core';
+
+import { Observable, Subscription } from 'rxjs';
+
+import { ExecutingTask } from '../models/executing-task';
+import { Summary } from '../models/summary.model';
+import { SummaryService } from './summary.service';
+import { TaskMessageService } from './task-message.service';
+
+@Injectable()
+export class TaskListService implements OnDestroy {
+ summaryDataSubscription: Subscription;
+
+ getUpdate: (context?: any) => Observable<object>;
+ preProcessing: (_: any) => any[];
+ setList: (_: any[]) => void;
+ onFetchError: (error: any) => void;
+ taskFilter: (task: ExecutingTask) => boolean;
+ itemFilter: (item: any, task: ExecutingTask) => boolean;
+ builders: object;
+ summary: Summary;
+
+ 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: (context?: any) => Observable<object>,
+ preProcessing: (_: any) => any[],
+ setList: (_: any[]) => void,
+ onFetchError: (error: any) => void,
+ taskFilter: (task: ExecutingTask) => boolean,
+ itemFilter: (item: any, 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((summary) => {
+ this.summary = summary;
+ this.fetch();
+ }, this.onFetchError);
+ }
+
+ fetch(context: any = null) {
+ this.getUpdate(context).subscribe((resp: any) => {
+ this.updateData(resp, this.summary?.['executing_tasks'].filter(this.taskFilter));
+ }, 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.metadata));
+ }
+ });
+ }
+
+ private getTaskAction(tasks: ExecutingTask[]): string {
+ if (tasks.length === 0) {
+ return undefined;
+ }
+ return tasks
+ .map((task) => {
+ const progress = task.progress ? ` ${task.progress}%` : '';
+ return this.taskMessageService.getRunningText(task) + '...' + progress;
+ })
+ .join(', ');
+ }
+
+ ngOnDestroy() {
+ if (this.summaryDataSubscription) {
+ this.summaryDataSubscription.unsubscribe();
+ }
+ }
+}