aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/package.json4
-rw-r--r--client/src/app/+admin/users/shared/user.service.ts25
-rw-r--r--client/src/app/+admin/users/user-add/user-add.component.html19
-rw-r--r--client/src/app/+admin/users/user-add/user-add.component.ts15
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.ts5
-rw-r--r--client/src/app/shared/forms/form-validators/user.ts7
-rw-r--r--client/src/app/shared/rest/rest-data-source.ts21
-rw-r--r--client/src/app/shared/users/user.model.ts13
-rw-r--r--client/tslint.json1
-rw-r--r--client/yarn.lock20
10 files changed, 104 insertions, 26 deletions
diff --git a/client/package.json b/client/package.json
index 27246027b..f1c7e8799 100644
--- a/client/package.json
+++ b/client/package.json
@@ -80,9 +80,9 @@
80 "string-replace-loader": "^1.0.3", 80 "string-replace-loader": "^1.0.3",
81 "style-loader": "^0.18.2", 81 "style-loader": "^0.18.2",
82 "tslib": "^1.5.0", 82 "tslib": "^1.5.0",
83 "tslint": "^5.4.3", 83 "tslint": "^5.7.0",
84 "tslint-loader": "^3.3.0", 84 "tslint-loader": "^3.3.0",
85 "typescript": "~2.4.0", 85 "typescript": "^2.5.2",
86 "url-loader": "^0.5.7", 86 "url-loader": "^0.5.7",
87 "video.js": "^6.2.0", 87 "video.js": "^6.2.0",
88 "videojs-dock": "^2.0.2", 88 "videojs-dock": "^2.0.2",
diff --git a/client/src/app/+admin/users/shared/user.service.ts b/client/src/app/+admin/users/shared/user.service.ts
index 1c1cd575e..ffd7ba7da 100644
--- a/client/src/app/+admin/users/shared/user.service.ts
+++ b/client/src/app/+admin/users/shared/user.service.ts
@@ -2,12 +2,15 @@ import { Injectable } from '@angular/core'
2import 'rxjs/add/operator/catch' 2import 'rxjs/add/operator/catch'
3import 'rxjs/add/operator/map' 3import 'rxjs/add/operator/map'
4 4
5import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe'
6
5import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared' 7import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared'
6import { UserCreate } from '../../../../../../shared' 8import { UserCreate } from '../../../../../../shared'
7 9
8@Injectable() 10@Injectable()
9export class UserService { 11export class UserService {
10 private static BASE_USERS_URL = API_URL + '/api/v1/users/' 12 private static BASE_USERS_URL = API_URL + '/api/v1/users/'
13 private bytesPipe = new BytesPipe()
11 14
12 constructor ( 15 constructor (
13 private authHttp: AuthHttp, 16 private authHttp: AuthHttp,
@@ -21,10 +24,30 @@ export class UserService {
21 } 24 }
22 25
23 getDataSource () { 26 getDataSource () {
24 return new RestDataSource(this.authHttp, UserService.BASE_USERS_URL) 27 return new RestDataSource(this.authHttp, UserService.BASE_USERS_URL, this.formatDataSource.bind(this))
25 } 28 }
26 29
27 removeUser (user: User) { 30 removeUser (user: User) {
28 return this.authHttp.delete(UserService.BASE_USERS_URL + user.id) 31 return this.authHttp.delete(UserService.BASE_USERS_URL + user.id)
29 } 32 }
33
34 private formatDataSource (users: User[]) {
35 const newUsers = []
36
37 users.forEach(user => {
38 let videoQuota
39 if (user.videoQuota === -1) {
40 videoQuota = 'Unlimited'
41 } else {
42 videoQuota = this.bytesPipe.transform(user.videoQuota)
43 }
44
45 const newUser = Object.assign(user, {
46 videoQuota
47 })
48 newUsers.push(newUser)
49 })
50
51 return newUsers
52 }
30} 53}
diff --git a/client/src/app/+admin/users/user-add/user-add.component.html b/client/src/app/+admin/users/user-add/user-add.component.html
index 9b487aa75..f84d72c7c 100644
--- a/client/src/app/+admin/users/user-add/user-add.component.html
+++ b/client/src/app/+admin/users/user-add/user-add.component.html
@@ -9,7 +9,7 @@
9 <div class="form-group"> 9 <div class="form-group">
10 <label for="username">Username</label> 10 <label for="username">Username</label>
11 <input 11 <input
12 type="text" class="form-control" id="username" placeholder="Username" 12 type="text" class="form-control" id="username" placeholder="john"
13 formControlName="username" 13 formControlName="username"
14 > 14 >
15 <div *ngIf="formErrors.username" class="alert alert-danger"> 15 <div *ngIf="formErrors.username" class="alert alert-danger">
@@ -20,7 +20,7 @@
20 <div class="form-group"> 20 <div class="form-group">
21 <label for="email">Email</label> 21 <label for="email">Email</label>
22 <input 22 <input
23 type="text" class="form-control" id="email" placeholder="Email" 23 type="text" class="form-control" id="email" placeholder="mail@example.com"
24 formControlName="email" 24 formControlName="email"
25 > 25 >
26 <div *ngIf="formErrors.email" class="alert alert-danger"> 26 <div *ngIf="formErrors.email" class="alert alert-danger">
@@ -31,7 +31,7 @@
31 <div class="form-group"> 31 <div class="form-group">
32 <label for="password">Password</label> 32 <label for="password">Password</label>
33 <input 33 <input
34 type="password" class="form-control" id="password" placeholder="Password" 34 type="password" class="form-control" id="password"
35 formControlName="password" 35 formControlName="password"
36 > 36 >
37 <div *ngIf="formErrors.password" class="alert alert-danger"> 37 <div *ngIf="formErrors.password" class="alert alert-danger">
@@ -39,6 +39,19 @@
39 </div> 39 </div>
40 </div> 40 </div>
41 41
42 <div class="form-group">
43 <label for="videoQuota">Video quota</label>
44 <select class="form-control" id="videoQuota" formControlName="videoQuota">
45 <option value="-1">Unlimited</option>
46 <option value="100000000">100MB</option>
47 <option value="500000000">500MB</option>
48 <option value="1000000000">1GB</option>
49 <option value="5000000000">5GB</option>
50 <option value="20000000000">20GB</option>
51 <option value="50000000000">50GB</option>
52 </select>
53 </div>
54
42 <input type="submit" value="Add user" class="btn btn-default" [disabled]="!form.valid"> 55 <input type="submit" value="Add user" class="btn btn-default" [disabled]="!form.valid">
43 </form> 56 </form>
44 </div> 57 </div>
diff --git a/client/src/app/+admin/users/user-add/user-add.component.ts b/client/src/app/+admin/users/user-add/user-add.component.ts
index 0dd99eccd..91377a933 100644
--- a/client/src/app/+admin/users/user-add/user-add.component.ts
+++ b/client/src/app/+admin/users/user-add/user-add.component.ts
@@ -9,7 +9,8 @@ import {
9 FormReactive, 9 FormReactive,
10 USER_USERNAME, 10 USER_USERNAME,
11 USER_EMAIL, 11 USER_EMAIL,
12 USER_PASSWORD 12 USER_PASSWORD,
13 USER_VIDEO_QUOTA
13} from '../../../shared' 14} from '../../../shared'
14import { UserCreate } from '../../../../../../shared' 15import { UserCreate } from '../../../../../../shared'
15 16
@@ -24,12 +25,14 @@ export class UserAddComponent extends FormReactive implements OnInit {
24 formErrors = { 25 formErrors = {
25 'username': '', 26 'username': '',
26 'email': '', 27 'email': '',
27 'password': '' 28 'password': '',
29 'videoQuota': ''
28 } 30 }
29 validationMessages = { 31 validationMessages = {
30 'username': USER_USERNAME.MESSAGES, 32 'username': USER_USERNAME.MESSAGES,
31 'email': USER_EMAIL.MESSAGES, 33 'email': USER_EMAIL.MESSAGES,
32 'password': USER_PASSWORD.MESSAGES 34 'password': USER_PASSWORD.MESSAGES,
35 'videoQuota': USER_VIDEO_QUOTA.MESSAGES
33 } 36 }
34 37
35 constructor ( 38 constructor (
@@ -45,7 +48,8 @@ export class UserAddComponent extends FormReactive implements OnInit {
45 this.form = this.formBuilder.group({ 48 this.form = this.formBuilder.group({
46 username: [ '', USER_USERNAME.VALIDATORS ], 49 username: [ '', USER_USERNAME.VALIDATORS ],
47 email: [ '', USER_EMAIL.VALIDATORS ], 50 email: [ '', USER_EMAIL.VALIDATORS ],
48 password: [ '', USER_PASSWORD.VALIDATORS ] 51 password: [ '', USER_PASSWORD.VALIDATORS ],
52 videoQuota: [ '-1', USER_VIDEO_QUOTA.VALIDATORS ]
49 }) 53 })
50 54
51 this.form.valueChanges.subscribe(data => this.onValueChanged(data)) 55 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
@@ -60,6 +64,9 @@ export class UserAddComponent extends FormReactive implements OnInit {
60 64
61 const userCreate: UserCreate = this.form.value 65 const userCreate: UserCreate = this.form.value
62 66
67 // A select in HTML is always mapped as a string, we convert it to number
68 userCreate.videoQuota = parseInt(this.form.value['videoQuota'], 10)
69
63 this.userService.addUser(userCreate).subscribe( 70 this.userService.addUser(userCreate).subscribe(
64 () => { 71 () => {
65 this.notificationsService.success('Success', `User ${userCreate.username} created.`) 72 this.notificationsService.success('Success', `User ${userCreate.username} created.`)
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 12826741c..dbb85cedd 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
@@ -30,7 +30,7 @@ export class UserListComponent {
30 }, 30 },
31 pager: { 31 pager: {
32 display: true, 32 display: true,
33 perPage: 10 33 perPage: 1
34 }, 34 },
35 columns: { 35 columns: {
36 id: { 36 id: {
@@ -43,6 +43,9 @@ export class UserListComponent {
43 email: { 43 email: {
44 title: 'Email' 44 title: 'Email'
45 }, 45 },
46 videoQuota: {
47 title: 'Video quota'
48 },
46 role: { 49 role: {
47 title: 'Role', 50 title: 'Role',
48 sort: false 51 sort: false
diff --git a/client/src/app/shared/forms/form-validators/user.ts b/client/src/app/shared/forms/form-validators/user.ts
index fd316583e..087a99760 100644
--- a/client/src/app/shared/forms/form-validators/user.ts
+++ b/client/src/app/shared/forms/form-validators/user.ts
@@ -22,3 +22,10 @@ export const USER_PASSWORD = {
22 'minlength': 'Password must be at least 6 characters long.' 22 'minlength': 'Password must be at least 6 characters long.'
23 } 23 }
24} 24}
25export const USER_VIDEO_QUOTA = {
26 VALIDATORS: [ Validators.required, Validators.min(-1) ],
27 MESSAGES: {
28 'required': 'Video quota is required.',
29 'min': 'Quota must be greater than -1.'
30 }
31} \ No newline at end of file
diff --git a/client/src/app/shared/rest/rest-data-source.ts b/client/src/app/shared/rest/rest-data-source.ts
index 7956637e0..5c205d280 100644
--- a/client/src/app/shared/rest/rest-data-source.ts
+++ b/client/src/app/shared/rest/rest-data-source.ts
@@ -3,14 +3,31 @@ import { Http, RequestOptionsArgs, URLSearchParams, Response } from '@angular/ht
3import { ServerDataSource } from 'ng2-smart-table' 3import { ServerDataSource } from 'ng2-smart-table'
4 4
5export class RestDataSource extends ServerDataSource { 5export class RestDataSource extends ServerDataSource {
6 constructor (http: Http, endpoint: string) { 6 private updateResponse: (input: any[]) => any[]
7
8 constructor (http: Http, endpoint: string, updateResponse?: (input: any[]) => any[]) {
7 const options = { 9 const options = {
8 endPoint: endpoint, 10 endPoint: endpoint,
9 sortFieldKey: 'sort', 11 sortFieldKey: 'sort',
10 dataKey: 'data' 12 dataKey: 'data'
11 } 13 }
12
13 super(http, options) 14 super(http, options)
15
16 if (updateResponse) {
17 this.updateResponse = updateResponse
18 }
19 }
20
21 protected extractDataFromResponse (res: Response) {
22 const json = res.json()
23 if (!json) return []
24 let data = json.data
25
26 if (this.updateResponse !== undefined) {
27 data = this.updateResponse(data)
28 }
29
30 return data
14 } 31 }
15 32
16 protected extractTotalFromResponse (res: Response) { 33 protected extractTotalFromResponse (res: Response) {
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts
index 1c2b481e3..bf12876c7 100644
--- a/client/src/app/shared/users/user.model.ts
+++ b/client/src/app/shared/users/user.model.ts
@@ -6,6 +6,7 @@ export class User implements UserServerModel {
6 email: string 6 email: string
7 role: UserRole 7 role: UserRole
8 displayNSFW: boolean 8 displayNSFW: boolean
9 videoQuota: number
9 createdAt: Date 10 createdAt: Date
10 11
11 constructor (hash: { 12 constructor (hash: {
@@ -13,6 +14,7 @@ export class User implements UserServerModel {
13 username: string, 14 username: string,
14 email: string, 15 email: string,
15 role: UserRole, 16 role: UserRole,
17 videoQuota?: number,
16 displayNSFW?: boolean, 18 displayNSFW?: boolean,
17 createdAt?: Date 19 createdAt?: Date
18 }) { 20 }) {
@@ -20,9 +22,16 @@ export class User implements UserServerModel {
20 this.username = hash.username 22 this.username = hash.username
21 this.email = hash.email 23 this.email = hash.email
22 this.role = hash.role 24 this.role = hash.role
23 this.displayNSFW = hash.displayNSFW
24 25
25 if (hash.createdAt) { 26 if (hash.videoQuota !== undefined) {
27 this.videoQuota = hash.videoQuota
28 }
29
30 if (hash.displayNSFW !== undefined) {
31 this.displayNSFW = hash.displayNSFW
32 }
33
34 if (hash.createdAt !== undefined) {
26 this.createdAt = hash.createdAt 35 this.createdAt = hash.createdAt
27 } 36 }
28 } 37 }
diff --git a/client/tslint.json b/client/tslint.json
index cfad2a5d9..b1e211ee9 100644
--- a/client/tslint.json
+++ b/client/tslint.json
@@ -4,7 +4,6 @@
4 "rules": { 4 "rules": {
5 "no-inferrable-types": true, 5 "no-inferrable-types": true,
6 "eofline": true, 6 "eofline": true,
7 "indent": ["spaces"],
8 "max-line-length": [true, 140], 7 "max-line-length": [true, 140],
9 "no-floating-promises": false, 8 "no-floating-promises": false,
10 "no-unused-variable": false, // Bug, wait TypeScript 2.4 9 "no-unused-variable": false, // Bug, wait TypeScript 2.4
diff --git a/client/yarn.lock b/client/yarn.lock
index 0fc5ec418..9478e23b2 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -6740,9 +6740,9 @@ tslint-loader@^3.3.0:
6740 rimraf "^2.4.4" 6740 rimraf "^2.4.4"
6741 semver "^5.3.0" 6741 semver "^5.3.0"
6742 6742
6743tslint@^5.4.3: 6743tslint@^5.7.0:
6744 version "5.6.0" 6744 version "5.7.0"
6745 resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.6.0.tgz#088aa6c6026623338650b2900828ab3edf59f6cf" 6745 resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.7.0.tgz#c25e0d0c92fa1201c2bc30e844e08e682b4f3552"
6746 dependencies: 6746 dependencies:
6747 babel-code-frame "^6.22.0" 6747 babel-code-frame "^6.22.0"
6748 colors "^1.1.2" 6748 colors "^1.1.2"
@@ -6753,7 +6753,7 @@ tslint@^5.4.3:
6753 resolve "^1.3.2" 6753 resolve "^1.3.2"
6754 semver "^5.3.0" 6754 semver "^5.3.0"
6755 tslib "^1.7.1" 6755 tslib "^1.7.1"
6756 tsutils "^2.7.1" 6756 tsutils "^2.8.1"
6757 6757
6758tsml@1.0.1: 6758tsml@1.0.1:
6759 version "1.0.1" 6759 version "1.0.1"
@@ -6763,9 +6763,9 @@ tsutils@^1.4.0:
6763 version "1.9.1" 6763 version "1.9.1"
6764 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.9.1.tgz#b9f9ab44e55af9681831d5f28d0aeeaf5c750cb0" 6764 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.9.1.tgz#b9f9ab44e55af9681831d5f28d0aeeaf5c750cb0"
6765 6765
6766tsutils@^2.7.1: 6766tsutils@^2.8.1:
6767 version "2.8.1" 6767 version "2.8.2"
6768 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.8.1.tgz#3771404e7ca9f0bedf5d919a47a4b1890a68efff" 6768 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.8.2.tgz#2c1486ba431260845b0ac6f902afd9d708a8ea6a"
6769 dependencies: 6769 dependencies:
6770 tslib "^1.7.1" 6770 tslib "^1.7.1"
6771 6771
@@ -6806,9 +6806,9 @@ typedarray@^0.0.6:
6806 version "0.0.6" 6806 version "0.0.6"
6807 resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 6807 resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
6808 6808
6809typescript@~2.4.0: 6809typescript@^2.5.2:
6810 version "2.4.2" 6810 version "2.5.2"
6811 resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.2.tgz#f8395f85d459276067c988aa41837a8f82870844" 6811 resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.2.tgz#038a95f7d9bbb420b1bf35ba31d4c5c1dd3ffe34"
6812 6812
6813uglify-js@3.0.x, uglify-js@^3.0.6: 6813uglify-js@3.0.x, uglify-js@^3.0.6:
6814 version "3.0.28" 6814 version "3.0.28"