From cd940f40cb62fa105b14e1ce838e97f316c13c5c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 20 Jan 2023 14:58:05 +0100 Subject: Support bulk registration request removal --- .../admin-registration.service.ts | 16 +++++--- .../registration-list.component.html | 19 ++++++++- .../registration-list.component.ts | 46 +++++++++++++++++----- 3 files changed, 64 insertions(+), 17 deletions(-) (limited to 'client/src/app/+admin/moderation') diff --git a/client/src/app/+admin/moderation/registration-list/admin-registration.service.ts b/client/src/app/+admin/moderation/registration-list/admin-registration.service.ts index 012f942b3..10e2938c7 100644 --- a/client/src/app/+admin/moderation/registration-list/admin-registration.service.ts +++ b/client/src/app/+admin/moderation/registration-list/admin-registration.service.ts @@ -1,8 +1,10 @@ import { SortMeta } from 'primeng/api' -import { catchError } from 'rxjs/operators' +import { from } from 'rxjs' +import { catchError, concatMap, toArray } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor, RestPagination, RestService } from '@app/core' +import { arrayify } from '@shared/core-utils' import { ResultList, UserRegistration } from '@shared/models' import { environment } from '../../../../environments/environment' @@ -54,10 +56,14 @@ export class AdminRegistrationService { .pipe(catchError(res => this.restExtractor.handleError(res))) } - removeRegistration (registration: UserRegistration) { - const url = AdminRegistrationService.BASE_REGISTRATION_URL + '/' + registration.id + removeRegistrations (registrationsArg: UserRegistration | UserRegistration[]) { + const registrations = arrayify(registrationsArg) - return this.authHttp.delete(url) - .pipe(catchError(res => this.restExtractor.handleError(res))) + return from(registrations) + .pipe( + concatMap(r => this.authHttp.delete(AdminRegistrationService.BASE_REGISTRATION_URL + '/' + r.id)), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) } } diff --git a/client/src/app/+admin/moderation/registration-list/registration-list.component.html b/client/src/app/+admin/moderation/registration-list/registration-list.component.html index 4f9d06acc..a2b888101 100644 --- a/client/src/app/+admin/moderation/registration-list/registration-list.component.html +++ b/client/src/app/+admin/moderation/registration-list/registration-list.component.html @@ -7,12 +7,20 @@ [value]="registrations" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start" [rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" - [showCurrentPageReport]="true" i18n-currentPageReportTemplate + [(selection)]="selectedRows" [showCurrentPageReport]="true" i18n-currentPageReportTemplate currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} registrations" [expandedRowKeys]="expandedRows" >
+
+ + +
+
@@ -21,6 +29,9 @@ + + + Account @@ -34,7 +45,11 @@ - + + + + + diff --git a/client/src/app/+admin/moderation/registration-list/registration-list.component.ts b/client/src/app/+admin/moderation/registration-list/registration-list.component.ts index 37514edf5..569eccaa2 100644 --- a/client/src/app/+admin/moderation/registration-list/registration-list.component.ts +++ b/client/src/app/+admin/moderation/registration-list/registration-list.component.ts @@ -1,7 +1,8 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' +import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' +import { prepareIcu } from '@app/helpers' import { AdvancedInputFilter } from '@app/shared/shared-forms' import { DropdownAction } from '@app/shared/shared-main' import { UserRegistration, UserRegistrationState } from '@shared/models' @@ -13,7 +14,7 @@ import { ProcessRegistrationModalComponent } from './process-registration-modal. templateUrl: './registration-list.component.html', styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './registration-list.component.scss' ] }) -export class RegistrationListComponent extends RestTable implements OnInit { +export class RegistrationListComponent extends RestTable implements OnInit { @ViewChild('processRegistrationModal', { static: true }) processRegistrationModal: ProcessRegistrationModalComponent registrations: (UserRegistration & { registrationReasonHTML?: string, moderationResponseHTML?: string })[] = [] @@ -22,6 +23,7 @@ export class RegistrationListComponent extends RestTable implements OnInit { pagination: RestPagination = { count: this.rowsPerPage, start: 0 } registrationActions: DropdownAction[][] = [] + bulkActions: DropdownAction[] = [] inputFilters: AdvancedInputFilter[] = [] @@ -33,6 +35,7 @@ export class RegistrationListComponent extends RestTable implements OnInit { private server: ServerService, private notifier: Notifier, private markdownRenderer: MarkdownService, + private confirmService: ConfirmService, private adminRegistrationService: AdminRegistrationService ) { super() @@ -40,22 +43,28 @@ export class RegistrationListComponent extends RestTable implements OnInit { this.registrationActions = [ [ { - label: $localize`Accept this registration`, + label: $localize`Accept this request`, handler: registration => this.openRegistrationRequestProcessModal(registration, 'accept'), isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING }, { - label: $localize`Reject this registration`, + label: $localize`Reject this request`, handler: registration => this.openRegistrationRequestProcessModal(registration, 'reject'), isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING }, { - label: $localize`Remove this registration request`, - handler: registration => this.removeRegistration(registration), - isDisplayed: registration => registration.state.id !== UserRegistrationState.PENDING + label: $localize`Remove this request`, + handler: registration => this.removeRegistrations([ registration ]) } ] ] + + this.bulkActions = [ + { + label: $localize`Delete`, + handler: registrations => this.removeRegistrations(registrations) + } + ] } ngOnInit () { @@ -107,11 +116,28 @@ export class RegistrationListComponent extends RestTable implements OnInit { this.processRegistrationModal.openModal(registration, mode) } - private removeRegistration (registration: UserRegistration) { - this.adminRegistrationService.removeRegistration(registration) + private async removeRegistrations (registrations: UserRegistration[]) { + const icuParams = { count: registrations.length, username: registrations[0].username } + + // eslint-disable-next-line max-len + const message = prepareIcu($localize`Do you really want to delete {count, plural, =1 {{username} registration request?} other {{count} registration requests?}}`)( + icuParams, + $localize`Do you really want to delete these registration requests?` + ) + + const res = await this.confirmService.confirm(message, $localize`Delete`) + if (res === false) return + + this.adminRegistrationService.removeRegistrations(registrations) .subscribe({ next: () => { - this.notifier.success($localize`Registration request deleted.`) + // eslint-disable-next-line max-len + const message = prepareIcu($localize`Removed {count, plural, =1 {{username} registration request} other {{count} registration requests}}`)( + icuParams, + $localize`Registration requests removed` + ) + + this.notifier.success(message) this.reloadData() }, -- cgit v1.2.3