aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-06-05 10:58:45 +0200
committerChocobozzz <me@florianbigard.com>2018-06-05 10:58:45 +0200
commitd18d64787b3ea174f7dc2740c8c8c9555625047e (patch)
treee65089e0ca81117c1ada981b9b8a524afa8d70f5 /client/src/app
parent25acef90a85c1584880dec96aa402f896af8364a (diff)
downloadPeerTube-d18d64787b3ea174f7dc2740c8c8c9555625047e.tar.gz
PeerTube-d18d64787b3ea174f7dc2740c8c8c9555625047e.tar.zst
PeerTube-d18d64787b3ea174f7dc2740c8c8c9555625047e.zip
Form validators refractoring
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts78
-rw-r--r--client/src/app/+admin/users/user-edit/user-create.component.ts45
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.ts4
-rw-r--r--client/src/app/+admin/users/user-edit/user-update.component.ts33
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts28
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts35
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.html6
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.ts4
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts29
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts32
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts32
-rw-r--r--client/src/app/login/login.component.ts34
-rw-r--r--client/src/app/reset-password/reset-password.component.ts31
-rw-r--r--client/src/app/shared/forms/form-reactive.ts52
-rw-r--r--client/src/app/shared/forms/form-validators/form-validator.service.ts65
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts1
-rw-r--r--client/src/app/shared/forms/form-validators/login.ts18
-rw-r--r--client/src/app/shared/forms/form-validators/reset-password.ts10
-rw-r--r--client/src/app/shared/shared.module.ts2
-rw-r--r--client/src/app/signup/signup.component.ts32
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts71
-rw-r--r--client/src/app/videos/+video-edit/video-add.component.ts16
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.ts15
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.ts24
-rw-r--r--client/src/app/videos/+video-watch/modal/video-report.component.ts21
25 files changed, 299 insertions, 419 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index 73ff4b7bb..f2a3464cb 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -17,6 +17,7 @@ import {
17import { NotificationsService } from 'angular2-notifications' 17import { NotificationsService } from 'angular2-notifications'
18import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' 18import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
19import { I18n } from '@ngx-translate/i18n-polyfill' 19import { I18n } from '@ngx-translate/i18n-polyfill'
20import { BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
20 21
21@Component({ 22@Component({
22 selector: 'my-edit-custom-config', 23 selector: 'my-edit-custom-config',
@@ -44,38 +45,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
44 { value: 8, label: '8' } 45 { value: 8, label: '8' }
45 ] 46 ]
46 47
47 form: FormGroup
48 formErrors = {
49 instanceName: '',
50 instanceShortDescription: '',
51 instanceDescription: '',
52 instanceTerms: '',
53 instanceDefaultClientRoute: '',
54 instanceDefaultNSFWPolicy: '',
55 servicesTwitterUsername: '',
56 cachePreviewsSize: '',
57 signupLimit: '',
58 adminEmail: '',
59 userVideoQuota: '',
60 transcodingThreads: '',
61 customizationJavascript: '',
62 customizationCSS: ''
63 }
64 validationMessages = {
65 instanceShortDescription: INSTANCE_SHORT_DESCRIPTION.MESSAGES,
66 instanceName: INSTANCE_NAME.MESSAGES,
67 servicesTwitterUsername: SERVICES_TWITTER_USERNAME,
68 cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES,
69 signupLimit: SIGNUP_LIMIT.MESSAGES,
70 adminEmail: ADMIN_EMAIL.MESSAGES,
71 userVideoQuota: USER_VIDEO_QUOTA.MESSAGES
72 }
73
74 private oldCustomJavascript: string 48 private oldCustomJavascript: string
75 private oldCustomCSS: string 49 private oldCustomCSS: string
76 50
77 constructor ( 51 constructor (
78 private formBuilder: FormBuilder, 52 protected formValidatorService: FormValidatorService,
79 private router: Router, 53 private router: Router,
80 private notificationsService: NotificationsService, 54 private notificationsService: NotificationsService,
81 private configService: ConfigService, 55 private configService: ConfigService,
@@ -90,39 +64,35 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
90 return 'transcodingResolution' + resolution 64 return 'transcodingResolution' + resolution
91 } 65 }
92 66
93 buildForm () { 67 ngOnInit () {
94 const formGroupData = { 68 const formGroupData = {
95 instanceName: [ '', INSTANCE_NAME.VALIDATORS ], 69 instanceName: INSTANCE_NAME,
96 instanceShortDescription: [ '', INSTANCE_SHORT_DESCRIPTION.VALIDATORS ], 70 instanceShortDescription: INSTANCE_SHORT_DESCRIPTION,
97 instanceDescription: [ '' ], 71 instanceDescription: null,
98 instanceTerms: [ '' ], 72 instanceTerms: null,
99 instanceDefaultClientRoute: [ '' ], 73 instanceDefaultClientRoute: null,
100 instanceDefaultNSFWPolicy: [ '' ], 74 instanceDefaultNSFWPolicy: null,
101 servicesTwitterUsername: [ '', SERVICES_TWITTER_USERNAME.VALIDATORS ], 75 servicesTwitterUsername: SERVICES_TWITTER_USERNAME,
102 servicesTwitterWhitelisted: [ ], 76 servicesTwitterWhitelisted: null,
103 cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ], 77 cachePreviewsSize: CACHE_PREVIEWS_SIZE,
104 signupEnabled: [ ], 78 signupEnabled: null,
105 signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ], 79 signupLimit: SIGNUP_LIMIT,
106 adminEmail: [ '', ADMIN_EMAIL.VALIDATORS ], 80 adminEmail: ADMIN_EMAIL,
107 userVideoQuota: [ '', USER_VIDEO_QUOTA.VALIDATORS ], 81 userVideoQuota: USER_VIDEO_QUOTA,
108 transcodingThreads: [ '', TRANSCODING_THREADS.VALIDATORS ], 82 transcodingThreads: TRANSCODING_THREADS,
109 transcodingEnabled: [ ], 83 transcodingEnabled: null,
110 customizationJavascript: [ '' ], 84 customizationJavascript: null,
111 customizationCSS: [ '' ] 85 customizationCSS: null
112 } 86 }
113 87
88 const defaultValues: BuildFormDefaultValues = {}
114 for (const resolution of this.resolutions) { 89 for (const resolution of this.resolutions) {
115 const key = this.getResolutionKey(resolution) 90 const key = this.getResolutionKey(resolution)
116 formGroupData[key] = [ false ] 91 defaultValues[key] = 'false'
92 formGroupData[key] = null
117 } 93 }
118 94
119 this.form = this.formBuilder.group(formGroupData) 95 this.buildForm(formGroupData)
120
121 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
122 }
123
124 ngOnInit () {
125 this.buildForm()
126 96
127 this.configService.getCustomConfig() 97 this.configService.getCustomConfig()
128 .subscribe( 98 .subscribe(
diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts
index 8478a7692..e5f0903b6 100644
--- a/client/src/app/+admin/users/user-edit/user-create.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-create.component.ts
@@ -1,5 +1,4 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { Router } from '@angular/router' 2import { Router } from '@angular/router'
4import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
5import { UserService } from '../shared' 4import { UserService } from '../shared'
@@ -8,6 +7,7 @@ import { ServerService } from '../../../core'
8import { UserCreate, UserRole } from '../../../../../../shared' 7import { UserCreate, UserRole } from '../../../../../../shared'
9import { UserEdit } from './user-edit' 8import { UserEdit } from './user-edit'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
11 11
12@Component({ 12@Component({
13 selector: 'my-user-create', 13 selector: 'my-user-create',
@@ -17,25 +17,9 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
17export class UserCreateComponent extends UserEdit implements OnInit { 17export class UserCreateComponent extends UserEdit implements OnInit {
18 error: string 18 error: string
19 19
20 form: FormGroup
21 formErrors = {
22 'username': '',
23 'email': '',
24 'password': '',
25 'role': '',
26 'videoQuota': ''
27 }
28 validationMessages = {
29 'username': USER_USERNAME.MESSAGES,
30 'email': USER_EMAIL.MESSAGES,
31 'password': USER_PASSWORD.MESSAGES,
32 'role': USER_ROLE.MESSAGES,
33 'videoQuota': USER_VIDEO_QUOTA.MESSAGES
34 }
35
36 constructor ( 20 constructor (
37 protected serverService: ServerService, 21 protected serverService: ServerService,
38 private formBuilder: FormBuilder, 22 protected formValidatorService: FormValidatorService,
39 private router: Router, 23 private router: Router,
40 private notificationsService: NotificationsService, 24 private notificationsService: NotificationsService,
41 private userService: UserService, 25 private userService: UserService,
@@ -44,20 +28,19 @@ export class UserCreateComponent extends UserEdit implements OnInit {
44 super() 28 super()
45 } 29 }
46 30
47 buildForm () {
48 this.form = this.formBuilder.group({
49 username: [ '', USER_USERNAME.VALIDATORS ],
50 email: [ '', USER_EMAIL.VALIDATORS ],
51 password: [ '', USER_PASSWORD.VALIDATORS ],
52 role: [ UserRole.USER, USER_ROLE.VALIDATORS ],
53 videoQuota: [ '-1', USER_VIDEO_QUOTA.VALIDATORS ]
54 })
55
56 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
57 }
58
59 ngOnInit () { 31 ngOnInit () {
60 this.buildForm() 32 const defaultValues = {
33 role: UserRole.USER.toString(),
34 videoQuota: '-1'
35 }
36
37 this.buildForm({
38 username: USER_USERNAME,
39 email: USER_EMAIL,
40 password: USER_PASSWORD,
41 role: USER_ROLE,
42 videoQuota: USER_VIDEO_QUOTA
43 }, defaultValues)
61 } 44 }
62 45
63 formValidated () { 46 formValidated () {
diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts
index 2b47c685c..ea8c733c3 100644
--- a/client/src/app/+admin/users/user-edit/user-edit.ts
+++ b/client/src/app/+admin/users/user-edit/user-edit.ts
@@ -12,9 +12,9 @@ export abstract class UserEdit extends FormReactive {
12 { value: 5 * 1024 * 1024 * 1024, label: '5GB' }, 12 { value: 5 * 1024 * 1024 * 1024, label: '5GB' },
13 { value: 20 * 1024 * 1024 * 1024, label: '20GB' }, 13 { value: 20 * 1024 * 1024 * 1024, label: '20GB' },
14 { value: 50 * 1024 * 1024 * 1024, label: '50GB' } 14 { value: 50 * 1024 * 1024 * 1024, label: '50GB' }
15 ] 15 ].map(q => ({ value: q.value.toString(), label: q.label })) // Used by a HTML select, so convert key into strings
16 16
17 roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key, label: USER_ROLE_LABELS[key] })) 17 roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] }))
18 18
19 protected abstract serverService: ServerService 19 protected abstract serverService: ServerService
20 abstract isCreation (): boolean 20 abstract isCreation (): boolean
diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts
index 5689aab2f..f8073c928 100644
--- a/client/src/app/+admin/users/user-edit/user-update.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-update.component.ts
@@ -1,5 +1,4 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
4import { Subscription } from 'rxjs' 3import { Subscription } from 'rxjs'
5import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
@@ -9,6 +8,7 @@ import { ServerService } from '../../../core'
9import { UserEdit } from './user-edit' 8import { UserEdit } from './user-edit'
10import { UserUpdate } from '../../../../../../shared' 9import { UserUpdate } from '../../../../../../shared'
11import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12 12
13@Component({ 13@Component({
14 selector: 'my-user-update', 14 selector: 'my-user-update',
@@ -20,44 +20,27 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
20 userId: number 20 userId: number
21 username: string 21 username: string
22 22
23 form: FormGroup
24 formErrors = {
25 'email': '',
26 'role': '',
27 'videoQuota': ''
28 }
29 validationMessages = {
30 'email': USER_EMAIL.MESSAGES,
31 'role': USER_ROLE.MESSAGES,
32 'videoQuota': USER_VIDEO_QUOTA.MESSAGES
33 }
34
35 private paramsSub: Subscription 23 private paramsSub: Subscription
36 24
37 constructor ( 25 constructor (
26 protected formValidatorService: FormValidatorService,
38 protected serverService: ServerService, 27 protected serverService: ServerService,
39 private route: ActivatedRoute, 28 private route: ActivatedRoute,
40 private router: Router, 29 private router: Router,
41 private notificationsService: NotificationsService, 30 private notificationsService: NotificationsService,
42 private formBuilder: FormBuilder,
43 private userService: UserService, 31 private userService: UserService,
44 private i18n: I18n 32 private i18n: I18n
45 ) { 33 ) {
46 super() 34 super()
47 } 35 }
48 36
49 buildForm () {
50 this.form = this.formBuilder.group({
51 email: [ '', USER_EMAIL.VALIDATORS ],
52 role: [ '', USER_ROLE.VALIDATORS ],
53 videoQuota: [ '-1', USER_VIDEO_QUOTA.VALIDATORS ]
54 })
55
56 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
57 }
58
59 ngOnInit () { 37 ngOnInit () {
60 this.buildForm() 38 const defaultValues = { videoQuota: '-1' }
39 this.buildForm({
40 email: USER_EMAIL,
41 role: USER_ROLE,
42 videoQuota: USER_VIDEO_QUOTA
43 }, defaultValues)
61 44
62 this.paramsSub = this.route.params.subscribe(routeParams => { 45 this.paramsSub = this.route.params.subscribe(routeParams => {
63 const userId = routeParams['id'] 46 const userId = routeParams['id']
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
index 1a88aa82e..56e644f39 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
@@ -1,8 +1,8 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
4import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' 3import { FormReactive, USER_PASSWORD, UserService } from '../../../shared'
5import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
6 6
7@Component({ 7@Component({
8 selector: 'my-account-change-password', 8 selector: 'my-account-change-password',
@@ -12,18 +12,8 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
12export class MyAccountChangePasswordComponent extends FormReactive implements OnInit { 12export class MyAccountChangePasswordComponent extends FormReactive implements OnInit {
13 error: string = null 13 error: string = null
14 14
15 form: FormGroup
16 formErrors = {
17 'new-password': '',
18 'new-confirmed-password': ''
19 }
20 validationMessages = {
21 'new-password': USER_PASSWORD.MESSAGES,
22 'new-confirmed-password': USER_PASSWORD.MESSAGES
23 }
24
25 constructor ( 15 constructor (
26 private formBuilder: FormBuilder, 16 protected formValidatorService: FormValidatorService,
27 private notificationsService: NotificationsService, 17 private notificationsService: NotificationsService,
28 private userService: UserService, 18 private userService: UserService,
29 private i18n: I18n 19 private i18n: I18n
@@ -31,17 +21,11 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
31 super() 21 super()
32 } 22 }
33 23
34 buildForm () {
35 this.form = this.formBuilder.group({
36 'new-password': [ '', USER_PASSWORD.VALIDATORS ],
37 'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ]
38 })
39
40 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
41 }
42
43 ngOnInit () { 24 ngOnInit () {
44 this.buildForm() 25 this.buildForm({
26 'new-password': USER_PASSWORD,
27 'new-confirmed-password': USER_PASSWORD
28 })
45 } 29 }
46 30
47 changePassword () { 31 changePassword () {
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
index 35843ecd9..1fe337da0 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
@@ -1,9 +1,10 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
4import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' 3import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared'
5import { User } from '@app/shared' 4import { User } from '@app/shared'
6import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { Subject } from 'rxjs/Subject'
7 8
8@Component({ 9@Component({
9 selector: 'my-account-profile', 10 selector: 'my-account-profile',
@@ -12,21 +13,12 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
12}) 13})
13export class MyAccountProfileComponent extends FormReactive implements OnInit { 14export class MyAccountProfileComponent extends FormReactive implements OnInit {
14 @Input() user: User = null 15 @Input() user: User = null
16 @Input() userInformationLoaded: Subject<any>
15 17
16 error: string = null 18 error: string = null
17 19
18 form: FormGroup
19 formErrors = {
20 'display-name': '',
21 'description': ''
22 }
23 validationMessages = {
24 'display-name': USER_DISPLAY_NAME.MESSAGES,
25 'description': USER_DESCRIPTION.MESSAGES
26 }
27
28 constructor ( 20 constructor (
29 private formBuilder: FormBuilder, 21 protected formValidatorService: FormValidatorService,
30 private notificationsService: NotificationsService, 22 private notificationsService: NotificationsService,
31 private userService: UserService, 23 private userService: UserService,
32 private i18n: I18n 24 private i18n: I18n
@@ -34,17 +26,18 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
34 super() 26 super()
35 } 27 }
36 28
37 buildForm () { 29 ngOnInit () {
38 this.form = this.formBuilder.group({ 30 this.buildForm({
39 'display-name': [ this.user.account.displayName, USER_DISPLAY_NAME.VALIDATORS ], 31 'display-name': USER_DISPLAY_NAME,
40 'description': [ this.user.account.description, USER_DESCRIPTION.VALIDATORS ] 32 description: USER_DESCRIPTION
41 }) 33 })
42 34
43 this.form.valueChanges.subscribe(data => this.onValueChanged(data)) 35 this.userInformationLoaded.subscribe(() => {
44 } 36 this.form.patchValue({
45 37 'display-name': this.user.account.displayName,
46 ngOnInit () { 38 description: this.user.account.description
47 this.buildForm() 39 })
40 })
48 } 41 }
49 42
50 updateMyProfile () { 43 updateMyProfile () {
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
index 056c2a7d7..f5d593f19 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
@@ -3,7 +3,7 @@
3 3
4 <div class="user-info"> 4 <div class="user-info">
5 <div class="user-info-names"> 5 <div class="user-info-names">
6 <div class="user-info-display-name">{{ user.account.displayName }}</div> 6 <div class="user-info-display-name">{{ user.account?.displayName }}</div>
7 <div class="user-info-username">{{ user.username }}</div> 7 <div class="user-info-username">{{ user.username }}</div>
8 </div> 8 </div>
9 <div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div> 9 <div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div>
@@ -22,11 +22,11 @@
22 22
23<ng-template [ngIf]="user && user.account"> 23<ng-template [ngIf]="user && user.account">
24 <div i18n class="account-title">Profile</div> 24 <div i18n class="account-title">Profile</div>
25 <my-account-profile [user]="user"></my-account-profile> 25 <my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
26</ng-template> 26</ng-template>
27 27
28<div i18n class="account-title">Password</div> 28<div i18n class="account-title">Password</div>
29<my-account-change-password></my-account-change-password> 29<my-account-change-password></my-account-change-password>
30 30
31<div i18n class="account-title">Video settings</div> 31<div i18n class="account-title">Video settings</div>
32<my-account-video-settings [user]="user"></my-account-video-settings> 32<my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings>
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
index 44eddaa7c..15f977e58 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
@@ -27,6 +27,10 @@ export class MyAccountSettingsComponent implements OnInit {
27 private i18n: I18n 27 private i18n: I18n
28 ) {} 28 ) {}
29 29
30 get userInformationLoaded () {
31 return this.authService.userInformationLoaded
32 }
33
30 ngOnInit () { 34 ngOnInit () {
31 this.user = this.authService.getUser() 35 this.user = this.authService.getUser()
32 36
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
index 4588f73db..85b3a48cc 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
@@ -1,10 +1,11 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
4import { UserUpdateMe } from '../../../../../../shared' 3import { UserUpdateMe } from '../../../../../../shared'
5import { AuthService } from '../../../core' 4import { AuthService } from '../../../core'
6import { FormReactive, User, UserService } from '../../../shared' 5import { FormReactive, User, UserService } from '../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
7import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8import { Subject } from 'rxjs/Subject'
8 9
9@Component({ 10@Component({
10 selector: 'my-account-video-settings', 11 selector: 'my-account-video-settings',
@@ -13,14 +14,11 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
13}) 14})
14export class MyAccountVideoSettingsComponent extends FormReactive implements OnInit { 15export class MyAccountVideoSettingsComponent extends FormReactive implements OnInit {
15 @Input() user: User = null 16 @Input() user: User = null
16 17 @Input() userInformationLoaded: Subject<any>
17 form: FormGroup
18 formErrors = {}
19 validationMessages = {}
20 18
21 constructor ( 19 constructor (
20 protected formValidatorService: FormValidatorService,
22 private authService: AuthService, 21 private authService: AuthService,
23 private formBuilder: FormBuilder,
24 private notificationsService: NotificationsService, 22 private notificationsService: NotificationsService,
25 private userService: UserService, 23 private userService: UserService,
26 private i18n: I18n 24 private i18n: I18n
@@ -28,17 +26,18 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
28 super() 26 super()
29 } 27 }
30 28
31 buildForm () { 29 ngOnInit () {
32 this.form = this.formBuilder.group({ 30 this.buildForm({
33 nsfwPolicy: [ this.user.nsfwPolicy ], 31 nsfwPolicy: null,
34 autoPlayVideo: [ this.user.autoPlayVideo ] 32 autoPlayVideo: null
35 }) 33 })
36 34
37 this.form.valueChanges.subscribe(data => this.onValueChanged(data)) 35 this.userInformationLoaded.subscribe(() => {
38 } 36 this.form.patchValue({
39 37 nsfwPolicy: this.user.nsfwPolicy,
40 ngOnInit () { 38 autoPlayVideo: this.user.autoPlayVideo === true ? 'true' : 'false'
41 this.buildForm() 39 })
40 })
42 } 41 }
43 42
44 updateDetails () { 43 updateDetails () {
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
index a4073728b..e38eaae9c 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
@@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { FormBuilder, FormGroup } from '@angular/forms'
6import { VideoChannelCreate } from '../../../../../shared/models/videos' 5import { VideoChannelCreate } from '../../../../../shared/models/videos'
7import { 6import {
8 VIDEO_CHANNEL_DESCRIPTION, 7 VIDEO_CHANNEL_DESCRIPTION,
@@ -12,6 +11,7 @@ import {
12import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 11import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
13import { AuthService } from '@app/core' 12import { AuthService } from '@app/core'
14import { I18n } from '@ngx-translate/i18n-polyfill' 13import { I18n } from '@ngx-translate/i18n-polyfill'
14import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
15 15
16@Component({ 16@Component({
17 selector: 'my-account-video-channel-create', 17 selector: 'my-account-video-channel-create',
@@ -21,41 +21,23 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
21export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit { 21export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit {
22 error: string 22 error: string
23 23
24 form: FormGroup
25 formErrors = {
26 'display-name': '',
27 'description': '',
28 'support': ''
29 }
30 validationMessages = {
31 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES,
32 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES,
33 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES
34 }
35
36 constructor ( 24 constructor (
25 protected formValidatorService: FormValidatorService,
37 private authService: AuthService, 26 private authService: AuthService,
38 private notificationsService: NotificationsService, 27 private notificationsService: NotificationsService,
39 private router: Router, 28 private router: Router,
40 private formBuilder: FormBuilder,
41 private videoChannelService: VideoChannelService, 29 private videoChannelService: VideoChannelService,
42 private i18n: I18n 30 private i18n: I18n
43 ) { 31 ) {
44 super() 32 super()
45 } 33 }
46 34
47 buildForm () {
48 this.form = this.formBuilder.group({
49 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ],
50 description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ],
51 support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ]
52 })
53
54 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
55 }
56
57 ngOnInit () { 35 ngOnInit () {
58 this.buildForm() 36 this.buildForm({
37 'display-name': VIDEO_CHANNEL_DISPLAY_NAME,
38 description: VIDEO_CHANNEL_DESCRIPTION,
39 support: VIDEO_CHANNEL_SUPPORT
40 })
59 } 41 }
60 42
61 formValidated () { 43 formValidated () {
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index db38c7da9..eda03374a 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { FormBuilder, FormGroup } from '@angular/forms'
6import { VideoChannelUpdate } from '../../../../../shared/models/videos' 5import { VideoChannelUpdate } from '../../../../../shared/models/videos'
7import { 6import {
8 VIDEO_CHANNEL_DESCRIPTION, 7 VIDEO_CHANNEL_DESCRIPTION,
@@ -14,6 +13,7 @@ import { Subscription } from 'rxjs'
14import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 13import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
15import { AuthService } from '@app/core' 14import { AuthService } from '@app/core'
16import { I18n } from '@ngx-translate/i18n-polyfill' 15import { I18n } from '@ngx-translate/i18n-polyfill'
16import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
17 17
18@Component({ 18@Component({
19 selector: 'my-account-video-channel-update', 19 selector: 'my-account-video-channel-update',
@@ -23,45 +23,27 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
23export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy { 23export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy {
24 error: string 24 error: string
25 25
26 form: FormGroup
27 formErrors = {
28 'display-name': '',
29 'description': '',
30 'support': ''
31 }
32 validationMessages = {
33 'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES,
34 'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES,
35 'support': VIDEO_CHANNEL_SUPPORT.MESSAGES
36 }
37
38 private videoChannelToUpdate: VideoChannel 26 private videoChannelToUpdate: VideoChannel
39 private paramsSub: Subscription 27 private paramsSub: Subscription
40 28
41 constructor ( 29 constructor (
30 protected formValidatorService: FormValidatorService,
42 private authService: AuthService, 31 private authService: AuthService,
43 private notificationsService: NotificationsService, 32 private notificationsService: NotificationsService,
44 private router: Router, 33 private router: Router,
45 private route: ActivatedRoute, 34 private route: ActivatedRoute,
46 private formBuilder: FormBuilder,
47 private videoChannelService: VideoChannelService, 35 private videoChannelService: VideoChannelService,
48 private i18n: I18n 36 private i18n: I18n
49 ) { 37 ) {
50 super() 38 super()
51 } 39 }
52 40
53 buildForm () {
54 this.form = this.formBuilder.group({
55 'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ],
56 description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ],
57 support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ]
58 })
59
60 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
61 }
62
63 ngOnInit () { 41 ngOnInit () {
64 this.buildForm() 42 this.buildForm({
43 'display-name': VIDEO_CHANNEL_DISPLAY_NAME,
44 description: VIDEO_CHANNEL_DESCRIPTION,
45 support: VIDEO_CHANNEL_SUPPORT
46 })
65 47
66 this.paramsSub = this.route.params.subscribe(routeParams => { 48 this.paramsSub = this.route.params.subscribe(routeParams => {
67 const videoChannelId = routeParams['videoChannelId'] 49 const videoChannelId = routeParams['videoChannelId']
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
index a14cb2eb7..f7aad06e8 100644
--- a/client/src/app/login/login.component.ts
+++ b/client/src/app/login/login.component.ts
@@ -1,6 +1,4 @@
1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
2import { FormBuilder, FormGroup, Validators } from '@angular/forms'
3import { Router } from '@angular/router'
4import { RedirectService, ServerService } from '@app/core' 2import { RedirectService, ServerService } from '@app/core'
5import { UserService } from '@app/shared' 3import { UserService } from '@app/shared'
6import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
@@ -8,6 +6,8 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
8import { AuthService } from '../core' 6import { AuthService } from '../core'
9import { FormReactive } from '../shared' 7import { FormReactive } from '../shared'
10import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
10import { LOGIN_PASSWORD, LOGIN_USERNAME } from '@app/shared/forms/form-validators/login'
11 11
12@Component({ 12@Component({
13 selector: 'my-login', 13 selector: 'my-login',
@@ -20,29 +20,15 @@ export class LoginComponent extends FormReactive implements OnInit {
20 @ViewChild('forgotPasswordEmailInput') forgotPasswordEmailInput: ElementRef 20 @ViewChild('forgotPasswordEmailInput') forgotPasswordEmailInput: ElementRef
21 21
22 error: string = null 22 error: string = null
23
24 form: FormGroup
25 formErrors = {
26 'username': '',
27 'password': ''
28 }
29 validationMessages = {
30 'username': {
31 'required': 'Username is required.'
32 },
33 'password': {
34 'required': 'Password is required.'
35 }
36 }
37 forgotPasswordEmail = '' 23 forgotPasswordEmail = ''
38 24
39 constructor ( 25 constructor (
26 protected formValidatorService: FormValidatorService,
40 private authService: AuthService, 27 private authService: AuthService,
41 private userService: UserService, 28 private userService: UserService,
42 private serverService: ServerService, 29 private serverService: ServerService,
43 private redirectService: RedirectService, 30 private redirectService: RedirectService,
44 private notificationsService: NotificationsService, 31 private notificationsService: NotificationsService,
45 private formBuilder: FormBuilder,
46 private i18n: I18n 32 private i18n: I18n
47 ) { 33 ) {
48 super() 34 super()
@@ -52,17 +38,11 @@ export class LoginComponent extends FormReactive implements OnInit {
52 return this.serverService.getConfig().signup.allowed === true 38 return this.serverService.getConfig().signup.allowed === true
53 } 39 }
54 40
55 buildForm () {
56 this.form = this.formBuilder.group({
57 username: [ '', Validators.required ],
58 password: [ '', Validators.required ]
59 })
60
61 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
62 }
63
64 ngOnInit () { 41 ngOnInit () {
65 this.buildForm() 42 this.buildForm({
43 username: LOGIN_USERNAME,
44 password: LOGIN_PASSWORD
45 })
66 } 46 }
67 47
68 login () { 48 login () {
diff --git a/client/src/app/reset-password/reset-password.component.ts b/client/src/app/reset-password/reset-password.component.ts
index c8bd368c1..58e086f45 100644
--- a/client/src/app/reset-password/reset-password.component.ts
+++ b/client/src/app/reset-password/reset-password.component.ts
@@ -1,11 +1,12 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup, Validators } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
4import { USER_PASSWORD, UserService } from '@app/shared' 3import { USER_PASSWORD, UserService } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../core' 5import { AuthService } from '../core'
7import { FormReactive } from '../shared' 6import { FormReactive } from '../shared'
8import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { RESET_PASSWORD_CONFIRM } from '@app/shared/forms/form-validators/reset-password'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
9 10
10@Component({ 11@Component({
11 selector: 'my-login', 12 selector: 'my-login',
@@ -14,26 +15,14 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
14}) 15})
15 16
16export class ResetPasswordComponent extends FormReactive implements OnInit { 17export class ResetPasswordComponent extends FormReactive implements OnInit {
17 form: FormGroup
18 formErrors = {
19 'password': '',
20 'password-confirm': ''
21 }
22 validationMessages = {
23 'password': USER_PASSWORD.MESSAGES,
24 'password-confirm': {
25 'required': 'Confirmation of the password is required.'
26 }
27 }
28
29 private userId: number 18 private userId: number
30 private verificationString: string 19 private verificationString: string
31 20
32 constructor ( 21 constructor (
22 protected formValidatorService: FormValidatorService,
33 private authService: AuthService, 23 private authService: AuthService,
34 private userService: UserService, 24 private userService: UserService,
35 private notificationsService: NotificationsService, 25 private notificationsService: NotificationsService,
36 private formBuilder: FormBuilder,
37 private router: Router, 26 private router: Router,
38 private route: ActivatedRoute, 27 private route: ActivatedRoute,
39 private i18n: I18n 28 private i18n: I18n
@@ -41,17 +30,11 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
41 super() 30 super()
42 } 31 }
43 32
44 buildForm () {
45 this.form = this.formBuilder.group({
46 password: [ '', USER_PASSWORD.VALIDATORS ],
47 'password-confirm': [ '', Validators.required ]
48 })
49
50 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
51 }
52
53 ngOnInit () { 33 ngOnInit () {
54 this.buildForm() 34 this.buildForm({
35 password: USER_PASSWORD,
36 'password-confirm': RESET_PASSWORD_CONFIRM
37 })
55 38
56 this.userId = this.route.snapshot.queryParams['userId'] 39 this.userId = this.route.snapshot.queryParams['userId']
57 this.verificationString = this.route.snapshot.queryParams['verificationString'] 40 this.verificationString = this.route.snapshot.queryParams['verificationString']
diff --git a/client/src/app/shared/forms/form-reactive.ts b/client/src/app/shared/forms/form-reactive.ts
index e7764d069..441ec8203 100644
--- a/client/src/app/shared/forms/form-reactive.ts
+++ b/client/src/app/shared/forms/form-reactive.ts
@@ -1,40 +1,48 @@
1import { FormGroup } from '@angular/forms' 1import { FormGroup } from '@angular/forms'
2import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
3
4export type FormReactiveErrors = { [ id: string ]: string }
5export type FormReactiveValidationMessages = {
6 [ id: string ]: {
7 [ name: string ]: string
8 }
9}
2 10
3export abstract class FormReactive { 11export abstract class FormReactive {
4 abstract form: FormGroup 12 protected abstract formValidatorService: FormValidatorService
5 abstract formErrors: Object
6 abstract validationMessages: Object
7 13
8 abstract buildForm (): void 14 form: FormGroup
15 formErrors: FormReactiveErrors
16 validationMessages: FormReactiveValidationMessages
9 17
10 protected onValueChanged (data?: any) { 18 buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
11 for (const field in this.formErrors) { 19 const { formErrors, validationMessages, form } = this.formValidatorService.buildForm(obj, defaultValues)
12 // clear previous error message (if any)
13 this.formErrors[field] = ''
14 const control = this.form.get(field)
15 20
16 if (control && control.dirty && !control.valid) { 21 this.form = form
17 const messages = this.validationMessages[field] 22 this.formErrors = formErrors
18 for (const key in control.errors) { 23 this.validationMessages = validationMessages
19 this.formErrors[field] += messages[key] + ' ' 24
20 } 25 this.form.valueChanges.subscribe(data => this.onValueChanged(false))
21 }
22 }
23 } 26 }
24 27
25 // Same as onValueChanged but force checking even if the field is not dirty 28 protected onValueChanged (forceCheck = false) {
26 protected forceCheck () {
27 for (const field in this.formErrors) { 29 for (const field in this.formErrors) {
28 // clear previous error message (if any) 30 // clear previous error message (if any)
29 this.formErrors[field] = '' 31 this.formErrors[ field ] = ''
30 const control = this.form.get(field) 32 const control = this.form.get(field)
31 33
32 if (control && !control.valid) { 34 // Don't care if dirty on force check
33 const messages = this.validationMessages[field] 35 const isDirty = control.dirty || forceCheck === true
36 if (control && isDirty && !control.valid) {
37 const messages = this.validationMessages[ field ]
34 for (const key in control.errors) { 38 for (const key in control.errors) {
35 this.formErrors[field] += messages[key] + ' ' 39 this.formErrors[ field ] += messages[ key ] + ' '
36 } 40 }
37 } 41 }
38 } 42 }
39 } 43 }
44
45 protected forceCheck () {
46 return this.onValueChanged(true)
47 }
40} 48}
diff --git a/client/src/app/shared/forms/form-validators/form-validator.service.ts b/client/src/app/shared/forms/form-validators/form-validator.service.ts
new file mode 100644
index 000000000..5c3d3e4bd
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/form-validator.service.ts
@@ -0,0 +1,65 @@
1import { FormBuilder, FormControl, FormGroup, ValidatorFn } from '@angular/forms'
2import { Injectable } from '@angular/core'
3import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared/forms/form-reactive'
4import { I18n } from '@ngx-translate/i18n-polyfill'
5
6export type BuildFormArgument = {
7 [ id: string ]: {
8 VALIDATORS: ValidatorFn[],
9 MESSAGES: { [ name: string ]: string }
10 }
11}
12export type BuildFormDefaultValues = {
13 [ name: string ]: string | string[]
14}
15
16@Injectable()
17export class FormValidatorService {
18
19 constructor (
20 private formBuilder: FormBuilder,
21 private i18n: I18n
22 ) {}
23
24 buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
25 const formErrors: FormReactiveErrors = {}
26 const validationMessages: FormReactiveValidationMessages = {}
27 const group: { [key: string]: any } = {}
28
29 for (const name of Object.keys(obj)) {
30 formErrors[name] = ''
31
32 const field = obj[name]
33 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES
34
35 const defaultValue = defaultValues[name] || ''
36
37 if (field && field.VALIDATORS) group[name] = [ defaultValue, field.VALIDATORS ]
38 else group[name] = [ defaultValue ]
39 }
40
41 const form = this.formBuilder.group(group)
42 return { form, formErrors, validationMessages }
43 }
44
45 updateForm (
46 form: FormGroup,
47 formErrors: FormReactiveErrors,
48 validationMessages: FormReactiveValidationMessages,
49 obj: BuildFormArgument,
50 defaultValues: BuildFormDefaultValues = {}
51 ) {
52 for (const name of Object.keys(obj)) {
53 formErrors[name] = ''
54
55 const field = obj[name]
56 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES
57
58 const defaultValue = defaultValues[name] || ''
59
60 if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS))
61 else form.addControl(name, new FormControl(defaultValue))
62 }
63 }
64
65}
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index 09ae86f8a..cf544b2a9 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -1,3 +1,4 @@
1export * from './form-validator.service'
1export * from './host' 2export * from './host'
2export * from './user' 3export * from './user'
3export * from './video-abuse' 4export * from './video-abuse'
diff --git a/client/src/app/shared/forms/form-validators/login.ts b/client/src/app/shared/forms/form-validators/login.ts
new file mode 100644
index 000000000..f37f8d285
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/login.ts
@@ -0,0 +1,18 @@
1import { Validators } from '@angular/forms'
2
3export const LOGIN_USERNAME = {
4 VALIDATORS: [
5 Validators.required
6 ],
7 MESSAGES: {
8 'required': 'Username is required.'
9 }
10}
11export const LOGIN_PASSWORD = {
12 VALIDATORS: [
13 Validators.required
14 ],
15 MESSAGES: {
16 'required': 'Password is required.'
17 }
18}
diff --git a/client/src/app/shared/forms/form-validators/reset-password.ts b/client/src/app/shared/forms/form-validators/reset-password.ts
new file mode 100644
index 000000000..7dafdef9a
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/reset-password.ts
@@ -0,0 +1,10 @@
1import { Validators } from '@angular/forms'
2
3export const RESET_PASSWORD_CONFIRM = {
4 VALIDATORS: [
5 Validators.required
6 ],
7 MESSAGES: {
8 'required': 'Confirmation of the password is required.'
9 }
10}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index fba099401..91d905ec7 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -34,6 +34,7 @@ import { VideoService } from './video/video.service'
34import { AccountService } from '@app/shared/account/account.service' 34import { AccountService } from '@app/shared/account/account.service'
35import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 35import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
36import { I18n } from '@ngx-translate/i18n-polyfill' 36import { I18n } from '@ngx-translate/i18n-polyfill'
37import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
37 38
38@NgModule({ 39@NgModule({
39 imports: [ 40 imports: [
@@ -110,6 +111,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
110 AccountService, 111 AccountService,
111 MarkdownService, 112 MarkdownService,
112 VideoChannelService, 113 VideoChannelService,
114 FormValidatorService,
113 I18n 115 I18n
114 ] 116 ]
115}) 117})
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts
index eaed2626d..682e592c7 100644
--- a/client/src/app/signup/signup.component.ts
+++ b/client/src/app/signup/signup.component.ts
@@ -1,5 +1,4 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { Router } from '@angular/router' 2import { Router } from '@angular/router'
4import { ServerService } from '@app/core/server' 3import { ServerService } from '@app/core/server'
5 4
@@ -8,6 +7,7 @@ import { UserCreate } from '../../../../shared'
8import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared' 7import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared'
9import { RedirectService } from '@app/core' 8import { RedirectService } from '@app/core'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
11 11
12@Component({ 12@Component({
13 selector: 'my-signup', 13 selector: 'my-signup',
@@ -18,18 +18,6 @@ export class SignupComponent extends FormReactive implements OnInit {
18 error: string = null 18 error: string = null
19 quotaHelpIndication = '' 19 quotaHelpIndication = ''
20 20
21 form: FormGroup
22 formErrors = {
23 'username': '',
24 'email': '',
25 'password': ''
26 }
27 validationMessages = {
28 'username': USER_USERNAME.MESSAGES,
29 'email': USER_EMAIL.MESSAGES,
30 'password': USER_PASSWORD.MESSAGES
31 }
32
33 private static getApproximateTime (seconds: number) { 21 private static getApproximateTime (seconds: number) {
34 const hours = Math.floor(seconds / 3600) 22 const hours = Math.floor(seconds / 3600)
35 let pluralSuffix = '' 23 let pluralSuffix = ''
@@ -43,7 +31,7 @@ export class SignupComponent extends FormReactive implements OnInit {
43 } 31 }
44 32
45 constructor ( 33 constructor (
46 private formBuilder: FormBuilder, 34 protected formValidatorService: FormValidatorService,
47 private router: Router, 35 private router: Router,
48 private notificationsService: NotificationsService, 36 private notificationsService: NotificationsService,
49 private userService: UserService, 37 private userService: UserService,
@@ -58,18 +46,12 @@ export class SignupComponent extends FormReactive implements OnInit {
58 return this.serverService.getConfig().user.videoQuota 46 return this.serverService.getConfig().user.videoQuota
59 } 47 }
60 48
61 buildForm () {
62 this.form = this.formBuilder.group({
63 username: [ '', USER_USERNAME.VALIDATORS ],
64 email: [ '', USER_EMAIL.VALIDATORS ],
65 password: [ '', USER_PASSWORD.VALIDATORS ]
66 })
67
68 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
69 }
70
71 ngOnInit () { 49 ngOnInit () {
72 this.buildForm() 50 this.buildForm({
51 username: USER_USERNAME,
52 password: USER_PASSWORD,
53 email: USER_EMAIL
54 })
73 55
74 this.serverService.configLoaded 56 this.serverService.configLoaded
75 .subscribe(() => this.buildQuotaHelpIndication()) 57 .subscribe(() => this.buildQuotaHelpIndication())
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
index ccfae5fcc..cd2a26ae3 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
@@ -1,7 +1,7 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { FormBuilder, FormControl, FormGroup } from '@angular/forms' 2import { FormGroup } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { VIDEO_IMAGE, VIDEO_SUPPORT } from '@app/shared' 4import { VIDEO_SUPPORT } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
6import { ServerService } from '../../../core/server' 6import { ServerService } from '../../../core/server'
7import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators' 7import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators'
@@ -17,6 +17,7 @@ import {
17} from '../../../shared/forms/form-validators/video' 17} from '../../../shared/forms/form-validators/video'
18import { VideoEdit } from '../../../shared/video/video-edit.model' 18import { VideoEdit } from '../../../shared/video/video-edit.model'
19import { map } from 'rxjs/operators' 19import { map } from 'rxjs/operators'
20import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
20 21
21@Component({ 22@Component({
22 selector: 'my-video-edit', 23 selector: 'my-video-edit',
@@ -42,7 +43,7 @@ export class VideoEditComponent implements OnInit {
42 error: string = null 43 error: string = null
43 44
44 constructor ( 45 constructor (
45 private formBuilder: FormBuilder, 46 private formValidatorService: FormValidatorService,
46 private route: ActivatedRoute, 47 private route: ActivatedRoute,
47 private router: Router, 48 private router: Router,
48 private notificationsService: NotificationsService, 49 private notificationsService: NotificationsService,
@@ -50,41 +51,34 @@ export class VideoEditComponent implements OnInit {
50 ) { } 51 ) { }
51 52
52 updateForm () { 53 updateForm () {
53 this.formErrors['name'] = '' 54 const defaultValues = {
54 this.formErrors['privacy'] = '' 55 nsfw: 'false',
55 this.formErrors['channelId'] = '' 56 commentsEnabled: 'true',
56 this.formErrors['category'] = '' 57 tags: []
57 this.formErrors['licence'] = '' 58 }
58 this.formErrors['language'] = '' 59 const obj = {
59 this.formErrors['description'] = '' 60 name: VIDEO_NAME,
60 this.formErrors['thumbnailfile'] = '' 61 privacy: VIDEO_PRIVACY,
61 this.formErrors['previewfile'] = '' 62 channelId: VIDEO_CHANNEL,
62 this.formErrors['support'] = '' 63 nsfw: null,
63 64 commentsEnabled: null,
64 this.validationMessages['name'] = VIDEO_NAME.MESSAGES 65 category: VIDEO_CATEGORY,
65 this.validationMessages['privacy'] = VIDEO_PRIVACY.MESSAGES 66 licence: VIDEO_LICENCE,
66 this.validationMessages['channelId'] = VIDEO_CHANNEL.MESSAGES 67 language: VIDEO_LANGUAGE,
67 this.validationMessages['category'] = VIDEO_CATEGORY.MESSAGES 68 description: VIDEO_DESCRIPTION,
68 this.validationMessages['licence'] = VIDEO_LICENCE.MESSAGES 69 tags: null,
69 this.validationMessages['language'] = VIDEO_LANGUAGE.MESSAGES 70 thumbnailfile: null,
70 this.validationMessages['description'] = VIDEO_DESCRIPTION.MESSAGES 71 previewfile: null,
71 this.validationMessages['thumbnailfile'] = VIDEO_IMAGE.MESSAGES 72 support: VIDEO_SUPPORT
72 this.validationMessages['previewfile'] = VIDEO_IMAGE.MESSAGES 73 }
73 this.validationMessages['support'] = VIDEO_SUPPORT.MESSAGES 74
74 75 this.formValidatorService.updateForm(
75 this.form.addControl('name', new FormControl('', VIDEO_NAME.VALIDATORS)) 76 this.form,
76 this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS)) 77 this.formErrors,
77 this.form.addControl('channelId', new FormControl('', VIDEO_CHANNEL.VALIDATORS)) 78 this.validationMessages,
78 this.form.addControl('nsfw', new FormControl(false)) 79 obj,
79 this.form.addControl('commentsEnabled', new FormControl(true)) 80 defaultValues
80 this.form.addControl('category', new FormControl('', VIDEO_CATEGORY.VALIDATORS)) 81 )
81 this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))
82 this.form.addControl('language', new FormControl('', VIDEO_LANGUAGE.VALIDATORS))
83 this.form.addControl('description', new FormControl('', VIDEO_DESCRIPTION.VALIDATORS))
84 this.form.addControl('tags', new FormControl([]))
85 this.form.addControl('thumbnailfile', new FormControl(''))
86 this.form.addControl('previewfile', new FormControl(''))
87 this.form.addControl('support', new FormControl('', VIDEO_SUPPORT.VALIDATORS))
88 82
89 // We will update the "support" field depending on the channel 83 // We will update the "support" field depending on the channel
90 this.form.controls['channelId'] 84 this.form.controls['channelId']
@@ -98,6 +92,7 @@ export class VideoEditComponent implements OnInit {
98 // Not initialized yet 92 // Not initialized yet
99 if (isNaN(newChannelId)) return 93 if (isNaN(newChannelId)) return
100 const newChannel = this.userVideoChannels.find(c => c.id === newChannelId) 94 const newChannel = this.userVideoChannels.find(c => c.id === newChannelId)
95 if (!newChannel) return
101 96
102 // First time we set the channel? 97 // First time we set the channel?
103 if (isNaN(oldChannelId)) return this.updateSupportField(newChannel.support) 98 if (isNaN(oldChannelId)) return this.updateSupportField(newChannel.support)
diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts
index a615fd92c..332f757d7 100644
--- a/client/src/app/videos/+video-edit/video-add.component.ts
+++ b/client/src/app/videos/+video-edit/video-add.component.ts
@@ -1,6 +1,5 @@
1import { HttpEventType, HttpResponse } from '@angular/common/http' 1import { HttpEventType, HttpResponse } from '@angular/common/http'
2import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' 2import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
3import { FormBuilder, FormGroup } from '@angular/forms'
4import { Router } from '@angular/router' 3import { Router } from '@angular/router'
5import { UserService } from '@app/shared' 4import { UserService } from '@app/shared'
6import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' 5import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
@@ -11,11 +10,11 @@ import { Subscription } from 'rxjs'
11import { VideoPrivacy } from '../../../../../shared/models/videos' 10import { VideoPrivacy } from '../../../../../shared/models/videos'
12import { AuthService, ServerService } from '../../core' 11import { AuthService, ServerService } from '../../core'
13import { FormReactive } from '../../shared' 12import { FormReactive } from '../../shared'
14import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
15import { populateAsyncUserVideoChannels } from '../../shared/misc/utils' 13import { populateAsyncUserVideoChannels } from '../../shared/misc/utils'
16import { VideoEdit } from '../../shared/video/video-edit.model' 14import { VideoEdit } from '../../shared/video/video-edit.model'
17import { VideoService } from '../../shared/video/video.service' 15import { VideoService } from '../../shared/video/video.service'
18import { I18n } from '@ngx-translate/i18n-polyfill' 16import { I18n } from '@ngx-translate/i18n-polyfill'
17import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
19 18
20@Component({ 19@Component({
21 selector: 'my-videos-add', 20 selector: 'my-videos-add',
@@ -39,10 +38,6 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
39 } 38 }
40 videoFileName: string 39 videoFileName: string
41 40
42 form: FormGroup
43 formErrors: { [ id: string ]: string } = {}
44 validationMessages: ValidatorMessage = {}
45
46 userVideoChannels: { id: number, label: string, support: string }[] = [] 41 userVideoChannels: { id: number, label: string, support: string }[] = []
47 userVideoQuotaUsed = 0 42 userVideoQuotaUsed = 0
48 videoPrivacies = [] 43 videoPrivacies = []
@@ -50,7 +45,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
50 firstStepChannelId = 0 45 firstStepChannelId = 0
51 46
52 constructor ( 47 constructor (
53 private formBuilder: FormBuilder, 48 protected formValidatorService: FormValidatorService,
54 private router: Router, 49 private router: Router,
55 private notificationsService: NotificationsService, 50 private notificationsService: NotificationsService,
56 private authService: AuthService, 51 private authService: AuthService,
@@ -67,13 +62,8 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
67 return this.serverService.getConfig().video.file.extensions.join(',') 62 return this.serverService.getConfig().video.file.extensions.join(',')
68 } 63 }
69 64
70 buildForm () {
71 this.form = this.formBuilder.group({})
72 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
73 }
74
75 ngOnInit () { 65 ngOnInit () {
76 this.buildForm() 66 this.buildForm({})
77 67
78 populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) 68 populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
79 .then(() => this.firstStepChannelId = this.userVideoChannels[0].id) 69 .then(() => this.firstStepChannelId = this.userVideoChannels[0].id)
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts
index e37dd526f..0266164af 100644
--- a/client/src/app/videos/+video-edit/video-update.component.ts
+++ b/client/src/app/videos/+video-edit/video-update.component.ts
@@ -1,6 +1,5 @@
1import { map, switchMap } from 'rxjs/operators' 1import { map, switchMap } from 'rxjs/operators'
2import { Component, OnInit } from '@angular/core' 2import { Component, OnInit } from '@angular/core'
3import { FormBuilder, FormGroup } from '@angular/forms'
4import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
5import { LoadingBarService } from '@ngx-loading-bar/core' 4import { LoadingBarService } from '@ngx-loading-bar/core'
6import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
@@ -8,11 +7,11 @@ import { VideoPrivacy } from '../../../../../shared/models/videos'
8import { ServerService } from '../../core' 7import { ServerService } from '../../core'
9import { AuthService } from '../../core/auth' 8import { AuthService } from '../../core/auth'
10import { FormReactive } from '../../shared' 9import { FormReactive } from '../../shared'
11import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
12import { VideoEdit } from '../../shared/video/video-edit.model' 10import { VideoEdit } from '../../shared/video/video-edit.model'
13import { VideoService } from '../../shared/video/video.service' 11import { VideoService } from '../../shared/video/video.service'
14import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 12import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
15import { I18n } from '@ngx-translate/i18n-polyfill' 13import { I18n } from '@ngx-translate/i18n-polyfill'
14import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
16 15
17@Component({ 16@Component({
18 selector: 'my-videos-update', 17 selector: 'my-videos-update',
@@ -23,14 +22,11 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
23 video: VideoEdit 22 video: VideoEdit
24 23
25 isUpdatingVideo = false 24 isUpdatingVideo = false
26 form: FormGroup
27 formErrors: { [ id: string ]: string } = {}
28 validationMessages: ValidatorMessage = {}
29 videoPrivacies = [] 25 videoPrivacies = []
30 userVideoChannels = [] 26 userVideoChannels = []
31 27
32 constructor ( 28 constructor (
33 private formBuilder: FormBuilder, 29 protected formValidatorService: FormValidatorService,
34 private route: ActivatedRoute, 30 private route: ActivatedRoute,
35 private router: Router, 31 private router: Router,
36 private notificationsService: NotificationsService, 32 private notificationsService: NotificationsService,
@@ -44,13 +40,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
44 super() 40 super()
45 } 41 }
46 42
47 buildForm () {
48 this.form = this.formBuilder.group({})
49 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
50 }
51
52 ngOnInit () { 43 ngOnInit () {
53 this.buildForm() 44 this.buildForm({})
54 45
55 this.serverService.videoPrivaciesLoaded 46 this.serverService.videoPrivaciesLoaded
56 .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies()) 47 .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies())
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
index 2ee5f5ef1..c70e544a3 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
@@ -1,5 +1,4 @@
1import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
4import { Observable } from 'rxjs' 3import { Observable } from 'rxjs'
5import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' 4import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
@@ -10,6 +9,7 @@ import { Video } from '../../../shared/video/video.model'
10import { VideoComment } from './video-comment.model' 9import { VideoComment } from './video-comment.model'
11import { VideoCommentService } from './video-comment.service' 10import { VideoCommentService } from './video-comment.service'
12import { I18n } from '@ngx-translate/i18n-polyfill' 11import { I18n } from '@ngx-translate/i18n-polyfill'
12import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
13 13
14@Component({ 14@Component({
15 selector: 'my-video-comment-add', 15 selector: 'my-video-comment-add',
@@ -25,18 +25,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
25 25
26 @Output() commentCreated = new EventEmitter<VideoCommentCreate>() 26 @Output() commentCreated = new EventEmitter<VideoCommentCreate>()
27 27
28 form: FormGroup
29 formErrors = {
30 'text': ''
31 }
32 validationMessages = {
33 'text': VIDEO_COMMENT_TEXT.MESSAGES
34 }
35
36 @ViewChild('textarea') private textareaElement: ElementRef 28 @ViewChild('textarea') private textareaElement: ElementRef
37 29
38 constructor ( 30 constructor (
39 private formBuilder: FormBuilder, 31 protected formValidatorService: FormValidatorService,
40 private notificationsService: NotificationsService, 32 private notificationsService: NotificationsService,
41 private videoCommentService: VideoCommentService, 33 private videoCommentService: VideoCommentService,
42 private i18n: I18n 34 private i18n: I18n
@@ -44,16 +36,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
44 super() 36 super()
45 } 37 }
46 38
47 buildForm () {
48 this.form = this.formBuilder.group({
49 text: [ '', VIDEO_COMMENT_TEXT.VALIDATORS ]
50 })
51
52 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
53 }
54
55 ngOnInit () { 39 ngOnInit () {
56 this.buildForm() 40 this.buildForm({
41 text: VIDEO_COMMENT_TEXT
42 })
57 43
58 if (this.focusOnInit === true) { 44 if (this.focusOnInit === true) {
59 this.textareaElement.nativeElement.focus() 45 this.textareaElement.nativeElement.focus()
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.ts b/client/src/app/videos/+video-watch/modal/video-report.component.ts
index 1bbd30226..8641e8dfb 100644
--- a/client/src/app/videos/+video-watch/modal/video-report.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-report.component.ts
@@ -5,6 +5,8 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
5import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index' 5import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index'
6import { VideoDetails } from '../../../shared/video/video-details.model' 6import { VideoDetails } from '../../../shared/video/video-details.model'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8 10
9@Component({ 11@Component({
10 selector: 'my-video-report', 12 selector: 'my-video-report',
@@ -17,16 +19,9 @@ export class VideoReportComponent extends FormReactive implements OnInit {
17 @ViewChild('modal') modal: ModalDirective 19 @ViewChild('modal') modal: ModalDirective
18 20
19 error: string = null 21 error: string = null
20 form: FormGroup
21 formErrors = {
22 reason: ''
23 }
24 validationMessages = {
25 reason: VIDEO_ABUSE_REASON.MESSAGES
26 }
27 22
28 constructor ( 23 constructor (
29 private formBuilder: FormBuilder, 24 protected formValidatorService: FormValidatorService,
30 private videoAbuseService: VideoAbuseService, 25 private videoAbuseService: VideoAbuseService,
31 private notificationsService: NotificationsService, 26 private notificationsService: NotificationsService,
32 private i18n: I18n 27 private i18n: I18n
@@ -35,15 +30,9 @@ export class VideoReportComponent extends FormReactive implements OnInit {
35 } 30 }
36 31
37 ngOnInit () { 32 ngOnInit () {
38 this.buildForm() 33 this.buildForm({
39 } 34 reason: VIDEO_ABUSE_REASON
40
41 buildForm () {
42 this.form = this.formBuilder.group({
43 reason: [ '', VIDEO_ABUSE_REASON.VALIDATORS ]
44 }) 35 })
45
46 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
47 } 36 }
48 37
49 show () { 38 show () {