From 0245f2ea9fc383e0c34f11d74a7ae2cbba09dcb1 Mon Sep 17 00:00:00 2001 From: "max.kless@googlemail.com" Date: Wed, 24 Mar 2021 17:11:21 +0100 Subject: [PATCH] feat: disabled prefilled fields --- ...ration-form-configuration.service.spec.ts} | 21 ++++----- ...egistration-form-configuration.service.ts} | 35 ++++++++++----- .../formly/disable-prefilled.extension.ts | 24 +++++++++++ .../registration-page.component.html | 5 +-- .../registration-page.component.spec.ts | 15 ++++--- .../registration-page.component.ts | 43 +++++++++---------- .../registration/registration-page.module.ts | 6 +-- 7 files changed, 94 insertions(+), 55 deletions(-) rename src/app/{pages/registration/registration-configuration/registration-configuration.service.spec.ts => core/services/registration-form-configuration/registration-form-configuration.service.spec.ts} (86%) rename src/app/{pages/registration/registration-configuration/registration-configuration.service.ts => core/services/registration-form-configuration/registration-form-configuration.service.ts} (91%) create mode 100644 src/app/pages/registration/formly/disable-prefilled.extension.ts diff --git a/src/app/pages/registration/registration-configuration/registration-configuration.service.spec.ts b/src/app/core/services/registration-form-configuration/registration-form-configuration.service.spec.ts similarity index 86% rename from src/app/pages/registration/registration-configuration/registration-configuration.service.spec.ts rename to src/app/core/services/registration-form-configuration/registration-form-configuration.service.spec.ts index 2ec517ff83..74c1ebab72 100644 --- a/src/app/pages/registration/registration-configuration/registration-configuration.service.spec.ts +++ b/src/app/core/services/registration-form-configuration/registration-form-configuration.service.spec.ts @@ -7,12 +7,13 @@ import { instance, mock } from 'ts-mockito'; import { AccountFacade } from 'ish-core/facades/account.facade'; import { extractKeys } from 'ish-shared/formly/dev/testing/formly-testing-utils'; -import { RegistrationConfigType } from '../registration-page.component'; +import { + RegistrationConfigType, + RegistrationFormConfigurationService, +} from './registration-form-configuration.service'; -import { RegistrationConfigurationService } from './registration-configuration.service'; - -describe('Registration Configuration Service', () => { - let registrationConfigurationService: RegistrationConfigurationService; +describe('Registration Form Configuration Service', () => { + let registrationConfigurationService: RegistrationFormConfigurationService; let accountFacade: AccountFacade; beforeEach(() => { @@ -23,17 +24,17 @@ describe('Registration Configuration Service', () => { { provide: Router, useFactory: () => instance(mock(Router)) }, { provide: Store, useFactory: () => instance(mock(Store)) }, { provide: AccountFacade, useFactory: () => instance(accountFacade) }, - RegistrationConfigurationService, + RegistrationFormConfigurationService, ], }); - registrationConfigurationService = TestBed.inject(RegistrationConfigurationService); + registrationConfigurationService = TestBed.inject(RegistrationFormConfigurationService); }); describe('with sso', () => { const registrationConfig: RegistrationConfigType = { businessCustomer: true, sso: true, userId: 'uid' }; it('should return right fields when calling getRegistrationConfig', () => { - const fieldConfig = registrationConfigurationService.getRegistrationConfiguration(registrationConfig); + const fieldConfig = registrationConfigurationService.getRegistrationFormConfiguration(registrationConfig); expect(extractKeys(fieldConfig)).toMatchInlineSnapshot(` Array [ Array [ @@ -59,7 +60,7 @@ describe('Registration Configuration Service', () => { const registrationConfig: RegistrationConfigType = { businessCustomer: true, sso: false }; it('should return the right fields when calling getRegistrationConfig', () => { - const fieldConfig = registrationConfigurationService.getRegistrationConfiguration(registrationConfig); + const fieldConfig = registrationConfigurationService.getRegistrationFormConfiguration(registrationConfig); expect(extractKeys(fieldConfig)).toMatchInlineSnapshot(` Array [ Array [ @@ -89,7 +90,7 @@ describe('Registration Configuration Service', () => { const registrationConfig: RegistrationConfigType = { businessCustomer: false, sso: false }; it('should return the right fields when calling getRegistrationConfig', () => { - const fieldConfig = registrationConfigurationService.getRegistrationConfiguration(registrationConfig); + const fieldConfig = registrationConfigurationService.getRegistrationFormConfiguration(registrationConfig); expect(extractKeys(fieldConfig)).toMatchInlineSnapshot(` Array [ Array [ diff --git a/src/app/pages/registration/registration-configuration/registration-configuration.service.ts b/src/app/core/services/registration-form-configuration/registration-form-configuration.service.ts similarity index 91% rename from src/app/pages/registration/registration-configuration/registration-configuration.service.ts rename to src/app/core/services/registration-form-configuration/registration-form-configuration.service.ts index 58229dc133..0459eed1dd 100644 --- a/src/app/pages/registration/registration-configuration/registration-configuration.service.ts +++ b/src/app/core/services/registration-form-configuration/registration-form-configuration.service.ts @@ -1,10 +1,8 @@ -// tslint:disable: project-structure -// tslint:disable-next-line: ish-ordered-imports import { Injectable } from '@angular/core'; import { FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; -import { FormlyFieldConfig } from '@ngx-formly/core'; +import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core'; import { UUID } from 'angular2-uuid'; import { AccountFacade } from 'ish-core/facades/account.facade'; @@ -14,13 +12,19 @@ import { Customer, CustomerRegistrationType } from 'ish-core/models/customer/cus import { User } from 'ish-core/models/user/user.model'; import { cancelRegistration, setRegistrationInfo } from 'ish-core/store/customer/sso-registration'; import { SpecialValidators } from 'ish-shared/forms/validators/special-validators'; -import { RegistrationConfiguration, RegistrationConfigType } from '../registration-page.component'; -@Injectable() -export class RegistrationConfigurationService implements RegistrationConfiguration { +export interface RegistrationConfigType { + businessCustomer?: boolean; + sso?: boolean; + userId?: string; +} + +@Injectable({ providedIn: 'root' }) +export class RegistrationFormConfigurationService { + // tslint:disable: no-intelligence-in-artifacts constructor(private accountFacade: AccountFacade, private store: Store, private router: Router) {} - getRegistrationConfiguration(registrationConfig: RegistrationConfigType) { + getRegistrationFormConfiguration(registrationConfig: RegistrationConfigType) { return [ { type: 'ish-registration-heading-field', @@ -76,8 +80,19 @@ export class RegistrationConfigurationService implements RegistrationConfigurati ]; } - submitRegistration(form: FormGroup, registrationConfig: RegistrationConfigType) { - const formValue = form.value; + getRegistrationFormConfigurationOptions( + registrationConfig: RegistrationConfigType, + model: Record + ): FormlyFormOptions { + if (registrationConfig.sso) { + return { formState: { disabled: Object.keys(model) } }; + } else { + return {}; + } + } + + submitRegistrationForm(form: FormGroup, registrationConfig: RegistrationConfigType, model?: Record) { + const formValue = { ...form.value, ...model }; const address: Address = { firstName: formValue.firstName, @@ -134,7 +149,7 @@ export class RegistrationConfigurationService implements RegistrationConfigurati } } - cancelRegistration(config: RegistrationConfigType): void { + cancelRegistrationForm(config: RegistrationConfigType): void { config.sso ? this.store.dispatch(cancelRegistration()) : this.router.navigate(['/home']); } diff --git a/src/app/pages/registration/formly/disable-prefilled.extension.ts b/src/app/pages/registration/formly/disable-prefilled.extension.ts new file mode 100644 index 0000000000..ad07f19a52 --- /dev/null +++ b/src/app/pages/registration/formly/disable-prefilled.extension.ts @@ -0,0 +1,24 @@ +import { FormlyExtension, FormlyFieldConfig } from '@ngx-formly/core'; + +/** + * This extension disables all fields that have keys that match those + * specified in the formstate.disabled property + */ +type FieldConfigWithDisabled = Omit & { options: { formState: { disabled: string[] } } }; + +export const disablePrefilledExtension: FormlyExtension = { + prePopulate: field => { + if (hasDisabled(field) && field.key) { + field.templateOptions = { ...field.templateOptions }; + field.templateOptions.disabled = field.options.formState.disabled.includes(field.key as string); + } + }, +}; + +function hasDisabled(field: FormlyFieldConfig): field is FieldConfigWithDisabled { + return ( + Array.isArray(field.options?.formState?.disabled) && + // tslint:disable-next-line: no-any + (field.options.formState.disabled as any[]).reduce((acc, val) => acc && typeof val === 'string', true) + ); +} diff --git a/src/app/pages/registration/registration-page.component.html b/src/app/pages/registration/registration-page.component.html index b06d873834..44c89932c3 100644 --- a/src/app/pages/registration/registration-page.component.html +++ b/src/app/pages/registration/registration-page.component.html @@ -1,15 +1,14 @@
- - +
diff --git a/src/app/pages/registration/registration-page.component.spec.ts b/src/app/pages/registration/registration-page.component.spec.ts index 5cb9be5432..c6af5aff39 100644 --- a/src/app/pages/registration/registration-page.component.spec.ts +++ b/src/app/pages/registration/registration-page.component.spec.ts @@ -9,17 +9,18 @@ import { anyString, anything, instance, mock, verify, when } from 'ts-mockito'; import { AccountFacade } from 'ish-core/facades/account.facade'; import { FeatureToggleService } from 'ish-core/feature-toggle.module'; +import { RegistrationFormConfigurationService } from 'ish-core/services/registration-form-configuration/registration-form-configuration.service'; import { ErrorMessageComponent } from 'ish-shared/components/common/error-message/error-message.component'; import { FormlyTestingModule } from 'ish-shared/formly/dev/testing/formly-testing.module'; -import { RegistrationConfigurationService } from './registration-configuration/registration-configuration.service'; -import { REGISTRATION_CONFIGURATION, RegistrationPageComponent } from './registration-page.component'; +import { RegistrationPageComponent } from './registration-page.component'; +// tslint:disable:no-intelligence-in-artifacts describe('Registration Page Component', () => { let fixture: ComponentFixture; let component: RegistrationPageComponent; let element: HTMLElement; - let configService: RegistrationConfigurationService; + let configService: RegistrationFormConfigurationService; let featureToggleService: FeatureToggleService; let activatedRoute: ActivatedRoute; let accountFacade: AccountFacade; @@ -28,7 +29,7 @@ describe('Registration Page Component', () => { class DummyComponent {} beforeEach(async () => { - configService = mock(RegistrationConfigurationService); + configService = mock(RegistrationFormConfigurationService); featureToggleService = mock(FeatureToggleService); activatedRoute = mock(ActivatedRoute); accountFacade = mock(AccountFacade); @@ -43,12 +44,12 @@ describe('Registration Page Component', () => { { provide: AccountFacade, useFactory: () => instance(accountFacade) }, { provide: FeatureToggleService, useFactory: () => instance(featureToggleService) }, { provide: ActivatedRoute, useFactory: () => instance(activatedRoute) }, - { provide: REGISTRATION_CONFIGURATION, useFactory: () => instance(configService) }, + { provide: RegistrationFormConfigurationService, useFactory: () => instance(configService) }, ], }).compileComponents(); when(featureToggleService.enabled(anyString())).thenReturn(false); - when(configService.getRegistrationConfiguration(anything())).thenReturn([ + when(configService.getRegistrationFormConfiguration(anything())).thenReturn([ { key: 'test', type: 'ish-text-input-field', @@ -117,6 +118,6 @@ describe('Registration Page Component', () => { tick(500); - verify(configService.cancelRegistration(anything())).once(); + verify(configService.cancelRegistrationForm(anything())).once(); })); }); diff --git a/src/app/pages/registration/registration-page.component.ts b/src/app/pages/registration/registration-page.component.ts index e52ab0a519..883b562d4e 100644 --- a/src/app/pages/registration/registration-page.component.ts +++ b/src/app/pages/registration/registration-page.component.ts @@ -1,28 +1,19 @@ -import { ChangeDetectionStrategy, Component, Inject, InjectionToken, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { ActivatedRoute, ParamMap } from '@angular/router'; -import { FormlyFieldConfig } from '@ngx-formly/core'; +import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core'; import { Observable, merge } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { AccountFacade } from 'ish-core/facades/account.facade'; import { FeatureToggleService } from 'ish-core/feature-toggle.module'; import { HttpError } from 'ish-core/models/http-error/http-error.model'; +import { + RegistrationConfigType, + RegistrationFormConfigurationService, +} from 'ish-core/services/registration-form-configuration/registration-form-configuration.service'; -export const REGISTRATION_CONFIGURATION = new InjectionToken('registrationConfiguration'); - -export interface RegistrationConfiguration { - getRegistrationConfiguration(registrationConfig: RegistrationConfigType): FormlyFieldConfig[]; - submitRegistration(form: FormGroup, registrationConfig: RegistrationConfigType): void; - cancelRegistration(config: RegistrationConfigType): void; -} - -export interface RegistrationConfigType { - businessCustomer?: boolean; - sso?: boolean; - userId?: string; -} - +// tslint:disable:no-intelligence-in-artifacts /** * The Registration Page Container renders the customer registration form using the {@link RegistrationFormComponent} * @@ -38,7 +29,7 @@ export class RegistrationPageComponent implements OnInit { private accountFacade: AccountFacade, private route: ActivatedRoute, private featureToggle: FeatureToggleService, - @Inject(REGISTRATION_CONFIGURATION) private registrationConfigurationProvider: RegistrationConfiguration + private registrationFormConfiguration: RegistrationFormConfigurationService ) {} submitted = false; @@ -46,7 +37,8 @@ export class RegistrationPageComponent implements OnInit { registrationConfig: RegistrationConfigType; fields$: Observable; - model: { [key: string]: unknown }; + model: Record; + options: FormlyFormOptions; form = new FormGroup({}); ngOnInit() { @@ -59,12 +51,19 @@ export class RegistrationPageComponent implements OnInit { businessCustomer: this.featureToggle.enabled('businessCustomerRegistration'), })), tap(config => (this.registrationConfig = config)), - map(config => this.registrationConfigurationProvider.getRegistrationConfiguration(config)) + tap( + config => + (this.options = this.registrationFormConfiguration.getRegistrationFormConfigurationOptions( + config, + this.model + )) + ), + map(config => this.registrationFormConfiguration.getRegistrationFormConfiguration(config)) ); } cancelForm() { - this.registrationConfigurationProvider.cancelRegistration(this.registrationConfig); + this.registrationFormConfiguration.cancelRegistrationForm(this.registrationConfig); } onCreate() { @@ -72,11 +71,11 @@ export class RegistrationPageComponent implements OnInit { this.submitted = true; return; } - this.registrationConfigurationProvider.submitRegistration(this.form, this.registrationConfig); + this.registrationFormConfiguration.submitRegistrationForm(this.form, this.registrationConfig, this.model); } /** return boolean to set submit button enabled/disabled */ - get formDisabled(): boolean { + get submitDisabled(): boolean { return this.form.invalid && this.submitted; } diff --git a/src/app/pages/registration/registration-page.module.ts b/src/app/pages/registration/registration-page.module.ts index 1d08d1ed44..8ab2d186f2 100644 --- a/src/app/pages/registration/registration-page.module.ts +++ b/src/app/pages/registration/registration-page.module.ts @@ -4,11 +4,11 @@ import { ConfigOption, FormlyModule } from '@ngx-formly/core'; import { SharedModule } from 'ish-shared/shared.module'; +import { disablePrefilledExtension } from './formly/disable-prefilled.extension'; import { RegistrationAddressFieldComponent } from './formly/registration-address-field/registration-address-field.component'; import { RegistrationHeadingFieldComponent } from './formly/registration-heading-field/registration-heading-field.component'; import { RegistrationTacFieldComponent } from './formly/registration-tac-field/registration-tac-field.component'; -import { RegistrationConfigurationService } from './registration-configuration/registration-configuration.service'; -import { REGISTRATION_CONFIGURATION, RegistrationPageComponent } from './registration-page.component'; +import { RegistrationPageComponent } from './registration-page.component'; const registrationPageRoutes: Routes = [{ path: '', component: RegistrationPageComponent }]; @@ -21,6 +21,7 @@ const registrationFormlyConfig: ConfigOption = { { name: 'ish-registration-heading-field', component: RegistrationHeadingFieldComponent }, { name: 'ish-registration-tac-field', component: RegistrationTacFieldComponent }, ], + extensions: [{ name: 'disable-prefilled', extension: disablePrefilledExtension }], }; @NgModule({ @@ -35,6 +36,5 @@ const registrationFormlyConfig: ConfigOption = { RegistrationPageComponent, RegistrationTacFieldComponent, ], - providers: [{ provide: REGISTRATION_CONFIGURATION, useClass: RegistrationConfigurationService }], }) export class RegistrationPageModule {}