aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+admin')
-rw-r--r--client/src/app/+admin/admin.module.ts6
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss5
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html4
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.html14
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.scss11
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.ts6
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.html12
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.scss11
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.ts6
-rw-r--r--client/src/app/+admin/follows/follows.component.scss2
-rw-r--r--client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.scss3
-rw-r--r--client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts6
-rw-r--r--client/src/app/+admin/moderation/abuse-list/abuse-list.component.html2
-rw-r--r--client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html16
-rw-r--r--client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.scss2
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.html25
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss17
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts48
-rw-r--r--client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html27
-rw-r--r--client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss20
-rw-r--r--client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts27
-rw-r--r--client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html14
-rw-r--r--client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss2
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.html11
-rw-r--r--client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.scss3
-rw-r--r--client/src/app/+admin/plugins/plugins.component.scss28
-rw-r--r--client/src/app/+admin/plugins/plugins.component.ts3
-rw-r--r--client/src/app/+admin/plugins/shared/plugin-list.component.scss16
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.scss2
-rw-r--r--client/src/app/+admin/system/jobs/jobs.component.ts6
-rw-r--r--client/src/app/+admin/system/logs/logs.component.scss4
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.component.scss3
-rw-r--r--client/src/app/+admin/users/user-edit/user-password.component.scss2
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html27
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.scss24
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.ts25
36 files changed, 155 insertions, 285 deletions
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts
index 8d1c3eadb..45366f9ec 100644
--- a/client/src/app/+admin/admin.module.ts
+++ b/client/src/app/+admin/admin.module.ts
@@ -3,12 +3,13 @@ import { SelectButtonModule } from 'primeng/selectbutton'
3import { TableModule } from 'primeng/table' 3import { TableModule } from 'primeng/table'
4import { NgModule } from '@angular/core' 4import { NgModule } from '@angular/core'
5import { SharedAbuseListModule } from '@app/shared/shared-abuse-list' 5import { SharedAbuseListModule } from '@app/shared/shared-abuse-list'
6import { SharedActorImageModule } from '@app/shared/shared-actor-image' 6import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit'
7import { SharedFormModule } from '@app/shared/shared-forms' 7import { SharedFormModule } from '@app/shared/shared-forms'
8import { SharedGlobalIconModule } from '@app/shared/shared-icons' 8import { SharedGlobalIconModule } from '@app/shared/shared-icons'
9import { SharedMainModule } from '@app/shared/shared-main' 9import { SharedMainModule } from '@app/shared/shared-main'
10import { SharedModerationModule } from '@app/shared/shared-moderation' 10import { SharedModerationModule } from '@app/shared/shared-moderation'
11import { SharedVideoCommentModule } from '@app/shared/shared-video-comment' 11import { SharedVideoCommentModule } from '@app/shared/shared-video-comment'
12import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module'
12import { AdminRoutingModule } from './admin-routing.module' 13import { AdminRoutingModule } from './admin-routing.module'
13import { AdminComponent } from './admin.component' 14import { AdminComponent } from './admin.component'
14import { 15import {
@@ -39,7 +40,6 @@ import { JobService, LogsComponent, LogsService, SystemComponent } from './syste
39import { DebugComponent, DebugService } from './system/debug' 40import { DebugComponent, DebugService } from './system/debug'
40import { JobsComponent } from './system/jobs/jobs.component' 41import { JobsComponent } from './system/jobs/jobs.component'
41import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users' 42import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersComponent, UserUpdateComponent } from './users'
42import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/shared-account-avatar.module'
43 43
44@NgModule({ 44@NgModule({
45 imports: [ 45 imports: [
@@ -51,8 +51,8 @@ import { SharedAccountAvatarModule } from '../shared/shared-account-avatar/share
51 SharedGlobalIconModule, 51 SharedGlobalIconModule,
52 SharedAbuseListModule, 52 SharedAbuseListModule,
53 SharedVideoCommentModule, 53 SharedVideoCommentModule,
54 SharedAccountAvatarModule,
55 SharedActorImageModule, 54 SharedActorImageModule,
55 SharedActorImageEditModule,
56 56
57 TableModule, 57 TableModule,
58 SelectButtonModule, 58 SelectButtonModule,
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
index c12465d45..cc2a98a17 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
@@ -57,7 +57,7 @@ input[type=submit] {
57 display: flex; 57 display: flex;
58 margin-left: auto; 58 margin-left: auto;
59 59
60 & + .form-error { 60 + .form-error {
61 display: inline; 61 display: inline;
62 margin-left: 5px; 62 margin-left: 5px;
63 } 63 }
@@ -84,7 +84,8 @@ textarea {
84} 84}
85 85
86.disabled-checkbox-extra { 86.disabled-checkbox-extra {
87 &, ::ng-deep label { 87 &,
88 ::ng-deep label {
88 opacity: .5; 89 opacity: .5;
89 pointer-events: none; 90 pointer-events: none;
90 } 91 }
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html b/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html
index 35b42e742..cbff26e5a 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-instance-information.component.html
@@ -104,7 +104,7 @@
104 <my-help> 104 <my-help>
105 <ng-template ptTemplate="customHtml"> 105 <ng-template ptTemplate="customHtml">
106 <ng-container i18n> 106 <ng-container i18n>
107 With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video. 107 With <strong>Hide</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video.
108 </ng-container> 108 </ng-container>
109 </ng-template> 109 </ng-template>
110 </my-help> 110 </my-help>
@@ -112,7 +112,7 @@
112 <div class="peertube-select-container"> 112 <div class="peertube-select-container">
113 <select id="instanceDefaultNSFWPolicy" formControlName="defaultNSFWPolicy" class="form-control"> 113 <select id="instanceDefaultNSFWPolicy" formControlName="defaultNSFWPolicy" class="form-control">
114 <option i18n value="undefined" disabled>Policy for sensitive videos</option> 114 <option i18n value="undefined" disabled>Policy for sensitive videos</option>
115 <option i18n value="do_not_list">Do not list</option> 115 <option i18n value="do_not_list">Hide</option>
116 <option i18n value="blur">Blur thumbnails</option> 116 <option i18n value="blur">Blur thumbnails</option>
117 <option i18n value="display">Display</option> 117 <option i18n value="display">Display</option>
118 </select> 118 </select>
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 633de9677..c2e9a4df6 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
@@ -4,20 +4,16 @@
4</h1> 4</h1>
5 5
6<p-table 6<p-table
7 [value]="followers" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 7 [value]="followers" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
8 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)" 8 [sortField]="sort.field" [sortOrder]="sort.order" (onPage)="onPage($event)"
9 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
9 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
10 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers" 11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers"
11> 12>
12 <ng-template pTemplate="caption"> 13 <ng-template pTemplate="caption">
13 <div class="caption"> 14 <div class="caption">
14 <div class="ml-auto has-feedback has-clear"> 15 <div class="ml-auto">
15 <input 16 <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
16 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
17 (keyup)="onSearch($event)"
18 >
19 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
20 <span class="sr-only" i18n>Clear filters</span>
21 </div> 17 </div>
22 </div> 18 </div>
23 </ng-template> 19 </ng-template>
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.scss b/client/src/app/+admin/follows/followers-list/followers-list.component.scss
index f2d752eb5..35f38aae0 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.scss
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.scss
@@ -1,19 +1,12 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.caption {
5 justify-content: flex-end;
6
7 input {
8 @include peertube-input-text(250px);
9 }
10}
11
12a { 4a {
13 @include disable-default-a-behaviour; 5 @include disable-default-a-behaviour;
14 display: inline-block; 6 display: inline-block;
15 7
16 &, &:hover { 8 &,
9 &:hover {
17 color: pvar(--mainForegroundColor); 10 color: pvar(--mainForegroundColor);
18 } 11 }
19 12
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
index 904e3c338..4a312f6aa 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
@@ -59,7 +59,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
59 const handle = follow.follower.name + '@' + follow.follower.host 59 const handle = follow.follower.name + '@' + follow.follower.host
60 this.notifier.success($localize`${handle} rejected from instance followers`) 60 this.notifier.success($localize`${handle} rejected from instance followers`)
61 61
62 this.loadData() 62 this.reloadData()
63 }, 63 },
64 64
65 err => { 65 err => {
@@ -80,14 +80,14 @@ export class FollowersListComponent extends RestTable implements OnInit {
80 const handle = follow.follower.name + '@' + follow.follower.host 80 const handle = follow.follower.name + '@' + follow.follower.host
81 this.notifier.success($localize`${handle} removed from instance followers`) 81 this.notifier.success($localize`${handle} removed from instance followers`)
82 82
83 this.loadData() 83 this.reloadData()
84 }, 84 },
85 85
86 err => this.notifier.error(err.message) 86 err => this.notifier.error(err.message)
87 ) 87 )
88 } 88 }
89 89
90 protected loadData () { 90 protected reloadData () {
91 this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search }) 91 this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search })
92 .subscribe( 92 .subscribe(
93 resultList => { 93 resultList => {
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 f4e6a60fe..e7c0c9088 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
@@ -4,8 +4,9 @@
4</h1> 4</h1>
5 5
6<p-table 6<p-table
7 [value]="following" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 7 [value]="following" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
8 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)" 8 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)"
9 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
9 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
10 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts" 11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts"
11> 12>
@@ -18,13 +19,8 @@
18 </a> 19 </a>
19 </div> 20 </div>
20 21
21 <div class="ml-auto has-feedback has-clear"> 22 <div class="ml-auto">
22 <input 23 <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
23 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
24 (keyup)="onSearch($event)"
25 >
26 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
27 <span class="sr-only" i18n>Clear filters</span>
28 </div> 24 </div>
29 </div> 25 </div>
30 </ng-template> 26 </ng-template>
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.scss b/client/src/app/+admin/follows/following-list/following-list.component.scss
index b108218b8..9474b0a23 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.scss
+++ b/client/src/app/+admin/follows/following-list/following-list.component.scss
@@ -5,7 +5,8 @@ a {
5 @include disable-default-a-behaviour; 5 @include disable-default-a-behaviour;
6 display: inline-block; 6 display: inline-block;
7 7
8 &, &:hover { 8 &,
9 &:hover {
9 color: pvar(--mainForegroundColor); 10 color: pvar(--mainForegroundColor);
10 } 11 }
11 12
@@ -15,14 +16,6 @@ a {
15 } 16 }
16} 17}
17 18
18.caption {
19 justify-content: flex-end;
20
21 input {
22 @include peertube-input-text(250px);
23 }
24}
25
26.follow-button { 19.follow-button {
27 @include create-button; 20 @include create-button;
28} 21}
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts
index f34490cc8..b63fe08c0 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.ts
+++ b/client/src/app/+admin/follows/following-list/following-list.component.ts
@@ -45,7 +45,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
45 this.followService.follow(hosts).subscribe( 45 this.followService.follow(hosts).subscribe(
46 () => { 46 () => {
47 this.notifier.success($localize`Follow request(s) sent!`) 47 this.notifier.success($localize`Follow request(s) sent!`)
48 this.loadData() 48 this.reloadData()
49 }, 49 },
50 50
51 err => this.notifier.error(err.message) 51 err => this.notifier.error(err.message)
@@ -62,14 +62,14 @@ export class FollowingListComponent extends RestTable implements OnInit {
62 this.followService.unfollow(follow).subscribe( 62 this.followService.unfollow(follow).subscribe(
63 () => { 63 () => {
64 this.notifier.success($localize`You are not following ${follow.following.host} anymore.`) 64 this.notifier.success($localize`You are not following ${follow.following.host} anymore.`)
65 this.loadData() 65 this.reloadData()
66 }, 66 },
67 67
68 err => this.notifier.error(err.message) 68 err => this.notifier.error(err.message)
69 ) 69 )
70 } 70 }
71 71
72 protected loadData () { 72 protected reloadData () {
73 this.followService.getFollowing({ pagination: this.pagination, sort: this.sort, search: this.search }) 73 this.followService.getFollowing({ pagination: this.pagination, sort: this.sort, search: this.search })
74 .subscribe( 74 .subscribe(
75 resultList => { 75 resultList => {
diff --git a/client/src/app/+admin/follows/follows.component.scss b/client/src/app/+admin/follows/follows.component.scss
index 33ff17539..1ed0d925f 100644
--- a/client/src/app/+admin/follows/follows.component.scss
+++ b/client/src/app/+admin/follows/follows.component.scss
@@ -1,4 +1,4 @@
1@import "mixins"; 1@import 'mixins';
2 2
3.form-sub-title { 3.form-sub-title {
4 flex-grow: 0; 4 flex-grow: 0;
diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.scss b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.scss
index adcf2037e..30b9f2147 100644
--- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.scss
+++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.scss
@@ -5,7 +5,8 @@ a {
5 @include disable-default-a-behaviour; 5 @include disable-default-a-behaviour;
6 display: inline-block; 6 display: inline-block;
7 7
8 &, &:hover { 8 &,
9 &:hover {
9 color: pvar(--mainForegroundColor); 10 color: pvar(--mainForegroundColor);
10 } 11 }
11 12
diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts
index d6fd1a1ab..3cd65dd6e 100644
--- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts
+++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts
@@ -78,7 +78,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit
78 this.pagination.start = 0 78 this.pagination.start = 0
79 this.saveSelectLocalStorage() 79 this.saveSelectLocalStorage()
80 80
81 this.loadData() 81 this.reloadData()
82 } 82 }
83 83
84 getRedundancyStrategy (redundancy: VideoRedundancy) { 84 getRedundancyStrategy (redundancy: VideoRedundancy) {
@@ -145,7 +145,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit
145 .subscribe( 145 .subscribe(
146 () => { 146 () => {
147 this.notifier.success($localize`Video redundancies removed!`) 147 this.notifier.success($localize`Video redundancies removed!`)
148 this.loadData() 148 this.reloadData()
149 }, 149 },
150 150
151 err => this.notifier.error(err.message) 151 err => this.notifier.error(err.message)
@@ -153,7 +153,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit
153 153
154 } 154 }
155 155
156 protected loadData () { 156 protected reloadData () {
157 const options = { 157 const options = {
158 pagination: this.pagination, 158 pagination: this.pagination,
159 sort: this.sort, 159 sort: this.sort,
diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html
index 9a6c124e1..a9e0931f8 100644
--- a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html
+++ b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html
@@ -3,4 +3,4 @@
3 <ng-container i18n>Reports</ng-container> 3 <ng-container i18n>Reports</ng-container>
4</h1> 4</h1>
5 5
6<my-abuse-list-table viewType="admin" baseRoute="/admin/moderation/abuses/list"></my-abuse-list-table> 6<my-abuse-list-table viewType="admin"></my-abuse-list-table>
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html
index f5cf93adb..e3a3a8320 100644
--- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html
+++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html
@@ -1,18 +1,14 @@
1<p-table 1<p-table
2 [value]="blockedAccounts" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 2 [value]="blockedAccounts" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" (onPage)="onPage($event)" 3 [sortField]="sort.field" [sortOrder]="sort.order" (onPage)="onPage($event)"
4 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
4 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 5 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
5 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts" 6 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts"
6> 7>
7 <ng-template pTemplate="caption"> 8 <ng-template pTemplate="caption">
8 <div class="caption"> 9 <div class="caption">
9 <div class="ml-auto has-feedback has-clear"> 10 <div class="ml-auto">
10 <input 11 <my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
11 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
12 (keyup)="onSearch($event)"
13 >
14 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
15 <span class="sr-only" i18n>Clear filters</span>
16 </div> 12 </div>
17 </div> 13 </div>
18 </ng-template> 14 </ng-template>
@@ -34,7 +30,7 @@
34 <td> 30 <td>
35 <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> 31 <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
36 <div class="chip two-lines"> 32 <div class="chip two-lines">
37 <my-account-avatar [account]="accountBlock.blockedAccount"></my-account-avatar> 33 <my-actor-avatar [account]="accountBlock.blockedAccount"></my-actor-avatar>
38 <div> 34 <div>
39 {{ accountBlock.blockedAccount.displayName }} 35 {{ accountBlock.blockedAccount.displayName }}
40 <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> 36 <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span>
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.scss b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.scss
index 6028b75ea..1d98e44d9 100644
--- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.scss
+++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.scss
@@ -4,4 +4,4 @@
4.unblock-button { 4.unblock-button {
5 @include peertube-button; 5 @include peertube-button;
6 @include grey-button; 6 @include grey-button;
7} \ No newline at end of file 7}
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html
index c7275de1b..d89c8f244 100644
--- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html
@@ -4,8 +4,9 @@
4</h1> 4</h1>
5 5
6<p-table 6<p-table
7 [value]="blocklist" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 7 [value]="blocklist" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
8 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" 8 [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
9 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
9 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
10 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blocked videos" 11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blocked videos"
11 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows" 12 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
@@ -13,25 +14,7 @@
13 <ng-template pTemplate="caption"> 14 <ng-template pTemplate="caption">
14 <div class="caption"> 15 <div class="caption">
15 <div class="ml-auto"> 16 <div class="ml-auto">
16 <div class="input-group has-feedback has-clear"> 17 <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
17 <div class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
18 <div class="input-group-text" ngbDropdownToggle>
19 <span class="caret" aria-haspopup="menu" role="button"></span>
20 </div>
21
22 <div role="menu" ngbDropdownMenu>
23 <h6 class="dropdown-header" i18n>Advanced block filters</h6>
24 <a [routerLink]="[ '/admin/moderation/video-blocks/list' ]" [queryParams]="{ 'search': 'type:auto' }" class="dropdown-item" i18n>Automatic blocks</a>
25 <a [routerLink]="[ '/admin/moderation/video-blocks/list' ]" [queryParams]="{ 'search': 'type:manual' }" class="dropdown-item" i18n>Manual blocks</a>
26 </div>
27 </div>
28 <input
29 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
30 (keyup)="onSearch($event)"
31 >
32 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetTableFilter()"></a>
33 <span class="sr-only" i18n>Clear filters</span>
34 </div>
35 </div> 18 </div>
36 </div> 19 </div>
37 </ng-template> 20 </ng-template>
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss
index b67e33cc1..068aa2aee 100644
--- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss
@@ -5,23 +5,6 @@ my-global-icon {
5 height: 24px; 5 height: 24px;
6} 6}
7 7
8.input-group {
9 @include peertube-input-group(300px);
10
11 .dropdown-toggle::after {
12 margin-left: 0;
13 }
14}
15
16.caption {
17 justify-content: flex-end;
18
19 input {
20 @include peertube-input-text(250px);
21 flex-grow: 1;
22 }
23}
24
25.badge { 8.badge {
26 @include table-badge; 9 @include table-badge;
27} 10}
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
index d6aca10e7..498d8321a 100644
--- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
@@ -2,10 +2,11 @@ import { SortMeta } from 'primeng/api'
2import { switchMap } from 'rxjs/operators' 2import { switchMap } from 'rxjs/operators'
3import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' 3import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils'
4import { environment } from 'src/environments/environment' 4import { environment } from 'src/environments/environment'
5import { AfterViewInit, Component, OnInit } from '@angular/core' 5import { Component, OnInit } from '@angular/core'
6import { DomSanitizer } from '@angular/platform-browser' 6import { DomSanitizer } from '@angular/platform-browser'
7import { ActivatedRoute, Params, Router } from '@angular/router' 7import { ActivatedRoute, Router } from '@angular/router'
8import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' 8import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
9import { AdvancedInputFilter } from '@app/shared/shared-forms'
9import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' 10import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
10import { VideoBlockService } from '@app/shared/shared-moderation' 11import { VideoBlockService } from '@app/shared/shared-moderation'
11import { VideoBlacklist, VideoBlacklistType } from '@shared/models' 12import { VideoBlacklist, VideoBlacklistType } from '@shared/models'
@@ -15,7 +16,7 @@ import { VideoBlacklist, VideoBlacklistType } from '@shared/models'
15 templateUrl: './video-block-list.component.html', 16 templateUrl: './video-block-list.component.html',
16 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-block-list.component.scss' ] 17 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-block-list.component.scss' ]
17}) 18})
18export class VideoBlockListComponent extends RestTable implements OnInit, AfterViewInit { 19export class VideoBlockListComponent extends RestTable implements OnInit {
19 blocklist: (VideoBlacklist & { reasonHtml?: string, embedHtml?: string })[] = [] 20 blocklist: (VideoBlacklist & { reasonHtml?: string, embedHtml?: string })[] = []
20 totalRecords = 0 21 totalRecords = 0
21 sort: SortMeta = { field: 'createdAt', order: -1 } 22 sort: SortMeta = { field: 'createdAt', order: -1 }
@@ -24,6 +25,17 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
24 25
25 videoBlocklistActions: DropdownAction<VideoBlacklist>[][] = [] 26 videoBlocklistActions: DropdownAction<VideoBlacklist>[][] = []
26 27
28 inputFilters: AdvancedInputFilter[] = [
29 {
30 queryParams: { 'search': 'type:auto' },
31 label: $localize`Automatic blocks`
32 },
33 {
34 queryParams: { 'search': 'type:manual' },
35 label: $localize`Manual blocks`
36 }
37 ]
38
27 constructor ( 39 constructor (
28 protected route: ActivatedRoute, 40 protected route: ActivatedRoute,
29 protected router: Router, 41 protected router: Router,
@@ -52,7 +64,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
52 ).subscribe( 64 ).subscribe(
53 () => { 65 () => {
54 this.notifier.success($localize`Video ${videoBlock.video.name} switched to manual block.`) 66 this.notifier.success($localize`Video ${videoBlock.video.name} switched to manual block.`)
55 this.loadData() 67 this.reloadData()
56 }, 68 },
57 69
58 err => this.notifier.error(err.message) 70 err => this.notifier.error(err.message)
@@ -104,31 +116,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
104 }) 116 })
105 117
106 this.initialize() 118 this.initialize()
107 this.listenToSearchChange()
108 }
109
110 ngAfterViewInit () {
111 if (this.search) this.setTableFilter(this.search, false)
112 }
113
114 /* Table filter functions */
115 onBlockSearch (event: Event) {
116 this.onSearch(event)
117 this.setQueryParams((event.target as HTMLInputElement).value)
118 }
119
120 setQueryParams (search: string) {
121 const queryParams: Params = {}
122 if (search) Object.assign(queryParams, { search })
123 this.router.navigate([ '/admin/moderation/video-blocks/list' ], { queryParams })
124 }
125
126 resetTableFilter () {
127 this.setTableFilter('')
128 this.setQueryParams('')
129 this.resetSearch()
130 } 119 }
131 /* END Table filter functions */
132 120
133 getIdentifier () { 121 getIdentifier () {
134 return 'VideoBlockListComponent' 122 return 'VideoBlockListComponent'
@@ -151,7 +139,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
151 this.videoBlocklistService.unblockVideo(entry.video.id).subscribe( 139 this.videoBlocklistService.unblockVideo(entry.video.id).subscribe(
152 () => { 140 () => {
153 this.notifier.success($localize`Video ${entry.video.name} unblocked.`) 141 this.notifier.success($localize`Video ${entry.video.name} unblocked.`)
154 this.loadData() 142 this.reloadData()
155 }, 143 },
156 144
157 err => this.notifier.error(err.message) 145 err => this.notifier.error(err.message)
@@ -169,7 +157,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
169 ) 157 )
170 } 158 }
171 159
172 protected loadData () { 160 protected reloadData () {
173 this.videoBlocklistService.listBlocks({ 161 this.videoBlocklistService.listBlocks({
174 pagination: this.pagination, 162 pagination: this.pagination,
175 sort: this.sort, 163 sort: this.sort,
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html
index d360c3c51..9d9283536 100644
--- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html
+++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html
@@ -8,8 +8,9 @@
8<em i18n>This view also shows comments from muted accounts.</em> 8<em i18n>This view also shows comments from muted accounts.</em>
9 9
10<p-table 10<p-table
11 [value]="comments" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 11 [value]="comments" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
12 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" 12 [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
13 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
13 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 14 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
14 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments" 15 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments"
15 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows" 16 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
@@ -26,25 +27,7 @@
26 </div> 27 </div>
27 28
28 <div class="ml-auto"> 29 <div class="ml-auto">
29 <div class="input-group has-feedback has-clear"> 30 <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
30 <div class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
31 <div class="input-group-text" ngbDropdownToggle>
32 <span class="caret" aria-haspopup="menu" role="button"></span>
33 </div>
34
35 <div role="menu" ngbDropdownMenu>
36 <h6 class="dropdown-header" i18n>Advanced comments filters</h6>
37 <a [routerLink]="[ '/admin/moderation/video-comments/list' ]" [queryParams]="{ 'search': 'local:true' }" class="dropdown-item" i18n>Local comments</a>
38 <a [routerLink]="[ '/admin/moderation/video-comments/list' ]" [queryParams]="{ 'search': 'local:false' }" class="dropdown-item" i18n>Remote comments</a>
39 </div>
40 </div>
41 <input
42 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
43 (keyup)="onSearch($event)"
44 >
45 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetTableFilter()"></a>
46 <span class="sr-only" i18n>Clear filters</span>
47 </div>
48 </div> 31 </div>
49 </div> 32 </div>
50 </ng-template> 33 </ng-template>
@@ -86,7 +69,7 @@
86 <td> 69 <td>
87 <a [href]="videoComment.account.localUrl" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> 70 <a [href]="videoComment.account.localUrl" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
88 <div class="chip two-lines"> 71 <div class="chip two-lines">
89 <my-account-avatar [account]="videoComment.account"></my-account-avatar> 72 <my-actor-avatar [account]="videoComment.account"></my-actor-avatar>
90 <div> 73 <div>
91 {{ videoComment.account.displayName }} 74 {{ videoComment.account.displayName }}
92 <span>{{ videoComment.by }}</span> 75 <span>{{ videoComment.by }}</span>
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss
index c9262da09..a6f931e3b 100644
--- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss
+++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss
@@ -11,23 +11,6 @@ my-global-icon {
11 height: 24px; 11 height: 24px;
12} 12}
13 13
14.input-group {
15 @include peertube-input-group(300px);
16
17 .dropdown-toggle::after {
18 margin-left: 0;
19 }
20}
21
22.caption {
23 justify-content: flex-end;
24
25 input {
26 @include peertube-input-text(250px);
27 flex-grow: 1;
28 }
29}
30
31.video { 14.video {
32 display: flex; 15 display: flex;
33 flex-direction: column; 16 flex-direction: column;
@@ -49,7 +32,8 @@ my-global-icon {
49 max-height: 22px; 32 max-height: 22px;
50 } 33 }
51 34
52 div, p { 35 div,
36 p {
53 @include ellipsis; 37 @include ellipsis;
54 } 38 }
55 39
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
index 63493d00d..e2ae993b0 100644
--- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
+++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
@@ -2,6 +2,7 @@ import { SortMeta } from 'primeng/api'
2import { AfterViewInit, Component, OnInit } from '@angular/core' 2import { AfterViewInit, Component, OnInit } from '@angular/core'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { AuthService, ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' 4import { AuthService, ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core'
5import { AdvancedInputFilter } from '@app/shared/shared-forms'
5import { DropdownAction } from '@app/shared/shared-main' 6import { DropdownAction } from '@app/shared/shared-main'
6import { BulkService } from '@app/shared/shared-moderation' 7import { BulkService } from '@app/shared/shared-moderation'
7import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' 8import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment'
@@ -12,9 +13,7 @@ import { FeedFormat, UserRight } from '@shared/models'
12 templateUrl: './video-comment-list.component.html', 13 templateUrl: './video-comment-list.component.html',
13 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ] 14 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
14}) 15})
15export class VideoCommentListComponent extends RestTable implements OnInit, AfterViewInit { 16export class VideoCommentListComponent extends RestTable implements OnInit {
16 baseRoute = '/admin/moderation/video-comments/list'
17
18 comments: VideoCommentAdmin[] 17 comments: VideoCommentAdmin[]
19 totalRecords = 0 18 totalRecords = 0
20 sort: SortMeta = { field: 'createdAt', order: -1 } 19 sort: SortMeta = { field: 'createdAt', order: -1 }
@@ -43,6 +42,17 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
43 selectedComments: VideoCommentAdmin[] = [] 42 selectedComments: VideoCommentAdmin[] = []
44 bulkCommentActions: DropdownAction<VideoCommentAdmin[]>[] = [] 43 bulkCommentActions: DropdownAction<VideoCommentAdmin[]>[] = []
45 44
45 inputFilters: AdvancedInputFilter[] = [
46 {
47 queryParams: { 'search': 'local:true' },
48 label: $localize`Local comments`
49 },
50 {
51 queryParams: { 'search': 'local:false' },
52 label: $localize`Remote comments`
53 }
54 ]
55
46 get authUser () { 56 get authUser () {
47 return this.auth.getUser() 57 return this.auth.getUser()
48 } 58 }
@@ -79,7 +89,6 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
79 89
80 ngOnInit () { 90 ngOnInit () {
81 this.initialize() 91 this.initialize()
82 this.listenToSearchChange()
83 92
84 this.bulkCommentActions = [ 93 this.bulkCommentActions = [
85 { 94 {
@@ -91,10 +100,6 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
91 ] 100 ]
92 } 101 }
93 102
94 ngAfterViewInit () {
95 if (this.search) this.setTableFilter(this.search, false)
96 }
97
98 getIdentifier () { 103 getIdentifier () {
99 return 'VideoCommentListComponent' 104 return 'VideoCommentListComponent'
100 } 105 }
@@ -107,7 +112,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
107 return this.selectedComments.length !== 0 112 return this.selectedComments.length !== 0
108 } 113 }
109 114
110 protected loadData () { 115 protected reloadData () {
111 this.videoCommentService.getAdminVideoComments({ 116 this.videoCommentService.getAdminVideoComments({
112 pagination: this.pagination, 117 pagination: this.pagination,
113 sort: this.sort, 118 sort: this.sort,
@@ -135,7 +140,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
135 this.videoCommentService.deleteVideoComments(commentArgs).subscribe( 140 this.videoCommentService.deleteVideoComments(commentArgs).subscribe(
136 () => { 141 () => {
137 this.notifier.success($localize`${commentArgs.length} comments deleted.`) 142 this.notifier.success($localize`${commentArgs.length} comments deleted.`)
138 this.loadData() 143 this.reloadData()
139 }, 144 },
140 145
141 err => this.notifier.error(err.message), 146 err => this.notifier.error(err.message),
@@ -147,7 +152,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit, Afte
147 private deleteComment (comment: VideoCommentAdmin) { 152 private deleteComment (comment: VideoCommentAdmin) {
148 this.videoCommentService.deleteVideoComment(comment.video.id, comment.id) 153 this.videoCommentService.deleteVideoComment(comment.video.id, comment.id)
149 .subscribe( 154 .subscribe(
150 () => this.loadData(), 155 () => this.reloadData(),
151 156
152 err => this.notifier.error(err.message) 157 err => this.notifier.error(err.message)
153 ) 158 )
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
index 9cbec03a1..bc4c2ef88 100644
--- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
+++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
@@ -23,13 +23,17 @@
23 </a> 23 </a>
24 24
25 <div class="buttons"> 25 <div class="buttons">
26 <my-edit-button *ngIf="!isTheme(plugin)" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> 26 <my-edit-button
27 27 *ngIf="!isTheme(plugin)" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label
28 <my-button class="update-button" *ngIf="isUpdateAvailable(plugin)" (click)="update(plugin)" [loading]="isUpdating(plugin)" 28 [responsiveLabel]="true"
29 [label]="getUpdateLabel(plugin)" icon="refresh" [attr.disabled]="isUpdating(plugin)" 29 ></my-edit-button>
30
31 <my-button
32 class="update-button" *ngIf="isUpdateAvailable(plugin)" (click)="update(plugin)" [loading]="isUpdating(plugin)"
33 [label]="getUpdateLabel(plugin)" icon="refresh" [attr.disabled]="isUpdating(plugin)" [responsiveLabel]="true"
30 ></my-button> 34 ></my-button>
31 35
32 <my-delete-button (click)="uninstall(plugin)" label="Uninstall" i18n-label></my-delete-button> 36 <my-delete-button (click)="uninstall(plugin)" label="Uninstall" i18n-label [responsiveLabel]="true"></my-delete-button>
33 </div> 37 </div>
34 </div> 38 </div>
35 39
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss
index 9376e38b0..22d4a59ab 100644
--- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss
+++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.scss
@@ -1,6 +1,6 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.update-button[disabled="true"] ::ng-deep .action-button { 4.update-button[disabled=true] ::ng-deep .action-button {
5 cursor: default !important; 5 cursor: default !important;
6} 6}
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
index 727633399..6900e8717 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
@@ -48,10 +48,15 @@
48 <span *ngIf="plugin.installed" class="badge badge-success">Installed</span> 48 <span *ngIf="plugin.installed" class="badge badge-success">Installed</span>
49 49
50 <div class="buttons"> 50 <div class="buttons">
51 <my-edit-button *ngIf="plugin.installed === true && !isThemeSearch()" [routerLink]="getShowRouterLink(plugin)" label="Settings" i18n-label></my-edit-button> 51 <my-edit-button
52 *ngIf="plugin.installed === true && !isThemeSearch()" [routerLink]="getShowRouterLink(plugin)"
53 label="Settings" i18n-label [responsiveLabel]="true"
54 ></my-edit-button>
52 55
53 <my-button class="update-button" *ngIf="plugin.installed === false" (click)="install(plugin)" [loading]="isInstalling(plugin)" 56 <my-button
54 label="Install" icon="cloud-download" [attr.disabled]="isInstalling(plugin)" 57 class="update-button" *ngIf="plugin.installed === false" (click)="install(plugin)"
58 [loading]="isInstalling(plugin)" label="Install" [responsiveLabel]="true"
59 icon="cloud-download" [attr.disabled]="isInstalling(plugin)"
55 ></my-button> 60 ></my-button>
56 </div> 61 </div>
57 </div> 62 </div>
diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.scss b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.scss
index 5ab6e5f1b..6b7b84e29 100644
--- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.scss
+++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.scss
@@ -5,7 +5,8 @@ h2 {
5 margin-bottom: 20px; 5 margin-bottom: 20px;
6} 6}
7 7
8input[type=submit], button { 8input[type=submit],
9button {
9 @include peertube-button; 10 @include peertube-button;
10 @include orange-button; 11 @include orange-button;
11 12
diff --git a/client/src/app/+admin/plugins/plugins.component.scss b/client/src/app/+admin/plugins/plugins.component.scss
deleted file mode 100644
index ce9825f53..000000000
--- a/client/src/app/+admin/plugins/plugins.component.scss
+++ /dev/null
@@ -1,28 +0,0 @@
1@import '_variables';
2@import '_mixins';
3
4@media screen and (max-width: $small-view) {
5 ::ng-deep .plugins .plugin .first-row {
6 flex-wrap: wrap;
7
8 .plugin-name,
9 .plugin-version,
10 .plugin-icon {
11 margin-bottom: 10px;
12 }
13
14 .buttons {
15 my-edit-button,
16 my-delete-button,
17 my-button {
18 .action-button {
19 padding: 0 13px;
20 }
21
22 .button-label {
23 display: none;
24 }
25 }
26 }
27 }
28}
diff --git a/client/src/app/+admin/plugins/plugins.component.ts b/client/src/app/+admin/plugins/plugins.component.ts
index 6ec6fa4a1..de06c0671 100644
--- a/client/src/app/+admin/plugins/plugins.component.ts
+++ b/client/src/app/+admin/plugins/plugins.component.ts
@@ -1,8 +1,7 @@
1import { Component } from '@angular/core' 1import { Component } from '@angular/core'
2 2
3@Component({ 3@Component({
4 templateUrl: './plugins.component.html', 4 templateUrl: './plugins.component.html'
5 styleUrls: [ './plugins.component.scss' ]
6}) 5})
7export class PluginsComponent { 6export class PluginsComponent {
8} 7}
diff --git a/client/src/app/+admin/plugins/shared/plugin-list.component.scss b/client/src/app/+admin/plugins/shared/plugin-list.component.scss
index f59a01b74..47cb1e6e5 100644
--- a/client/src/app/+admin/plugins/shared/plugin-list.component.scss
+++ b/client/src/app/+admin/plugins/shared/plugin-list.component.scss
@@ -27,7 +27,7 @@
27 my-global-icon { 27 my-global-icon {
28 @include apply-svg-color(pvar(--greyForegroundColor)); 28 @include apply-svg-color(pvar(--greyForegroundColor));
29 29
30 &[iconName="npm"] { 30 &[iconName=npm] {
31 @include fill-svg-color(pvar(--greyForegroundColor)); 31 @include fill-svg-color(pvar(--greyForegroundColor));
32 } 32 }
33 } 33 }
@@ -36,6 +36,7 @@
36 .buttons { 36 .buttons {
37 margin-left: auto; 37 margin-left: auto;
38 width: max-content; 38 width: max-content;
39
39 > *:not(:last-child) { 40 > *:not(:last-child) {
40 margin-right: 10px; 41 margin-right: 10px;
41 } 42 }
@@ -49,7 +50,7 @@
49 justify-content: space-between; 50 justify-content: space-between;
50 51
51 .description { 52 .description {
52 opacity: 0.8 53 opacity: 0.8;
53 } 54 }
54} 55}
55 56
@@ -57,3 +58,14 @@
57 @include peertube-button-link; 58 @include peertube-button-link;
58 @include button-with-icon(21px, 0, -2px); 59 @include button-with-icon(21px, 0, -2px);
59} 60}
61
62@media screen and (max-width: $small-view) {
63 .first-row {
64 flex-wrap: wrap;
65
66 .buttons {
67 flex-basis: 100%;
68 margin-top: 10px;
69 }
70 }
71}
diff --git a/client/src/app/+admin/system/jobs/jobs.component.scss b/client/src/app/+admin/system/jobs/jobs.component.scss
index 7c6159420..65ee6ec5f 100644
--- a/client/src/app/+admin/system/jobs/jobs.component.scss
+++ b/client/src/app/+admin/system/jobs/jobs.component.scss
@@ -51,7 +51,7 @@ pre {
51} 51}
52 52
53.job-error { 53.job-error {
54 color: red; 54 color: #ff0000;
55} 55}
56 56
57.badge { 57.badge {
diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts
index 43578eedd..29ba95c5c 100644
--- a/client/src/app/+admin/system/jobs/jobs.component.ts
+++ b/client/src/app/+admin/system/jobs/jobs.component.ts
@@ -86,7 +86,7 @@ export class JobsComponent extends RestTable implements OnInit {
86 onJobStateOrTypeChanged () { 86 onJobStateOrTypeChanged () {
87 this.pagination.start = 0 87 this.pagination.start = 0
88 88
89 this.loadData() 89 this.reloadData()
90 this.saveJobStateAndType() 90 this.saveJobStateAndType()
91 } 91 }
92 92
@@ -104,10 +104,10 @@ export class JobsComponent extends RestTable implements OnInit {
104 this.jobs = [] 104 this.jobs = []
105 this.totalRecords = 0 105 this.totalRecords = 0
106 106
107 this.loadData() 107 this.reloadData()
108 } 108 }
109 109
110 protected loadData () { 110 protected reloadData () {
111 let jobState = this.jobState as JobState 111 let jobState = this.jobState as JobState
112 if (this.jobState === 'all') jobState = null 112 if (this.jobState === 'all') jobState = null
113 113
diff --git a/client/src/app/+admin/system/logs/logs.component.scss b/client/src/app/+admin/system/logs/logs.component.scss
index 587a9795c..1a7c3be75 100644
--- a/client/src/app/+admin/system/logs/logs.component.scss
+++ b/client/src/app/+admin/system/logs/logs.component.scss
@@ -66,7 +66,7 @@
66 ng-select, 66 ng-select,
67 my-button { 67 my-button {
68 width: 100% !important; 68 width: 100% !important;
69 margin-left: 0px !important; 69 margin-left: 0 !important;
70 margin-bottom: 10px !important; 70 margin-bottom: 10px !important;
71 } 71 }
72 72
@@ -85,7 +85,7 @@
85 ng-select, 85 ng-select,
86 my-button { 86 my-button {
87 width: 100% !important; 87 width: 100% !important;
88 margin-left: 0px !important; 88 margin-left: 0 !important;
89 margin-bottom: 10px !important; 89 margin-bottom: 10px !important;
90 } 90 }
91 91
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 8b0ac8783..145177fb9 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
@@ -37,7 +37,8 @@ my-select-custom-value {
37 display: block; 37 display: block;
38} 38}
39 39
40input[type=submit], button { 40input[type=submit],
41button {
41 @include peertube-button; 42 @include peertube-button;
42 @include orange-button; 43 @include orange-button;
43 44
diff --git a/client/src/app/+admin/users/user-edit/user-password.component.scss b/client/src/app/+admin/users/user-edit/user-password.component.scss
index 1f0d49227..66d15ee9c 100644
--- a/client/src/app/+admin/users/user-edit/user-password.component.scss
+++ b/client/src/app/+admin/users/user-edit/user-password.component.scss
@@ -7,7 +7,7 @@ input:not([type=submit]):not([type=checkbox]) {
7 display: block; 7 display: block;
8 border-top-right-radius: 0; 8 border-top-right-radius: 0;
9 border-bottom-right-radius: 0; 9 border-bottom-right-radius: 0;
10 border-right: none; 10 border-right: 0;
11} 11}
12 12
13input[type=submit] { 13input[type=submit] {
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 e114f3425..44d8a7e87 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,7 +1,7 @@
1<p-table 1<p-table
2 [value]="users" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" 2 [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" [resizableColumns]="true" 3 [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" [(selection)]="selectedUsers"
4 [(selection)]="selectedUsers" 4 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
5 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 5 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
6 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users" 6 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
7 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows" 7 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
@@ -22,24 +22,7 @@
22 </div> 22 </div>
23 23
24 <div class="ml-auto"> 24 <div class="ml-auto">
25 <div class="input-group has-feedback has-clear"> 25 <my-advanced-input-filter [filters]="inputFilters" (search)="onSearch($event)"></my-advanced-input-filter>
26 <div class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
27 <div class="input-group-text" ngbDropdownToggle>
28 <span class="caret" aria-haspopup="menu" role="button"></span>
29 </div>
30
31 <div role="menu" ngbDropdownMenu>
32 <h6 class="dropdown-header" i18n>Advanced user filters</h6>
33 <a [routerLink]="[ '/admin/users/list' ]" [queryParams]="{ 'search': 'banned:true' }" class="dropdown-item" i18n>Banned users</a>
34 </div>
35 </div>
36 <input
37 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
38 (keyup)="onSearch($event)"
39 >
40 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetTableFilter()"></a>
41 <span class="sr-only" i18n>Clear filters</span>
42 </div>
43 </div> 26 </div>
44 27
45 </div> 28 </div>
@@ -106,7 +89,7 @@
106 <td *ngIf="isSelected('username')"> 89 <td *ngIf="isSelected('username')">
107 <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]"> 90 <a i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer" [routerLink]="[ '/accounts/' + user.username ]">
108 <div class="chip two-lines"> 91 <div class="chip two-lines">
109 <my-account-avatar [account]="user?.account"></my-account-avatar> 92 <my-actor-avatar [account]="user?.account" size="32"></my-actor-avatar>
110 <div> 93 <div>
111 <span class="user-table-primary-text">{{ user.account.displayName }}</span> 94 <span class="user-table-primary-text">{{ user.account.displayName }}</span>
112 <span class="text-muted">{{ user.username }}</span> 95 <span class="text-muted">{{ user.username }}</span>
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 50080bad6..db4979a51 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
@@ -11,6 +11,7 @@ tr.banned > td {
11 11
12.table-email { 12.table-email {
13 @include disable-default-a-behaviour; 13 @include disable-default-a-behaviour;
14
14 color: pvar(--mainForegroundColor); 15 color: pvar(--mainForegroundColor);
15} 16}
16 17
@@ -24,18 +25,10 @@ tr.banned > td {
24 25
25.user-table-primary-text .glyphicon { 26.user-table-primary-text .glyphicon {
26 font-size: 80%; 27 font-size: 80%;
27 color: gray; 28 color: #808080;
28 margin-left: 0.1rem; 29 margin-left: 0.1rem;
29} 30}
30 31
31.caption {
32 justify-content: space-between;
33
34 input {
35 @include peertube-input-text(250px);
36 }
37}
38
39p-tableCheckbox { 32p-tableCheckbox {
40 position: relative; 33 position: relative;
41 top: -2.5px; 34 top: -2.5px;
@@ -55,18 +48,7 @@ my-global-icon {
55 48
56.progress { 49.progress {
57 @include progressbar($small: true); 50 @include progressbar($small: true);
51
58 width: auto; 52 width: auto;
59 max-width: 100%; 53 max-width: 100%;
60} 54}
61
62.input-group {
63 @include peertube-input-group(300px);
64
65 input {
66 flex: 1;
67 }
68
69 .dropdown-toggle::after {
70 margin-left: 0;
71 }
72}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts
index 339e18206..1c60adf89 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/users/user-list/user-list.component.ts
@@ -1,8 +1,9 @@
1import { SortMeta } from 'primeng/api' 1import { SortMeta } from 'primeng/api'
2import { Component, OnInit, ViewChild } from '@angular/core' 2import { Component, OnInit, ViewChild } from '@angular/core'
3import { ActivatedRoute, Params, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core' 4import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core'
5import { Account, DropdownAction } from '@app/shared/shared-main' 5import { AdvancedInputFilter } from '@app/shared/shared-forms'
6import { DropdownAction } from '@app/shared/shared-main'
6import { UserBanModalComponent } from '@app/shared/shared-moderation' 7import { UserBanModalComponent } from '@app/shared/shared-moderation'
7import { ServerConfig, User, UserRole } from '@shared/models' 8import { ServerConfig, User, UserRole } from '@shared/models'
8 9
@@ -22,15 +23,24 @@ export class UserListComponent extends RestTable implements OnInit {
22 @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent 23 @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
23 24
24 users: User[] = [] 25 users: User[] = []
26
25 totalRecords = 0 27 totalRecords = 0
26 sort: SortMeta = { field: 'createdAt', order: 1 } 28 sort: SortMeta = { field: 'createdAt', order: 1 }
27 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 29 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
30
28 highlightBannedUsers = false 31 highlightBannedUsers = false
29 32
30 selectedUsers: User[] = [] 33 selectedUsers: User[] = []
31 bulkUserActions: DropdownAction<User[]>[][] = [] 34 bulkUserActions: DropdownAction<User[]>[][] = []
32 columns: { id: string, label: string }[] 35 columns: { id: string, label: string }[]
33 36
37 inputFilters: AdvancedInputFilter[] = [
38 {
39 queryParams: { 'search': 'banned:true' },
40 label: $localize`Banned users`
41 }
42 ]
43
34 private _selectedColumns: string[] 44 private _selectedColumns: string[]
35 private serverConfig: ServerConfig 45 private serverConfig: ServerConfig
36 46
@@ -68,7 +78,6 @@ export class UserListComponent extends RestTable implements OnInit {
68 .subscribe(config => this.serverConfig = config) 78 .subscribe(config => this.serverConfig = config)
69 79
70 this.initialize() 80 this.initialize()
71 this.listenToSearchChange()
72 81
73 this.bulkUserActions = [ 82 this.bulkUserActions = [
74 [ 83 [
@@ -160,7 +169,7 @@ export class UserListComponent extends RestTable implements OnInit {
160 } 169 }
161 170
162 onUserChanged () { 171 onUserChanged () {
163 this.loadData() 172 this.reloadData()
164 } 173 }
165 174
166 async unbanUsers (users: User[]) { 175 async unbanUsers (users: User[]) {
@@ -171,7 +180,7 @@ export class UserListComponent extends RestTable implements OnInit {
171 .subscribe( 180 .subscribe(
172 () => { 181 () => {
173 this.notifier.success($localize`${users.length} users unbanned.`) 182 this.notifier.success($localize`${users.length} users unbanned.`)
174 this.loadData() 183 this.reloadData()
175 }, 184 },
176 185
177 err => this.notifier.error(err.message) 186 err => this.notifier.error(err.message)
@@ -193,7 +202,7 @@ export class UserListComponent extends RestTable implements OnInit {
193 this.userService.removeUser(users).subscribe( 202 this.userService.removeUser(users).subscribe(
194 () => { 203 () => {
195 this.notifier.success($localize`${users.length} users deleted.`) 204 this.notifier.success($localize`${users.length} users deleted.`)
196 this.loadData() 205 this.reloadData()
197 }, 206 },
198 207
199 err => this.notifier.error(err.message) 208 err => this.notifier.error(err.message)
@@ -204,7 +213,7 @@ export class UserListComponent extends RestTable implements OnInit {
204 this.userService.updateUsers(users, { emailVerified: true }).subscribe( 213 this.userService.updateUsers(users, { emailVerified: true }).subscribe(
205 () => { 214 () => {
206 this.notifier.success($localize`${users.length} users email set as verified.`) 215 this.notifier.success($localize`${users.length} users email set as verified.`)
207 this.loadData() 216 this.reloadData()
208 }, 217 },
209 218
210 err => this.notifier.error(err.message) 219 err => this.notifier.error(err.message)
@@ -215,7 +224,7 @@ export class UserListComponent extends RestTable implements OnInit {
215 return this.selectedUsers.length !== 0 224 return this.selectedUsers.length !== 0
216 } 225 }
217 226
218 protected loadData () { 227 protected reloadData () {
219 this.selectedUsers = [] 228 this.selectedUsers = []
220 229
221 this.userService.getUsers({ 230 this.userService.getUsers({