aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-12-08 10:41:49 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-12-08 10:41:49 +0100
commit04e0fc488826f505a8de3ce99113f3cb2fcec147 (patch)
tree92cfb91ebfd284735026433abd54e4fd560bda41
parent18327bdf51ff534136d06906ba5c1f228718c371 (diff)
downloadPeerTube-04e0fc488826f505a8de3ce99113f3cb2fcec147.tar.gz
PeerTube-04e0fc488826f505a8de3ce99113f3cb2fcec147.tar.zst
PeerTube-04e0fc488826f505a8de3ce99113f3cb2fcec147.zip
Begin admin design
-rw-r--r--client/src/app/+admin/admin.component.html27
-rw-r--r--client/src/app/+admin/admin.component.scss0
-rw-r--r--client/src/app/+admin/admin.component.ts26
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.html26
-rw-r--r--client/src/app/+admin/follows/following-add/following-add.component.html53
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.html34
-rw-r--r--client/src/app/+admin/follows/follows.component.scss18
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.component.html123
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.component.scss18
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html63
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.scss22
-rw-r--r--client/src/app/app.component.html3
-rw-r--r--client/src/app/app.module.ts3
-rw-r--r--client/src/app/header/header.component.scss7
-rw-r--r--client/src/app/menu/index.ts1
-rw-r--r--client/src/app/menu/menu-admin.component.html35
-rw-r--r--client/src/app/menu/menu-admin.component.ts33
-rw-r--r--client/src/app/videos/+video-edit/shared/video-description.component.scss34
-rw-r--r--client/src/assets/images/admin/add.svg13
-rw-r--r--client/src/sass/application.scss42
-rw-r--r--server/tests/api/users.ts4
21 files changed, 290 insertions, 295 deletions
diff --git a/client/src/app/+admin/admin.component.html b/client/src/app/+admin/admin.component.html
new file mode 100644
index 000000000..0bf4c8aac
--- /dev/null
+++ b/client/src/app/+admin/admin.component.html
@@ -0,0 +1,27 @@
1<div class="row">
2 <div class="sub-menu">
3 <a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page">
4 Users
5 </a>
6
7 <a *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page">
8 Manage follows
9 </a>
10
11 <a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active" class="title-page">
12 Video abuses
13 </a>
14
15 <a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active" class="title-page">
16 Video blacklist
17 </a>
18
19 <a *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active" class="title-page">
20 Jobs
21 </a>
22 </div>
23
24 <div class="margin-content">
25 <router-outlet></router-outlet>
26 </div>
27</div>
diff --git a/client/src/app/+admin/admin.component.scss b/client/src/app/+admin/admin.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/client/src/app/+admin/admin.component.scss
diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts
index ecd62ee61..75cd50cc7 100644
--- a/client/src/app/+admin/admin.component.ts
+++ b/client/src/app/+admin/admin.component.ts
@@ -1,7 +1,31 @@
1import { Component } from '@angular/core' 1import { Component } from '@angular/core'
2import { UserRight } from '../../../../shared'
3import { AuthService } from '../core/auth/auth.service'
2 4
3@Component({ 5@Component({
4 template: '<router-outlet></router-outlet>' 6 templateUrl: './admin.component.html',
7 styleUrls: [ './admin.component.scss' ]
5}) 8})
6export class AdminComponent { 9export class AdminComponent {
10 constructor (private auth: AuthService) {}
11
12 hasUsersRight () {
13 return this.auth.getUser().hasRight(UserRight.MANAGE_USERS)
14 }
15
16 hasServerFollowRight () {
17 return this.auth.getUser().hasRight(UserRight.MANAGE_SERVER_FOLLOW)
18 }
19
20 hasVideoAbusesRight () {
21 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES)
22 }
23
24 hasVideoBlacklistRight () {
25 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)
26 }
27
28 hasJobsRight () {
29 return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS)
30 }
7} 31}
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 473801822..ea5380ff7 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,16 +1,12 @@
1<div class="row"> 1<h3>Followers list</h3>
2 <div class="content-padding">
3 <h3>Followers list</h3>
4 2
5 <p-dataTable 3<p-dataTable
6 [value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 4 [value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 sortField="createdAt" (onLazyLoad)="loadLazy($event)" 5 sortField="createdAt" (onLazyLoad)="loadLazy($event)"
8 > 6>
9 <p-column field="id" header="ID"></p-column> 7 <p-column field="id" header="ID"></p-column>
10 <p-column field="follower.host" header="Host"></p-column> 8 <p-column field="follower.host" header="Host"></p-column>
11 <p-column field="follower.score" header="Score"></p-column> 9 <p-column field="follower.score" header="Score"></p-column>
12 <p-column field="state" header="State"></p-column> 10 <p-column field="state" header="State"></p-column>
13 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 11 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
14 </p-dataTable> 12</p-dataTable>
15 </div>
16</div>
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.html b/client/src/app/+admin/follows/following-add/following-add.component.html
index 8e7dddc11..65c1eda0c 100644
--- a/client/src/app/+admin/follows/following-add/following-add.component.html
+++ b/client/src/app/+admin/follows/following-add/following-add.component.html
@@ -1,35 +1,30 @@
1<div class="row"> 1<h3>Add following</h3>
2 <div class="content-padding">
3 2
4 <h3>Add following</h3> 3<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
5 4
6 <div *ngIf="error" class="alert alert-danger">{{ error }}</div> 5<form (ngSubmit)="addFollowing()" [formGroup]="form">
6 <div class="form-group" *ngFor="let host of hosts; let id = index; trackBy:customTrackBy">
7 <label [for]="'host-' + id">Host (so without "http://")</label>
7 8
8 <form (ngSubmit)="addFollowing()" [formGroup]="form"> 9 <div class="input-group">
9 <div class="form-group" *ngFor="let host of hosts; let id = index; trackBy:customTrackBy"> 10 <input
10 <label [for]="'host-' + id">Host (so without "http://")</label> 11 type="text" class="form-control" placeholder="example.com"
12 [id]="'host-' + id" [formControlName]="'host-' + id"
13 />
14 <span class="input-group-btn">
15 <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
16 <button *ngIf="displayRemoveField(id)" (click)="removeField(id)" class="btn btn-default" type="button">-</button>
17 </span>
18 </div>
11 19
12 <div class="input-group"> 20 <div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning">
13 <input 21 It should be a valid host.
14 type="text" class="form-control" placeholder="example.com" 22 </div>
15 [id]="'host-' + id" [formControlName]="'host-' + id" 23 </div>
16 />
17 <span class="input-group-btn">
18 <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
19 <button *ngIf="displayRemoveField(id)" (click)="removeField(id)" class="btn btn-default" type="button">-</button>
20 </span>
21 </div>
22
23 <div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning">
24 It should be a valid host.
25 </div>
26 </div>
27
28 <div *ngIf="canMakeFriends() === false" class="alert alert-warning">
29 It seems that you are not on a HTTPS server. Your webserver need to have TLS activated in order to follow servers.
30 </div>
31 24
32 <input type="submit" value="Add following" class="btn btn-default" [disabled]="!isFormValid()"> 25 <div *ngIf="canMakeFriends() === false" class="alert alert-warning">
33 </form> 26 It seems that you are not on a HTTPS server. Your webserver need to have TLS activated in order to follow servers.
34 </div> 27 </div>
35</div> 28
29 <input type="submit" value="Add following" class="btn btn-default" [disabled]="!isFormValid()">
30</form>
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 a73084312..85c7c3af1 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,20 +1,16 @@
1<div class="row"> 1<h3>Following list</h3>
2 <div class="content-padding">
3 <h3>Following list</h3>
4 2
5 <p-dataTable 3<p-dataTable
6 [value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 4 [value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 sortField="createdAt" (onLazyLoad)="loadLazy($event)" 5 sortField="createdAt" (onLazyLoad)="loadLazy($event)"
8 > 6>
9 <p-column field="id" header="ID"></p-column> 7 <p-column field="id" header="ID"></p-column>
10 <p-column field="following.host" header="Host"></p-column> 8 <p-column field="following.host" header="Host"></p-column>
11 <p-column field="state" header="State"></p-column> 9 <p-column field="state" header="State"></p-column>
12 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column> 10 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
13 <p-column header="Unfollow" styleClass="action-cell"> 11 <p-column header="Unfollow" styleClass="action-cell">
14 <ng-template pTemplate="body" let-following="rowData"> 12 <ng-template pTemplate="body" let-following="rowData">
15 <span (click)="removeFollowing(following)" class="glyphicon glyphicon-remove glyphicon-black" title="Unfollow"></span> 13 <span (click)="removeFollowing(following)" class="glyphicon glyphicon-remove glyphicon-black" title="Unfollow"></span>
16 </ng-template> 14 </ng-template>
17 </p-column> 15 </p-column>
18 </p-dataTable> 16</p-dataTable>
19 </div>
20</div>
diff --git a/client/src/app/+admin/follows/follows.component.scss b/client/src/app/+admin/follows/follows.component.scss
index d8ab41975..242effd85 100644
--- a/client/src/app/+admin/follows/follows.component.scss
+++ b/client/src/app/+admin/follows/follows.component.scss
@@ -1,21 +1,3 @@
1.follows-menu { 1.follows-menu {
2 margin-top: 20px; 2 margin-top: 20px;
3} 3}
4
5tabset /deep/ {
6 .nav-link {
7 padding: 0;
8 }
9
10 .tab-link {
11 display: block;
12 text-align: center;
13 height: 40px;
14 width: 120px;
15 line-height: 40px;
16
17 &:hover, &:active, &:focus {
18 text-decoration: none !important;
19 }
20 }
21}
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html
index 349be13c1..ed27ea745 100644
--- a/client/src/app/+admin/users/user-edit/user-edit.component.html
+++ b/client/src/app/+admin/users/user-edit/user-edit.component.html
@@ -1,73 +1,68 @@
1<div class="row"> 1<div class="admin-sub-title" *ngIf="isCreation() === true">Add user</div>
2 <div class="content-padding"> 2<div class="admin-sub-title" *ngIf="isCreation() === false">Edit user {{ username }}</div>
3 3
4 <h3 *ngIf="isCreation() === true">Add user</h3> 4<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
5 <h3 *ngIf="isCreation() === false">Edit user {{ username }}</h3>
6 5
7 <div *ngIf="error" class="alert alert-danger">{{ error }}</div> 6<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
8 7 <div class="form-group" *ngIf="isCreation()">
9 <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> 8 <label for="username">Username</label>
10 <div class="form-group" *ngIf="isCreation()"> 9 <input
11 <label for="username">Username</label> 10 type="text" class="form-control" id="username" placeholder="john"
12 <input 11 formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }"
13 type="text" class="form-control" id="username" placeholder="john" 12 >
14 formControlName="username" 13 <div *ngIf="formErrors.username" class="form-error">
15 > 14 {{ formErrors.username }}
16 <div *ngIf="formErrors.username" class="alert alert-danger"> 15 </div>
17 {{ formErrors.username }} 16 </div>
18 </div>
19 </div>
20
21 <div class="form-group">
22 <label for="email">Email</label>
23 <input
24 type="text" class="form-control" id="email" placeholder="mail@example.com"
25 formControlName="email"
26 >
27 <div *ngIf="formErrors.email" class="alert alert-danger">
28 {{ formErrors.email }}
29 </div>
30 </div>
31 17
32 <div class="form-group" *ngIf="isCreation()"> 18 <div class="form-group">
33 <label for="password">Password</label> 19 <label for="email">Email</label>
34 <input 20 <input
35 type="password" class="form-control" id="password" 21 type="text" class="form-control" id="email" placeholder="mail@example.com"
36 formControlName="password" 22 formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }"
37 > 23 >
38 <div *ngIf="formErrors.password" class="alert alert-danger"> 24 <div *ngIf="formErrors.email" class="form-error">
39 {{ formErrors.password }} 25 {{ formErrors.email }}
40 </div> 26 </div>
41 </div> 27 </div>
42 28
43 <div class="form-group"> 29 <div class="form-group" *ngIf="isCreation()">
44 <label for="role">Role</label> 30 <label for="password">Password</label>
45 <select class="form-control" id="role" formControlName="role"> 31 <input
46 <option *ngFor="let role of roles" [value]="role.value"> 32 type="password" class="form-control" id="password"
47 {{ role.label }} 33 formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
48 </option> 34 >
49 </select> 35 <div *ngIf="formErrors.password" class="form-error">
36 {{ formErrors.password }}
37 </div>
38 </div>
50 39
51 <div *ngIf="formErrors.role" class="alert alert-danger"> 40 <div class="form-group">
52 {{ formErrors.role }} 41 <label for="role">Role</label>
53 </div> 42 <select class="form-control" id="role" formControlName="role">
54 </div> 43 <option *ngFor="let role of roles" [value]="role.value">
44 {{ role.label }}
45 </option>
46 </select>
55 47
56 <div class="form-group"> 48 <div *ngIf="formErrors.role" class="form-error">
57 <label for="videoQuota">Video quota</label> 49 {{ formErrors.role }}
58 <select class="form-control" id="videoQuota" formControlName="videoQuota"> 50 </div>
59 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> 51 </div>
60 {{ videoQuotaOption.label }}
61 </option>
62 </select>
63 52
64 <div class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()"> 53 <div class="form-group">
65 Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br /> 54 <label for="videoQuota">Video quota</label>
66 In maximum, this user could use ~ {{ computeQuotaWithTranscoding() | bytes }}. 55 <select class="form-control" id="videoQuota" formControlName="videoQuota">
67 </div> 56 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
68 </div> 57 {{ videoQuotaOption.label }}
58 </option>
59 </select>
69 60
70 <input type="submit" value="{{ getFormButtonTitle() }}" class="btn btn-default" [disabled]="!form.valid"> 61 <div class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()">
71 </form> 62 Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br />
63 In maximum, this user could use ~ {{ computeQuotaWithTranscoding() | bytes }}.
64 </div>
72 </div> 65 </div>
73</div> 66
67 <input type="submit" value="{{ getFormButtonTitle() }}" class="btn btn-default" [disabled]="!form.valid">
68</form>
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.scss b/client/src/app/+admin/users/user-edit/user-edit.component.scss
index 401caa0c6..68d270c19 100644
--- a/client/src/app/+admin/users/user-edit/user-edit.component.scss
+++ b/client/src/app/+admin/users/user-edit/user-edit.component.scss
@@ -1,3 +1,21 @@
1.admin-sub-title {
2 margin-bottom: 30px;
3}
4
5input:not([type=submit]) {
6 @include peertube-input-text(340px);
7 display: block;
8}
9
10select {
11 @include peertube-select(340px);
12}
13
14input[type=submit] {
15 @include peertube-button;
16 @include orange-button;
17}
18
1.transcoding-information { 19.transcoding-information {
2 margin-top: 5px; 20 margin-top: 5px;
3 font-size: 11px; 21 font-size: 11px;
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 16a8a8033..a100ddfaa 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
@@ -1,35 +1,32 @@
1<div class="row"> 1<div class="sub-header">
2 <div class="content-padding"> 2 <div class="admin-sub-title">Users list</div>
3 3
4 <h3>Users list</h3> 4 <a class="add-button" routerLink="/admin/users/add">
5 5 <span class="icon icon-add"></span>
6 <p-dataTable 6 Add user
7 [value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 7 </a>
8 sortField="id" (onLazyLoad)="loadLazy($event)"
9 >
10 <p-column field="id" header="ID" [sortable]="true"></p-column>
11 <p-column field="username" header="Username" [sortable]="true"></p-column>
12 <p-column field="email" header="Email"></p-column>
13 <p-column field="videoQuota" header="Video quota"></p-column>
14 <p-column field="roleLabel" header="Role"></p-column>
15 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
16 <p-column header="Edit" styleClass="action-cell">
17 <ng-template pTemplate="body" let-user="rowData">
18 <a [routerLink]="getRouterUserEditLink(user)" title="Edit this user">
19 <span class="glyphicon glyphicon-pencil glyphicon-black"></span>
20 </a>
21 </ng-template>
22 </p-column>
23 <p-column header="Delete" styleClass="action-cell">
24 <ng-template pTemplate="body" let-user="rowData">
25 <span (click)="removeUser(user)" class="glyphicon glyphicon-remove glyphicon-black" title="Remove this user"></span>
26 </ng-template>
27 </p-column>
28 </p-dataTable>
29
30 <a class="add-user btn btn-success pull-right" [routerLink]="['/admin/users/add']">
31 <span class="glyphicon glyphicon-plus"></span>
32 Add user
33 </a>
34 </div>
35</div> 8</div>
9
10<p-dataTable
11 [value]="users" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
12 sortField="id" (onLazyLoad)="loadLazy($event)"
13>
14 <p-column field="id" header="ID" [sortable]="true"></p-column>
15 <p-column field="username" header="Username" [sortable]="true"></p-column>
16 <p-column field="email" header="Email"></p-column>
17 <p-column field="videoQuota" header="Video quota"></p-column>
18 <p-column field="roleLabel" header="Role"></p-column>
19 <p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
20 <p-column header="Edit" styleClass="action-cell">
21 <ng-template pTemplate="body" let-user="rowData">
22 <a [routerLink]="getRouterUserEditLink(user)" title="Edit this user">
23 <span class="glyphicon glyphicon-pencil glyphicon-black"></span>
24 </a>
25 </ng-template>
26 </p-column>
27 <p-column header="Delete" styleClass="action-cell">
28 <ng-template pTemplate="body" let-user="rowData">
29 <span (click)="removeUser(user)" class="glyphicon glyphicon-remove glyphicon-black" title="Remove this user"></span>
30 </ng-template>
31 </p-column>
32</p-dataTable>
diff --git a/client/src/app/+admin/users/user-list/user-list.component.scss b/client/src/app/+admin/users/user-list/user-list.component.scss
index 71adef653..54ecb61b4 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.scss
+++ b/client/src/app/+admin/users/user-list/user-list.component.scss
@@ -1,3 +1,21 @@
1.add-user { 1.sub-header {
2 margin-top: 10px; 2 display: flex;
3 align-items: center;
4 margin-bottom: 30px;
5
6 .admin-sub-title {
7 flex-grow: 1;
8 }
9
10 .add-button {
11 @include peertube-button-link;
12 @include orange-button;
13
14 .icon.icon-add {
15 @include icon(22px);
16
17 margin-right: 3px;
18 background-image: url('../../../../assets/images/admin/add.svg');
19 }
20 }
3} 21}
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index b095e44d6..cb1f4e4ef 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -19,8 +19,7 @@
19 <div class="title-menu-left"> 19 <div class="title-menu-left">
20 20
21 <div class="title-menu-left-block menu"> 21 <div class="title-menu-left-block menu">
22 <my-menu *ngIf="isMenuDisplayed && isInAdmin() === false"></my-menu> 22 <my-menu *ngIf="isMenuDisplayed"></my-menu>
23 <my-menu-admin *ngIf="isMenuDisplayed && isInAdmin() === true"></my-menu-admin>
24 </div> 23 </div>
25 </div> 24 </div>
26 25
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index ee7cb0c8a..1326e3411 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -20,7 +20,7 @@ import { LoginModule } from './login'
20import { SignupModule } from './signup' 20import { SignupModule } from './signup'
21import { SharedModule } from './shared' 21import { SharedModule } from './shared'
22import { VideosModule } from './videos' 22import { VideosModule } from './videos'
23import { MenuComponent, MenuAdminComponent } from './menu' 23import { MenuComponent } from './menu'
24import { HeaderComponent } from './header' 24import { HeaderComponent } from './header'
25 25
26export function metaFactory (): MetaLoader { 26export function metaFactory (): MetaLoader {
@@ -52,7 +52,6 @@ const APP_PROVIDERS = [
52 AppComponent, 52 AppComponent,
53 53
54 MenuComponent, 54 MenuComponent,
55 MenuAdminComponent,
56 HeaderComponent 55 HeaderComponent
57 ], 56 ],
58 imports: [ 57 imports: [
diff --git a/client/src/app/header/header.component.scss b/client/src/app/header/header.component.scss
index d1c59e8d1..ed8695eab 100644
--- a/client/src/app/header/header.component.scss
+++ b/client/src/app/header/header.component.scss
@@ -27,10 +27,9 @@
27 margin-right: 25px; 27 margin-right: 25px;
28 28
29 .icon.icon-upload { 29 .icon.icon-upload {
30 display: inline-block; 30 @include icon(22px);
31 background: url('../../assets/images/header/upload.svg') no-repeat; 31
32 background-size: contain; 32 background-image: url('../../assets/images/header/upload.svg');
33 width: 22px;
34 height: 24px; 33 height: 24px;
35 vertical-align: middle; 34 vertical-align: middle;
36 margin-right: 6px; 35 margin-right: 6px;
diff --git a/client/src/app/menu/index.ts b/client/src/app/menu/index.ts
index c905ed20a..421271c12 100644
--- a/client/src/app/menu/index.ts
+++ b/client/src/app/menu/index.ts
@@ -1,2 +1 @@
1export * from './menu.component' export * from './menu.component'
2export * from './menu-admin.component'
diff --git a/client/src/app/menu/menu-admin.component.html b/client/src/app/menu/menu-admin.component.html
deleted file mode 100644
index 9857b2e3e..000000000
--- a/client/src/app/menu/menu-admin.component.html
+++ /dev/null
@@ -1,35 +0,0 @@
1<menu>
2 <div class="panel-block">
3 <a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active">
4 <span class="hidden-xs glyphicon glyphicon-user"></span>
5 List users
6 </a>
7
8 <a *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active">
9 <span class="hidden-xs glyphicon glyphicon-cloud"></span>
10 Manage follows
11 </a>
12
13 <a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active">
14 <span class="hidden-xs glyphicon glyphicon-alert"></span>
15 Video abuses
16 </a>
17
18 <a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active">
19 <span class="hidden-xs glyphicon glyphicon-eye-close"></span>
20 Video blacklist
21 </a>
22
23 <a *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active">
24 <span class="hidden-xs glyphicon glyphicon-tasks"></span>
25 Jobs
26 </a>
27 </div>
28
29 <div class="panel-block">
30 <a routerLink="/videos/list" routerLinkActive="active">
31 <span class="hidden-xs glyphicon glyphicon-cog"></span>
32 Quit admin.
33 </a>
34 </div>
35</menu>
diff --git a/client/src/app/menu/menu-admin.component.ts b/client/src/app/menu/menu-admin.component.ts
deleted file mode 100644
index 1babf5eb6..000000000
--- a/client/src/app/menu/menu-admin.component.ts
+++ /dev/null
@@ -1,33 +0,0 @@
1import { Component } from '@angular/core'
2
3import { AuthService } from '../core/auth/auth.service'
4import { UserRight } from '../../../../shared'
5
6@Component({
7 selector: 'my-menu-admin',
8 templateUrl: './menu-admin.component.html',
9 styleUrls: [ './menu.component.scss' ]
10})
11export class MenuAdminComponent {
12 constructor (private auth: AuthService) {}
13
14 hasUsersRight () {
15 return this.auth.getUser().hasRight(UserRight.MANAGE_USERS)
16 }
17
18 hasServerFollowRight () {
19 return this.auth.getUser().hasRight(UserRight.MANAGE_SERVER_FOLLOW)
20 }
21
22 hasVideoAbusesRight () {
23 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES)
24 }
25
26 hasVideoBlacklistRight () {
27 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)
28 }
29
30 hasJobsRight () {
31 return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS)
32 }
33}
diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.scss b/client/src/app/videos/+video-edit/shared/video-description.component.scss
index 38506bb46..8155cbca7 100644
--- a/client/src/app/videos/+video-edit/shared/video-description.component.scss
+++ b/client/src/app/videos/+video-edit/shared/video-description.component.scss
@@ -5,37 +5,3 @@ textarea {
5 font-size: 15px; 5 font-size: 15px;
6 height: 150px; 6 height: 150px;
7} 7}
8
9.previews /deep/ {
10 font-size: 15px !important;
11
12 .nav {
13 margin-top: 10px;
14 font-size: 16px !important;
15 border: none !important;
16
17 .nav-item .nav-link {
18 color: #000 !important;
19 height: 30px !important;
20 margin-right: 30px;
21 padding: 0 15px;
22 display: flex;
23 align-items: center;
24 border-radius: 3px;
25 border: none !important;
26
27 &.active, &:hover {
28 background-color: #F0F0F0;
29 }
30
31 &.active {
32 font-weight: $font-semibold !important;
33 }
34 }
35 }
36
37 .tab-content {
38 min-height: 75px;
39 padding: 15px;
40 }
41}
diff --git a/client/src/assets/images/admin/add.svg b/client/src/assets/images/admin/add.svg
new file mode 100644
index 000000000..42b269c43
--- /dev/null
+++ b/client/src/assets/images/admin/add.svg
@@ -0,0 +1,13 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs>
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5 <g id="Artboard-4" transform="translate(-92.000000, -115.000000)">
6 <g id="2" transform="translate(92.000000, 115.000000)">
7 <circle id="Oval-1" stroke="#ffffff" stroke-width="2" cx="12" cy="12" r="10"></circle>
8 <rect id="Rectangle-1" fill="#ffffff" x="11" y="7" width="2" height="10" rx="1"></rect>
9 <rect id="Rectangle-1" fill="#ffffff" x="7" y="11" width="10" height="2" rx="1"></rect>
10 </g>
11 </g>
12 </g>
13</svg>
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index 3c5a00309..e7b4024a7 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -89,7 +89,12 @@ label {
89 89
90 &:hover, &:active, &:focus { 90 &:hover, &:active, &:focus {
91 color: #000; 91 color: #000;
92 }
92} 93}
94
95.admin-sub-title {
96 font-size: 20px;
97 font-weight: bold;
93} 98}
94 99
95// On small screen, menu is absolute and displayed over the page 100// On small screen, menu is absolute and displayed over the page
@@ -132,7 +137,7 @@ label {
132 to { -moz-transform: rotate(360deg);} 137 to { -moz-transform: rotate(360deg);}
133} 138}
134 139
135/* ngprime data table customizations */ 140// ngprime data table customizations
136p-datatable { 141p-datatable {
137 .action-cell { 142 .action-cell {
138 text-align: center; 143 text-align: center;
@@ -143,6 +148,7 @@ p-datatable {
143 } 148 }
144} 149}
145 150
151// Bootstrap customizations
146.dropdown-menu { 152.dropdown-menu {
147 border-radius: 3px; 153 border-radius: 3px;
148 box-shadow: 0 3px 6px; 154 box-shadow: 0 3px 6px;
@@ -167,6 +173,40 @@ p-datatable {
167 } 173 }
168} 174}
169 175
176.nav {
177 margin-top: 10px;
178 font-size: 16px !important;
179 border: none !important;
180
181 .nav-item .nav-link {
182 height: 30px !important;
183 margin-right: 30px;
184 padding: 0 15px;
185 display: flex;
186 align-items: center;
187 border-radius: 3px;
188 border: none !important;
189
190 &, & a {
191 color: #000 !important;
192 }
193
194 &.active, &:hover {
195 background-color: #F0F0F0;
196 }
197
198 &.active {
199 font-weight: $font-semibold !important;
200 }
201 }
202
203 .tab-content {
204 min-height: 75px;
205 padding: 15px;
206 }
207}
208
209
170.orange-button { 210.orange-button {
171 @include peertube-button; 211 @include peertube-button;
172 @include orange-button; 212 @include orange-button;
diff --git a/server/tests/api/users.ts b/server/tests/api/users.ts
index 5066e73fc..b3163b1e1 100644
--- a/server/tests/api/users.ts
+++ b/server/tests/api/users.ts
@@ -113,7 +113,7 @@ describe('Test users', function () {
113 113
114 it('Should upload the video with the correct token', async function () { 114 it('Should upload the video with the correct token', async function () {
115 const videoAttributes = {} 115 const videoAttributes = {}
116 await uploadVideo(server.url, accessToken, videoAttributes, 204) 116 await uploadVideo(server.url, accessToken, videoAttributes)
117 const res = await getVideosList(server.url) 117 const res = await getVideosList(server.url)
118 const video = res.body.data[ 0 ] 118 const video = res.body.data[ 0 ]
119 119
@@ -125,7 +125,7 @@ describe('Test users', function () {
125 125
126 it('Should upload the video again with the correct token', async function () { 126 it('Should upload the video again with the correct token', async function () {
127 const videoAttributes = {} 127 const videoAttributes = {}
128 await uploadVideo(server.url, accessToken, videoAttributes, 204) 128 await uploadVideo(server.url, accessToken, videoAttributes)
129 }) 129 })
130 130
131 it('Should retrieve a video rating', async function () { 131 it('Should retrieve a video rating', async function () {