diff options
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 @@ | |||
1 | import { Component } from '@angular/core' | 1 | import { Component } from '@angular/core' |
2 | import { UserRight } from '../../../../shared' | ||
3 | import { 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 | }) |
6 | export class AdminComponent { | 9 | export 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 | |||
5 | tabset /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 | |||
5 | input:not([type=submit]) { | ||
6 | @include peertube-input-text(340px); | ||
7 | display: block; | ||
8 | } | ||
9 | |||
10 | select { | ||
11 | @include peertube-select(340px); | ||
12 | } | ||
13 | |||
14 | input[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' | |||
20 | import { SignupModule } from './signup' | 20 | import { SignupModule } from './signup' |
21 | import { SharedModule } from './shared' | 21 | import { SharedModule } from './shared' |
22 | import { VideosModule } from './videos' | 22 | import { VideosModule } from './videos' |
23 | import { MenuComponent, MenuAdminComponent } from './menu' | 23 | import { MenuComponent } from './menu' |
24 | import { HeaderComponent } from './header' | 24 | import { HeaderComponent } from './header' |
25 | 25 | ||
26 | export function metaFactory (): MetaLoader { | 26 | export 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 @@ | |||
1 | export * from './menu.component' | export * from './menu.component' | |
2 | export * 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 @@ | |||
1 | import { Component } from '@angular/core' | ||
2 | |||
3 | import { AuthService } from '../core/auth/auth.service' | ||
4 | import { UserRight } from '../../../../shared' | ||
5 | |||
6 | @Component({ | ||
7 | selector: 'my-menu-admin', | ||
8 | templateUrl: './menu-admin.component.html', | ||
9 | styleUrls: [ './menu.component.scss' ] | ||
10 | }) | ||
11 | export 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 |
136 | p-datatable { | 141 | p-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 () { |