Improve admin tables
This commit is contained in:
parent
621d99f53f
commit
ab998f7b6d
|
@ -5,6 +5,7 @@
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* Add ability for admin to inject custom JavaScript/CSS
|
* Add ability for admin to inject custom JavaScript/CSS
|
||||||
|
* Add help tooltip on some fields
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'
|
||||||
import { ConfigComponent, EditCustomConfigComponent } from '@app/+admin/config'
|
import { ConfigComponent, EditCustomConfigComponent } from '@app/+admin/config'
|
||||||
import { ConfigService } from '@app/+admin/config/shared/config.service'
|
import { ConfigService } from '@app/+admin/config/shared/config.service'
|
||||||
import { TabsModule } from 'ngx-bootstrap/tabs'
|
import { TabsModule } from 'ngx-bootstrap/tabs'
|
||||||
import { DataTableModule } from 'primeng/components/datatable/datatable'
|
import { TableModule } from 'primeng/table'
|
||||||
import { SharedModule } from '../shared'
|
import { SharedModule } from '../shared'
|
||||||
import { AdminRoutingModule } from './admin-routing.module'
|
import { AdminRoutingModule } from './admin-routing.module'
|
||||||
import { AdminComponent } from './admin.component'
|
import { AdminComponent } from './admin.component'
|
||||||
|
@ -19,7 +19,7 @@ import { VideoBlacklistComponent, VideoBlacklistListComponent } from './video-bl
|
||||||
imports: [
|
imports: [
|
||||||
AdminRoutingModule,
|
AdminRoutingModule,
|
||||||
TabsModule.forRoot(),
|
TabsModule.forRoot(),
|
||||||
DataTableModule,
|
TableModule,
|
||||||
SharedModule
|
SharedModule
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
<p-dataTable
|
<p-table
|
||||||
[value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
<p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column>
|
<ng-template pTemplate="header">
|
||||||
<p-column field="score" header="Score"></p-column>
|
<tr>
|
||||||
<p-column field="follower.name" header="Name"></p-column>
|
<th style="width: 60px">ID</th>
|
||||||
<p-column field="follower.host" header="Host"></p-column>
|
<th>Score</th>
|
||||||
<p-column field="state" header="State"></p-column>
|
<th>Name</th>
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
<th>Host</th>
|
||||||
</p-dataTable>
|
<th>State</th>
|
||||||
|
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-follow>
|
||||||
|
<tr>
|
||||||
|
<td>{{ follow.id }}</td>
|
||||||
|
<td>{{ follow.score }}</td>
|
||||||
|
<td>{{ follow.follower.name }}</td>
|
||||||
|
<td>{{ follow.follower.host }}</td>
|
||||||
|
<td>{{ follow.state }}</td>
|
||||||
|
<td>{{ follow.createdAt }}</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
|
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
import { SortMeta } from 'primeng/primeng'
|
import { SortMeta } from 'primeng/primeng'
|
||||||
|
@ -11,7 +11,7 @@ import { FollowService } from '../shared'
|
||||||
templateUrl: './followers-list.component.html',
|
templateUrl: './followers-list.component.html',
|
||||||
styleUrls: [ './followers-list.component.scss' ]
|
styleUrls: [ './followers-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class FollowersListComponent extends RestTable {
|
export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
followers: AccountFollow[] = []
|
followers: AccountFollow[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
|
@ -25,6 +25,10 @@ export class FollowersListComponent extends RestTable {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit () {
|
||||||
|
this.loadSort()
|
||||||
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
this.followService.getFollowers(this.pagination, this.sort)
|
this.followService.getFollowers(this.pagination, this.sort)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
<p-dataTable
|
<p-table
|
||||||
[value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
<p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column>
|
<ng-template pTemplate="header">
|
||||||
<p-column field="following.host" header="Host"></p-column>
|
<tr>
|
||||||
<p-column field="state" header="State"></p-column>
|
<th style="width: 60px">ID</th>
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
<th>Host</th>
|
||||||
<p-column styleClass="action-cell">
|
<th>State</th>
|
||||||
<ng-template pTemplate="body" let-following="rowData">
|
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<my-delete-button (click)="removeFollowing(following)"></my-delete-button>
|
<th></th>
|
||||||
</ng-template>
|
</tr>
|
||||||
</p-column>
|
</ng-template>
|
||||||
</p-dataTable>
|
|
||||||
|
<ng-template pTemplate="body" let-follow>
|
||||||
|
<tr>
|
||||||
|
<td>{{ follow.id }}</td>
|
||||||
|
<td>{{ follow.following.host }}</td>
|
||||||
|
<td>{{ follow.state }}</td>
|
||||||
|
<td>{{ follow.createdAt }}</td>
|
||||||
|
<td class="action-cell">
|
||||||
|
<my-delete-button (click)="removeFollowing(follow)"></my-delete-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
import { SortMeta } from 'primeng/primeng'
|
import { SortMeta } from 'primeng/primeng'
|
||||||
import { AccountFollow } from '../../../../../../shared/models/actors/follow.model'
|
import { AccountFollow } from '../../../../../../shared/models/actors/follow.model'
|
||||||
|
@ -10,7 +10,7 @@ import { FollowService } from '../shared'
|
||||||
selector: 'my-followers-list',
|
selector: 'my-followers-list',
|
||||||
templateUrl: './following-list.component.html'
|
templateUrl: './following-list.component.html'
|
||||||
})
|
})
|
||||||
export class FollowingListComponent extends RestTable {
|
export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
following: AccountFollow[] = []
|
following: AccountFollow[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
|
@ -25,6 +25,10 @@ export class FollowingListComponent extends RestTable {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit () {
|
||||||
|
this.loadSort()
|
||||||
|
}
|
||||||
|
|
||||||
async removeFollowing (follow: AccountFollow) {
|
async removeFollowing (follow: AccountFollow) {
|
||||||
const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow')
|
const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow')
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
|
@ -8,20 +8,42 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p-table
|
||||||
|
[value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" dataKey="id"
|
||||||
<p-dataTable
|
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
|
||||||
[value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
|
||||||
sortField="createdAt" (onLazyLoad)="loadLazy($event)" [scrollable]="true" [virtualScroll]="true" [scrollHeight]="scrollHeight"
|
|
||||||
>
|
>
|
||||||
<p-column field="id" header="ID" [style]="{ width: '60px' }"></p-column>
|
<ng-template pTemplate="header">
|
||||||
<p-column field="type" header="Type" [style]="{ width: '210px' }"></p-column>
|
<tr>
|
||||||
<p-column field="state" header="State" [style]="{ width: '130px' }"></p-column>
|
<th style="width: 27px"></th>
|
||||||
<p-column header="Payload">
|
<th style="width: 60px">ID</th>
|
||||||
<ng-template pTemplate="body" let-job="rowData">
|
<th style="width: 210px">Type</th>
|
||||||
<pre>{{ job.data }}</pre>
|
<th style="width: 130px">State</th>
|
||||||
</ng-template>
|
<th style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
</p-column>
|
<th style="width: 250px">Updated</th>
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true" [style]="{ width: '250px' }"></p-column>
|
</tr>
|
||||||
<p-column field="updatedAt" header="Updated date" [style]="{ width: '250px' }"></p-column>
|
</ng-template>
|
||||||
</p-dataTable>
|
|
||||||
|
<ng-template pTemplate="body" let-expanded="expanded" let-job>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span class="expander" [pRowToggler]="job">
|
||||||
|
<i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>{{ job.id }}</td>
|
||||||
|
<td>{{ job.type }}</td>
|
||||||
|
<td>{{ job.state }}</td>
|
||||||
|
<td>{{ job.createdAt }}</td>
|
||||||
|
<td>{{ job.updatedAt }}</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="rowexpansion" let-job>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6">
|
||||||
|
<pre>{{ job.data }}</pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,13 @@ import { RestExtractor } from '../../../shared/rest/rest-extractor.service'
|
||||||
styleUrls: [ './jobs-list.component.scss' ]
|
styleUrls: [ './jobs-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class JobsListComponent extends RestTable implements OnInit {
|
export class JobsListComponent extends RestTable implements OnInit {
|
||||||
|
private static JOB_STATE_LOCAL_STORAGE_STATE = 'jobs-list-state'
|
||||||
|
|
||||||
jobState: JobState = 'inactive'
|
jobState: JobState = 'inactive'
|
||||||
jobStates: JobState[] = [ 'active', 'complete', 'failed', 'inactive', 'delayed' ]
|
jobStates: JobState[] = [ 'active', 'complete', 'failed', 'inactive', 'delayed' ]
|
||||||
jobs: Job[] = []
|
jobs: Job[] = []
|
||||||
totalRecords = 0
|
totalRecords: number
|
||||||
rowsPerPage = 20
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
scrollHeight = ''
|
scrollHeight = ''
|
||||||
|
@ -32,12 +34,16 @@ export class JobsListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
// 270 -> headers + footer...
|
// 380 -> headers + footer...
|
||||||
this.scrollHeight = (viewportHeight() - 380) + 'px'
|
this.scrollHeight = (viewportHeight() - 380) + 'px'
|
||||||
|
|
||||||
|
this.loadJobState()
|
||||||
|
this.loadSort()
|
||||||
}
|
}
|
||||||
|
|
||||||
onJobStateChanged () {
|
onJobStateChanged () {
|
||||||
this.loadData()
|
this.loadData()
|
||||||
|
this.saveJobState()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
|
@ -52,4 +58,14 @@ export class JobsListComponent extends RestTable implements OnInit {
|
||||||
err => this.notificationsService.error('Error', err.message)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,20 +7,32 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p-dataTable
|
<p-table
|
||||||
[value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
sortField="id" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
<p-column field="id" header="ID" [sortable]="true" [style]="{ width: '60px' }"></p-column>
|
<ng-template pTemplate="header">
|
||||||
<p-column field="username" header="Username" [sortable]="true"></p-column>
|
<tr>
|
||||||
<p-column field="email" header="Email"></p-column>
|
<th pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th>
|
||||||
<p-column field="videoQuota" header="Video quota"></p-column>
|
<th>Email</th>
|
||||||
<p-column field="roleLabel" header="Role"></p-column>
|
<th>Video quota</th>
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
<th>Role</th>
|
||||||
<p-column styleClass="action-cell">
|
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<ng-template pTemplate="body" let-user="rowData">
|
<th></th>
|
||||||
<my-edit-button [routerLink]="getRouterUserEditLink(user)"></my-edit-button>
|
</tr>
|
||||||
<my-delete-button (click)="removeUser(user)"></my-delete-button>
|
</ng-template>
|
||||||
</ng-template>
|
|
||||||
</p-column>
|
<ng-template pTemplate="body" let-user>
|
||||||
</p-dataTable>
|
<tr>
|
||||||
|
<td>{{ user.username }}</td>
|
||||||
|
<td>{{ user.email }}</td>
|
||||||
|
<td>{{ user.videoQuota }}</td>
|
||||||
|
<td>{{ user.roleLabel }}</td>
|
||||||
|
<td>{{ user.createdAt }}</td>
|
||||||
|
<td class="action-cell">
|
||||||
|
<my-edit-button [routerLink]="getRouterUserEditLink(user)"></my-edit-button>
|
||||||
|
<my-delete-button (click)="removeUser(user)"></my-delete-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
|
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
import { SortMeta } from 'primeng/components/common/sortmeta'
|
import { SortMeta } from 'primeng/components/common/sortmeta'
|
||||||
|
@ -12,11 +12,11 @@ import { UserService } from '../shared'
|
||||||
templateUrl: './user-list.component.html',
|
templateUrl: './user-list.component.html',
|
||||||
styleUrls: [ './user-list.component.scss' ]
|
styleUrls: [ './user-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class UserListComponent extends RestTable {
|
export class UserListComponent extends RestTable implements OnInit {
|
||||||
users: User[] = []
|
users: User[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'id', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@ -27,6 +27,10 @@ export class UserListComponent extends RestTable {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit () {
|
||||||
|
this.loadSort()
|
||||||
|
}
|
||||||
|
|
||||||
async removeUser (user: User) {
|
async removeUser (user: User) {
|
||||||
if (user.username === 'root') {
|
if (user.username === 'root') {
|
||||||
this.notificationsService.error('Error', 'You cannot delete root.')
|
this.notificationsService.error('Error', 'You cannot delete root.')
|
||||||
|
|
|
@ -2,18 +2,27 @@
|
||||||
<div class="admin-sub-title">Video abuses list</div>
|
<div class="admin-sub-title">Video abuses list</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p-dataTable
|
<p-table
|
||||||
[value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
sortField="id" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
<p-column field="id" header="ID" [sortable]="true" [style]="{ width: '60px' }"></p-column>
|
<ng-template pTemplate="header">
|
||||||
<p-column field="reason" header="Reason"></p-column>
|
<tr>
|
||||||
<p-column field="reporterServerHost" header="Reporter server host"></p-column>
|
<th>Reason</th>
|
||||||
<p-column field="reporterUsername" header="Reporter username"></p-column>
|
<th>Reporter</th>
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<p-column header="Video">
|
<th>Video</th>
|
||||||
<ng-template pTemplate="body" let-videoAbuse="rowData">
|
</tr>
|
||||||
<a [routerLink]="getRouterVideoLink(videoAbuse.videoId)" title="Go to the video">{{ videoAbuse.videoName }}</a>
|
</ng-template>
|
||||||
</ng-template>
|
|
||||||
</p-column>
|
<ng-template pTemplate="body" let-videoAbuse>
|
||||||
</p-dataTable>
|
<tr>
|
||||||
|
<td>{{ videoAbuse.reason }}</td>
|
||||||
|
<td>{{ videoAbuse.reporterServerHost + '@' + videoAbuse.reporterUsername }}</td>
|
||||||
|
<td>{{ videoAbuse.createdAt }}</td>
|
||||||
|
<td>
|
||||||
|
<a [routerLink]="getRouterVideoLink(videoAbuse.videoUUID)" title="Go to the video">{{ videoAbuse.videoName }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
|
@ -15,7 +15,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
||||||
videoAbuses: VideoAbuse[] = []
|
videoAbuses: VideoAbuse[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'id', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@ -26,11 +26,11 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.loadData()
|
this.loadSort()
|
||||||
}
|
}
|
||||||
|
|
||||||
getRouterVideoLink (videoId: number) {
|
getRouterVideoLink (videoUUID: string) {
|
||||||
return [ '/videos', videoId ]
|
return [ '/videos', videoUUID ]
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
|
|
|
@ -1,23 +1,35 @@
|
||||||
<div class="row">
|
<div class="admin-sub-header">
|
||||||
<div class="content-padding">
|
<div class="admin-sub-title">Blacklisted videos</div>
|
||||||
<h3>Blacklisted videos</h3>
|
|
||||||
|
|
||||||
<p-dataTable
|
|
||||||
[value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
|
||||||
sortField="id" (onLazyLoad)="loadLazy($event)"
|
|
||||||
>
|
|
||||||
<p-column field="id" header="ID" [sortable]="true"></p-column>
|
|
||||||
<p-column field="name" header="Name" [sortable]="true"></p-column>
|
|
||||||
<p-column field="description" header="Description"></p-column>
|
|
||||||
<p-column field="views" header="Views" [sortable]="true"></p-column>
|
|
||||||
<p-column field="nsfw" header="NSFW"></p-column>
|
|
||||||
<p-column field="uuid" header="UUID" [sortable]="true"></p-column>
|
|
||||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
|
||||||
<p-column header="Delete" styleClass="action-cell">
|
|
||||||
<ng-template pTemplate="body" let-entry="rowData">
|
|
||||||
<my-delete-button (click)="removeVideoFromBlacklist(entry)"></my-delete-button>
|
|
||||||
</ng-template>
|
|
||||||
</p-column>
|
|
||||||
</p-dataTable>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p-table
|
||||||
|
[value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
|
>
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th>
|
||||||
|
<th>NSFW</th>
|
||||||
|
<th>UUID</th>
|
||||||
|
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-videoBlacklist>
|
||||||
|
<tr>
|
||||||
|
<td>{{ videoBlacklist.name }}</td>
|
||||||
|
<td>{{ videoBlacklist.description }}</td>
|
||||||
|
<td>{{ videoBlacklist.views }}</td>
|
||||||
|
<td>{{ videoBlacklist.nsfw }}</td>
|
||||||
|
<td>{{ videoBlacklist.uuid }}</td>
|
||||||
|
<td>{{ videoBlacklist.createdAt }}</td>
|
||||||
|
<td class="action-cell">
|
||||||
|
<my-delete-button label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
blacklist: BlacklistedVideo[] = []
|
blacklist: BlacklistedVideo[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPage = 10
|
||||||
sort: SortMeta = { field: 'id', order: 1 }
|
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@ -28,13 +28,13 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.loadData()
|
this.loadSort()
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeVideoFromBlacklist (entry: BlacklistedVideo) {
|
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
|
if (res === false) return
|
||||||
|
|
||||||
this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe(
|
this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<span class="action-button action-button-delete" >
|
<span class="action-button action-button-delete" >
|
||||||
<span class="icon icon-delete-grey"></span>
|
<span class="icon icon-delete-grey"></span>
|
||||||
Delete
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-delete-button',
|
selector: 'my-delete-button',
|
||||||
|
@ -7,4 +7,5 @@ import { Component } from '@angular/core'
|
||||||
})
|
})
|
||||||
|
|
||||||
export class DeleteButtonComponent {
|
export class DeleteButtonComponent {
|
||||||
|
@Input() label = 'Delete'
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,28 @@ import { SortMeta } from 'primeng/components/common/sortmeta'
|
||||||
import { RestPagination } from './rest-pagination'
|
import { RestPagination } from './rest-pagination'
|
||||||
|
|
||||||
export abstract class RestTable {
|
export abstract class RestTable {
|
||||||
|
|
||||||
abstract totalRecords: number
|
abstract totalRecords: number
|
||||||
abstract rowsPerPage: number
|
abstract rowsPerPage: number
|
||||||
abstract sort: SortMeta
|
abstract sort: SortMeta
|
||||||
abstract pagination: RestPagination
|
abstract pagination: RestPagination
|
||||||
|
|
||||||
|
private sortLocalStorageKey = 'rest-table-sort-' + this.constructor.name
|
||||||
|
|
||||||
protected abstract loadData (): void
|
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) {
|
loadLazy (event: LazyLoadEvent) {
|
||||||
this.sort = {
|
this.sort = {
|
||||||
order: event.sortOrder,
|
order: event.sortOrder,
|
||||||
|
@ -23,6 +38,11 @@ export abstract class RestTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadData()
|
this.loadData()
|
||||||
|
this.saveSort()
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSort () {
|
||||||
|
localStorage.setItem(this.sortLocalStorageKey, JSON.stringify(this.sort))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,21 +131,9 @@ label {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ngprime data table customizations
|
// ngprime data table customizations
|
||||||
p-datatable {
|
p-table {
|
||||||
font-size: 15px !important;
|
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 {
|
td {
|
||||||
border: 1px solid #E5E5E5 !important;
|
border: 1px solid #E5E5E5 !important;
|
||||||
padding-left: 15px !important;
|
padding-left: 15px !important;
|
||||||
|
@ -157,23 +145,33 @@ p-datatable {
|
||||||
tr {
|
tr {
|
||||||
background-color: #fff !important;
|
background-color: #fff !important;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
.ui-table-tbody {
|
||||||
background-color: #f0f0f0 !important;
|
tr {
|
||||||
}
|
&:hover {
|
||||||
|
background-color: #f0f0f0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:not(:hover) {
|
&:not(:hover) {
|
||||||
.action-cell * {
|
.action-cell * {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child td {
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child td {
|
||||||
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-child td {
|
.expander {
|
||||||
border-top: none !important;
|
cursor: pointer;
|
||||||
}
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
&:last-child td {
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +193,7 @@ p-datatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.ui-state-active {
|
&.ui-state-highlight {
|
||||||
background-color: #fff !important;
|
background-color: #fff !important;
|
||||||
|
|
||||||
.fa {
|
.fa {
|
||||||
|
|
Loading…
Reference in New Issue