aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html20
-rw-r--r--client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts38
-rw-r--r--client/src/app/+admin/system/runners/runner.service.ts16
3 files changed, 58 insertions, 16 deletions
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 @@
14 [value]="runnerJobs" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start" 14 [value]="runnerJobs" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
15 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" 15 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order"
16 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" 16 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
17 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 17 [(selection)]="selectedRows" [showCurrentPageReport]="true" i18n-currentPageReportTemplate
18 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} runner jobs" 18 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} runner jobs"
19 [expandedRowKeys]="expandedRows" dataKey="uuid" 19 [expandedRowKeys]="expandedRows" dataKey="uuid"
20> 20>
21 <ng-template pTemplate="header"> 21 <ng-template pTemplate="header">
22 <tr> 22 <tr>
23 <th style="width: 40px">
24 <p-tableHeaderCheckbox ariaLabel="Select all rows" i18n-ariaLabel></p-tableHeaderCheckbox>
25 </th>
23 <th style="width: 40px"></th> 26 <th style="width: 40px"></th>
24 <th style="width: 120px;"></th> 27 <th style="width: 120px;"></th>
25 <th i18n>UUID</th> 28 <th i18n>UUID</th>
@@ -33,7 +36,16 @@
33 </ng-template> 36 </ng-template>
34 37
35 <ng-template pTemplate="caption"> 38 <ng-template pTemplate="caption">
39
36 <div class="caption"> 40 <div class="caption">
41 <div class="left-buttons">
42 <my-action-dropdown
43 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
44 [actions]="bulkActions" [entry]="selectedRows"
45 >
46 </my-action-dropdown>
47 </div>
48
37 <div class="ms-auto d-flex"> 49 <div class="ms-auto d-flex">
38 <my-advanced-input-filter class="me-2" (search)="onSearch($event)"></my-advanced-input-filter> 50 <my-advanced-input-filter class="me-2" (search)="onSearch($event)"></my-advanced-input-filter>
39 51
@@ -43,7 +55,11 @@
43 </ng-template> 55 </ng-template>
44 56
45 <ng-template pTemplate="body" let-expanded="expanded" let-runnerJob> 57 <ng-template pTemplate="body" let-expanded="expanded" let-runnerJob>
46 <tr> 58 <tr [pSelectableRow]="runnerJob">
59 <td class="checkbox-cell">
60 <p-tableCheckbox [value]="runnerJob" ariaLabel="Select this row" i18n-ariaLabel></p-tableCheckbox>
61 </td>
62
47 <td class="expand-cell" [pRowToggler]="runnerJob"> 63 <td class="expand-cell" [pRowToggler]="runnerJob">
48 <my-table-expander-icon [expanded]="expanded"></my-table-expander-icon> 64 <my-table-expander-icon [expanded]="expanded"></my-table-expander-icon>
49 </td> 65 </td>
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 @@
1import { SortMeta } from 'primeng/api' 1import { SortMeta } from 'primeng/api'
2import { Component, OnInit } from '@angular/core' 2import { Component, OnInit } from '@angular/core'
3import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' 3import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
4import { prepareIcu } from '@app/helpers'
4import { DropdownAction } from '@app/shared/shared-main' 5import { DropdownAction } from '@app/shared/shared-main'
5import { RunnerJob } from '@shared/models' 6import { RunnerJob, RunnerJobState } from '@shared/models'
6import { RunnerJobFormatted, RunnerService } from '../runner.service' 7import { RunnerJobFormatted, RunnerService } from '../runner.service'
7 8
8@Component({ 9@Component({
@@ -17,6 +18,7 @@ export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnI
17 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
18 19
19 actions: DropdownAction<RunnerJob>[][] = [] 20 actions: DropdownAction<RunnerJob>[][] = []
21 bulkActions: DropdownAction<RunnerJob[]>[][] = []
20 22
21 constructor ( 23 constructor (
22 private runnerService: RunnerService, 24 private runnerService: RunnerService,
@@ -31,7 +33,18 @@ export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnI
31 [ 33 [
32 { 34 {
33 label: $localize`Cancel this job`, 35 label: $localize`Cancel this job`,
34 handler: job => this.cancelJob(job) 36 handler: job => this.cancelJobs([ job ]),
37 isDisplayed: job => this.canCancelJob(job)
38 }
39 ]
40 ]
41
42 this.bulkActions = [
43 [
44 {
45 label: $localize`Cancel`,
46 handler: jobs => this.cancelJobs(jobs),
47 isDisplayed: jobs => jobs.every(j => this.canCancelJob(j))
35 } 48 }
36 ] 49 ]
37 ] 50 ]
@@ -43,19 +56,20 @@ export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnI
43 return 'RunnerJobListComponent' 56 return 'RunnerJobListComponent'
44 } 57 }
45 58
46 async cancelJob (job: RunnerJob) { 59 async cancelJobs (jobs: RunnerJob[]) {
47 const res = await this.confirmService.confirm( 60 const message = prepareIcu(
48 $localize`Do you really want to cancel this job? Children won't be processed.`, 61 $localize`Do you really want to cancel {count, plural, =1 {this job} other {{count} jobs}}? Children jobs will also be cancelled.`
49 $localize`Cancel job` 62 )({ count: jobs.length }, $localize`Do you really want to cancel these jobs? Children jobs will also be cancelled.`)
50 ) 63
64 const res = await this.confirmService.confirm(message, $localize`Cancel`)
51 65
52 if (res === false) return 66 if (res === false) return
53 67
54 this.runnerService.cancelJob(job) 68 this.runnerService.cancelJobs(jobs)
55 .subscribe({ 69 .subscribe({
56 next: () => { 70 next: () => {
57 this.reloadData() 71 this.reloadData()
58 this.notifier.success($localize`Job cancelled.`) 72 this.notifier.success($localize`Job(s) cancelled.`)
59 }, 73 },
60 74
61 error: err => this.notifier.error(err.message) 75 error: err => this.notifier.error(err.message)
@@ -73,4 +87,10 @@ export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnI
73 error: err => this.notifier.error(err.message) 87 error: err => this.notifier.error(err.message)
74 }) 88 })
75 } 89 }
90
91 private canCancelJob (job: RunnerJob) {
92 return job.state.id === RunnerJobState.PENDING ||
93 job.state.id === RunnerJobState.PROCESSING ||
94 job.state.id === RunnerJobState.WAITING_FOR_PARENT_JOB
95 }
76} 96}
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 @@
1 1
2import { SortMeta } from 'primeng/api' 2import { SortMeta } from 'primeng/api'
3import { catchError, forkJoin, map } from 'rxjs' 3import { catchError, concatMap, forkJoin, from, map, toArray } from 'rxjs'
4import { HttpClient, HttpParams } from '@angular/common/http' 4import { HttpClient, HttpParams } from '@angular/common/http'
5import { Injectable } from '@angular/core' 5import { Injectable } from '@angular/core'
6import { RestExtractor, RestPagination, RestService, ServerService } from '@app/core' 6import { RestExtractor, RestPagination, RestService, ServerService } from '@app/core'
7import { peertubeTranslate } from '@shared/core-utils' 7import { arrayify, peertubeTranslate } from '@shared/core-utils'
8import { ResultList } from '@shared/models/common' 8import { ResultList } from '@shared/models/common'
9import { Runner, RunnerJob, RunnerJobAdmin, RunnerRegistrationToken } from '@shared/models/runners' 9import { Runner, RunnerJob, RunnerJobAdmin, RunnerRegistrationToken } from '@shared/models/runners'
10import { environment } from '../../../../environments/environment' 10import { environment } from '../../../../environments/environment'
@@ -90,9 +90,15 @@ export class RunnerService {
90 ) 90 )
91 } 91 }
92 92
93 cancelJob (job: RunnerJob) { 93 cancelJobs (jobsArg: RunnerJob | RunnerJob[]) {
94 return this.authHttp.post(RunnerService.BASE_RUNNER_URL + '/jobs/' + job.uuid + '/cancel', {}) 94 const jobs = arrayify(jobsArg)
95 .pipe(catchError(res => this.restExtractor.handleError(res))) 95
96 return from(jobs)
97 .pipe(
98 concatMap(job => this.authHttp.post(RunnerService.BASE_RUNNER_URL + '/jobs/' + job.uuid + '/cancel', {})),
99 toArray(),
100 catchError(err => this.restExtractor.handleError(err))
101 )
96 } 102 }
97 103
98 // --------------------------------------------------------------------------- 104 // ---------------------------------------------------------------------------