Form validators refractoring

pull/619/head
Chocobozzz 2018-06-05 10:58:45 +02:00
parent 25acef90a8
commit d18d64787b
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
25 changed files with 312 additions and 432 deletions

View 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(

View 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 () {

View 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

View 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']

View 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 () {

View 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 () {

View 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>
@ -22,11 +22,11 @@
<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>

View 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()

View 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 () {

View 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 () {

View 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']

View 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 () {

View 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']

View File

@ -1,40 +1,48 @@
import { FormGroup } from '@angular/forms'
import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
export abstract class FormReactive {
abstract form: FormGroup
abstract formErrors: Object
abstract validationMessages: Object
abstract buildForm (): void
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)
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field]
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' '
}
}
}
}
// Same as onValueChanged but force checking even if the field is not dirty
protected forceCheck () {
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = ''
const control = this.form.get(field)
if (control && !control.valid) {
const messages = this.validationMessages[field]
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' '
}
}
}
export type FormReactiveErrors = { [ id: string ]: string }
export type FormReactiveValidationMessages = {
[ id: string ]: {
[ name: string ]: string
}
}
export abstract class FormReactive {
protected abstract formValidatorService: FormValidatorService
form: FormGroup
formErrors: FormReactiveErrors
validationMessages: FormReactiveValidationMessages
buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
const { formErrors, validationMessages, form } = this.formValidatorService.buildForm(obj, defaultValues)
this.form = form
this.formErrors = formErrors
this.validationMessages = validationMessages
this.form.valueChanges.subscribe(data => this.onValueChanged(false))
}
protected onValueChanged (forceCheck = false) {
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[ field ] = ''
const control = this.form.get(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 ] + ' '
}
}
}
}
protected forceCheck () {
return this.onValueChanged(true)
}
}

View File

@ -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))
}
}
}

View File

@ -1,3 +1,4 @@
export * from './form-validator.service'
export * from './host'
export * from './user'
export * from './video-abuse'

View File

@ -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.'
}
}

View File

@ -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.'
}
}

View 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
]
})

View 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())

View 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'] = ''
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.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))
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)

View 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)

View 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())

View 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()

View 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 () {