diff options
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.ts | 111 |
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(); + } + } +} |