From 476ce1d7f42701cb2ce456b52c27a23ccfcef6d4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 19 May 2023 14:27:27 +0200 Subject: Add bulk actions on runner jobs --- .../runner-job-list/runner-job-list.component.html | 20 ++++++++++-- .../runner-job-list/runner-job-list.component.ts | 38 +++++++++++++++++----- .../app/+admin/system/runners/runner.service.ts | 16 ++++++--- 3 files changed, 58 insertions(+), 16 deletions(-) (limited to 'client/src/app/+admin/system') diff --git a/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html index 654b60ca9..5356e0e03 100644 --- a/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html +++ b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html @@ -14,12 +14,15 @@ [value]="runnerJobs" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start" [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" - [showCurrentPageReport]="true" i18n-currentPageReportTemplate + [(selection)]="selectedRows" [showCurrentPageReport]="true" i18n-currentPageReportTemplate currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} runner jobs" [expandedRowKeys]="expandedRows" dataKey="uuid" > + + + UUID @@ -33,7 +36,16 @@ +
+
+ + +
+
@@ -43,7 +55,11 @@ - + + + + + diff --git a/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts index ea889f0f7..8ba956eb8 100644 --- a/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts +++ b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts @@ -1,8 +1,9 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit } from '@angular/core' import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' +import { prepareIcu } from '@app/helpers' import { DropdownAction } from '@app/shared/shared-main' -import { RunnerJob } from '@shared/models' +import { RunnerJob, RunnerJobState } from '@shared/models' import { RunnerJobFormatted, RunnerService } from '../runner.service' @Component({ @@ -17,6 +18,7 @@ export class RunnerJobListComponent extends RestTable implements OnI pagination: RestPagination = { count: this.rowsPerPage, start: 0 } actions: DropdownAction[][] = [] + bulkActions: DropdownAction[][] = [] constructor ( private runnerService: RunnerService, @@ -31,7 +33,18 @@ export class RunnerJobListComponent extends RestTable implements OnI [ { label: $localize`Cancel this job`, - handler: job => this.cancelJob(job) + handler: job => this.cancelJobs([ job ]), + isDisplayed: job => this.canCancelJob(job) + } + ] + ] + + this.bulkActions = [ + [ + { + label: $localize`Cancel`, + handler: jobs => this.cancelJobs(jobs), + isDisplayed: jobs => jobs.every(j => this.canCancelJob(j)) } ] ] @@ -43,19 +56,20 @@ export class RunnerJobListComponent extends RestTable implements OnI return 'RunnerJobListComponent' } - async cancelJob (job: RunnerJob) { - const res = await this.confirmService.confirm( - $localize`Do you really want to cancel this job? Children won't be processed.`, - $localize`Cancel job` - ) + async cancelJobs (jobs: RunnerJob[]) { + const message = prepareIcu( + $localize`Do you really want to cancel {count, plural, =1 {this job} other {{count} jobs}}? Children jobs will also be cancelled.` + )({ count: jobs.length }, $localize`Do you really want to cancel these jobs? Children jobs will also be cancelled.`) + + const res = await this.confirmService.confirm(message, $localize`Cancel`) if (res === false) return - this.runnerService.cancelJob(job) + this.runnerService.cancelJobs(jobs) .subscribe({ next: () => { this.reloadData() - this.notifier.success($localize`Job cancelled.`) + this.notifier.success($localize`Job(s) cancelled.`) }, error: err => this.notifier.error(err.message) @@ -73,4 +87,10 @@ export class RunnerJobListComponent extends RestTable implements OnI error: err => this.notifier.error(err.message) }) } + + private canCancelJob (job: RunnerJob) { + return job.state.id === RunnerJobState.PENDING || + job.state.id === RunnerJobState.PROCESSING || + job.state.id === RunnerJobState.WAITING_FOR_PARENT_JOB + } } diff --git a/client/src/app/+admin/system/runners/runner.service.ts b/client/src/app/+admin/system/runners/runner.service.ts index 05083318c..392ec82bc 100644 --- a/client/src/app/+admin/system/runners/runner.service.ts +++ b/client/src/app/+admin/system/runners/runner.service.ts @@ -1,10 +1,10 @@ import { SortMeta } from 'primeng/api' -import { catchError, forkJoin, map } from 'rxjs' +import { catchError, concatMap, forkJoin, from, map, toArray } from 'rxjs' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor, RestPagination, RestService, ServerService } from '@app/core' -import { peertubeTranslate } from '@shared/core-utils' +import { arrayify, peertubeTranslate } from '@shared/core-utils' import { ResultList } from '@shared/models/common' import { Runner, RunnerJob, RunnerJobAdmin, RunnerRegistrationToken } from '@shared/models/runners' import { environment } from '../../../../environments/environment' @@ -90,9 +90,15 @@ export class RunnerService { ) } - cancelJob (job: RunnerJob) { - return this.authHttp.post(RunnerService.BASE_RUNNER_URL + '/jobs/' + job.uuid + '/cancel', {}) - .pipe(catchError(res => this.restExtractor.handleError(res))) + cancelJobs (jobsArg: RunnerJob | RunnerJob[]) { + const jobs = arrayify(jobsArg) + + return from(jobs) + .pipe( + concatMap(job => this.authHttp.post(RunnerService.BASE_RUNNER_URL + '/jobs/' + job.uuid + '/cancel', {})), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) } // --------------------------------------------------------------------------- -- cgit v1.2.3