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/admin.component.ts | 16 +- client/src/app/+admin/admin.module.ts | 2 +- .../src/app/+admin/moderation/moderation.routes.ts | 12 +- .../+admin/moderation/video-comment-list/index.ts | 1 - .../video-comment-list.component.html | 111 ------------ .../video-comment-list.component.scss | 52 ------ .../video-comment-list.component.ts | 186 --------------------- 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 +- 16 files changed, 402 insertions(+), 374 deletions(-) delete mode 100644 client/src/app/+admin/moderation/video-comment-list/index.ts delete mode 100644 client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html delete mode 100644 client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss delete mode 100644 client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts 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') diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts index b8a957d1c..746549555 100644 --- a/client/src/app/+admin/admin.component.ts +++ b/client/src/app/+admin/admin.component.ts @@ -52,6 +52,14 @@ export class AdminComponent implements OnInit { }) } + if (this.hasVideoCommentsRight()) { + overviewItems.children.push({ + label: $localize`Comments`, + routerLink: '/admin/comments', + iconName: 'message-circle' + }) + } + if (overviewItems.children.length !== 0) { this.menuEntries.push(overviewItems) } @@ -104,14 +112,6 @@ export class AdminComponent implements OnInit { }) } - if (this.hasVideoCommentsRight()) { - moderationItems.children.push({ - label: $localize`Video comments`, - routerLink: '/admin/moderation/video-comments/list', - iconName: 'message-circle' - }) - } - if (this.hasAccountsBlocklistRight()) { moderationItems.children.push({ label: $localize`Muted accounts`, diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts index c672fa280..366e29883 100644 --- a/client/src/app/+admin/admin.module.ts +++ b/client/src/app/+admin/admin.module.ts @@ -32,13 +32,13 @@ import { RedundancyCheckboxComponent } from './follows/shared/redundancy-checkbo import { VideoRedundancyInformationComponent } from './follows/video-redundancies-list/video-redundancy-information.component' import { AbuseListComponent, VideoBlockListComponent } from './moderation' import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from './moderation/instance-blocklist' -import { VideoCommentListComponent } from './moderation/video-comment-list' import { UserCreateComponent, UserListComponent, UserPasswordComponent, UserUpdateComponent, VideoAdminService, + VideoCommentListComponent, VideoListComponent } from './overview' import { diff --git a/client/src/app/+admin/moderation/moderation.routes.ts b/client/src/app/+admin/moderation/moderation.routes.ts index 5c39ff366..1ad301039 100644 --- a/client/src/app/+admin/moderation/moderation.routes.ts +++ b/client/src/app/+admin/moderation/moderation.routes.ts @@ -2,7 +2,6 @@ import { Routes } from '@angular/router' import { AbuseListComponent } from '@app/+admin/moderation/abuse-list' import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from '@app/+admin/moderation/instance-blocklist' import { VideoBlockListComponent } from '@app/+admin/moderation/video-block-list' -import { VideoCommentListComponent } from './video-comment-list' import { UserRightGuard } from '@app/core' import { UserRight } from '@shared/models' @@ -69,6 +68,7 @@ export const ModerationRoutes: Routes = [ } }, + // We move this component in admin overview pages { path: 'video-comments', redirectTo: 'video-comments/list', @@ -76,14 +76,8 @@ export const ModerationRoutes: Routes = [ }, { path: 'video-comments/list', - component: VideoCommentListComponent, - canActivate: [ UserRightGuard ], - data: { - userRight: UserRight.SEE_ALL_COMMENTS, - meta: { - title: $localize`Video comments` - } - } + redirectTo: '/admin/comments/list', + pathMatch: 'full' }, { diff --git a/client/src/app/+admin/moderation/video-comment-list/index.ts b/client/src/app/+admin/moderation/video-comment-list/index.ts deleted file mode 100644 index eb08b4177..000000000 --- a/client/src/app/+admin/moderation/video-comment-list/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './video-comment-list.component' diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html deleted file mode 100644 index 0dbbbe1cc..000000000 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.html +++ /dev/null @@ -1,111 +0,0 @@ -

- - 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/moderation/video-comment-list/video-comment-list.component.scss b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss deleted file mode 100644 index 3cf7b8db6..000000000 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.scss +++ /dev/null @@ -1,52 +0,0 @@ -@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/moderation/video-comment-list/video-comment-list.component.ts b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts deleted file mode 100644 index 25fe65133..000000000 --- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts +++ /dev/null @@ -1,186 +0,0 @@ -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/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