diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-01-30 22:41:14 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-01-30 22:41:14 +0100 |
commit | 28798b5d949826551740fc893d06e6424b77aa6a (patch) | |
tree | e235a7f49164a06c4b76df49ca61b89998d4ed81 | |
parent | 13fc89f4a4b91b3da10493517de556240fb65463 (diff) | |
download | PeerTube-28798b5d949826551740fc893d06e6424b77aa6a.tar.gz PeerTube-28798b5d949826551740fc893d06e6424b77aa6a.tar.zst PeerTube-28798b5d949826551740fc893d06e6424b77aa6a.zip |
Client: replace simple tables by ng2 smart table component
17 files changed, 263 insertions, 162 deletions
diff --git a/client/package.json b/client/package.json index bd6cb03e7..c762a1fd5 100644 --- a/client/package.json +++ b/client/package.json | |||
@@ -58,6 +58,7 @@ | |||
58 | "ng2-bootstrap": "1.1.16-10", | 58 | "ng2-bootstrap": "1.1.16-10", |
59 | "ng2-file-upload": "^1.1.4-2", | 59 | "ng2-file-upload": "^1.1.4-2", |
60 | "ng2-meta": "https://github.com/chocobozzz/ng2-meta#build", | 60 | "ng2-meta": "https://github.com/chocobozzz/ng2-meta#build", |
61 | "ng2-smart-table": "^0.5.1-0", | ||
61 | "ngc-webpack": "1.1.0", | 62 | "ngc-webpack": "1.1.0", |
62 | "node-sass": "^4.1.1", | 63 | "node-sass": "^4.1.1", |
63 | "normalize.css": "^5.0.0", | 64 | "normalize.css": "^5.0.0", |
diff --git a/client/src/app/+admin/friends/friend-list/friend-list.component.html b/client/src/app/+admin/friends/friend-list/friend-list.component.html index 06258f8c8..254d0c65e 100644 --- a/client/src/app/+admin/friends/friend-list/friend-list.component.html +++ b/client/src/app/+admin/friends/friend-list/friend-list.component.html | |||
@@ -1,29 +1,11 @@ | |||
1 | <h3>Friends list</h3> | 1 | <h3>Friends list</h3> |
2 | 2 | ||
3 | <table class="table table-hover"> | 3 | <ng2-smart-table [settings]="tableSettings" [source]="friendsSource"></ng2-smart-table> |
4 | <thead> | ||
5 | <tr> | ||
6 | <th class="table-column-id">ID</th> | ||
7 | <th>Host</th> | ||
8 | <th>Score</th> | ||
9 | <th>Created Date</th> | ||
10 | </tr> | ||
11 | </thead> | ||
12 | 4 | ||
13 | <tbody> | 5 | <a *ngIf="hasFriends()" class="add-user btn btn-danger pull-left" (click)="quitFriends()"> |
14 | <tr *ngFor="let friend of friends"> | ||
15 | <td>{{ friend.id }}</td> | ||
16 | <td>{{ friend.host }}</td> | ||
17 | <td>{{ friend.score }}</td> | ||
18 | <td>{{ friend.createdAt | date: 'medium' }}</td> | ||
19 | </tr> | ||
20 | </tbody> | ||
21 | </table> | ||
22 | |||
23 | <a *ngIf="friends && friends.length !== 0" class="add-user btn btn-danger pull-left" (click)="quitFriends()"> | ||
24 | Quit friends | 6 | Quit friends |
25 | </a> | 7 | </a> |
26 | 8 | ||
27 | <a *ngIf="friends?.length === 0" class="add-user btn btn-success pull-right" [routerLink]="['/admin/friends/add']"> | 9 | <a *ngIf="!hasFriends()" class="add-user btn btn-success pull-right" [routerLink]="['/admin/friends/add']"> |
28 | Make friends | 10 | Make friends |
29 | </a> | 11 | </a> |
diff --git a/client/src/app/+admin/friends/friend-list/friend-list.component.ts b/client/src/app/+admin/friends/friend-list/friend-list.component.ts index 175ad9cba..f29427640 100644 --- a/client/src/app/+admin/friends/friend-list/friend-list.component.ts +++ b/client/src/app/+admin/friends/friend-list/friend-list.component.ts | |||
@@ -1,8 +1,10 @@ | |||
1 | import { Component, OnInit } from '@angular/core'; | 1 | import { Component } from '@angular/core'; |
2 | 2 | ||
3 | import { NotificationsService } from 'angular2-notifications'; | 3 | import { NotificationsService } from 'angular2-notifications'; |
4 | import { ServerDataSource } from 'ng2-smart-table'; | ||
4 | 5 | ||
5 | import { ConfirmService } from '../../../core'; | 6 | import { ConfirmService } from '../../../core'; |
7 | import { Utils } from '../../../shared'; | ||
6 | import { Friend, FriendService } from '../shared'; | 8 | import { Friend, FriendService } from '../shared'; |
7 | 9 | ||
8 | @Component({ | 10 | @Component({ |
@@ -10,17 +12,51 @@ import { Friend, FriendService } from '../shared'; | |||
10 | templateUrl: './friend-list.component.html', | 12 | templateUrl: './friend-list.component.html', |
11 | styleUrls: [ './friend-list.component.scss' ] | 13 | styleUrls: [ './friend-list.component.scss' ] |
12 | }) | 14 | }) |
13 | export class FriendListComponent implements OnInit { | 15 | export class FriendListComponent { |
14 | friends: Friend[]; | 16 | friendsSource = null; |
17 | tableSettings = { | ||
18 | attr: { | ||
19 | class: 'table-hover' | ||
20 | }, | ||
21 | hideSubHeader: true, | ||
22 | actions: { | ||
23 | position: 'right', | ||
24 | add: false, | ||
25 | edit: false, | ||
26 | delete: false | ||
27 | }, | ||
28 | columns: { | ||
29 | id: { | ||
30 | title: 'ID', | ||
31 | sort: false, | ||
32 | sortDirection: 'asc' | ||
33 | }, | ||
34 | host: { | ||
35 | title: 'Host', | ||
36 | sort: false | ||
37 | }, | ||
38 | score: { | ||
39 | title: 'Score', | ||
40 | sort: false | ||
41 | }, | ||
42 | createdAt: { | ||
43 | title: 'Created Date', | ||
44 | sort: false, | ||
45 | valuePrepareFunction: Utils.dateToHuman | ||
46 | } | ||
47 | } | ||
48 | } | ||
15 | 49 | ||
16 | constructor( | 50 | constructor( |
17 | private notificationsService: NotificationsService, | 51 | private notificationsService: NotificationsService, |
18 | private confirmService: ConfirmService, | 52 | private confirmService: ConfirmService, |
19 | private friendService: FriendService | 53 | private friendService: FriendService |
20 | ) { } | 54 | ) { |
55 | this.friendsSource = this.friendService.getDataSource(); | ||
56 | } | ||
21 | 57 | ||
22 | ngOnInit() { | 58 | hasFriends() { |
23 | this.getFriends(); | 59 | return this.friendsSource.count() != 0; |
24 | } | 60 | } |
25 | 61 | ||
26 | quitFriends() { | 62 | quitFriends() { |
@@ -33,7 +69,7 @@ export class FriendListComponent implements OnInit { | |||
33 | status => { | 69 | status => { |
34 | this.notificationsService.success('Sucess', 'Friends left!'); | 70 | this.notificationsService.success('Sucess', 'Friends left!'); |
35 | 71 | ||
36 | this.getFriends(); | 72 | this.friendsSource.refresh(); |
37 | }, | 73 | }, |
38 | 74 | ||
39 | err => this.notificationsService.error('Error', err.text) | 75 | err => this.notificationsService.error('Error', err.text) |
@@ -41,12 +77,4 @@ export class FriendListComponent implements OnInit { | |||
41 | } | 77 | } |
42 | ); | 78 | ); |
43 | } | 79 | } |
44 | |||
45 | private getFriends() { | ||
46 | this.friendService.getFriends().subscribe( | ||
47 | res => this.friends = res.friends, | ||
48 | |||
49 | err => this.notificationsService.error('Error', err.text) | ||
50 | ); | ||
51 | } | ||
52 | } | 80 | } |
diff --git a/client/src/app/+admin/friends/shared/friend.service.ts b/client/src/app/+admin/friends/shared/friend.service.ts index e97459385..6cb84f5cd 100644 --- a/client/src/app/+admin/friends/shared/friend.service.ts +++ b/client/src/app/+admin/friends/shared/friend.service.ts | |||
@@ -3,8 +3,10 @@ import { Observable } from 'rxjs/Observable'; | |||
3 | import 'rxjs/add/operator/catch'; | 3 | import 'rxjs/add/operator/catch'; |
4 | import 'rxjs/add/operator/map'; | 4 | import 'rxjs/add/operator/map'; |
5 | 5 | ||
6 | import { ServerDataSource } from 'ng2-smart-table'; | ||
7 | |||
6 | import { Friend } from './friend.model'; | 8 | import { Friend } from './friend.model'; |
7 | import { AuthHttp, RestExtractor, ResultList } from '../../../shared'; | 9 | import { AuthHttp, RestExtractor, RestDataSource, ResultList } from '../../../shared'; |
8 | 10 | ||
9 | @Injectable() | 11 | @Injectable() |
10 | export class FriendService { | 12 | export class FriendService { |
@@ -15,11 +17,8 @@ export class FriendService { | |||
15 | private restExtractor: RestExtractor | 17 | private restExtractor: RestExtractor |
16 | ) {} | 18 | ) {} |
17 | 19 | ||
18 | getFriends() { | 20 | getDataSource() { |
19 | return this.authHttp.get(FriendService.BASE_FRIEND_URL) | 21 | return new RestDataSource(this.authHttp, FriendService.BASE_FRIEND_URL); |
20 | .map(this.restExtractor.extractDataList) | ||
21 | .map(this.extractFriends) | ||
22 | .catch((res) => this.restExtractor.handleError(res)); | ||
23 | } | 22 | } |
24 | 23 | ||
25 | makeFriends(notEmptyHosts) { | 24 | makeFriends(notEmptyHosts) { |
@@ -37,11 +36,4 @@ export class FriendService { | |||
37 | .map(res => res.status) | 36 | .map(res => res.status) |
38 | .catch((res) => this.restExtractor.handleError(res)); | 37 | .catch((res) => this.restExtractor.handleError(res)); |
39 | } | 38 | } |
40 | |||
41 | private extractFriends(result: ResultList) { | ||
42 | const friends: Friend[] = result.data; | ||
43 | const totalFriends = result.total; | ||
44 | |||
45 | return { friends, totalFriends }; | ||
46 | } | ||
47 | } | 39 | } |
diff --git a/client/src/app/+admin/users/shared/user.service.ts b/client/src/app/+admin/users/shared/user.service.ts index d9005b213..f6d360e09 100644 --- a/client/src/app/+admin/users/shared/user.service.ts +++ b/client/src/app/+admin/users/shared/user.service.ts | |||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; | |||
2 | import 'rxjs/add/operator/catch'; | 2 | import 'rxjs/add/operator/catch'; |
3 | import 'rxjs/add/operator/map'; | 3 | import 'rxjs/add/operator/map'; |
4 | 4 | ||
5 | import { AuthHttp, RestExtractor, ResultList, User } from '../../../shared'; | 5 | import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared'; |
6 | 6 | ||
7 | @Injectable() | 7 | @Injectable() |
8 | export class UserService { | 8 | export class UserService { |
@@ -25,25 +25,11 @@ export class UserService { | |||
25 | .catch(this.restExtractor.handleError); | 25 | .catch(this.restExtractor.handleError); |
26 | } | 26 | } |
27 | 27 | ||
28 | getUsers() { | 28 | getDataSource() { |
29 | return this.authHttp.get(UserService.BASE_USERS_URL) | 29 | return new RestDataSource(this.authHttp, UserService.BASE_USERS_URL); |
30 | .map(this.restExtractor.extractDataList) | ||
31 | .map(this.extractUsers) | ||
32 | .catch((res) => this.restExtractor.handleError(res)); | ||
33 | } | 30 | } |
34 | 31 | ||
35 | removeUser(user: User) { | 32 | removeUser(user: User) { |
36 | return this.authHttp.delete(UserService.BASE_USERS_URL + user.id); | 33 | return this.authHttp.delete(UserService.BASE_USERS_URL + user.id); |
37 | } | 34 | } |
38 | |||
39 | private extractUsers(result: ResultList) { | ||
40 | const usersJson = result.data; | ||
41 | const totalUsers = result.total; | ||
42 | const users = []; | ||
43 | for (const userJson of usersJson) { | ||
44 | users.push(new User(userJson)); | ||
45 | } | ||
46 | |||
47 | return { users, totalUsers }; | ||
48 | } | ||
49 | } | 35 | } |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html index 36193d119..3d3d7e054 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ b/client/src/app/+admin/users/user-list/user-list.component.html | |||
@@ -1,26 +1,9 @@ | |||
1 | <h3>Users list</h3> | 1 | <h3>Users list</h3> |
2 | 2 | ||
3 | <table class="table table-hover"> | 3 | <ng2-smart-table |
4 | <thead> | 4 | [settings]="tableSettings" [source]="usersSource" |
5 | <tr> | 5 | (delete)="removeUser($event)" |
6 | <th class="table-column-id">ID</th> | 6 | ></ng2-smart-table> |
7 | <th>Username</th> | ||
8 | <th>Created Date</th> | ||
9 | <th class="text-right">Remove</th> | ||
10 | </tr> | ||
11 | </thead> | ||
12 | |||
13 | <tbody> | ||
14 | <tr *ngFor="let user of users"> | ||
15 | <td>{{ user.id }}</td> | ||
16 | <td>{{ user.username }}</td> | ||
17 | <td>{{ user.createdAt | date: 'medium' }}</td> | ||
18 | <td class="text-right"> | ||
19 | <span class="glyphicon glyphicon-remove" *ngIf="!user.isAdmin()" (click)="removeUser(user)"></span> | ||
20 | </td> | ||
21 | </tr> | ||
22 | </tbody> | ||
23 | </table> | ||
24 | 7 | ||
25 | <a class="add-user btn btn-success pull-right" [routerLink]="['/admin/users/add']"> | 8 | <a class="add-user btn btn-success pull-right" [routerLink]="['/admin/users/add']"> |
26 | <span class="glyphicon glyphicon-plus"></span> | 9 | <span class="glyphicon glyphicon-plus"></span> |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index baefb7064..db025d3a8 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import { Component, OnInit } from '@angular/core'; | 1 | import { Component } from '@angular/core'; |
2 | 2 | ||
3 | import { NotificationsService } from 'angular2-notifications'; | 3 | import { NotificationsService } from 'angular2-notifications'; |
4 | 4 | ||
5 | import { ConfirmService } from '../../../core'; | 5 | import { ConfirmService } from '../../../core'; |
6 | import { User } from '../../../shared'; | 6 | import { User, Utils } from '../../../shared'; |
7 | import { UserService } from '../shared'; | 7 | import { UserService } from '../shared'; |
8 | 8 | ||
9 | @Component({ | 9 | @Component({ |
@@ -11,33 +11,62 @@ import { UserService } from '../shared'; | |||
11 | templateUrl: './user-list.component.html', | 11 | templateUrl: './user-list.component.html', |
12 | styleUrls: [ './user-list.component.scss' ] | 12 | styleUrls: [ './user-list.component.scss' ] |
13 | }) | 13 | }) |
14 | export class UserListComponent implements OnInit { | 14 | export class UserListComponent { |
15 | totalUsers: number; | 15 | usersSource = null; |
16 | users: User[]; | 16 | tableSettings = { |
17 | mode: 'external', | ||
18 | attr: { | ||
19 | class: 'table-hover' | ||
20 | }, | ||
21 | hideSubHeader: true, | ||
22 | actions: { | ||
23 | position: 'right', | ||
24 | add: false, | ||
25 | edit: false, | ||
26 | delete: true | ||
27 | }, | ||
28 | delete: { | ||
29 | deleteButtonContent: Utils.getRowDeleteButton() | ||
30 | }, | ||
31 | pager: { | ||
32 | display: true, | ||
33 | perPage: 10 | ||
34 | }, | ||
35 | columns: { | ||
36 | id: { | ||
37 | title: 'ID', | ||
38 | sortDirection: 'asc' | ||
39 | }, | ||
40 | username: { | ||
41 | title: 'Username' | ||
42 | }, | ||
43 | role: { | ||
44 | title: 'Role', | ||
45 | sort: false | ||
46 | }, | ||
47 | createdAt: { | ||
48 | title: 'Created Date', | ||
49 | valuePrepareFunction: Utils.dateToHuman | ||
50 | } | ||
51 | } | ||
52 | } | ||
17 | 53 | ||
18 | constructor( | 54 | constructor( |
19 | private notificationsService: NotificationsService, | 55 | private notificationsService: NotificationsService, |
20 | private confirmService: ConfirmService, | 56 | private confirmService: ConfirmService, |
21 | private userService: UserService | 57 | private userService: UserService |
22 | ) {} | 58 | ) { |
23 | 59 | this.usersSource = this.userService.getDataSource(); | |
24 | ngOnInit() { | ||
25 | this.getUsers(); | ||
26 | } | 60 | } |
27 | 61 | ||
28 | getUsers() { | 62 | removeUser({ data }) { |
29 | this.userService.getUsers().subscribe( | 63 | const user: User = data; |
30 | ({ users, totalUsers }) => { | ||
31 | this.users = users; | ||
32 | this.totalUsers = totalUsers; | ||
33 | }, | ||
34 | |||
35 | err => this.notificationsService.error('Error', err.text) | ||
36 | ); | ||
37 | } | ||
38 | 64 | ||
65 | if (user.username === 'root') { | ||
66 | this.notificationsService.error('Error', 'You cannot delete root.'); | ||
67 | return; | ||
68 | } | ||
39 | 69 | ||
40 | removeUser(user: User) { | ||
41 | this.confirmService.confirm('Do you really want to delete this user?', 'Delete').subscribe( | 70 | this.confirmService.confirm('Do you really want to delete this user?', 'Delete').subscribe( |
42 | res => { | 71 | res => { |
43 | if (res === false) return; | 72 | if (res === false) return; |
@@ -45,7 +74,7 @@ export class UserListComponent implements OnInit { | |||
45 | this.userService.removeUser(user).subscribe( | 74 | this.userService.removeUser(user).subscribe( |
46 | () => { | 75 | () => { |
47 | this.notificationsService.success('Success', `User ${user.username} deleted.`); | 76 | this.notificationsService.success('Success', `User ${user.username} deleted.`); |
48 | this.getUsers(); | 77 | this.usersSource.refresh(); |
49 | }, | 78 | }, |
50 | 79 | ||
51 | err => this.notificationsService.error('Error', err.text) | 80 | err => this.notificationsService.error('Error', err.text) |
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html index 46043577c..b2fd17bf0 100644 --- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html +++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html | |||
@@ -1,27 +1,5 @@ | |||
1 | <h3>Video abuses list</h3> | 1 | <h3>Video abuses list</h3> |
2 | 2 | ||
3 | <table class="table table-hover"> | 3 | <ng2-smart-table |
4 | <thead> | 4 | [settings]="tableSettings" [source]="videoAbusesSource" |
5 | <tr> | 5 | ></ng2-smart-table> |
6 | <th class="cell-id">ID</th> | ||
7 | <th class="cell-reason">Reason</th> | ||
8 | <th>Reporter pod host</th> | ||
9 | <th>Reporter username</th> | ||
10 | <th>Video</th> | ||
11 | <th>Created at</th> | ||
12 | </tr> | ||
13 | </thead> | ||
14 | |||
15 | <tbody> | ||
16 | <tr *ngFor="let videoAbuse of videoAbuses"> | ||
17 | <td>{{ videoAbuse.id }}</td> | ||
18 | <td>{{ videoAbuse.reason }}</td> | ||
19 | <td>{{ videoAbuse.reporterPodHost }}</td> | ||
20 | <td>{{ videoAbuse.reporterUsername }}</td> | ||
21 | <td> | ||
22 | <a [routerLink]="buildVideoLink(videoAbuse)" title="Go to video">{{ videoAbuse.videoId }}</a> | ||
23 | </td> | ||
24 | <td>{{ videoAbuse.createdAt | date: 'medium' }}</td> | ||
25 | </tr> | ||
26 | </tbody> | ||
27 | </table> | ||
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts index cfd9151b0..2f22a4ab0 100644 --- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts +++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts | |||
@@ -1,35 +1,72 @@ | |||
1 | import { Component, OnInit } from '@angular/core'; | 1 | import { Component } from '@angular/core'; |
2 | 2 | ||
3 | import { NotificationsService } from 'angular2-notifications'; | 3 | import { NotificationsService } from 'angular2-notifications'; |
4 | 4 | ||
5 | import { VideoAbuseService, VideoAbuse} from '../../../shared'; | 5 | import { Utils, VideoAbuseService, VideoAbuse} from '../../../shared'; |
6 | 6 | ||
7 | @Component({ | 7 | @Component({ |
8 | selector: 'my-video-abuse-list', | 8 | selector: 'my-video-abuse-list', |
9 | templateUrl: './video-abuse-list.component.html', | 9 | templateUrl: './video-abuse-list.component.html', |
10 | styleUrls: [ './video-abuse-list.component.scss' ] | 10 | styleUrls: [ './video-abuse-list.component.scss' ] |
11 | }) | 11 | }) |
12 | export class VideoAbuseListComponent implements OnInit { | 12 | export class VideoAbuseListComponent { |
13 | videoAbuses: VideoAbuse[]; | 13 | videoAbusesSource = null; |
14 | tableSettings = { | ||
15 | mode: 'external', | ||
16 | attr: { | ||
17 | class: 'table-hover' | ||
18 | }, | ||
19 | hideSubHeader: true, | ||
20 | actions: { | ||
21 | position: 'right', | ||
22 | add: false, | ||
23 | edit: false, | ||
24 | delete: false | ||
25 | }, | ||
26 | pager: { | ||
27 | display: true, | ||
28 | perPage: 10 | ||
29 | }, | ||
30 | columns: { | ||
31 | id: { | ||
32 | title: 'ID', | ||
33 | sortDirection: 'asc' | ||
34 | }, | ||
35 | reason: { | ||
36 | title: 'Reason', | ||
37 | sort: false | ||
38 | }, | ||
39 | reporterPodHost: { | ||
40 | title: 'Reporter pod host', | ||
41 | sort: false | ||
42 | }, | ||
43 | reporterUsername: { | ||
44 | title: 'Reporter username', | ||
45 | sort: false | ||
46 | }, | ||
47 | videoId: { | ||
48 | title: 'Video', | ||
49 | type: 'html', | ||
50 | sort: false, | ||
51 | valuePrepareFunction: this.buildVideoLink | ||
52 | }, | ||
53 | createdAt: { | ||
54 | title: 'Created Date', | ||
55 | valuePrepareFunction: Utils.dateToHuman | ||
56 | } | ||
57 | } | ||
58 | } | ||
14 | 59 | ||
15 | constructor( | 60 | constructor( |
16 | private notificationsService: NotificationsService, | 61 | private notificationsService: NotificationsService, |
17 | private videoAbuseService: VideoAbuseService | 62 | private videoAbuseService: VideoAbuseService |
18 | ) { } | 63 | ) { |
19 | 64 | this.videoAbusesSource = this.videoAbuseService.getDataSource(); | |
20 | ngOnInit() { | 65 | } |
21 | this.getVideoAbuses(); | ||
22 | } | ||
23 | |||
24 | buildVideoLink(videoAbuse: VideoAbuse) { | ||
25 | return `/videos/${videoAbuse.videoId}`; | ||
26 | } | ||
27 | |||
28 | private getVideoAbuses() { | ||
29 | this.videoAbuseService.getVideoAbuses().subscribe( | ||
30 | res => this.videoAbuses = res.videoAbuses, | ||
31 | 66 | ||
32 | err => this.notificationsService.error('Error', err.text) | 67 | buildVideoLink(videoId: string) { |
33 | ); | 68 | // TODO: transform to routerLink |
69 | // https://github.com/akveo/ng2-smart-table/issues/57 | ||
70 | return `<a href="/videos/${videoId}" title="Go to the video">${videoId}</a>`; | ||
34 | } | 71 | } |
35 | } | 72 | } |
diff --git a/client/src/app/shared/index.ts b/client/src/app/shared/index.ts index 7876e6f14..61e8ed523 100644 --- a/client/src/app/shared/index.ts +++ b/client/src/app/shared/index.ts | |||
@@ -5,3 +5,4 @@ export * from './search'; | |||
5 | export * from './users'; | 5 | export * from './users'; |
6 | export * from './video-abuse'; | 6 | export * from './video-abuse'; |
7 | export * from './shared.module'; | 7 | export * from './shared.module'; |
8 | export * from './utils'; | ||
diff --git a/client/src/app/shared/rest/index.ts b/client/src/app/shared/rest/index.ts index 3c9509dc7..3cb123c3b 100644 --- a/client/src/app/shared/rest/index.ts +++ b/client/src/app/shared/rest/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './rest-data-source'; | ||
1 | export * from './rest-extractor.service'; | 2 | export * from './rest-extractor.service'; |
2 | export * from './rest-pagination'; | 3 | export * from './rest-pagination'; |
3 | export * from './rest.service'; | 4 | export * from './rest.service'; |
diff --git a/client/src/app/shared/rest/rest-data-source.ts b/client/src/app/shared/rest/rest-data-source.ts new file mode 100644 index 000000000..847dd7c56 --- /dev/null +++ b/client/src/app/shared/rest/rest-data-source.ts | |||
@@ -0,0 +1,51 @@ | |||
1 | import { Http, RequestOptionsArgs, URLSearchParams, } from '@angular/http'; | ||
2 | |||
3 | import { ServerDataSource } from 'ng2-smart-table'; | ||
4 | |||
5 | export class RestDataSource extends ServerDataSource { | ||
6 | constructor(http: Http, endpoint: string) { | ||
7 | const options = { | ||
8 | endPoint: endpoint, | ||
9 | sortFieldKey: 'sort', | ||
10 | dataKey: 'data' | ||
11 | } | ||
12 | |||
13 | super(http, options); | ||
14 | } | ||
15 | |||
16 | protected extractTotalFromResponse(res) { | ||
17 | const rawData = res.json(); | ||
18 | return rawData ? parseInt(rawData.total): 0; | ||
19 | } | ||
20 | |||
21 | protected addSortRequestOptions(requestOptions: RequestOptionsArgs) { | ||
22 | let searchParams: URLSearchParams = <URLSearchParams> requestOptions.search; | ||
23 | |||
24 | if (this.sortConf) { | ||
25 | this.sortConf.forEach((fieldConf) => { | ||
26 | const sortPrefix = fieldConf.direction === 'desc' ? '-' : ''; | ||
27 | |||
28 | searchParams.set(this.conf.sortFieldKey, sortPrefix + fieldConf.field); | ||
29 | }); | ||
30 | } | ||
31 | |||
32 | return requestOptions; | ||
33 | } | ||
34 | |||
35 | protected addPagerRequestOptions(requestOptions: RequestOptionsArgs) { | ||
36 | let searchParams: URLSearchParams = <URLSearchParams> requestOptions.search; | ||
37 | |||
38 | if (this.pagingConf && this.pagingConf['page'] && this.pagingConf['perPage']) { | ||
39 | const perPage = this.pagingConf['perPage']; | ||
40 | const page = this.pagingConf['page']; | ||
41 | |||
42 | const start = (page - 1) * perPage; | ||
43 | const count = perPage; | ||
44 | |||
45 | searchParams.set('start', start.toString()); | ||
46 | searchParams.set('count', count.toString()); | ||
47 | } | ||
48 | |||
49 | return requestOptions; | ||
50 | } | ||
51 | } | ||
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 7b2386d6c..99893c8b1 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -10,6 +10,7 @@ import { ProgressbarModule } from 'ng2-bootstrap/progressbar'; | |||
10 | import { PaginationModule } from 'ng2-bootstrap/pagination'; | 10 | import { PaginationModule } from 'ng2-bootstrap/pagination'; |
11 | import { ModalModule } from 'ng2-bootstrap/modal'; | 11 | import { ModalModule } from 'ng2-bootstrap/modal'; |
12 | import { FileUploadModule } from 'ng2-file-upload/ng2-file-upload'; | 12 | import { FileUploadModule } from 'ng2-file-upload/ng2-file-upload'; |
13 | import { Ng2SmartTableModule } from 'ng2-smart-table'; | ||
13 | 14 | ||
14 | import { AUTH_HTTP_PROVIDERS } from './auth'; | 15 | import { AUTH_HTTP_PROVIDERS } from './auth'; |
15 | import { RestExtractor, RestService } from './rest'; | 16 | import { RestExtractor, RestService } from './rest'; |
@@ -29,7 +30,8 @@ import { VideoAbuseService } from './video-abuse'; | |||
29 | PaginationModule.forRoot(), | 30 | PaginationModule.forRoot(), |
30 | ProgressbarModule.forRoot(), | 31 | ProgressbarModule.forRoot(), |
31 | 32 | ||
32 | FileUploadModule | 33 | FileUploadModule, |
34 | Ng2SmartTableModule | ||
33 | ], | 35 | ], |
34 | 36 | ||
35 | declarations: [ | 37 | declarations: [ |
@@ -49,6 +51,7 @@ import { VideoAbuseService } from './video-abuse'; | |||
49 | ModalModule, | 51 | ModalModule, |
50 | PaginationModule, | 52 | PaginationModule, |
51 | ProgressbarModule, | 53 | ProgressbarModule, |
54 | Ng2SmartTableModule, | ||
52 | BytesPipe, | 55 | BytesPipe, |
53 | 56 | ||
54 | SearchComponent | 57 | SearchComponent |
diff --git a/client/src/app/shared/utils.ts b/client/src/app/shared/utils.ts new file mode 100644 index 000000000..1dd6f96f0 --- /dev/null +++ b/client/src/app/shared/utils.ts | |||
@@ -0,0 +1,12 @@ | |||
1 | import { DatePipe } from '@angular/common'; | ||
2 | |||
3 | export class Utils { | ||
4 | |||
5 | static dateToHuman(date: String) { | ||
6 | return new DatePipe('en').transform(date, 'medium') | ||
7 | } | ||
8 | |||
9 | static getRowDeleteButton() { | ||
10 | return '<span class="glyphicon glyphicon-remove glyphicon-black"></span>'; | ||
11 | } | ||
12 | } | ||
diff --git a/client/src/app/shared/video-abuse/video-abuse.service.ts b/client/src/app/shared/video-abuse/video-abuse.service.ts index 2750a41c7..f23c36f05 100644 --- a/client/src/app/shared/video-abuse/video-abuse.service.ts +++ b/client/src/app/shared/video-abuse/video-abuse.service.ts | |||
@@ -6,7 +6,7 @@ import 'rxjs/add/operator/map'; | |||
6 | 6 | ||
7 | import { AuthService } from '../core'; | 7 | import { AuthService } from '../core'; |
8 | import { AuthHttp } from '../auth'; | 8 | import { AuthHttp } from '../auth'; |
9 | import { RestExtractor, ResultList } from '../rest'; | 9 | import { RestDataSource, RestExtractor, ResultList } from '../rest'; |
10 | import { VideoAbuse } from './video-abuse.model'; | 10 | import { VideoAbuse } from './video-abuse.model'; |
11 | 11 | ||
12 | @Injectable() | 12 | @Injectable() |
@@ -18,10 +18,8 @@ export class VideoAbuseService { | |||
18 | private restExtractor: RestExtractor | 18 | private restExtractor: RestExtractor |
19 | ) {} | 19 | ) {} |
20 | 20 | ||
21 | getVideoAbuses() { | 21 | getDataSource() { |
22 | return this.authHttp.get(VideoAbuseService.BASE_VIDEO_ABUSE_URL + 'abuse') | 22 | return new RestDataSource(this.authHttp, VideoAbuseService.BASE_VIDEO_ABUSE_URL + 'abuse'); |
23 | .map(this.restExtractor.extractDataList) | ||
24 | .map(this.extractVideoAbuses) | ||
25 | } | 23 | } |
26 | 24 | ||
27 | reportVideo(id: string, reason: string) { | 25 | reportVideo(id: string, reason: string) { |
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss index 30588067f..994b1e2b9 100644 --- a/client/src/sass/application.scss +++ b/client/src/sass/application.scss | |||
@@ -42,8 +42,23 @@ menu { | |||
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | ||
45 | .table-column-id { | 45 | .ng2-smart-table-container { |
46 | width: 200px; | 46 | .ng2-smart-table { |
47 | |||
48 | thead tr { | ||
49 | border-top: 1px solid rgb(233, 235, 236) | ||
50 | } | ||
51 | |||
52 | td, th { | ||
53 | padding: 8px !important; | ||
54 | color: #333333 !important; | ||
55 | font-size: 14px !important; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | .ng2-smart-pagination-nav .page-link { | ||
60 | font-size: 11px !important; | ||
61 | } | ||
47 | } | 62 | } |
48 | 63 | ||
49 | [hidden] { | 64 | [hidden] { |
@@ -55,6 +70,10 @@ input.readonly { | |||
55 | background-color: #fff !important; | 70 | background-color: #fff !important; |
56 | } | 71 | } |
57 | 72 | ||
73 | .glyphicon-black { | ||
74 | color: black; | ||
75 | } | ||
76 | |||
58 | footer { | 77 | footer { |
59 | border-top: 1px solid rgba(0, 0, 0, 0.2); | 78 | border-top: 1px solid rgba(0, 0, 0, 0.2); |
60 | padding-top: 10px; | 79 | padding-top: 10px; |
diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 90adbf406..ad7cf4f4d 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js | |||
@@ -18,8 +18,8 @@ const SEARCHABLE_COLUMNS = { | |||
18 | 18 | ||
19 | // Sortable columns per schema | 19 | // Sortable columns per schema |
20 | const SORTABLE_COLUMNS = { | 20 | const SORTABLE_COLUMNS = { |
21 | USERS: [ 'username', '-username', 'createdAt', '-createdAt' ], | 21 | USERS: [ 'id', '-id', 'username', '-username', 'createdAt', '-createdAt' ], |
22 | VIDEO_ABUSES: [ 'createdAt', '-createdAt' ], | 22 | VIDEO_ABUSES: [ 'id', '-id', 'createdAt', '-createdAt' ], |
23 | VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdAt', '-createdAt' ] | 23 | VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdAt', '-createdAt' ] |
24 | } | 24 | } |
25 | 25 | ||