import { SortMeta } from 'primeng/api'
import { Component, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
-import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
-import { getAPIHost } from '@app/helpers'
+import { AuthService, ConfirmService, LocalStorageService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
+import { prepareIcu, getAPIHost } from '@app/helpers'
import { AdvancedInputFilter } from '@app/shared/shared-forms'
import { Actor, DropdownAction } from '@app/shared/shared-main'
import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation'
styleUrls: [ './user-list.component.scss' ]
})
export class UserListComponent extends RestTable implements OnInit {
+ private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns'
+
@ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
users: (User & { accountMutedStatus: AccountMutedStatus })[] = []
requiresEmailVerification = false
- private _selectedColumns: string[]
+ private _selectedColumns: string[] = []
constructor (
protected route: ActivatedRoute,
private serverService: ServerService,
private auth: AuthService,
private blocklist: BlocklistService,
- private userAdminService: UserAdminService
+ private userAdminService: UserAdminService,
+ private peertubeLocalStorage: LocalStorageService
) {
super()
}
}
get selectedColumns () {
- return this._selectedColumns
+ return this._selectedColumns || []
}
set selectedColumns (val: string[]) {
this._selectedColumns = val
+
+ this.saveSelectedColumns()
}
ngOnInit () {
{ id: 'role', label: $localize`Role` },
{ id: 'email', label: $localize`Email` },
{ id: 'quota', label: $localize`Video quota` },
- { id: 'createdAt', label: $localize`Created` }
+ { id: 'createdAt', label: $localize`Created` },
+ { id: 'lastLoginDate', label: $localize`Last login` },
+
+ { id: 'quotaDaily', label: $localize`Daily quota` },
+ { id: 'pluginAuth', label: $localize`Auth plugin` }
]
- this.selectedColumns = this.columns.map(c => c.id)
+ this.loadSelectedColumns()
+ }
+
+ loadSelectedColumns () {
+ const result = this.peertubeLocalStorage.getItem(UserListComponent.LOCAL_STORAGE_SELECTED_COLUMNS_KEY)
- this.columns.push({ id: 'quotaDaily', label: $localize`Daily quota` })
- this.columns.push({ id: 'pluginAuth', label: $localize`Auth plugin` })
- this.columns.push({ id: 'lastLoginDate', label: $localize`Last login` })
+ if (result) {
+ try {
+ this.selectedColumns = JSON.parse(result)
+ return
+ } catch (err) {
+ console.error('Cannot load selected columns.', err)
+ }
+ }
+
+ // Default behaviour
+ this.selectedColumns = [ 'username', 'role', 'email', 'quota', 'createdAt', 'lastLoginDate' ]
+ return
+ }
+
+ saveSelectedColumns () {
+ this.peertubeLocalStorage.setItem(UserListComponent.LOCAL_STORAGE_SELECTED_COLUMNS_KEY, JSON.stringify(this.selectedColumns))
}
getIdentifier () {
}
async unbanUsers (users: User[]) {
- const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`)
+ const res = await this.confirmService.confirm(
+ prepareIcu($localize`Do you really want to unban {count, plural, =1 {1 user} other {{count} users}}?`)(
+ { count: users.length },
+ $localize`Do you really want to unban ${users.length} users?`
+ ),
+ $localize`Unban`
+ )
+
if (res === false) return
this.userAdminService.unbanUsers(users)
.subscribe({
next: () => {
- this.notifier.success($localize`${users.length} users unbanned.`)
+ this.notifier.success(
+ prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} unbanned.`)(
+ { count: users.length },
+ $localize`${users.length} users unbanned.`
+ )
+ )
this.reloadData()
},
}
async removeUsers (users: User[]) {
- for (const user of users) {
- if (user.username === 'root') {
- this.notifier.error($localize`You cannot delete root.`)
- return
- }
+ if (users.some(u => u.username === 'root')) {
+ this.notifier.error($localize`You cannot delete root.`)
+ return
}
- const message = $localize`If you remove these users, you will not be able to create others with the same username!`
+ const message = $localize`<p>You can't create users or channels with a username that already used by a deleted user/channel.</p>` +
+ $localize`It means the following usernames will be permanently deleted and cannot be recovered:` +
+ '<ul>' + users.map(u => '<li>' + u.username + '</li>').join('') + '</ul>'
+
const res = await this.confirmService.confirm(message, $localize`Delete`)
if (res === false) return
this.userAdminService.removeUser(users)
.subscribe({
next: () => {
- this.notifier.success($localize`${users.length} users deleted.`)
+ this.notifier.success(
+ prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} deleted.`)(
+ { count: users.length },
+ $localize`${users.length} users deleted.`
+ )
+ )
+
this.reloadData()
},
this.userAdminService.updateUsers(users, { emailVerified: true })
.subscribe({
next: () => {
- this.notifier.success($localize`${users.length} users email set as verified.`)
+ this.notifier.success(
+ prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} email set as verified.`)(
+ { count: users.length },
+ $localize`${users.length} users email set as verified.`
+ )
+ )
+
this.reloadData()
},