aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--client/src/app/+admin/admin.module.ts4
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.html35
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.ts8
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.html38
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.ts8
-rw-r--r--client/src/app/+admin/jobs/jobs-list/jobs-list.component.html52
-rw-r--r--client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts22
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html44
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.ts10
-rw-r--r--client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html37
-rw-r--r--client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts8
-rw-r--r--client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html56
-rw-r--r--client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts8
-rw-r--r--client/src/app/shared/misc/delete-button.component.html2
-rw-r--r--client/src/app/shared/misc/delete-button.component.ts3
-rw-r--r--client/src/app/shared/rest/rest-table.ts20
-rw-r--r--client/src/sass/application.scss48
18 files changed, 267 insertions, 137 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f2e376cf..9f919fef2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
5### Features 5### Features
6 6
7 * Add ability for admin to inject custom JavaScript/CSS 7 * Add ability for admin to inject custom JavaScript/CSS
8 * Add help tooltip on some fields
8 9
9### Bug fixes 10### Bug fixes
10 11
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts
index 1d9120490..b389f3d4f 100644
--- a/client/src/app/+admin/admin.module.ts
+++ b/client/src/app/+admin/admin.module.ts
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'
2import { ConfigComponent, EditCustomConfigComponent } from '@app/+admin/config' 2import { ConfigComponent, EditCustomConfigComponent } from '@app/+admin/config'
3import { ConfigService } from '@app/+admin/config/shared/config.service' 3import { ConfigService } from '@app/+admin/config/shared/config.service'
4import { TabsModule } from 'ngx-bootstrap/tabs' 4import { TabsModule } from 'ngx-bootstrap/tabs'
5import { DataTableModule } from 'primeng/components/datatable/datatable' 5import { TableModule } from 'primeng/table'
6import { SharedModule } from '../shared' 6import { SharedModule } from '../shared'
7import { AdminRoutingModule } from './admin-routing.module' 7import { AdminRoutingModule } from './admin-routing.module'
8import { AdminComponent } from './admin.component' 8import { AdminComponent } from './admin.component'
@@ -19,7 +19,7 @@ import { VideoBlacklistComponent, VideoBlacklistListComponent } from './video-bl
19 imports: [ 19 imports: [
20 AdminRoutingModule, 20 AdminRoutingModule,
21 TabsModule.forRoot(), 21 TabsModule.forRoot(),
22 DataTableModule, 22 TableModule,
23 SharedModule 23 SharedModule
24 ], 24 ],
25 25
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html
index 74f2c2e36..85d2a2cf6 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.html
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html
@@ -1,11 +1,26 @@
1<p-dataTable 1<p-table
2 [value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 2 [value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
3 sortField="createdAt" (onLazyLoad)="loadLazy($event)" 3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
4> 4>
5 <p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column> 5 <ng-template pTemplate="header">
6 <p-column field="score" header="Score"></p-column> 6 <tr>
7 <p-column field="follower.name" header="Name"></p-column> 7 <th style="width: 60px">ID</th>
8 <p-column field="follower.host" header="Host"></p-column> 8 <th>Score</th>
9 <p-column field="state" header="State"></p-column> 9 <th>Name</th>
10 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 10 <th>Host</th>
11</p-dataTable> 11 <th>State</th>
12 <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
13 </tr>
14 </ng-template>
15
16 <ng-template pTemplate="body" let-follow>
17 <tr>
18 <td>{{ follow.id }}</td>
19 <td>{{ follow.score }}</td>
20 <td>{{ follow.follower.name }}</td>
21 <td>{{ follow.follower.host }}</td>
22 <td>{{ follow.state }}</td>
23 <td>{{ follow.createdAt }}</td>
24 </tr>
25 </ng-template>
26</p-table>
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
index 649815709..69b3e5e58 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
@@ -1,4 +1,4 @@
1import { Component } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2 2
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { SortMeta } from 'primeng/primeng' 4import { SortMeta } from 'primeng/primeng'
@@ -11,7 +11,7 @@ import { FollowService } from '../shared'
11 templateUrl: './followers-list.component.html', 11 templateUrl: './followers-list.component.html',
12 styleUrls: [ './followers-list.component.scss' ] 12 styleUrls: [ './followers-list.component.scss' ]
13}) 13})
14export class FollowersListComponent extends RestTable { 14export class FollowersListComponent extends RestTable implements OnInit {
15 followers: AccountFollow[] = [] 15 followers: AccountFollow[] = []
16 totalRecords = 0 16 totalRecords = 0
17 rowsPerPage = 10 17 rowsPerPage = 10
@@ -25,6 +25,10 @@ export class FollowersListComponent extends RestTable {
25 super() 25 super()
26 } 26 }
27 27
28 ngOnInit () {
29 this.loadSort()
30 }
31
28 protected loadData () { 32 protected loadData () {
29 this.followService.getFollowers(this.pagination, this.sort) 33 this.followService.getFollowers(this.pagination, this.sort)
30 .subscribe( 34 .subscribe(
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html
index fc1cf0dc4..24981d3e9 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.html
+++ b/client/src/app/+admin/follows/following-list/following-list.component.html
@@ -1,14 +1,26 @@
1<p-dataTable 1<p-table
2 [value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 2 [value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
3 sortField="createdAt" (onLazyLoad)="loadLazy($event)" 3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
4> 4>
5 <p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column> 5 <ng-template pTemplate="header">
6 <p-column field="following.host" header="Host"></p-column> 6 <tr>
7 <p-column field="state" header="State"></p-column> 7 <th style="width: 60px">ID</th>
8 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 8 <th>Host</th>
9 <p-column styleClass="action-cell"> 9 <th>State</th>
10 <ng-template pTemplate="body" let-following="rowData"> 10 <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
11 <my-delete-button (click)="removeFollowing(following)"></my-delete-button> 11 <th></th>
12 </ng-template> 12 </tr>
13 </p-column> 13 </ng-template>
14</p-dataTable> 14
15 <ng-template pTemplate="body" let-follow>
16 <tr>
17 <td>{{ follow.id }}</td>
18 <td>{{ follow.following.host }}</td>
19 <td>{{ follow.state }}</td>
20 <td>{{ follow.createdAt }}</td>
21 <td class="action-cell">
22 <my-delete-button (click)="removeFollowing(follow)"></my-delete-button>
23 </td>
24 </tr>
25 </ng-template>
26</p-table>
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts
index ad1bd4536..873a5d965 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.ts
+++ b/client/src/app/+admin/follows/following-list/following-list.component.ts
@@ -1,4 +1,4 @@
1import { Component } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
3import { SortMeta } from 'primeng/primeng' 3import { SortMeta } from 'primeng/primeng'
4import { AccountFollow } from '../../../../../../shared/models/actors/follow.model' 4import { AccountFollow } from '../../../../../../shared/models/actors/follow.model'
@@ -10,7 +10,7 @@ import { FollowService } from '../shared'
10 selector: 'my-followers-list', 10 selector: 'my-followers-list',
11 templateUrl: './following-list.component.html' 11 templateUrl: './following-list.component.html'
12}) 12})
13export class FollowingListComponent extends RestTable { 13export class FollowingListComponent extends RestTable implements OnInit {
14 following: AccountFollow[] = [] 14 following: AccountFollow[] = []
15 totalRecords = 0 15 totalRecords = 0
16 rowsPerPage = 10 16 rowsPerPage = 10
@@ -25,6 +25,10 @@ export class FollowingListComponent extends RestTable {
25 super() 25 super()
26 } 26 }
27 27
28 ngOnInit () {
29 this.loadSort()
30 }
31
28 async removeFollowing (follow: AccountFollow) { 32 async removeFollowing (follow: AccountFollow) {
29 const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow') 33 const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow')
30 if (res === false) return 34 if (res === false) return
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html
index f1b14e5e3..87717d3dd 100644
--- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html
+++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html
@@ -8,20 +8,42 @@
8 </div> 8 </div>
9</div> 9</div>
10 10
11<p-table
12 [value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" dataKey="id"
13 sortField="createdAt" (onLazyLoad)="loadLazy($event)"
14>
15 <ng-template pTemplate="header">
16 <tr>
17 <th style="width: 27px"></th>
18 <th style="width: 60px">ID</th>
19 <th style="width: 210px">Type</th>
20 <th style="width: 130px">State</th>
21 <th style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
22 <th style="width: 250px">Updated</th>
23 </tr>
24 </ng-template>
11 25
26 <ng-template pTemplate="body" let-expanded="expanded" let-job>
27 <tr>
28 <td>
29 <span class="expander" [pRowToggler]="job">
30 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
31 </span>
32 </td>
33 <td>{{ job.id }}</td>
34 <td>{{ job.type }}</td>
35 <td>{{ job.state }}</td>
36 <td>{{ job.createdAt }}</td>
37 <td>{{ job.updatedAt }}</td>
38 </tr>
39 </ng-template>
40
41 <ng-template pTemplate="rowexpansion" let-job>
42 <tr>
43 <td colspan="6">
44 <pre>{{ job.data }}</pre>
45 </td>
46 </tr>
47 </ng-template>
48</p-table>
12 49
13<p-dataTable
14 [value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
15 sortField="createdAt" (onLazyLoad)="loadLazy($event)" [scrollable]="true" [virtualScroll]="true" [scrollHeight]="scrollHeight"
16>
17 <p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column>
18 <p-column field="type" header="Type" [style]="{ width: '210px' }"></p-column>
19 <p-column field="state" header="State" [style]="{ width: '130px' }"></p-column>
20 <p-column header="Payload">
21 <ng-template pTemplate="body" let-job="rowData">
22 <pre>{{ job.data }}</pre>
23 </ng-template>
24 </p-column>
25 <p-column field="createdAt" header="Created date" [sortable]="true" [style]="{ width: '250px' }"></p-column>
26 <p-column field="updatedAt" header="Updated date" [style]="{ width: '250px' }"></p-column>
27</p-dataTable>
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
index 7de6f70d2..80aba9f3a 100644
--- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
+++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
@@ -14,11 +14,13 @@ import { RestExtractor } from '../../../shared/rest/rest-extractor.service'
14 styleUrls: [ './jobs-list.component.scss' ] 14 styleUrls: [ './jobs-list.component.scss' ]
15}) 15})
16export class JobsListComponent extends RestTable implements OnInit { 16export class JobsListComponent extends RestTable implements OnInit {
17 private static JOB_STATE_LOCAL_STORAGE_STATE = 'jobs-list-state'
18
17 jobState: JobState = 'inactive' 19 jobState: JobState = 'inactive'
18 jobStates: JobState[] = [ 'active', 'complete', 'failed', 'inactive', 'delayed' ] 20 jobStates: JobState[] = [ 'active', 'complete', 'failed', 'inactive', 'delayed' ]
19 jobs: Job[] = [] 21 jobs: Job[] = []
20 totalRecords = 0 22 totalRecords: number
21 rowsPerPage = 20 23 rowsPerPage = 10
22 sort: SortMeta = { field: 'createdAt', order: -1 } 24 sort: SortMeta = { field: 'createdAt', order: -1 }
23 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
24 scrollHeight = '' 26 scrollHeight = ''
@@ -32,12 +34,16 @@ export class JobsListComponent extends RestTable implements OnInit {
32 } 34 }
33 35
34 ngOnInit () { 36 ngOnInit () {
35 // 270 -> headers + footer... 37 // 380 -> headers + footer...
36 this.scrollHeight = (viewportHeight() - 380) + 'px' 38 this.scrollHeight = (viewportHeight() - 380) + 'px'
39
40 this.loadJobState()
41 this.loadSort()
37 } 42 }
38 43
39 onJobStateChanged () { 44 onJobStateChanged () {
40 this.loadData() 45 this.loadData()
46 this.saveJobState()
41 } 47 }
42 48
43 protected loadData () { 49 protected loadData () {
@@ -52,4 +58,14 @@ export class JobsListComponent extends RestTable implements OnInit {
52 err => this.notificationsService.error('Error', err.message) 58 err => this.notificationsService.error('Error', err.message)
53 ) 59 )
54 } 60 }
61
62 private loadJobState () {
63 const result = localStorage.getItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE)
64
65 if (result) this.jobState = result as JobState
66 }
67
68 private saveJobState () {
69 localStorage.setItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE, this.jobState)
70 }
55} 71}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html
index 08f4caeb9..8dbe9ddc4 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.html
+++ b/client/src/app/+admin/users/user-list/user-list.component.html
@@ -7,20 +7,32 @@
7 </a> 7 </a>
8</div> 8</div>
9 9
10<p-dataTable 10<p-table
11 [value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 11 [value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
12 sortField="id" (onLazyLoad)="loadLazy($event)" 12 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
13> 13>
14 <p-column field="id" header="ID" [sortable]="true" [style]="{ width: '60px' }"></p-column> 14 <ng-template pTemplate="header">
15 <p-column field="username" header="Username" [sortable]="true"></p-column> 15 <tr>
16 <p-column field="email" header="Email"></p-column> 16 <th pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th>
17 <p-column field="videoQuota" header="Video quota"></p-column> 17 <th>Email</th>
18 <p-column field="roleLabel" header="Role"></p-column> 18 <th>Video quota</th>
19 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 19 <th>Role</th>
20 <p-column styleClass="action-cell"> 20 <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
21 <ng-template pTemplate="body" let-user="rowData"> 21 <th></th>
22 <my-edit-button [routerLink]="getRouterUserEditLink(user)"></my-edit-button> 22 </tr>
23 <my-delete-button (click)="removeUser(user)"></my-delete-button> 23 </ng-template>
24 </ng-template> 24
25 </p-column> 25 <ng-template pTemplate="body" let-user>
26</p-dataTable> 26 <tr>
27 <td>{{ user.username }}</td>
28 <td>{{ user.email }}</td>
29 <td>{{ user.videoQuota }}</td>
30 <td>{{ user.roleLabel }}</td>
31 <td>{{ user.createdAt }}</td>
32 <td class="action-cell">
33 <my-edit-button [routerLink]="getRouterUserEditLink(user)"></my-edit-button>
34 <my-delete-button (click)="removeUser(user)"></my-delete-button>
35 </td>
36 </tr>
37 </ng-template>
38</p-table>
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts
index 512152808..a52df49c0 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/users/user-list/user-list.component.ts
@@ -1,4 +1,4 @@
1import { Component } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2 2
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { SortMeta } from 'primeng/components/common/sortmeta' 4import { SortMeta } from 'primeng/components/common/sortmeta'
@@ -12,11 +12,11 @@ import { UserService } from '../shared'
12 templateUrl: './user-list.component.html', 12 templateUrl: './user-list.component.html',
13 styleUrls: [ './user-list.component.scss' ] 13 styleUrls: [ './user-list.component.scss' ]
14}) 14})
15export class UserListComponent extends RestTable { 15export class UserListComponent extends RestTable implements OnInit {
16 users: User[] = [] 16 users: User[] = []
17 totalRecords = 0 17 totalRecords = 0
18 rowsPerPage = 10 18 rowsPerPage = 10
19 sort: SortMeta = { field: 'id', order: 1 } 19 sort: SortMeta = { field: 'createdAt', order: 1 }
20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
21 21
22 constructor ( 22 constructor (
@@ -27,6 +27,10 @@ export class UserListComponent extends RestTable {
27 super() 27 super()
28 } 28 }
29 29
30 ngOnInit () {
31 this.loadSort()
32 }
33
30 async removeUser (user: User) { 34 async removeUser (user: User) {
31 if (user.username === 'root') { 35 if (user.username === 'root') {
32 this.notificationsService.error('Error', 'You cannot delete root.') 36 this.notificationsService.error('Error', 'You cannot delete root.')
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
index 65d061246..2779db5bc 100644
--- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
+++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
@@ -2,18 +2,27 @@
2 <div class="admin-sub-title">Video abuses list</div> 2 <div class="admin-sub-title">Video abuses list</div>
3</div> 3</div>
4 4
5<p-dataTable 5<p-table
6 [value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 6 [value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 sortField="id" (onLazyLoad)="loadLazy($event)" 7 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
8> 8>
9 <p-column field="id" header="ID" [sortable]="true" [style]="{ width: '60px' }"></p-column> 9 <ng-template pTemplate="header">
10 <p-column field="reason" header="Reason"></p-column> 10 <tr>
11 <p-column field="reporterServerHost" header="Reporter server host"></p-column> 11 <th>Reason</th>
12 <p-column field="reporterUsername" header="Reporter username"></p-column> 12 <th>Reporter</th>
13 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 13 <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
14 <p-column header="Video"> 14 <th>Video</th>
15 <ng-template pTemplate="body" let-videoAbuse="rowData"> 15 </tr>
16 <a [routerLink]="getRouterVideoLink(videoAbuse.videoId)" title="Go to the video">{{ videoAbuse.videoName }}</a> 16 </ng-template>
17 </ng-template> 17
18 </p-column> 18 <ng-template pTemplate="body" let-videoAbuse>
19</p-dataTable> 19 <tr>
20 <td>{{ videoAbuse.reason }}</td>
21 <td>{{ videoAbuse.reporterServerHost + '@' + videoAbuse.reporterUsername }}</td>
22 <td>{{ videoAbuse.createdAt }}</td>
23 <td>
24 <a [routerLink]="getRouterVideoLink(videoAbuse.videoUUID)" title="Go to the video">{{ videoAbuse.videoName }}</a>
25 </td>
26 </tr>
27 </ng-template>
28</p-table>
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts
index b4d3bbd24..bf9483f34 100644
--- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts
+++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts
@@ -15,7 +15,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
15 videoAbuses: VideoAbuse[] = [] 15 videoAbuses: VideoAbuse[] = []
16 totalRecords = 0 16 totalRecords = 0
17 rowsPerPage = 10 17 rowsPerPage = 10
18 sort: SortMeta = { field: 'id', order: 1 } 18 sort: SortMeta = { field: 'createdAt', order: 1 }
19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
20 20
21 constructor ( 21 constructor (
@@ -26,11 +26,11 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
26 } 26 }
27 27
28 ngOnInit () { 28 ngOnInit () {
29 this.loadData() 29 this.loadSort()
30 } 30 }
31 31
32 getRouterVideoLink (videoId: number) { 32 getRouterVideoLink (videoUUID: string) {
33 return [ '/videos', videoId ] 33 return [ '/videos', videoUUID ]
34 } 34 }
35 35
36 protected loadData () { 36 protected loadData () {
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
index 942f7c9f1..ac30cec39 100644
--- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
+++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
@@ -1,23 +1,35 @@
1<div class="row"> 1<div class="admin-sub-header">
2 <div class="content-padding"> 2 <div class="admin-sub-title">Blacklisted videos</div>
3 <h3>Blacklisted videos</h3>
4
5 <p-dataTable
6 [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 sortField="id" (onLazyLoad)="loadLazy($event)"
8 >
9 <p-column field="id" header="ID" [sortable]="true"></p-column>
10 <p-column field="name" header="Name" [sortable]="true"></p-column>
11 <p-column field="description" header="Description"></p-column>
12 <p-column field="views" header="Views" [sortable]="true"></p-column>
13 <p-column field="nsfw" header="NSFW"></p-column>
14 <p-column field="uuid" header="UUID" [sortable]="true"></p-column>
15 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
16 <p-column header="Delete" styleClass="action-cell">
17 <ng-template pTemplate="body" let-entry="rowData">
18 <my-delete-button (click)="removeVideoFromBlacklist(entry)"></my-delete-button>
19 </ng-template>
20 </p-column>
21 </p-dataTable>
22 </div>
23</div> 3</div>
4
5<p-table
6 [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
8>
9 <ng-template pTemplate="header">
10 <tr>
11 <th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
12 <th>Description</th>
13 <th pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th>
14 <th>NSFW</th>
15 <th>UUID</th>
16 <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
17 <th></th>
18 </tr>
19 </ng-template>
20
21 <ng-template pTemplate="body" let-videoBlacklist>
22 <tr>
23 <td>{{ videoBlacklist.name }}</td>
24 <td>{{ videoBlacklist.description }}</td>
25 <td>{{ videoBlacklist.views }}</td>
26 <td>{{ videoBlacklist.nsfw }}</td>
27 <td>{{ videoBlacklist.uuid }}</td>
28 <td>{{ videoBlacklist.createdAt }}</td>
29 <td class="action-cell">
30 <my-delete-button label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button>
31 </td>
32 </tr>
33 </ng-template>
34</p-table>
35
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
index f4cf21259..7210e677c 100644
--- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
+++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
@@ -16,7 +16,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
16 blacklist: BlacklistedVideo[] = [] 16 blacklist: BlacklistedVideo[] = []
17 totalRecords = 0 17 totalRecords = 0
18 rowsPerPage = 10 18 rowsPerPage = 10
19 sort: SortMeta = { field: 'id', order: 1 } 19 sort: SortMeta = { field: 'createdAt', order: 1 }
20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
21 21
22 constructor ( 22 constructor (
@@ -28,13 +28,13 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
28 } 28 }
29 29
30 ngOnInit () { 30 ngOnInit () {
31 this.loadData() 31 this.loadSort()
32 } 32 }
33 33
34 async removeVideoFromBlacklist (entry: BlacklistedVideo) { 34 async removeVideoFromBlacklist (entry: BlacklistedVideo) {
35 const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the video list.' 35 const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.'
36 36
37 const res = await this.confirmService.confirm(confirmMessage, 'Remove') 37 const res = await this.confirmService.confirm(confirmMessage, 'Unblacklist')
38 if (res === false) return 38 if (res === false) return
39 39
40 this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( 40 this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe(
diff --git a/client/src/app/shared/misc/delete-button.component.html b/client/src/app/shared/misc/delete-button.component.html
index 3db483882..d49de294a 100644
--- a/client/src/app/shared/misc/delete-button.component.html
+++ b/client/src/app/shared/misc/delete-button.component.html
@@ -1,4 +1,4 @@
1<span class="action-button action-button-delete" > 1<span class="action-button action-button-delete" >
2 <span class="icon icon-delete-grey"></span> 2 <span class="icon icon-delete-grey"></span>
3 Delete 3 {{ label }}
4</span> 4</span>
diff --git a/client/src/app/shared/misc/delete-button.component.ts b/client/src/app/shared/misc/delete-button.component.ts
index e04039f69..2ffd98212 100644
--- a/client/src/app/shared/misc/delete-button.component.ts
+++ b/client/src/app/shared/misc/delete-button.component.ts
@@ -1,4 +1,4 @@
1import { Component } from '@angular/core' 1import { Component, Input } from '@angular/core'
2 2
3@Component({ 3@Component({
4 selector: 'my-delete-button', 4 selector: 'my-delete-button',
@@ -7,4 +7,5 @@ import { Component } from '@angular/core'
7}) 7})
8 8
9export class DeleteButtonComponent { 9export class DeleteButtonComponent {
10 @Input() label = 'Delete'
10} 11}
diff --git a/client/src/app/shared/rest/rest-table.ts b/client/src/app/shared/rest/rest-table.ts
index d04d91c68..165fc4e45 100644
--- a/client/src/app/shared/rest/rest-table.ts
+++ b/client/src/app/shared/rest/rest-table.ts
@@ -4,13 +4,28 @@ import { SortMeta } from 'primeng/components/common/sortmeta'
4import { RestPagination } from './rest-pagination' 4import { RestPagination } from './rest-pagination'
5 5
6export abstract class RestTable { 6export abstract class RestTable {
7
7 abstract totalRecords: number 8 abstract totalRecords: number
8 abstract rowsPerPage: number 9 abstract rowsPerPage: number
9 abstract sort: SortMeta 10 abstract sort: SortMeta
10 abstract pagination: RestPagination 11 abstract pagination: RestPagination
11 12
13 private sortLocalStorageKey = 'rest-table-sort-' + this.constructor.name
14
12 protected abstract loadData (): void 15 protected abstract loadData (): void
13 16
17 loadSort () {
18 const result = localStorage.getItem(this.sortLocalStorageKey)
19
20 if (result) {
21 try {
22 this.sort = JSON.parse(result)
23 } catch (err) {
24 console.error('Cannot load sort of local storage key ' + this.sortLocalStorageKey, err)
25 }
26 }
27 }
28
14 loadLazy (event: LazyLoadEvent) { 29 loadLazy (event: LazyLoadEvent) {
15 this.sort = { 30 this.sort = {
16 order: event.sortOrder, 31 order: event.sortOrder,
@@ -23,6 +38,11 @@ export abstract class RestTable {
23 } 38 }
24 39
25 this.loadData() 40 this.loadData()
41 this.saveSort()
42 }
43
44 saveSort () {
45 localStorage.setItem(this.sortLocalStorageKey, JSON.stringify(this.sort))
26 } 46 }
27 47
28} 48}
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index f998096ae..438990a40 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -131,21 +131,9 @@ label {
131} 131}
132 132
133// ngprime data table customizations 133// ngprime data table customizations
134p-datatable { 134p-table {
135 font-size: 15px !important; 135 font-size: 15px !important;
136 136
137 .ui-datatable-scrollable-header {
138 background-color: #fff !important;
139 }
140
141 .ui-widget-content {
142 border: none !important;
143 }
144
145 .ui-datatable-virtual-table {
146 border-top: none !important;
147 }
148
149 td { 137 td {
150 border: 1px solid #E5E5E5 !important; 138 border: 1px solid #E5E5E5 !important;
151 padding-left: 15px !important; 139 padding-left: 15px !important;
@@ -157,23 +145,33 @@ p-datatable {
157 tr { 145 tr {
158 background-color: #fff !important; 146 background-color: #fff !important;
159 height: 46px; 147 height: 46px;
148 }
160 149
161 &:hover { 150 .ui-table-tbody {
162 background-color: #f0f0f0 !important; 151 tr {
163 } 152 &:hover {
153 background-color: #f0f0f0 !important;
154 }
164 155
165 &:not(:hover) { 156 &:not(:hover) {
166 .action-cell * { 157 .action-cell * {
167 display: none !important; 158 display: none !important;
159 }
168 } 160 }
169 }
170 161
171 &:first-child td { 162 &:first-child td {
172 border-top: none !important; 163 border-top: none !important;
164 }
165
166 &:last-child td {
167 border-bottom: none !important;
168 }
173 } 169 }
174 170
175 &:last-child td { 171 .expander {
176 border-bottom: none !important; 172 cursor: pointer;
173 position: relative;
174 top: 1px;
177 } 175 }
178 } 176 }
179 177
@@ -195,7 +193,7 @@ p-datatable {
195 } 193 }
196 } 194 }
197 195
198 &.ui-state-active { 196 &.ui-state-highlight {
199 background-color: #fff !important; 197 background-color: #fff !important;
200 198
201 .fa { 199 .fa {