diff options
Diffstat (limited to 'client/src/app/+admin')
3 files changed, 53 insertions, 13 deletions
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 7eb89fea1..0662e3ac3 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 | |||
@@ -62,10 +62,10 @@ | |||
62 | </div> | 62 | </div> |
63 | </th> | 63 | </th> |
64 | <th *ngIf="isSelected('username')" pResizableColumn pSortableColumn="username">{{ getColumn('username').label }} <p-sortIcon field="username"></p-sortIcon></th> | 64 | <th *ngIf="isSelected('username')" pResizableColumn pSortableColumn="username">{{ getColumn('username').label }} <p-sortIcon field="username"></p-sortIcon></th> |
65 | <th *ngIf="isSelected('role')" style="width: 120px;" pSortableColumn="role">{{ getColumn('role').label }} <p-sortIcon field="role"></p-sortIcon></th> | ||
65 | <th *ngIf="isSelected('email')">{{ getColumn('email').label }}</th> | 66 | <th *ngIf="isSelected('email')">{{ getColumn('email').label }}</th> |
66 | <th *ngIf="isSelected('quota')" style="width: 160px;" pSortableColumn="videoQuotaUsed">{{ getColumn('quota').label }} <p-sortIcon field="videoQuotaUsed"></p-sortIcon></th> | 67 | <th *ngIf="isSelected('quota')" style="width: 160px;" pSortableColumn="videoQuotaUsed">{{ getColumn('quota').label }} <p-sortIcon field="videoQuotaUsed"></p-sortIcon></th> |
67 | <th *ngIf="isSelected('quotaDaily')" style="width: 160px;">{{ getColumn('quotaDaily').label }}</th> | 68 | <th *ngIf="isSelected('quotaDaily')" style="width: 160px;">{{ getColumn('quotaDaily').label }}</th> |
68 | <th *ngIf="isSelected('role')" style="width: 120px;" pSortableColumn="role">{{ getColumn('role').label }} <p-sortIcon field="role"></p-sortIcon></th> | ||
69 | <th *ngIf="isSelected('pluginAuth')" style="width: 140px;" pResizableColumn >{{ getColumn('pluginAuth').label }}</th> | 69 | <th *ngIf="isSelected('pluginAuth')" style="width: 140px;" pResizableColumn >{{ getColumn('pluginAuth').label }}</th> |
70 | <th *ngIf="isSelected('createdAt')" style="width: 150px;" pSortableColumn="createdAt">{{ getColumn('createdAt').label }} <p-sortIcon field="createdAt"></p-sortIcon></th> | 70 | <th *ngIf="isSelected('createdAt')" style="width: 150px;" pSortableColumn="createdAt">{{ getColumn('createdAt').label }} <p-sortIcon field="createdAt"></p-sortIcon></th> |
71 | <th *ngIf="isSelected('lastLoginDate')" style="width: 150px;" pSortableColumn="lastLoginDate">{{ getColumn('lastLoginDate').label }} <p-sortIcon field="lastLoginDate"></p-sortIcon></th> | 71 | <th *ngIf="isSelected('lastLoginDate')" style="width: 150px;" pSortableColumn="lastLoginDate">{{ getColumn('lastLoginDate').label }} <p-sortIcon field="lastLoginDate"></p-sortIcon></th> |
@@ -84,8 +84,9 @@ | |||
84 | </td> | 84 | </td> |
85 | 85 | ||
86 | <td class="action-cell"> | 86 | <td class="action-cell"> |
87 | <my-user-moderation-dropdown *ngIf="!isInSelectionMode()" [user]="user" container="body" | 87 | <my-user-moderation-dropdown |
88 | (userChanged)="onUserChanged()" (userDeleted)="onUserChanged()"> | 88 | *ngIf="!isInSelectionMode()" [user]="user" [account]="user.accountMutedStatus" [displayOptions]="userModerationDisplayOptions" |
89 | container="body" (userChanged)="onUserChanged()" (userDeleted)="onUserChanged()"> | ||
89 | </my-user-moderation-dropdown> | 90 | </my-user-moderation-dropdown> |
90 | </td> | 91 | </td> |
91 | 92 | ||
@@ -99,6 +100,14 @@ | |||
99 | </div> | 100 | </div> |
100 | </div> | 101 | </div> |
101 | </a> | 102 | </a> |
103 | |||
104 | <div *ngIf="user.accountMutedStatus.mutedByInstance" class="badges-username badge badge-red" i18n>Muted</div> | ||
105 | <div *ngIf="user.blocked" class="badges-username badge badge-red" i18n>Banned</div> | ||
106 | </td> | ||
107 | |||
108 | <td *ngIf="isSelected('role')"> | ||
109 | <span *ngIf="user.blocked" class="badge badge-banned" i18n-title title="The user was banned">{{ user.roleLabel }}</span> | ||
110 | <span *ngIf="!user.blocked" class="badge" [ngClass]="getRoleClass(user.role)">{{ user.roleLabel }}</span> | ||
102 | </td> | 111 | </td> |
103 | 112 | ||
104 | <td *ngIf="isSelected('email')" [title]="user.email"> | 113 | <td *ngIf="isSelected('email')" [title]="user.email"> |
@@ -138,11 +147,6 @@ | |||
138 | </div> | 147 | </div> |
139 | </td> | 148 | </td> |
140 | 149 | ||
141 | <td *ngIf="isSelected('role')"> | ||
142 | <span *ngIf="user.blocked" class="badge badge-banned" i18n-title title="The user was banned">{{ user.roleLabel }}</span> | ||
143 | <span *ngIf="!user.blocked" class="badge" [ngClass]="getRoleClass(user.role)">{{ user.roleLabel }}</span> | ||
144 | </td> | ||
145 | |||
146 | <td *ngIf="isSelected('pluginAuth')"> | 150 | <td *ngIf="isSelected('pluginAuth')"> |
147 | <ng-container *ngIf="user.pluginAuth">{{ user.pluginAuth }}</ng-container> | 151 | <ng-container *ngIf="user.pluginAuth">{{ user.pluginAuth }}</ng-container> |
148 | </td> | 152 | </td> |
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 335bd2995..8160703f0 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 | |||
@@ -23,6 +23,10 @@ tr.banned > td { | |||
23 | font-weight: $font-semibold; | 23 | font-weight: $font-semibold; |
24 | } | 24 | } |
25 | 25 | ||
26 | .badges-username { | ||
27 | margin-left: 15px; | ||
28 | } | ||
29 | |||
26 | .user-table-primary-text .glyphicon { | 30 | .user-table-primary-text .glyphicon { |
27 | @include margin-left(0.1rem); | 31 | @include margin-left(0.1rem); |
28 | 32 | ||
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 9a9d0f5c6..d22e1355e 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 | |||
@@ -2,9 +2,10 @@ import { SortMeta } from 'primeng/api' | |||
2 | import { Component, OnInit, ViewChild } from '@angular/core' | 2 | import { Component, OnInit, ViewChild } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' | 4 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' |
5 | import { getAPIHost } from '@app/helpers' | ||
5 | import { AdvancedInputFilter } from '@app/shared/shared-forms' | 6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' |
6 | import { DropdownAction } from '@app/shared/shared-main' | 7 | import { Actor, DropdownAction } from '@app/shared/shared-main' |
7 | import { UserBanModalComponent } from '@app/shared/shared-moderation' | 8 | import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' |
8 | import { UserAdminService } from '@app/shared/shared-users' | 9 | import { UserAdminService } from '@app/shared/shared-users' |
9 | import { User, UserRole } from '@shared/models' | 10 | import { User, UserRole } from '@shared/models' |
10 | 11 | ||
@@ -23,7 +24,7 @@ type UserForList = User & { | |||
23 | export class UserListComponent extends RestTable implements OnInit { | 24 | export class UserListComponent extends RestTable implements OnInit { |
24 | @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent | 25 | @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent |
25 | 26 | ||
26 | users: User[] = [] | 27 | users: (User & { accountMutedStatus: AccountMutedStatus })[] = [] |
27 | 28 | ||
28 | totalRecords = 0 | 29 | totalRecords = 0 |
29 | sort: SortMeta = { field: 'createdAt', order: 1 } | 30 | sort: SortMeta = { field: 'createdAt', order: 1 } |
@@ -47,6 +48,12 @@ export class UserListComponent extends RestTable implements OnInit { | |||
47 | } | 48 | } |
48 | ] | 49 | ] |
49 | 50 | ||
51 | userModerationDisplayOptions: UserModerationDisplayType = { | ||
52 | instanceAccount: true, | ||
53 | instanceUser: true, | ||
54 | myAccount: false | ||
55 | } | ||
56 | |||
50 | requiresEmailVerification = false | 57 | requiresEmailVerification = false |
51 | 58 | ||
52 | private _selectedColumns: string[] | 59 | private _selectedColumns: string[] |
@@ -58,6 +65,7 @@ export class UserListComponent extends RestTable implements OnInit { | |||
58 | private confirmService: ConfirmService, | 65 | private confirmService: ConfirmService, |
59 | private serverService: ServerService, | 66 | private serverService: ServerService, |
60 | private auth: AuthService, | 67 | private auth: AuthService, |
68 | private blocklist: BlocklistService, | ||
61 | private userAdminService: UserAdminService | 69 | private userAdminService: UserAdminService |
62 | ) { | 70 | ) { |
63 | super() | 71 | super() |
@@ -115,9 +123,9 @@ export class UserListComponent extends RestTable implements OnInit { | |||
115 | 123 | ||
116 | this.columns = [ | 124 | this.columns = [ |
117 | { id: 'username', label: $localize`Username` }, | 125 | { id: 'username', label: $localize`Username` }, |
126 | { id: 'role', label: $localize`Role` }, | ||
118 | { id: 'email', label: $localize`Email` }, | 127 | { id: 'email', label: $localize`Email` }, |
119 | { id: 'quota', label: $localize`Video quota` }, | 128 | { id: 'quota', label: $localize`Video quota` }, |
120 | { id: 'role', label: $localize`Role` }, | ||
121 | { id: 'createdAt', label: $localize`Created` } | 129 | { id: 'createdAt', label: $localize`Created` } |
122 | ] | 130 | ] |
123 | 131 | ||
@@ -237,11 +245,35 @@ export class UserListComponent extends RestTable implements OnInit { | |||
237 | search: this.search | 245 | search: this.search |
238 | }).subscribe({ | 246 | }).subscribe({ |
239 | next: resultList => { | 247 | next: resultList => { |
240 | this.users = resultList.data | 248 | this.users = resultList.data.map(u => ({ |
249 | ...u, | ||
250 | |||
251 | accountMutedStatus: { | ||
252 | ...u.account, | ||
253 | |||
254 | nameWithHost: Actor.CREATE_BY_STRING(u.account.name, u.account.host), | ||
255 | |||
256 | mutedByInstance: false, | ||
257 | mutedByUser: false, | ||
258 | mutedServerByInstance: false, | ||
259 | mutedServerByUser: false | ||
260 | } | ||
261 | })) | ||
241 | this.totalRecords = resultList.total | 262 | this.totalRecords = resultList.total |
263 | |||
264 | this.loadMutedStatus() | ||
242 | }, | 265 | }, |
243 | 266 | ||
244 | error: err => this.notifier.error(err.message) | 267 | error: err => this.notifier.error(err.message) |
245 | }) | 268 | }) |
246 | } | 269 | } |
270 | |||
271 | private loadMutedStatus () { | ||
272 | this.blocklist.getStatus({ accounts: this.users.map(u => u.username + '@' + getAPIHost()) }) | ||
273 | .subscribe(blockStatus => { | ||
274 | for (const user of this.users) { | ||
275 | user.accountMutedStatus.mutedByInstance = blockStatus.accounts[user.username + '@' + getAPIHost()].blockedByServer | ||
276 | } | ||
277 | }) | ||
278 | } | ||
247 | } | 279 | } |