diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f2e376cf..9f919fef2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
### Features
* Add ability for admin to inject custom JavaScript/CSS
+ * Add help tooltip on some fields
### Bug fixes
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'
import { ConfigComponent, EditCustomConfigComponent } from '@app/+admin/config'
import { ConfigService } from '@app/+admin/config/shared/config.service'
import { TabsModule } from 'ngx-bootstrap/tabs'
-import { DataTableModule } from 'primeng/components/datatable/datatable'
+import { TableModule } from 'primeng/table'
import { SharedModule } from '../shared'
import { AdminRoutingModule } from './admin-routing.module'
import { AdminComponent } from './admin.component'
@@ -19,7 +19,7 @@ import { VideoBlacklistComponent, VideoBlacklistListComponent } from './video-bl
imports: [
AdminRoutingModule,
TabsModule.forRoot(),
- DataTableModule,
+ TableModule,
SharedModule
],
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 @@
-
-
-
-
-
-
-
-
+
+
+ ID |
+ Score |
+ Name |
+ Host |
+ State |
+ Created |
+
+
+
+
+
+ {{ follow.id }} |
+ {{ follow.score }} |
+ {{ follow.follower.name }} |
+ {{ follow.follower.host }} |
+ {{ follow.state }} |
+ {{ follow.createdAt }} |
+
+
+
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 @@
-import { Component } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
import { NotificationsService } from 'angular2-notifications'
import { SortMeta } from 'primeng/primeng'
@@ -11,7 +11,7 @@ import { FollowService } from '../shared'
templateUrl: './followers-list.component.html',
styleUrls: [ './followers-list.component.scss' ]
})
-export class FollowersListComponent extends RestTable {
+export class FollowersListComponent extends RestTable implements OnInit {
followers: AccountFollow[] = []
totalRecords = 0
rowsPerPage = 10
@@ -25,6 +25,10 @@ export class FollowersListComponent extends RestTable {
super()
}
+ ngOnInit () {
+ this.loadSort()
+ }
+
protected loadData () {
this.followService.getFollowers(this.pagination, this.sort)
.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 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+ ID |
+ Host |
+ State |
+ Created |
+ |
+
+
+
+
+
+ {{ follow.id }} |
+ {{ follow.following.host }} |
+ {{ follow.state }} |
+ {{ follow.createdAt }} |
+
+
+ |
+
+
+
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 @@
-import { Component } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
import { NotificationsService } from 'angular2-notifications'
import { SortMeta } from 'primeng/primeng'
import { AccountFollow } from '../../../../../../shared/models/actors/follow.model'
@@ -10,7 +10,7 @@ import { FollowService } from '../shared'
selector: 'my-followers-list',
templateUrl: './following-list.component.html'
})
-export class FollowingListComponent extends RestTable {
+export class FollowingListComponent extends RestTable implements OnInit {
following: AccountFollow[] = []
totalRecords = 0
rowsPerPage = 10
@@ -25,6 +25,10 @@ export class FollowingListComponent extends RestTable {
super()
}
+ ngOnInit () {
+ this.loadSort()
+ }
+
async removeFollowing (follow: AccountFollow) {
const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow')
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 @@
-
-
-
-
-
-
-
-
- {{ job.data }}
-
-
-
-
-
+
+
+ |
+ ID |
+ Type |
+ State |
+ Created |
+ Updated |
+
+
+
+
+
+
+
+
+
+ |
+ {{ job.id }} |
+ {{ job.type }} |
+ {{ job.state }} |
+ {{ job.createdAt }} |
+ {{ job.updatedAt }} |
+
+
+
+
+
+
+ {{ job.data }}
+ |
+
+
+
+
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'
styleUrls: [ './jobs-list.component.scss' ]
})
export class JobsListComponent extends RestTable implements OnInit {
+ private static JOB_STATE_LOCAL_STORAGE_STATE = 'jobs-list-state'
+
jobState: JobState = 'inactive'
jobStates: JobState[] = [ 'active', 'complete', 'failed', 'inactive', 'delayed' ]
jobs: Job[] = []
- totalRecords = 0
- rowsPerPage = 20
+ totalRecords: number
+ rowsPerPage = 10
sort: SortMeta = { field: 'createdAt', order: -1 }
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
scrollHeight = ''
@@ -32,12 +34,16 @@ export class JobsListComponent extends RestTable implements OnInit {
}
ngOnInit () {
- // 270 -> headers + footer...
+ // 380 -> headers + footer...
this.scrollHeight = (viewportHeight() - 380) + 'px'
+
+ this.loadJobState()
+ this.loadSort()
}
onJobStateChanged () {
this.loadData()
+ this.saveJobState()
}
protected loadData () {
@@ -52,4 +58,14 @@ export class JobsListComponent extends RestTable implements OnInit {
err => this.notificationsService.error('Error', err.message)
)
}
+
+ private loadJobState () {
+ const result = localStorage.getItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE)
+
+ if (result) this.jobState = result as JobState
+ }
+
+ private saveJobState () {
+ localStorage.setItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE, this.jobState)
+ }
}
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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Username |
+ Email |
+ Video quota |
+ Role |
+ Created |
+ |
+
+
+
+
+
+ {{ user.username }} |
+ {{ user.email }} |
+ {{ user.videoQuota }} |
+ {{ user.roleLabel }} |
+ {{ user.createdAt }} |
+
+
+
+ |
+
+
+
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 @@
-import { Component } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
import { NotificationsService } from 'angular2-notifications'
import { SortMeta } from 'primeng/components/common/sortmeta'
@@ -12,11 +12,11 @@ import { UserService } from '../shared'
templateUrl: './user-list.component.html',
styleUrls: [ './user-list.component.scss' ]
})
-export class UserListComponent extends RestTable {
+export class UserListComponent extends RestTable implements OnInit {
users: User[] = []
totalRecords = 0
rowsPerPage = 10
- sort: SortMeta = { field: 'id', order: 1 }
+ sort: SortMeta = { field: 'createdAt', order: 1 }
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
constructor (
@@ -27,6 +27,10 @@ export class UserListComponent extends RestTable {
super()
}
+ ngOnInit () {
+ this.loadSort()
+ }
+
async removeUser (user: User) {
if (user.username === 'root') {
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 @@
Video abuses list
-
-
-
-
-
-
-
-
- {{ videoAbuse.videoName }}
-
-
-
+
+
+ Reason |
+ Reporter |
+ Created |
+ Video |
+
+
+
+
+
+ {{ videoAbuse.reason }} |
+ {{ videoAbuse.reporterServerHost + '@' + videoAbuse.reporterUsername }} |
+ {{ videoAbuse.createdAt }} |
+
+ {{ videoAbuse.videoName }}
+ |
+
+
+
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 {
videoAbuses: VideoAbuse[] = []
totalRecords = 0
rowsPerPage = 10
- sort: SortMeta = { field: 'id', order: 1 }
+ sort: SortMeta = { field: 'createdAt', order: 1 }
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
constructor (
@@ -26,11 +26,11 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
}
ngOnInit () {
- this.loadData()
+ this.loadSort()
}
- getRouterVideoLink (videoId: number) {
- return [ '/videos', videoId ]
+ getRouterVideoLink (videoUUID: string) {
+ return [ '/videos', videoUUID ]
}
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 @@
-
-
-
Blacklisted videos
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Name |
+ Description |
+ Views |
+ NSFW |
+ UUID |
+ Created |
+ |
+
+
+
+
+
+ {{ videoBlacklist.name }} |
+ {{ videoBlacklist.description }} |
+ {{ videoBlacklist.views }} |
+ {{ videoBlacklist.nsfw }} |
+ {{ videoBlacklist.uuid }} |
+ {{ videoBlacklist.createdAt }} |
+
+
+ |
+
+
+
+
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 {
blacklist: BlacklistedVideo[] = []
totalRecords = 0
rowsPerPage = 10
- sort: SortMeta = { field: 'id', order: 1 }
+ sort: SortMeta = { field: 'createdAt', order: 1 }
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
constructor (
@@ -28,13 +28,13 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
}
ngOnInit () {
- this.loadData()
+ this.loadSort()
}
async removeVideoFromBlacklist (entry: BlacklistedVideo) {
- const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the video list.'
+ const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.'
- const res = await this.confirmService.confirm(confirmMessage, 'Remove')
+ const res = await this.confirmService.confirm(confirmMessage, 'Unblacklist')
if (res === false) return
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 @@
- Delete
+ {{ label }}
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 @@
-import { Component } from '@angular/core'
+import { Component, Input } from '@angular/core'
@Component({
selector: 'my-delete-button',
@@ -7,4 +7,5 @@ import { Component } from '@angular/core'
})
export class DeleteButtonComponent {
+ @Input() label = 'Delete'
}
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'
import { RestPagination } from './rest-pagination'
export abstract class RestTable {
+
abstract totalRecords: number
abstract rowsPerPage: number
abstract sort: SortMeta
abstract pagination: RestPagination
+ private sortLocalStorageKey = 'rest-table-sort-' + this.constructor.name
+
protected abstract loadData (): void
+ loadSort () {
+ const result = localStorage.getItem(this.sortLocalStorageKey)
+
+ if (result) {
+ try {
+ this.sort = JSON.parse(result)
+ } catch (err) {
+ console.error('Cannot load sort of local storage key ' + this.sortLocalStorageKey, err)
+ }
+ }
+ }
+
loadLazy (event: LazyLoadEvent) {
this.sort = {
order: event.sortOrder,
@@ -23,6 +38,11 @@ export abstract class RestTable {
}
this.loadData()
+ this.saveSort()
+ }
+
+ saveSort () {
+ localStorage.setItem(this.sortLocalStorageKey, JSON.stringify(this.sort))
}
}
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 {
}
// ngprime data table customizations
-p-datatable {
+p-table {
font-size: 15px !important;
- .ui-datatable-scrollable-header {
- background-color: #fff !important;
- }
-
- .ui-widget-content {
- border: none !important;
- }
-
- .ui-datatable-virtual-table {
- border-top: none !important;
- }
-
td {
border: 1px solid #E5E5E5 !important;
padding-left: 15px !important;
@@ -157,23 +145,33 @@ p-datatable {
tr {
background-color: #fff !important;
height: 46px;
+ }
- &:hover {
- background-color: #f0f0f0 !important;
- }
+ .ui-table-tbody {
+ tr {
+ &:hover {
+ background-color: #f0f0f0 !important;
+ }
- &:not(:hover) {
- .action-cell * {
- display: none !important;
+ &:not(:hover) {
+ .action-cell * {
+ display: none !important;
+ }
+ }
+
+ &:first-child td {
+ border-top: none !important;
+ }
+
+ &:last-child td {
+ border-bottom: none !important;
}
}
- &:first-child td {
- border-top: none !important;
- }
-
- &:last-child td {
- border-bottom: none !important;
+ .expander {
+ cursor: pointer;
+ position: relative;
+ top: 1px;
}
}
@@ -195,7 +193,7 @@ p-datatable {
}
}
- &.ui-state-active {
+ &.ui-state-highlight {
background-color: #fff !important;
.fa {