diff --git a/src/app/configuration/configuration.component.ts b/src/app/configuration/configuration.component.ts index e67de40b4f..76d396442b 100644 --- a/src/app/configuration/configuration.component.ts +++ b/src/app/configuration/configuration.component.ts @@ -1,5 +1,12 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { + AbstractControl, + AsyncValidatorFn, + FormControl, + FormGroup, + NonNullableFormBuilder, + Validators +} from '@angular/forms'; import { Router, ActivatedRoute } from '@angular/router'; import { MatStepper } from '@angular/material/stepper'; import { finalize } from 'rxjs/operators'; @@ -20,6 +27,36 @@ const removeProtocol = (str: string) => { return /\/\/(.*?)$/.exec(str)[1]; }; +type LoginFormControls = { + name: FormControl; + password: FormControl; + confirmPassword: FormControl; +}; + +type DatePlaceholder = CouchService['datePlaceholder']; + +type ConfigurationFormControls = { + planetType: FormControl; + localDomain: FormControl; + name: FormControl; + parentDomain: FormControl; + parentCode: FormControl; + preferredLang: FormControl; + code: FormControl; + createdDate: FormControl; + autoAccept: FormControl; + alwaysOnline: FormControl; + betaEnabled: FormControl; +}; + +type ContactFormControls = { + firstName: FormControl; + lastName: FormControl; + middleName: FormControl; + email: FormControl; + phoneNumber: FormControl; +}; + @Component({ selector: 'planet-configuration', templateUrl: './configuration.component.html', @@ -41,9 +78,9 @@ export class ConfigurationComponent implements OnInit { configurationType = 'new'; nationOrCommunity = 'community'; message = ''; - loginForm: UntypedFormGroup; - configurationFormGroup: UntypedFormGroup; - contactFormGroup: UntypedFormGroup; + loginForm: FormGroup; + configurationFormGroup: FormGroup; + contactFormGroup: FormGroup; nations = []; showAdvancedOptions = false; isAdvancedOptionsChanged = false; @@ -54,7 +91,7 @@ export class ConfigurationComponent implements OnInit { languageNames = languages.map(list => list.name); constructor( - private formBuilder: UntypedFormBuilder, + private formBuilder: NonNullableFormBuilder, private couchService: CouchService, private planetMessageService: PlanetMessageService, private validatorService: ValidatorService, @@ -69,60 +106,58 @@ export class ConfigurationComponent implements OnInit { this.initUpdate(); } this.loginForm = this.formBuilder.group({ - name: [ '', [ - Validators.required, - CustomValidators.pattern(/^([^\x00-\x7F]|[A-Za-z0-9])/i, 'invalidFirstCharacter'), - Validators.pattern(/^([^\x00-\x7F]|[A-Za-z0-9_.-])*$/i) ] - ], - password: [ - '', - Validators.compose([ + name: this.formBuilder.control('', { + validators: [ + Validators.required, + CustomValidators.pattern(/^([^\x00-\x7F]|[A-Za-z0-9])/i, 'invalidFirstCharacter'), + Validators.pattern(/^([^\x00-\x7F]|[A-Za-z0-9_.-])*$/i) + ] + }), + password: this.formBuilder.control('', { + validators: Validators.compose([ Validators.required, CustomValidators.matchPassword('confirmPassword', false) - ]) - ], - confirmPassword: [ - '', - Validators.compose([ + ]) || [] + }), + confirmPassword: this.formBuilder.control('', { + validators: Validators.compose([ Validators.required, CustomValidators.matchPassword('password', true) - ]) - ] - }); - this.configurationFormGroup = this.formBuilder.group({ - planetType: [ '', Validators.required ], - localDomain: this.defaultLocal, - name: [ - '', - [ Validators.required, - Validators.pattern(/^[A-Za-z0-9]/i) ], - this.parentUniqueValidator('name') - ], - parentDomain: [ '', Validators.required ], - parentCode: [ '', Validators.required ], - preferredLang: [ '', Validators.required ], - code: [ - '', - Validators.required, - this.parentUniqueValidator('code') - ], - createdDate: this.couchService.datePlaceholder, - autoAccept: true, - alwaysOnline: false, - betaEnabled: 'off' + ]) || [] + }) }); + const configurationControls = { + planetType: this.formBuilder.control('', { validators: Validators.required }), + localDomain: this.formBuilder.control(this.defaultLocal), + name: this.formBuilder.control('', { + validators: [ Validators.required, Validators.pattern(/^[A-Za-z0-9]/i) ], + asyncValidators: this.parentUniqueValidator('name') + }), + parentDomain: this.formBuilder.control('', { validators: Validators.required }), + parentCode: this.formBuilder.control('', { validators: Validators.required }), + preferredLang: this.formBuilder.control('', { validators: Validators.required }), + code: this.formBuilder.control('', { + validators: Validators.required, + asyncValidators: this.parentUniqueValidator('code') + }), + createdDate: this.formBuilder.control(this.couchService.datePlaceholder), + autoAccept: this.formBuilder.control(true), + alwaysOnline: this.formBuilder.control(false), + betaEnabled: this.formBuilder.control('off') + } satisfies ConfigurationFormControls; + + this.configurationFormGroup = this.formBuilder.group(configurationControls); this.contactFormGroup = this.formBuilder.group({ - firstName: [ '', CustomValidators.required ], - lastName: [ '', CustomValidators.required ], - middleName: [ '' ], - email: [ - '', - Validators.compose([ + firstName: this.formBuilder.control('', { validators: CustomValidators.required }), + lastName: this.formBuilder.control('', { validators: CustomValidators.required }), + middleName: this.formBuilder.control(''), + email: this.formBuilder.control('', { + validators: Validators.compose([ Validators.required, Validators.email - ]) - ], - phoneNumber: [ '', CustomValidators.required ] + ]) || [] + }), + phoneNumber: this.formBuilder.control('', { validators: CustomValidators.required }) }); this.getNationList(); } @@ -141,15 +176,16 @@ export class ConfigurationComponent implements OnInit { } ); } - parentUniqueValidator(controlName: string) { - return ac => { + parentUniqueValidator(controlName: 'name' | 'code'): AsyncValidatorFn { + return (ac: AbstractControl) => { + const parentDomainControl = ac.parent?.get('parentDomain') as AbstractControl | null; return this.validatorService.isUnique$( 'communityregistrationrequests', controlName, ac, { exceptions: [ this.configuration[controlName] ], - opts: { domain: ac.parent.get('parentDomain').value } + opts: { domain: parentDomainControl?.value } } ); }; @@ -163,8 +199,9 @@ export class ConfigurationComponent implements OnInit { } } - localDomainChange(event) { - this.isAdvancedOptionsChanged = (this.defaultLocal !== event.target.value); + localDomainChange(event: Event) { + const target = event.target as HTMLInputElement; + this.isAdvancedOptionsChanged = (this.defaultLocal !== target.value); } resetDefault() { @@ -173,14 +210,19 @@ export class ConfigurationComponent implements OnInit { this.configurationFormGroup.get('localDomain').setValue(this.defaultLocal); } - planetNameChange(event) { + planetNameChange(event: Event) { + event.preventDefault(); if (this.configurationType !== 'update') { - let code = this.configurationFormGroup.get('name').value; + const nameControl = this.configurationFormGroup.get('name'); + if (!nameControl) { + return; + } + let code = nameControl.value; // convert special character to dot except last character code = code.replace(/\W+(?!$)/g, '.').toLowerCase(); // skip special character if comes as last character code = code.replace(/\W+$/, '').toLowerCase(); - this.configurationFormGroup.get('code').setValue(code); + this.configurationFormGroup.get('code')?.setValue(code); } } @@ -211,9 +253,10 @@ export class ConfigurationComponent implements OnInit { } onChangeNation() { - const parentCode = this.nations.find(n => n.localDomain === this.configurationFormGroup.get('parentDomain').value); - this.configurationFormGroup.get('parentCode').setValue(parentCode.code); - if (this.configurationFormGroup.get('name').value !== '') { + const parentDomain = this.configurationFormGroup.get('parentDomain')?.value; + const parentCode = this.nations.find(n => n.localDomain === parentDomain); + this.configurationFormGroup.get('parentCode')?.setValue(parentCode?.code ?? ''); + if (this.configurationFormGroup.get('name')?.value !== '') { this.configurationFormGroup.controls.name.updateValueAndValidity(); this.configurationFormGroup.controls.code.updateValueAndValidity(); }