From 5a51ecc2172282786dab47bd874026621554ba6d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 28 Feb 2022 16:27:25 +0100 Subject: Move admin comments list in overviews menu --- client/src/app/+admin/overview/comments/index.ts | 2 + .../comments/video-comment-list.component.html | 111 ++++++++++++ .../comments/video-comment-list.component.scss | 52 ++++++ .../comments/video-comment-list.component.ts | 186 +++++++++++++++++++++ .../overview/comments/video-comment.routes.ts | 30 ++++ client/src/app/+admin/overview/index.ts | 1 + client/src/app/+admin/overview/overview.routes.ts | 10 +- .../src/app/+admin/overview/users/users.routes.ts | 2 +- .../src/app/+admin/overview/videos/video.routes.ts | 2 +- 9 files changed, 390 insertions(+), 6 deletions(-) create mode 100644 client/src/app/+admin/overview/comments/index.ts create mode 100644 client/src/app/+admin/overview/comments/video-comment-list.component.html create mode 100644 client/src/app/+admin/overview/comments/video-comment-list.component.scss create mode 100644 client/src/app/+admin/overview/comments/video-comment-list.component.ts create mode 100644 client/src/app/+admin/overview/comments/video-comment.routes.ts (limited to 'client/src/app/+admin/overview') diff --git a/client/src/app/+admin/overview/comments/index.ts b/client/src/app/+admin/overview/comments/index.ts new file mode 100644 index 000000000..c487f7a81 --- /dev/null +++ b/client/src/app/+admin/overview/comments/index.ts @@ -0,0 +1,2 @@ +export * from './video-comment-list.component' +export * from './video-comment.routes' diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.html b/client/src/app/+admin/overview/comments/video-comment-list.component.html new file mode 100644 index 000000000..0dbbbe1cc --- /dev/null +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.html @@ -0,0 +1,111 @@ +

+ + Video comments + + +

+ +This view also shows comments from muted accounts. + + + +
+
+ + +
+ +
+ +
+
+
+ + + + + + + + + Account + Video + Comment + Date + + + + + + + + + + + + + + + + + + + + +
+ +
+ {{ videoComment.account.displayName }} + {{ videoComment.by }} +
+
+
+ + + + Commented video + + {{ videoComment.video.name }} + + + +
+ + + {{ videoComment.createdAt | date: 'short' }} + +
+ + + + +
+ + +
+ + + + +
+ No comments found matching current filters. + No comments found. +
+ + +
+
+ diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.scss b/client/src/app/+admin/overview/comments/video-comment-list.component.scss new file mode 100644 index 000000000..3cf7b8db6 --- /dev/null +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.scss @@ -0,0 +1,52 @@ +@use '_mixins' as *; +@use '_variables' as *; + +my-feed { + @include margin-left(5px); + + display: inline-block; + width: 15px; +} + +my-global-icon { + width: 24px; + height: 24px; +} + +.video { + display: flex; + flex-direction: column; + + em { + font-size: 11px; + } + + a { + @include ellipsis; + + color: pvar(--mainForegroundColor); + } +} + +.comment-html { + ::ng-deep { + > div { + max-height: 22px; + } + + div, + p { + @include ellipsis; + } + + p { + margin: 0; + } + } +} + +@media screen and (max-width: $primeng-breakpoint) { + .video { + align-items: flex-start !important; + } +} diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.ts b/client/src/app/+admin/overview/comments/video-comment-list.component.ts new file mode 100644 index 000000000..25fe65133 --- /dev/null +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.ts @@ -0,0 +1,186 @@ +import { SortMeta } from 'primeng/api' +import { Component, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { AuthService, ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' +import { AdvancedInputFilter } from '@app/shared/shared-forms' +import { DropdownAction } from '@app/shared/shared-main' +import { BulkService } from '@app/shared/shared-moderation' +import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' +import { FeedFormat, UserRight } from '@shared/models' + +@Component({ + selector: 'my-video-comment-list', + templateUrl: './video-comment-list.component.html', + styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ] +}) +export class VideoCommentListComponent extends RestTable implements OnInit { + comments: VideoCommentAdmin[] + totalRecords = 0 + sort: SortMeta = { field: 'createdAt', order: -1 } + pagination: RestPagination = { count: this.rowsPerPage, start: 0 } + + videoCommentActions: DropdownAction[][] = [] + + syndicationItems = [ + { + format: FeedFormat.RSS, + label: 'media rss 2.0', + url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.RSS.toLowerCase() + }, + { + format: FeedFormat.ATOM, + label: 'atom 1.0', + url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.ATOM.toLowerCase() + }, + { + format: FeedFormat.JSON, + label: 'json 1.0', + url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.JSON.toLowerCase() + } + ] + + selectedComments: VideoCommentAdmin[] = [] + bulkCommentActions: DropdownAction[] = [] + + inputFilters: AdvancedInputFilter[] = [ + { + title: $localize`Advanced filters`, + children: [ + { + value: 'local:true', + label: $localize`Local comments` + }, + { + value: 'local:false', + label: $localize`Remote comments` + } + ] + } + ] + + get authUser () { + return this.auth.getUser() + } + + constructor ( + protected router: Router, + protected route: ActivatedRoute, + private auth: AuthService, + private notifier: Notifier, + private confirmService: ConfirmService, + private videoCommentService: VideoCommentService, + private markdownRenderer: MarkdownService, + private bulkService: BulkService + ) { + super() + + this.videoCommentActions = [ + [ + { + label: $localize`Delete this comment`, + handler: comment => this.deleteComment(comment), + isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) + }, + + { + label: $localize`Delete all comments of this account`, + description: $localize`Comments are deleted after a few minutes`, + handler: comment => this.deleteUserComments(comment), + isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) + } + ] + ] + } + + ngOnInit () { + this.initialize() + + this.bulkCommentActions = [ + { + label: $localize`Delete`, + handler: comments => this.removeComments(comments), + isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT), + iconName: 'delete' + } + ] + } + + getIdentifier () { + return 'VideoCommentListComponent' + } + + toHtml (text: string) { + return this.markdownRenderer.textMarkdownToHTML(text, true, true) + } + + isInSelectionMode () { + return this.selectedComments.length !== 0 + } + + protected reloadData () { + this.videoCommentService.getAdminVideoComments({ + pagination: this.pagination, + sort: this.sort, + search: this.search + }).subscribe({ + next: async resultList => { + this.totalRecords = resultList.total + + this.comments = [] + + for (const c of resultList.data) { + this.comments.push( + new VideoCommentAdmin(c, await this.toHtml(c.text)) + ) + } + }, + + error: err => this.notifier.error(err.message) + }) + } + + private removeComments (comments: VideoCommentAdmin[]) { + const commentArgs = comments.map(c => ({ videoId: c.video.id, commentId: c.id })) + + this.videoCommentService.deleteVideoComments(commentArgs) + .subscribe({ + next: () => { + this.notifier.success($localize`${commentArgs.length} comments deleted.`) + this.reloadData() + }, + + error: err => this.notifier.error(err.message), + + complete: () => this.selectedComments = [] + }) + } + + private deleteComment (comment: VideoCommentAdmin) { + this.videoCommentService.deleteVideoComment(comment.video.id, comment.id) + .subscribe({ + next: () => this.reloadData(), + + error: err => this.notifier.error(err.message) + }) + } + + private async deleteUserComments (comment: VideoCommentAdmin) { + const message = $localize`Do you really want to delete all comments of ${comment.by}?` + const res = await this.confirmService.confirm(message, $localize`Delete`) + if (res === false) return + + const options = { + accountName: comment.by, + scope: 'instance' as 'instance' + } + + this.bulkService.removeCommentsOf(options) + .subscribe({ + next: () => { + this.notifier.success($localize`Comments of ${options.accountName} will be deleted in a few minutes`) + }, + + error: err => this.notifier.error(err.message) + }) + } +} diff --git a/client/src/app/+admin/overview/comments/video-comment.routes.ts b/client/src/app/+admin/overview/comments/video-comment.routes.ts new file mode 100644 index 000000000..f0bd440ad --- /dev/null +++ b/client/src/app/+admin/overview/comments/video-comment.routes.ts @@ -0,0 +1,30 @@ +import { Routes } from '@angular/router' +import { UserRightGuard } from '@app/core' +import { UserRight } from '@shared/models' +import { VideoCommentListComponent } from './video-comment-list.component' + +export const commentRoutes: Routes = [ + { + path: 'comments', + canActivate: [ UserRightGuard ], + data: { + userRight: UserRight.SEE_ALL_COMMENTS + }, + children: [ + { + path: '', + redirectTo: 'list', + pathMatch: 'full' + }, + { + path: 'list', + component: VideoCommentListComponent, + data: { + meta: { + title: $localize`Comments list` + } + } + } + ] + } +] diff --git a/client/src/app/+admin/overview/index.ts b/client/src/app/+admin/overview/index.ts index a9c46893f..111360734 100644 --- a/client/src/app/+admin/overview/index.ts +++ b/client/src/app/+admin/overview/index.ts @@ -1,3 +1,4 @@ +export * from './comments' export * from './users' export * from './videos' export * from './overview.routes' diff --git a/client/src/app/+admin/overview/overview.routes.ts b/client/src/app/+admin/overview/overview.routes.ts index 1e6686d16..72d6835d7 100644 --- a/client/src/app/+admin/overview/overview.routes.ts +++ b/client/src/app/+admin/overview/overview.routes.ts @@ -1,8 +1,10 @@ import { Routes } from '@angular/router' -import { UsersRoutes } from './users' -import { VideosRoutes } from './videos' +import { commentRoutes } from './comments' +import { usersRoutes } from './users' +import { videosRoutes } from './videos' export const OverviewRoutes: Routes = [ - ...UsersRoutes, - ...VideosRoutes + ...commentRoutes, + ...usersRoutes, + ...videosRoutes ] diff --git a/client/src/app/+admin/overview/users/users.routes.ts b/client/src/app/+admin/overview/users/users.routes.ts index 8b63f5bc7..c9724e5fb 100644 --- a/client/src/app/+admin/overview/users/users.routes.ts +++ b/client/src/app/+admin/overview/users/users.routes.ts @@ -4,7 +4,7 @@ import { UserRight } from '@shared/models' import { UserCreateComponent, UserUpdateComponent } from './user-edit' import { UserListComponent } from './user-list' -export const UsersRoutes: Routes = [ +export const usersRoutes: Routes = [ { path: 'users', canActivate: [ UserRightGuard ], diff --git a/client/src/app/+admin/overview/videos/video.routes.ts b/client/src/app/+admin/overview/videos/video.routes.ts index 984df7b82..01cb5b497 100644 --- a/client/src/app/+admin/overview/videos/video.routes.ts +++ b/client/src/app/+admin/overview/videos/video.routes.ts @@ -3,7 +3,7 @@ import { UserRightGuard } from '@app/core' import { UserRight } from '@shared/models' import { VideoListComponent } from './video-list.component' -export const VideosRoutes: Routes = [ +export const videosRoutes: Routes = [ { path: 'videos', canActivate: [ UserRightGuard ], -- cgit v1.2.3