Design admin data tables
This commit is contained in:
parent
04e0fc4888
commit
cd83ea1b90
|
@ -1,18 +1,20 @@
|
|||
<div class="row">
|
||||
<div class="content-padding">
|
||||
<h3>Jobs list</h3>
|
||||
<div class="admin-sub-header">
|
||||
<div class="admin-sub-title">Jobs list</div>
|
||||
</div>
|
||||
|
||||
<p-dataTable
|
||||
[value]="jobs" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
|
||||
sortField="createdAt" (onLazyLoad)="loadLazy($event)" [scrollable]="true" [virtualScroll]="true" [scrollHeight]="scrollHeight"
|
||||
>
|
||||
<p-column field="id" header="ID"></p-column>
|
||||
<p-column field="category" header="Category"></p-column>
|
||||
<p-column field="handlerName" header="Handler name"></p-column>
|
||||
<p-column field="handlerInputData" header="Input data"></p-column>
|
||||
<p-column field="state" header="State"></p-column>
|
||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
||||
<p-column field="updatedAt" header="Updated date"></p-column>
|
||||
<p-column field="id" header="ID" [style]="{ width: '40px' }"></p-column>
|
||||
<p-column field="category" header="Category" [style]="{ width: '100px' }"></p-column>
|
||||
<p-column field="handlerName" header="Handler name" [style]="{ width: '150px' }"></p-column>
|
||||
<p-column header="Input data">
|
||||
<ng-template pTemplate="body" let-job="rowData">
|
||||
<pre>{{ job.handlerInputData }}</pre>
|
||||
</ng-template>
|
||||
</p-column>
|
||||
<p-column field="state" header="State" [style]="{ width: '100px' }"></p-column>
|
||||
<p-column field="createdAt" header="Created date" [sortable]="true" [style]="{ width: '250px' }"></p-column>
|
||||
<p-column field="updatedAt" header="Updated date" [style]="{ width: '250px' }"></p-column>
|
||||
</p-dataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
pre {
|
||||
font-size: 13px;
|
||||
}
|
|
@ -1,22 +1,24 @@
|
|||
import { Component } from '@angular/core'
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { SortMeta } from 'primeng/primeng'
|
||||
import { Job } from '../../../../../../shared/index'
|
||||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { viewportHeight } from '../../../shared/misc/utils'
|
||||
import { JobService } from '../shared'
|
||||
import { RestExtractor } from '../../../shared/rest/rest-extractor.service'
|
||||
|
||||
@Component({
|
||||
selector: 'my-jobs-list',
|
||||
templateUrl: './jobs-list.component.html',
|
||||
styleUrls: [ ]
|
||||
styleUrls: [ './jobs-list.component.scss' ]
|
||||
})
|
||||
export class JobsListComponent extends RestTable {
|
||||
export class JobsListComponent extends RestTable implements OnInit {
|
||||
jobs: Job[] = []
|
||||
totalRecords = 0
|
||||
rowsPerPage = 10
|
||||
rowsPerPage = 20
|
||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||
scrollHeight = ''
|
||||
|
||||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
|
@ -26,10 +28,14 @@ export class JobsListComponent extends RestTable {
|
|||
super()
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
// 270 -> headers + footer...
|
||||
this.scrollHeight = (viewportHeight() - 380) + 'px'
|
||||
}
|
||||
|
||||
protected loadData () {
|
||||
this.jobsService
|
||||
.getJobs(this.pagination, this.sort)
|
||||
.map(res => this.restExtractor.applyToResultListData(res, this.formatJob.bind(this)))
|
||||
.subscribe(
|
||||
resultList => {
|
||||
this.jobs = resultList.data
|
||||
|
@ -39,12 +45,4 @@ export class JobsListComponent extends RestTable {
|
|||
err => this.notificationsService.error('Error', err.message)
|
||||
)
|
||||
}
|
||||
|
||||
private formatJob (job: Job) {
|
||||
const handlerInputData = JSON.stringify(job.handlerInputData)
|
||||
|
||||
return Object.assign(job, {
|
||||
handlerInputData
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,13 @@ export class JobService {
|
|||
|
||||
return this.authHttp.get<ResultList<Job>>(JobService.BASE_JOB_URL, { params })
|
||||
.map(res => this.restExtractor.convertResultListDateToHuman(res))
|
||||
.map(res => this.restExtractor.applyToResultListData(res, this.prettyPrintData))
|
||||
.catch(err => this.restExtractor.handleError(err))
|
||||
}
|
||||
|
||||
private prettyPrintData (obj: Job) {
|
||||
const handlerInputData = JSON.stringify(obj.handlerInputData, null, 2)
|
||||
|
||||
return Object.assign(obj, { handlerInputData })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="sub-header">
|
||||
<div class="admin-sub-header">
|
||||
<div class="admin-sub-title">Users list</div>
|
||||
|
||||
<a class="add-button" routerLink="/admin/users/add">
|
||||
|
@ -17,16 +17,10 @@
|
|||
<p-column field="videoQuota" header="Video quota"></p-column>
|
||||
<p-column field="roleLabel" header="Role"></p-column>
|
||||
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
||||
<p-column header="Edit" styleClass="action-cell">
|
||||
<p-column styleClass="action-cell">
|
||||
<ng-template pTemplate="body" let-user="rowData">
|
||||
<a [routerLink]="getRouterUserEditLink(user)" title="Edit this user">
|
||||
<span class="glyphicon glyphicon-pencil glyphicon-black"></span>
|
||||
</a>
|
||||
</ng-template>
|
||||
</p-column>
|
||||
<p-column header="Delete" styleClass="action-cell">
|
||||
<ng-template pTemplate="body" let-user="rowData">
|
||||
<span (click)="removeUser(user)" class="glyphicon glyphicon-remove glyphicon-black" title="Remove this user"></span>
|
||||
<my-edit-button [routerLink]="getRouterUserEditLink(user)"></my-edit-button>
|
||||
<my-delete-button (click)="removeUser(user)"></my-delete-button>
|
||||
</ng-template>
|
||||
</p-column>
|
||||
</p-dataTable>
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
.sub-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.admin-sub-title {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.add-button {
|
||||
@include peertube-button-link;
|
||||
@include orange-button;
|
||||
|
@ -18,4 +9,3 @@
|
|||
background-image: url('../../../../assets/images/admin/add.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,9 @@
|
|||
</div>
|
||||
|
||||
<ng-template [ngIf]="isInSelectionMode() === false">
|
||||
<span class="action-button action-button-delete" (click)="deleteVideo(video)">
|
||||
<span class="icon icon-delete-grey"></span>
|
||||
Delete
|
||||
</span>
|
||||
<my-delete-button (click)="deleteVideo(video)"></my-delete-button>
|
||||
|
||||
<a class="action-button" [routerLink]="[ '/videos', 'edit', video.uuid ]">
|
||||
<span class="icon icon-edit"></span>
|
||||
Edit
|
||||
</a>
|
||||
<my-edit-button [routerLink]="[ '/videos', 'edit', video.uuid ]"></my-edit-button>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,17 +6,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.action-button {
|
||||
@include peertube-button-link;
|
||||
|
||||
font-size: 15px;
|
||||
font-weight: $font-semibold;
|
||||
color: #585858;
|
||||
background-color: #E5E5E5;
|
||||
|
||||
&:hover {
|
||||
background-color: #EFEFEF;
|
||||
}
|
||||
/deep/ .action-button {
|
||||
|
||||
&.action-button-delete {
|
||||
margin-right: 10px;
|
||||
|
@ -32,21 +22,8 @@
|
|||
}
|
||||
|
||||
.icon {
|
||||
@include icon(21px);
|
||||
|
||||
position: relative;
|
||||
top: -2px;
|
||||
|
||||
&.icon-edit {
|
||||
background-image: url('../../../assets/images/global/edit.svg');
|
||||
}
|
||||
|
||||
&.icon-delete-grey {
|
||||
background-image: url('../../../assets/images/account/delete-grey.svg');
|
||||
}
|
||||
|
||||
&.icon-delete-white {
|
||||
background-image: url('../../../assets/images/account/delete-white.svg');
|
||||
background-image: url('../../../assets/images/global/delete-white.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
.action-button {
|
||||
@include peertube-button-link;
|
||||
|
||||
font-size: 15px;
|
||||
font-weight: $font-semibold;
|
||||
color: #585858;
|
||||
background-color: #E5E5E5;
|
||||
|
||||
&:hover {
|
||||
background-color: #EFEFEF;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@include icon(21px);
|
||||
|
||||
position: relative;
|
||||
top: -2px;
|
||||
|
||||
&.icon-edit {
|
||||
background-image: url('../../../assets/images/global/edit.svg');
|
||||
}
|
||||
|
||||
&.icon-delete-grey {
|
||||
background-image: url('../../../assets/images/global/delete-grey.svg');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<span class="action-button action-button-delete" >
|
||||
<span class="icon icon-delete-grey"></span>
|
||||
Delete
|
||||
</span>
|
|
@ -0,0 +1,10 @@
|
|||
import { Component } from '@angular/core'
|
||||
|
||||
@Component({
|
||||
selector: 'my-delete-button',
|
||||
styleUrls: [ './button.component.scss' ],
|
||||
templateUrl: './delete-button.component.html'
|
||||
})
|
||||
|
||||
export class DeleteButtonComponent {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<a class="action-button" [routerLink]="routerLink">
|
||||
<span class="icon icon-edit"></span>
|
||||
Edit
|
||||
</a>
|
|
@ -0,0 +1,11 @@
|
|||
import { Component, Input } from '@angular/core'
|
||||
|
||||
@Component({
|
||||
selector: 'my-edit-button',
|
||||
styleUrls: [ './button.component.scss' ],
|
||||
templateUrl: './edit-button.component.html'
|
||||
})
|
||||
|
||||
export class EditButtonComponent {
|
||||
@Input() routerLink = []
|
||||
}
|
|
@ -13,6 +13,11 @@ function getParameterByName (name: string, url: string) {
|
|||
return decodeURIComponent(results[2].replace(/\+/g, ' '))
|
||||
}
|
||||
|
||||
function viewportHeight () {
|
||||
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
|
||||
}
|
||||
|
||||
export {
|
||||
viewportHeight,
|
||||
getParameterByName
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import { SharedModule as PrimeSharedModule } from 'primeng/components/common/sha
|
|||
import { DataTableModule } from 'primeng/components/datatable/datatable'
|
||||
|
||||
import { AUTH_INTERCEPTOR_PROVIDER } from './auth'
|
||||
import { DeleteButtonComponent } from './misc/delete-button.component'
|
||||
import { EditButtonComponent } from './misc/edit-button.component'
|
||||
import { FromNowPipe } from './misc/from-now.pipe'
|
||||
import { LoaderComponent } from './misc/loader.component'
|
||||
import { NumberFormatterPipe } from './misc/number-formatter.pipe'
|
||||
|
@ -44,6 +46,8 @@ import { VideoService } from './video/video.service'
|
|||
LoaderComponent,
|
||||
VideoThumbnailComponent,
|
||||
VideoMiniatureComponent,
|
||||
DeleteButtonComponent,
|
||||
EditButtonComponent,
|
||||
NumberFormatterPipe,
|
||||
FromNowPipe
|
||||
],
|
||||
|
@ -66,6 +70,8 @@ import { VideoService } from './video/video.service'
|
|||
LoaderComponent,
|
||||
VideoThumbnailComponent,
|
||||
VideoMiniatureComponent,
|
||||
DeleteButtonComponent,
|
||||
EditButtonComponent,
|
||||
|
||||
NumberFormatterPipe,
|
||||
FromNowPipe
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -92,6 +92,16 @@ label {
|
|||
}
|
||||
}
|
||||
|
||||
.admin-sub-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.admin-sub-title {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-sub-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
|
@ -139,11 +149,96 @@ label {
|
|||
|
||||
// ngprime data table customizations
|
||||
p-datatable {
|
||||
.action-cell {
|
||||
text-align: center;
|
||||
font-size: 15px !important;
|
||||
|
||||
.glyphicon {
|
||||
cursor: pointer;
|
||||
.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: 15px;
|
||||
}
|
||||
|
||||
tr {
|
||||
background-color: #fff !important;
|
||||
height: 46px;
|
||||
|
||||
&:hover {
|
||||
background-color: #f0f0f0 !important;
|
||||
}
|
||||
|
||||
&:not(:hover) {
|
||||
.action-cell * {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child td {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
border: none !important;
|
||||
border-bottom: 1px solid #f0f0f0 !important;
|
||||
text-align: left !important;
|
||||
padding: 5px 0 5px 15px !important;
|
||||
font-weight: $font-semibold !important;
|
||||
color: #000 !important;
|
||||
|
||||
&.ui-state-active, &.ui-sortable-column:hover {
|
||||
background-color: #f0f0f0 !important;
|
||||
border: 1px solid #f0f0f0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.action-cell {
|
||||
width: 250px !important;
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p-paginator {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
padding-top: 2px;
|
||||
border: 1px solid #f0f0f0 !important;
|
||||
border-top: none !important;
|
||||
|
||||
.ui-paginator-bottom {
|
||||
position: relative;
|
||||
border: none !important;
|
||||
border-top: 1px solid #f0f0f0 !important;
|
||||
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.16);
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
color: #000 !important;
|
||||
font-weight: $font-semibold !important;
|
||||
margin-right: 20px !important;
|
||||
outline: 0 !important;
|
||||
border-radius: 3px !important;
|
||||
padding: 5px 2px !important;
|
||||
|
||||
&.ui-state-active {
|
||||
&, &:hover, &:active, &:focus {
|
||||
color: #fff !important;
|
||||
background-color: $orange-color !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue