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',
{ 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,
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(
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'
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',
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,
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 () {
{ 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
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'
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',
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']
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',
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
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 () {
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',
})
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
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 () {
<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>
private i18n: I18n
) {}
+ get userInformationLoaded () {
+ return this.authService.userInformationLoaded
+ }
+
ngOnInit () {
this.user = this.authService.getUser()
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',
})
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
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 () {
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,
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',
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 () {
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,
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',
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']
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'
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',
@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()
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 () {
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',
})
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
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']
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)
+ }
}
--- /dev/null
+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))
+ }
+ }
+
+}
+export * from './form-validator.service'
export * from './host'
export * from './user'
export * from './video-abuse'
--- /dev/null
+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.'
+ }
+}
--- /dev/null
+import { Validators } from '@angular/forms'
+
+export const RESET_PASSWORD_CONFIRM = {
+ VALIDATORS: [
+ Validators.required
+ ],
+ MESSAGES: {
+ 'required': 'Confirmation of the password is required.'
+ }
+}
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: [
AccountService,
MarkdownService,
VideoChannelService,
+ FormValidatorService,
I18n
]
})
import { Component, OnInit } from '@angular/core'
-import { FormBuilder, FormGroup } from '@angular/forms'
import { Router } from '@angular/router'
import { ServerService } from '@app/core/server'
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',
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 = ''
}
constructor (
- private formBuilder: FormBuilder,
+ protected formValidatorService: FormValidatorService,
private router: Router,
private notificationsService: NotificationsService,
private userService: UserService,
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())
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'
} 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',
error: string = null
constructor (
- private formBuilder: FormBuilder,
+ private formValidatorService: FormValidatorService,
private route: ActivatedRoute,
private router: Router,
private notificationsService: NotificationsService,
) { }
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']
// 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)
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'
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',
}
videoFileName: string
- form: FormGroup
- formErrors: { [ id: string ]: string } = {}
- validationMessages: ValidatorMessage = {}
-
userVideoChannels: { id: number, label: string, support: string }[] = []
userVideoQuotaUsed = 0
videoPrivacies = []
firstStepChannelId = 0
constructor (
- private formBuilder: FormBuilder,
+ protected formValidatorService: FormValidatorService,
private router: Router,
private notificationsService: NotificationsService,
private authService: AuthService,
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)
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'
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',
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,
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())
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'
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',
@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
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()
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',
@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
}
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 () {