From 00004f7f6b966a975498612117212b5373f4103c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 27 Oct 2021 09:36:37 +0200 Subject: Put admin users in overview tab --- client/src/app/+admin/users/index.ts | 4 - client/src/app/+admin/users/user-edit/index.ts | 3 - .../users/user-edit/user-create.component.ts | 98 -------- .../users/user-edit/user-edit.component.html | 237 -------------------- .../users/user-edit/user-edit.component.scss | 76 ------- client/src/app/+admin/users/user-edit/user-edit.ts | 102 --------- .../users/user-edit/user-password.component.html | 21 -- .../users/user-edit/user-password.component.scss | 23 -- .../users/user-edit/user-password.component.ts | 55 ----- .../users/user-edit/user-update.component.ts | 139 ------------ client/src/app/+admin/users/user-list/index.ts | 1 - .../users/user-list/user-list.component.html | 163 -------------- .../users/user-list/user-list.component.scss | 65 ------ .../+admin/users/user-list/user-list.component.ts | 246 --------------------- client/src/app/+admin/users/users.component.ts | 7 - client/src/app/+admin/users/users.routes.ts | 51 ----- 16 files changed, 1291 deletions(-) delete mode 100644 client/src/app/+admin/users/index.ts delete mode 100644 client/src/app/+admin/users/user-edit/index.ts delete mode 100644 client/src/app/+admin/users/user-edit/user-create.component.ts delete mode 100644 client/src/app/+admin/users/user-edit/user-edit.component.html delete mode 100644 client/src/app/+admin/users/user-edit/user-edit.component.scss delete mode 100644 client/src/app/+admin/users/user-edit/user-edit.ts delete mode 100644 client/src/app/+admin/users/user-edit/user-password.component.html delete mode 100644 client/src/app/+admin/users/user-edit/user-password.component.scss delete mode 100644 client/src/app/+admin/users/user-edit/user-password.component.ts delete mode 100644 client/src/app/+admin/users/user-edit/user-update.component.ts delete mode 100644 client/src/app/+admin/users/user-list/index.ts delete mode 100644 client/src/app/+admin/users/user-list/user-list.component.html delete mode 100644 client/src/app/+admin/users/user-list/user-list.component.scss delete mode 100644 client/src/app/+admin/users/user-list/user-list.component.ts delete mode 100644 client/src/app/+admin/users/users.component.ts delete mode 100644 client/src/app/+admin/users/users.routes.ts (limited to 'client/src/app/+admin/users') diff --git a/client/src/app/+admin/users/index.ts b/client/src/app/+admin/users/index.ts deleted file mode 100644 index 156e54d89..000000000 --- a/client/src/app/+admin/users/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './user-edit' -export * from './user-list' -export * from './users.component' -export * from './users.routes' diff --git a/client/src/app/+admin/users/user-edit/index.ts b/client/src/app/+admin/users/user-edit/index.ts deleted file mode 100644 index ec734ef92..000000000 --- a/client/src/app/+admin/users/user-edit/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './user-create.component' -export * from './user-update.component' -export * from './user-password.component' diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts deleted file mode 100644 index b61b22fd0..000000000 --- a/client/src/app/+admin/users/user-edit/user-create.component.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Component, OnInit } from '@angular/core' -import { Router } from '@angular/router' -import { ConfigService } from '@app/+admin/config/shared/config.service' -import { AuthService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { - USER_CHANNEL_NAME_VALIDATOR, - USER_EMAIL_VALIDATOR, - USER_PASSWORD_OPTIONAL_VALIDATOR, - USER_PASSWORD_VALIDATOR, - USER_ROLE_VALIDATOR, - USER_USERNAME_VALIDATOR, - USER_VIDEO_QUOTA_DAILY_VALIDATOR, - USER_VIDEO_QUOTA_VALIDATOR -} from '@app/shared/form-validators/user-validators' -import { FormValidatorService } from '@app/shared/shared-forms' -import { UserCreate, UserRole } from '@shared/models' -import { UserEdit } from './user-edit' - -@Component({ - selector: 'my-user-create', - templateUrl: './user-edit.component.html', - styleUrls: [ './user-edit.component.scss' ] -}) -export class UserCreateComponent extends UserEdit implements OnInit { - error: string - - constructor ( - protected serverService: ServerService, - protected formValidatorService: FormValidatorService, - protected configService: ConfigService, - protected screenService: ScreenService, - protected auth: AuthService, - private router: Router, - private notifier: Notifier, - private userService: UserService - ) { - super() - - this.buildQuotaOptions() - } - - ngOnInit () { - super.ngOnInit() - - const defaultValues = { - role: UserRole.USER.toString(), - videoQuota: -1, - videoQuotaDaily: -1 - } - - this.buildForm({ - username: USER_USERNAME_VALIDATOR, - channelName: USER_CHANNEL_NAME_VALIDATOR, - email: USER_EMAIL_VALIDATOR, - password: this.isPasswordOptional() ? USER_PASSWORD_OPTIONAL_VALIDATOR : USER_PASSWORD_VALIDATOR, - role: USER_ROLE_VALIDATOR, - videoQuota: USER_VIDEO_QUOTA_VALIDATOR, - videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR, - byPassAutoBlock: null - }, defaultValues) - } - - formValidated () { - this.error = undefined - - const userCreate: UserCreate = this.form.value - - userCreate.adminFlags = this.buildAdminFlags(this.form.value) - - // A select in HTML is always mapped as a string, we convert it to number - userCreate.videoQuota = parseInt(this.form.value['videoQuota'], 10) - userCreate.videoQuotaDaily = parseInt(this.form.value['videoQuotaDaily'], 10) - - this.userService.addUser(userCreate) - .subscribe({ - next: () => { - this.notifier.success($localize`User ${userCreate.username} created.`) - this.router.navigate([ '/admin/users/list' ]) - }, - - error: err => { - this.error = err.message - } - }) - } - - isCreation () { - return true - } - - isPasswordOptional () { - return this.serverConfig.email.enabled - } - - getFormButtonTitle () { - return $localize`Create user` - } -} diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html deleted file mode 100644 index 772ebf272..000000000 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - -
-
- -
- -
-
- -
{{ error }}
- -
-
-
- - -
- -
- -
-
- - -
- {{ formErrors.username }} -
-
- -
- - -
- {{ formErrors.channelName }} -
-
- -
- - -
- {{ formErrors.email }} -
-
- -
- - - - - If you leave the password empty, an email will be sent to the user. - - - - - - -
- {{ formErrors.password }} -
-
- -
- -
- -
- -
- {{ formErrors.role }} -
-
- -
- - - - -
- Transcoding is enabled. The video quota only takes into account original video size.
- At most, this user could upload ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}. -
- -
- {{ formErrors.videoQuota }} -
-
- -
- - - - -
- {{ formErrors.videoQuotaDaily }} -
-
- -
- - -
- -
-
- -
- -
- - -
- -
- -
- -
-
- - -
-
-
- -
- -
- -
-
- - -
- -
- - -
-
- -
-
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 deleted file mode 100644 index d7932154b..000000000 --- a/client/src/app/+admin/users/user-edit/user-edit.component.scss +++ /dev/null @@ -1,76 +0,0 @@ -@use 'sass:math'; -@use '_variables' as *; -@use '_mixins' as *; - -$form-base-input-width: 340px; - -label { - font-weight: $font-regular; - font-size: 100%; -} - -.account-title { - @include settings-big-title; - - &.account-title-danger { - color: lighten($color: #c54130, $amount: 10); - } -} - -input:not([type=submit]) { - @include peertube-input-text($form-base-input-width); - display: block; -} - -my-input-toggle-hidden { - @include responsive-width($form-base-input-width); - - display: block; -} - -.peertube-select-container { - @include peertube-select-container($form-base-input-width); -} - -my-select-custom-value { - @include responsive-width($form-base-input-width); - - display: block; -} - -input[type=submit], -button { - @include peertube-button; - @include orange-button; - - margin-top: 10px; -} - -.transcoding-information { - margin-top: 5px; - font-size: 11px; -} - -.danger-zone { - .reset-password-email { - margin-bottom: 30px; - - button { - @include peertube-button; - @include danger-button; - @include disable-outline; - - display: block; - margin-top: 0; - } - } -} - -.breadcrumb { - @include breadcrumb; -} - -.dashboard { - @include dashboard; - max-width: 900px; -} diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts deleted file mode 100644 index af5e674a7..000000000 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Directive, OnInit } from '@angular/core' -import { ConfigService } from '@app/+admin/config/shared/config.service' -import { AuthService, ScreenService, ServerService, User } from '@app/core' -import { FormReactive } from '@app/shared/shared-forms' -import { USER_ROLE_LABELS } from '@shared/core-utils/users' -import { HTMLServerConfig, UserAdminFlag, UserRole, VideoResolution } from '@shared/models' -import { SelectOptionsItem } from '../../../../types/select-options-item.model' - -@Directive() -// eslint-disable-next-line @angular-eslint/directive-class-suffix -export abstract class UserEdit extends FormReactive implements OnInit { - videoQuotaOptions: SelectOptionsItem[] = [] - videoQuotaDailyOptions: SelectOptionsItem[] = [] - username: string - user: User - - roles: { value: string, label: string }[] = [] - - protected serverConfig: HTMLServerConfig - - protected abstract serverService: ServerService - protected abstract configService: ConfigService - protected abstract screenService: ScreenService - protected abstract auth: AuthService - abstract isCreation (): boolean - abstract getFormButtonTitle (): string - - ngOnInit (): void { - this.serverConfig = this.serverService.getHTMLConfig() - - this.buildRoles() - } - - get subscribersCount () { - const forAccount = this.user - ? this.user.account.followersCount - : 0 - const forChannels = this.user - ? this.user.videoChannels.map(c => c.followersCount).reduce((a, b) => a + b, 0) - : 0 - return forAccount + forChannels - } - - getAuthPlugins () { - return this.serverConfig.plugin.registeredIdAndPassAuths.map(p => p.npmName) - .concat(this.serverConfig.plugin.registeredExternalAuths.map(p => p.npmName)) - } - - isInBigView () { - return this.screenService.getWindowInnerWidth() > 1600 - } - - buildRoles () { - const authUser = this.auth.getUser() - - if (authUser.role === UserRole.ADMINISTRATOR) { - this.roles = Object.keys(USER_ROLE_LABELS) - .map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] })) - return - } - - this.roles = [ - { value: UserRole.USER.toString(), label: USER_ROLE_LABELS[UserRole.USER] } - ] - } - - isTranscodingInformationDisplayed () { - const formVideoQuota = parseInt(this.form.value['videoQuota'], 10) - - return this.serverConfig.transcoding.enabledResolutions.length !== 0 && - formVideoQuota > 0 - } - - computeQuotaWithTranscoding () { - const transcodingConfig = this.serverConfig.transcoding - - const resolutions = transcodingConfig.enabledResolutions - const higherResolution = VideoResolution.H_4K - let multiplier = 0 - - for (const resolution of resolutions) { - multiplier += resolution / higherResolution - } - - if (transcodingConfig.hls.enabled) multiplier *= 2 - - return multiplier * parseInt(this.form.value['videoQuota'], 10) - } - - resetPassword () { - return - } - - protected buildAdminFlags (formValue: any) { - return formValue.byPassAutoBlock ? UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST : UserAdminFlag.NONE - } - - protected buildQuotaOptions () { - this.videoQuotaOptions = this.configService.videoQuotaOptions - this.videoQuotaDailyOptions = this.configService.videoQuotaDailyOptions - } -} diff --git a/client/src/app/+admin/users/user-edit/user-password.component.html b/client/src/app/+admin/users/user-edit/user-password.component.html deleted file mode 100644 index 1238d1839..000000000 --- a/client/src/app/+admin/users/user-edit/user-password.component.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
- -
- -
- -
-
-
- {{ formErrors.password }} -
-
- - -
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 deleted file mode 100644 index acb680682..000000000 --- a/client/src/app/+admin/users/user-edit/user-password.component.scss +++ /dev/null @@ -1,23 +0,0 @@ -@use '_variables' as *; -@use '_mixins' as *; - -input:not([type=submit]):not([type=checkbox]) { - @include peertube-input-text(340px); - - display: block; - border-top-right-radius: 0; - border-bottom-right-radius: 0; - border-right: 0; -} - -input[type=submit] { - @include peertube-button; - @include danger-button; - @include disable-outline; - - margin-top: 10px; -} - -.input-group-append { - height: 30px; -} diff --git a/client/src/app/+admin/users/user-edit/user-password.component.ts b/client/src/app/+admin/users/user-edit/user-password.component.ts deleted file mode 100644 index 42bf20de1..000000000 --- a/client/src/app/+admin/users/user-edit/user-password.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core' -import { Notifier, UserService } from '@app/core' -import { USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators' -import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' -import { UserUpdate } from '@shared/models' - -@Component({ - selector: 'my-user-password', - templateUrl: './user-password.component.html', - styleUrls: [ './user-password.component.scss' ] -}) -export class UserPasswordComponent extends FormReactive implements OnInit { - error: string - username: string - showPassword = false - - @Input() userId: number - - constructor ( - protected formValidatorService: FormValidatorService, - private notifier: Notifier, - private userService: UserService - ) { - super() - } - - ngOnInit () { - this.buildForm({ - password: USER_PASSWORD_VALIDATOR - }) - } - - formValidated () { - this.error = undefined - - const userUpdate: UserUpdate = this.form.value - - this.userService.updateUser(this.userId, userUpdate) - .subscribe({ - next: () => this.notifier.success($localize`Password changed for user ${this.username}.`), - - error: err => { - this.error = err.message - } - }) - } - - togglePasswordVisibility () { - this.showPassword = !this.showPassword - } - - getFormButtonTitle () { - return $localize`Update user password` - } -} diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts deleted file mode 100644 index 42599a17e..000000000 --- a/client/src/app/+admin/users/user-edit/user-update.component.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Subscription } from 'rxjs' -import { Component, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { ConfigService } from '@app/+admin/config/shared/config.service' -import { AuthService, Notifier, ScreenService, ServerService, User, UserService } from '@app/core' -import { - USER_EMAIL_VALIDATOR, - USER_ROLE_VALIDATOR, - USER_VIDEO_QUOTA_DAILY_VALIDATOR, - USER_VIDEO_QUOTA_VALIDATOR -} from '@app/shared/form-validators/user-validators' -import { FormValidatorService } from '@app/shared/shared-forms' -import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@shared/models' -import { UserEdit } from './user-edit' - -@Component({ - selector: 'my-user-update', - templateUrl: './user-edit.component.html', - styleUrls: [ './user-edit.component.scss' ] -}) -export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { - error: string - - private paramsSub: Subscription - - constructor ( - protected formValidatorService: FormValidatorService, - protected serverService: ServerService, - protected configService: ConfigService, - protected screenService: ScreenService, - protected auth: AuthService, - private route: ActivatedRoute, - private router: Router, - private notifier: Notifier, - private userService: UserService - ) { - super() - - this.buildQuotaOptions() - } - - ngOnInit () { - super.ngOnInit() - - const defaultValues = { - role: UserRole.USER.toString(), - videoQuota: '-1', - videoQuotaDaily: '-1' - } - - this.buildForm({ - email: USER_EMAIL_VALIDATOR, - role: USER_ROLE_VALIDATOR, - videoQuota: USER_VIDEO_QUOTA_VALIDATOR, - videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR, - byPassAutoBlock: null, - pluginAuth: null - }, defaultValues) - - this.paramsSub = this.route.params.subscribe(routeParams => { - const userId = routeParams['id'] - this.userService.getUser(userId, true) - .subscribe({ - next: user => this.onUserFetched(user), - - error: err => { - this.error = err.message - } - }) - }) - } - - ngOnDestroy () { - this.paramsSub.unsubscribe() - } - - formValidated () { - this.error = undefined - - const userUpdate: UserUpdate = this.form.value - userUpdate.adminFlags = this.buildAdminFlags(this.form.value) - - // A select in HTML is always mapped as a string, we convert it to number - userUpdate.videoQuota = parseInt(this.form.value['videoQuota'], 10) - userUpdate.videoQuotaDaily = parseInt(this.form.value['videoQuotaDaily'], 10) - - if (userUpdate.pluginAuth === 'null') userUpdate.pluginAuth = null - - this.userService.updateUser(this.user.id, userUpdate) - .subscribe({ - next: () => { - this.notifier.success($localize`User ${this.user.username} updated.`) - this.router.navigate([ '/admin/users/list' ]) - }, - - error: err => { - this.error = err.message - } - }) - } - - isCreation () { - return false - } - - isPasswordOptional () { - return false - } - - getFormButtonTitle () { - return $localize`Update user` - } - - resetPassword () { - this.userService.askResetPassword(this.user.email) - .subscribe({ - next: () => { - this.notifier.success($localize`An email asking for password reset has been sent to ${this.user.username}.`) - }, - - error: err => { - this.error = err.message - } - }) - } - - private onUserFetched (userJson: UserType) { - this.user = new User(userJson) - - this.form.patchValue({ - email: userJson.email, - role: userJson.role.toString(), - videoQuota: userJson.videoQuota, - videoQuotaDaily: userJson.videoQuotaDaily, - pluginAuth: userJson.pluginAuth, - byPassAutoBlock: userJson.adminFlags & UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST - }) - } -} diff --git a/client/src/app/+admin/users/user-list/index.ts b/client/src/app/+admin/users/user-list/index.ts deleted file mode 100644 index 1826a4abe..000000000 --- a/client/src/app/+admin/users/user-list/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './user-list.component' 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 deleted file mode 100644 index c82f3c06f..000000000 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ /dev/null @@ -1,163 +0,0 @@ - - -
- - -
- -
- -
-
- - - - - - - - -
- - - -
- - {{ getColumn('username').label }} - {{ getColumn('email').label }} - {{ getColumn('quota').label }} - {{ getColumn('quotaDaily').label }} - {{ getColumn('role').label }} - {{ getColumn('pluginAuth').label }} - {{ getColumn('createdAt').label }} - {{ getColumn('lastLoginDate').label }} - -
- - - - - - - - - - - - - - - - - - - - - -
- -
- {{ user.account.displayName }} - {{ user.username }} -
-
-
- - - - - {{ user.email }} - - - - - - ? {{ user.email }} - - - - ✓ {{ user.email }} - - - - - -
-
-
- {{ user.videoQuotaUsed }} - {{ user.videoQuota }} -
- - - -
-
-
- {{ user.videoQuotaUsedDaily }} - {{ user.videoQuotaDaily }} -
- - - - {{ user.roleLabel }} - {{ user.roleLabel }} - - - - {{ user.pluginAuth }} - - - {{ user.createdAt | date: 'short' }} - - {{ user.lastLoginDate | date: 'short' }} - -
- - - - - Ban reason: - {{ user.blockedReason }} - - - -
- - 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 deleted file mode 100644 index e425306b5..000000000 --- a/client/src/app/+admin/users/user-list/user-list.component.scss +++ /dev/null @@ -1,65 +0,0 @@ -@use '_variables' as *; -@use '_mixins' as *; - -.add-button { - @include create-button; -} - -tr.banned > td { - background-color: lighten($color: $red, $amount: 40) !important; -} - -.table-email { - @include disable-default-a-behaviour; - - color: pvar(--mainForegroundColor); -} - -.banned-info { - font-style: italic; -} - -.ban-reason-label { - font-weight: $font-semibold; -} - -.user-table-primary-text .glyphicon { - @include margin-left(0.1rem); - - font-size: 80%; - color: #808080; -} - -p-tableCheckbox { - position: relative; - top: -2.5px; -} - -my-global-icon { - width: 18px; -} - -.chip { - @include chip; -} - -.badge { - @include table-badge; -} - -.progress { - @include progressbar($small: true); - - width: auto; - max-width: 100%; -} - -@media screen and (max-width: $primeng-breakpoint) { - .progress { - width: 100%; - } - - .empty-cell { - padding: 0; - } -} 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 deleted file mode 100644 index 548e6e80f..000000000 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ /dev/null @@ -1,246 +0,0 @@ -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, UserService } from '@app/core' -import { AdvancedInputFilter } from '@app/shared/shared-forms' -import { DropdownAction } from '@app/shared/shared-main' -import { UserBanModalComponent } from '@app/shared/shared-moderation' -import { User, UserRole } from '@shared/models' - -type UserForList = User & { - rawVideoQuota: number - rawVideoQuotaUsed: number - rawVideoQuotaDaily: number - rawVideoQuotaUsedDaily: number -} - -@Component({ - selector: 'my-user-list', - templateUrl: './user-list.component.html', - styleUrls: [ './user-list.component.scss' ] -}) -export class UserListComponent extends RestTable implements OnInit { - @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent - - users: User[] = [] - - totalRecords = 0 - sort: SortMeta = { field: 'createdAt', order: 1 } - pagination: RestPagination = { count: this.rowsPerPage, start: 0 } - - highlightBannedUsers = false - - selectedUsers: User[] = [] - bulkUserActions: DropdownAction[][] = [] - columns: { id: string, label: string }[] - - inputFilters: AdvancedInputFilter[] = [ - { - title: $localize`Advanced filters`, - children: [ - { - queryParams: { search: 'banned:true' }, - label: $localize`Banned users` - } - ] - } - ] - - requiresEmailVerification = false - - private _selectedColumns: string[] - - constructor ( - protected route: ActivatedRoute, - protected router: Router, - private notifier: Notifier, - private confirmService: ConfirmService, - private serverService: ServerService, - private auth: AuthService, - private userService: UserService - ) { - super() - } - - get authUser () { - return this.auth.getUser() - } - - get selectedColumns () { - return this._selectedColumns - } - - set selectedColumns (val: string[]) { - this._selectedColumns = val - } - - ngOnInit () { - this.serverService.getConfig() - .subscribe(config => this.requiresEmailVerification = config.signup.requiresEmailVerification) - - this.initialize() - - this.bulkUserActions = [ - [ - { - label: $localize`Delete`, - description: $localize`Videos will be deleted, comments will be tombstoned.`, - handler: users => this.removeUsers(users), - isDisplayed: users => users.every(u => this.authUser.canManage(u)) - }, - { - label: $localize`Ban`, - description: $localize`User won't be able to login anymore, but videos and comments will be kept as is.`, - handler: users => this.openBanUserModal(users), - isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === false) - }, - { - label: $localize`Unban`, - handler: users => this.unbanUsers(users), - isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === true) - } - ], - [ - { - label: $localize`Set Email as Verified`, - handler: users => this.setEmailsAsVerified(users), - isDisplayed: users => { - return this.requiresEmailVerification && - users.every(u => this.authUser.canManage(u) && !u.blocked && u.emailVerified === false) - } - } - ] - ] - - this.columns = [ - { id: 'username', label: $localize`Username` }, - { id: 'email', label: $localize`Email` }, - { id: 'quota', label: $localize`Video quota` }, - { id: 'role', label: $localize`Role` }, - { id: 'createdAt', label: $localize`Created` } - ] - - this.selectedColumns = this.columns.map(c => c.id) - - 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` }) - } - - getIdentifier () { - return 'UserListComponent' - } - - getRoleClass (role: UserRole) { - switch (role) { - case UserRole.ADMINISTRATOR: - return 'badge-purple' - case UserRole.MODERATOR: - return 'badge-blue' - default: - return 'badge-yellow' - } - } - - isSelected (id: string) { - return this.selectedColumns.find(c => c === id) - } - - getColumn (id: string) { - return this.columns.find(c => c.id === id) - } - - getUserVideoQuotaPercentage (user: UserForList) { - return user.rawVideoQuotaUsed * 100 / user.rawVideoQuota - } - - getUserVideoQuotaDailyPercentage (user: UserForList) { - return user.rawVideoQuotaUsedDaily * 100 / user.rawVideoQuotaDaily - } - - openBanUserModal (users: User[]) { - for (const user of users) { - if (user.username === 'root') { - this.notifier.error($localize`You cannot ban root.`) - return - } - } - - this.userBanModal.openModal(users) - } - - onUserChanged () { - this.reloadData() - } - - async unbanUsers (users: User[]) { - const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) - if (res === false) return - - this.userService.unbanUsers(users) - .subscribe({ - next: () => { - this.notifier.success($localize`${users.length} users unbanned.`) - this.reloadData() - }, - - error: err => this.notifier.error(err.message) - }) - } - - async removeUsers (users: User[]) { - for (const user of users) { - if (user.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 res = await this.confirmService.confirm(message, $localize`Delete`) - if (res === false) return - - this.userService.removeUser(users) - .subscribe({ - next: () => { - this.notifier.success($localize`${users.length} users deleted.`) - this.reloadData() - }, - - error: err => this.notifier.error(err.message) - }) - } - - setEmailsAsVerified (users: User[]) { - this.userService.updateUsers(users, { emailVerified: true }) - .subscribe({ - next: () => { - this.notifier.success($localize`${users.length} users email set as verified.`) - this.reloadData() - }, - - error: err => this.notifier.error(err.message) - }) - } - - isInSelectionMode () { - return this.selectedUsers.length !== 0 - } - - protected reloadData () { - this.selectedUsers = [] - - this.userService.getUsers({ - pagination: this.pagination, - sort: this.sort, - search: this.search - }).subscribe({ - next: resultList => { - this.users = resultList.data - this.totalRecords = resultList.total - }, - - error: err => this.notifier.error(err.message) - }) - } -} diff --git a/client/src/app/+admin/users/users.component.ts b/client/src/app/+admin/users/users.component.ts deleted file mode 100644 index e9c8f6b0d..000000000 --- a/client/src/app/+admin/users/users.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core' - -@Component({ - template: '' -}) -export class UsersComponent { -} diff --git a/client/src/app/+admin/users/users.routes.ts b/client/src/app/+admin/users/users.routes.ts deleted file mode 100644 index 9175be067..000000000 --- a/client/src/app/+admin/users/users.routes.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Routes } from '@angular/router' -import { UserRightGuard } from '@app/core' -import { UserRight } from '@shared/models' -import { UserCreateComponent, UserUpdateComponent } from './user-edit' -import { UserListComponent } from './user-list' -import { UsersComponent } from './users.component' - -export const UsersRoutes: Routes = [ - { - path: 'users', - component: UsersComponent, - canActivate: [ UserRightGuard ], - data: { - userRight: UserRight.MANAGE_USERS - }, - children: [ - { - path: '', - redirectTo: 'list', - pathMatch: 'full' - }, - { - path: 'list', - component: UserListComponent, - data: { - meta: { - title: $localize`Users list` - } - } - }, - { - path: 'create', - component: UserCreateComponent, - data: { - meta: { - title: $localize`Create a user` - } - } - }, - { - path: 'update/:id', - component: UserUpdateComponent, - data: { - meta: { - title: $localize`Update a user` - } - } - } - ] - } -] -- cgit v1.2.3