Increase rows per page, add reporter muting for abuse list
This commit is contained in:
parent
68d19a0ace
commit
9b4241e33b
9 changed files with 78 additions and 14 deletions
|
@ -8,7 +8,7 @@
|
|||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th i18n>Account</th>
|
||||
<th style="width: 200px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 190px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 100px;"></th> <!-- column for action buttons -->
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th i18n>Instance</th>
|
||||
<th style="width: 200px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 190px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 100px;"></th> <!-- column for action buttons -->
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.glyphicon-trash {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.screenratio {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<p-table
|
||||
[value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
|
||||
[value]="videoAbuses" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
|
||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" [resizableColumns]="true"
|
||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} reports"
|
||||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr> <!-- header -->
|
||||
<th style="width: 40px;"></th>
|
||||
<th i18n>Reporter</th>
|
||||
<th style="width: 200px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 20%;" pResizableColumn i18n>Reporter</th>
|
||||
<th i18n>Video</th>
|
||||
<th style="width:190px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th>
|
||||
<th style="width: 120px;"></th>
|
||||
</tr>
|
||||
|
@ -40,14 +40,15 @@
|
|||
</a>
|
||||
</td>
|
||||
|
||||
<td>{{ videoAbuse.createdAt }}</td>
|
||||
|
||||
<td>
|
||||
<span *ngIf="videoAbuse.video.deleted" i18n-title title="Video was deleted" class="glyphicon glyphicon-trash"></span>
|
||||
<a [href]="getVideoUrl(videoAbuse)" i18n-title title="Open video in a new tab" target="_blank" rel="noopener noreferrer">
|
||||
{{ videoAbuse.video.name }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>{{ videoAbuse.createdAt }}</td>
|
||||
|
||||
<td class="c-hand video-abuse-states" [pRowToggler]="videoAbuse">
|
||||
<span *ngIf="isVideoAbuseAccepted(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-ok"></span>
|
||||
<span *ngIf="isVideoAbuseRejected(videoAbuse)" [title]="videoAbuse.state.label" class="glyphicon glyphicon-remove"></span>
|
||||
|
@ -55,7 +56,7 @@
|
|||
</td>
|
||||
|
||||
<td class="action-cell">
|
||||
<my-action-dropdown placement="bottom-right auto" i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown>
|
||||
<my-action-dropdown placement="bottom-right auto" container="body" i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -15,6 +15,7 @@ import { buildVideoLink, buildVideoEmbed } from 'src/assets/player/utils'
|
|||
import { getAbsoluteAPIUrl } from '@app/shared/misc/utils'
|
||||
import { DomSanitizer } from '@angular/platform-browser'
|
||||
import { BlocklistService } from '@app/shared/blocklist'
|
||||
import { VideoService } from '@app/shared/video/video.service'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-abuse-list',
|
||||
|
@ -26,7 +27,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
|
||||
videoAbuses: (VideoAbuse & { moderationCommentHtml?: string, reasonHtml?: string })[] = []
|
||||
totalRecords = 0
|
||||
rowsPerPage = 10
|
||||
rowsPerPageOptions = [ 20, 50, 100 ]
|
||||
rowsPerPage = this.rowsPerPageOptions[0]
|
||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||
|
||||
|
@ -36,6 +38,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
private notifier: Notifier,
|
||||
private videoAbuseService: VideoAbuseService,
|
||||
private blocklistService: BlocklistService,
|
||||
private videoService: VideoService,
|
||||
private videoBlacklistService: VideoBlacklistService,
|
||||
private confirmService: ConfirmService,
|
||||
private i18n: I18n,
|
||||
|
@ -78,10 +81,12 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
[
|
||||
{
|
||||
label: this.i18n('Actions for the video'),
|
||||
isHeader: true
|
||||
isHeader: true,
|
||||
isDisplayed: videoAbuse => !videoAbuse.video.deleted
|
||||
},
|
||||
{
|
||||
label: this.i18n('Blacklist video'),
|
||||
isDisplayed: videoAbuse => !videoAbuse.video.deleted,
|
||||
handler: videoAbuse => {
|
||||
this.videoBlacklistService.blacklistVideo(videoAbuse.video.id, undefined, true)
|
||||
.subscribe(
|
||||
|
@ -91,6 +96,48 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED)
|
||||
},
|
||||
|
||||
err => this.notifier.error(err.message)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: this.i18n('Delete video'),
|
||||
isDisplayed: videoAbuse => !videoAbuse.video.deleted,
|
||||
handler: async videoAbuse => {
|
||||
const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this video?'), this.i18n('Delete'))
|
||||
if (res === false) return
|
||||
|
||||
this.videoService.removeVideo(videoAbuse.video.id)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.notifier.success(this.i18n('Video deleted.'))
|
||||
|
||||
this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED)
|
||||
},
|
||||
|
||||
err => this.notifier.error(err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
label: this.i18n('Actions for the reporter'),
|
||||
isHeader: true
|
||||
},
|
||||
{
|
||||
label: this.i18n('Mute reporter'),
|
||||
handler: async videoAbuse => {
|
||||
const account = videoAbuse.reporterAccount as Account
|
||||
|
||||
this.blocklistService.blockAccountByInstance(account)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.notifier.success(this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost }))
|
||||
|
||||
account.mutedByInstance = true
|
||||
},
|
||||
|
||||
err => this.notifier.error(err.message)
|
||||
)
|
||||
}
|
||||
|
@ -180,7 +227,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
Object.assign(abuse, {
|
||||
reasonHtml: await this.toHtml(abuse.reason),
|
||||
moderationCommentHtml: await this.toHtml(abuse.moderationComment),
|
||||
embedHtml: this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse))
|
||||
embedHtml: this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse)),
|
||||
reporterAccount: new Account(abuse.reporterAccount)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th>
|
||||
<th style="width: 120px;" i18n>Sensitive</th>
|
||||
<th style="width: 120px;" i18n>Unfederated</th>
|
||||
<th style="width: 200px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 190px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 120px;"></th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="dropdown-root" ngbDropdown [placement]="placement" container="body" *ngIf="areActionsDisplayed(actions, entry)">
|
||||
<div class="dropdown-root" ngbDropdown [placement]="placement" [container]="container" *ngIf="areActionsDisplayed(actions, entry)">
|
||||
<div
|
||||
class="action-button" [ngClass]="{ small: buttonSize === 'small', grey: theme === 'grey', orange: theme === 'orange', 'button-styled': buttonStyled }"
|
||||
ngbDropdownToggle role="button"
|
||||
|
|
|
@ -27,6 +27,7 @@ export class ActionDropdownComponent<T> {
|
|||
@Input() entry: T
|
||||
|
||||
@Input() placement = 'bottom-left auto'
|
||||
@Input() container: null | 'body'
|
||||
|
||||
@Input() buttonSize: DropdownButtonSize = 'normal'
|
||||
@Input() buttonDirection: DropdownDirection = 'horizontal'
|
||||
|
|
|
@ -191,12 +191,22 @@ p-table {
|
|||
|
||||
.ui-dropdown {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 0;
|
||||
|
||||
&.ui-state-focus {
|
||||
box-shadow: #{$focus-box-shadow-form} var(--mainColorLightest);
|
||||
}
|
||||
|
||||
.ui-dropdown-label {
|
||||
color: var(--inputPlaceholderColor);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-paginator-current {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
color: var(--inputPlaceholderColor);
|
||||
}
|
||||
|
||||
.ui-paginator-first,
|
||||
|
|
Loading…
Reference in a new issue