Form validators refractoring
authorChocobozzz <me@florianbigard.com>
Tue, 5 Jun 2018 08:58:45 +0000 (10:58 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 5 Jun 2018 08:58:45 +0000 (10:58 +0200)
25 files changed:
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
client/src/app/+admin/users/user-edit/user-create.component.ts
client/src/app/+admin/users/user-edit/user-edit.ts
client/src/app/+admin/users/user-edit/user-update.component.ts
client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
client/src/app/+my-account/my-account-settings/my-account-settings.component.html
client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
client/src/app/login/login.component.ts
client/src/app/reset-password/reset-password.component.ts
client/src/app/shared/forms/form-reactive.ts
client/src/app/shared/forms/form-validators/form-validator.service.ts [new file with mode: 0644]
client/src/app/shared/forms/form-validators/index.ts
client/src/app/shared/forms/form-validators/login.ts [new file with mode: 0644]
client/src/app/shared/forms/form-validators/reset-password.ts [new file with mode: 0644]
client/src/app/shared/shared.module.ts
client/src/app/signup/signup.component.ts
client/src/app/videos/+video-edit/shared/video-edit.component.ts
client/src/app/videos/+video-edit/video-add.component.ts
client/src/app/videos/+video-edit/video-update.component.ts
client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
client/src/app/videos/+video-watch/modal/video-report.component.ts

index 73ff4b7bbe6551ecb68e51670f2ec2c6d8ff826f..f2a3464cb83ad991c8121e68ed53388bbdf85eed 100644 (file)
@@ -17,6 +17,7 @@ import {
 import { NotificationsService } from 'angular2-notifications'
 import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-edit-custom-config',
@@ -44,38 +45,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
     { value: 8, label: '8' }
   ]
 
-  form: FormGroup
-  formErrors = {
-    instanceName: '',
-    instanceShortDescription: '',
-    instanceDescription: '',
-    instanceTerms: '',
-    instanceDefaultClientRoute: '',
-    instanceDefaultNSFWPolicy: '',
-    servicesTwitterUsername: '',
-    cachePreviewsSize: '',
-    signupLimit: '',
-    adminEmail: '',
-    userVideoQuota: '',
-    transcodingThreads: '',
-    customizationJavascript: '',
-    customizationCSS: ''
-  }
-  validationMessages = {
-    instanceShortDescription: INSTANCE_SHORT_DESCRIPTION.MESSAGES,
-    instanceName: INSTANCE_NAME.MESSAGES,
-    servicesTwitterUsername: SERVICES_TWITTER_USERNAME,
-    cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES,
-    signupLimit: SIGNUP_LIMIT.MESSAGES,
-    adminEmail: ADMIN_EMAIL.MESSAGES,
-    userVideoQuota: USER_VIDEO_QUOTA.MESSAGES
-  }
-
   private oldCustomJavascript: string
   private oldCustomCSS: string
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private router: Router,
     private notificationsService: NotificationsService,
     private configService: ConfigService,
@@ -90,39 +64,35 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
     return 'transcodingResolution' + resolution
   }
 
-  buildForm () {
+  ngOnInit () {
     const formGroupData = {
-      instanceName: [ '', INSTANCE_NAME.VALIDATORS ],
-      instanceShortDescription: [ '', INSTANCE_SHORT_DESCRIPTION.VALIDATORS ],
-      instanceDescription: [ '' ],
-      instanceTerms: [ '' ],
-      instanceDefaultClientRoute: [ '' ],
-      instanceDefaultNSFWPolicy: [ '' ],
-      servicesTwitterUsername: [ '', SERVICES_TWITTER_USERNAME.VALIDATORS ],
-      servicesTwitterWhitelisted: [ ],
-      cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
-      signupEnabled: [ ],
-      signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
-      adminEmail: [ '', ADMIN_EMAIL.VALIDATORS ],
-      userVideoQuota: [ '', USER_VIDEO_QUOTA.VALIDATORS ],
-      transcodingThreads: [ '', TRANSCODING_THREADS.VALIDATORS ],
-      transcodingEnabled: [ ],
-      customizationJavascript: [ '' ],
-      customizationCSS: [ '' ]
+      instanceName: INSTANCE_NAME,
+      instanceShortDescription: INSTANCE_SHORT_DESCRIPTION,
+      instanceDescription: null,
+      instanceTerms: null,
+      instanceDefaultClientRoute: null,
+      instanceDefaultNSFWPolicy: null,
+      servicesTwitterUsername: SERVICES_TWITTER_USERNAME,
+      servicesTwitterWhitelisted: null,
+      cachePreviewsSize: CACHE_PREVIEWS_SIZE,
+      signupEnabled: null,
+      signupLimit: SIGNUP_LIMIT,
+      adminEmail: ADMIN_EMAIL,
+      userVideoQuota: USER_VIDEO_QUOTA,
+      transcodingThreads: TRANSCODING_THREADS,
+      transcodingEnabled: null,
+      customizationJavascript: null,
+      customizationCSS: null
     }
 
+    const defaultValues: BuildFormDefaultValues = {}
     for (const resolution of this.resolutions) {
       const key = this.getResolutionKey(resolution)
-      formGroupData[key] = [ false ]
+      defaultValues[key] = 'false'
+      formGroupData[key] = null
     }
 
-    this.form = this.formBuilder.group(formGroupData)
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
-  ngOnInit () {
-    this.buildForm()
+    this.buildForm(formGroupData)
 
     this.configService.getCustomConfig()
       .subscribe(
index 8478a7692e9ef1b5608a0d1d0edaa1e87ddee1db..e5f0903b646e4b6af73265fa0d94f90d3c2938a8 100644 (file)
@@ -1,5 +1,4 @@
 import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { Router } from '@angular/router'
 import { NotificationsService } from 'angular2-notifications'
 import { UserService } from '../shared'
@@ -8,6 +7,7 @@ import { ServerService } from '../../../core'
 import { UserCreate, UserRole } from '../../../../../../shared'
 import { UserEdit } from './user-edit'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-user-create',
@@ -17,25 +17,9 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 export class UserCreateComponent extends UserEdit implements OnInit {
   error: string
 
-  form: FormGroup
-  formErrors = {
-    'username': '',
-    'email': '',
-    'password': '',
-    'role': '',
-    'videoQuota': ''
-  }
-  validationMessages = {
-    'username': USER_USERNAME.MESSAGES,
-    'email': USER_EMAIL.MESSAGES,
-    'password': USER_PASSWORD.MESSAGES,
-    'role': USER_ROLE.MESSAGES,
-    'videoQuota': USER_VIDEO_QUOTA.MESSAGES
-  }
-
   constructor (
     protected serverService: ServerService,
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private router: Router,
     private notificationsService: NotificationsService,
     private userService: UserService,
@@ -44,20 +28,19 @@ export class UserCreateComponent extends UserEdit implements OnInit {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      username: [ '', USER_USERNAME.VALIDATORS ],
-      email:    [ '', USER_EMAIL.VALIDATORS ],
-      password: [ '', USER_PASSWORD.VALIDATORS ],
-      role: [ UserRole.USER, USER_ROLE.VALIDATORS ],
-      videoQuota: [ '-1', USER_VIDEO_QUOTA.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    const defaultValues = {
+      role: UserRole.USER.toString(),
+      videoQuota: '-1'
+    }
+
+    this.buildForm({
+      username: USER_USERNAME,
+      email: USER_EMAIL,
+      password: USER_PASSWORD,
+      role: USER_ROLE,
+      videoQuota: USER_VIDEO_QUOTA
+    }, defaultValues)
   }
 
   formValidated () {
index 2b47c685c905590773a2412e48241a66063b9df1..ea8c733c3cbc0c5aafaa1f7e692f5db2ea69362d 100644 (file)
@@ -12,9 +12,9 @@ export abstract class UserEdit extends FormReactive {
     { value: 5 * 1024 * 1024 * 1024, label: '5GB' },
     { value: 20 * 1024 * 1024 * 1024, label: '20GB' },
     { value: 50 * 1024 * 1024 * 1024, label: '50GB' }
-  ]
+  ].map(q => ({ value: q.value.toString(), label: q.label })) // Used by a HTML select, so convert key into strings
 
-  roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key, label: USER_ROLE_LABELS[key] }))
+  roles = Object.keys(USER_ROLE_LABELS).map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] }))
 
   protected abstract serverService: ServerService
   abstract isCreation (): boolean
index 5689aab2f8932b269a9f1aae0b92ebdbdd860d97..f8073c928341b2962d8f9eb8c5ef6d371a385eb4 100644 (file)
@@ -1,5 +1,4 @@
 import { Component, OnDestroy, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { ActivatedRoute, Router } from '@angular/router'
 import { Subscription } from 'rxjs'
 import { NotificationsService } from 'angular2-notifications'
@@ -9,6 +8,7 @@ import { ServerService } from '../../../core'
 import { UserEdit } from './user-edit'
 import { UserUpdate } from '../../../../../../shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-user-update',
@@ -20,44 +20,27 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
   userId: number
   username: string
 
-  form: FormGroup
-  formErrors = {
-    'email': '',
-    'role': '',
-    'videoQuota': ''
-  }
-  validationMessages = {
-    'email': USER_EMAIL.MESSAGES,
-    'role': USER_ROLE.MESSAGES,
-    'videoQuota': USER_VIDEO_QUOTA.MESSAGES
-  }
-
   private paramsSub: Subscription
 
   constructor (
+    protected formValidatorService: FormValidatorService,
     protected serverService: ServerService,
     private route: ActivatedRoute,
     private router: Router,
     private notificationsService: NotificationsService,
-    private formBuilder: FormBuilder,
     private userService: UserService,
     private i18n: I18n
   ) {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      email:    [ '', USER_EMAIL.VALIDATORS ],
-      role: [ '', USER_ROLE.VALIDATORS ],
-      videoQuota: [ '-1', USER_VIDEO_QUOTA.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    const defaultValues = { videoQuota: '-1' }
+    this.buildForm({
+      email: USER_EMAIL,
+      role: USER_ROLE,
+      videoQuota: USER_VIDEO_QUOTA
+    }, defaultValues)
 
     this.paramsSub = this.route.params.subscribe(routeParams => {
       const userId = routeParams['id']
index 1a88aa82e38afaef4f87386943fe80c51346cd87..56e644f39639e93fcf4a53c309aeb95aca7f3d2a 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { NotificationsService } from 'angular2-notifications'
 import { FormReactive, USER_PASSWORD, UserService } from '../../../shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-account-change-password',
@@ -12,18 +12,8 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 export class MyAccountChangePasswordComponent extends FormReactive implements OnInit {
   error: string = null
 
-  form: FormGroup
-  formErrors = {
-    'new-password': '',
-    'new-confirmed-password': ''
-  }
-  validationMessages = {
-    'new-password': USER_PASSWORD.MESSAGES,
-    'new-confirmed-password': USER_PASSWORD.MESSAGES
-  }
-
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private notificationsService: NotificationsService,
     private userService: UserService,
     private i18n: I18n
@@ -31,17 +21,11 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      'new-password': [ '', USER_PASSWORD.VALIDATORS ],
-      'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      'new-password': USER_PASSWORD,
+      'new-confirmed-password': USER_PASSWORD
+    })
   }
 
   changePassword () {
index 35843ecd92899a535ae9c9b26d2aa13773fa9db9..1fe337da0d51fcd87c103fc16204d44a25c6861a 100644 (file)
@@ -1,9 +1,10 @@
 import { Component, Input, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { NotificationsService } from 'angular2-notifications'
 import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared'
 import { User } from '@app/shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
+import { Subject } from 'rxjs/Subject'
 
 @Component({
   selector: 'my-account-profile',
@@ -12,21 +13,12 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 })
 export class MyAccountProfileComponent extends FormReactive implements OnInit {
   @Input() user: User = null
+  @Input() userInformationLoaded: Subject<any>
 
   error: string = null
 
-  form: FormGroup
-  formErrors = {
-    'display-name': '',
-    'description': ''
-  }
-  validationMessages = {
-    'display-name': USER_DISPLAY_NAME.MESSAGES,
-    'description': USER_DESCRIPTION.MESSAGES
-  }
-
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private notificationsService: NotificationsService,
     private userService: UserService,
     private i18n: I18n
@@ -34,17 +26,18 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      'display-name': [ this.user.account.displayName, USER_DISPLAY_NAME.VALIDATORS ],
-      'description': [ this.user.account.description, USER_DESCRIPTION.VALIDATORS ]
+  ngOnInit () {
+    this.buildForm({
+      'display-name': USER_DISPLAY_NAME,
+      description: USER_DESCRIPTION
     })
 
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
-  ngOnInit () {
-    this.buildForm()
+    this.userInformationLoaded.subscribe(() => {
+      this.form.patchValue({
+        'display-name': this.user.account.displayName,
+        description: this.user.account.description
+      })
+    })
   }
 
   updateMyProfile () {
index 056c2a7d76b26f88d8eca3307d654090ce03e46b..f5d593f19f5714ab8d1ae74ae26a5a2bffc99455 100644 (file)
@@ -3,7 +3,7 @@
 
   <div class="user-info">
     <div class="user-info-names">
-      <div class="user-info-display-name">{{ user.account.displayName }}</div>
+      <div class="user-info-display-name">{{ user.account?.displayName }}</div>
       <div class="user-info-username">{{ user.username }}</div>
     </div>
     <div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div>
 
 <ng-template [ngIf]="user && user.account">
   <div i18n class="account-title">Profile</div>
-  <my-account-profile [user]="user"></my-account-profile>
+  <my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
 </ng-template>
 
 <div i18n class="account-title">Password</div>
 <my-account-change-password></my-account-change-password>
 
 <div i18n class="account-title">Video settings</div>
-<my-account-video-settings [user]="user"></my-account-video-settings>
+<my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings>
index 44eddaa7c5a76066d83eaaef911d118c44344d76..15f977e586477aa74303c185c64a8efb186df324 100644 (file)
@@ -27,6 +27,10 @@ export class MyAccountSettingsComponent implements OnInit {
     private i18n: I18n
   ) {}
 
+  get userInformationLoaded () {
+    return this.authService.userInformationLoaded
+  }
+
   ngOnInit () {
     this.user = this.authService.getUser()
 
index 4588f73db46ff5069b930790ad008fcde572f781..85b3a48cc728b60fb411d1913af764c345bb6717 100644 (file)
@@ -1,10 +1,11 @@
 import { Component, Input, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { NotificationsService } from 'angular2-notifications'
 import { UserUpdateMe } from '../../../../../../shared'
 import { AuthService } from '../../../core'
 import { FormReactive, User, UserService } from '../../../shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
+import { Subject } from 'rxjs/Subject'
 
 @Component({
   selector: 'my-account-video-settings',
@@ -13,14 +14,11 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 })
 export class MyAccountVideoSettingsComponent extends FormReactive implements OnInit {
   @Input() user: User = null
-
-  form: FormGroup
-  formErrors = {}
-  validationMessages = {}
+  @Input() userInformationLoaded: Subject<any>
 
   constructor (
+    protected formValidatorService: FormValidatorService,
     private authService: AuthService,
-    private formBuilder: FormBuilder,
     private notificationsService: NotificationsService,
     private userService: UserService,
     private i18n: I18n
@@ -28,17 +26,18 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      nsfwPolicy: [ this.user.nsfwPolicy ],
-      autoPlayVideo: [ this.user.autoPlayVideo ]
+  ngOnInit () {
+    this.buildForm({
+      nsfwPolicy: null,
+      autoPlayVideo: null
     })
 
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
-  ngOnInit () {
-    this.buildForm()
+    this.userInformationLoaded.subscribe(() => {
+      this.form.patchValue({
+        nsfwPolicy: this.user.nsfwPolicy,
+        autoPlayVideo: this.user.autoPlayVideo === true ? 'true' : 'false'
+      })
+    })
   }
 
   updateDetails () {
index a4073728b223ef2096bcc46027529a758b4c9515..e38eaae9c876da5f5c90b124dd5c712f5bd4115a 100644 (file)
@@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core'
 import { Router } from '@angular/router'
 import { NotificationsService } from 'angular2-notifications'
 import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { VideoChannelCreate } from '../../../../../shared/models/videos'
 import {
   VIDEO_CHANNEL_DESCRIPTION,
@@ -12,6 +11,7 @@ import {
 import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
 import { AuthService } from '@app/core'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-account-video-channel-create',
@@ -21,41 +21,23 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit {
   error: string
 
-  form: FormGroup
-  formErrors = {
-    'display-name': '',
-    'description': '',
-    'support': ''
-  }
-  validationMessages = {
-    'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES,
-    'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES,
-    'support': VIDEO_CHANNEL_SUPPORT.MESSAGES
-  }
-
   constructor (
+    protected formValidatorService: FormValidatorService,
     private authService: AuthService,
     private notificationsService: NotificationsService,
     private router: Router,
-    private formBuilder: FormBuilder,
     private videoChannelService: VideoChannelService,
     private i18n: I18n
   ) {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ],
-      description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ],
-      support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      'display-name': VIDEO_CHANNEL_DISPLAY_NAME,
+      description: VIDEO_CHANNEL_DESCRIPTION,
+      support: VIDEO_CHANNEL_SUPPORT
+    })
   }
 
   formValidated () {
index db38c7da9c3561e74f67488d8305bbff519db350..eda03374ad9a4d4d431ec8a6f34638cc1cdf3ca6 100644 (file)
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
 import { ActivatedRoute, Router } from '@angular/router'
 import { NotificationsService } from 'angular2-notifications'
 import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { VideoChannelUpdate } from '../../../../../shared/models/videos'
 import {
   VIDEO_CHANNEL_DESCRIPTION,
@@ -14,6 +13,7 @@ import { Subscription } from 'rxjs'
 import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
 import { AuthService } from '@app/core'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-account-video-channel-update',
@@ -23,45 +23,27 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy {
   error: string
 
-  form: FormGroup
-  formErrors = {
-    'display-name': '',
-    'description': '',
-    'support': ''
-  }
-  validationMessages = {
-    'display-name': VIDEO_CHANNEL_DISPLAY_NAME.MESSAGES,
-    'description': VIDEO_CHANNEL_DESCRIPTION.MESSAGES,
-    'support': VIDEO_CHANNEL_SUPPORT.MESSAGES
-  }
-
   private videoChannelToUpdate: VideoChannel
   private paramsSub: Subscription
 
   constructor (
+    protected formValidatorService: FormValidatorService,
     private authService: AuthService,
     private notificationsService: NotificationsService,
     private router: Router,
     private route: ActivatedRoute,
-    private formBuilder: FormBuilder,
     private videoChannelService: VideoChannelService,
     private i18n: I18n
   ) {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      'display-name': [ '', VIDEO_CHANNEL_DISPLAY_NAME.VALIDATORS ],
-      description: [ '', VIDEO_CHANNEL_DESCRIPTION.VALIDATORS ],
-      support: [ '', VIDEO_CHANNEL_SUPPORT.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      'display-name': VIDEO_CHANNEL_DISPLAY_NAME,
+      description: VIDEO_CHANNEL_DESCRIPTION,
+      support: VIDEO_CHANNEL_SUPPORT
+    })
 
     this.paramsSub = this.route.params.subscribe(routeParams => {
       const videoChannelId = routeParams['videoChannelId']
index a14cb2eb7243e81fc9ba8ba03dc50cd38c29efc6..f7aad06e89075a56283dc492d46ace00f70793d7 100644 (file)
@@ -1,6 +1,4 @@
 import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
-import { FormBuilder, FormGroup, Validators } from '@angular/forms'
-import { Router } from '@angular/router'
 import { RedirectService, ServerService } from '@app/core'
 import { UserService } from '@app/shared'
 import { NotificationsService } from 'angular2-notifications'
@@ -8,6 +6,8 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
 import { AuthService } from '../core'
 import { FormReactive } from '../shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
+import { LOGIN_PASSWORD, LOGIN_USERNAME } from '@app/shared/forms/form-validators/login'
 
 @Component({
   selector: 'my-login',
@@ -20,29 +20,15 @@ export class LoginComponent extends FormReactive implements OnInit {
   @ViewChild('forgotPasswordEmailInput') forgotPasswordEmailInput: ElementRef
 
   error: string = null
-
-  form: FormGroup
-  formErrors = {
-    'username': '',
-    'password': ''
-  }
-  validationMessages = {
-    'username': {
-      'required': 'Username is required.'
-    },
-    'password': {
-      'required': 'Password is required.'
-    }
-  }
   forgotPasswordEmail = ''
 
   constructor (
+    protected formValidatorService: FormValidatorService,
     private authService: AuthService,
     private userService: UserService,
     private serverService: ServerService,
     private redirectService: RedirectService,
     private notificationsService: NotificationsService,
-    private formBuilder: FormBuilder,
     private i18n: I18n
   ) {
     super()
@@ -52,17 +38,11 @@ export class LoginComponent extends FormReactive implements OnInit {
     return this.serverService.getConfig().signup.allowed === true
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      username: [ '', Validators.required ],
-      password: [ '', Validators.required ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      username: LOGIN_USERNAME,
+      password: LOGIN_PASSWORD
+    })
   }
 
   login () {
index c8bd368c19df09e2928f9fd5507cbd5f91915ed5..58e086f4548a4f3f8c0d21574eca1d6364146810 100644 (file)
@@ -1,11 +1,12 @@
 import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup, Validators } from '@angular/forms'
 import { ActivatedRoute, Router } from '@angular/router'
 import { USER_PASSWORD, UserService } from '@app/shared'
 import { NotificationsService } from 'angular2-notifications'
 import { AuthService } from '../core'
 import { FormReactive } from '../shared'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { RESET_PASSWORD_CONFIRM } from '@app/shared/forms/form-validators/reset-password'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-login',
@@ -14,26 +15,14 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
 })
 
 export class ResetPasswordComponent extends FormReactive implements OnInit {
-  form: FormGroup
-  formErrors = {
-    'password': '',
-    'password-confirm': ''
-  }
-  validationMessages = {
-    'password': USER_PASSWORD.MESSAGES,
-    'password-confirm': {
-      'required': 'Confirmation of the password is required.'
-    }
-  }
-
   private userId: number
   private verificationString: string
 
   constructor (
+    protected formValidatorService: FormValidatorService,
     private authService: AuthService,
     private userService: UserService,
     private notificationsService: NotificationsService,
-    private formBuilder: FormBuilder,
     private router: Router,
     private route: ActivatedRoute,
     private i18n: I18n
@@ -41,17 +30,11 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      password: [ '', USER_PASSWORD.VALIDATORS ],
-      'password-confirm': [ '', Validators.required ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      password: USER_PASSWORD,
+      'password-confirm': RESET_PASSWORD_CONFIRM
+    })
 
     this.userId = this.route.snapshot.queryParams['userId']
     this.verificationString = this.route.snapshot.queryParams['verificationString']
index e7764d0695d1fe197e500f298c54159d7d6c7343..441ec8203688830ed891f6b1f0ffeef1268d43c4 100644 (file)
@@ -1,40 +1,48 @@
 import { FormGroup } from '@angular/forms'
+import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
+
+export type FormReactiveErrors = { [ id: string ]: string }
+export type FormReactiveValidationMessages = {
+  [ id: string ]: {
+    [ name: string ]: string
+  }
+}
 
 export abstract class FormReactive {
-  abstract form: FormGroup
-  abstract formErrors: Object
-  abstract validationMessages: Object
+  protected abstract formValidatorService: FormValidatorService
 
-  abstract buildForm (): void
+  form: FormGroup
+  formErrors: FormReactiveErrors
+  validationMessages: FormReactiveValidationMessages
 
-  protected onValueChanged (data?: any) {
-    for (const field in this.formErrors) {
-      // clear previous error message (if any)
-      this.formErrors[field] = ''
-      const control = this.form.get(field)
+  buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
+    const { formErrors, validationMessages, form } = this.formValidatorService.buildForm(obj, defaultValues)
 
-      if (control && control.dirty && !control.valid) {
-        const messages = this.validationMessages[field]
-        for (const key in control.errors) {
-          this.formErrors[field] += messages[key] + ' '
-        }
-      }
-    }
+    this.form = form
+    this.formErrors = formErrors
+    this.validationMessages = validationMessages
+
+    this.form.valueChanges.subscribe(data => this.onValueChanged(false))
   }
 
-  // Same as onValueChanged but force checking even if the field is not dirty
-  protected forceCheck () {
+  protected onValueChanged (forceCheck = false) {
     for (const field in this.formErrors) {
       // clear previous error message (if any)
-      this.formErrors[field] = ''
+      this.formErrors[ field ] = ''
       const control = this.form.get(field)
 
-      if (control && !control.valid) {
-        const messages = this.validationMessages[field]
+      // Don't care if dirty on force check
+      const isDirty = control.dirty || forceCheck === true
+      if (control && isDirty && !control.valid) {
+        const messages = this.validationMessages[ field ]
         for (const key in control.errors) {
-          this.formErrors[field] += messages[key] + ' '
+          this.formErrors[ field ] += messages[ key ] + ' '
         }
       }
     }
   }
+
+  protected forceCheck () {
+    return this.onValueChanged(true)
+  }
 }
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 (file)
index 0000000..5c3d3e4
--- /dev/null
@@ -0,0 +1,65 @@
+import { FormBuilder, FormControl, FormGroup, ValidatorFn } from '@angular/forms'
+import { Injectable } from '@angular/core'
+import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared/forms/form-reactive'
+import { I18n } from '@ngx-translate/i18n-polyfill'
+
+export type BuildFormArgument = {
+  [ id: string ]: {
+    VALIDATORS: ValidatorFn[],
+    MESSAGES: { [ name: string ]: string }
+  }
+}
+export type BuildFormDefaultValues = {
+  [ name: string ]: string | string[]
+}
+
+@Injectable()
+export class FormValidatorService {
+
+  constructor (
+    private formBuilder: FormBuilder,
+    private i18n: I18n
+  ) {}
+
+  buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
+    const formErrors: FormReactiveErrors = {}
+    const validationMessages: FormReactiveValidationMessages = {}
+    const group: { [key: string]: any } = {}
+
+    for (const name of Object.keys(obj)) {
+      formErrors[name] = ''
+
+      const field = obj[name]
+      if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES
+
+      const defaultValue = defaultValues[name] || ''
+
+      if (field && field.VALIDATORS) group[name] = [ defaultValue, field.VALIDATORS ]
+      else group[name] = [ defaultValue ]
+    }
+
+    const form = this.formBuilder.group(group)
+    return { form, formErrors, validationMessages }
+  }
+
+  updateForm (
+    form: FormGroup,
+    formErrors: FormReactiveErrors,
+    validationMessages: FormReactiveValidationMessages,
+    obj: BuildFormArgument,
+    defaultValues: BuildFormDefaultValues = {}
+  ) {
+    for (const name of Object.keys(obj)) {
+      formErrors[name] = ''
+
+      const field = obj[name]
+      if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES
+
+      const defaultValue = defaultValues[name] || ''
+
+      if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS))
+      else form.addControl(name, new FormControl(defaultValue))
+    }
+  }
+
+}
index 09ae86f8af0ac8f75e26b5f022f62f15eb2bedbb..cf544b2a9b44ce5cfd7dcc48a57f0e1444bb43c4 100644 (file)
@@ -1,3 +1,4 @@
+export * from './form-validator.service'
 export * from './host'
 export * from './user'
 export * 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 (file)
index 0000000..f37f8d2
--- /dev/null
@@ -0,0 +1,18 @@
+import { Validators } from '@angular/forms'
+
+export const LOGIN_USERNAME = {
+  VALIDATORS: [
+    Validators.required
+  ],
+  MESSAGES: {
+    'required': 'Username is required.'
+  }
+}
+export const LOGIN_PASSWORD = {
+  VALIDATORS: [
+    Validators.required
+  ],
+  MESSAGES: {
+    'required': 'Password is required.'
+  }
+}
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 (file)
index 0000000..7dafdef
--- /dev/null
@@ -0,0 +1,10 @@
+import { Validators } from '@angular/forms'
+
+export const RESET_PASSWORD_CONFIRM = {
+  VALIDATORS: [
+    Validators.required
+  ],
+  MESSAGES: {
+    'required': 'Confirmation of the password is required.'
+  }
+}
index fba099401a02225682a227f0eb5fdb840e760696..91d905ec7120eaddce89d6721ddd2db2dd731199 100644 (file)
@@ -34,6 +34,7 @@ import { VideoService } from './video/video.service'
 import { AccountService } from '@app/shared/account/account.service'
 import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @NgModule({
   imports: [
@@ -110,6 +111,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
     AccountService,
     MarkdownService,
     VideoChannelService,
+    FormValidatorService,
     I18n
   ]
 })
index eaed2626d2f2395ac2138777331a54aa04393ba1..682e592c79704da19bad91dea1021c616ef724f2 100644 (file)
@@ -1,5 +1,4 @@
 import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { Router } from '@angular/router'
 import { ServerService } from '@app/core/server'
 
@@ -8,6 +7,7 @@ import { UserCreate } from '../../../../shared'
 import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared'
 import { RedirectService } from '@app/core'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-signup',
@@ -18,18 +18,6 @@ export class SignupComponent extends FormReactive implements OnInit {
   error: string = null
   quotaHelpIndication = ''
 
-  form: FormGroup
-  formErrors = {
-    'username': '',
-    'email': '',
-    'password': ''
-  }
-  validationMessages = {
-    'username': USER_USERNAME.MESSAGES,
-    'email': USER_EMAIL.MESSAGES,
-    'password': USER_PASSWORD.MESSAGES
-  }
-
   private static getApproximateTime (seconds: number) {
     const hours = Math.floor(seconds / 3600)
     let pluralSuffix = ''
@@ -43,7 +31,7 @@ export class SignupComponent extends FormReactive implements OnInit {
   }
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private router: Router,
     private notificationsService: NotificationsService,
     private userService: UserService,
@@ -58,18 +46,12 @@ export class SignupComponent extends FormReactive implements OnInit {
     return this.serverService.getConfig().user.videoQuota
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      username: [ '', USER_USERNAME.VALIDATORS ],
-      email:    [ '', USER_EMAIL.VALIDATORS ],
-      password: [ '', USER_PASSWORD.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      username: USER_USERNAME,
+      password: USER_PASSWORD,
+      email: USER_EMAIL
+    })
 
     this.serverService.configLoaded
       .subscribe(() => this.buildQuotaHelpIndication())
index ccfae5fcc00424a77900161ebf6836d169681695..cd2a26ae3067bfebf1c9eeb53d85222effcfa6c0 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, Input, OnInit } from '@angular/core'
-import { FormBuilder, FormControl, FormGroup } from '@angular/forms'
+import { FormGroup } from '@angular/forms'
 import { ActivatedRoute, Router } from '@angular/router'
-import { VIDEO_IMAGE, VIDEO_SUPPORT } from '@app/shared'
+import { VIDEO_SUPPORT } from '@app/shared'
 import { NotificationsService } from 'angular2-notifications'
 import { ServerService } from '../../../core/server'
 import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators'
@@ -17,6 +17,7 @@ import {
 } from '../../../shared/forms/form-validators/video'
 import { VideoEdit } from '../../../shared/video/video-edit.model'
 import { map } from 'rxjs/operators'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-video-edit',
@@ -42,7 +43,7 @@ export class VideoEditComponent implements OnInit {
   error: string = null
 
   constructor (
-    private formBuilder: FormBuilder,
+    private formValidatorService: FormValidatorService,
     private route: ActivatedRoute,
     private router: Router,
     private notificationsService: NotificationsService,
@@ -50,41 +51,34 @@ export class VideoEditComponent implements OnInit {
   ) { }
 
   updateForm () {
-    this.formErrors['name'] = ''
-    this.formErrors['privacy'] = ''
-    this.formErrors['channelId'] = ''
-    this.formErrors['category'] = ''
-    this.formErrors['licence'] = ''
-    this.formErrors['language'] = ''
-    this.formErrors['description'] = ''
-    this.formErrors['thumbnailfile'] = ''
-    this.formErrors['previewfile'] = ''
-    this.formErrors['support'] = ''
-
-    this.validationMessages['name'] = VIDEO_NAME.MESSAGES
-    this.validationMessages['privacy'] = VIDEO_PRIVACY.MESSAGES
-    this.validationMessages['channelId'] = VIDEO_CHANNEL.MESSAGES
-    this.validationMessages['category'] = VIDEO_CATEGORY.MESSAGES
-    this.validationMessages['licence'] = VIDEO_LICENCE.MESSAGES
-    this.validationMessages['language'] = VIDEO_LANGUAGE.MESSAGES
-    this.validationMessages['description'] = VIDEO_DESCRIPTION.MESSAGES
-    this.validationMessages['thumbnailfile'] = VIDEO_IMAGE.MESSAGES
-    this.validationMessages['previewfile'] = VIDEO_IMAGE.MESSAGES
-    this.validationMessages['support'] = VIDEO_SUPPORT.MESSAGES
-
-    this.form.addControl('name', new FormControl('', VIDEO_NAME.VALIDATORS))
-    this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS))
-    this.form.addControl('channelId', new FormControl('', VIDEO_CHANNEL.VALIDATORS))
-    this.form.addControl('nsfw', new FormControl(false))
-    this.form.addControl('commentsEnabled', new FormControl(true))
-    this.form.addControl('category', new FormControl('', VIDEO_CATEGORY.VALIDATORS))
-    this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))
-    this.form.addControl('language', new FormControl('', VIDEO_LANGUAGE.VALIDATORS))
-    this.form.addControl('description', new FormControl('', VIDEO_DESCRIPTION.VALIDATORS))
-    this.form.addControl('tags', new FormControl([]))
-    this.form.addControl('thumbnailfile', new FormControl(''))
-    this.form.addControl('previewfile', new FormControl(''))
-    this.form.addControl('support', new FormControl('', VIDEO_SUPPORT.VALIDATORS))
+    const defaultValues = {
+      nsfw: 'false',
+      commentsEnabled: 'true',
+      tags: []
+    }
+    const obj = {
+      name: VIDEO_NAME,
+      privacy: VIDEO_PRIVACY,
+      channelId: VIDEO_CHANNEL,
+      nsfw: null,
+      commentsEnabled: null,
+      category: VIDEO_CATEGORY,
+      licence: VIDEO_LICENCE,
+      language: VIDEO_LANGUAGE,
+      description: VIDEO_DESCRIPTION,
+      tags: null,
+      thumbnailfile: null,
+      previewfile: null,
+      support: VIDEO_SUPPORT
+    }
+
+    this.formValidatorService.updateForm(
+      this.form,
+      this.formErrors,
+      this.validationMessages,
+      obj,
+      defaultValues
+    )
 
     // We will update the "support" field depending on the channel
     this.form.controls['channelId']
@@ -98,6 +92,7 @@ export class VideoEditComponent implements OnInit {
           // Not initialized yet
           if (isNaN(newChannelId)) return
           const newChannel = this.userVideoChannels.find(c => c.id === newChannelId)
+          if (!newChannel) return
 
           // First time we set the channel?
           if (isNaN(oldChannelId)) return this.updateSupportField(newChannel.support)
index a615fd92c3ecdf6ad0853be472c77bbd08cc2c4b..332f757d73cacddfe4e71f17a5a56f67e5e0056c 100644 (file)
@@ -1,6 +1,5 @@
 import { HttpEventType, HttpResponse } from '@angular/common/http'
 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { Router } from '@angular/router'
 import { UserService } from '@app/shared'
 import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
@@ -11,11 +10,11 @@ import { Subscription } from 'rxjs'
 import { VideoPrivacy } from '../../../../../shared/models/videos'
 import { AuthService, ServerService } from '../../core'
 import { FormReactive } from '../../shared'
-import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
 import { populateAsyncUserVideoChannels } from '../../shared/misc/utils'
 import { VideoEdit } from '../../shared/video/video-edit.model'
 import { VideoService } from '../../shared/video/video.service'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-videos-add',
@@ -39,10 +38,6 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
   }
   videoFileName: string
 
-  form: FormGroup
-  formErrors: { [ id: string ]: string } = {}
-  validationMessages: ValidatorMessage = {}
-
   userVideoChannels: { id: number, label: string, support: string }[] = []
   userVideoQuotaUsed = 0
   videoPrivacies = []
@@ -50,7 +45,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
   firstStepChannelId = 0
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private router: Router,
     private notificationsService: NotificationsService,
     private authService: AuthService,
@@ -67,13 +62,8 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
     return this.serverService.getConfig().video.file.extensions.join(',')
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({})
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({})
 
     populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
       .then(() => this.firstStepChannelId = this.userVideoChannels[0].id)
index e37dd526fc794f3186b80786ba0cfe30185c3304..0266164aff350ed3cd30f43d11a08950e076568b 100644 (file)
@@ -1,6 +1,5 @@
 import { map, switchMap } from 'rxjs/operators'
 import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { ActivatedRoute, Router } from '@angular/router'
 import { LoadingBarService } from '@ngx-loading-bar/core'
 import { NotificationsService } from 'angular2-notifications'
@@ -8,11 +7,11 @@ import { VideoPrivacy } from '../../../../../shared/models/videos'
 import { ServerService } from '../../core'
 import { AuthService } from '../../core/auth'
 import { FormReactive } from '../../shared'
-import { ValidatorMessage } from '../../shared/forms/form-validators/validator-message'
 import { VideoEdit } from '../../shared/video/video-edit.model'
 import { VideoService } from '../../shared/video/video.service'
 import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-videos-update',
@@ -23,14 +22,11 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
   video: VideoEdit
 
   isUpdatingVideo = false
-  form: FormGroup
-  formErrors: { [ id: string ]: string } = {}
-  validationMessages: ValidatorMessage = {}
   videoPrivacies = []
   userVideoChannels = []
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private route: ActivatedRoute,
     private router: Router,
     private notificationsService: NotificationsService,
@@ -44,13 +40,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({})
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({})
 
     this.serverService.videoPrivaciesLoaded
       .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies())
index 2ee5f5ef1e1b1c7d522452c13d60cdea47aa8220..c70e544a33417225619c4099afa088c55f59dcb3 100644 (file)
@@ -1,5 +1,4 @@
 import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
 import { NotificationsService } from 'angular2-notifications'
 import { Observable } from 'rxjs'
 import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
@@ -10,6 +9,7 @@ import { Video } from '../../../shared/video/video.model'
 import { VideoComment } from './video-comment.model'
 import { VideoCommentService } from './video-comment.service'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-video-comment-add',
@@ -25,18 +25,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
 
   @Output() commentCreated = new EventEmitter<VideoCommentCreate>()
 
-  form: FormGroup
-  formErrors = {
-    'text': ''
-  }
-  validationMessages = {
-    'text': VIDEO_COMMENT_TEXT.MESSAGES
-  }
-
   @ViewChild('textarea') private textareaElement: ElementRef
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private notificationsService: NotificationsService,
     private videoCommentService: VideoCommentService,
     private i18n: I18n
@@ -44,16 +36,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
     super()
   }
 
-  buildForm () {
-    this.form = this.formBuilder.group({
-      text: [ '', VIDEO_COMMENT_TEXT.VALIDATORS ]
-    })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
-  }
-
   ngOnInit () {
-    this.buildForm()
+    this.buildForm({
+      text: VIDEO_COMMENT_TEXT
+    })
 
     if (this.focusOnInit === true) {
       this.textareaElement.nativeElement.focus()
index 1bbd3022638c2a2d234faed134d0c0c764bd11ae..8641e8dfbff43e0aaa487f4044882ae5b3b20548 100644 (file)
@@ -5,6 +5,8 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
 import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index'
 import { VideoDetails } from '../../../shared/video/video-details.model'
 import { I18n } from '@ngx-translate/i18n-polyfill'
+import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared'
+import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
 
 @Component({
   selector: 'my-video-report',
@@ -17,16 +19,9 @@ export class VideoReportComponent extends FormReactive implements OnInit {
   @ViewChild('modal') modal: ModalDirective
 
   error: string = null
-  form: FormGroup
-  formErrors = {
-    reason: ''
-  }
-  validationMessages = {
-    reason: VIDEO_ABUSE_REASON.MESSAGES
-  }
 
   constructor (
-    private formBuilder: FormBuilder,
+    protected formValidatorService: FormValidatorService,
     private videoAbuseService: VideoAbuseService,
     private notificationsService: NotificationsService,
     private i18n: I18n
@@ -35,15 +30,9 @@ export class VideoReportComponent extends FormReactive implements OnInit {
   }
 
   ngOnInit () {
-    this.buildForm()
-  }
-
-  buildForm () {
-    this.form = this.formBuilder.group({
-      reason: [ '', VIDEO_ABUSE_REASON.VALIDATORS ]
+    this.buildForm({
+      reason: VIDEO_ABUSE_REASON
     })
-
-    this.form.valueChanges.subscribe(data => this.onValueChanged(data))
   }
 
   show () {