aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/overview
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+admin/overview')
-rw-r--r--client/src/app/+admin/overview/comments/video-comment-list.component.html4
-rw-r--r--client/src/app/+admin/overview/comments/video-comment-list.component.ts15
-rw-r--r--client/src/app/+admin/overview/users/user-list/user-list.component.html23
-rw-r--r--client/src/app/+admin/overview/users/user-list/user-list.component.scss10
-rw-r--r--client/src/app/+admin/overview/users/user-list/user-list.component.ts17
-rw-r--r--client/src/app/+admin/overview/videos/video-list.component.html4
-rw-r--r--client/src/app/+admin/overview/videos/video-list.component.ts46
7 files changed, 38 insertions, 81 deletions
diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.html b/client/src/app/+admin/overview/comments/video-comment-list.component.html
index d2ca5f700..b0d8131bf 100644
--- a/client/src/app/+admin/overview/comments/video-comment-list.component.html
+++ b/client/src/app/+admin/overview/comments/video-comment-list.component.html
@@ -13,14 +13,14 @@
13 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true" 13 [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
14 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 14 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
15 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments" 15 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments"
16 [expandedRowKeys]="expandedRows" [(selection)]="selectedComments" 16 [expandedRowKeys]="expandedRows" [(selection)]="selectedRows"
17> 17>
18 <ng-template pTemplate="caption"> 18 <ng-template pTemplate="caption">
19 <div class="caption"> 19 <div class="caption">
20 <div> 20 <div>
21 <my-action-dropdown 21 <my-action-dropdown
22 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange" 22 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
23 [actions]="bulkCommentActions" [entry]="selectedComments" 23 [actions]="bulkActions" [entry]="selectedRows"
24 > 24 >
25 </my-action-dropdown> 25 </my-action-dropdown>
26 </div> 26 </div>
diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.ts b/client/src/app/+admin/overview/comments/video-comment-list.component.ts
index c95d2ffeb..28efdc076 100644
--- a/client/src/app/+admin/overview/comments/video-comment-list.component.ts
+++ b/client/src/app/+admin/overview/comments/video-comment-list.component.ts
@@ -14,7 +14,7 @@ import { prepareIcu } from '@app/helpers'
14 templateUrl: './video-comment-list.component.html', 14 templateUrl: './video-comment-list.component.html',
15 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ] 15 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
16}) 16})
17export class VideoCommentListComponent extends RestTable implements OnInit { 17export class VideoCommentListComponent extends RestTable <VideoCommentAdmin> implements OnInit {
18 comments: VideoCommentAdmin[] 18 comments: VideoCommentAdmin[]
19 totalRecords = 0 19 totalRecords = 0
20 sort: SortMeta = { field: 'createdAt', order: -1 } 20 sort: SortMeta = { field: 'createdAt', order: -1 }
@@ -40,8 +40,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
40 } 40 }
41 ] 41 ]
42 42
43 selectedComments: VideoCommentAdmin[] = [] 43 bulkActions: DropdownAction<VideoCommentAdmin[]>[] = []
44 bulkCommentActions: DropdownAction<VideoCommentAdmin[]>[] = []
45 44
46 inputFilters: AdvancedInputFilter[] = [ 45 inputFilters: AdvancedInputFilter[] = [
47 { 46 {
@@ -100,7 +99,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
100 ngOnInit () { 99 ngOnInit () {
101 this.initialize() 100 this.initialize()
102 101
103 this.bulkCommentActions = [ 102 this.bulkActions = [
104 { 103 {
105 label: $localize`Delete`, 104 label: $localize`Delete`,
106 handler: comments => this.removeComments(comments), 105 handler: comments => this.removeComments(comments),
@@ -118,11 +117,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
118 return this.markdownRenderer.textMarkdownToHTML({ markdown: text, withHtml: true, withEmoji: true }) 117 return this.markdownRenderer.textMarkdownToHTML({ markdown: text, withHtml: true, withEmoji: true })
119 } 118 }
120 119
121 isInSelectionMode () { 120 protected reloadDataInternal () {
122 return this.selectedComments.length !== 0
123 }
124
125 reloadData () {
126 this.videoCommentService.getAdminVideoComments({ 121 this.videoCommentService.getAdminVideoComments({
127 pagination: this.pagination, 122 pagination: this.pagination,
128 sort: this.sort, 123 sort: this.sort,
@@ -162,7 +157,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
162 157
163 error: err => this.notifier.error(err.message), 158 error: err => this.notifier.error(err.message),
164 159
165 complete: () => this.selectedComments = [] 160 complete: () => this.selectedRows = []
166 }) 161 })
167 } 162 }
168 163
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.html b/client/src/app/+admin/overview/users/user-list/user-list.component.html
index a96ce561c..7eb5e0fc7 100644
--- a/client/src/app/+admin/overview/users/user-list/user-list.component.html
+++ b/client/src/app/+admin/overview/users/user-list/user-list.component.html
@@ -6,7 +6,7 @@
6<p-table 6<p-table
7 [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start" 7 [value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
8 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" 8 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
9 [(selection)]="selectedUsers" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true" 9 [(selection)]="selectedRows" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users" 11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
12 [expandedRowKeys]="expandedRows" 12 [expandedRowKeys]="expandedRows"
@@ -16,7 +16,7 @@
16 <div class="left-buttons"> 16 <div class="left-buttons">
17 <my-action-dropdown 17 <my-action-dropdown
18 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange" 18 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
19 [actions]="bulkUserActions" [entry]="selectedUsers" 19 [actions]="bulkActions" [entry]="selectedRows"
20 > 20 >
21 </my-action-dropdown> 21 </my-action-dropdown>
22 22
@@ -95,7 +95,7 @@
95 <div class="chip two-lines"> 95 <div class="chip two-lines">
96 <my-actor-avatar [actor]="user?.account" actorType="account" size="32"></my-actor-avatar> 96 <my-actor-avatar [actor]="user?.account" actorType="account" size="32"></my-actor-avatar>
97 <div> 97 <div>
98 <span class="user-table-primary-text">{{ user.account.displayName }}</span> 98 <span>{{ user.account.displayName }}</span>
99 <span class="muted">{{ user.username }}</span> 99 <span class="muted">{{ user.username }}</span>
100 </div> 100 </div>
101 </div> 101 </div>
@@ -110,23 +110,10 @@
110 <span *ngIf="!user.blocked" class="pt-badge" [ngClass]="getRoleClass(user.role.id)">{{ user.role.label }}</span> 110 <span *ngIf="!user.blocked" class="pt-badge" [ngClass]="getRoleClass(user.role.id)">{{ user.role.label }}</span>
111 </td> 111 </td>
112 112
113 <td *ngIf="isSelected('email')" [title]="user.email"> 113 <td *ngIf="isSelected('email')">
114 <ng-container *ngIf="!requiresEmailVerification || user.blocked; else emailWithVerificationStatus"> 114 <my-user-email-info [entry]="user" [requiresEmailVerification]="requiresEmailVerification"></my-user-email-info>
115 <a class="table-email" [href]="'mailto:' + user.email">{{ user.email }}</a>
116 </ng-container>
117 </td> 115 </td>
118 116
119 <ng-template #emailWithVerificationStatus>
120 <td *ngIf="user.emailVerified === false; else emailVerifiedNotFalse" i18n-title title="User's email must be verified to login">
121 <em>? {{ user.email }}</em>
122 </td>
123 <ng-template #emailVerifiedNotFalse>
124 <td i18n-title title="User's email is verified / User can login without email verification">
125 &#x2713; {{ user.email }}
126 </td>
127 </ng-template>
128 </ng-template>
129
130 <td *ngIf="isSelected('quota')"> 117 <td *ngIf="isSelected('quota')">
131 <div class="progress" i18n-title title="Total video quota"> 118 <div class="progress" i18n-title title="Total video quota">
132 <div class="progress-bar" role="progressbar" [style]="{ width: getUserVideoQuotaPercentage(user) + '%' }" 119 <div class="progress-bar" role="progressbar" [style]="{ width: getUserVideoQuotaPercentage(user) + '%' }"
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.scss b/client/src/app/+admin/overview/users/user-list/user-list.component.scss
index 23e0d29ee..2a3b955d2 100644
--- a/client/src/app/+admin/overview/users/user-list/user-list.component.scss
+++ b/client/src/app/+admin/overview/users/user-list/user-list.component.scss
@@ -10,12 +10,6 @@ tr.banned > td {
10 background-color: lighten($color: $red, $amount: 40) !important; 10 background-color: lighten($color: $red, $amount: 40) !important;
11} 11}
12 12
13.table-email {
14 @include disable-default-a-behaviour;
15
16 color: pvar(--mainForegroundColor);
17}
18
19.banned-info { 13.banned-info {
20 font-style: italic; 14 font-style: italic;
21} 15}
@@ -37,10 +31,6 @@ my-global-icon {
37 width: 18px; 31 width: 18px;
38} 32}
39 33
40.chip {
41 @include chip;
42}
43
44.progress { 34.progress {
45 @include progressbar($small: true); 35 @include progressbar($small: true);
46 36
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.ts b/client/src/app/+admin/overview/users/user-list/user-list.component.ts
index 99987fdff..19420b748 100644
--- a/client/src/app/+admin/overview/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/overview/users/user-list/user-list.component.ts
@@ -22,7 +22,7 @@ type UserForList = User & {
22 templateUrl: './user-list.component.html', 22 templateUrl: './user-list.component.html',
23 styleUrls: [ './user-list.component.scss' ] 23 styleUrls: [ './user-list.component.scss' ]
24}) 24})
25export class UserListComponent extends RestTable implements OnInit { 25export class UserListComponent extends RestTable <User> implements OnInit {
26 private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns' 26 private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns'
27 27
28 @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent 28 @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
@@ -35,8 +35,7 @@ export class UserListComponent extends RestTable implements OnInit {
35 35
36 highlightBannedUsers = false 36 highlightBannedUsers = false
37 37
38 selectedUsers: User[] = [] 38 bulkActions: DropdownAction<User[]>[][] = []
39 bulkUserActions: DropdownAction<User[]>[][] = []
40 columns: { id: string, label: string }[] 39 columns: { id: string, label: string }[]
41 40
42 inputFilters: AdvancedInputFilter[] = [ 41 inputFilters: AdvancedInputFilter[] = [
@@ -95,7 +94,7 @@ export class UserListComponent extends RestTable implements OnInit {
95 94
96 this.initialize() 95 this.initialize()
97 96
98 this.bulkUserActions = [ 97 this.bulkActions = [
99 [ 98 [
100 { 99 {
101 label: $localize`Delete`, 100 label: $localize`Delete`,
@@ -249,7 +248,7 @@ export class UserListComponent extends RestTable implements OnInit {
249 const res = await this.confirmService.confirm(message, $localize`Delete`) 248 const res = await this.confirmService.confirm(message, $localize`Delete`)
250 if (res === false) return 249 if (res === false) return
251 250
252 this.userAdminService.removeUser(users) 251 this.userAdminService.removeUsers(users)
253 .subscribe({ 252 .subscribe({
254 next: () => { 253 next: () => {
255 this.notifier.success( 254 this.notifier.success(
@@ -284,13 +283,7 @@ export class UserListComponent extends RestTable implements OnInit {
284 }) 283 })
285 } 284 }
286 285
287 isInSelectionMode () { 286 protected reloadDataInternal () {
288 return this.selectedUsers.length !== 0
289 }
290
291 protected reloadData () {
292 this.selectedUsers = []
293
294 this.userAdminService.getUsers({ 287 this.userAdminService.getUsers({
295 pagination: this.pagination, 288 pagination: this.pagination,
296 sort: this.sort, 289 sort: this.sort,
diff --git a/client/src/app/+admin/overview/videos/video-list.component.html b/client/src/app/+admin/overview/videos/video-list.component.html
index a6cd2e257..5b8405ad9 100644
--- a/client/src/app/+admin/overview/videos/video-list.component.html
+++ b/client/src/app/+admin/overview/videos/video-list.component.html
@@ -6,7 +6,7 @@
6<p-table 6<p-table
7 [value]="videos" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start" 7 [value]="videos" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
8 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true" 8 [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
9 [(selection)]="selectedVideos" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true" 9 [(selection)]="selectedRows" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate 10 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} videos" 11 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} videos"
12 [expandedRowKeys]="expandedRows" [ngClass]="{ loading: loading }" 12 [expandedRowKeys]="expandedRows" [ngClass]="{ loading: loading }"
@@ -16,7 +16,7 @@
16 <div class="left-buttons"> 16 <div class="left-buttons">
17 <my-action-dropdown 17 <my-action-dropdown
18 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange" 18 *ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
19 [actions]="bulkVideoActions" [entry]="selectedVideos" 19 [actions]="bulkActions" [entry]="selectedRows"
20 > 20 >
21 </my-action-dropdown> 21 </my-action-dropdown>
22 </div> 22 </div>
diff --git a/client/src/app/+admin/overview/videos/video-list.component.ts b/client/src/app/+admin/overview/videos/video-list.component.ts
index 4d3e9873c..1ea295499 100644
--- a/client/src/app/+admin/overview/videos/video-list.component.ts
+++ b/client/src/app/+admin/overview/videos/video-list.component.ts
@@ -17,7 +17,7 @@ import { VideoAdminService } from './video-admin.service'
17 templateUrl: './video-list.component.html', 17 templateUrl: './video-list.component.html',
18 styleUrls: [ './video-list.component.scss' ] 18 styleUrls: [ './video-list.component.scss' ]
19}) 19})
20export class VideoListComponent extends RestTable implements OnInit { 20export class VideoListComponent extends RestTable <Video> implements OnInit {
21 @ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent 21 @ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
22 22
23 videos: Video[] = [] 23 videos: Video[] = []
@@ -26,9 +26,7 @@ export class VideoListComponent extends RestTable implements OnInit {
26 sort: SortMeta = { field: 'publishedAt', order: -1 } 26 sort: SortMeta = { field: 'publishedAt', order: -1 }
27 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 27 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
28 28
29 bulkVideoActions: DropdownAction<Video[]>[][] = [] 29 bulkActions: DropdownAction<Video[]>[][] = []
30
31 selectedVideos: Video[] = []
32 30
33 inputFilters: AdvancedInputFilter[] 31 inputFilters: AdvancedInputFilter[]
34 32
@@ -72,7 +70,7 @@ export class VideoListComponent extends RestTable implements OnInit {
72 70
73 this.inputFilters = this.videoAdminService.buildAdminInputFilter() 71 this.inputFilters = this.videoAdminService.buildAdminInputFilter()
74 72
75 this.bulkVideoActions = [ 73 this.bulkActions = [
76 [ 74 [
77 { 75 {
78 label: $localize`Delete`, 76 label: $localize`Delete`,
@@ -126,10 +124,6 @@ export class VideoListComponent extends RestTable implements OnInit {
126 return 'VideoListComponent' 124 return 'VideoListComponent'
127 } 125 }
128 126
129 isInSelectionMode () {
130 return this.selectedVideos.length !== 0
131 }
132
133 getPrivacyBadgeClass (video: Video) { 127 getPrivacyBadgeClass (video: Video) {
134 if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green' 128 if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green'
135 129
@@ -189,9 +183,23 @@ export class VideoListComponent extends RestTable implements OnInit {
189 return files.reduce((p, f) => p += f.size, 0) 183 return files.reduce((p, f) => p += f.size, 0)
190 } 184 }
191 185
192 reloadData () { 186 async removeVideoFile (video: Video, file: VideoFile, type: 'hls' | 'webtorrent') {
193 this.selectedVideos = [] 187 const message = $localize`Are you sure you want to delete this ${file.resolution.label} file?`
188 const res = await this.confirmService.confirm(message, $localize`Delete file`)
189 if (res === false) return
190
191 this.videoService.removeFile(video.uuid, file.id, type)
192 .subscribe({
193 next: () => {
194 this.notifier.success($localize`File removed.`)
195 this.reloadData()
196 },
197
198 error: err => this.notifier.error(err.message)
199 })
200 }
194 201
202 protected reloadDataInternal () {
195 this.loading = true 203 this.loading = true
196 204
197 this.videoAdminService.getAdminVideos({ 205 this.videoAdminService.getAdminVideos({
@@ -209,22 +217,6 @@ export class VideoListComponent extends RestTable implements OnInit {
209 }) 217 })
210 } 218 }
211 219
212 async removeVideoFile (video: Video, file: VideoFile, type: 'hls' | 'webtorrent') {
213 const message = $localize`Are you sure you want to delete this ${file.resolution.label} file?`
214 const res = await this.confirmService.confirm(message, $localize`Delete file`)
215 if (res === false) return
216
217 this.videoService.removeFile(video.uuid, file.id, type)
218 .subscribe({
219 next: () => {
220 this.notifier.success($localize`File removed.`)
221 this.reloadData()
222 },
223
224 error: err => this.notifier.error(err.message)
225 })
226 }
227
228 private async removeVideos (videos: Video[]) { 220 private async removeVideos (videos: Video[]) {
229 const message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`)( 221 const message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`)(
230 { count: videos.length }, 222 { count: videos.length },