aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/system
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-08-27 17:27:37 +0200
committerRigel Kent <par@rigelk.eu>2020-09-28 13:25:50 +0200
commit7f0d85616944681ed447f4342d86eee8141c7612 (patch)
treedc51b7dd989f7bcdff37ef1332a61d05a652ab53 /client/src/app/+admin/system
parentcd372e840b6a291a56e0d5135548d05a98415155 (diff)
downloadPeerTube-7f0d85616944681ed447f4342d86eee8141c7612.tar.gz
PeerTube-7f0d85616944681ed447f4342d86eee8141c7612.tar.zst
PeerTube-7f0d85616944681ed447f4342d86eee8141c7612.zip
jobs/logs view select and empty state visual improvements
Diffstat (limited to 'client/src/app/+admin/system')
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.html56
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.scss12
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.ts15
-rw-r--r--client/src/app/+admin/system/logs/logs.component.html35
-rw-r--r--client/src/app/+admin/system/logs/logs.component.scss5
-rw-r--r--client/src/app/+admin/system/logs/logs.component.ts19
6 files changed, 98 insertions, 44 deletions
diff --git a/client/src/app/+admin/system/jobs/jobs.component.html b/client/src/app/+admin/system/jobs/jobs.component.html
index 185fae220..e06156a9e 100644
--- a/client/src/app/+admin/system/jobs/jobs.component.html
+++ b/client/src/app/+admin/system/jobs/jobs.component.html
@@ -10,45 +10,48 @@
10 10
11 <div class="select-filter-block"> 11 <div class="select-filter-block">
12 <label for="jobState" i18n>Job state</label> 12 <label for="jobState" i18n>Job state</label>
13 <div class="peertube-select-container"> 13 <ng-select
14 <select id="jobState" name="jobState" [(ngModel)]="jobState" (ngModelChange)="onJobStateOrTypeChanged()" class="form-control"> 14 class="select-job-state"
15 <option *ngFor="let state of jobStates" [value]="state">{{ state }}</option> 15 [(ngModel)]="jobState"
16 </select> 16 (ngModelChange)="onJobStateOrTypeChanged()"
17 </div> 17 [clearable]="false"
18 [searchable]="false"
19 >
20 <ng-option *ngFor="let state of jobStates" [value]="state">
21 <span class="badge" [ngClass]="getJobStateClass(state)">{{ state }}</span>
22 </ng-option>
23 </ng-select>
18 </div> 24 </div>
19</div> 25</div>
20 26
21<p-table 27<p-table
22 [value]="jobs" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" dataKey="uniqId" 28 [value]="jobs" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
23 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" [first]="pagination.start" 29 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="uniqId" [first]="pagination.start"
24 [tableStyle]="{'table-layout':'auto'}" (onPage)="onPage($event)" [expandedRowKeys]="expandedRows" 30 [tableStyle]="{'table-layout':'auto'}" (onPage)="onPage($event)"
31 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
32 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} jobs"
33 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
25> 34>
26 <ng-template pTemplate="header"> 35 <ng-template pTemplate="header">
27 <tr> 36 <tr>
28 <th style="width: 40px"></th> 37 <th style="width: 40px"></th>
29 <th style="width: 100%" class="job-id" i18n>ID</th> 38 <th style="width: calc(100% - 390px)" class="job-id" i18n>ID</th>
30 <th style="width: 200px" class="job-type" i18n>Type</th> 39 <th style="width: 200px" class="job-type" i18n>Type</th>
31 <th style="width: 150px" class="job-date" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> 40 <th style="width: 150px" class="job-date" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
32 <th style="width: 150px" class="job-state" i18n>State</th>
33 </tr> 41 </tr>
34 </ng-template> 42 </ng-template>
35 43
36 <ng-template pTemplate="body" let-expanded="expanded" let-job> 44 <ng-template pTemplate="body" let-expanded="expanded" let-job>
37 <tr> 45 <tr>
38 <td class="expand-cell"> 46 <td class="expand-cell" [pRowToggler]="job" i18n-ngbTooltip ngbTooltip="More information" placement="top-left" container="body">
39 <span class="expander" [pRowToggler]="job" i18n-ngbTooltip ngbTooltip="More information" placement="top-left" container="body"> 47 <span class="expander">
40 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i> 48 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
41 </span> 49 </span>
42 </td> 50 </td>
43 51
44 <td class="job-id" [title]="job.id">{{ job.id }}</td> 52 <td class="job-id" [pRowToggler]="job" [title]="job.id">{{ job.id }}</td>
45 <td class="job-type">{{ job.type }}</td> 53 <td class="job-type" [pRowToggler]="job">{{ job.type }}</td>
46 <td class="job-date">{{ job.createdAt | date: 'short' }}</td> 54 <td class="job-date" [pRowToggler]="job">{{ job.createdAt | date: 'short' }}</td>
47 <td class="job-state" *ngIf="job.state === 'delayed'" class="text-muted"><span class="glyphicon glyphicon-repeat"></span> <span i18n>Delayed</span></td>
48 <td class="job-state" *ngIf="job.state === 'waiting'" class="text-warning"><span class="glyphicon glyphicon-hourglass"></span> <span i18n>Will start soon...</span></td>
49 <td class="job-state" *ngIf="job.state === 'active'" class="text-warning"><span class="glyphicon glyphicon-cog"></span> <span i18n>Running...</span></td>
50 <td class="job-state" *ngIf="job.state === 'completed'" class="text-success"><span class="glyphicon glyphicon-ok"></span> <span i18n>Finished</span></td>
51 <td class="job-state" *ngIf="job.state === 'failed'" class="text-danger"><span class="glyphicon glyphicon-remove"></span> <span i18n>Failed</span></td>
52 </tr> 55 </tr>
53 </ng-template> 56 </ng-template>
54 57
@@ -74,5 +77,18 @@
74 </td> 77 </td>
75 </tr> 78 </tr>
76 </ng-template> 79 </ng-template>
80
81 <ng-template pTemplate="emptymessage">
82 <tr>
83 <td colspan="4">
84 <div class="no-results">
85 <div class="d-block">
86 <ng-container *ngIf="jobType === 'all'" i18n>No <span class="badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span> jobs found.</ng-container>
87 <ng-container *ngIf="jobType !== 'all'" i18n>No <code>{{ jobType }}</code> jobs found that are <span class="badge" [ngClass]="getJobStateClass(jobState)">{{ jobState }}</span>.</ng-container>
88 </div>
89 </div>
90 </td>
91 </tr>
92 </ng-template>
77</p-table> 93</p-table>
78 94
diff --git a/client/src/app/+admin/system/jobs/jobs.component.scss b/client/src/app/+admin/system/jobs/jobs.component.scss
index c33e14292..784ec4572 100644
--- a/client/src/app/+admin/system/jobs/jobs.component.scss
+++ b/client/src/app/+admin/system/jobs/jobs.component.scss
@@ -1,6 +1,10 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.select-job-state {
5 min-width: 120px;
6}
7
4.job-id { 8.job-id {
5 max-width: 30vw !important; 9 max-width: 30vw !important;
6} 10}
@@ -13,10 +17,6 @@
13 width: 170px !important; 17 width: 170px !important;
14} 18}
15 19
16.job-state {
17 max-width: 60px;
18}
19
20.admin-sub-header { 20.admin-sub-header {
21 flex-direction: row !important; 21 flex-direction: row !important;
22 justify-content: flex-end; 22 justify-content: flex-end;
@@ -47,3 +47,7 @@ pre {
47.job-error { 47.job-error {
48 color: red; 48 color: red;
49} 49}
50
51.badge {
52 @include table-badge;
53}
diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts
index 96e0f25b0..25d75aed2 100644
--- a/client/src/app/+admin/system/jobs/jobs.component.ts
+++ b/client/src/app/+admin/system/jobs/jobs.component.ts
@@ -56,6 +56,21 @@ export class JobsComponent extends RestTable implements OnInit {
56 return 'JobsComponent' 56 return 'JobsComponent'
57 } 57 }
58 58
59 getJobStateClass (state: JobStateClient) {
60 switch (state) {
61 case 'active':
62 return 'badge-blue'
63 case 'completed':
64 return 'badge-green'
65 case 'delayed':
66 return 'badge-brown'
67 case 'failed':
68 return 'badge-red'
69 case 'waiting':
70 return 'badge-yellow'
71 }
72 }
73
59 onJobStateOrTypeChanged () { 74 onJobStateOrTypeChanged () {
60 this.pagination.start = 0 75 this.pagination.start = 0
61 76
diff --git a/client/src/app/+admin/system/logs/logs.component.html b/client/src/app/+admin/system/logs/logs.component.html
index ae1b0c601..e92e11c2a 100644
--- a/client/src/app/+admin/system/logs/logs.component.html
+++ b/client/src/app/+admin/system/logs/logs.component.html
@@ -5,17 +5,30 @@
5 </select> 5 </select>
6 </div> 6 </div>
7 7
8 <div class="peertube-select-container"> 8 <ng-select
9 <select [(ngModel)]="startDate" (ngModelChange)="refresh()" class="form-control"> 9 [(ngModel)]="startDate"
10 <option *ngFor="let timeChoice of timeChoices" [value]="timeChoice.id">{{ timeChoice.label }}</option> 10 (ngModelChange)="refresh()"
11 </select> 11 [clearable]="false"
12 </div> 12 [searchable]="false"
13 13 >
14 <div class="peertube-select-container" *ngIf="!isAuditLog()"> 14 <ng-option *ngFor="let time of timeChoices" [value]="time.id">
15 <select [(ngModel)]="level" (ngModelChange)="refresh()" class="form-control"> 15 {{ time.label }} ({{ time.id | date: time.dateFormat }} - <span i18n>now</span>)
16 <option *ngFor="let levelChoice of levelChoices" [value]="levelChoice.id">{{ levelChoice.label }}</option> 16 </ng-option>
17 </select> 17 </ng-select>
18 </div> 18
19 <ng-select
20 [(ngModel)]="level"
21 (ngModelChange)="refresh()"
22 [clearable]="false"
23 [searchable]="false"
24 >
25 <ng-option *ngFor="let levelChoice of levelChoices" [value]="levelChoice.id">
26 <ng-container *ngIf="levelChoice.id === 'debug'"><span style="font-size:80%;color:lightgray;vertical-align:text-top;">&#11044;</span> {{ levelChoice.label }}</ng-container>
27 <ng-container *ngIf="levelChoice.id === 'info'"><span style="font-size:80%;color:lightskyblue;vertical-align:text-top;">&#11044;</span> {{ levelChoice.label }}</ng-container>
28 <ng-container *ngIf="levelChoice.id === 'warn'"><span style="font-size:80%;color:orange;vertical-align:text-top;">&#11044;</span> {{ levelChoice.label }}</ng-container>
29 <ng-container *ngIf="levelChoice.id === 'error'"><span style="font-size:80%;color:red;vertical-align:text-top;">&#11044;</span> {{ levelChoice.label }}</ng-container>
30 </ng-option>
31 </ng-select>
19 32
20 <my-button i18n-label label="Refresh" icon="refresh" (click)="refresh()"></my-button> 33 <my-button i18n-label label="Refresh" icon="refresh" (click)="refresh()"></my-button>
21</div> 34</div>
diff --git a/client/src/app/+admin/system/logs/logs.component.scss b/client/src/app/+admin/system/logs/logs.component.scss
index 6b92f4d0b..587a9795c 100644
--- a/client/src/app/+admin/system/logs/logs.component.scss
+++ b/client/src/app/+admin/system/logs/logs.component.scss
@@ -52,7 +52,8 @@
52 } 52 }
53 53
54 my-button, 54 my-button,
55 .peertube-select-container { 55 .peertube-select-container,
56 ng-select {
56 margin-left: 10px; 57 margin-left: 10px;
57 } 58 }
58} 59}
@@ -62,6 +63,7 @@
62 flex-direction: column; 63 flex-direction: column;
63 64
64 .peertube-select-container, 65 .peertube-select-container,
66 ng-select,
65 my-button { 67 my-button {
66 width: 100% !important; 68 width: 100% !important;
67 margin-left: 0px !important; 69 margin-left: 0px !important;
@@ -80,6 +82,7 @@
80 flex-direction: column; 82 flex-direction: column;
81 83
82 .peertube-select-container, 84 .peertube-select-container,
85 ng-select,
83 my-button { 86 my-button {
84 width: 100% !important; 87 width: 100% !important;
85 margin-left: 0px !important; 88 margin-left: 0px !important;
diff --git a/client/src/app/+admin/system/logs/logs.component.ts b/client/src/app/+admin/system/logs/logs.component.ts
index c9c9dc3d1..62b8bc0b9 100644
--- a/client/src/app/+admin/system/logs/logs.component.ts
+++ b/client/src/app/+admin/system/logs/logs.component.ts
@@ -14,7 +14,7 @@ export class LogsComponent implements OnInit {
14 loading = false 14 loading = false
15 15
16 logs: LogRow[] = [] 16 logs: LogRow[] = []
17 timeChoices: { id: string, label: string }[] = [] 17 timeChoices: { id: string, label: string, dateFormat: string }[] = []
18 levelChoices: { id: LogLevel, label: string }[] = [] 18 levelChoices: { id: LogLevel, label: string }[] = []
19 logTypeChoices: { id: 'audit' | 'standard', label: string }[] = [] 19 logTypeChoices: { id: 'audit' | 'standard', label: string }[] = []
20 20
@@ -76,15 +76,18 @@ export class LogsComponent implements OnInit {
76 this.timeChoices = [ 76 this.timeChoices = [
77 { 77 {
78 id: lastWeek.toISOString(), 78 id: lastWeek.toISOString(),
79 label: $localize`Last week` 79 label: $localize`Last week`,
80 dateFormat: 'shortDate'
80 }, 81 },
81 { 82 {
82 id: lastDay.toISOString(), 83 id: lastDay.toISOString(),
83 label: $localize`Last day` 84 label: $localize`Last day`,
85 dateFormat: 'short'
84 }, 86 },
85 { 87 {
86 id: lastHour.toISOString(), 88 id: lastHour.toISOString(),
87 label: $localize`Last hour` 89 label: $localize`Last hour`,
90 dateFormat: 'mediumTime'
88 } 91 }
89 ] 92 ]
90 93
@@ -95,19 +98,19 @@ export class LogsComponent implements OnInit {
95 this.levelChoices = [ 98 this.levelChoices = [
96 { 99 {
97 id: 'debug', 100 id: 'debug',
98 label: $localize`Debug` 101 label: $localize`debug`
99 }, 102 },
100 { 103 {
101 id: 'info', 104 id: 'info',
102 label: $localize`Info` 105 label: $localize`info`
103 }, 106 },
104 { 107 {
105 id: 'warn', 108 id: 'warn',
106 label: $localize`Warning` 109 label: $localize`warning`
107 }, 110 },
108 { 111 {
109 id: 'error', 112 id: 'error',
110 label: $localize`Error` 113 label: $localize`error`
111 } 114 }
112 ] 115 ]
113 116