From 1bbfd57910a1cb19f94cec4feab6c85ac1ffd166 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Wed, 22 Sep 2021 09:48:35 +0200 Subject: [PATCH] feat(employee): Now possible to edit employee and remove data, also changed validation-rules. (TV-631) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 082d573764be4306255d5b99f28095f96691ec43 Merge: 528b858 5846c2c Author: Erik Tiekstra Date: Wed Sep 22 07:32:17 2021 +0200 Merged develop and fixed conflict commit 528b858f17919836ce0aaa0e09e100855ad00762 Author: Erik Tiekstra Date: Wed Sep 22 07:25:08 2021 +0200 Updated validation commit 28d37a1eb95a8df2520b3e7967c91e7da9e508f6 Author: Erik Tiekstra Date: Tue Sep 21 08:20:36 2021 +0200 Updated validation functionality to support submit without tjänster or utförande verksamheter --- .../edit-employee-form.component.html | 35 +++++--- .../edit-employee-form.component.ts | 83 +++++++++---------- .../tree-nodes-selector.component.html | 13 +-- .../src/app/shared/constants/regex.ts | 1 + .../utils/validators/email.validator.ts | 7 +- .../utils/validators/employee.validator.ts | 62 +++++++++----- 6 files changed, 117 insertions(+), 84 deletions(-) create mode 100644 apps/mina-sidor-fa/src/app/shared/constants/regex.ts diff --git a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.html b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.html index 9e72199..ee27be7 100644 --- a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.html +++ b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.html @@ -15,10 +15,16 @@ afLabel="E-post adress" afType="email" [formControlName]="emailFormControlName" - [afInvalidMessage]="emailFormControl?.errors?.required ? 'Du måste ange E-post' : 'E-post adressen är ogiltig'" [afDisableValidStyle]="true" - [afInvalid]="emailFormControl.invalid && emailFormControl.touched" + [afInvalid]="editEmployeeFormGroup.errors?.email && emailFormControl.touched" > +
+ {{editEmployeeFormGroup.errors.email}} +
@@ -35,16 +41,18 @@ [afPlaceholder]="'Välj tjänst'" [afSelectItems]="selectableTjansterFormItems" [afDisableValidStyle]="true" - [afInvalid]="tjansterFormControl.invalid && tjansterFormControl.touched" + [afInvalid]="editEmployeeFormGroup.errors?.tjanster && tjansterFormControl.touched" [afId]="tjansterElementId" (afOnChange)="toggleTjanst()" > - - Du måste välja minst en tjänst - +
+ + {{editEmployeeFormGroup.errors.tjanster}} + +
@@ -59,6 +67,7 @@ class="edit-employee-form__choose-all-utforande-verksamheter" [formControl]="selectAllUtforandeVerksamheterFormControl" [afLabel]="'Välj alla utförande verksamheter och alla utförande adresser'" + [afInvalid]="editEmployeeFormGroup.errors?.utforandeVerksamheter && (selectAllUtforandeVerksamheterFormControl.touched || utforandeVerksamheterFormControl.touched)" >
diff --git a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.ts b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.ts index 34b0675..a81693c 100644 --- a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/edit-employee-form/edit-employee-form.component.ts @@ -24,9 +24,7 @@ import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamhe import { ValidationErrorLink } from '@msfa-shared/components/error-list/error-list.component'; import { TreeNodesSelectorService } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service'; import { uuid } from '@msfa-utils/uuid'; -import { EmailValidator } from '@msfa-utils/validators/email.validator'; import { EmployeeValidator } from '@msfa-utils/validators/employee.validator'; -import { RequiredValidator } from '@msfa-utils/validators/required.validator'; import { EmployeeFormService } from '../services/employee-form.service'; @Component({ @@ -162,27 +160,21 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges { this.editEmployeeFormGroup = new FormGroup( { - email: new FormControl(this.employee.email, [ - RequiredValidator('E-postadress'), - EmailValidator('e-postadress'), - ]), - tjanster: new FormControl(tjanstId, [RequiredValidator('Tjänst')]), + email: new FormControl(this.employee.email), + tjanster: new FormControl(tjanstId), roles: this.employeeFormService.getRolesFormGroup(this.availableRoles, this.employee.roles), utforandeVerksamheter: new FormControl( this.utforandeVerksamheterService.getTreeNodeDataFromUtforandeVerksamheter( this.availableUtforandeVerksamheter, this.employee?.utforandeVerksamheter - ), - [] + ) ), allaUtforandeVerksamheter: new FormControl(this.employee.allaUtforandeVerksamheter), }, { - validators: EmployeeValidator.HasSelectedAtLeastOneUtforandeVerksamhet( - this.utforandeVerksamheterFormControlName, - this.selectAllUtforandeVerksamheterFormControlName, - this.utforandeVerksamheterService.hasSelectedUtforandeVerksamhet - ), + validators: [ + EmployeeValidator.isEmployeeValid(this.utforandeVerksamheterService.hasSelectedUtforandeVerksamhet), + ], } ); @@ -198,11 +190,26 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges { } onFormSubmitted(saveWithoutRoles = false): void { - this._submitted = true; if (!this.editEmployeeFormGroup || this.isLoadingUtforandeVerksamheter) { return; } + const roles = this.employeeFormService.getRolesFromFormGroup(this.rolesFormGroup, this.availableRoles); + + if (!roles.length && !saveWithoutRoles) { + this.displayEditWithoutRolesDialog = true; + return; + } + + this._submitted = true; + + if (!roles.length && saveWithoutRoles) { + this.utforandeVerksamheterFormControl.clearValidators(); + this.utforandeVerksamheterFormControl.updateValueAndValidity(); + this.tjansterFormControl.clearValidators(); + this.tjansterFormControl.updateValueAndValidity(); + } + this.editEmployeeFormGroup.markAllAsTouched(); if (this.editEmployeeFormGroup.invalid) { @@ -217,30 +224,21 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges { return; } - const roles = this.employeeFormService.getRolesFromFormGroup(this.rolesFormGroup, this.availableRoles); - - if (!roles.length && !saveWithoutRoles) { - this.displayEditWithoutRolesDialog = true; - return; - } - this.formSubmitted.emit({ email: this.emailFormControl?.value as string, - tjanstIds: this.employeeFormService - .getSelectedTjanster(this.availableTjanster, +this.tjansterFormControl?.value) - .map(tjanst => tjanst.tjanstId), - roles: [ - ...new Set([ - ...this.employeeFormService.getRolesFromFormGroup(this.rolesFormGroup, this.availableRoles), - RoleEnum.MSFA_Standard, - ]), - ], - adressIds: this.selectAllUtforandeVerksamheterFormControl.value + tjanstIds: !roles.length ? [] - : this.utforandeVerksamheterService.getSelectedAdressIdsFromTreeNode( - this.utforandeVerksamheterFormControl?.value - ), - allaUtforandeVerksamheter: !!this.selectAllUtforandeVerksamheterFormControl.value, + : this.employeeFormService + .getSelectedTjanster(this.availableTjanster, +this.tjansterFormControl?.value) + .map(tjanst => tjanst.tjanstId), + roles: [...new Set([...roles, RoleEnum.MSFA_Standard])], + adressIds: + !roles.length || this.selectAllUtforandeVerksamheterFormControl.value + ? [] + : this.utforandeVerksamheterService.getSelectedAdressIdsFromTreeNode( + this.utforandeVerksamheterFormControl?.value + ), + allaUtforandeVerksamheter: !roles.length ? false : !!this.selectAllUtforandeVerksamheterFormControl.value, }); } @@ -250,25 +248,26 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges { if (!this.editEmployeeFormGroup) { return; } + const { email, tjanster, utforandeVerksamheter } = this.editEmployeeFormGroup.errors || {}; - if (this.emailFormControl?.errors) { + if (email) { validationErrorLinks = validationErrorLinks.concat({ elementId: this.emailElementId, - text: this.emailFormControl?.errors?.message as string, + text: email as string, }); } - if (this.tjansterFormControl?.errors) { + if (tjanster) { validationErrorLinks = validationErrorLinks.concat({ elementId: this.tjansterElementId, - text: this.tjansterFormControl?.errors?.message as string, + text: tjanster as string, }); } - if (this.editEmployeeFormGroup.errors?.noUtforandeVerksamhetSelected) { + if (utforandeVerksamheter) { validationErrorLinks = validationErrorLinks.concat({ elementId: this.utforandeVerksamhetElementId, - text: this.utforandeVerksamhetRequiredMessage, + text: utforandeVerksamheter as string, }); } diff --git a/apps/mina-sidor-fa/src/app/shared/components/tree-nodes-selector/components/tree-nodes-selector/tree-nodes-selector.component.html b/apps/mina-sidor-fa/src/app/shared/components/tree-nodes-selector/components/tree-nodes-selector/tree-nodes-selector.component.html index d8fb969..ba78437 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/tree-nodes-selector/components/tree-nodes-selector/tree-nodes-selector.component.html +++ b/apps/mina-sidor-fa/src/app/shared/components/tree-nodes-selector/components/tree-nodes-selector/tree-nodes-selector.component.html @@ -34,9 +34,12 @@
-
    -
  • - {{validationMessage}} -
  • -
+ +
+
    +
  • + {{validationMessage}} +
  • +
+
diff --git a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts new file mode 100644 index 0000000..0bb8c1c --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts @@ -0,0 +1 @@ +export const EMAIL_REGEX = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/; diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/email.validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/email.validator.ts index 05a1e46..804271e 100644 --- a/apps/mina-sidor-fa/src/app/shared/utils/validators/email.validator.ts +++ b/apps/mina-sidor-fa/src/app/shared/utils/validators/email.validator.ts @@ -1,14 +1,17 @@ import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { EMAIL_REGEX } from '@msfa-constants/regex'; import { ValidationError } from '@msfa-models/validation-error.model'; -const EMAIL_REGEX = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/; +export function emailIsValid(email: string): boolean { + return EMAIL_REGEX.test(email.toLowerCase()); +} export function EmailValidator(label = 'Fältet'): ValidatorFn { return (control: AbstractControl): ValidationError => { if (control && control.value) { const value: string = control.value as string; - if (!EMAIL_REGEX.test(value.toLowerCase())) { + if (!emailIsValid(value)) { return { type: 'invalid', message: `Ogiltig ${label}` }; } } diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/employee.validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/employee.validator.ts index 407764c..9b46412 100644 --- a/apps/mina-sidor-fa/src/app/shared/utils/validators/employee.validator.ts +++ b/apps/mina-sidor-fa/src/app/shared/utils/validators/employee.validator.ts @@ -1,32 +1,50 @@ -import { FormGroup, ValidatorFn } from '@angular/forms'; +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { RoleEnum } from '@msfa-enums/role.enum'; import { TreeNode } from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service'; +import { emailIsValid } from './email.validator'; export class EmployeeValidator { - static HasSelectedAtLeastOneRole(roleFormControlNames: Array): ValidatorFn { - return (fg: FormGroup): { [key: string]: unknown } => { - if (!roleFormControlNames || roleFormControlNames.length === 0) { - return { noRoleSelected: true }; + static isEmployeeValid(hasSelectedUtforandeVerksamhetFn: (treeNode: TreeNode) => boolean): ValidatorFn { + return (c: AbstractControl): { [key: string]: string } => { + let errors: { [key: string]: string } = null; + const email = c.get('email')?.value as string; + const roles = c.get('roles')?.value as { [key: string]: boolean }; + const tjanster = c.get('tjanster')?.value as string; + const allaUtforandeVerksamheter = c.get('allaUtforandeVerksamheter')?.value as boolean; + const utforandeVerksamheter = c.get('utforandeVerksamheter').value as TreeNode; + const rolesWithObligatoryFormElements = Object.entries(roles) + .filter(([key, value]) => !!(value && key !== RoleEnum.MSFA_AuthAdmin)) + .map(([key]) => key); + + if (!email) { + errors = { + ...errors, + email: 'E-postadress är obligatoriskt', + }; + } + if (email && !emailIsValid(email)) { + errors = { + ...errors, + email: 'Ogiltig e-postadress', + }; } - return roleFormControlNames.some(roleFormControlName => fg?.controls[roleFormControlName]?.value) - ? null - : { noRoleSelected: true }; - }; - } - - static HasSelectedAtLeastOneUtforandeVerksamhet( - utforandeVerksamheterFormControlName: string, - selectAllUtforandeVerksamheterFormControlName: string, - validationFn: (treeNode: TreeNode | null | undefined) => boolean - ): ValidatorFn { - return (fg: FormGroup): { [key: string]: unknown } => { - if (fg?.get(selectAllUtforandeVerksamheterFormControlName)?.value) { - return null; + if (rolesWithObligatoryFormElements.length) { + if (!tjanster) { + errors = { + ...errors, + tjanster: 'Minst en tjänst behöver väljas', + }; + } + if (!allaUtforandeVerksamheter && !hasSelectedUtforandeVerksamhetFn(utforandeVerksamheter)) { + errors = { + ...errors, + utforandeVerksamheter: 'Minst en utförande verksamhet och adress behöver väljas', + }; + } } - return validationFn(fg?.get(utforandeVerksamheterFormControlName)?.value) - ? null - : { noUtforandeVerksamhetSelected: true }; + return errors; }; } }