Support bulk registration request removal
This commit is contained in:
parent
9436936cf6
commit
cd940f40cb
|
@ -9,14 +9,14 @@
|
||||||
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
|
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers"
|
||||||
[(selection)]="selectedFollows"
|
[(selection)]="selectedRows"
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<div class="left-buttons">
|
<div class="left-buttons">
|
||||||
<my-action-dropdown
|
<my-action-dropdown
|
||||||
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
[actions]="bulkFollowsActions" [entry]="selectedFollows"
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
>
|
>
|
||||||
</my-action-dropdown>
|
</my-action-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { ActorFollow } from '@shared/models'
|
||||||
templateUrl: './followers-list.component.html',
|
templateUrl: './followers-list.component.html',
|
||||||
styleUrls: [ './followers-list.component.scss' ]
|
styleUrls: [ './followers-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class FollowersListComponent extends RestTable implements OnInit {
|
export class FollowersListComponent extends RestTable <ActorFollow> implements OnInit {
|
||||||
followers: ActorFollow[] = []
|
followers: ActorFollow[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
|
@ -20,8 +20,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
searchFilters: AdvancedInputFilter[] = []
|
searchFilters: AdvancedInputFilter[] = []
|
||||||
|
|
||||||
selectedFollows: ActorFollow[] = []
|
bulkActions: DropdownAction<ActorFollow[]>[] = []
|
||||||
bulkFollowsActions: DropdownAction<ActorFollow[]>[] = []
|
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private confirmService: ConfirmService,
|
private confirmService: ConfirmService,
|
||||||
|
@ -36,7 +35,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
this.searchFilters = this.followService.buildFollowsListFilters()
|
this.searchFilters = this.followService.buildFollowsListFilters()
|
||||||
|
|
||||||
this.bulkFollowsActions = [
|
this.bulkActions = [
|
||||||
{
|
{
|
||||||
label: $localize`Reject`,
|
label: $localize`Reject`,
|
||||||
handler: follows => this.rejectFollower(follows),
|
handler: follows => this.rejectFollower(follows),
|
||||||
|
@ -105,12 +104,14 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteFollowers (follows: ActorFollow[]) {
|
async deleteFollowers (follows: ActorFollow[]) {
|
||||||
|
const icuParams = { count: follows.length, followerName: this.buildFollowerName(follows[0]) }
|
||||||
|
|
||||||
let message = $localize`Deleted followers will be able to send again a follow request.`
|
let message = $localize`Deleted followers will be able to send again a follow request.`
|
||||||
message += '<br /><br />'
|
message += '<br /><br />'
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
message += prepareIcu($localize`Do you really want to delete {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`)(
|
message += prepareIcu($localize`Do you really want to delete {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`)(
|
||||||
{ count: follows.length, followerName: this.buildFollowerName(follows[0]) },
|
icuParams,
|
||||||
$localize`Do you really want to delete these follow requests?`
|
$localize`Do you really want to delete these follow requests?`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
next: () => {
|
next: () => {
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const message = prepareIcu($localize`Removed {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`)(
|
const message = prepareIcu($localize`Removed {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`)(
|
||||||
{ count: follows.length, followerName: this.buildFollowerName(follows[0]) },
|
icuParams,
|
||||||
$localize`Follow requests removed`
|
$localize`Follow requests removed`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -139,10 +140,6 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
||||||
return follow.follower.name + '@' + follow.follower.host
|
return follow.follower.name + '@' + follow.follower.host
|
||||||
}
|
}
|
||||||
|
|
||||||
isInSelectionMode () {
|
|
||||||
return this.selectedFollows.length !== 0
|
|
||||||
}
|
|
||||||
|
|
||||||
protected reloadData () {
|
protected reloadData () {
|
||||||
this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search })
|
this.followService.getFollowers({ pagination: this.pagination, sort: this.sort, search: this.search })
|
||||||
.subscribe({
|
.subscribe({
|
||||||
|
|
|
@ -9,14 +9,14 @@
|
||||||
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
|
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts"
|
||||||
[(selection)]="selectedFollows"
|
[(selection)]="selectedRows"
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<div class="left-buttons">
|
<div class="left-buttons">
|
||||||
<my-action-dropdown
|
<my-action-dropdown
|
||||||
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
[actions]="bulkFollowsActions" [entry]="selectedFollows"
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
>
|
>
|
||||||
</my-action-dropdown>
|
</my-action-dropdown>
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { prepareIcu } from '@app/helpers'
|
||||||
templateUrl: './following-list.component.html',
|
templateUrl: './following-list.component.html',
|
||||||
styleUrls: [ './following-list.component.scss' ]
|
styleUrls: [ './following-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class FollowingListComponent extends RestTable implements OnInit {
|
export class FollowingListComponent extends RestTable <ActorFollow> implements OnInit {
|
||||||
@ViewChild('followModal') followModal: FollowModalComponent
|
@ViewChild('followModal') followModal: FollowModalComponent
|
||||||
|
|
||||||
following: ActorFollow[] = []
|
following: ActorFollow[] = []
|
||||||
|
@ -22,8 +22,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
searchFilters: AdvancedInputFilter[] = []
|
searchFilters: AdvancedInputFilter[] = []
|
||||||
|
|
||||||
selectedFollows: ActorFollow[] = []
|
bulkActions: DropdownAction<ActorFollow[]>[] = []
|
||||||
bulkFollowsActions: DropdownAction<ActorFollow[]>[] = []
|
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
|
@ -38,7 +37,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
this.searchFilters = this.followService.buildFollowsListFilters()
|
this.searchFilters = this.followService.buildFollowsListFilters()
|
||||||
|
|
||||||
this.bulkFollowsActions = [
|
this.bulkActions = [
|
||||||
{
|
{
|
||||||
label: $localize`Delete`,
|
label: $localize`Delete`,
|
||||||
handler: follows => this.removeFollowing(follows)
|
handler: follows => this.removeFollowing(follows)
|
||||||
|
@ -58,10 +57,6 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
return follow.following.name === 'peertube'
|
return follow.following.name === 'peertube'
|
||||||
}
|
}
|
||||||
|
|
||||||
isInSelectionMode () {
|
|
||||||
return this.selectedFollows.length !== 0
|
|
||||||
}
|
|
||||||
|
|
||||||
buildFollowingName (follow: ActorFollow) {
|
buildFollowingName (follow: ActorFollow) {
|
||||||
return follow.following.name + '@' + follow.following.host
|
return follow.following.name + '@' + follow.following.host
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { SortMeta } from 'primeng/api'
|
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 { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { RestExtractor, RestPagination, RestService } from '@app/core'
|
import { RestExtractor, RestPagination, RestService } from '@app/core'
|
||||||
|
import { arrayify } from '@shared/core-utils'
|
||||||
import { ResultList, UserRegistration } from '@shared/models'
|
import { ResultList, UserRegistration } from '@shared/models'
|
||||||
import { environment } from '../../../../environments/environment'
|
import { environment } from '../../../../environments/environment'
|
||||||
|
|
||||||
|
@ -54,10 +56,14 @@ export class AdminRegistrationService {
|
||||||
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
||||||
}
|
}
|
||||||
|
|
||||||
removeRegistration (registration: UserRegistration) {
|
removeRegistrations (registrationsArg: UserRegistration | UserRegistration[]) {
|
||||||
const url = AdminRegistrationService.BASE_REGISTRATION_URL + '/' + registration.id
|
const registrations = arrayify(registrationsArg)
|
||||||
|
|
||||||
return this.authHttp.delete(url)
|
return from(registrations)
|
||||||
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
.pipe(
|
||||||
|
concatMap(r => this.authHttp.delete(AdminRegistrationService.BASE_REGISTRATION_URL + '/' + r.id)),
|
||||||
|
toArray(),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,20 @@
|
||||||
[value]="registrations" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
[value]="registrations" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
||||||
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
|
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id"
|
||||||
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false"
|
[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"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} registrations"
|
||||||
[expandedRowKeys]="expandedRows"
|
[expandedRowKeys]="expandedRows"
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
|
<div class="left-buttons">
|
||||||
|
<my-action-dropdown
|
||||||
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
|
>
|
||||||
|
</my-action-dropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="ms-auto">
|
<div class="ms-auto">
|
||||||
<my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
|
<my-advanced-input-filter (search)="onSearch($event)"></my-advanced-input-filter>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +29,9 @@
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr> <!-- header -->
|
<tr> <!-- header -->
|
||||||
|
<th style="width: 40px">
|
||||||
|
<p-tableHeaderCheckbox ariaLabel="Select all rows" i18n-ariaLabel></p-tableHeaderCheckbox>
|
||||||
|
</th>
|
||||||
<th style="width: 40px;"></th>
|
<th style="width: 40px;"></th>
|
||||||
<th style="width: 150px;"></th>
|
<th style="width: 150px;"></th>
|
||||||
<th i18n>Account</th>
|
<th i18n>Account</th>
|
||||||
|
@ -34,7 +45,11 @@
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="body" let-expanded="expanded" let-registration>
|
<ng-template pTemplate="body" let-expanded="expanded" let-registration>
|
||||||
<tr>
|
<tr [pSelectableRow]="registration">
|
||||||
|
<td class="checkbox-cell">
|
||||||
|
<p-tableCheckbox [value]="registration" ariaLabel="Select this row" i18n-ariaLabel></p-tableCheckbox>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td class="expand-cell" [pRowToggler]="registration">
|
<td class="expand-cell" [pRowToggler]="registration">
|
||||||
<my-table-expander-icon [expanded]="expanded"></my-table-expander-icon>
|
<my-table-expander-icon [expanded]="expanded"></my-table-expander-icon>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core'
|
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
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 { AdvancedInputFilter } from '@app/shared/shared-forms'
|
||||||
import { DropdownAction } from '@app/shared/shared-main'
|
import { DropdownAction } from '@app/shared/shared-main'
|
||||||
import { UserRegistration, UserRegistrationState } from '@shared/models'
|
import { UserRegistration, UserRegistrationState } from '@shared/models'
|
||||||
|
@ -13,7 +14,7 @@ import { ProcessRegistrationModalComponent } from './process-registration-modal.
|
||||||
templateUrl: './registration-list.component.html',
|
templateUrl: './registration-list.component.html',
|
||||||
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './registration-list.component.scss' ]
|
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './registration-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class RegistrationListComponent extends RestTable implements OnInit {
|
export class RegistrationListComponent extends RestTable <UserRegistration> implements OnInit {
|
||||||
@ViewChild('processRegistrationModal', { static: true }) processRegistrationModal: ProcessRegistrationModalComponent
|
@ViewChild('processRegistrationModal', { static: true }) processRegistrationModal: ProcessRegistrationModalComponent
|
||||||
|
|
||||||
registrations: (UserRegistration & { registrationReasonHTML?: string, moderationResponseHTML?: string })[] = []
|
registrations: (UserRegistration & { registrationReasonHTML?: string, moderationResponseHTML?: string })[] = []
|
||||||
|
@ -22,6 +23,7 @@ export class RegistrationListComponent extends RestTable implements OnInit {
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
registrationActions: DropdownAction<UserRegistration>[][] = []
|
registrationActions: DropdownAction<UserRegistration>[][] = []
|
||||||
|
bulkActions: DropdownAction<UserRegistration[]>[] = []
|
||||||
|
|
||||||
inputFilters: AdvancedInputFilter[] = []
|
inputFilters: AdvancedInputFilter[] = []
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ export class RegistrationListComponent extends RestTable implements OnInit {
|
||||||
private server: ServerService,
|
private server: ServerService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private markdownRenderer: MarkdownService,
|
private markdownRenderer: MarkdownService,
|
||||||
|
private confirmService: ConfirmService,
|
||||||
private adminRegistrationService: AdminRegistrationService
|
private adminRegistrationService: AdminRegistrationService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
@ -40,22 +43,28 @@ export class RegistrationListComponent extends RestTable implements OnInit {
|
||||||
this.registrationActions = [
|
this.registrationActions = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
label: $localize`Accept this registration`,
|
label: $localize`Accept this request`,
|
||||||
handler: registration => this.openRegistrationRequestProcessModal(registration, 'accept'),
|
handler: registration => this.openRegistrationRequestProcessModal(registration, 'accept'),
|
||||||
isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING
|
isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: $localize`Reject this registration`,
|
label: $localize`Reject this request`,
|
||||||
handler: registration => this.openRegistrationRequestProcessModal(registration, 'reject'),
|
handler: registration => this.openRegistrationRequestProcessModal(registration, 'reject'),
|
||||||
isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING
|
isDisplayed: registration => registration.state.id === UserRegistrationState.PENDING
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: $localize`Remove this registration request`,
|
label: $localize`Remove this request`,
|
||||||
handler: registration => this.removeRegistration(registration),
|
handler: registration => this.removeRegistrations([ registration ])
|
||||||
isDisplayed: registration => registration.state.id !== UserRegistrationState.PENDING
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
this.bulkActions = [
|
||||||
|
{
|
||||||
|
label: $localize`Delete`,
|
||||||
|
handler: registrations => this.removeRegistrations(registrations)
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
|
@ -107,11 +116,28 @@ export class RegistrationListComponent extends RestTable implements OnInit {
|
||||||
this.processRegistrationModal.openModal(registration, mode)
|
this.processRegistrationModal.openModal(registration, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeRegistration (registration: UserRegistration) {
|
private async removeRegistrations (registrations: UserRegistration[]) {
|
||||||
this.adminRegistrationService.removeRegistration(registration)
|
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({
|
.subscribe({
|
||||||
next: () => {
|
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()
|
this.reloadData()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@
|
||||||
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
[lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} comments"
|
||||||
[expandedRowKeys]="expandedRows" [(selection)]="selectedComments"
|
[expandedRowKeys]="expandedRows" [(selection)]="selectedRows"
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<div>
|
<div>
|
||||||
<my-action-dropdown
|
<my-action-dropdown
|
||||||
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
[actions]="bulkCommentActions" [entry]="selectedComments"
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
>
|
>
|
||||||
</my-action-dropdown>
|
</my-action-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { prepareIcu } from '@app/helpers'
|
||||||
templateUrl: './video-comment-list.component.html',
|
templateUrl: './video-comment-list.component.html',
|
||||||
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
|
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class VideoCommentListComponent extends RestTable implements OnInit {
|
export class VideoCommentListComponent extends RestTable <VideoCommentAdmin> implements OnInit {
|
||||||
comments: VideoCommentAdmin[]
|
comments: VideoCommentAdmin[]
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
|
@ -40,8 +40,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
selectedComments: VideoCommentAdmin[] = []
|
bulkActions: DropdownAction<VideoCommentAdmin[]>[] = []
|
||||||
bulkCommentActions: DropdownAction<VideoCommentAdmin[]>[] = []
|
|
||||||
|
|
||||||
inputFilters: AdvancedInputFilter[] = [
|
inputFilters: AdvancedInputFilter[] = [
|
||||||
{
|
{
|
||||||
|
@ -100,7 +99,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.initialize()
|
this.initialize()
|
||||||
|
|
||||||
this.bulkCommentActions = [
|
this.bulkActions = [
|
||||||
{
|
{
|
||||||
label: $localize`Delete`,
|
label: $localize`Delete`,
|
||||||
handler: comments => this.removeComments(comments),
|
handler: comments => this.removeComments(comments),
|
||||||
|
@ -118,10 +117,6 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
|
||||||
return this.markdownRenderer.textMarkdownToHTML({ markdown: text, withHtml: true, withEmoji: true })
|
return this.markdownRenderer.textMarkdownToHTML({ markdown: text, withHtml: true, withEmoji: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
isInSelectionMode () {
|
|
||||||
return this.selectedComments.length !== 0
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadData () {
|
reloadData () {
|
||||||
this.videoCommentService.getAdminVideoComments({
|
this.videoCommentService.getAdminVideoComments({
|
||||||
pagination: this.pagination,
|
pagination: this.pagination,
|
||||||
|
@ -162,7 +157,7 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
error: err => this.notifier.error(err.message),
|
error: err => this.notifier.error(err.message),
|
||||||
|
|
||||||
complete: () => this.selectedComments = []
|
complete: () => this.selectedRows = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<p-table
|
<p-table
|
||||||
[value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
[value]="users" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
||||||
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
|
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
|
||||||
[(selection)]="selectedUsers" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
[(selection)]="selectedRows" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
|
||||||
[expandedRowKeys]="expandedRows"
|
[expandedRowKeys]="expandedRows"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
<div class="left-buttons">
|
<div class="left-buttons">
|
||||||
<my-action-dropdown
|
<my-action-dropdown
|
||||||
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
[actions]="bulkUserActions" [entry]="selectedUsers"
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
>
|
>
|
||||||
</my-action-dropdown>
|
</my-action-dropdown>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ type UserForList = User & {
|
||||||
templateUrl: './user-list.component.html',
|
templateUrl: './user-list.component.html',
|
||||||
styleUrls: [ './user-list.component.scss' ]
|
styleUrls: [ './user-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class UserListComponent extends RestTable implements OnInit {
|
export class UserListComponent extends RestTable <User> implements OnInit {
|
||||||
private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns'
|
private static readonly LOCAL_STORAGE_SELECTED_COLUMNS_KEY = 'admin-user-list-selected-columns'
|
||||||
|
|
||||||
@ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
|
@ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent
|
||||||
|
@ -35,8 +35,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
highlightBannedUsers = false
|
highlightBannedUsers = false
|
||||||
|
|
||||||
selectedUsers: User[] = []
|
bulkActions: DropdownAction<User[]>[][] = []
|
||||||
bulkUserActions: DropdownAction<User[]>[][] = []
|
|
||||||
columns: { id: string, label: string }[]
|
columns: { id: string, label: string }[]
|
||||||
|
|
||||||
inputFilters: AdvancedInputFilter[] = [
|
inputFilters: AdvancedInputFilter[] = [
|
||||||
|
@ -95,7 +94,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
this.initialize()
|
this.initialize()
|
||||||
|
|
||||||
this.bulkUserActions = [
|
this.bulkActions = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
label: $localize`Delete`,
|
label: $localize`Delete`,
|
||||||
|
@ -249,7 +248,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
const res = await this.confirmService.confirm(message, $localize`Delete`)
|
const res = await this.confirmService.confirm(message, $localize`Delete`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userAdminService.removeUser(users)
|
this.userAdminService.removeUsers(users)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success(
|
this.notifier.success(
|
||||||
|
@ -284,12 +283,8 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
isInSelectionMode () {
|
|
||||||
return this.selectedUsers.length !== 0
|
|
||||||
}
|
|
||||||
|
|
||||||
protected reloadData () {
|
protected reloadData () {
|
||||||
this.selectedUsers = []
|
this.selectedRows = []
|
||||||
|
|
||||||
this.userAdminService.getUsers({
|
this.userAdminService.getUsers({
|
||||||
pagination: this.pagination,
|
pagination: this.pagination,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<p-table
|
<p-table
|
||||||
[value]="videos" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
[value]="videos" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [first]="pagination.start"
|
||||||
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
|
[rowsPerPageOptions]="rowsPerPageOptions" [sortField]="sort.field" [sortOrder]="sort.order" dataKey="id" [resizableColumns]="true"
|
||||||
[(selection)]="selectedVideos" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
[(selection)]="selectedRows" [lazy]="true" (onLazyLoad)="loadLazy($event)" [lazyLoadOnInit]="false" [selectionPageOnly]="true"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} videos"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} videos"
|
||||||
[expandedRowKeys]="expandedRows" [ngClass]="{ loading: loading }"
|
[expandedRowKeys]="expandedRows" [ngClass]="{ loading: loading }"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
<div class="left-buttons">
|
<div class="left-buttons">
|
||||||
<my-action-dropdown
|
<my-action-dropdown
|
||||||
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
*ngIf="isInSelectionMode()" i18n-label label="Batch actions" theme="orange"
|
||||||
[actions]="bulkVideoActions" [entry]="selectedVideos"
|
[actions]="bulkActions" [entry]="selectedRows"
|
||||||
>
|
>
|
||||||
</my-action-dropdown>
|
</my-action-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { VideoAdminService } from './video-admin.service'
|
||||||
templateUrl: './video-list.component.html',
|
templateUrl: './video-list.component.html',
|
||||||
styleUrls: [ './video-list.component.scss' ]
|
styleUrls: [ './video-list.component.scss' ]
|
||||||
})
|
})
|
||||||
export class VideoListComponent extends RestTable implements OnInit {
|
export class VideoListComponent extends RestTable <Video> implements OnInit {
|
||||||
@ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
|
@ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
|
||||||
|
|
||||||
videos: Video[] = []
|
videos: Video[] = []
|
||||||
|
@ -26,9 +26,7 @@ export class VideoListComponent extends RestTable implements OnInit {
|
||||||
sort: SortMeta = { field: 'publishedAt', order: -1 }
|
sort: SortMeta = { field: 'publishedAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
bulkVideoActions: DropdownAction<Video[]>[][] = []
|
bulkActions: DropdownAction<Video[]>[][] = []
|
||||||
|
|
||||||
selectedVideos: Video[] = []
|
|
||||||
|
|
||||||
inputFilters: AdvancedInputFilter[]
|
inputFilters: AdvancedInputFilter[]
|
||||||
|
|
||||||
|
@ -72,7 +70,7 @@ export class VideoListComponent extends RestTable implements OnInit {
|
||||||
|
|
||||||
this.inputFilters = this.videoAdminService.buildAdminInputFilter()
|
this.inputFilters = this.videoAdminService.buildAdminInputFilter()
|
||||||
|
|
||||||
this.bulkVideoActions = [
|
this.bulkActions = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
label: $localize`Delete`,
|
label: $localize`Delete`,
|
||||||
|
@ -126,10 +124,6 @@ export class VideoListComponent extends RestTable implements OnInit {
|
||||||
return 'VideoListComponent'
|
return 'VideoListComponent'
|
||||||
}
|
}
|
||||||
|
|
||||||
isInSelectionMode () {
|
|
||||||
return this.selectedVideos.length !== 0
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrivacyBadgeClass (video: Video) {
|
getPrivacyBadgeClass (video: Video) {
|
||||||
if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green'
|
if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green'
|
||||||
|
|
||||||
|
@ -190,7 +184,7 @@ export class VideoListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadData () {
|
reloadData () {
|
||||||
this.selectedVideos = []
|
this.selectedRows = []
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ export class LinkifierService {
|
||||||
},
|
},
|
||||||
formatHref: {
|
formatHref: {
|
||||||
mention: (href: string) => {
|
mention: (href: string) => {
|
||||||
return getAbsoluteAPIUrl() + '/services/redirect/accounts/' + href.substr(1)
|
return getAbsoluteAPIUrl() + '/services/redirect/accounts/' + href.substring(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { RestPagination } from './rest-pagination'
|
||||||
|
|
||||||
const debugLogger = debug('peertube:tables:RestTable')
|
const debugLogger = debug('peertube:tables:RestTable')
|
||||||
|
|
||||||
export abstract class RestTable {
|
export abstract class RestTable <T = unknown> {
|
||||||
|
|
||||||
abstract totalRecords: number
|
abstract totalRecords: number
|
||||||
abstract sort: SortMeta
|
abstract sort: SortMeta
|
||||||
|
@ -17,6 +17,8 @@ export abstract class RestTable {
|
||||||
rowsPerPage = this.rowsPerPageOptions[0]
|
rowsPerPage = this.rowsPerPageOptions[0]
|
||||||
expandedRows = {}
|
expandedRows = {}
|
||||||
|
|
||||||
|
selectedRows: T[] = []
|
||||||
|
|
||||||
search: string
|
search: string
|
||||||
|
|
||||||
protected route: ActivatedRoute
|
protected route: ActivatedRoute
|
||||||
|
@ -75,6 +77,10 @@ export abstract class RestTable {
|
||||||
this.reloadData()
|
this.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isInSelectionMode () {
|
||||||
|
return this.selectedRows.length !== 0
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract reloadData (): void
|
protected abstract reloadData (): void
|
||||||
|
|
||||||
private getSortLocalStorageKey () {
|
private getSortLocalStorageKey () {
|
||||||
|
|
|
@ -105,7 +105,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
|
||||||
const res = await this.confirmService.confirm(message, $localize`Delete ${user.username}`)
|
const res = await this.confirmService.confirm(message, $localize`Delete ${user.username}`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userAdminService.removeUser(user)
|
this.userAdminService.removeUsers(user)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${user.username} deleted.`)
|
this.notifier.success($localize`User ${user.username} deleted.`)
|
||||||
|
|
|
@ -64,7 +64,7 @@ export class UserAdminService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeUser (usersArg: UserServerModel | UserServerModel[]) {
|
removeUsers (usersArg: UserServerModel | UserServerModel[]) {
|
||||||
const users = arrayify(usersArg)
|
const users = arrayify(usersArg)
|
||||||
|
|
||||||
return from(users)
|
return from(users)
|
||||||
|
|
Loading…
Reference in New Issue