From 7c37fae1639369dd92eef687c5dc9022f963da2a Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Mon, 11 Oct 2021 14:39:48 +0200 Subject: [PATCH 1/4] Implemented better validation inside avvikelse-report --- .../deltagare-avvikelserapport.component.html | 12 ++--------- .../deltagare-avvikelserapport.component.ts | 21 +++++++++++++------ .../src/app/shared/constants/regex.ts | 1 + .../utils/mark-controls-as-dirty.util.ts | 13 ++++++++++++ .../utils/validators/regex.validator.ts | 15 +++++++++++++ 5 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html index 9f4d403..444bfea 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html @@ -32,15 +32,11 @@ afPlaceholder="Välj orsak till avvikelse" [afSelectItems]="reason" [afRequired]="true" + [afInvalidMessage]="reasonFormControl.errors?.required" [afAnnounceIfOptional]="true" [afDisableValidStyle]="true" [afInvalid]="formControlIsInvalid(reasonFormControl)" > -
- {{reasonFormControl.errors?.required}} - -
-
- {{question.errors?.required}} - -
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts index 7f952aa..413c84c 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts @@ -8,6 +8,8 @@ import { CustomError } from '@msfa-models/error/custom-error'; import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; +import { RegexValidator } from '@msfa-utils/validators/regex.validator'; import { RequiredValidator } from '@msfa-validators/required.validator'; import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { map, shareReplay, switchMap, take } from 'rxjs/operators'; @@ -48,9 +50,9 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { shareReplay(1) ); - reasons$ = this.deltagareAvvikelseService.getAvvikelseOrsaker$; + reasons$: Observable = this.deltagareAvvikelseService.getAvvikelseOrsaker$; reasonsAsNgDigiFormSelectItems$: Observable = this.reasons$.pipe( - map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id }))) + map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id as string }))) ); allAvvikelseQuestions$ = this.deltagareAvvikelseService.fragorForAvvikelser$; @@ -63,8 +65,8 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { private subscriptions: Subscription[] = []; private todayDateISO = new Date().toISOString().slice(0, 10); avvikelseFormGroup = new FormGroup({ - [this.reasonFormName]: new FormControl(null, RequiredValidator('Orsak är obligatorisk')), - [this.reportingDateFormName]: new FormControl(this.todayDateISO, RequiredValidator('Datum är obligatoriskt')), + [this.reasonFormName]: new FormControl(null, [RequiredValidator('Orsak är obligatorisk')]), + [this.reportingDateFormName]: new FormControl(this.todayDateISO, [RequiredValidator('Datum är obligatoriskt')]), [this.questionsFormName]: new FormArray([]), }); private formData$: Observable = this.avvikelseFormGroup @@ -141,6 +143,8 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { openConfirmDialog(): void { this.shouldValidate$.next(true); + markControlsAsDirty(Object.values(this.avvikelseFormGroup.controls)); + this.avvikelseFormGroup.markAllAsTouched(); if (this.avvikelseFormGroup.valid) { this.confirmDialogIsOpen$.next(true); @@ -184,7 +188,7 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { svar: question, })), rapporteringsdatum: formData.reportingDate, - }; + } as AvvikelseAlternativ; return { genomforandeReferens, avvikelseAlternativ }; } @@ -199,7 +203,12 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { this.currentQuestions.push(question); this.questionsFormArray.push( - new FormControl('', this.questionIsRequired(question) ? RequiredValidator('Frågan är obligatorisk') : null) + new FormControl( + '', + this.questionIsRequired(question) + ? [RequiredValidator('Frågan är obligatorisk'), RegexValidator()] + : [RegexValidator()] + ) ); } } diff --git a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts index 6949a19..03cbae6 100644 --- a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts +++ b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts @@ -1,2 +1,3 @@ export const EMAIL_REGEX = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/; export const ISO_DATE_NO_TIME = /^\d{4}[-/\s]?((((0[13578])|(1[02]))[-/\s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[-/\s]?(([0-2][0-9])|(30)))|(02[-/\s]?[0-2][0-9]))$/; +export const CHARACTER_REGEX = /\w/; diff --git a/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts b/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts new file mode 100644 index 0000000..5c5ace5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/mark-controls-as-dirty.util.ts @@ -0,0 +1,13 @@ +import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; + +export function markControlsAsDirty(controls: AbstractControl[]): void { + controls.forEach(control => { + if (control instanceof FormControl) { + control.markAsDirty({ onlySelf: true }); + } else if (control instanceof FormGroup) { + markControlsAsDirty(Object.values(control.controls)); + } else if (control instanceof FormArray) { + markControlsAsDirty(control.controls); + } + }); +} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts new file mode 100644 index 0000000..446f63e --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/validators/regex.validator.ts @@ -0,0 +1,15 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { CHARACTER_REGEX } from '@msfa-constants/regex'; +import { ValidationError } from '@msfa-models/validation-error.model'; + +export function RegexValidator(regex = CHARACTER_REGEX, message = 'Ogiltig värde'): ValidatorFn { + return (control: AbstractControl): ValidationError => { + if (control && control.value) { + if (!regex.test(control.value)) { + return { invalid: message }; + } + } + + return null; + }; +} From c37b9cb8b98c4437a0a8383fba59469a0235e345 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Mon, 11 Oct 2021 15:06:03 +0200 Subject: [PATCH 2/4] =?UTF-8?q?Fixed=20validation=20for=20fr=C3=A5nvaro-re?= =?UTF-8?q?port?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../franvaro-report.validator.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.validator.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.validator.ts index b742122..4bbd21d 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.validator.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.validator.ts @@ -1,5 +1,6 @@ import { AbstractControl, ValidatorFn } from '@angular/forms'; import { ANNAN_KAND_ORSAK_ID, ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons'; +import { CHARACTER_REGEX } from '@msfa-constants/regex'; import { Franvaro } from '@msfa-models/franvaro.model'; const TIME_REGEX = /^([0-1]?[0-9]|2[0-4]):([0-5][0-9])(:[0-5][0-9])?$/; @@ -36,11 +37,18 @@ export class FranvaroReportValidator { ...errors, otherKnownReason: 'Känd orsak måste väljas', }; - } else if (otherKnownReason === ANNAN_ORSAK_ID && !knownReasonComment) { - errors = { - ...errors, - knownReasonComment: 'Beskrivning av frånvaro är obligatorisk', - }; + } else if (otherKnownReason === ANNAN_ORSAK_ID) { + if (!knownReasonComment) { + errors = { + ...errors, + knownReasonComment: 'Beskrivning av frånvaro är obligatorisk', + }; + } else if (!CHARACTER_REGEX.test(knownReasonComment)) { + errors = { + ...errors, + knownReasonComment: 'Beskrivning av frånvaro har en ogiltig värde', + }; + } } } if (!date) { From ad2dd86ecd07846ebb5a988ec3842794885296d9 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Mon, 11 Oct 2021 15:08:31 +0200 Subject: [PATCH 3/4] Implemented start-/enddate in gemensam planering as it is in other reports --- .../deltagare-gemensam-planering.component.html | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.html index 5014391..4328fd3 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.html @@ -3,7 +3,6 @@ *ngIf="avrop$ | async as avrop; else skeletonRef" reportTitle="Gemensam planering" [avrop]="avrop" - [isPeriodDate]="true" >
@@ -120,9 +119,12 @@
Tjänst
{{avrop.tjanst}}
-
Avser period
+
Startdatum
+
+ +
+
Slutdatum
- -
Deltar arbetssökande på distans?
From eac45ebd167c008789ba07dc85f943f7a4e97c35 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Mon, 11 Oct 2021 15:13:52 +0200 Subject: [PATCH 4/4] Fixed linting --- .../deltagare-avvikelserapport.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts index 413c84c..3180f4e 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts @@ -52,7 +52,7 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { reasons$: Observable = this.deltagareAvvikelseService.getAvvikelseOrsaker$; reasonsAsNgDigiFormSelectItems$: Observable = this.reasons$.pipe( - map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id as string }))) + map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id }))) ); allAvvikelseQuestions$ = this.deltagareAvvikelseService.fragorForAvvikelser$;