feat(periodisk-redovisning): Added dialog when changing period to either keep/discard formstate. (TV-800)

Squashed commit of the following:

commit 6da28385733d69771335efd9cdf44c4b3e6257a7
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Oct 21 13:01:29 2021 +0200

    Updated texts

commit 5d3f2ad73fe57251a2e078f31be7a20146321770
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Oct 21 12:52:05 2021 +0200

    Capitalized month

commit 6f89951aa6e7811731dca07b12c56ca1b4846427
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Oct 21 11:29:44 2021 +0200

    Styling changes

commit 9bc2ff2d929f6ac00671351069be81fc101e0f2e
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Oct 21 10:22:02 2021 +0200

    Added dialog to confirm after change of period

commit 8560cbe835b0a49945aa826b317dcfa82fbb3663
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Thu Oct 21 08:03:52 2021 +0200

    Removed old periodisk redovisning component
This commit is contained in:
Erik Tiekstra
2021-10-21 14:21:58 +02:00
parent 2e01e79cf7
commit 9fc6f40c45
14 changed files with 200 additions and 419 deletions

View File

@@ -7,35 +7,35 @@
<digi-ng-link-button
class="deltagare-tab-reports__button"
afRoute="./gemensam-planering"
afText="Skapa ny Gemensam planering"
afText="Gemensam planering"
></digi-ng-link-button>
</li>
<li>
<digi-ng-link-button
class="deltagare-tab-reports__button"
afRoute="./franvarorapport"
afText="Skapa ny Avvikelserapport (frånvaro)"
afText="Avvikelserapport (frånvaro)"
></digi-ng-link-button>
</li>
<li>
<digi-ng-link-button
class="deltagare-tab-reports__button"
afRoute="./avvikelserapport"
afText="Skapa ny Avvikelserapport (avvikelse)"
afText="Avvikelserapport (avvikelse)"
></digi-ng-link-button>
</li>
<li *ngIf="periodiskRedovisningButtonVisible">
<digi-ng-link-button
class="deltagare-tab-reports__button"
afRoute="./periodisk-redovisning"
afText="Skapa ny Periodisk redovisning"
afText="Periodisk redovisning"
></digi-ng-link-button>
</li>
<li *ngIf="signalButtonVisible">
<digi-ng-link-button
class="deltagare-tab-reports__button"
afRoute="./signal"
afText="Skapa ny Signal om arbete eller studier"
afText="Signal om arbete eller studier"
></digi-ng-link-button>
</li>
</ul>

View File

@@ -1,9 +0,0 @@
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.pr-form {
padding: $digi--layout--gutter--xl 0;
&__space-top {
margin-top: $digi--layout--gutter--xl;
}
}

View File

@@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PeriodiskRedovisningFormComponent } from './periodisk-redovisning-form.component';
describe('PeriodiskRedovisningFormComponent', () => {
let component: PeriodiskRedovisningFormComponent;
let fixture: ComponentFixture<PeriodiskRedovisningFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PeriodiskRedovisningFormComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PeriodiskRedovisningFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,15 +0,0 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'msfa-periodisk-redovisning-form',
templateUrl: './periodisk-redovisning-form.component.html',
styleUrls: ['./periodisk-redovisning-form.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PeriodiskRedovisningFormComponent {
@Input() periodiskRedovisningFormGroup: FormGroup;
@Input() totalAmountOfSteps: number;
@Input() currentStep: number;
@Output() submitPRFormGroup = new EventEmitter<FormGroup>();
}

View File

@@ -1,13 +0,0 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { PeriodiskRedovisningFormComponent } from './periodisk-redovisning-form.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [PeriodiskRedovisningFormComponent],
imports: [
CommonModule,
],
exports: [PeriodiskRedovisningFormComponent]
})
export class PeriodiskRedovisningFormModule { }

View File

@@ -1,66 +0,0 @@
<msfa-layout>
<msfa-report-layout
[currentStep]="currentStep"
[endDate]="'2021-09-30'"
[isPeriodDate]="true"
[startDate]="'2021-09-01'"
[totalAmountOfSteps]="totalAmountOfSteps"
reportSubTitle="Skapa redovisning"
reportTitle="Periodisk Redovisning">
<form
*ngIf="periodiskRedovisningFormGroup"
[formGroup]="periodiskRedovisningFormGroup"
class="periodisk-redovisning">
<ng-container *ngIf="currentStep === 1">
<p>Har ni lämnat individuella förslag på arbeten till arbetssökande under perioden?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="lamnatJobbForslagFormControlName"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
*ngIf="submitted && lamnatJobbForslagFormControl.invalid"
af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
<p class="periodisk-redovisning__space-top">Har ni, under perioden, tillhandahållit språkstöd?</p>
<digi-ng-form-radiobutton-group
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControlName]="providedSprakStodFormControlName"
></digi-ng-form-radiobutton-group>
<digi-form-validation-message
*ngIf="submitted && providedSprakStodFormControl.invalid"
af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
</ng-container>
<div class="periodisk-redovisning__step-buttons-wrapper">
<br/>
<ng-container *ngIf="currentStep > 1">
<digi-button (afOnClick)="previousStep()"
af-size="m" af-variation="secondary" class="periodisk-redovisning__step-buttons-wrapper--space-right">
Tillbaka
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep < (totalAmountOfSteps -1)">
<digi-button (afOnClick)="nextStep()"
af-size="m" class="periodisk-redovisning__step-buttons-wrapper">
Nästa
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === (totalAmountOfSteps -1)">
<digi-button (afOnClick)="nextStep()" af-size="m">
Förhandsgranska
</digi-button>
</ng-container>
<ng-container *ngIf="currentStep === totalAmountOfSteps">
<digi-button (afOnClick)="sendRequest(true)" af-size="m">
Skicka in
</digi-button>
</ng-container>
</div>
</form>
</msfa-report-layout>
</msfa-layout>

View File

@@ -1,15 +0,0 @@
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
.periodisk-redovisning {
&__step-buttons-wrapper--space-right {
margin-right: var(--digi--layout--gutter--s);
}
&__space-top {
margin-top: $digi--layout--gutter--xl;
}
&__step-buttons-wrapper {
padding-top: $digi--layout--gutter--xxl;
}
}

View File

@@ -1,23 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
describe('DeltagarePeriodiskRedovisningComponent', () => {
let component: DeltagarePeriodiskRedovisningComponent;
let fixture: ComponentFixture<DeltagarePeriodiskRedovisningComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DeltagarePeriodiskRedovisningComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DeltagarePeriodiskRedovisningComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,130 +0,0 @@
import { RadiobuttonGroupDirection } from '@af/digi-ng/_form/form-radiobutton-group';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { Activity, SubActivity } from '@msfa-models/activity.model';
import { RequiredValidator } from '@msfa-utils/validators/required.validator';
@Component({
selector: 'msfa-deltagare-periodisk-redovisning',
templateUrl: './deltagare-periodisk-redovisning.component.html',
styleUrls: ['./deltagare-periodisk-redovisning.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DeltagarePeriodiskRedovisningComponent {
radiobuttonGroupDirection = RadiobuttonGroupDirection;
totalAmountOfSteps = 3;
currentStep = 1;
moveToNextStep = false;
periodiskRedovisningFormGroup: FormGroup;
submitted = false;
readonly lamnatJobbForslagFormControlName = 'lamnatJobbForslag';
readonly providedSprakStodFormControlName = 'providedSprakStod';
readonly activitiesFormArrayName = 'activities';
readonly datesForActivitiesFormArrayName = 'datesForActivities';
readonly subActivitiesFormArrayName = 'subActivities';
get lamnatJobbForslagFormControl(): AbstractControl {
return this.periodiskRedovisningFormGroup.get(this.lamnatJobbForslagFormControlName);
}
get providedSprakStodFormControl(): AbstractControl {
return this.periodiskRedovisningFormGroup.get(this.providedSprakStodFormControlName);
}
get activitiesFormArray(): FormArray {
return this.periodiskRedovisningFormGroup.get(this.activitiesFormArrayName) as FormArray;
}
initializePeriodiskRedovisningFormGroup(activitiesList: Activity[]): void {
this.periodiskRedovisningFormGroup = new FormGroup({
lamnatJobbForslag: new FormControl(null, [RequiredValidator()]),
providedSprakStod: new FormControl(null, [RequiredValidator()]),
activities: new FormArray([]),
});
this.getActivitesFormArray(activitiesList);
}
getActivitesFormArray(activities: Activity[]): void {
activities.forEach(activity => {
const newActivity = [`activity${activity.id}`, 'datesForActivities', 'subActivities', 'comment'];
this.activitiesFormArray.push(
new FormGroup(
Object.fromEntries(
newActivity.map(formCtrlName => [formCtrlName, this.getActivtiesFormField(formCtrlName, activity)])
)
)
);
});
}
getActivtiesFormField(formCtrlName: string, activity: Activity): FormArray | FormControl {
if (formCtrlName === 'datesForActivities') {
return new FormArray([]);
}
return new FormControl(null, []);
}
addSelectedDatesToFormArray(datesList: string[]): FormArray {
// TODO: Använd denna metod när datumen valts i kalendern!
const formcontrolNamesList = ['date', 'hours', 'doneOnRemote'];
const datesForActivitiesFormArray = new FormArray([]);
for (let i = 0; i < datesList.length; i++) {
datesForActivitiesFormArray.push(
new FormGroup(
Object.fromEntries(formcontrolNamesList.map(formCtrlName => [formCtrlName, new FormControl(null, [])]))
)
);
}
return datesForActivitiesFormArray;
}
addSubActivitesFormArray(subActivities: SubActivity[], activityId: number): FormArray {
// TODO: lägg till if-sats ex: if !subActivities etc.
if (!subActivities) {
return;
}
const subActivitiesList = subActivities.map(activity => [`activity${activity.id}`]);
const subActivitiesFormArray = new FormArray([]);
if (activityId === 188 || activityId === 162) {
subActivitiesList.forEach(activity => {
subActivitiesFormArray.push(
new FormGroup(Object.fromEntries(activity.map(formCtrlName => [formCtrlName, new FormControl(null, [])])))
);
});
}
return subActivitiesFormArray;
}
getActivityId(formCtrlName: string): number {
if (!formCtrlName.startsWith('activity')) {
return;
}
return Number(formCtrlName.replace('activity', ''));
}
nextStep(): void {
this.submitted = true;
console.log('TESSSSST:::', this.periodiskRedovisningFormGroup.getRawValue());
this.moveToNextStep = true;
if (this.currentStep === 1 && this.lamnatJobbForslagFormControl.valid && this.providedSprakStodFormControl.valid) {
this.moveToNextStep = false;
this.currentStep++;
} else if (this.periodiskRedovisningFormGroup.valid && this.currentStep === this.totalAmountOfSteps - 2) {
this.currentStep++;
}
}
previousStep(): void {
this.moveToNextStep = false;
if (this.currentStep > 1) {
this.currentStep--;
}
}
sendRequest(val: boolean): boolean {
return val;
}
}

View File

@@ -1,25 +0,0 @@
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { PeriodiskRedovisningFormModule } from './components/periodisk-redovisning-form/periodisk-redovisning-form.module';
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagarePeriodiskRedovisningComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: DeltagarePeriodiskRedovisningComponent }]),
LayoutModule,
ReactiveFormsModule,
ReportLayoutModule,
PeriodiskRedovisningFormModule,
DigiNgFormRadiobuttonGroupModule,
],
exports: [DeltagarePeriodiskRedovisningComponent],
})
export class DeltagarePeriodiskRedovisningModule {}

View File

@@ -34,13 +34,16 @@
<digi-ng-form-select
afLabel="Period"
[afSelectItems]="periodsToFormselectItems(periods)"
[afDisableValidStyle]="true"
[afRequired]="true"
[formControl]="periodFormControl"
[afInvalid]="formControlIsInvalid(periodFormControl)"
(afOnChange)="openChangePeriodDialogIfValuesExist()"
></digi-ng-form-select>
<div>
<digi-form-fieldset
af-legend="Har ni, under perioden, tillhandahållit språkstöd?"
af-legend="Har ni under perioden tillhandahållit språkstöd till deltagaren?"
af-name="languageSupport"
af-form="periodisk-redovisning-form"
>
@@ -48,19 +51,24 @@
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControl]="hasOfferedLanguageSupportFormControl"
[afRequired]="true"
class="periodisk-redovisning-form__radio-buttons"
[ngClass]="{'periodisk-redovisning-form__radio-buttons--invalid': formControlIsInvalid(hasOfferedLanguageSupportFormControl)}"
></digi-ng-form-radiobutton-group>
</digi-form-fieldset>
<digi-form-validation-message
*ngIf="formControlIsInvalid(hasOfferedLanguageSupportFormControl)"
af-variation="error"
>
Ett val är obligatoriskt
</digi-form-validation-message>
<div aria-atomic="true" role="alert">
<digi-form-validation-message
*ngIf="formControlIsInvalid(hasOfferedLanguageSupportFormControl)"
af-variation="error"
>
Ett val är obligatoriskt
</digi-form-validation-message>
</div>
</div>
<div>
<digi-form-fieldset
af-legend="Har ni erbjudit arbete?"
af-legend="Har ni lämnat individuella förslag på lämpliga arbeten att söka till deltagaren?"
af-name="jobOffered"
af-form="periodisk-redovisning-form"
>
@@ -68,63 +76,85 @@
[afRadiobuttonGroupDirection]="radiobuttonGroupDirection.HORIZONTAL"
[afRadiobuttons]="[{label:'Ja', value: true}, {label:'Nej', value: false}]"
[formControl]="hasOfferedJobFormControl"
class="periodisk-redovisning-form__radio-buttons"
[ngClass]="{'periodisk-redovisning-form__radio-buttons--invalid': formControlIsInvalid(hasOfferedJobFormControl)}"
></digi-ng-form-radiobutton-group>
</digi-form-fieldset>
<digi-form-validation-message *ngIf="formControlIsInvalid(hasOfferedJobFormControl)" af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
<div aria-atomic="true" role="alert">
<digi-form-validation-message *ngIf="formControlIsInvalid(hasOfferedJobFormControl)" af-variation="error">
Ett val är obligatoriskt
</digi-form-validation-message>
</div>
</div>
<div>
<h2>Aktiviteter från Gemensam planering</h2>
<p>
Du kan endast välja de aktiviteter som planerats i tidigare inskickad Gemensam planering för deltagaren.
Om du vill redovisa en aktivitet som inte finns i listan, måste du först uppdatera den Gemensamma
planeringen. Sedan kan du redovisa aktiviteten i Periodisk redovisning.
</p>
</div>
<digi-form-fieldset
af-legend="Ange aktiviteter som har utförts under perioden"
af-name="activities"
af-form="periodisk-redovisning-form"
>
<div class="periodisk-redovisning-form__no-activities-has-been-conducted-checkbox">
<digi-ng-form-checkbox
formControlName="noActivitiesHasBeenConducted"
afLabel="Deltagaren har inte deltagit i några aktiviteter denna period"
[afInvalid]="this.shouldValidate$.value && !!formErrors?.activitiesMismatch"
></digi-ng-form-checkbox>
<ng-container *ngIf="this.shouldValidate$.value && !!formErrors?.activitiesMismatch">
<digi-form-validation-message af-variation="error">
{{formErrors?.activitiesMismatch}}
</digi-form-validation-message>
</ng-container>
</div>
<div
[formArrayName]="ACTIVITES_FORM_NAME"
class="periodisk-redovisning-form__activity-checkboxes"
*ngFor="let activityFormGroup of activitiesFormArray.controls; let i=index"
>
<div [formGroupName]="i" class="">
<div class="periodisk-redovisning-form__activities">
<div class="periodisk-redovisning-form__no-activities-has-been-conducted-checkbox">
<digi-ng-form-checkbox
#isSelected
formControlName="isSelected"
[afLabel]="activitiesFormArrayMetadata[i].name"
formControlName="noActivitiesHasBeenConducted"
afLabel="Deltagaren har inte deltagit i några aktiviteter denna period"
[afInvalid]="this.shouldValidate$.value && !!formErrors?.activitiesMismatch"
></digi-ng-form-checkbox>
<div class="periodisk-redovisning-form__activity-location-checkboxes">
<digi-ng-form-checkbox
*ngIf="isSelected.currentValue"
formControlName="performedRemotely"
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
afLabel="Utfört på distans"
></digi-ng-form-checkbox>
<digi-ng-form-checkbox
*ngIf="isSelected.currentValue"
formControlName="performedPhysically"
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
afLabel="Utfört på plats"
></digi-ng-form-checkbox>
<ng-container *ngIf="formControlIsInvalid(activityFormGroup)">
<digi-form-validation-message
*ngFor="let errorText of errorsToArray(activityFormGroup.errors)"
af-variation="error"
>
{{errorText}}
</digi-form-validation-message>
</ng-container>
<div aria-atomic="true" role="alert">
<digi-form-validation-message
af-variation="error"
*ngIf="this.shouldValidate$.value && !!formErrors?.activitiesMismatch"
>
{{formErrors?.activitiesMismatch}}
</digi-form-validation-message>
</div>
</div>
<ng-container *ngIf="activitiesFormArray.controls.length; else loadingRef">
<div
[formArrayName]="ACTIVITES_FORM_NAME"
class="periodisk-redovisning-form__activity"
*ngFor="let activityFormGroup of activitiesFormArray.controls; let i=index"
>
<ng-container [formGroupName]="i">
<digi-ng-form-checkbox
#isSelected
formControlName="isSelected"
[afLabel]="activitiesFormArrayMetadata[i].name"
></digi-ng-form-checkbox>
<div class="periodisk-redovisning-form__activity-location" *ngIf="isSelected.currentValue">
<digi-ng-form-checkbox
formControlName="performedRemotely"
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
afLabel="Utfört på distans"
></digi-ng-form-checkbox>
<digi-ng-form-checkbox
formControlName="performedPhysically"
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
afLabel="Utfört på plats"
></digi-ng-form-checkbox>
<div aria-atomic="true" role="alert">
<ng-container *ngIf="formControlIsInvalid(activityFormGroup)">
<digi-form-validation-message
*ngFor="let errorText of errorsToArray(activityFormGroup.errors)"
af-variation="error"
>
{{errorText}}
</digi-form-validation-message>
</ng-container>
</div>
</div>
</ng-container>
</div>
</ng-container>
</div>
</digi-form-fieldset>
@@ -174,23 +204,29 @@
<digi-typography-time [afDateTime]="avrop.endDate"></digi-typography-time>
</dd>
<ng-container *ngIf="submitData$ | async; let submitData; else loadingRef">
<dt>Har ni, under perioden, tillhandahållit språkstöd:</dt>
<dt>Har ni under perioden tillhandahållit språkstöd till deltagaren:</dt>
<dd>{{submitData.hasOfferedLanguageSupport ? 'Ja' : 'Nej' }}</dd>
<dt>Har ni, under perioden, erbjudit arbete:</dt>
<dt>Har ni lämnat individuella förslag på lämpliga arbeten att söka till deltagaren:</dt>
<dd>{{submitData.hasOfferedJob ? 'Ja' : 'Nej' }}</dd>
<dt>Aktiviteter som utförts under perioden:</dt>
<ng-container *ngIf="submitData.activities.length === 0"
>Deltagaren har inte deltagit i några aktiviteter denna period
</ng-container>
<ng-container *ngFor="let activity of submitData.activities">
<dd>
{{getActivityMetadata(activity.id).name}}: {{ activity.performedRemotely &&
activity.performedPhysically ? 'På distans och på plats' : activity.performedRemotely ? 'På distans' :
'På plats'}}
<dd *ngIf="submitData.activities.length === 0; else activityList">
Deltagaren har inte deltagit i några aktiviteter denna period
</dd>
<ng-template #activityList>
<dd *ngFor="let activity of submitData.activities" class="periodisk-redovisning-form__activity-item">
<digi-icon-check-circle
class="msfa__digi-icon periodisk-redovisning-form__activity-check"
aria-hidden="true"
></digi-icon-check-circle>
<span>
{{getActivityMetadata(activity.id).name}}: {{ activity.performedRemotely &&
activity.performedPhysically ? 'på distans och på plats' : activity.performedRemotely ? 'på distans'
: 'på plats'}}
</span>
</dd>
</ng-container>
</ng-template>
</ng-container>
</dl>
<digi-notification-alert
@@ -202,6 +238,20 @@
<p *ngIf="error.message" class="msfa__small-text">{{error.message}}</p>
</digi-notification-alert>
</digi-ng-dialog>
<digi-ng-dialog
[afActive]="changePeriodDialogIsOpen$ | async"
(afOnPrimaryClick)="closePeriodDialogAndKeepForm()"
(afOnInactive)="closePeriodDialogAndKeepForm()"
afHeadingLevel="h2"
afPrimaryButtonText="Ja, behåll val"
afSecondaryButtonText="Nej, rensa formuläret"
(afOnSecondaryClick)="closePeriodDialogAndResetForm()"
afHeading="Du har bytt period"
afAriaLabel="Du har bytt period. Vill du behålla de svar och aktiviteter du valt"
id="confirm-periodisk-redovisning-form"
>
<p>Vill du behålla de svar och aktiviteter du tidigare valt?</p>
</digi-ng-dialog>
</ng-template>
</div>
</msfa-report-layout>

View File

@@ -24,15 +24,46 @@
gap: var(--digi--layout--gutter);
}
&__activities {
display: flex;
flex-direction: column;
gap: var(--digi--layout--gutter--xs);
}
&__radio-buttons {
&--invalid {
::ng-deep .digi-ng-form-radiobutton__input {
border-color: var(--digi--ui--color--border--error);
background-color: var(--digi--ui--color--background--error);
box-shadow: 0 0 0 var(--digi--ui--border--width) var(--digi--ui--color--border--error);
}
}
}
&__no-activities-has-been-conducted-checkbox,
&__activity,
&__activity-location {
display: flex;
flex-direction: column;
gap: var(--digi--layout--gutter--s);
}
&__no-activities-has-been-conducted-checkbox {
margin-bottom: $digi--layout--gutter--l;
}
&__activity-checkboxes {
&__activity-location {
margin-left: var(--digi--layout--gutter);
margin-bottom: var(--digi--layout--gutter--s);
}
&__activity-location-checkboxes {
margin-left: var(--digi--layout--gutter);
&__activity-item {
display: flex;
align-items: center;
gap: var(--digi--layout--gutter--s);
}
&__activity-check {
color: var(--digi--ui--color--border--success);
}
}

View File

@@ -1,33 +1,33 @@
import { RadiobuttonGroupDirection } from '@af/digi-ng/_form/form-radiobutton-group';
import { FormSelectItem } from '@af/digi-ng/_form/form-select';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Params } from '@angular/router';
import { Avrop } from '@msfa-models/avrop.model';
import { AvropPeriod } from '@msfa-models/avrop-period.model';
import { formatDate } from '@msfa-utils/format-to-date.util';
import { subMonths } from 'date-fns';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { map, shareReplay, switchMap, take } from 'rxjs/operators';
import { dateToPeriodId, extractAvropPeriods } from './extract-avrop-periods';
import { PeriodiskRedovisningFormService } from './periodisk-redovisning-form.service';
import { RadiobuttonGroupDirection } from '@af/digi-ng/_form/form-radiobutton-group';
import { RequiredValidator } from '@msfa-validators/required.validator';
import { Activity } from '@msfa-models/activity.model';
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
import {
PeriodiskRedovisningActivityRequest,
PeriodiskRedovisningRequest,
} from '@msfa-models/api/periodisk-redovisning.request.model';
import { AvropPeriod } from '@msfa-models/avrop-period.model';
import { Avrop } from '@msfa-models/avrop.model';
import { DateFormatOptions } from '@msfa-models/date-format-options.model';
import { CustomError } from '@msfa-models/error/custom-error';
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
import { capitalizeWords } from '@msfa-utils/capitalize-words.util';
import { formatDate } from '@msfa-utils/format-to-date.util';
import { RequiredValidator } from '@msfa-validators/required.validator';
import { subMonths } from 'date-fns';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { map, shareReplay, switchMap, take } from 'rxjs/operators';
import { dateToPeriodId, extractAvropPeriods } from './extract-avrop-periods';
import {
ActivityFormErrors,
PeriodiskRedovisningFormData,
PeriodiskRedovisningFormErrors,
PeriodiskRedovisningFormKeys,
} from './periodisk-redovisning-form.model';
import { PeriodiskRedovisningFormService } from './periodisk-redovisning-form.service';
import { PeriodiskRedovisningValidator } from './periodisk-redovisning.validator';
import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive';
import { CustomError } from '@msfa-models/error/custom-error';
@Component({
selector: 'msfa-periodisk-redovisning-form',
@@ -35,7 +35,7 @@ import { CustomError } from '@msfa-models/error/custom-error';
styleUrls: ['./periodisk-redovisning-form.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PeriodiskRedovisningFormComponent extends UnsubscribeDirective implements OnInit {
export class PeriodiskRedovisningFormComponent implements OnInit {
readonly PERIOD_FORM_NAME: PeriodiskRedovisningFormKeys = 'period';
readonly HAS_OFFERED_LANGUAGE_SUPPORT_FORM_NAME: PeriodiskRedovisningFormKeys = 'hasOfferedLanguageSupport';
readonly HAS_OFFERED_JOB_FORM_NAME: PeriodiskRedovisningFormKeys = 'hasOfferedJob';
@@ -44,6 +44,7 @@ export class PeriodiskRedovisningFormComponent extends UnsubscribeDirective impl
today = new Date();
shouldValidate$ = new BehaviorSubject<boolean>(false);
changePeriodDialogIsOpen$ = new BehaviorSubject<boolean>(false);
confirmDialogIsOpen$ = new BehaviorSubject<boolean>(false);
submittedDate$ = new BehaviorSubject<Date>(null);
submitIsLoading$ = new BehaviorSubject<boolean>(false);
@@ -88,7 +89,9 @@ export class PeriodiskRedovisningFormComponent extends UnsubscribeDirective impl
periodsToFormselectItems(periods: AvropPeriod[]): FormSelectItem[] {
return periods.map(period => ({
name: `${formatDate(period.startDate, 'sv-SE', { month: 'long', year: 'numeric' } as DateFormatOptions)}`,
name: capitalizeWords(
formatDate(period.startDate, 'sv-SE', { month: 'long', year: 'numeric' } as DateFormatOptions)
),
value: period.periodId,
}));
}
@@ -102,15 +105,7 @@ export class PeriodiskRedovisningFormComponent extends UnsubscribeDirective impl
private activatedRoute: ActivatedRoute,
// TODO. GemensamPlaneringApiService is used for fetching activities. Replace with own service once ready
private gemensamPlaneringApiService: GemensamPlaneringApiService
) {
super();
super.unsubscribeOnDestroy(
this.formGroup.valueChanges.subscribe(value => {
this.shouldValidate$.next(false);
})
);
}
) {}
get periodFormControl(): AbstractControl | undefined {
return this.formGroup.get(this.PERIOD_FORM_NAME);
@@ -229,7 +224,34 @@ export class PeriodiskRedovisningFormComponent extends UnsubscribeDirective impl
return this.formControlIsInvalid(activityFormGroup) && !!errors.locationCheckboxes;
}
getActivityMetadata(activityId: number) {
getActivityMetadata(activityId: number): Activity {
return this.activitiesFormArrayMetadata.find(activity => activity.id === activityId);
}
openChangePeriodDialogIfValuesExist(): void {
const { activities, hasOfferedJob, hasOfferedLanguageSupport, noActivitiesHasBeenConducted } = this.formGroup
.value as PeriodiskRedovisningFormData;
if (
activities.filter(({ isSelected }) => !!isSelected).length ||
hasOfferedJob !== null ||
hasOfferedLanguageSupport !== null ||
noActivitiesHasBeenConducted
) {
this.changePeriodDialogIsOpen$.next(true);
}
}
closePeriodDialogAndResetForm(): void {
this.hasOfferedJobFormControl.reset();
this.hasOfferedLanguageSupportFormControl.reset();
this.noActivitiesHasBeenConductedFormControl.reset();
this.activitiesFormArray.reset();
this.shouldValidate$.next(false);
this.changePeriodDialogIsOpen$.next(false);
}
closePeriodDialogAndKeepForm(): void {
this.changePeriodDialogIsOpen$.next(false);
}
}