diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-04-19 14:11:40 +0200 |
---|---|---|
committer | Rigel Kent <par@rigelk.eu> | 2020-05-01 16:41:02 +0200 |
commit | e0a929179a9dc76e035ca7fda2b61d5ff46afbc5 (patch) | |
tree | 1e6615c612ad6995dcb1c3619342dbbc7db35034 | |
parent | aeb1bed9835b3b092832160245080d4023c14d91 (diff) | |
download | PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.tar.gz PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.tar.zst PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.zip |
Add filter inputs for blacklisted videos and muted accounts/servers
19 files changed, 202 insertions, 61 deletions
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html index 6d77c8290..d340b5e57 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.html | |||
@@ -1,9 +1,19 @@ | |||
1 | <p-table | 1 | <p-table |
2 | [value]="blockedAccounts" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" | 2 | [value]="blockedAccounts" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" |
3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" | 3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" |
4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate | 4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate |
5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts" | 5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts" |
6 | > | 6 | > |
7 | <ng-template pTemplate="caption"> | ||
8 | <div class="caption"> | ||
9 | <div class="ml-auto"> | ||
10 | <input | ||
11 | type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." | ||
12 | (keyup)="onSearch($event)" | ||
13 | > | ||
14 | </div> | ||
15 | </div> | ||
16 | </ng-template> | ||
7 | 17 | ||
8 | <ng-template pTemplate="header"> | 18 | <ng-template pTemplate="header"> |
9 | <tr> | 19 | <tr> |
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts index a3910177f..607b1cbe0 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts | |||
@@ -7,13 +7,14 @@ import { AccountBlock, BlocklistService } from '@app/shared/blocklist' | |||
7 | 7 | ||
8 | @Component({ | 8 | @Component({ |
9 | selector: 'my-instance-account-blocklist', | 9 | selector: 'my-instance-account-blocklist', |
10 | styleUrls: [ './instance-account-blocklist.component.scss' ], | 10 | styleUrls: [ '../moderation.component.scss', './instance-account-blocklist.component.scss' ], |
11 | templateUrl: './instance-account-blocklist.component.html' | 11 | templateUrl: './instance-account-blocklist.component.html' |
12 | }) | 12 | }) |
13 | export class InstanceAccountBlocklistComponent extends RestTable implements OnInit { | 13 | export class InstanceAccountBlocklistComponent extends RestTable implements OnInit { |
14 | blockedAccounts: AccountBlock[] = [] | 14 | blockedAccounts: AccountBlock[] = [] |
15 | totalRecords = 0 | 15 | totalRecords = 0 |
16 | rowsPerPage = 10 | 16 | rowsPerPageOptions = [ 20, 50, 100 ] |
17 | rowsPerPage = this.rowsPerPageOptions[0] | ||
17 | sort: SortMeta = { field: 'createdAt', order: -1 } | 18 | sort: SortMeta = { field: 'createdAt', order: -1 } |
18 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } | 19 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } |
19 | 20 | ||
@@ -49,7 +50,11 @@ export class InstanceAccountBlocklistComponent extends RestTable implements OnIn | |||
49 | } | 50 | } |
50 | 51 | ||
51 | protected loadData () { | 52 | protected loadData () { |
52 | return this.blocklistService.getInstanceAccountBlocklist(this.pagination, this.sort) | 53 | return this.blocklistService.getInstanceAccountBlocklist({ |
54 | pagination: this.pagination, | ||
55 | sort: this.sort, | ||
56 | search: this.search | ||
57 | }) | ||
53 | .subscribe( | 58 | .subscribe( |
54 | resultList => { | 59 | resultList => { |
55 | this.blockedAccounts = resultList.data | 60 | this.blockedAccounts = resultList.data |
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.html b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.html index 19b33a0f5..b6c87fdc8 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.html +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.html | |||
@@ -1,12 +1,18 @@ | |||
1 | <p-table | 1 | <p-table |
2 | [value]="blockedServers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" | 2 | [value]="blockedServers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" |
3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" | 3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" |
4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate | 4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate |
5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted instances" | 5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted instances" |
6 | > | 6 | > |
7 | <ng-template pTemplate="caption"> | 7 | <ng-template pTemplate="caption"> |
8 | <div class="caption"> | 8 | <div class="caption"> |
9 | <a class="ml-auto block-button" (click)="addServersToBlock()" (key.enter)="addServersToBlock()"> | 9 | <div class="ml-auto"> |
10 | <input | ||
11 | type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." | ||
12 | (keyup)="onSearch($event)" | ||
13 | > | ||
14 | </div> | ||
15 | <a class="ml-2 block-button" (click)="addServersToBlock()" (key.enter)="addServersToBlock()"> | ||
10 | <my-global-icon iconName="add"></my-global-icon> | 16 | <my-global-icon iconName="add"></my-global-icon> |
11 | <ng-container i18n>Mute domain</ng-container> | 17 | <ng-container i18n>Mute domain</ng-container> |
12 | </a> | 18 | </a> |
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts index 431729ef2..4efadc386 100644 --- a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts +++ b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts | |||
@@ -9,7 +9,7 @@ import { BatchDomainsModalComponent } from '@app/+admin/config/shared/batch-doma | |||
9 | 9 | ||
10 | @Component({ | 10 | @Component({ |
11 | selector: 'my-instance-server-blocklist', | 11 | selector: 'my-instance-server-blocklist', |
12 | styleUrls: [ './instance-server-blocklist.component.scss' ], | 12 | styleUrls: [ '../moderation.component.scss', './instance-server-blocklist.component.scss' ], |
13 | templateUrl: './instance-server-blocklist.component.html' | 13 | templateUrl: './instance-server-blocklist.component.html' |
14 | }) | 14 | }) |
15 | export class InstanceServerBlocklistComponent extends RestTable implements OnInit { | 15 | export class InstanceServerBlocklistComponent extends RestTable implements OnInit { |
@@ -17,7 +17,8 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni | |||
17 | 17 | ||
18 | blockedServers: ServerBlock[] = [] | 18 | blockedServers: ServerBlock[] = [] |
19 | totalRecords = 0 | 19 | totalRecords = 0 |
20 | rowsPerPage = 10 | 20 | rowsPerPageOptions = [ 20, 50, 100 ] |
21 | rowsPerPage = this.rowsPerPageOptions[0] | ||
21 | sort: SortMeta = { field: 'createdAt', order: -1 } | 22 | sort: SortMeta = { field: 'createdAt', order: -1 } |
22 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } | 23 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } |
23 | 24 | ||
@@ -72,7 +73,11 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni | |||
72 | } | 73 | } |
73 | 74 | ||
74 | protected loadData () { | 75 | protected loadData () { |
75 | return this.blocklistService.getInstanceServerBlocklist(this.pagination, this.sort) | 76 | return this.blocklistService.getInstanceServerBlocklist({ |
77 | pagination: this.pagination, | ||
78 | sort: this.sort, | ||
79 | search: this.search | ||
80 | }) | ||
76 | .subscribe( | 81 | .subscribe( |
77 | resultList => { | 82 | resultList => { |
78 | this.blockedServers = resultList.data | 83 | this.blockedServers = resultList.data |
diff --git a/client/src/app/+admin/moderation/moderation.component.scss b/client/src/app/+admin/moderation/moderation.component.scss index a4ee65423..97af74541 100644 --- a/client/src/app/+admin/moderation/moderation.component.scss +++ b/client/src/app/+admin/moderation/moderation.component.scss | |||
@@ -7,6 +7,14 @@ | |||
7 | margin-right: 30px; | 7 | margin-right: 30px; |
8 | } | 8 | } |
9 | 9 | ||
10 | .caption { | ||
11 | justify-content: flex-end; | ||
12 | |||
13 | input { | ||
14 | @include peertube-input-text(250px); | ||
15 | } | ||
16 | } | ||
17 | |||
10 | .moderation-expanded { | 18 | .moderation-expanded { |
11 | font-size: 90%; | 19 | font-size: 90%; |
12 | 20 | ||
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.scss b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.scss index a9251e2f0..d6bc34935 100644 --- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.scss +++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.scss | |||
@@ -1,14 +1,6 @@ | |||
1 | @import 'mixins'; | 1 | @import 'mixins'; |
2 | @import 'miniature'; | 2 | @import 'miniature'; |
3 | 3 | ||
4 | .caption { | ||
5 | justify-content: flex-end; | ||
6 | |||
7 | input { | ||
8 | @include peertube-input-text(250px); | ||
9 | } | ||
10 | } | ||
11 | |||
12 | .video-details-date-updated { | 4 | .video-details-date-updated { |
13 | font-size: 90%; | 5 | font-size: 90%; |
14 | margin-top: .1rem; | 6 | margin-top: .1rem; |
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html index 90a786ad0..6375dacd9 100644 --- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html +++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html | |||
@@ -1,9 +1,20 @@ | |||
1 | <p-table | 1 | <p-table |
2 | [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" | 2 | [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions" |
3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" | 3 | [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" |
4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate | 4 | [showCurrentPageReport]="true" i18n-currentPageReportTemplate |
5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blacklisted videos" | 5 | currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blacklisted videos" |
6 | > | 6 | > |
7 | <ng-template pTemplate="caption"> | ||
8 | <div class="caption"> | ||
9 | <div class="ml-auto"> | ||
10 | <input | ||
11 | type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..." | ||
12 | (keyup)="onSearch($event)" | ||
13 | > | ||
14 | </div> | ||
15 | </div> | ||
16 | </ng-template> | ||
17 | |||
7 | <ng-template pTemplate="header"> | 18 | <ng-template pTemplate="header"> |
8 | <tr> | 19 | <tr> |
9 | <th style="width: 40px"></th> | 20 | <th style="width: 40px"></th> |
@@ -33,7 +44,7 @@ | |||
33 | <div class="video-table-video-text"> | 44 | <div class="video-table-video-text"> |
34 | <div> | 45 | <div> |
35 | {{ videoBlacklist.video.name }} | 46 | {{ videoBlacklist.video.name }} |
36 | <span class="glyphicon glyphicon-new-window"></span> | 47 | <span i18n-title title="Video was blacklisted" class="glyphicon glyphicon-ban-circle"></span> |
37 | </div> | 48 | </div> |
38 | <div class="text-muted">by {{ videoBlacklist.video.channel?.displayName }} on {{ videoBlacklist.video.channel?.host }} </div> | 49 | <div class="text-muted">by {{ videoBlacklist.video.channel?.displayName }} on {{ videoBlacklist.video.channel?.host }} </div> |
39 | </div> | 50 | </div> |
@@ -53,7 +64,10 @@ | |||
53 | </ng-container> | 64 | </ng-container> |
54 | 65 | ||
55 | <td class="action-cell"> | 66 | <td class="action-cell"> |
56 | <my-action-dropdown i18n-label placement="bottom-right" label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"></my-action-dropdown> | 67 | <my-action-dropdown |
68 | [ngClass]="{ 'show': expanded }" placement="bottom-right" container="body" | ||
69 | i18n-label label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist" | ||
70 | ></my-action-dropdown> | ||
57 | </td> | 71 | </td> |
58 | </tr> | 72 | </tr> |
59 | </ng-template> | 73 | </ng-template> |
@@ -61,8 +75,10 @@ | |||
61 | <ng-template pTemplate="rowexpansion" let-videoBlacklist> | 75 | <ng-template pTemplate="rowexpansion" let-videoBlacklist> |
62 | <tr> | 76 | <tr> |
63 | <td class="expand-cell" colspan="6"> | 77 | <td class="expand-cell" colspan="6"> |
64 | <span class="col-2 moderation-expanded-label" i18n>Blacklist reason:</span> | 78 | <div class="d-flex moderation-expanded"> |
65 | <span class="col-9 moderation-expanded-text" [innerHTML]="videoBlacklist.reasonHtml"></span> | 79 | <span class="col-2 moderation-expanded-label" i18n>Blacklist reason:</span> |
80 | <span class="col-9 moderation-expanded-text" [innerHTML]="videoBlacklist.reasonHtml"></span> | ||
81 | </div> | ||
66 | </td> | 82 | </td> |
67 | </tr> | 83 | </tr> |
68 | </ng-template> | 84 | </ng-template> |
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts index c38d30865..e9925f9bf 100644 --- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts +++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts | |||
@@ -17,7 +17,8 @@ import { MarkdownService } from '@app/shared/renderer' | |||
17 | export class VideoBlacklistListComponent extends RestTable implements OnInit { | 17 | export class VideoBlacklistListComponent extends RestTable implements OnInit { |
18 | blacklist: (VideoBlacklist & { reasonHtml?: string })[] = [] | 18 | blacklist: (VideoBlacklist & { reasonHtml?: string })[] = [] |
19 | totalRecords = 0 | 19 | totalRecords = 0 |
20 | rowsPerPage = 10 | 20 | rowsPerPageOptions = [ 20, 50, 100 ] |
21 | rowsPerPage = this.rowsPerPageOptions[0] | ||
21 | sort: SortMeta = { field: 'createdAt', order: -1 } | 22 | sort: SortMeta = { field: 'createdAt', order: -1 } |
22 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } | 23 | pagination: RestPagination = { count: this.rowsPerPage, start: 0 } |
23 | listBlacklistTypeFilter: VideoBlacklistType = undefined | 24 | listBlacklistTypeFilter: VideoBlacklistType = undefined |
@@ -38,7 +39,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { | |||
38 | ngOnInit () { | 39 | ngOnInit () { |
39 | this.serverService.getConfig() | 40 | this.serverService.getConfig() |
40 | .subscribe(config => { | 41 | .subscribe(config => { |
41 | // don't filter if auto-blacklist not enabled as this will be the only list | 42 | // don't filter if auto-blacklist is not enabled as this will be the only list |
42 | if (config.autoBlacklist.videos.ofUsers.enabled) { | 43 | if (config.autoBlacklist.videos.ofUsers.enabled) { |
43 | this.listBlacklistTypeFilter = VideoBlacklistType.MANUAL | 44 | this.listBlacklistTypeFilter = VideoBlacklistType.MANUAL |
44 | } | 45 | } |
@@ -91,7 +92,12 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { | |||
91 | } | 92 | } |
92 | 93 | ||
93 | protected loadData () { | 94 | protected loadData () { |
94 | this.videoBlacklistService.listBlacklist(this.pagination, this.sort, this.listBlacklistTypeFilter) | 95 | this.videoBlacklistService.listBlacklist({ |
96 | pagination: this.pagination, | ||
97 | sort: this.sort, | ||
98 | search: this.search, | ||
99 | type: this.listBlacklistTypeFilter | ||
100 | }) | ||
95 | .subscribe( | 101 | .subscribe( |
96 | async resultList => { | 102 | async resultList => { |
97 | this.totalRecords = resultList.total | 103 | this.totalRecords = resultList.total |
diff --git a/client/src/app/shared/blocklist/blocklist.service.ts b/client/src/app/shared/blocklist/blocklist.service.ts index c1f7312f0..5cf265bc1 100644 --- a/client/src/app/shared/blocklist/blocklist.service.ts +++ b/client/src/app/shared/blocklist/blocklist.service.ts | |||
@@ -76,10 +76,14 @@ export class BlocklistService { | |||
76 | 76 | ||
77 | /*********************** Instance -> Account blocklist ***********************/ | 77 | /*********************** Instance -> Account blocklist ***********************/ |
78 | 78 | ||
79 | getInstanceAccountBlocklist (pagination: RestPagination, sort: SortMeta) { | 79 | getInstanceAccountBlocklist (options: { pagination: RestPagination, sort: SortMeta, search: string }) { |
80 | const { pagination, sort, search } = options | ||
81 | |||
80 | let params = new HttpParams() | 82 | let params = new HttpParams() |
81 | params = this.restService.addRestGetParams(params, pagination, sort) | 83 | params = this.restService.addRestGetParams(params, pagination, sort) |
82 | 84 | ||
85 | if (search) params = params.append('search', search) | ||
86 | |||
83 | return this.authHttp.get<ResultList<AccountBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', { params }) | 87 | return this.authHttp.get<ResultList<AccountBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', { params }) |
84 | .pipe( | 88 | .pipe( |
85 | map(res => this.restExtractor.convertResultListDateToHuman(res)), | 89 | map(res => this.restExtractor.convertResultListDateToHuman(res)), |
@@ -104,10 +108,14 @@ export class BlocklistService { | |||
104 | 108 | ||
105 | /*********************** Instance -> Server blocklist ***********************/ | 109 | /*********************** Instance -> Server blocklist ***********************/ |
106 | 110 | ||
107 | getInstanceServerBlocklist (pagination: RestPagination, sort: SortMeta) { | 111 | getInstanceServerBlocklist (options: { pagination: RestPagination, sort: SortMeta, search: string }) { |
112 | const { pagination, sort, search } = options | ||
113 | |||
108 | let params = new HttpParams() | 114 | let params = new HttpParams() |
109 | params = this.restService.addRestGetParams(params, pagination, sort) | 115 | params = this.restService.addRestGetParams(params, pagination, sort) |
110 | 116 | ||
117 | if (search) params = params.append('search', search) | ||
118 | |||
111 | return this.authHttp.get<ResultList<ServerBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/servers', { params }) | 119 | return this.authHttp.get<ResultList<ServerBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/servers', { params }) |
112 | .pipe( | 120 | .pipe( |
113 | map(res => this.restExtractor.convertResultListDateToHuman(res)), | 121 | map(res => this.restExtractor.convertResultListDateToHuman(res)), |
diff --git a/client/src/app/shared/video-blacklist/video-blacklist.service.ts b/client/src/app/shared/video-blacklist/video-blacklist.service.ts index 116177c4a..c0e13a651 100644 --- a/client/src/app/shared/video-blacklist/video-blacklist.service.ts +++ b/client/src/app/shared/video-blacklist/video-blacklist.service.ts | |||
@@ -19,13 +19,19 @@ export class VideoBlacklistService { | |||
19 | private restExtractor: RestExtractor | 19 | private restExtractor: RestExtractor |
20 | ) {} | 20 | ) {} |
21 | 21 | ||
22 | listBlacklist (pagination: RestPagination, sort: SortMeta, type?: VideoBlacklistType): Observable<ResultList<VideoBlacklist>> { | 22 | listBlacklist (options: { |
23 | pagination: RestPagination, | ||
24 | sort: SortMeta, | ||
25 | search?: string | ||
26 | type?: VideoBlacklistType | ||
27 | }): Observable<ResultList<VideoBlacklist>> { | ||
28 | const { pagination, sort, search, type } = options | ||
29 | |||
23 | let params = new HttpParams() | 30 | let params = new HttpParams() |
24 | params = this.restService.addRestGetParams(params, pagination, sort) | 31 | params = this.restService.addRestGetParams(params, pagination, sort) |
25 | 32 | ||
26 | if (type) { | 33 | if (search) params = params.append('search', search) |
27 | params = params.set('type', type.toString()) | 34 | if (type) params = params.append('type', type.toString()) |
28 | } | ||
29 | 35 | ||
30 | return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params }) | 36 | return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params }) |
31 | .pipe( | 37 | .pipe( |
diff --git a/server/controllers/api/server/server-blocklist.ts b/server/controllers/api/server/server-blocklist.ts index d165db191..ffb7814fa 100644 --- a/server/controllers/api/server/server-blocklist.ts +++ b/server/controllers/api/server/server-blocklist.ts | |||
@@ -82,7 +82,13 @@ export { | |||
82 | async function listBlockedAccounts (req: express.Request, res: express.Response) { | 82 | async function listBlockedAccounts (req: express.Request, res: express.Response) { |
83 | const serverActor = await getServerActor() | 83 | const serverActor = await getServerActor() |
84 | 84 | ||
85 | const resultList = await AccountBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort) | 85 | const resultList = await AccountBlocklistModel.listForApi({ |
86 | start: req.query.start, | ||
87 | count: req.query.count, | ||
88 | sort: req.query.sort, | ||
89 | search: req.query.search, | ||
90 | accountId: serverActor.Account.id | ||
91 | }) | ||
86 | 92 | ||
87 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 93 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
88 | } | 94 | } |
@@ -107,7 +113,13 @@ async function unblockAccount (req: express.Request, res: express.Response) { | |||
107 | async function listBlockedServers (req: express.Request, res: express.Response) { | 113 | async function listBlockedServers (req: express.Request, res: express.Response) { |
108 | const serverActor = await getServerActor() | 114 | const serverActor = await getServerActor() |
109 | 115 | ||
110 | const resultList = await ServerBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort) | 116 | const resultList = await ServerBlocklistModel.listForApi({ |
117 | start: req.query.start, | ||
118 | count: req.query.count, | ||
119 | sort: req.query.sort, | ||
120 | search: req.query.search, | ||
121 | accountId: serverActor.Account.id | ||
122 | }) | ||
111 | 123 | ||
112 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 124 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
113 | } | 125 | } |
diff --git a/server/controllers/api/users/my-blocklist.ts b/server/controllers/api/users/my-blocklist.ts index 713c16022..3a44376f2 100644 --- a/server/controllers/api/users/my-blocklist.ts +++ b/server/controllers/api/users/my-blocklist.ts | |||
@@ -74,7 +74,13 @@ export { | |||
74 | async function listBlockedAccounts (req: express.Request, res: express.Response) { | 74 | async function listBlockedAccounts (req: express.Request, res: express.Response) { |
75 | const user = res.locals.oauth.token.User | 75 | const user = res.locals.oauth.token.User |
76 | 76 | ||
77 | const resultList = await AccountBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort) | 77 | const resultList = await AccountBlocklistModel.listForApi({ |
78 | start: req.query.start, | ||
79 | count: req.query.count, | ||
80 | sort: req.query.sort, | ||
81 | search: req.query.search, | ||
82 | accountId: user.Account.id | ||
83 | }) | ||
78 | 84 | ||
79 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 85 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
80 | } | 86 | } |
@@ -99,7 +105,13 @@ async function unblockAccount (req: express.Request, res: express.Response) { | |||
99 | async function listBlockedServers (req: express.Request, res: express.Response) { | 105 | async function listBlockedServers (req: express.Request, res: express.Response) { |
100 | const user = res.locals.oauth.token.User | 106 | const user = res.locals.oauth.token.User |
101 | 107 | ||
102 | const resultList = await ServerBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort) | 108 | const resultList = await ServerBlocklistModel.listForApi({ |
109 | start: req.query.start, | ||
110 | count: req.query.count, | ||
111 | sort: req.query.sort, | ||
112 | search: req.query.search, | ||
113 | accountId: user.Account.id | ||
114 | }) | ||
103 | 115 | ||
104 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 116 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
105 | } | 117 | } |
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index 2a667480d..c4aa79cd2 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts | |||
@@ -102,7 +102,13 @@ async function updateVideoBlacklistController (req: express.Request, res: expres | |||
102 | } | 102 | } |
103 | 103 | ||
104 | async function listBlacklist (req: express.Request, res: express.Response) { | 104 | async function listBlacklist (req: express.Request, res: express.Response) { |
105 | const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.type) | 105 | const resultList = await VideoBlacklistModel.listForApi({ |
106 | start: req.query.start, | ||
107 | count: req.query.count, | ||
108 | sort: req.query.sort, | ||
109 | search: req.query.search, | ||
110 | type: req.query.type | ||
111 | }) | ||
106 | 112 | ||
107 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 113 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
108 | } | 114 | } |
diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts index 5440e57e7..4bd6a8333 100644 --- a/server/middlewares/validators/videos/video-blacklist.ts +++ b/server/middlewares/validators/videos/video-blacklist.ts | |||
@@ -69,6 +69,10 @@ const videosBlacklistFiltersValidator = [ | |||
69 | query('type') | 69 | query('type') |
70 | .optional() | 70 | .optional() |
71 | .custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'), | 71 | .custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'), |
72 | query('search') | ||
73 | .optional() | ||
74 | .not() | ||
75 | .isEmpty().withMessage('Should have a valid search'), | ||
72 | 76 | ||
73 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 77 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
74 | logger.debug('Checking videos blacklist filters query', { parameters: req.query }) | 78 | logger.debug('Checking videos blacklist filters query', { parameters: req.query }) |
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts index e2f66d733..fe2d5d010 100644 --- a/server/models/account/account-blocklist.ts +++ b/server/models/account/account-blocklist.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | 1 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { AccountModel } from './account' | 2 | import { AccountModel } from './account' |
3 | import { getSort } from '../utils' | 3 | import { getSort, searchAttribute } from '../utils' |
4 | import { AccountBlock } from '../../../shared/models/blocklist' | 4 | import { AccountBlock } from '../../../shared/models/blocklist' |
5 | import { Op } from 'sequelize' | 5 | import { Op } from 'sequelize' |
6 | import * as Bluebird from 'bluebird' | 6 | import * as Bluebird from 'bluebird' |
@@ -111,16 +111,36 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> { | |||
111 | return AccountBlocklistModel.findOne(query) | 111 | return AccountBlocklistModel.findOne(query) |
112 | } | 112 | } |
113 | 113 | ||
114 | static listForApi (accountId: number, start: number, count: number, sort: string) { | 114 | static listForApi (parameters: { |
115 | start: number | ||
116 | count: number | ||
117 | sort: string | ||
118 | search?: string | ||
119 | accountId: number | ||
120 | }) { | ||
121 | const { start, count, sort, search, accountId } = parameters | ||
122 | |||
115 | const query = { | 123 | const query = { |
116 | offset: start, | 124 | offset: start, |
117 | limit: count, | 125 | limit: count, |
118 | order: getSort(sort), | 126 | order: getSort(sort) |
119 | where: { | 127 | } |
120 | accountId | 128 | |
121 | } | 129 | const where = { |
130 | accountId | ||
122 | } | 131 | } |
123 | 132 | ||
133 | if (search) { | ||
134 | Object.assign(where, { | ||
135 | [Op.or]: [ | ||
136 | { ...searchAttribute(search, '$BlockedAccount.name$') }, | ||
137 | { ...searchAttribute(search, '$BlockedAccount.Actor.url$') } | ||
138 | ] | ||
139 | }) | ||
140 | } | ||
141 | |||
142 | Object.assign(query, { where }) | ||
143 | |||
124 | return AccountBlocklistModel | 144 | return AccountBlocklistModel |
125 | .scope([ ScopeNames.WITH_ACCOUNTS ]) | 145 | .scope([ ScopeNames.WITH_ACCOUNTS ]) |
126 | .findAndCountAll<MAccountBlocklistAccounts>(query) | 146 | .findAndCountAll<MAccountBlocklistAccounts>(query) |
diff --git a/server/models/server/server-blocklist.ts b/server/models/server/server-blocklist.ts index 883ae47ab..764203d2c 100644 --- a/server/models/server/server-blocklist.ts +++ b/server/models/server/server-blocklist.ts | |||
@@ -2,7 +2,7 @@ import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, Updated | |||
2 | import { AccountModel } from '../account/account' | 2 | import { AccountModel } from '../account/account' |
3 | import { ServerModel } from './server' | 3 | import { ServerModel } from './server' |
4 | import { ServerBlock } from '../../../shared/models/blocklist' | 4 | import { ServerBlock } from '../../../shared/models/blocklist' |
5 | import { getSort } from '../utils' | 5 | import { getSort, searchAttribute } from '../utils' |
6 | import * as Bluebird from 'bluebird' | 6 | import * as Bluebird from 'bluebird' |
7 | import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models' | 7 | import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models' |
8 | import { Op } from 'sequelize' | 8 | import { Op } from 'sequelize' |
@@ -120,16 +120,27 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> { | |||
120 | return ServerBlocklistModel.findOne(query) | 120 | return ServerBlocklistModel.findOne(query) |
121 | } | 121 | } |
122 | 122 | ||
123 | static listForApi (accountId: number, start: number, count: number, sort: string) { | 123 | static listForApi (parameters: { |
124 | start: number | ||
125 | count: number | ||
126 | sort: string | ||
127 | search?: string | ||
128 | accountId: number | ||
129 | }) { | ||
130 | const { start, count, sort, search, accountId } = parameters | ||
131 | |||
124 | const query = { | 132 | const query = { |
125 | offset: start, | 133 | offset: start, |
126 | limit: count, | 134 | limit: count, |
127 | order: getSort(sort), | 135 | order: getSort(sort), |
128 | where: { | 136 | where: { |
129 | accountId | 137 | accountId, |
138 | ...searchAttribute(search, '$BlockedServer.host$') | ||
130 | } | 139 | } |
131 | } | 140 | } |
132 | 141 | ||
142 | console.log(search) | ||
143 | |||
133 | return ServerBlocklistModel | 144 | return ServerBlocklistModel |
134 | .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ]) | 145 | .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ]) |
135 | .findAndCountAll<MServerBlocklistAccountServer>(query) | 146 | .findAndCountAll<MServerBlocklistAccountServer>(query) |
diff --git a/server/models/utils.ts b/server/models/utils.ts index 06ff05864..7137419a2 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Model, Sequelize } from 'sequelize-typescript' | 1 | import { Model, Sequelize } from 'sequelize-typescript' |
2 | import validator from 'validator' | 2 | import validator from 'validator' |
3 | import { Col } from 'sequelize/types/lib/utils' | 3 | import { Col } from 'sequelize/types/lib/utils' |
4 | import { literal, OrderItem } from 'sequelize' | 4 | import { literal, OrderItem, Op } from 'sequelize' |
5 | 5 | ||
6 | type Primitive = string | Function | number | boolean | Symbol | undefined | null | 6 | type Primitive = string | Function | number | boolean | Symbol | undefined | null |
7 | type DeepOmitHelper<T, K extends keyof T> = { | 7 | type DeepOmitHelper<T, K extends keyof T> = { |
@@ -207,6 +207,16 @@ function buildDirectionAndField (value: string) { | |||
207 | return { direction, field } | 207 | return { direction, field } |
208 | } | 208 | } |
209 | 209 | ||
210 | function searchAttribute (sourceField, targetField) { | ||
211 | return sourceField | ||
212 | ? { | ||
213 | [targetField]: { | ||
214 | [Op.iLike]: `%${sourceField}%` | ||
215 | } | ||
216 | } | ||
217 | : {} | ||
218 | } | ||
219 | |||
210 | // --------------------------------------------------------------------------- | 220 | // --------------------------------------------------------------------------- |
211 | 221 | ||
212 | export { | 222 | export { |
@@ -228,7 +238,8 @@ export { | |||
228 | parseAggregateResult, | 238 | parseAggregateResult, |
229 | getFollowsSort, | 239 | getFollowsSort, |
230 | buildDirectionAndField, | 240 | buildDirectionAndField, |
231 | createSafeIn | 241 | createSafeIn, |
242 | searchAttribute | ||
232 | } | 243 | } |
233 | 244 | ||
234 | // --------------------------------------------------------------------------- | 245 | // --------------------------------------------------------------------------- |
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts index d68608ca6..e8c3bd823 100644 --- a/server/models/video/video-abuse.ts +++ b/server/models/video/video-abuse.ts | |||
@@ -9,7 +9,7 @@ import { | |||
9 | isVideoAbuseStateValid | 9 | isVideoAbuseStateValid |
10 | } from '../../helpers/custom-validators/video-abuses' | 10 | } from '../../helpers/custom-validators/video-abuses' |
11 | import { AccountModel } from '../account/account' | 11 | import { AccountModel } from '../account/account' |
12 | import { buildBlockedAccountSQL, getSort, throwIfNotValid } from '../utils' | 12 | import { buildBlockedAccountSQL, getSort, throwIfNotValid, searchAttribute } from '../utils' |
13 | import { VideoModel } from './video' | 13 | import { VideoModel } from './video' |
14 | import { VideoAbuseState, VideoDetails } from '../../../shared' | 14 | import { VideoAbuseState, VideoDetails } from '../../../shared' |
15 | import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' | 15 | import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' |
@@ -17,8 +17,8 @@ import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } | |||
17 | import * as Bluebird from 'bluebird' | 17 | import * as Bluebird from 'bluebird' |
18 | import { literal, Op } from 'sequelize' | 18 | import { literal, Op } from 'sequelize' |
19 | import { ThumbnailModel } from './thumbnail' | 19 | import { ThumbnailModel } from './thumbnail' |
20 | import { VideoChannelModel } from './video-channel' | ||
21 | import { VideoBlacklistModel } from './video-blacklist' | 20 | import { VideoBlacklistModel } from './video-blacklist' |
21 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' | ||
22 | 22 | ||
23 | export enum ScopeNames { | 23 | export enum ScopeNames { |
24 | FOR_API = 'FOR_API' | 24 | FOR_API = 'FOR_API' |
@@ -33,12 +33,6 @@ export enum ScopeNames { | |||
33 | serverAccountId: number | 33 | serverAccountId: number |
34 | userAccountId: any | 34 | userAccountId: any |
35 | }) => { | 35 | }) => { |
36 | const search = (sourceField, targetField) => sourceField ? ({ | ||
37 | [targetField]: { | ||
38 | [Op.iLike]: `%${sourceField}%` | ||
39 | } | ||
40 | }) : {} | ||
41 | |||
42 | let where = { | 36 | let where = { |
43 | reporterAccountId: { | 37 | reporterAccountId: { |
44 | [Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')') | 38 | [Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')') |
@@ -148,19 +142,19 @@ export enum ScopeNames { | |||
148 | { | 142 | { |
149 | model: AccountModel, | 143 | model: AccountModel, |
150 | required: true, | 144 | required: true, |
151 | where: { ...search(options.searchReporter, 'name') } | 145 | where: { ...searchAttribute(options.searchReporter, 'name') } |
152 | }, | 146 | }, |
153 | { | 147 | { |
154 | model: VideoModel, | 148 | model: VideoModel, |
155 | required: false, | 149 | required: false, |
156 | where: { ...search(options.searchVideo, 'name') }, | 150 | where: { ...searchAttribute(options.searchVideo, 'name') }, |
157 | include: [ | 151 | include: [ |
158 | { | 152 | { |
159 | model: ThumbnailModel | 153 | model: ThumbnailModel |
160 | }, | 154 | }, |
161 | { | 155 | { |
162 | model: VideoChannelModel.scope([ 'WITH_ACTOR', 'WITH_ACCOUNT' ]), | 156 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), |
163 | where: { ...search(options.searchVideoChannel, 'name') } | 157 | where: { ...searchAttribute(options.searchVideoChannel, 'name') } |
164 | }, | 158 | }, |
165 | { | 159 | { |
166 | attributes: [ 'id', 'reason', 'unfederated' ], | 160 | attributes: [ 'id', 'reason', 'unfederated' ], |
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts index 694983cb3..680eba471 100644 --- a/server/models/video/video-blacklist.ts +++ b/server/models/video/video-blacklist.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' | 1 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { getBlacklistSort, SortType, throwIfNotValid } from '../utils' | 2 | import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '../utils' |
3 | import { VideoModel } from './video' | 3 | import { VideoModel } from './video' |
4 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' | 4 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' |
5 | import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' | 5 | import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' |
@@ -54,7 +54,15 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> { | |||
54 | }) | 54 | }) |
55 | Video: VideoModel | 55 | Video: VideoModel |
56 | 56 | ||
57 | static listForApi (start: number, count: number, sort: SortType, type?: VideoBlacklistType) { | 57 | static listForApi (parameters: { |
58 | start: number | ||
59 | count: number | ||
60 | sort: SortType | ||
61 | search?: string | ||
62 | type?: VideoBlacklistType | ||
63 | }) { | ||
64 | const { start, count, sort, search, type } = parameters | ||
65 | |||
58 | function buildBaseQuery (): FindOptions { | 66 | function buildBaseQuery (): FindOptions { |
59 | return { | 67 | return { |
60 | offset: start, | 68 | offset: start, |
@@ -70,6 +78,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> { | |||
70 | { | 78 | { |
71 | model: VideoModel, | 79 | model: VideoModel, |
72 | required: true, | 80 | required: true, |
81 | where: { ...searchAttribute(search, 'name') }, | ||
73 | include: [ | 82 | include: [ |
74 | { | 83 | { |
75 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), | 84 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), |