diff options
Diffstat (limited to 'client/src')
7 files changed, 92 insertions, 13 deletions
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' | |||
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 { BytesPipe } from 'angular-pipes/src/math/bytes.pipe' | ||
6 | |||
5 | import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared' | 7 | import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared' |
6 | import { UserCreate } from '../../../../../../shared' | 8 | import { UserCreate } from '../../../../../../shared' |
7 | 9 | ||
8 | @Injectable() | 10 | @Injectable() |
9 | export class UserService { | 11 | export 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' |
14 | import { UserCreate } from '../../../../../../shared' | 15 | import { 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 | } |
25 | export 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 | |||
3 | import { ServerDataSource } from 'ng2-smart-table' | 3 | import { ServerDataSource } from 'ng2-smart-table' |
4 | 4 | ||
5 | export class RestDataSource extends ServerDataSource { | 5 | export 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 | } |