Add ability to search on followers/following
This commit is contained in:
parent
9ccff23877
commit
b014b6b9c7
|
@ -2,6 +2,15 @@
|
||||||
[value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="followers" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="caption">
|
||||||
|
<input
|
||||||
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
|
(keyup)="onSearch($event.target.value)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr>
|
<tr>
|
||||||
<th i18n style="width: 60px">ID</th>
|
<th i18n style="width: 60px">ID</th>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
@import '_variables';
|
||||||
|
@import '_mixins';
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
input {
|
||||||
|
@include peertube-input-text(250px);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,17 @@
|
||||||
[value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
[value]="following" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
[sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
|
||||||
>
|
>
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="caption">
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
|
||||||
|
(keyup)="onSearch($event.target.value)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="header">
|
<ng-template pTemplate="header">
|
||||||
<tr>
|
<tr>
|
||||||
<th i18n style="width: 60px">ID</th>
|
<th i18n style="width: 60px">ID</th>
|
||||||
|
|
|
@ -10,4 +10,12 @@ my-redundancy-checkbox /deep/ my-peertube-checkbox {
|
||||||
label {
|
label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
input {
|
||||||
|
@include peertube-input-text(250px);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -53,7 +53,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadData () {
|
protected loadData () {
|
||||||
this.followService.getFollowing(this.pagination, this.sort)
|
this.followService.getFollowing(this.pagination, this.sort, this.search)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
resultList => {
|
resultList => {
|
||||||
this.following = resultList.data
|
this.following = resultList.data
|
||||||
|
|
|
@ -18,10 +18,12 @@ export class FollowService {
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<ActorFollow>> {
|
getFollowing (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<ActorFollow>> {
|
||||||
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<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params })
|
return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/following', { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||||
|
@ -29,10 +31,12 @@ export class FollowService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<ActorFollow>> {
|
getFollowers (pagination: RestPagination, sort: SortMeta, search?: string): Observable<ResultList<ActorFollow>> {
|
||||||
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<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params })
|
return this.authHttp.get<ResultList<ActorFollow>>(FollowService.BASE_APPLICATION_URL + '/followers', { params })
|
||||||
.pipe(
|
.pipe(
|
||||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||||
|
|
|
@ -18,10 +18,7 @@ tr.banned {
|
||||||
}
|
}
|
||||||
|
|
||||||
.caption {
|
.caption {
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@include peertube-input-text(250px);
|
@include peertube-input-text(250px);
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="submit" i18n-value value="Submit" class="action-button-submit"
|
type="submit" i18n-value value="Submit" class="action-button-submit"
|
||||||
[disabled]="!form.valid"
|
[disabled]="!form.valid"
|
||||||
(click)="close()"
|
(click)="close()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,6 +16,12 @@ p-table {
|
||||||
|
|
||||||
.ui-table-caption {
|
.ui-table-caption {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
|
|
@ -61,14 +61,26 @@ export {
|
||||||
|
|
||||||
async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
const resultList = await ActorFollowModel.listFollowingForApi(serverActor.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await ActorFollowModel.listFollowingForApi(
|
||||||
|
serverActor.id,
|
||||||
|
req.query.start,
|
||||||
|
req.query.count,
|
||||||
|
req.query.sort,
|
||||||
|
req.query.search
|
||||||
|
)
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
const resultList = await ActorFollowModel.listFollowersForApi(serverActor.id, req.query.start, req.query.count, req.query.sort)
|
const resultList = await ActorFollowModel.listFollowersForApi(
|
||||||
|
serverActor.id,
|
||||||
|
req.query.start,
|
||||||
|
req.query.count,
|
||||||
|
req.query.sort,
|
||||||
|
req.query.search
|
||||||
|
)
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
||||||
return ActorFollowModel.findAll(query)
|
return ActorFollowModel.findAll(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static listFollowingForApi (id: number, start: number, count: number, sort: string) {
|
static listFollowingForApi (id: number, start: number, count: number, sort: string, search?: string) {
|
||||||
const query = {
|
const query = {
|
||||||
distinct: true,
|
distinct: true,
|
||||||
offset: start,
|
offset: start,
|
||||||
|
@ -299,7 +299,17 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
||||||
model: ActorModel,
|
model: ActorModel,
|
||||||
as: 'ActorFollowing',
|
as: 'ActorFollowing',
|
||||||
required: true,
|
required: true,
|
||||||
include: [ ServerModel ]
|
include: [
|
||||||
|
{
|
||||||
|
model: ServerModel,
|
||||||
|
required: true,
|
||||||
|
where: search ? {
|
||||||
|
host: {
|
||||||
|
[Sequelize.Op.iLike]: '%' + search + '%'
|
||||||
|
}
|
||||||
|
} : undefined
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -313,6 +323,49 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static listFollowersForApi (id: number, start: number, count: number, sort: string, search?: string) {
|
||||||
|
const query = {
|
||||||
|
distinct: true,
|
||||||
|
offset: start,
|
||||||
|
limit: count,
|
||||||
|
order: getSort(sort),
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: ActorModel,
|
||||||
|
required: true,
|
||||||
|
as: 'ActorFollower',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: ServerModel,
|
||||||
|
required: true,
|
||||||
|
where: search ? {
|
||||||
|
host: {
|
||||||
|
[ Sequelize.Op.iLike ]: '%' + search + '%'
|
||||||
|
}
|
||||||
|
} : undefined
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: ActorModel,
|
||||||
|
as: 'ActorFollowing',
|
||||||
|
required: true,
|
||||||
|
where: {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActorFollowModel.findAndCountAll(query)
|
||||||
|
.then(({ rows, count }) => {
|
||||||
|
return {
|
||||||
|
data: rows,
|
||||||
|
total: count
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
static listSubscriptionsForApi (id: number, start: number, count: number, sort: string) {
|
static listSubscriptionsForApi (id: number, start: number, count: number, sort: string) {
|
||||||
const query = {
|
const query = {
|
||||||
attributes: [],
|
attributes: [],
|
||||||
|
@ -370,39 +423,6 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static listFollowersForApi (id: number, start: number, count: number, sort: string) {
|
|
||||||
const query = {
|
|
||||||
distinct: true,
|
|
||||||
offset: start,
|
|
||||||
limit: count,
|
|
||||||
order: getSort(sort),
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: ActorModel,
|
|
||||||
required: true,
|
|
||||||
as: 'ActorFollower',
|
|
||||||
include: [ ServerModel ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: ActorModel,
|
|
||||||
as: 'ActorFollowing',
|
|
||||||
required: true,
|
|
||||||
where: {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ActorFollowModel.findAndCountAll(query)
|
|
||||||
.then(({ rows, count }) => {
|
|
||||||
return {
|
|
||||||
data: rows,
|
|
||||||
total: count
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
static listAcceptedFollowerUrlsForApi (actorIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
|
static listAcceptedFollowerUrlsForApi (actorIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
|
||||||
return ActorFollowModel.createListAcceptedFollowForApiQuery('followers', actorIds, t, start, count)
|
return ActorFollowModel.createListAcceptedFollowForApiQuery('followers', actorIds, t, start, count)
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,26 @@ describe('Test follows', function () {
|
||||||
expect(server3Follow.state).to.equal('accepted')
|
expect(server3Follow.state).to.equal('accepted')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should have 0 followings on server 1 and 2', async function () {
|
it('Should search followings on server 1', async function () {
|
||||||
|
{
|
||||||
|
const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', ':9002')
|
||||||
|
const follows = res.body.data
|
||||||
|
|
||||||
|
expect(res.body.total).to.equal(1)
|
||||||
|
expect(follows.length).to.equal(1)
|
||||||
|
expect(follows[ 0 ].following.host).to.equal('localhost:9002')
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', 'bla')
|
||||||
|
const follows = res.body.data
|
||||||
|
|
||||||
|
expect(res.body.total).to.equal(0)
|
||||||
|
expect(follows.length).to.equal(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should have 0 followings on server 2 and 3', async function () {
|
||||||
for (const server of [ servers[1], servers[2] ]) {
|
for (const server of [ servers[1], servers[2] ]) {
|
||||||
const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt')
|
const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt')
|
||||||
const follows = res.body.data
|
const follows = res.body.data
|
||||||
|
@ -116,6 +135,25 @@ describe('Test follows', function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should search followers on server 2', async function () {
|
||||||
|
{
|
||||||
|
const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', '9001')
|
||||||
|
const follows = res.body.data
|
||||||
|
|
||||||
|
expect(res.body.total).to.equal(1)
|
||||||
|
expect(follows.length).to.equal(1)
|
||||||
|
expect(follows[ 0 ].following.host).to.equal('localhost:9003')
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', 'bla')
|
||||||
|
const follows = res.body.data
|
||||||
|
|
||||||
|
expect(res.body.total).to.equal(0)
|
||||||
|
expect(follows.length).to.equal(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('Should have 0 followers on server 1', async function () {
|
it('Should have 0 followers on server 1', async function () {
|
||||||
const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt')
|
const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt')
|
||||||
const follows = res.body.data
|
const follows = res.body.data
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as request from 'supertest'
|
||||||
import { ServerInfo } from './servers'
|
import { ServerInfo } from './servers'
|
||||||
import { waitJobs } from './jobs'
|
import { waitJobs } from './jobs'
|
||||||
|
|
||||||
function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) {
|
function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
|
||||||
const path = '/api/v1/server/followers'
|
const path = '/api/v1/server/followers'
|
||||||
|
|
||||||
return request(url)
|
return request(url)
|
||||||
|
@ -10,12 +10,13 @@ function getFollowersListPaginationAndSort (url: string, start: number, count: n
|
||||||
.query({ start })
|
.query({ start })
|
||||||
.query({ count })
|
.query({ count })
|
||||||
.query({ sort })
|
.query({ sort })
|
||||||
|
.query({ search })
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) {
|
function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string, search?: string) {
|
||||||
const path = '/api/v1/server/following'
|
const path = '/api/v1/server/following'
|
||||||
|
|
||||||
return request(url)
|
return request(url)
|
||||||
|
@ -23,6 +24,7 @@ function getFollowingListPaginationAndSort (url: string, start: number, count: n
|
||||||
.query({ start })
|
.query({ start })
|
||||||
.query({ count })
|
.query({ count })
|
||||||
.query({ sort })
|
.query({ sort })
|
||||||
|
.query({ search })
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user