aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/system/runners/runner-job-list
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+admin/system/runners/runner-job-list')
-rw-r--r--client/src/app/+admin/system/runners/runner-job-list/index.ts1
-rw-r--r--client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html101
-rw-r--r--client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts76
3 files changed, 178 insertions, 0 deletions
diff --git a/client/src/app/+admin/system/runners/runner-job-list/index.ts b/client/src/app/+admin/system/runners/runner-job-list/index.ts
new file mode 100644
index 000000000..bdcf93234
--- /dev/null
+++ b/client/src/app/+admin/system/runners/runner-job-list/index.ts
@@ -0,0 +1 @@
export * from './runner-job-list.component'
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
new file mode 100644
index 000000000..7858b4bca
--- /dev/null
+++ b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.html
@@ -0,0 +1,101 @@
1<h1 class="d-flex justify-content-between">
2 <span class="text-nowrap me-2">
3 <my-global-icon iconName="globe" aria-hidden="true"></my-global-icon>
4 <span i18n>Runner jobs</span>
5 </span>
6
7 <a routerLink="/admin/system/runners/runners-list" class="peertube-button-link peertube-button-icon grey-button">
8 <my-global-icon iconName="codesandbox" aria-hidden="true"></my-global-icon>
9 <ng-container i18n>Remote runners</ng-container>
10 </a>
11</h1>
12
13<p-table
14 [value]="runnerJobs" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
15 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order"
16 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
17 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
18 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} runner jobs"
19 [expandedRowKeys]="expandedRows" dataKey="uuid"
20>
21 <ng-template pTemplate="header">
22 <tr>
23 <th style="width: 40px"></th>
24 <th style="width: 120px;"></th>
25 <th i18n>UUID</th>
26 <th i18n>Type</th>
27 <th i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th>
28 <th style="width: 100px" i18n pSortableColumn="priority">Priority <p-sortIcon field="priority"></p-sortIcon></th>
29 <th style="width: 100px" i18n pSortableColumn="progress">Progress <p-sortIcon field="progress"></p-sortIcon></th>
30 <th i18n>Runner</th>
31 <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
32 </tr>
33 </ng-template>
34
35 <ng-template pTemplate="caption">
36 <div class="caption">
37 <div class="ms-auto d-flex">
38 <my-advanced-input-filter class="me-2" (search)="onSearch($event)"></my-advanced-input-filter>
39
40 <my-button i18n-label label="Refresh" icon="refresh" (click)="reloadData()"></my-button>
41 </div>
42 </div>
43 </ng-template>
44
45 <ng-template pTemplate="body" let-expanded="expanded" let-runnerJob>
46 <tr>
47 <td class="expand-cell" [pRowToggler]="runnerJob">
48 <my-table-expander-icon [expanded]="expanded"></my-table-expander-icon>
49 </td>
50
51 <td class="action-cell">
52 <my-action-dropdown
53 placement="bottom-right top-right left auto" container="body"
54 i18n-label label="Actions" [actions]="actions" [entry]="runnerJob"
55 ></my-action-dropdown>
56 </td>
57
58 <td>{{ runnerJob.uuid }}</td>
59 <td>{{ runnerJob.type }}</td>
60 <td>{{ runnerJob.state.label }}</td>
61 <td>{{ runnerJob.priority }}</td>
62 <td>{{ runnerJob.progress }}</td>
63 <td>{{ runnerJob.runner?.name }}</td>
64 <td>{{ runnerJob.createdAt | date: 'short' }}</td>
65 </tr>
66 </ng-template>
67
68 <ng-template pTemplate="rowexpansion" let-runnerJob>
69 <tr>
70 <td colspan="9">
71 <div class="mt-2 fs-7 font-monospace">
72 Parent job: {{ runnerJob.parent?.uuid || '-' }} <br />
73 Processed on {{ (runnerJob.startedAt || '-') }} <br />
74 Finished on {{ (runnerJob.finishedAt || '-') }} <br />
75 </div>
76
77 <div class="mt-2">
78 <strong i18n>Payload:</strong>
79 <pre>{{ runnerJob.payload }}</pre>
80 </div>
81
82 <div class="mt-2">
83 <strong i18n>Private payload:</strong>
84 <pre>{{ runnerJob.privatePayload }}</pre>
85 </div>
86
87 <pre *ngIf="runnerJob.error" class=".text-danger" >{{ runnerJob.error }}</pre>
88 </td>
89 </tr>
90 </ng-template>
91
92 <ng-template pTemplate="emptymessage">
93 <tr>
94 <td colspan="9">
95 <div class="no-results">
96 <ng-container i18n>No runner jobs found.</ng-container>
97 </div>
98 </td>
99 </tr>
100 </ng-template>
101</p-table>
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
new file mode 100644
index 000000000..ea889f0f7
--- /dev/null
+++ b/client/src/app/+admin/system/runners/runner-job-list/runner-job-list.component.ts
@@ -0,0 +1,76 @@
1import { SortMeta } from 'primeng/api'
2import { Component, OnInit } from '@angular/core'
3import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
4import { DropdownAction } from '@app/shared/shared-main'
5import { RunnerJob } from '@shared/models'
6import { RunnerJobFormatted, RunnerService } from '../runner.service'
7
8@Component({
9 selector: 'my-runner-job-list',
10 templateUrl: './runner-job-list.component.html'
11})
12export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnInit {
13 runnerJobs: RunnerJobFormatted[] = []
14 totalRecords = 0
15
16 sort: SortMeta = { field: 'createdAt', order: -1 }
17 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
18
19 actions: DropdownAction<RunnerJob>[][] = []
20
21 constructor (
22 private runnerService: RunnerService,
23 private notifier: Notifier,
24 private confirmService: ConfirmService
25 ) {
26 super()
27 }
28
29 ngOnInit () {
30 this.actions = [
31 [
32 {
33 label: $localize`Cancel this job`,
34 handler: job => this.cancelJob(job)
35 }
36 ]
37 ]
38
39 this.initialize()
40 }
41
42 getIdentifier () {
43 return 'RunnerJobListComponent'
44 }
45
46 async cancelJob (job: RunnerJob) {
47 const res = await this.confirmService.confirm(
48 $localize`Do you really want to cancel this job? Children won't be processed.`,
49 $localize`Cancel job`
50 )
51
52 if (res === false) return
53
54 this.runnerService.cancelJob(job)
55 .subscribe({
56 next: () => {
57 this.reloadData()
58 this.notifier.success($localize`Job cancelled.`)
59 },
60
61 error: err => this.notifier.error(err.message)
62 })
63 }
64
65 protected reloadDataInternal () {
66 this.runnerService.listRunnerJobs({ pagination: this.pagination, sort: this.sort, search: this.search })
67 .subscribe({
68 next: resultList => {
69 this.runnerJobs = resultList.data
70 this.totalRecords = resultList.total
71 },
72
73 error: err => this.notifier.error(err.message)
74 })
75 }
76}