diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts index 9a93888..fa9a3b9 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts @@ -9,11 +9,17 @@ const routes: Routes = [ }, { path: 'avvikelserapport', + data: { title: 'Skapa avvikelserapport' }, + loadChildren: () => + import('./pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.module').then( + m => m.DeltagareAvvikelserapportModule + ), + }, + { + path: 'franvarorapport', data: { title: 'Skapa rapport' }, loadChildren: () => - import('./pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module').then( - m => m.DeltagareAvvikelseModule - ), + import('./pages/deltagare-reports/franvaro-report/franvaro-report.module').then(m => m.FranvaroReportModule), }, { path: 'gemensam-planering', diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html index e94367f..60b199c 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html @@ -1,27 +1,25 @@
-
-

Skapa ny rapport

-

Här kan du skicka rapporter om deltagaren till arbetsförmedlingen.

- - - - Du måste välja en rapporttyp - -
-
+ +

Skapa ny rapport

+

Här kan du skicka rapporter om deltagaren till arbetsförmedlingen.

+ + +

+ +

+

-

+

+

+ +

+

Inskickade rapporter

-
+
-

Vad är det du vill rapportera?

-

{{ formGroup?.get('alternative').value === 'franvaro' ? 'Frånvaro' : 'Avvikelse'}}

- - -

Orsak till frånvaro

- -

{{orsak.name}}

-
- - -

Annan känd orsak

- -

- {{annanKandOrsak.name}} -

-
-
- - -

Beskrivning

-

{{formGroup?.get('description').value}}

-
- -

Datum

-

{{formGroup?.get('date').value}}

-

Hel eller del av dag

-

{{formGroup.get('dayOrPartOfDay').value === 'HELDAG' ? 'Heldag' : 'Del av dag'}}

- - -

Starttid

-

{{formGroup?.get('timepickerFormGroup').get('startTime').value}}

- -

Sluttid

-

{{formGroup?.get('timepickerFormGroup').get('endTime').value}}

-
-
- - -

Orsak till avvikelse

- -

{{orsak.name}}

-
- - -

- {{fraga.name}} -

-
-

{{formGroup?.get('fragorFormGroup').get('fraga1').value}}

- - -

- {{fraga.name}} -

-
-

{{formGroup?.get('fragorFormGroup').get('fraga2').value}}

- -

Datum

-

{{formGroup?.get('date').value}}

-
- diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.scss deleted file mode 100644 index 7235003..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.scss +++ /dev/null @@ -1,10 +0,0 @@ -@import 'apps/mina-sidor-fa/src/styles/variables/gutters'; - -.deltagare-confirm { - margin-bottom: $digi--layout--gutter--xl; - - &__header { - font-size: var(--digi--typography--font-size--l); - margin: 0; - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.spec.ts deleted file mode 100644 index 37d62ed..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DeltagareConfirmFormComponent } from './deltagare-confirm-form.component'; - -describe('DeltagareConfirmFormComponent', () => { - let component: DeltagareConfirmFormComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ DeltagareConfirmFormComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(DeltagareConfirmFormComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.ts deleted file mode 100644 index 73a8db6..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { AvvikelseOrsaksKodEnum } from '@msfa-enums/avvikelse-orsak-kod.enum'; -import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; -import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; -import { KandaAvvikelseKoder, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; - -@Component({ - selector: 'msfa-deltagare-confirm-form', - templateUrl: './deltagare-confirm-form.component.html', - styleUrls: ['./deltagare-confirm-form.component.scss'], - changeDetection: ChangeDetectionStrategy.Default -}) -export class DeltagareConfirmFormComponent implements OnChanges { - @Input() formGroup: FormGroup | null = null; - @Input() orsakskoderfranvaro: OrsaksKoderFranvaro[]; - @Input() andraKandaOrsaker: KandaAvvikelseKoder[]; - @Input() avvikelseOrsaker: OrsaksKoderAvvikelse[]; - @Input() fragor1: FragorForAvvikelser[]; - @Input() fragor2: FragorForAvvikelser[]; - @Input() selectedOrsak: string; - - ngOnChanges(changes: SimpleChanges): void { - if (Number(changes.selectedOrsak?.currentValue) === AvvikelseOrsaksKodEnum.SerTillAttErbjudetArbeteInteKommerTillStand) { - this.formGroup?.get('fragorFormGroup').get('fraga2').reset(''); - } - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.module.ts deleted file mode 100644 index 9848b0c..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-confirm-form/deltagare-confirm-form.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DeltagareConfirmFormComponent } from './deltagare-confirm-form.component'; - - - -@NgModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareConfirmFormComponent], - imports: [ - CommonModule - ], - exports: [DeltagareConfirmFormComponent] -}) -export class DeltagareConfirmFormModule { } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.html deleted file mode 100644 index 6d60905..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.html +++ /dev/null @@ -1,28 +0,0 @@ -
- -
- -
-
- -
- -
-
-
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.scss deleted file mode 100644 index 0d8fedc..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import 'apps/mina-sidor-fa/src/styles/variables/gutters'; - -.fragor-form { - &__content { - max-width: var(--digi--typography--text--max-width); - margin-bottom: $digi--layout--gutter--xl; - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.spec.ts deleted file mode 100644 index 8fa0f24..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; -import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; - -import { DeltagareFragorFormComponent } from './deltagare-fragor-form.component'; - -describe('DeltagareAvvikelseFormComponent', () => { - let component: DeltagareFragorFormComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [DigiNgFormRadiobuttonGroupModule, ReactiveFormsModule, DigiNgFormTextareaModule], - declarations: [DeltagareFragorFormComponent] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(DeltagareFragorFormComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.ts deleted file mode 100644 index c4ec107..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; - -@Component({ - selector: 'msfa-deltagare-fragor-form', - templateUrl: './deltagare-fragor-form.component.html', - styleUrls: ['./deltagare-fragor-form.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush - -}) - -export class DeltagareFragorFormComponent { - @Input() fragor1: FragorForAvvikelser[] | null = null; - @Input() fragor2: FragorForAvvikelser[] | null = null; - @Input() fragorFormGroup: FormGroup | null = null; - @Input() avvikelseFormGroup: FormGroup | null = null; - @Input() selectedOrsaksKod: string | null = null; -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.module.ts deleted file mode 100644 index bffba9d..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/deltagare-fragor-form.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DeltagareFragorFormComponent } from './deltagare-fragor-form.component'; -import { ReactiveFormsModule } from '@angular/forms'; -import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea'; -import { FilterFragorPipe } from './filter-fragor.pipe'; - - - -@NgModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareFragorFormComponent, FilterFragorPipe], - imports: [ - CommonModule, - ReactiveFormsModule, - DigiNgFormTextareaModule - ], - exports: [DeltagareFragorFormComponent] -}) -export class DeltagareFragorFormModule { } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/filter-fragor.pipe.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/filter-fragor.pipe.ts deleted file mode 100644 index e1c8bb9..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-fragor-form/filter-fragor.pipe.ts +++ /dev/null @@ -1,19 +0,0 @@ - -import { Pipe, PipeTransform } from '@angular/core'; -import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; - -@Pipe({ - name: 'filterFragor', - -}) -export class FilterFragorPipe implements PipeTransform { - transform(fragor: FragorForAvvikelser[], id: string): FragorForAvvikelser[] { - if (fragor?.length === 0) { - return fragor; - } - - return fragor?.filter(fraga => fraga?.id.substring(0, 2) === id); - } -} - - diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.html deleted file mode 100644 index b68b31d..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.html +++ /dev/null @@ -1,43 +0,0 @@ -
-
- - - Orsak är obligatoriskt - -
- - - - -
- - - Orsak är obligatoriskt - -
- - - -
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.scss deleted file mode 100644 index 2324f00..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -@import 'apps/mina-sidor-fa/src/styles/variables/gutters'; - -.orsaks-form { - &__content { - max-width: var(--digi--typography--text--max-width); - margin-bottom: $digi--layout--gutter--xl; - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.spec.ts deleted file mode 100644 index b76083e..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; -import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { DeltagareOrsaksFormComponent } from './deltagare-orsaks-form.component'; - - -describe('DeltagareAvvikelseFormComponent', () => { - let component: DeltagareOrsaksFormComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [DigiNgFormRadiobuttonGroupModule, ReactiveFormsModule, DigiNgFormSelectModule], - declarations: [DeltagareOrsaksFormComponent] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(DeltagareOrsaksFormComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.ts deleted file mode 100644 index 32a6d70..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { FranvaroOrsaksKodEnum } from '@msfa-enums/franvaro-orsak-kod.enum'; -import { ReportType } from '@msfa-enums/report-type.enum'; -import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; -import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; - -@Component({ - selector: 'msfa-deltagare-orsaks-form', - templateUrl: './deltagare-orsaks-form.component.html', - styleUrls: ['./deltagare-orsaks-form.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DeltagareOrsaksFormComponent implements OnChanges { - @Input() franvaroOrsaker: OrsaksKoderFranvaro[] | null = null; - @Input() avvikelseOrsaker: OrsaksKoderAvvikelse[] | null = null; - @Input() andraKandaOrsaker: OrsaksKoderFranvaro[] | null = null; - @Input() orsakerFormGroup: FormGroup | null = null; - @Input() avvikelseFormGroup: FormGroup | null = null; - @Input() selectedAlternative: string | null = null; - - ngOnChanges(changes: SimpleChanges): void { - if (changes) { - this.orsakerFormGroup.reset(); - } - } - - get showAndraKandaOrsaker(): boolean { - return ( - this.selectedAlternative === ReportType.FRANVARO && - +this.orsakerFormGroup.get('orsaker')?.value === FranvaroOrsaksKodEnum.AnnanKandOrsak - ); - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.module.ts deleted file mode 100644 index 14d6170..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-orsaks-form/deltagare-orsaks-form.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; -import { DeltagareOrsaksFormComponent } from './deltagare-orsaks-form.component'; - - - -@NgModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareOrsaksFormComponent], - imports: [ - CommonModule, - ReactiveFormsModule, - DigiNgFormSelectModule, - LoaderModule - ], - exports: [DeltagareOrsaksFormComponent] -}) -export class DeltagareOrsaksFormModule { } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.html deleted file mode 100644 index 5fe0e64..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
- - - - -
- -
-
- -
-
-
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.scss deleted file mode 100644 index 37d98f2..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -@import 'apps/mina-sidor-fa/src/styles/variables/gutters'; - -.deltagare-timepicker { - margin-bottom: $digi--layout--gutter--xl; - - &__heading { - font-weight: var(--digi--typography--font-weight--semibold); - } - - &__start-time { - margin-bottom: $digi--layout--gutter--l; - } - - &__input { - width: 127px; - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.spec.ts deleted file mode 100644 index 862dcc3..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; -import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { DeltagareTimePickerComponent } from './deltagare-time-picker.component'; - - -describe('DeltagareTimePickerComponent', () => { - let component: DeltagareTimePickerComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareTimePickerComponent], - imports: [ReactiveFormsModule, DigiNgFormSelectModule, DigiNgFormInputModule] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(DeltagareTimePickerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.ts deleted file mode 100644 index 328fe97..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { FormGroup } from '@angular/forms'; - -@Component({ - selector: 'msfa-deltagare-time-picker', - templateUrl: './deltagare-time-picker.component.html', - styleUrls: ['./deltagare-time-picker.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DeltagareTimePickerComponent { - @Input() timepickerFormGroup: FormGroup | null = null; - @Input() avvikelseFormGroup: FormGroup | null = null; -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.module.ts deleted file mode 100644 index 2bb832e..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/components/deltagare-time-picker/deltagare-time-picker.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { DeltagareTimePickerComponent } from './deltagare-time-picker.component'; -import {DigiNgFormInputModule} from '@af/digi-ng/_form/form-input' - - - -@NgModule({ - schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareTimePickerComponent], - imports: [ - CommonModule, - ReactiveFormsModule, - DigiNgFormSelectModule, - DigiNgFormInputModule - ], - exports: [DeltagareTimePickerComponent] -}) -export class DeltagareTimePickerModule { } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.html deleted file mode 100644 index 7703a56..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.html +++ /dev/null @@ -1,166 +0,0 @@ - - -
- -

- Avvikelserapport för deltagare {{avrop.fullName}} är nu inskickad till - Arbetsförmedlingen och inväntar - godkännande. -

-
-
Datum
-
{{submittedDate | date:'longDate'}} kl {{submittedDate | date:'shortTime'}}
-
-
- Tillbaka till deltagaren -
- - -

Vad är det du vill rapportera?

-
-
- - - Alternativ är obligatoriskt - -
- - - -
- -
- - - -
- - - {{avvikelseFormGroup.errors?.dateIsRequired}} - -
- -
- - - {{dayOrPartOfDayFormControl.errors?.message}} - -
- - -
-
- - - - -

Kunde inte spara avvikelserapporten. Ladda om sidan och försök igen.

-

{{error.message}}

-
- -
- - - Tillbaka - - - Skicka in - - - - Förhandsgranska - -
-
- - - -
- - - diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.ts deleted file mode 100644 index 32a7476..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.ts +++ /dev/null @@ -1,360 +0,0 @@ -import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; -import { FormTextareaSize } from '@af/digi-ng/_form/form-textarea'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; -import { ConfirmDialog } from '@msfa-enums/confirm-dialog.enum'; -import { DayOrPartOfDay } from '@msfa-enums/day-or-part-of-day.enum'; -import { FranvaroOrsaksKodEnum } from '@msfa-enums/franvaro-orsak-kod.enum'; -import { KandaOrsakerEnum } from '@msfa-enums/kanda-orsaker-kod.enum'; -import { ReportType } from '@msfa-enums/report-type.enum'; -import { AvvikelseAlternativ } from '@msfa-models/avvikelse-alternativ.model'; -import { Avvikelse } from '@msfa-models/avvikelse.model'; -import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; -import { FranvaroAlternativ } from '@msfa-models/franvaro-alternativ.model'; -import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; -import { KandaAvvikelseKoder, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; -import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { - requiredAnnanKandOrsakValidator, - RequiredDateValidator, - requiredDayOrPartOfDayValidator, - requiredDescriptionValidator, - requiredEndTimeValidator, - requiredFraga1Validator, - requiredfraga2Validator, - requiredOrsakerValidator, - requiredStartTimeValidator, -} from '@msfa-validators/avvikelse-form-validator'; -import { RequiredValidator } from '@msfa-validators/required.validator'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { map, shareReplay, switchMap } from 'rxjs/operators'; -import { DeltagareAvvikelseService } from './deltagare-avvikelse.service'; -import { avvikelseAlternatives, dayOrPartOfDay } from './report-alternatives'; -import { CustomError } from '@msfa-models/error/custom-error'; -import { ErrorType } from '@msfa-enums/error-type.enum'; -import { Avrop } from '@msfa-models/avrop.model'; - -interface Params { - genomforandeReferens: string; -} - -@Component({ - selector: 'msfa-deltagare-avvikelse', - templateUrl: './deltagare-avvikelse.component.html', - styleUrls: ['./deltagare-avvikelse.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class DeltagareAvvikelseComponent { - readonly alternativeFormControlName = 'alternative'; - readonly descriptionFormControlName = 'description'; - readonly dateFormControlName = 'date'; - readonly dayOrPartOfDayFormControlName = 'dayOrPartOfDay'; - readonly orsakerFormControlName = 'orsaker'; - readonly andraKandaOrsakerFormControlName = 'andraKandaOrsaker'; - readonly fraga1FormControlName = 'fraga1'; - readonly fraga2FormControlName = 'fraga2'; - readonly startTimeFormControlName = 'startTime'; - readonly endTimeFormControlName = 'endTime'; - genomforandeReferens$: Observable = this.activatedRoute.params.pipe( - map((params: Params) => +params.genomforandeReferens) - ); - avrop$: Observable = this.genomforandeReferens$.pipe( - switchMap(genomforandeReferens => this.deltagareAvvikelseService.fetchAvropInformation$(genomforandeReferens)), - shareReplay(1) - ); - - franvaroOrsaker$: Observable; - avvikelseOrsaker$: Observable; - andraKandaOrsaker$: Observable; - fragor1$: Observable; - fragor2$: Observable; - sizeTextArea: FormTextareaSize.S; - todayDate = new Date().toISOString().slice(0, 10); - avvikelseAlternatives: RadiobuttonModel[] = avvikelseAlternatives; - dayOrPartOfDay: RadiobuttonModel[] = dayOrPartOfDay; - selectedOrsaksKod: string; - avvikelseFormGroup = new FormGroup( - { - alternative: new FormControl(null, [RequiredValidator()]), - description: new FormControl('', [requiredDescriptionValidator()]), - date: new FormControl(this.todayDate), - dayOrPartOfDay: new FormControl(null, [requiredDayOrPartOfDayValidator()]), - orsakerFormGroup: new FormGroup({ - orsaker: new FormControl([], [requiredOrsakerValidator()]), - andraKandaOrsaker: new FormControl([], [requiredAnnanKandOrsakValidator()]), - }), - fragorFormGroup: new FormGroup({ - fraga1: new FormControl('', [requiredFraga1Validator()]), - fraga2: new FormControl('', [requiredfraga2Validator()]), - }), - timepickerFormGroup: new FormGroup({ - startTime: new FormControl('', [requiredStartTimeValidator()]), - endTime: new FormControl('', [requiredEndTimeValidator()]), - }), - }, - { - validators: [RequiredDateValidator.CheckIfRequired()], - } - ); - totalAmountOfSteps = 2; - currentStep = 1; - openConfirmDialog = false; - private _submittedDate$ = new BehaviorSubject(null); - submittedDate$: Observable = this._submittedDate$.asObservable(); - private _error$ = new BehaviorSubject(null); - error$: Observable = this._error$.asObservable(); - private _showDangerNotification$ = new BehaviorSubject(false); - - constructor( - private deltagareAvvikelseService: DeltagareAvvikelseService, - private deltagareApiService: DeltagareApiService, - private activatedRoute: ActivatedRoute - ) {} - - get alternativeFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get(this.alternativeFormControlName); - } - - get descriptionFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get(this.descriptionFormControlName); - } - - get dateFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get(this.dateFormControlName); - } - - get dayOrPartOfDayFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get(this.dayOrPartOfDayFormControlName); - } - - get orsakerFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get('orsakerFormGroup').get(this.orsakerFormControlName); - } - - get andraKandaOrsakerFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup?.get('orsakerFormGroup').get(this.andraKandaOrsakerFormControlName); - } - - get fraga1FormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup.get('fragorFormGroup').get(this.fraga1FormControlName); - } - - get fraga2FormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup.get('fragorFormGroup').get(this.fraga2FormControlName); - } - - get startTimeFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup.get('timepickerFormGroup').get(this.startTimeFormControlName); - } - - get endTimeFormControl(): AbstractControl | undefined { - return this.avvikelseFormGroup.get('timepickerFormGroup').get(this.endTimeFormControlName); - } - - get franvaro(): FranvaroAlternativ { - return { - avvikelseOrsaksKod: this.orsakerFormControl.value as string, - datum: this.dateFormControl.value as string, - heldag: this.dayOrPartOfDayFormControl.value === DayOrPartOfDay.HELDAG, - startTid: (this.startTimeFormControl.value as string) || '9:00', - slutTid: (this.endTimeFormControl.value as string) || '16:00', - forvantadNarvaro: { - startTid: '', - slutTid: '', - }, - alternativForKandaOrsaker: { - typ: (this.andraKandaOrsakerFormControl.value as string) || '', - motivering: this.descriptionFormControl.value as string, - }, - }; - } - - get avvikelse(): AvvikelseAlternativ { - return { - avvikelseorsakskod: this.orsakerFormControl.value as string, - frageformular: [ - { - fraga: (this.avvikelseFormGroup.get('orsakerFormGroup').get('orsaker').value as string) + '_1', - svar: this.fraga1FormControl.value as string, - }, - { - fraga: - (this.fraga2FormControl.value as string) !== '' - ? (this.avvikelseFormGroup.get('orsakerFormGroup').get('orsaker').value as string) + '_2' - : '', - svar: this.fraga2FormControl.value as string, - }, - ], - rapporteringsdatum: this.dateFormControl.value as string, - }; - } - - get showDescription(): boolean { - return ( - (this.alternativeFormControl.value as string) === ReportType.FRANVARO && - +this.orsakerFormControl.value === FranvaroOrsaksKodEnum.AnnanKandOrsak && - +this.andraKandaOrsakerFormControl.value === KandaOrsakerEnum.AnnanOrsak - ); - } - - get showFragor(): boolean { - return ( - (this.alternativeFormControl.value as string) === ReportType.AVVIKELSE && - (this.orsakerFormControl.value as boolean) - ); - } - - get showDatePicker(): boolean { - return this.orsakerFormControl.value as boolean; - } - - get showDayOrPartOfDayPicker(): boolean { - return ( - (this.alternativeFormControl.value as string) === ReportType.FRANVARO && - (this.orsakerFormControl.value as boolean) - ); - } - - get showTimePicker(): boolean { - return ( - (this.alternativeFormControl.value as string) === ReportType.FRANVARO && - (this.dayOrPartOfDayFormControl.value as string) === DayOrPartOfDay.DEL_AV_DAG - ); - } - - get nextStep(): number { - this.avvikelseFormGroup.markAllAsTouched(); - if (this.avvikelseFormGroup.valid && this.currentStep < this.totalAmountOfSteps) { - return this.currentStep++; - } - } - - setConfirmDialogChanged(confirm: ConfirmDialog): void { - this.openConfirmDialog = false; - if (confirm === ConfirmDialog.ACCEPTED) { - const postAvvikelse: Avvikelse = { - genomforandeReferens: +this.activatedRoute.snapshot.params['genomforandeReferens'], - }; - - if ((this.alternativeFormControl.value as string) === ReportType.AVVIKELSE) { - this.postAvvikelse(); - } else if ((this.alternativeFormControl.value as string) === ReportType.FRANVARO) { - this.postFranvaro(); - } - } - } - - get genomforandeReferensSnapshot() { - return +this.activatedRoute.snapshot.params['genomforandeReferens']; - } - - postAvvikelse() { - const avvikelseData: Avvikelse = { - genomforandeReferens: this.genomforandeReferensSnapshot, - avvikelseAlternativ: this.avvikelse, - }; - - this.deltagareAvvikelseService - .createAvvikelse$(avvikelseData) - .then(() => { - this._submittedDate$.next(new Date()); - this.avvikelseFormGroup.reset(); - this.currentStep = 3; - }) - .catch((error: Error) => { - this._error$.next(new CustomError({ error, message: error.message, type: ErrorType.API })); - }); - } - - postFranvaro() { - const avvikelseData: Avvikelse = { - genomforandeReferens: this.genomforandeReferensSnapshot, - franvaro: this.franvaro, - }; - - this.deltagareAvvikelseService - .createFranvaro$(avvikelseData) - .then(() => { - this._submittedDate$.next(new Date()); - this.avvikelseFormGroup.reset(); - this.currentStep = 3; - }) - .catch((error: Error) => { - this._error$.next(new CustomError({ error, message: error.message, type: ErrorType.API })); - }); - } - - setAlternative(): void { - if ((this.alternativeFormControl.value as string) == ReportType.FRANVARO) { - this.franvaroOrsaker$ = this.deltagareAvvikelseService.getOrsaksKoderFranvaro$.pipe(shareReplay(1)); - this.andraKandaOrsaker$ = this.deltagareAvvikelseService.getAndraKandaOrsaker$.pipe(shareReplay(1)); - } - - if ((this.alternativeFormControl.value as string) == ReportType.AVVIKELSE) { - this.avvikelseOrsaker$ = this.deltagareAvvikelseService.getOrsaksKoderAvvikelse$.pipe(shareReplay(1)); - this.fragor1$ = this.deltagareAvvikelseService.fragorForAvvikelser$.pipe( - map((fragor: FragorForAvvikelser[]) => { - return fragor.filter((fraga: FragorForAvvikelser) => fraga.id.includes('_1')); - }) - ); - - this.fragor2$ = this.deltagareAvvikelseService.fragorForAvvikelser$.pipe( - map((fragor: FragorForAvvikelser[]) => { - return fragor.filter((fraga: FragorForAvvikelser) => { - return fraga.id.includes('_2'); - }); - }) - ); - } - - this.clearControlOnAlternativeChange(); - } - - setOrsakerChanged(): void { - this.avvikelseFormGroup.markAsUntouched(); - if ((this.alternativeFormControl.value as string) === ReportType.AVVIKELSE) { - this.selectedOrsaksKod = this.avvikelseFormGroup.get('orsakerFormGroup').get('orsaker').value as string; - } - - this.avvikelseFormGroup - .get('orsakerFormGroup') - .get('orsaker') - .valueChanges.subscribe(value => { - if (value !== null) { - this.avvikelseFormGroup.get('orsakerFormGroup').get('andraKandaOrsaker').reset(); - } - }); - } - - setDayOrPartOfDayChanged(): void { - if (this.dayOrPartOfDayFormControl.value === DayOrPartOfDay.HELDAG) { - this.startTimeFormControl.reset(); - this.endTimeFormControl.reset(); - } - } - - setMinDate(startdatumAvrop: Date): Date { - return new Date(startdatumAvrop); - } - - get setMaxDate(): Date { - return new Date(); - } - - previousStep(): void { - if (this.currentStep > 1) { - this.currentStep--; - this._submittedDate$.next(null); - this._showDangerNotification$.next(false); - } - } - - private clearControlOnAlternativeChange(): void { - this.descriptionFormControl.setValue(''); - this.fraga1FormControl.setValue(''); - this.fraga2FormControl.setValue(''); - this.dayOrPartOfDayFormControl.reset(); - this.avvikelseFormGroup?.get('timepickerFormGroup').reset(); - } -} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.service.ts deleted file mode 100644 index 840b6b0..0000000 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.service.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Injectable } from '@angular/core'; -import { FranvaroOrsaksKodEnum } from '@msfa-enums/franvaro-orsak-kod.enum'; -import { Avvikelse } from '@msfa-models/avvikelse.model'; -import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; -import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; -import { KandaAvvikelseKoder, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; -import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service'; -import { Observable } from 'rxjs'; -import { map, shareReplay } from 'rxjs/operators'; -import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; - -@Injectable() -export class DeltagareAvvikelseService { - public fragorForAvvikelser$: Observable< - FragorForAvvikelser[] - > = this.avvikelseApiService.getFragorForAvvikelser$().pipe(shareReplay(1)); - public getOrsaksKoderFranvaro$: Observable< - OrsaksKoderFranvaro[] - > = this.avvikelseApiService.getOrsaksKoderFranvaro$().pipe( - map((orsaksKoder: OrsaksKoderFranvaro[]) => { - orsaksKoder.find(kod => { - if (kod.value === FranvaroOrsaksKodEnum.VAB) { - kod.name = 'Vård av barn'; - } - }); - return this.sortOrsaksKoder(orsaksKoder); - }), - shareReplay(1) - ); - - constructor(private avvikelseApiService: AvvikelseApiService, private deltagareApiService: DeltagareApiService) {} - - public getOrsaksKoderAvvikelse$: Observable< - OrsaksKoderAvvikelse[] - > = this.avvikelseApiService.getOrsaksKoderAvvikelse$(); - - public getAndraKandaOrsaker$: Observable = this.avvikelseApiService.getAndraKandaOrsaker$(); - - public createAvvikelse$(avvikelse: Avvikelse): Promise { - return this.avvikelseApiService.createAvvikelse$(avvikelse); - } - - public createFranvaro$(avvikelse: Avvikelse): Promise { - return this.avvikelseApiService.createFranvaro$(avvikelse); - } - - private sortOrsaksKoder(orsaksKoder: OrsaksKoderFranvaro[]): OrsaksKoderFranvaro[] { - orsaksKoder.map(orsak => { - if (+orsak.value == FranvaroOrsaksKodEnum.Sjuk) { - orsak.index = 1; - } - if (+orsak.value == FranvaroOrsaksKodEnum.Arbete) { - orsak.index = 3; - } - if (+orsak.value == FranvaroOrsaksKodEnum.OkandOrsak) { - orsak.index = 6; - } - if (+orsak.value == FranvaroOrsaksKodEnum.AnnanKandOrsak) { - orsak.index = 5; - } - if (+orsak.value == FranvaroOrsaksKodEnum.VAB) { - orsak.index = 2; - } - if (+orsak.value == FranvaroOrsaksKodEnum.Utbildning) { - orsak.index = 4; - } - }); - - const sortedOrsaksKoder = orsaksKoder.sort((kodA, kodB) => (kodA.index < kodB.index ? -1 : 1)); - return sortedOrsaksKoder; - } - - fetchAvropInformation$(genomforandeReferens: number) { - return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); - } -} 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 new file mode 100644 index 0000000..311d776 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.html @@ -0,0 +1,124 @@ + + +
+ +

+ Avvikelserapport för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen och inväntar + godkännande. +

+
+
Datum
+
{{submittedDate | date:'longDate'}} kl {{submittedDate | date:'shortTime'}}
+
+
+ Tillbaka till deltagaren +
+ + +
+
+ + {{reasonFormControl.errors?.message}} + +
+ +
+ +
+
+ + + {{question.errors?.message}} + +
+
+
+
+ + + + + + {{avvikelseDateFormControl.errors?.message}} + + + +
+ Förhandsgranska + Avbryt +
+
+
+
+ + +
+
Orsak till avvikelse:
+
{{(chosenReason$ | async)?.name }}
+ + +
{{getCurrentQuestionFromId(question.fraga).name}}
+
{{question.svar.length === 0 ? 'Inget svar' : question.svar }}
+
+
Dag för avvikelse:
+
{{avvikelseSubmitData.avvikelseAlternativ.rapporteringsdatum }}
+
+
+ + +
+
+ + + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.scss similarity index 68% rename from apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.scss rename to apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.scss index 2f4acc8..8e59404 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.scss +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.scss @@ -36,4 +36,26 @@ &__alert { max-width: var(--digi--typography--text--max-width); } + + + &__cta-wrapper { + display: flex; + gap: var(--digi--layout--gutter); + } + +} + +.fragor-form { + &__content { + max-width: var(--digi--typography--text--max-width); + margin-bottom: $digi--layout--gutter--xl; + } +} + + +.orsaks-form { + &__content { + max-width: var(--digi--typography--text--max-width); + margin-bottom: $digi--layout--gutter--xl; + } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.spec.ts similarity index 69% rename from apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.spec.ts rename to apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.spec.ts index f062a51..f21a3d6 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.component.spec.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.spec.ts @@ -6,17 +6,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; -import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component'; -import { DeltagareAvvikelseService } from './deltagare-avvikelse.service'; +import { DeltagareAvvikelserapportComponent } from './deltagare-avvikelserapport.component'; +import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; describe('DeltagareAvvikelseComponent', () => { - let component: DeltagareAvvikelseComponent; - let fixture: ComponentFixture; + let component: DeltagareAvvikelserapportComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareAvvikelseComponent, LayoutComponent], + declarations: [DeltagareAvvikelserapportComponent, LayoutComponent], imports: [ RouterTestingModule, HttpClientTestingModule, @@ -24,12 +24,12 @@ describe('DeltagareAvvikelseComponent', () => { DigiNgFormRadiobuttonGroupModule, DigiNgFormDatepickerModule, ], - providers: [DeltagareAvvikelseService], + providers: [DeltagareAvvikelserapportService], }).compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(DeltagareAvvikelseComponent); + fixture = TestBed.createComponent(DeltagareAvvikelserapportComponent); component = fixture.componentInstance; fixture.detectChanges(); }); 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 new file mode 100644 index 0000000..2a72dfd --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.component.ts @@ -0,0 +1,205 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { AvvikelseAlternativ, AvvikelseRequestData } from '@msfa-models/avvikelse.model'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; +import { map, shareReplay, switchMap, take } from 'rxjs/operators'; +import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; +import { Avrop } from '@msfa-models/avrop.model'; +import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; +import { RequiredValidator } from '@msfa-validators/required.validator'; +import { FormSelectItem } from '@af/digi-ng/_form/form-select'; +import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; +import { CustomError } from '@msfa-models/error/custom-error'; + +interface Params { + genomforandeReferens: string; +} + +interface AvvikelseFormData { + reason: string; + questions: string[]; + reportingDate: string; +} + +type AvvikelseFormKeys = keyof AvvikelseFormData; + +@Component({ + selector: 'msfa-deltagare-avvikelse', + templateUrl: './deltagare-avvikelserapport.component.html', + styleUrls: ['./deltagare-avvikelserapport.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { + shouldValidate$ = new BehaviorSubject(false); + + reasonFormName: AvvikelseFormKeys = 'reason'; + questionsFormName: AvvikelseFormKeys = 'questions'; + reportingDateFormName: AvvikelseFormKeys = 'reportingDate'; + + submitIsLoading$ = new BehaviorSubject(false); + + genomforandeReferens$: Observable = this.activatedRoute.params.pipe( + map((params: Params) => +params.genomforandeReferens) + ); + avrop$: Observable = this.genomforandeReferens$.pipe( + switchMap(genomforandeReferens => this.deltagareAvvikelseService.fetchAvropInformation$(genomforandeReferens)), + shareReplay(1) + ); + + reasons$ = this.deltagareAvvikelseService.getAvvikelseOrsaker$; + reasonsAsNgDigiFormSelectItems$: Observable = this.reasons$.pipe( + map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id }))) + ); + + allAvvikelseQuestions$ = this.deltagareAvvikelseService.fragorForAvvikelser$; + chosenReasonId$: Observable; + chosenReason$: Observable; + questionsForChosenReason$: Observable; + avvikelseSubmitData$: Observable; + confirmDialogIsOpen$ = new BehaviorSubject(false); + submittedDate$ = new BehaviorSubject(null); + private subscriptions: Subscription[] = []; + private todayDateISO = new Date().toISOString().slice(0, 10); + avvikelseFormGroup = new FormGroup({ + [this.reasonFormName]: new FormControl(null, RequiredValidator('En orsak')), //[this.orsakFormControlName]: + [this.reportingDateFormName]: new FormControl(this.todayDateISO, RequiredValidator('Datum')), + [this.questionsFormName]: new FormArray([]), + }); + private formData$: Observable = this.avvikelseFormGroup + .valueChanges as Observable; + private currentQuestions: FragorForAvvikelser[]; + + constructor( + private deltagareAvvikelseService: DeltagareAvvikelserapportService, + private deltagareApiService: DeltagareApiService, + private activatedRoute: ActivatedRoute + ) {} + + get reasonFormControl(): AbstractControl | undefined { + return this.avvikelseFormGroup.get(this.reasonFormName); + } + + get avvikelseDateFormControl(): AbstractControl | undefined { + return this.avvikelseFormGroup.get(this.reportingDateFormName); + } + + get questionsFormArray(): FormArray { + return this.avvikelseFormGroup.get('questions') as FormArray; + } + + get maxDate(): Date { + return new Date(); + } + + getCurrentQuestionFromId(id: string): FragorForAvvikelser { + return this.currentQuestions.find(currentQuestions => currentQuestions.id === id); + } + + ngOnInit(): void { + this.chosenReasonId$ = this.reasonFormControl.valueChanges as Observable; + this.chosenReason$ = combineLatest([this.chosenReasonId$, this.reasons$]).pipe( + map(([chosenReasonId, reasons]) => reasons.find(reason => reason.id === chosenReasonId)) + ); + + this.questionsForChosenReason$ = combineLatest([this.chosenReasonId$, this.allAvvikelseQuestions$]).pipe( + map(([chosenOrsak, allAvvikelseQuestions]) => { + return allAvvikelseQuestions.filter(question => question.id.startsWith(chosenOrsak.toString() + '_')); + }) + ); + + this.subscriptions.push( + this.chosenReason$.subscribe(() => { + this.shouldValidate$.next(false); + }), + this.questionsForChosenReason$.subscribe(questions => { + this.clearQuestions(); + questions.forEach(question => this.addQuestionToForm(question)); + }) + ); + + this.avvikelseSubmitData$ = combineLatest([this.genomforandeReferens$, this.chosenReasonId$, this.formData$]).pipe( + map(([genomforandeReferens, chosenReason, formData]) => + this.makeAvvikelseSubmitData(genomforandeReferens, chosenReason, formData) + ), + shareReplay(1) + ); + } + + questionIsRequired(question: FragorForAvvikelser): boolean { + return !(question.id === '19_2' || question.id === '20_2'); + } + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate$.value); + } + + minDate(avrop: Avrop): Date { + return new Date(avrop.recievedTimestamp); + } + + openConfirmDialog(): void { + this.shouldValidate$.next(true); + + if (this.avvikelseFormGroup.valid) { + this.confirmDialogIsOpen$.next(true); + } + } + + submitAndCloseConfirmDialog(): void { + this.submitIsLoading$.next(true); + this.avvikelseSubmitData$.pipe(take(1)).subscribe(avvikelseSubmitData => + this.deltagareAvvikelseService.createAvvikelse$(avvikelseSubmitData).subscribe({ + next: () => { + this.submitIsLoading$.next(false); + this.submittedDate$.next(new Date()); + this.confirmDialogIsOpen$.next(false); + }, + error: error => { + this.submitIsLoading$.next(false); + throw new CustomError(error); + }, + }) + ); + } + + cancelConfirmDialog(): void { + this.confirmDialogIsOpen$.next(false); + } + + ngOnDestroy(): void { + this.subscriptions.forEach(subscription => subscription.unsubscribe()); + } + + private makeAvvikelseSubmitData( + genomforandeReferens: number, + chosenReason: string, + formData: AvvikelseFormData + ): AvvikelseRequestData { + const avvikelseAlternativ: AvvikelseAlternativ = { + avvikelseorsakskod: chosenReason, + frageformular: formData.questions.map((question, index) => ({ + fraga: this.currentQuestions[index].id, + svar: question, + })), + rapporteringsdatum: formData.reportingDate, + }; + + return { genomforandeReferens, avvikelseAlternativ }; + } + + private clearQuestions(): void { + this.questionsFormArray.clear(); + this.currentQuestions = []; + } + + private addQuestionToForm(question: FragorForAvvikelser): void { + // FormArray doesnt hold any IDs so we need to store these seperately and rebuild structure at submit + this.currentQuestions.push(question); + + this.questionsFormArray.push( + new FormControl('', this.questionIsRequired(question) ? RequiredValidator('Frågan') : null) + ); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.module.ts similarity index 60% rename from apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module.ts rename to apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.module.ts index 563c93f..1d70ee9 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/deltagare-avvikelse.module.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.module.ts @@ -9,37 +9,37 @@ import { RouterModule } from '@angular/router'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module'; import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; -import { DeltagareConfirmFormModule } from './components/deltagare-confirm-form/deltagare-confirm-form.module'; -import { DeltagareFragorFormModule } from './components/deltagare-fragor-form/deltagare-fragor-form.module'; -import { DeltagareOrsaksFormModule } from './components/deltagare-orsaks-form/deltagare-orsaks-form.module'; -import { DeltagareTimePickerModule } from './components/deltagare-time-picker/deltagare-time-picker.module'; -import { DeltagareAvvikelseComponent } from './deltagare-avvikelse.component'; -import { DeltagareAvvikelseService } from './deltagare-avvikelse.service'; +import { DeltagareAvvikelserapportComponent } from './deltagare-avvikelserapport.component'; +import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base'; +import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; +import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; +import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; +import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog'; @NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA], - declarations: [DeltagareAvvikelseComponent], + declarations: [DeltagareAvvikelserapportComponent], imports: [ CommonModule, - RouterModule.forChild([{ path: '', component: DeltagareAvvikelseComponent }]), + RouterModule.forChild([{ path: '', component: DeltagareAvvikelserapportComponent }]), LayoutModule, ReactiveFormsModule, DigiNgFormRadiobuttonGroupModule, DigiNgFormDatepickerModule, DigiNgFormTextareaModule, DigiNgProgressProgressbarModule, - DeltagareOrsaksFormModule, - DeltagareFragorFormModule, - DeltagareTimePickerModule, - DeltagareConfirmFormModule, ReportLayoutModule, ConfirmDialogModule, BackLinkModule, DigiNgSkeletonBaseModule, + DigiNgFormSelectModule, + LoaderModule, + DigiNgFormInputModule, + DigiNgDialogModule, ], - providers: [DeltagareAvvikelseService], - exports: [DeltagareAvvikelseComponent], + providers: [DeltagareAvvikelserapportService], + exports: [DeltagareAvvikelserapportComponent], }) -export class DeltagareAvvikelseModule {} +export class DeltagareAvvikelserapportModule {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.service.ts new file mode 100644 index 0000000..53e966f --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { Avvikelse } from '@msfa-models/avvikelse.model'; +import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; +import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; +import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service'; +import { Observable } from 'rxjs'; +import { shareReplay } from 'rxjs/operators'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; + +@Injectable() +export class DeltagareAvvikelserapportService { + fragorForAvvikelser$: Observable = this.avvikelseApiService + .getFragorForAvvikelser$() + .pipe(shareReplay(1)); + + getAvvikelseOrsaker$: Observable = this.avvikelseApiService.getOrsaksKoderAvvikelse$(); + + constructor(private avvikelseApiService: AvvikelseApiService, private deltagareApiService: DeltagareApiService) {} + + createAvvikelse$(avvikelse: Avvikelse): Observable { + return this.avvikelseApiService.createAvvikelse$(avvikelse); + } + + fetchAvropInformation$(genomforandeReferens: number) { + return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/report-alternatives.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/report-alternatives.ts similarity index 57% rename from apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/report-alternatives.ts rename to apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/report-alternatives.ts index 9502e6f..02fbcb5 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelse/report-alternatives.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-avvikelserapport/report-alternatives.ts @@ -1,18 +1,6 @@ -import { ReportType } from '@msfa-enums/report-type.enum'; import { DayOrPartOfDay } from '@msfa-enums/day-or-part-of-day.enum'; import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; -export const avvikelseAlternatives: RadiobuttonModel[] = [ - { - label: 'Frånvaro', - value: ReportType.FRANVARO, - }, - { - label: 'Avvikelse', - value: ReportType.AVVIKELSE, - }, -]; - export const dayOrPartOfDay: RadiobuttonModel[] = [ { label: 'Heldag', 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 9fce8b1..ef576e7 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 @@ -2,10 +2,7 @@
@@ -35,66 +32,44 @@ id="gemensam-planering-form" > - - - - - -

- Varje gemensam planering måste innehålla de två obligatoriska aktiviteterna samt en frivillig aktivitet - som en del av det individuella stödet för varje deltagare. -

+ + + + +

+ Varje gemensam planering måste innehålla de två obligatoriska aktiviteterna samt en frivillig aktivitet + som en del av det individuella stödet för varje deltagare. +

+ + +
    +
  • + +
  • +
+ {{gpFormGroup.errors.activityIds}} +
+
- -
    -
  • - -
  • -
- {{gpFormGroup.errors.activityIds}} -
-
-
- -
-
Deltar arbetssökande på distans?
-
{{gpFormGroup.value.distance ? 'Ja' : 'Nej'}}
-
Aktiviteter
-
-
    -
  • - - {{activity.name}} -
  • -
-
-
-
{{error.message}}

- - Tillbaka - - - Förhandsgranska - - - Bekräfta och skicka in - + Bekräfta och skicka in + Avbryt
+ > +
+
Deltar arbetssökande på distans?
+
{{gpFormGroup.value.distance ? 'Ja' : 'Nej'}}
+
Aktiviteter
+
+
    +
  • + + {{activity.name}} +
  • +
+
+
+
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.scss index 3094b6b..4080376 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.scss +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.scss @@ -2,6 +2,8 @@ @import 'variables/gutters'; .gemensam-planering { + max-width: var(--digi--typography--text--max-width); + &__confirmation, &__form { position: relative; @@ -26,10 +28,6 @@ color: var(--digi--ui--color--border--success); } - &__alert { - max-width: var(--digi--typography--text--max-width); - } - &__footer { display: flex; flex-direction: column; @@ -40,15 +38,4 @@ display: flex; gap: var(--digi--layout--gutter); } - - ::ng-deep { - .digi-form-fieldset { - margin: 0; - - &__legend { - margin-bottom: var(--digi--layout--gutter--s); - padding: 0; - } - } - } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.ts index 0922900..2c1dd17 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.component.ts @@ -23,8 +23,6 @@ import { GemensamPlaneringValidator } from './gemensam-planering.validator'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class DeltagareGemensamPlaneringComponent { - totalAmountOfSteps = 2; - currentStep = 1; obligatoryActivityIds = [165, 188]; shouldValidate = false; RadiobuttonGroupDirection = RadiobuttonGroupDirection; @@ -109,22 +107,12 @@ export class DeltagareGemensamPlaneringComponent { } } - goToPreview(): void { + openConfirmDialog(): void { this.shouldValidate = true; if (this.gpFormGroup.invalid) { return; } - - this.currentStep = 2; - } - - goToStep1(): void { - this.shouldValidate = false; - this.currentStep = 1; - } - - openConfirmDialog(): void { this.confirmDialogOpen = true; } @@ -144,7 +132,6 @@ export class DeltagareGemensamPlaneringComponent { .postGemensamPlanering(mapGemensamPlaneringToGemensamPlaneringPostRequest(postRequest)) .then(() => { this._lastSubmittedGP$.next(new Date()); - this.currentStep = 3; }) .catch((error: Error) => { this._error$.next(new CustomError({ error, message: error.message, type: ErrorType.API })); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.html new file mode 100644 index 0000000..8bfebce --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.html @@ -0,0 +1,313 @@ + + +
+ +

Det går inte att rapportera frånvaro eftersom tjänsten inte har startad ännu.

+
+ + +
+ +

Avvikelserapport (frånvaro) för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen.

+
+
Datum
+
+ {{lastSubmittedFranvaroReport | date:'longDate'}} kl {{lastSubmittedFranvaroReport | date:'shortTime'}} +
+
+
+ Tillbaka till deltagaren +
+ +
+ +
+ +
+ +
+
+ + + +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+
+ + + + + + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+ + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+ +
+ +

Kunde inte spara Avvikelserapport (frånvaro). Ladda om sidan och försök igen.

+

{{error.message}}

+
+
+ Förhandsgranska + Avbryt +
+
+
+ +
+ +
Orsak till frånvaro
+
{{getReasonNameFromValue(reasons, reasonFormControl.value)}}
+
+ + +
Annan känd orsak
+
{{getReasonNameFromValue(otherKnownReasons, otherKnownReasonFormControl.value)}}
+
+ +
Beskrivning för frånvaro
+
{{knownReasonCommentFormControl.value}}
+
+
+
Datum
+
+
Hel eller del av dag
+
{{dayOrPartOfDayFromValue}}
+ +
Tid för frånvaro
+
{{startTimeFormControl.value}} - {{endTimeFormControl.value}}
+
+
Tid för förväntad närvaro
+
{{expectedPresenceStartTimeFormControl.value}} - {{expectedPresenceEndTimeFormControl.value}}
+
+
+
+
+
+
+
+ + + + + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.scss new file mode 100644 index 0000000..ee27625 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.scss @@ -0,0 +1,39 @@ +@import 'variables/gutters'; +@import 'variables/z-index'; + +.franvaro-report { + max-width: var(--digi--typography--text--max-width); + + &__confirmation, + &__form { + position: relative; + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + z-index: $msfa__z-index-default; + } + + &__time-pickers { + display: flex; + gap: var(--digi--layout--gutter); + } + + &__time-picker { + flex-grow: 1; + } + + &__footer { + display: flex; + flex-direction: column; + gap: var(--digi--layout--gutter); + } + + &__cta-wrapper { + display: flex; + gap: var(--digi--layout--gutter); + } + + &__validation-message { + margin-top: var(--digi--layout--gutter--s); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.spec.ts new file mode 100644 index 0000000..5e6e8fe --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.spec.ts @@ -0,0 +1,29 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; +import { FranvaroReportComponent } from './franvaro-report.component'; + +describe('FranvaroReportComponent', () => { + let component: FranvaroReportComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [FranvaroReportComponent, LayoutComponent], + imports: [RouterTestingModule, HttpClientTestingModule], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FranvaroReportComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.ts new file mode 100644 index 0000000..1e9e5c1 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.component.ts @@ -0,0 +1,187 @@ +import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { FormControl, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { ANNAN_KAND_ORSAK_ID, ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons'; +import { ConfirmDialog } from '@msfa-enums/confirm-dialog.enum'; +import { ErrorType } from '@msfa-enums/error-type.enum'; +import { Avrop } from '@msfa-models/avrop.model'; +import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Franvaro } from '@msfa-models/franvaro.model'; +import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; +import { dateToIsoString } from '@msfa-utils/format-to-date.util'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { map, shareReplay, switchMap } from 'rxjs/operators'; +import { FranvaroReportService } from './franvaro-report.service'; +import { FranvaroReportValidator } from './franvaro-report.validator'; + +@Component({ + selector: 'msfa-franvaro-report', + templateUrl: './franvaro-report.component.html', + styleUrls: ['./franvaro-report.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FranvaroReportComponent { + maxDate = new Date(); + shouldValidate$ = new BehaviorSubject(false); + confirmDialogOpen$ = new BehaviorSubject(false); + franvaroFormGroup = new FormGroup( + { + reason: new FormControl(null), + otherKnownReason: new FormControl(null), + knownReasonComment: new FormControl(''), + date: new FormControl(new Date()), + wholeDay: new FormControl(true), + startTime: new FormControl(null), + endTime: new FormControl(null), + expectedPresenceStartTime: new FormControl(null), + expectedPresenceEndTime: new FormControl(null), + }, + [FranvaroReportValidator.isFranvaroReportValid()] + ); + + error$ = new BehaviorSubject(null); + submitLoading$ = new BehaviorSubject(false); + lastSubmittedFranvaroReport$ = new BehaviorSubject(null); + currentGenomforandeReferens$: Observable = this.activatedRoute.params.pipe( + map(params => params.genomforandeReferens as string) + ); + avrop$: Observable = this.currentGenomforandeReferens$.pipe( + switchMap(genomforandeReferens => this.franvaroReportService.fetchAvropInformation$(+genomforandeReferens)), + shareReplay(1) + ); + reasons$: Observable = this.franvaroReportService.reasons$; + otherKnownReasons$: Observable = this.franvaroReportService.otherKnownReasons$; + + wholeDayOrPartOfDayRadiobuttons: RadiobuttonModel[] = [ + { label: 'Heldag', value: true }, + { label: 'Del av dag', value: false }, + ]; + + constructor(private franvaroReportService: FranvaroReportService, private activatedRoute: ActivatedRoute) {} + + get showOtherKnownReasonsSelect(): boolean { + return this.reasonFormControl.value === ANNAN_KAND_ORSAK_ID; + } + + get showKnownReasonTextArea(): boolean { + return this.otherKnownReasonFormControl.value === ANNAN_ORSAK_ID; + } + + get showTimePickers(): boolean { + return !this.wholeDayFormControl.value; + } + + get formErrors(): { [key: string]: string } { + return this.franvaroFormGroup.errors || {}; + } + + get reasonFormControl(): FormControl { + return this.franvaroFormGroup.get('reason') as FormControl; + } + get dateFormControl(): FormControl { + return this.franvaroFormGroup.get('date') as FormControl; + } + get wholeDayFormControl(): FormControl { + return this.franvaroFormGroup.get('wholeDay') as FormControl; + } + get startTimeFormControl(): FormControl { + return this.franvaroFormGroup.get('startTime') as FormControl; + } + get endTimeFormControl(): FormControl { + return this.franvaroFormGroup.get('endTime') as FormControl; + } + get expectedPresenceStartTimeFormControl(): FormControl { + return this.franvaroFormGroup.get('expectedPresenceStartTime') as FormControl; + } + get expectedPresenceEndTimeFormControl(): FormControl { + return this.franvaroFormGroup.get('expectedPresenceEndTime') as FormControl; + } + get otherKnownReasonFormControl(): FormControl { + return this.franvaroFormGroup.get('otherKnownReason') as FormControl; + } + get knownReasonCommentFormControl(): FormControl { + return this.franvaroFormGroup.get('knownReasonComment') as FormControl; + } + + getReasonNameFromValue(reasons: OrsaksKoderFranvaro[], value: string): string { + return reasons.find(reason => reason.value.toString() === value)?.name; + } + + get dayOrPartOfDayFromValue(): string { + return this.wholeDayFormControl.value ? 'Heldag' : 'Del av dag'; + } + + formControlIsInvalid(formControlNames: string[]): boolean { + return ( + formControlNames.some(formControlName => this.formErrors[formControlName]) && this.shouldValidate$.getValue() + ); + } + + openConfirmDialog(): void { + this.shouldValidate$.next(true); + if (this.franvaroFormGroup.invalid) { + return; + } + + this.confirmDialogOpen$.next(true); + } + + closeConfirmDialogAndProceed(confirmDialogAnswer: ConfirmDialog, genomforandeReferens: number): void { + this.confirmDialogOpen$.next(true); + + if (confirmDialogAnswer === ConfirmDialog.ACCEPTED) { + void this.postFranvaroReport(genomforandeReferens); + } + } + + async postFranvaroReport(genomforandeReferens: number): Promise { + this.submitLoading$.next(true); + + const { + reason, + date, + wholeDay, + startTime, + endTime, + otherKnownReason, + knownReasonComment, + expectedPresenceStartTime, + expectedPresenceEndTime, + } = this.franvaroFormGroup.value as Franvaro; + + const postRequest: FranvaroRequestData = { + genomforandeReferens, + franvaro: { + avvikelseOrsaksKod: reason, + datum: dateToIsoString(date), + heldag: wholeDay, + startTid: this.showTimePickers ? startTime : '0:00', // BÄR doesn't accept empty string or null + slutTid: this.showTimePickers ? endTime : '23:59', // BÄR doesn't accept empty string or null + alternativForKandaOrsaker: this.showOtherKnownReasonsSelect + ? { + typ: otherKnownReason, + motivering: this.showKnownReasonTextArea ? knownReasonComment : '', + } + : null, + forvantadNarvaro: { + startTid: expectedPresenceStartTime, + slutTid: expectedPresenceEndTime, + }, + }, + }; + + return this.franvaroReportService + .postFranvaroReport(postRequest) + .then(() => { + this.lastSubmittedFranvaroReport$.next(new Date()); + }) + .catch((error: Error) => { + this.error$.next(new CustomError({ error, message: error.message, type: ErrorType.API })); + }) + .finally(() => { + this.submitLoading$.next(false); + }); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.module.ts new file mode 100644 index 0000000..a229ba5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.module.ts @@ -0,0 +1,43 @@ +import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker'; +import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; +import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; +import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; +import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea'; +import { DigiNgFormValidationMessageModule } from '@af/digi-ng/_form/form-validation-message'; +import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base'; +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; +import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module'; +import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; +import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; +import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; +import { FranvaroReportComponent } from './franvaro-report.component'; +import { FranvaroReportService } from './franvaro-report.service'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [FranvaroReportComponent], + imports: [ + CommonModule, + RouterModule.forChild([{ path: '', component: FranvaroReportComponent }]), + ReactiveFormsModule, + LayoutModule, + ReportLayoutModule, + LoaderModule, + BackLinkModule, + ConfirmDialogModule, + DigiNgFormSelectModule, + DigiNgFormDatepickerModule, + DigiNgFormRadiobuttonGroupModule, + DigiNgSkeletonBaseModule, + DigiNgFormTextareaModule, + DigiNgFormInputModule, + DigiNgFormValidationMessageModule, + ], + providers: [FranvaroReportService], + exports: [FranvaroReportComponent], +}) +export class FranvaroReportModule {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.service.ts new file mode 100644 index 0000000..c7b3755 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Avrop } from '@msfa-models/avrop.model'; +import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; +import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; +import { FranvaroReportApiService } from '@msfa-services/api/franvaro-report.api.service'; +import { Observable } from 'rxjs'; + +@Injectable() +export class FranvaroReportService { + public reasons$: Observable = this.franvaroReportApiService.fetchReasons$(); + public otherKnownReasons$: Observable< + OrsaksKoderFranvaro[] + > = this.franvaroReportApiService.fetchOtherKnownReasons$(); + + constructor(private franvaroReportApiService: FranvaroReportApiService) {} + + public fetchAvropInformation$(genomforandeReferens: number): Observable { + return this.franvaroReportApiService.fetchAvropInformation$(genomforandeReferens); + } + + public async postFranvaroReport(requestData: FranvaroRequestData): Promise { + return this.franvaroReportApiService.postFranvaroReport$(requestData); + } +} 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 new file mode 100644 index 0000000..b742122 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-reports/franvaro-report/franvaro-report.validator.ts @@ -0,0 +1,114 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { ANNAN_KAND_ORSAK_ID, ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons'; +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])?$/; + +function isTimeValid(value: string): boolean { + return TIME_REGEX.test(value); +} + +export class FranvaroReportValidator { + static isFranvaroReportValid(): ValidatorFn { + return (c: AbstractControl): { [key: string]: string } => { + let errors: { [key: string]: string } = null; + const { + reason, + date, + wholeDay, + startTime, + endTime, + otherKnownReason, + knownReasonComment, + expectedPresenceStartTime, + expectedPresenceEndTime, + } = c.value as Franvaro; + + if (!reason) { + errors = { + ...errors, + reason: 'Orsak till frånvaro måste väljas', + }; + } + if (reason === ANNAN_KAND_ORSAK_ID) { + if (!otherKnownReason) { + errors = { + ...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', + }; + } + } + if (!date) { + errors = { + ...errors, + date: 'Dag för frånvaro måste väljas', + }; + } + if (!wholeDay) { + if (!startTime) { + errors = { + ...errors, + startTime: 'Starttid för frånvaro måste väljas', + }; + } else if (!isTimeValid(startTime)) { + errors = { + ...errors, + startTime: 'Felaktig tid för starttid (HH:MM)', + }; + } + if (!endTime) { + errors = { + ...errors, + endTime: 'Sluttid för frånvaro måste väljas', + }; + } else if (!isTimeValid(endTime)) { + errors = { + ...errors, + endTime: 'Felaktig tid för sluttid (HH:MM)', + }; + } + if (endTime && startTime && endTime < startTime) { + errors = { + ...errors, + expectedEndTimeIsBeforeStartTime: 'Sluttid för frånvaro får inte vara före starttid', + }; + } + } + if (!expectedPresenceStartTime) { + errors = { + ...errors, + expectedPresenceStartTime: 'Starttid för förväntad närvaro måste väljas', + }; + } else if (!isTimeValid(expectedPresenceStartTime)) { + errors = { + ...errors, + expectedPresenceStartTime: 'Felaktig tid för starttid för förväntad närvaro (HH:MM)', + }; + } + if (!expectedPresenceEndTime) { + errors = { + ...errors, + expectedPresenceEndTime: 'Sluttid för förväntad närvaro måste väljas', + }; + } else if (!isTimeValid(expectedPresenceEndTime)) { + errors = { + ...errors, + expectedPresenceEndTime: 'Felaktig tid för sluttid för förväntad närvaro (HH:MM)', + }; + } + + if (expectedPresenceEndTime && expectedPresenceStartTime && expectedPresenceEndTime < expectedPresenceStartTime) { + errors = { + ...errors, + expectedPresenceEndTimeIsBeforeStartTime: 'Sluttid för förväntad närvaro får inte vara före starttid', + }; + } + return errors; + }; + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.html b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.html index c376d2b..093147c 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.html +++ b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.html @@ -1,4 +1,4 @@ - - + + diff --git a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.scss b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.scss index de25bd1..13ba8b9 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.scss +++ b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.scss @@ -1,5 +1,12 @@ +@import 'mixins/buttons'; @import 'mixins/link'; .back-link { - @include msfa__link(true); + &--link { + @include msfa__link(true); + } + + &--button { + @include msfa__button('secondary'); + } } diff --git a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.ts b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.ts index bfd5dd6..9ed6f7c 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.ts +++ b/apps/mina-sidor-fa/src/app/shared/components/back-link/back-link.component.ts @@ -8,6 +8,17 @@ import { IconType } from '@msfa-enums/icon-type.enum'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class BackLinkComponent { + private readonly _defaultClass = 'back-link'; @Input() route: string[]; + @Input() showIcon = true; + @Input() asButton = false; iconType = IconType; + + get backLinkClass(): string { + if (this.asButton) { + return `${this._defaultClass} ${this._defaultClass}--button`; + } + + return `${this._defaultClass} ${this._defaultClass}--link`; + } } diff --git a/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.html b/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.html index a6a3b5f..0c9169a 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.html +++ b/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.html @@ -1,14 +1,14 @@ -

Är du säker på att du vill skicka in en {{reportToConfirm}}?

+
diff --git a/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.ts b/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.ts index 1d71865..1f1801e 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.ts +++ b/apps/mina-sidor-fa/src/app/shared/components/confirm-dialog/confirm-dialog.component.ts @@ -8,17 +8,15 @@ import { ConfirmDialog } from '@msfa-enums/confirm-dialog.enum'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ConfirmDialogComponent { - @Input() openConfirmDialog: boolean; - @Input() reportToConfirm: string; + @Input() dialogOpen: boolean; + @Input() dialogTitle = 'Bekräfta'; + @Input() ariaLabel = 'Bekräfta för att gå vidare'; + @Input() primaryButtonText = 'Skicka'; + @Input() secondaryButtonText = 'Avbryt'; @Output() confirmDialogChanged = new EventEmitter(); - sendRequest(): void { - this.openConfirmDialog = false; - this.confirmDialogChanged.emit(ConfirmDialog.ACCEPTED); - } - - closeConfirmDialog(): void { - this.openConfirmDialog = false; - this.confirmDialogChanged.emit(ConfirmDialog.DISMISSED); + closeDialog(confirmed: boolean): void { + this.dialogOpen = false; + this.confirmDialogChanged.emit(confirmed ? ConfirmDialog.ACCEPTED : ConfirmDialog.DISMISSED); } } diff --git a/apps/mina-sidor-fa/src/app/shared/constants/franvaro-reasons.ts b/apps/mina-sidor-fa/src/app/shared/constants/franvaro-reasons.ts new file mode 100644 index 0000000..ba2fff9 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/constants/franvaro-reasons.ts @@ -0,0 +1,2 @@ +export const ANNAN_KAND_ORSAK_ID = '18'; +export const ANNAN_ORSAK_ID = '5'; diff --git a/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts b/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts index 056c715..46c1425 100644 --- a/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts +++ b/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts @@ -1,7 +1,8 @@ export const DELTAGARE_REPORTING_ROUTES = { 'gemensam-planering': 'Gemensam planering', 'periodisk-redovisning': 'Periodisk redovisning', - avvikelserapport: 'Avvikelserapport', + franvarorapport: 'Avvikelserapport (frånvaro)', + avvikelserapport: 'Avvikelserapport (avvikelse)', }; export const NAVIGATION = { 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 0bb8c1c..b77d3e7 100644 --- a/apps/mina-sidor-fa/src/app/shared/constants/regex.ts +++ b/apps/mina-sidor-fa/src/app/shared/constants/regex.ts @@ -1 +1,2 @@ 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]))$/; diff --git a/apps/mina-sidor-fa/src/app/shared/enums/avvikelse-orsak-kod.enum.ts b/apps/mina-sidor-fa/src/app/shared/enums/avvikelse-orsak-kod.enum.ts deleted file mode 100644 index 5ead09a..0000000 --- a/apps/mina-sidor-fa/src/app/shared/enums/avvikelse-orsak-kod.enum.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum AvvikelseOrsaksKodEnum { - TackatNejTillInsatsEllerAktivitet = 19, - TackatNejTillErbjudetArbete = 20, - KanInteTillGodoGoraSigProgrammet = 21, - MisskottSigEllerStortVerksamheten = 22, - SerTillAttErbjudetArbeteInteKommerTillStand = 28 -} diff --git a/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts b/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts index 1d11f51..cbe142d 100644 --- a/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts +++ b/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts @@ -2,6 +2,6 @@ export enum ReportType { FRANVARO = 'franvaro', AVVIKELSE = 'avvikelse', GemensamPlanering = 'Gemensam planering', - Franvaro = 'Frånvaro', - Avvikelse = 'Avvikelse', + Avvikelse = 'Avvikelserapport (avvikelse)', + Franvaro = 'Avvikelserapport (frånvaro)', } diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/avrop.response.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/avrop.response.model.ts index 1672bd4..5742f90 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/api/avrop.response.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/api/avrop.response.model.ts @@ -29,7 +29,7 @@ export interface AvropResponse { sparNamn: string; handledareCiamUserId: string; handledare: string; - recievedTimestamp: string; + recievedTimestamp: Date; } export interface AvropApiResponse { diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/orsaks-koder-franvaro.response.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/orsaks-koder-franvaro.response.model.ts index d0d6f2c..12acb3d 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/api/orsaks-koder-franvaro.response.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/api/orsaks-koder-franvaro.response.model.ts @@ -1,5 +1,4 @@ export interface OrsaksKoderFranvaroResponse { id: number; name: string; - state: number; } diff --git a/apps/mina-sidor-fa/src/app/shared/models/avrop.model.ts b/apps/mina-sidor-fa/src/app/shared/models/avrop.model.ts index 3410848..c2c7525 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/avrop.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/avrop.model.ts @@ -24,6 +24,7 @@ export interface Avrop extends AvropCompact { utforandeVerksamhet: string; // utforandeverksamhet handledareCiamUserId: string; handledare: string; + recievedTimestamp: Date; } export interface AvropCompactData { @@ -49,6 +50,7 @@ export function mapAvropResponseToAvrop(data: AvropResponse): Avrop { utforandeverksamhet, handledareCiamUserId, handledare, + recievedTimestamp, } = data; return { @@ -69,5 +71,6 @@ export function mapAvropResponseToAvrop(data: AvropResponse): Avrop { utforandeVerksamhet: utforandeverksamhet, handledareCiamUserId: handledareCiamUserId, handledare, + recievedTimestamp, }; } diff --git a/apps/mina-sidor-fa/src/app/shared/models/avvikelse-alternativ.model.ts b/apps/mina-sidor-fa/src/app/shared/models/avvikelse-alternativ.model.ts deleted file mode 100644 index 87c422f..0000000 --- a/apps/mina-sidor-fa/src/app/shared/models/avvikelse-alternativ.model.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Fraga } from './fraga.model'; - -export interface AvvikelseAlternativ { - avvikelseorsakskod: string, - frageformular: Array, - rapporteringsdatum: string -} diff --git a/apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts b/apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts index a847beb..adb2402 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts @@ -1,5 +1,11 @@ -import { AvvikelseAlternativ } from './avvikelse-alternativ.model'; import { FranvaroAlternativ } from './franvaro-alternativ.model'; +import { Fraga } from '@msfa-models/fraga.model'; + +export interface AvvikelseAlternativ { + avvikelseorsakskod: string; + frageformular: Fraga[]; + rapporteringsdatum: string; +} export interface Avvikelse { genomforandeReferens: number; diff --git a/apps/mina-sidor-fa/src/app/shared/models/date-format-options.model.ts b/apps/mina-sidor-fa/src/app/shared/models/date-format-options.model.ts index b81b130..7171ab0 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/date-format-options.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/date-format-options.model.ts @@ -1,6 +1,6 @@ export interface DateFormatOptions { - year?: 'short' | 'long' | 'numeric'; + year?: 'numeric' | '2-digit'; month?: 'short' | 'long' | 'numeric'; - day?: 'short' | 'long' | 'numeric'; - weekday?: 'short' | 'long' | 'numeric'; + day?: 'numeric' | '2-digit'; + weekday?: 'short' | 'long' | 'narrow'; } diff --git a/apps/mina-sidor-fa/src/app/shared/models/franvaro-alternativ.model.ts b/apps/mina-sidor-fa/src/app/shared/models/franvaro-alternativ.model.ts index a921fb0..2a2367b 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/franvaro-alternativ.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/franvaro-alternativ.model.ts @@ -2,8 +2,8 @@ export interface FranvaroAlternativ { avvikelseOrsaksKod: string; datum: string; heldag: boolean; - startTid: string; - slutTid: string; + startTid: string | null; + slutTid: string | null; forvantadNarvaro: { startTid: string; slutTid: string; diff --git a/apps/mina-sidor-fa/src/app/shared/models/franvaro.model.ts b/apps/mina-sidor-fa/src/app/shared/models/franvaro.model.ts new file mode 100644 index 0000000..5d2bce9 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/franvaro.model.ts @@ -0,0 +1,11 @@ +export interface Franvaro { + reason: string; + date: Date; + wholeDay: boolean; + startTime: string; + endTime: string; + expectedPresenceStartTime: string; + expectedPresenceEndTime: string; + otherKnownReason: string; + knownReasonComment: string; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-avvikelse.model.ts b/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-avvikelse.model.ts index 4758209..093f600 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-avvikelse.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-avvikelse.model.ts @@ -1,9 +1,9 @@ -import { AvvikelseOrsaksKodEnum } from '@msfa-enums/avvikelse-orsak-kod.enum'; import { OrsaksKoderAvvikelseResponse } from './api/orsaks-koder-avvikelse.response.model'; +// TODO rename to AvvikelseOrsaker export interface OrsaksKoderAvvikelse { name: string; - value: AvvikelseOrsaksKodEnum; + id: string; //AvvikelseOrsaksKodEnum state: number; } @@ -12,7 +12,7 @@ export function mapResponseToOrsaksKoderAvvikelse(data: OrsaksKoderAvvikelseResp return { name, - value: id, - state - } + id: id.toString(), + state, + }; } diff --git a/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-franvaro.model.ts b/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-franvaro.model.ts index 38ae8bb..0f2a055 100644 --- a/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-franvaro.model.ts +++ b/apps/mina-sidor-fa/src/app/shared/models/orsaks-koder-franvaro.model.ts @@ -5,7 +5,6 @@ import { OrsaksKoderFranvaroResponse } from './api/orsaks-koder-franvaro.respons export interface OrsaksKoderFranvaro { name: string; value: FranvaroOrsaksKodEnum; - state: number; index?: number; } @@ -15,13 +14,12 @@ export interface KandaAvvikelseKoder { } export function mapResponseToOrsaksKoderFranvaro(data: OrsaksKoderFranvaroResponse): OrsaksKoderFranvaro { - const { name, id, state } = data; + const { name, id } = data; return { name, value: id, - state - } + }; } export function mapResponseToAndraKandaOrsaker(data: KandaAvvikelseKoderResponse): KandaAvvikelseKoder { @@ -29,6 +27,6 @@ export function mapResponseToAndraKandaOrsaker(data: KandaAvvikelseKoderResponse return { name, - value: id - } + value: id, + }; } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts index 382dd59..660eb23 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts @@ -14,7 +14,9 @@ import { OrsaksKoderFranvaro, } from '@msfa-models/orsaks-koder-franvaro.model'; import { Observable } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; +import { catchError, filter, map } from 'rxjs/operators'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { ErrorType } from '@msfa-enums/error-type.enum'; @Injectable({ providedIn: 'root', @@ -56,8 +58,16 @@ export class AvvikelseApiService { ); } - public createAvvikelse$(avvikelse: Avvikelse): Promise { - return this.httpClient.post(`${this._apiBaseUrl}/avvikelse`, avvikelse).toPromise(); + public createAvvikelse$(avvikelse: Avvikelse): Observable { + return this.httpClient.post(`${this._apiBaseUrl}/avvikelse`, avvikelse).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: 'Det gick inte att skicka avvikelse \n\n' + error.message, + type: ErrorType.API, + }); + }) + ); } public createFranvaro$(avvikelse: Avvikelse): Promise { diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts new file mode 100644 index 0000000..45ff60f --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts @@ -0,0 +1,53 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from '@msfa-environment'; +import { OrsaksKoderFranvaroResponse } from '@msfa-models/api/orsaks-koder-franvaro.response.model'; +import { Avrop } from '@msfa-models/avrop.model'; +import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; +import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; +import { mapResponseToOrsaksKoderFranvaro, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { Observable } from 'rxjs'; +import { catchError, filter, map, shareReplay } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root', +}) +export class FranvaroReportApiService { + private _apiBaseUrl = `${environment.api.url}/rapporter`; + + constructor(private httpClient: HttpClient, private deltagareApiService: DeltagareApiService) {} + + public fetchReasons$(): Observable { + return this.httpClient.get<{ data: OrsaksKoderFranvaroResponse[] }>(`${this._apiBaseUrl}/orsakskoderfranvaro`).pipe( + filter(response => !!response?.data), + map(({ data }) => data.map(reason => mapResponseToOrsaksKoderFranvaro(reason))), + catchError((error: Error & { status: number }) => { + throw new CustomError( + errorToCustomError({ ...error, message: `Kunde inte hämta orsaker till frånvaro.\n\n${error.message}` }) + ); + }), + shareReplay(1) + ); + } + public fetchOtherKnownReasons$(): Observable { + return this.httpClient.get<{ data: OrsaksKoderFranvaroResponse[] }>(`${this._apiBaseUrl}/kandaavvikelsekoder`).pipe( + filter(response => !!response?.data), + map(({ data }) => data.map(reason => mapResponseToOrsaksKoderFranvaro(reason))), + catchError((error: Error & { status: number }) => { + throw new CustomError( + errorToCustomError({ ...error, message: `Kunde inte hämta kända orsaker till frånvaro.\n\n${error.message}` }) + ); + }), + shareReplay(1) + ); + } + + public fetchAvropInformation$(genomforandeReferens: number): Observable { + return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); + } + + public async postFranvaroReport$(requestData: FranvaroRequestData): Promise { + return this.httpClient.post(`${this._apiBaseUrl}/franvaro`, requestData).toPromise(); + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/format-to-date.util.ts b/apps/mina-sidor-fa/src/app/shared/utils/format-to-date.util.ts index c7784f4..c5c97c1 100644 --- a/apps/mina-sidor-fa/src/app/shared/utils/format-to-date.util.ts +++ b/apps/mina-sidor-fa/src/app/shared/utils/format-to-date.util.ts @@ -1,3 +1,5 @@ +import { DateFormatOptions } from '@msfa-models/date-format-options.model'; + // Takes either 6 or 8 characters string (YYYYMMDD) and formats it to ISO standard (YYYY-MM-DD). export function formatToIsoString(date: string): string { if (date.length === 6) { @@ -16,3 +18,13 @@ export function formatToDate(date: string): Date { return new Date(`${year}-${month}-${day}`); } + +export function dateToIsoString(date: Date, locale: string = 'sv-SE'): string { + const formatOptions: DateFormatOptions = { + year: 'numeric', + month: 'numeric', + day: 'numeric', + }; + + return new Date(date).toLocaleDateString(locale, formatOptions); +} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/avvikelse-form-validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/avvikelse-form-validator.ts deleted file mode 100644 index 87b668d..0000000 --- a/apps/mina-sidor-fa/src/app/shared/utils/validators/avvikelse-form-validator.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { AbstractControl, ValidatorFn } from '@angular/forms'; -import { ReportType } from '@msfa-enums/report-type.enum'; -import { DayOrPartOfDay } from '@msfa-enums/day-or-part-of-day.enum'; -import { FranvaroOrsaksKodEnum } from '@msfa-enums/franvaro-orsak-kod.enum'; -import { KandaOrsakerEnum } from '@msfa-enums/kanda-orsaker-kod.enum'; -import { ValidationError } from '@msfa-models/validation-error.model'; - -export interface Controls { - [key: string]: AbstractControl; -} - -export function requiredDescriptionValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.controls as Controls; - - if (ctrls) { - const valueOfNestedFormControl = ctrls['orsakerFormGroup'].get('andraKandaOrsaker').value as string; - const valueOfFormControl = control.value as string; - const isRequired = !valueOfFormControl && +valueOfNestedFormControl === KandaOrsakerEnum.AnnanOrsak; - - if (isRequired) { - return { type: 'required', message: 'Beskrivning är obligatoriskt' }; - } - - return null; - } - }; -} - -export function requiredOrsakerValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.controls as Controls; - - if (ctrls) { - const valueOfNestedFormControl = ctrls['orsaker'].value as string; - const isRequired = !valueOfNestedFormControl && !ctrls['andraKandaOrsaker'].value; - - if (isRequired) { - return { type: 'required', message: `Orsak är obligatoriskt` }; - } - - return null; - } - }; -} - -export function requiredAnnanKandOrsakValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.controls as Controls; - - if (ctrls) { - const isAnnanKandOrsak = +ctrls['orsaker'].value === FranvaroOrsaksKodEnum.AnnanKandOrsak; - const valueOfNestedFormControl = ctrls['andraKandaOrsaker'].value as string; - const isRequired = isAnnanKandOrsak && !valueOfNestedFormControl; - - if (isRequired) { - return { type: 'required', message: `Annan orsak är obligatoriskt` }; - } - - return null; - } - }; -} - -export class RequiredDateValidator { - static CheckIfRequired(): ValidatorFn { - return (fg: AbstractControl): { [key: string]: string } => { - const valueOfFormControl = fg?.get('date')?.value as string; - const isRequired = !valueOfFormControl; - - return isRequired ? { dateIsRequired: 'Datum är obligatoriskt' } : null; - }; - } -} - -export function requiredDayOrPartOfDayValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.controls as Controls; - - if (ctrls) { - const isFranvaro = ctrls['alternative'].value === ReportType.FRANVARO; - const valueOfFormControl = control.value as string; - const isRequired = isFranvaro && !valueOfFormControl; - - if (isRequired) { - return { type: 'required', message: `Hel- eller del av dag är obligatoriskt` }; - } - - return null; - } - }; -} - -export function requiredStartTimeValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.parent?.controls as Controls; - - if (ctrls) { - const isFranvaro = (ctrls['alternative']?.value as string) === ReportType.FRANVARO; - const isPartOfDay = ctrls['dayOrPartOfDay']?.value === DayOrPartOfDay.DEL_AV_DAG; - const valueOfFormControl = control?.value as string; - const isRequired = isFranvaro && isPartOfDay && (valueOfFormControl === '' || valueOfFormControl === null); - - if (isRequired) { - return { type: 'required', message: `Starttid är obligatoriskt` }; - } - - return null; - } - }; -} - -export function requiredEndTimeValidator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.parent?.controls as Controls; - - if (ctrls) { - const isFranvaro = (ctrls['alternative']?.value as string) === ReportType.FRANVARO; - const isPartOfDay = ctrls['dayOrPartOfDay']?.value === DayOrPartOfDay.DEL_AV_DAG; - const valueOfFormControl = control?.value as string; - const isRequired = isFranvaro && isPartOfDay && (valueOfFormControl === '' || valueOfFormControl === null); - - if (isRequired) { - return { type: 'required', message: `Sluttid är obligatoriskt` }; - } - - return null; - } - }; -} - -export function requiredFraga1Validator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.parent?.controls as Controls; - - if (ctrls) { - const isAvvikelse = ctrls['alternative']?.value === 'avvikelse'; - const valueOfFormControl = control.value as string; - const isRequired = isAvvikelse && !valueOfFormControl; - - if (isRequired) { - return { type: 'required', message: `Beskrivning är obligatoriskt` }; - } - - return null; - } - }; -} - -export function requiredfraga2Validator(): ValidatorFn { - return (control: AbstractControl): ValidationError => { - const ctrls = control?.parent?.parent?.controls as Controls; - - if (ctrls) { - const isAvvikelse = ctrls['alternative']?.value === 'avvikelse'; - const valueOfFormControl = control.value as string; - const orsaksKodToValidate = ctrls['orsakerFormGroup']?.get('orsaker')?.value as string; - const isRequired = - isAvvikelse && - !valueOfFormControl && - orsaksKodToValidate !== '19' && - orsaksKodToValidate !== '20' && - orsaksKodToValidate !== '28'; - - if (isRequired) { - return { type: 'required', message: `Beskrivning är obligatoriskt` }; - } - - return null; - } - }; -} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/validators/date.validator.ts b/apps/mina-sidor-fa/src/app/shared/utils/validators/date.validator.ts new file mode 100644 index 0000000..7e1688e --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/validators/date.validator.ts @@ -0,0 +1,21 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { ISO_DATE_NO_TIME } from '@msfa-constants/regex'; +import { ValidationError } from '@msfa-models/validation-error.model'; + +export function isoDateIsValid(date: string): boolean { + return ISO_DATE_NO_TIME.test(date); +} + +export function isoDateWithoutTimeValidator(): ValidatorFn { + return (control: AbstractControl): ValidationError => { + if (control && control.value) { + const value: string = control.value as string; + + if (!isoDateIsValid(value)) { + return { type: 'invalid', message: `Ogiltigt datum, vänligen ange YYYY-MM-DD` }; + } + } + + return null; + }; +} diff --git a/apps/mina-sidor-fa/src/styles/mixins/_buttons.scss b/apps/mina-sidor-fa/src/styles/mixins/_buttons.scss index 1a85a72..d361567 100644 --- a/apps/mina-sidor-fa/src/styles/mixins/_buttons.scss +++ b/apps/mina-sidor-fa/src/styles/mixins/_buttons.scss @@ -35,7 +35,7 @@ @if $type == 'secondary' { background-color: var(--digi-button--background--secondary--hover); - color: var(--digi-button--color--secondary--hover); + color: var(--digi-button--color--secondary); } @else if $type == 'tertiary' { color: var(--digi-button--color--tertiary--hover); } @else { diff --git a/apps/mina-sidor-fa/src/styles/styles.scss b/apps/mina-sidor-fa/src/styles/styles.scss index 4d7a880..9533fcf 100644 --- a/apps/mina-sidor-fa/src/styles/styles.scss +++ b/apps/mina-sidor-fa/src/styles/styles.scss @@ -66,6 +66,16 @@ dl { left: 0; } +// Removing margins from digi fieldset component. +.digi-form-fieldset { + margin: 0; + + &__legend { + margin-bottom: var(--digi--layout--gutter--s); + padding: 0; + } +} + .msfa { &__a11y-sr-only { @include msfa__a11y-sr-only;