aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/system
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-04-10 15:26:33 +0200
committerChocobozzz <me@florianbigard.com>2019-04-10 16:38:32 +0200
commitfd8710b897a67518d3a61c319e54b6a65ba443ef (patch)
treed9953b7e0bb4e5a119c872ab21021f4c1ab33bea /client/src/app/+admin/system
parent31b6ddf86652502e0c96d77fa10861ce4af11aa4 (diff)
downloadPeerTube-fd8710b897a67518d3a61c319e54b6a65ba443ef.tar.gz
PeerTube-fd8710b897a67518d3a61c319e54b6a65ba443ef.tar.zst
PeerTube-fd8710b897a67518d3a61c319e54b6a65ba443ef.zip
Add logs endpoint
Diffstat (limited to 'client/src/app/+admin/system')
-rw-r--r--client/src/app/+admin/system/jobs/index.ts4
-rw-r--r--client/src/app/+admin/system/jobs/job.service.ts46
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.html56
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.scss14
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.ts69
5 files changed, 189 insertions, 0 deletions
diff --git a/client/src/app/+admin/system/jobs/index.ts b/client/src/app/+admin/system/jobs/index.ts
new file mode 100644
index 000000000..c0e0cc95d
--- /dev/null
+++ b/client/src/app/+admin/system/jobs/index.ts
@@ -0,0 +1,4 @@
1export * from './shared'
2export * from './jobs-list'
3export * from './job.routes'
4export * from './job.component'
diff --git a/client/src/app/+admin/system/jobs/job.service.ts b/client/src/app/+admin/system/jobs/job.service.ts
new file mode 100644
index 000000000..b96dc3359
--- /dev/null
+++ b/client/src/app/+admin/system/jobs/job.service.ts
@@ -0,0 +1,46 @@
1import { catchError, map } from 'rxjs/operators'
2import { HttpClient, HttpParams } from '@angular/common/http'
3import { Injectable } from '@angular/core'
4import { SortMeta } from 'primeng/primeng'
5import { Observable } from 'rxjs'
6import { ResultList } from '../../../../../../shared'
7import { JobState } from '../../../../../../shared/models'
8import { Job } from '../../../../../../shared/models/server/job.model'
9import { environment } from '../../../../environments/environment'
10import { RestExtractor, RestPagination, RestService } from '../../../shared'
11
12@Injectable()
13export class JobService {
14 private static BASE_JOB_URL = environment.apiUrl + '/api/v1/jobs'
15
16 constructor (
17 private authHttp: HttpClient,
18 private restService: RestService,
19 private restExtractor: RestExtractor
20 ) {}
21
22 getJobs (state: JobState, pagination: RestPagination, sort: SortMeta): Observable<ResultList<Job>> {
23 let params = new HttpParams()
24 params = this.restService.addRestGetParams(params, pagination, sort)
25
26 return this.authHttp.get<ResultList<Job>>(JobService.BASE_JOB_URL + '/' + state, { params })
27 .pipe(
28 map(res => {
29 return this.restExtractor.convertResultListDateToHuman(res, [ 'createdAt', 'processedOn', 'finishedOn' ])
30 }),
31 map(res => this.restExtractor.applyToResultListData(res, this.prettyPrintData)),
32 map(res => this.restExtractor.applyToResultListData(res, this.buildUniqId)),
33 catchError(err => this.restExtractor.handleError(err))
34 )
35 }
36
37 private prettyPrintData (obj: Job) {
38 const data = JSON.stringify(obj.data, null, 2)
39
40 return Object.assign(obj, { data })
41 }
42
43 private buildUniqId (obj: Job) {
44 return Object.assign(obj, { uniqId: `${obj.id}-${obj.type}` })
45 }
46}
diff --git a/client/src/app/+admin/system/jobs/jobs.component.html b/client/src/app/+admin/system/jobs/jobs.component.html
new file mode 100644
index 000000000..7ed1888e2
--- /dev/null
+++ b/client/src/app/+admin/system/jobs/jobs.component.html
@@ -0,0 +1,56 @@
1<div class="admin-sub-header">
2 <div i18n class="form-sub-title">Jobs list</div>
3
4 <div class="peertube-select-container">
5 <select [(ngModel)]="jobState" (ngModelChange)="onJobStateChanged()">
6 <option *ngFor="let state of jobStates" [value]="state">{{ state }}</option>
7 </select>
8 </div>
9</div>
10
11<p-table
12 [value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" dataKey="uniqId"
13 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" [first]="pagination.start"
14>
15 <ng-template pTemplate="header">
16 <tr>
17 <th style="width: 27px"></th>
18 <th i18n style="width: 60px">ID</th>
19 <th i18n style="width: 210px">Type</th>
20 <th i18n style="width: 130px">State</th>
21 <th i18n style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
22 <th i18n style="width: 250px">Processed on</th>
23 <th i18n style="width: 250px">Finished on</th>
24 </tr>
25 </ng-template>
26
27 <ng-template pTemplate="body" let-expanded="expanded" let-job>
28 <tr>
29 <td>
30 <span class="expander" [pRowToggler]="job">
31 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
32 </span>
33 </td>
34 <td>{{ job.id }}</td>
35 <td>{{ job.type }}</td>
36 <td>{{ job.state }}</td>
37 <td>{{ job.createdAt }}</td>
38 <td>{{ job.processedOn }}</td>
39 <td>{{ job.finishedOn }}</td>
40 </tr>
41 </ng-template>
42
43 <ng-template pTemplate="rowexpansion" let-job>
44 <tr>
45 <td colspan="7">
46 <pre>{{ job.data }}</pre>
47 </td>
48 </tr>
49 <tr class="job-error" *ngIf="job.error">
50 <td colspan="7">
51 <pre>{{ job.error }}</pre>
52 </td>
53 </tr>
54 </ng-template>
55</p-table>
56
diff --git a/client/src/app/+admin/system/jobs/jobs.component.scss b/client/src/app/+admin/system/jobs/jobs.component.scss
new file mode 100644
index 000000000..ab05f1982
--- /dev/null
+++ b/client/src/app/+admin/system/jobs/jobs.component.scss
@@ -0,0 +1,14 @@
1@import '_variables';
2@import '_mixins';
3
4.peertube-select-container {
5 @include peertube-select-container(auto);
6}
7
8pre {
9 font-size: 11px;
10}
11
12.job-error {
13 color: red;
14}
diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts
new file mode 100644
index 000000000..b265e1dd6
--- /dev/null
+++ b/client/src/app/+admin/system/jobs/jobs.component.ts
@@ -0,0 +1,69 @@
1import { Component, OnInit } from '@angular/core'
2import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
3import { Notifier } from '@app/core'
4import { SortMeta } from 'primeng/primeng'
5import { Job } from '../../../../../../shared/index'
6import { JobState } from '../../../../../../shared/models'
7import { RestPagination, RestTable } from '../../../shared'
8import { JobService } from '../shared'
9import { I18n } from '@ngx-translate/i18n-polyfill'
10
11@Component({
12 selector: 'my-jobs-list',
13 templateUrl: './jobs-list.component.html',
14 styleUrls: [ './jobs-list.component.scss' ]
15})
16export class JobsListComponent extends RestTable implements OnInit {
17 private static JOB_STATE_LOCAL_STORAGE_STATE = 'jobs-list-state'
18
19 jobState: JobState = 'waiting'
20 jobStates: JobState[] = [ 'active', 'completed', 'failed', 'waiting', 'delayed' ]
21 jobs: Job[] = []
22 totalRecords: number
23 rowsPerPage = 10
24 sort: SortMeta = { field: 'createdAt', order: -1 }
25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
26
27 constructor (
28 private notifier: Notifier,
29 private jobsService: JobService,
30 private i18n: I18n
31 ) {
32 super()
33 }
34
35 ngOnInit () {
36 this.loadJobState()
37 this.initialize()
38 }
39
40 onJobStateChanged () {
41 this.pagination.start = 0
42
43 this.loadData()
44 this.saveJobState()
45 }
46
47 protected loadData () {
48 this.jobsService
49 .getJobs(this.jobState, this.pagination, this.sort)
50 .subscribe(
51 resultList => {
52 this.jobs = resultList.data
53 this.totalRecords = resultList.total
54 },
55
56 err => this.notifier.error(err.message)
57 )
58 }
59
60 private loadJobState () {
61 const result = peertubeLocalStorage.getItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE)
62
63 if (result) this.jobState = result as JobState
64 }
65
66 private saveJobState () {
67 peertubeLocalStorage.setItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE, this.jobState)
68 }
69}