Add filter inputs for blacklisted videos and muted accounts/servers
This commit is contained in:
parent
aeb1bed983
commit
e0a929179a
|
@ -1,9 +1,19 @@
|
||||||
<p-table
|
<p-table
|
||||||
[value]="blockedAccounts" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="blockedAccounts" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
|
||||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted accounts"
|
||||||
>
|
>
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="caption">
|
||||||
|
<div class="ml-auto">
|
||||||
|
<input
|
||||||
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
|
(keyup)="onSearch($event)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -7,13 +7,14 @@ import { AccountBlock, BlocklistService } from '@app/shared/blocklist'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-instance-account-blocklist',
|
selector: 'my-instance-account-blocklist',
|
||||||
styleUrls: [ './instance-account-blocklist.component.scss' ],
|
styleUrls: [ '../moderation.component.scss', './instance-account-blocklist.component.scss' ],
|
||||||
templateUrl: './instance-account-blocklist.component.html'
|
templateUrl: './instance-account-blocklist.component.html'
|
||||||
})
|
})
|
||||||
export class InstanceAccountBlocklistComponent extends RestTable implements OnInit {
|
export class InstanceAccountBlocklistComponent extends RestTable implements OnInit {
|
||||||
blockedAccounts: AccountBlock[] = []
|
blockedAccounts: AccountBlock[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPageOptions = [ 20, 50, 100 ]
|
||||||
|
rowsPerPage = this.rowsPerPageOptions[0]
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
|
@ -49,7 +50,11 @@ export class InstanceAccountBlocklistComponent extends RestTable implements OnIn
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
return this.blocklistService.getInstanceAccountBlocklist(this.pagination, this.sort)
|
return this.blocklistService.getInstanceAccountBlocklist({
|
||||||
|
pagination: this.pagination,
|
||||||
|
sort: this.sort,
|
||||||
|
search: this.search
|
||||||
|
})
|
||||||
.subscribe(
|
.subscribe(
|
||||||
resultList => {
|
resultList => {
|
||||||
this.blockedAccounts = resultList.data
|
this.blockedAccounts = resultList.data
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
<p-table
|
<p-table
|
||||||
[value]="blockedServers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="blockedServers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
|
||||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted instances"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} muted instances"
|
||||||
>
|
>
|
||||||
<ng-template pTemplate="caption">
|
<ng-template pTemplate="caption">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<a class="ml-auto block-button" (click)="addServersToBlock()" (key.enter)="addServersToBlock()">
|
<div class="ml-auto">
|
||||||
|
<input
|
||||||
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
|
(keyup)="onSearch($event)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<a class="ml-2 block-button" (click)="addServersToBlock()" (key.enter)="addServersToBlock()">
|
||||||
<my-global-icon iconName="add"></my-global-icon>
|
<my-global-icon iconName="add"></my-global-icon>
|
||||||
<ng-container i18n>Mute domain</ng-container>
|
<ng-container i18n>Mute domain</ng-container>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { BatchDomainsModalComponent } from '@app/+admin/config/shared/batch-doma
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-instance-server-blocklist',
|
selector: 'my-instance-server-blocklist',
|
||||||
styleUrls: [ './instance-server-blocklist.component.scss' ],
|
styleUrls: [ '../moderation.component.scss', './instance-server-blocklist.component.scss' ],
|
||||||
templateUrl: './instance-server-blocklist.component.html'
|
templateUrl: './instance-server-blocklist.component.html'
|
||||||
})
|
})
|
||||||
export class InstanceServerBlocklistComponent extends RestTable implements OnInit {
|
export class InstanceServerBlocklistComponent extends RestTable implements OnInit {
|
||||||
|
@ -17,7 +17,8 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
|
||||||
|
|
||||||
blockedServers: ServerBlock[] = []
|
blockedServers: ServerBlock[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPageOptions = [ 20, 50, 100 ]
|
||||||
|
rowsPerPage = this.rowsPerPageOptions[0]
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
|
@ -72,7 +73,11 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
return this.blocklistService.getInstanceServerBlocklist(this.pagination, this.sort)
|
return this.blocklistService.getInstanceServerBlocklist({
|
||||||
|
pagination: this.pagination,
|
||||||
|
sort: this.sort,
|
||||||
|
search: this.search
|
||||||
|
})
|
||||||
.subscribe(
|
.subscribe(
|
||||||
resultList => {
|
resultList => {
|
||||||
this.blockedServers = resultList.data
|
this.blockedServers = resultList.data
|
||||||
|
|
|
@ -7,6 +7,14 @@
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
input {
|
||||||
|
@include peertube-input-text(250px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.moderation-expanded {
|
.moderation-expanded {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
@import 'mixins';
|
@import 'mixins';
|
||||||
@import 'miniature';
|
@import 'miniature';
|
||||||
|
|
||||||
.caption {
|
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
input {
|
|
||||||
@include peertube-input-text(250px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-details-date-updated {
|
.video-details-date-updated {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
margin-top: .1rem;
|
margin-top: .1rem;
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
<p-table
|
<p-table
|
||||||
[value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
|
||||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
|
||||||
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
|
||||||
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blacklisted videos"
|
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blacklisted videos"
|
||||||
>
|
>
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="caption">
|
||||||
|
<div class="ml-auto">
|
||||||
|
<input
|
||||||
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
|
(keyup)="onSearch($event)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 40px"></th>
|
<th style="width: 40px"></th>
|
||||||
|
@ -33,7 +44,7 @@
|
||||||
<div class="video-table-video-text">
|
<div class="video-table-video-text">
|
||||||
<div>
|
<div>
|
||||||
{{ videoBlacklist.video.name }}
|
{{ videoBlacklist.video.name }}
|
||||||
<span class="glyphicon glyphicon-new-window"></span>
|
<span i18n-title title="Video was blacklisted" class="glyphicon glyphicon-ban-circle"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-muted">by {{ videoBlacklist.video.channel?.displayName }} on {{ videoBlacklist.video.channel?.host }} </div>
|
<div class="text-muted">by {{ videoBlacklist.video.channel?.displayName }} on {{ videoBlacklist.video.channel?.host }} </div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,7 +64,10 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<td class="action-cell">
|
<td class="action-cell">
|
||||||
<my-action-dropdown i18n-label placement="bottom-right" label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"></my-action-dropdown>
|
<my-action-dropdown
|
||||||
|
[ngClass]="{ 'show': expanded }" placement="bottom-right" container="body"
|
||||||
|
i18n-label label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"
|
||||||
|
></my-action-dropdown>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -61,8 +75,10 @@
|
||||||
<ng-template pTemplate="rowexpansion" let-videoBlacklist>
|
<ng-template pTemplate="rowexpansion" let-videoBlacklist>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="expand-cell" colspan="6">
|
<td class="expand-cell" colspan="6">
|
||||||
|
<div class="d-flex moderation-expanded">
|
||||||
<span class="col-2 moderation-expanded-label" i18n>Blacklist reason:</span>
|
<span class="col-2 moderation-expanded-label" i18n>Blacklist reason:</span>
|
||||||
<span class="col-9 moderation-expanded-text" [innerHTML]="videoBlacklist.reasonHtml"></span>
|
<span class="col-9 moderation-expanded-text" [innerHTML]="videoBlacklist.reasonHtml"></span>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
|
@ -17,7 +17,8 @@ import { MarkdownService } from '@app/shared/renderer'
|
||||||
export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
blacklist: (VideoBlacklist & { reasonHtml?: string })[] = []
|
blacklist: (VideoBlacklist & { reasonHtml?: string })[] = []
|
||||||
totalRecords = 0
|
totalRecords = 0
|
||||||
rowsPerPage = 10
|
rowsPerPageOptions = [ 20, 50, 100 ]
|
||||||
|
rowsPerPage = this.rowsPerPageOptions[0]
|
||||||
sort: SortMeta = { field: 'createdAt', order: -1 }
|
sort: SortMeta = { field: 'createdAt', order: -1 }
|
||||||
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
listBlacklistTypeFilter: VideoBlacklistType = undefined
|
listBlacklistTypeFilter: VideoBlacklistType = undefined
|
||||||
|
@ -38,7 +39,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.serverService.getConfig()
|
this.serverService.getConfig()
|
||||||
.subscribe(config => {
|
.subscribe(config => {
|
||||||
// don't filter if auto-blacklist not enabled as this will be the only list
|
// don't filter if auto-blacklist is not enabled as this will be the only list
|
||||||
if (config.autoBlacklist.videos.ofUsers.enabled) {
|
if (config.autoBlacklist.videos.ofUsers.enabled) {
|
||||||
this.listBlacklistTypeFilter = VideoBlacklistType.MANUAL
|
this.listBlacklistTypeFilter = VideoBlacklistType.MANUAL
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,12 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
this.videoBlacklistService.listBlacklist(this.pagination, this.sort, this.listBlacklistTypeFilter)
|
this.videoBlacklistService.listBlacklist({
|
||||||
|
pagination: this.pagination,
|
||||||
|
sort: this.sort,
|
||||||
|
search: this.search,
|
||||||
|
type: this.listBlacklistTypeFilter
|
||||||
|
})
|
||||||
.subscribe(
|
.subscribe(
|
||||||
async resultList => {
|
async resultList => {
|
||||||
this.totalRecords = resultList.total
|
this.totalRecords = resultList.total
|
||||||
|
|
|
@ -76,10 +76,14 @@ export class BlocklistService {
|
||||||
|
|
||||||
/*********************** Instance -> Account blocklist ***********************/
|
/*********************** Instance -> Account blocklist ***********************/
|
||||||
|
|
||||||
getInstanceAccountBlocklist (pagination: RestPagination, sort: SortMeta) {
|
getInstanceAccountBlocklist (options: { pagination: RestPagination, sort: SortMeta, search: string }) {
|
||||||
|
const { pagination, sort, search } = options
|
||||||
|
|
||||||
let params = new HttpParams()
|
let params = new HttpParams()
|
||||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
|
if (search) params = params.append('search', search)
|
||||||
|
|
||||||
return this.authHttp.get<ResultList<AccountBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', { params })
|
return this.authHttp.get<ResultList<AccountBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||||
|
@ -104,10 +108,14 @@ export class BlocklistService {
|
||||||
|
|
||||||
/*********************** Instance -> Server blocklist ***********************/
|
/*********************** Instance -> Server blocklist ***********************/
|
||||||
|
|
||||||
getInstanceServerBlocklist (pagination: RestPagination, sort: SortMeta) {
|
getInstanceServerBlocklist (options: { pagination: RestPagination, sort: SortMeta, search: string }) {
|
||||||
|
const { pagination, sort, search } = options
|
||||||
|
|
||||||
let params = new HttpParams()
|
let params = new HttpParams()
|
||||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
|
if (search) params = params.append('search', search)
|
||||||
|
|
||||||
return this.authHttp.get<ResultList<ServerBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/servers', { params })
|
return this.authHttp.get<ResultList<ServerBlock>>(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/servers', { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||||
|
|
|
@ -19,13 +19,19 @@ export class VideoBlacklistService {
|
||||||
private restExtractor: RestExtractor
|
private restExtractor: RestExtractor
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
listBlacklist (pagination: RestPagination, sort: SortMeta, type?: VideoBlacklistType): Observable<ResultList<VideoBlacklist>> {
|
listBlacklist (options: {
|
||||||
|
pagination: RestPagination,
|
||||||
|
sort: SortMeta,
|
||||||
|
search?: string
|
||||||
|
type?: VideoBlacklistType
|
||||||
|
}): Observable<ResultList<VideoBlacklist>> {
|
||||||
|
const { pagination, sort, search, type } = options
|
||||||
|
|
||||||
let params = new HttpParams()
|
let params = new HttpParams()
|
||||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
if (type) {
|
if (search) params = params.append('search', search)
|
||||||
params = params.set('type', type.toString())
|
if (type) params = params.append('type', type.toString())
|
||||||
}
|
|
||||||
|
|
||||||
return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
|
return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
|
|
|
@ -82,7 +82,13 @@ export {
|
||||||
async function listBlockedAccounts (req: express.Request, res: express.Response) {
|
async function listBlockedAccounts (req: express.Request, res: express.Response) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
|
|
||||||
const resultList = await AccountBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await AccountBlocklistModel.listForApi({
|
||||||
|
start: req.query.start,
|
||||||
|
count: req.query.count,
|
||||||
|
sort: req.query.sort,
|
||||||
|
search: req.query.search,
|
||||||
|
accountId: serverActor.Account.id
|
||||||
|
})
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
@ -107,7 +113,13 @@ async function unblockAccount (req: express.Request, res: express.Response) {
|
||||||
async function listBlockedServers (req: express.Request, res: express.Response) {
|
async function listBlockedServers (req: express.Request, res: express.Response) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
|
|
||||||
const resultList = await ServerBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await ServerBlocklistModel.listForApi({
|
||||||
|
start: req.query.start,
|
||||||
|
count: req.query.count,
|
||||||
|
sort: req.query.sort,
|
||||||
|
search: req.query.search,
|
||||||
|
accountId: serverActor.Account.id
|
||||||
|
})
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,13 @@ export {
|
||||||
async function listBlockedAccounts (req: express.Request, res: express.Response) {
|
async function listBlockedAccounts (req: express.Request, res: express.Response) {
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
const resultList = await AccountBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await AccountBlocklistModel.listForApi({
|
||||||
|
start: req.query.start,
|
||||||
|
count: req.query.count,
|
||||||
|
sort: req.query.sort,
|
||||||
|
search: req.query.search,
|
||||||
|
accountId: user.Account.id
|
||||||
|
})
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
@ -99,7 +105,13 @@ async function unblockAccount (req: express.Request, res: express.Response) {
|
||||||
async function listBlockedServers (req: express.Request, res: express.Response) {
|
async function listBlockedServers (req: express.Request, res: express.Response) {
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
const resultList = await ServerBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await ServerBlocklistModel.listForApi({
|
||||||
|
start: req.query.start,
|
||||||
|
count: req.query.count,
|
||||||
|
sort: req.query.sort,
|
||||||
|
search: req.query.search,
|
||||||
|
accountId: user.Account.id
|
||||||
|
})
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,13 @@ async function updateVideoBlacklistController (req: express.Request, res: expres
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listBlacklist (req: express.Request, res: express.Response) {
|
async function listBlacklist (req: express.Request, res: express.Response) {
|
||||||
const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.type)
|
const resultList = await VideoBlacklistModel.listForApi({
|
||||||
|
start: req.query.start,
|
||||||
|
count: req.query.count,
|
||||||
|
sort: req.query.sort,
|
||||||
|
search: req.query.search,
|
||||||
|
type: req.query.type
|
||||||
|
})
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,10 @@ const videosBlacklistFiltersValidator = [
|
||||||
query('type')
|
query('type')
|
||||||
.optional()
|
.optional()
|
||||||
.custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'),
|
.custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'),
|
||||||
|
query('search')
|
||||||
|
.optional()
|
||||||
|
.not()
|
||||||
|
.isEmpty().withMessage('Should have a valid search'),
|
||||||
|
|
||||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
logger.debug('Checking videos blacklist filters query', { parameters: req.query })
|
logger.debug('Checking videos blacklist filters query', { parameters: req.query })
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { AccountModel } from './account'
|
import { AccountModel } from './account'
|
||||||
import { getSort } from '../utils'
|
import { getSort, searchAttribute } from '../utils'
|
||||||
import { AccountBlock } from '../../../shared/models/blocklist'
|
import { AccountBlock } from '../../../shared/models/blocklist'
|
||||||
import { Op } from 'sequelize'
|
import { Op } from 'sequelize'
|
||||||
import * as Bluebird from 'bluebird'
|
import * as Bluebird from 'bluebird'
|
||||||
|
@ -111,16 +111,36 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
|
||||||
return AccountBlocklistModel.findOne(query)
|
return AccountBlocklistModel.findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static listForApi (accountId: number, start: number, count: number, sort: string) {
|
static listForApi (parameters: {
|
||||||
|
start: number
|
||||||
|
count: number
|
||||||
|
sort: string
|
||||||
|
search?: string
|
||||||
|
accountId: number
|
||||||
|
}) {
|
||||||
|
const { start, count, sort, search, accountId } = parameters
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: getSort(sort),
|
order: getSort(sort)
|
||||||
where: {
|
}
|
||||||
|
|
||||||
|
const where = {
|
||||||
accountId
|
accountId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
Object.assign(where, {
|
||||||
|
[Op.or]: [
|
||||||
|
{ ...searchAttribute(search, '$BlockedAccount.name$') },
|
||||||
|
{ ...searchAttribute(search, '$BlockedAccount.Actor.url$') }
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object.assign(query, { where })
|
||||||
|
|
||||||
return AccountBlocklistModel
|
return AccountBlocklistModel
|
||||||
.scope([ ScopeNames.WITH_ACCOUNTS ])
|
.scope([ ScopeNames.WITH_ACCOUNTS ])
|
||||||
.findAndCountAll<MAccountBlocklistAccounts>(query)
|
.findAndCountAll<MAccountBlocklistAccounts>(query)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, Updated
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { ServerModel } from './server'
|
import { ServerModel } from './server'
|
||||||
import { ServerBlock } from '../../../shared/models/blocklist'
|
import { ServerBlock } from '../../../shared/models/blocklist'
|
||||||
import { getSort } from '../utils'
|
import { getSort, searchAttribute } from '../utils'
|
||||||
import * as Bluebird from 'bluebird'
|
import * as Bluebird from 'bluebird'
|
||||||
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models'
|
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models'
|
||||||
import { Op } from 'sequelize'
|
import { Op } from 'sequelize'
|
||||||
|
@ -120,16 +120,27 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> {
|
||||||
return ServerBlocklistModel.findOne(query)
|
return ServerBlocklistModel.findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static listForApi (accountId: number, start: number, count: number, sort: string) {
|
static listForApi (parameters: {
|
||||||
|
start: number
|
||||||
|
count: number
|
||||||
|
sort: string
|
||||||
|
search?: string
|
||||||
|
accountId: number
|
||||||
|
}) {
|
||||||
|
const { start, count, sort, search, accountId } = parameters
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: getSort(sort),
|
order: getSort(sort),
|
||||||
where: {
|
where: {
|
||||||
accountId
|
accountId,
|
||||||
|
...searchAttribute(search, '$BlockedServer.host$')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(search)
|
||||||
|
|
||||||
return ServerBlocklistModel
|
return ServerBlocklistModel
|
||||||
.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ])
|
.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ])
|
||||||
.findAndCountAll<MServerBlocklistAccountServer>(query)
|
.findAndCountAll<MServerBlocklistAccountServer>(query)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Model, Sequelize } from 'sequelize-typescript'
|
import { Model, Sequelize } from 'sequelize-typescript'
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
import { Col } from 'sequelize/types/lib/utils'
|
import { Col } from 'sequelize/types/lib/utils'
|
||||||
import { literal, OrderItem } from 'sequelize'
|
import { literal, OrderItem, Op } from 'sequelize'
|
||||||
|
|
||||||
type Primitive = string | Function | number | boolean | Symbol | undefined | null
|
type Primitive = string | Function | number | boolean | Symbol | undefined | null
|
||||||
type DeepOmitHelper<T, K extends keyof T> = {
|
type DeepOmitHelper<T, K extends keyof T> = {
|
||||||
|
@ -207,6 +207,16 @@ function buildDirectionAndField (value: string) {
|
||||||
return { direction, field }
|
return { direction, field }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function searchAttribute (sourceField, targetField) {
|
||||||
|
return sourceField
|
||||||
|
? {
|
||||||
|
[targetField]: {
|
||||||
|
[Op.iLike]: `%${sourceField}%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -228,7 +238,8 @@ export {
|
||||||
parseAggregateResult,
|
parseAggregateResult,
|
||||||
getFollowsSort,
|
getFollowsSort,
|
||||||
buildDirectionAndField,
|
buildDirectionAndField,
|
||||||
createSafeIn
|
createSafeIn,
|
||||||
|
searchAttribute
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
isVideoAbuseStateValid
|
isVideoAbuseStateValid
|
||||||
} from '../../helpers/custom-validators/video-abuses'
|
} from '../../helpers/custom-validators/video-abuses'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { buildBlockedAccountSQL, getSort, throwIfNotValid } from '../utils'
|
import { buildBlockedAccountSQL, getSort, throwIfNotValid, searchAttribute } from '../utils'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
import { VideoAbuseState, VideoDetails } from '../../../shared'
|
import { VideoAbuseState, VideoDetails } from '../../../shared'
|
||||||
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
|
||||||
|
@ -17,8 +17,8 @@ import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo }
|
||||||
import * as Bluebird from 'bluebird'
|
import * as Bluebird from 'bluebird'
|
||||||
import { literal, Op } from 'sequelize'
|
import { literal, Op } from 'sequelize'
|
||||||
import { ThumbnailModel } from './thumbnail'
|
import { ThumbnailModel } from './thumbnail'
|
||||||
import { VideoChannelModel } from './video-channel'
|
|
||||||
import { VideoBlacklistModel } from './video-blacklist'
|
import { VideoBlacklistModel } from './video-blacklist'
|
||||||
|
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
|
||||||
|
|
||||||
export enum ScopeNames {
|
export enum ScopeNames {
|
||||||
FOR_API = 'FOR_API'
|
FOR_API = 'FOR_API'
|
||||||
|
@ -33,12 +33,6 @@ export enum ScopeNames {
|
||||||
serverAccountId: number
|
serverAccountId: number
|
||||||
userAccountId: any
|
userAccountId: any
|
||||||
}) => {
|
}) => {
|
||||||
const search = (sourceField, targetField) => sourceField ? ({
|
|
||||||
[targetField]: {
|
|
||||||
[Op.iLike]: `%${sourceField}%`
|
|
||||||
}
|
|
||||||
}) : {}
|
|
||||||
|
|
||||||
let where = {
|
let where = {
|
||||||
reporterAccountId: {
|
reporterAccountId: {
|
||||||
[Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')')
|
[Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')')
|
||||||
|
@ -148,19 +142,19 @@ export enum ScopeNames {
|
||||||
{
|
{
|
||||||
model: AccountModel,
|
model: AccountModel,
|
||||||
required: true,
|
required: true,
|
||||||
where: { ...search(options.searchReporter, 'name') }
|
where: { ...searchAttribute(options.searchReporter, 'name') }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: VideoModel,
|
model: VideoModel,
|
||||||
required: false,
|
required: false,
|
||||||
where: { ...search(options.searchVideo, 'name') },
|
where: { ...searchAttribute(options.searchVideo, 'name') },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: ThumbnailModel
|
model: ThumbnailModel
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: VideoChannelModel.scope([ 'WITH_ACTOR', 'WITH_ACCOUNT' ]),
|
model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }),
|
||||||
where: { ...search(options.searchVideoChannel, 'name') }
|
where: { ...searchAttribute(options.searchVideoChannel, 'name') }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
attributes: [ 'id', 'reason', 'unfederated' ],
|
attributes: [ 'id', 'reason', 'unfederated' ],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { getBlacklistSort, SortType, throwIfNotValid } from '../utils'
|
import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '../utils'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
|
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
|
||||||
import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
|
import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
|
||||||
|
@ -54,7 +54,15 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
|
||||||
})
|
})
|
||||||
Video: VideoModel
|
Video: VideoModel
|
||||||
|
|
||||||
static listForApi (start: number, count: number, sort: SortType, type?: VideoBlacklistType) {
|
static listForApi (parameters: {
|
||||||
|
start: number
|
||||||
|
count: number
|
||||||
|
sort: SortType
|
||||||
|
search?: string
|
||||||
|
type?: VideoBlacklistType
|
||||||
|
}) {
|
||||||
|
const { start, count, sort, search, type } = parameters
|
||||||
|
|
||||||
function buildBaseQuery (): FindOptions {
|
function buildBaseQuery (): FindOptions {
|
||||||
return {
|
return {
|
||||||
offset: start,
|
offset: start,
|
||||||
|
@ -70,6 +78,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
|
||||||
{
|
{
|
||||||
model: VideoModel,
|
model: VideoModel,
|
||||||
required: true,
|
required: true,
|
||||||
|
where: { ...searchAttribute(search, 'name') },
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }),
|
model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }),
|
||||||
|
|
Loading…
Reference in New Issue