Merge pull request #234 in TEA/mina-sidor-fa-web from feature/periodisk-redovisning-add-hours-to-activity to develop
Squashed commit of the following: commit 01d637f78f28a68794ba4e8a12135f05fb91ddb7 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Fri Oct 29 12:42:29 2021 +0200 Added hours to PR incl. models commit 8bea7c7ff17b80a2aa05416fd63d2bc697ba45a4 Author: Daniel Appelgren <daniel.appelgren@arbetsformedlingen.se> Date: Fri Oct 29 11:57:59 2021 +0200 wip
This commit is contained in:
@@ -137,26 +137,47 @@
|
|||||||
formControlName="isSelected"
|
formControlName="isSelected"
|
||||||
[afLabel]="activitiesFormArrayMetadata[i].name"
|
[afLabel]="activitiesFormArrayMetadata[i].name"
|
||||||
></digi-ng-form-checkbox>
|
></digi-ng-form-checkbox>
|
||||||
<div class="periodisk-redovisning-form__activity-location" *ngIf="isSelected.currentValue">
|
<div class="periodisk-redovisning-form__activity-details" *ngIf="isSelected.currentValue">
|
||||||
<digi-ng-form-checkbox
|
<div class="periodisk-redovisning-form__activity-group">
|
||||||
formControlName="performedRemotely"
|
<digi-form-input
|
||||||
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
|
class="periodisk-redovisning-form__activity-hours"
|
||||||
afLabel="Utfört på distans"
|
af-label="Antal timmar under perioden"
|
||||||
></digi-ng-form-checkbox>
|
af-type="number"
|
||||||
<digi-ng-form-checkbox
|
af-max="200"
|
||||||
formControlName="performedPhysically"
|
af-min="0"
|
||||||
[afInvalid]="activityLocationIsInvalid(activityFormGroup)"
|
[afValidation]="activityHoursIsInvalid(activityFormGroup) ? 'error' : 'neutral'"
|
||||||
afLabel="Utfört på plats"
|
formControlName="hours"
|
||||||
></digi-ng-form-checkbox>
|
ngDefaultControl
|
||||||
<div aria-atomic="true" role="alert">
|
></digi-form-input>
|
||||||
<ng-container *ngIf="formControlIsInvalid(activityFormGroup)">
|
<div aria-atomic="true" role="alert">
|
||||||
<digi-form-validation-message
|
<digi-form-validation-message
|
||||||
*ngFor="let errorText of errorsToArray(activityFormGroup.errors)"
|
*ngIf="activityHoursIsInvalid(activityFormGroup)"
|
||||||
af-variation="error"
|
af-variation="error"
|
||||||
>
|
>
|
||||||
{{errorText}}
|
{{activityFormGroup.errors.hours}}
|
||||||
</digi-form-validation-message>
|
</digi-form-validation-message>
|
||||||
</ng-container>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="periodisk-redovisning-form__activity-group">
|
||||||
|
<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">
|
||||||
|
<digi-form-validation-message
|
||||||
|
*ngIf="activityLocationIsInvalid(activityFormGroup)"
|
||||||
|
af-variation="error"
|
||||||
|
>
|
||||||
|
{{activityFormGroup.errors.locationCheckboxes}}
|
||||||
|
</digi-form-validation-message>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -208,11 +229,7 @@
|
|||||||
class="msfa__digi-icon periodisk-redovisning-form__activity-check"
|
class="msfa__digi-icon periodisk-redovisning-form__activity-check"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></digi-icon-check-circle>
|
></digi-icon-check-circle>
|
||||||
<span>
|
<span>{{getActivityInfoAsString(activity)}}</span>
|
||||||
{{getActivityMetadata(activity.id).name}}: {{ activity.performedRemotely &&
|
|
||||||
activity.performedPhysically ? 'på distans och på plats' : activity.performedRemotely ? 'på
|
|
||||||
distans' : 'på plats'}}
|
|
||||||
</span>
|
|
||||||
</dd>
|
</dd>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|||||||
@@ -42,18 +42,27 @@
|
|||||||
|
|
||||||
&__no-activities-has-been-conducted-checkbox,
|
&__no-activities-has-been-conducted-checkbox,
|
||||||
&__activity,
|
&__activity,
|
||||||
&__activity-location {
|
&__activity-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--digi--layout--gutter--s);
|
gap: var(--digi--layout--gutter--s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__activity-hours {
|
||||||
|
::ng-deep .digi-form-input__content {
|
||||||
|
max-width: 10rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__no-activities-has-been-conducted-checkbox {
|
&__no-activities-has-been-conducted-checkbox {
|
||||||
margin-bottom: $digi--layout--gutter--l;
|
margin-bottom: $digi--layout--gutter--l;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__activity-location {
|
&__activity-details {
|
||||||
margin-left: var(--digi--layout--gutter);
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--digi--layout--gutter);
|
||||||
|
margin-left: 1.875rem;
|
||||||
margin-bottom: var(--digi--layout--gutter--s);
|
margin-bottom: var(--digi--layout--gutter--s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
|||||||
isSelected: new FormControl(),
|
isSelected: new FormControl(),
|
||||||
performedRemotely: new FormControl(),
|
performedRemotely: new FormControl(),
|
||||||
performedPhysically: new FormControl(),
|
performedPhysically: new FormControl(),
|
||||||
|
hours: new FormControl(),
|
||||||
},
|
},
|
||||||
PeriodiskRedovisningValidator.activityIsValid()
|
PeriodiskRedovisningValidator.activityIsValid()
|
||||||
)
|
)
|
||||||
@@ -200,14 +201,20 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
|||||||
): PeriodiskRedovisningRequest {
|
): PeriodiskRedovisningRequest {
|
||||||
const { period, hasOfferedJob, hasOfferedLanguageSupport } = formData;
|
const { period, hasOfferedJob, hasOfferedLanguageSupport } = formData;
|
||||||
const activities: PeriodiskRedovisningActivityRequest[] = formData.activities
|
const activities: PeriodiskRedovisningActivityRequest[] = formData.activities
|
||||||
.map(({ performedPhysically, performedRemotely, isSelected }, index) => ({
|
.map(({ performedPhysically, performedRemotely, isSelected, hours }, index) => ({
|
||||||
id: this.activitiesFormArrayMetadata[index].id,
|
id: this.activitiesFormArrayMetadata[index].id,
|
||||||
performedPhysically: performedPhysically ?? false,
|
performedPhysically: performedPhysically ?? false,
|
||||||
performedRemotely: performedRemotely ?? false,
|
performedRemotely: performedRemotely ?? false,
|
||||||
|
hours: +hours,
|
||||||
isSelected,
|
isSelected,
|
||||||
}))
|
}))
|
||||||
.filter(activity => activity.isSelected)
|
.filter(activity => activity.isSelected)
|
||||||
.map(({ id, performedPhysically, performedRemotely }) => ({ id, performedPhysically, performedRemotely }));
|
.map(({ id, performedPhysically, performedRemotely, hours }) => ({
|
||||||
|
id,
|
||||||
|
performedPhysically,
|
||||||
|
performedRemotely,
|
||||||
|
hours,
|
||||||
|
}));
|
||||||
return {
|
return {
|
||||||
genomforandeReferens,
|
genomforandeReferens,
|
||||||
period,
|
period,
|
||||||
@@ -226,10 +233,27 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
|||||||
return this.formControlIsInvalid(activityFormGroup) && !!errors.locationCheckboxes;
|
return this.formControlIsInvalid(activityFormGroup) && !!errors.locationCheckboxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activityHoursIsInvalid(activityFormGroup: AbstractControl): boolean {
|
||||||
|
const errors = activityFormGroup.errors as ActivityFormErrors;
|
||||||
|
return this.formControlIsInvalid(activityFormGroup) && !!errors.hours;
|
||||||
|
}
|
||||||
|
|
||||||
getActivityMetadata(activityId: number): Activity {
|
getActivityMetadata(activityId: number): Activity {
|
||||||
return this.activitiesFormArrayMetadata.find(activity => activity.id === activityId);
|
return this.activitiesFormArrayMetadata.find(activity => activity.id === activityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getActivityInfoAsString(activity: PeriodiskRedovisningActivityRequest): string {
|
||||||
|
const { name } = this.getActivityMetadata(activity.id);
|
||||||
|
const hours = activity.hours === 1 ? '1 timme' : `${activity.hours} timmar`;
|
||||||
|
const location =
|
||||||
|
activity.performedRemotely && activity.performedPhysically
|
||||||
|
? 'på distans och på plats'
|
||||||
|
: activity.performedRemotely
|
||||||
|
? 'på distans'
|
||||||
|
: 'på plats';
|
||||||
|
return `${name}: ${hours} ${location}`;
|
||||||
|
}
|
||||||
|
|
||||||
openChangePeriodDialogIfValuesExist(): void {
|
openChangePeriodDialogIfValuesExist(): void {
|
||||||
const { activities, hasOfferedJob, hasOfferedLanguageSupport, noActivitiesHasBeenConducted } = this.formGroup
|
const { activities, hasOfferedJob, hasOfferedLanguageSupport, noActivitiesHasBeenConducted } = this.formGroup
|
||||||
.value as PeriodiskRedovisningFormData;
|
.value as PeriodiskRedovisningFormData;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export interface PeriodiskRedovisningFormActivity {
|
|||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
performedRemotely: boolean;
|
performedRemotely: boolean;
|
||||||
performedPhysically: boolean;
|
performedPhysically: boolean;
|
||||||
|
hours: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeriodiskRedovisningFormData {
|
export interface PeriodiskRedovisningFormData {
|
||||||
@@ -20,4 +21,5 @@ export interface PeriodiskRedovisningFormErrors {
|
|||||||
|
|
||||||
export interface ActivityFormErrors {
|
export interface ActivityFormErrors {
|
||||||
locationCheckboxes?: string;
|
locationCheckboxes?: string;
|
||||||
|
hours?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,10 @@ export class PeriodiskRedovisningValidator {
|
|||||||
static activityIsValid(): ValidatorFn {
|
static activityIsValid(): ValidatorFn {
|
||||||
return (c: AbstractControl): ActivityFormErrors => {
|
return (c: AbstractControl): ActivityFormErrors => {
|
||||||
let errors: ActivityFormErrors;
|
let errors: ActivityFormErrors;
|
||||||
|
const controlValue = c.value as PeriodiskRedovisningFormActivity;
|
||||||
|
|
||||||
|
const { performedRemotely, performedPhysically, isSelected, hours } = controlValue;
|
||||||
|
|
||||||
const { performedRemotely, performedPhysically, isSelected } = c.value as PeriodiskRedovisningFormActivity;
|
|
||||||
if (isSelected && !performedPhysically && !performedRemotely) {
|
if (isSelected && !performedPhysically && !performedRemotely) {
|
||||||
errors = {
|
errors = {
|
||||||
...errors,
|
...errors,
|
||||||
@@ -45,6 +47,15 @@ export class PeriodiskRedovisningValidator {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isValidHours = hours?.length > 0 && Number.isInteger(+hours) && +hours >= 0 && +hours <= 200;
|
||||||
|
|
||||||
|
if (isSelected && !isValidHours) {
|
||||||
|
errors = {
|
||||||
|
...errors,
|
||||||
|
hours: 'Antal timmar måste vara ett heltal mellan 0 och 200',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,7 @@
|
|||||||
class="msfa__digi-icon periodisk-redovisning-view__activity-check"
|
class="msfa__digi-icon periodisk-redovisning-view__activity-check"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></digi-icon-check-circle>
|
></digi-icon-check-circle>
|
||||||
{{activity.name}}: {{ activity.performedRemotely && activity.performedPhysically ? 'På distans och på
|
{{getActivityInfoAsString(activity)}}
|
||||||
plats' : activity.performedRemotely ? 'På distans' : 'På plats'}}
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Params } from '@msfa-models/api/params.model';
|
import { Params } from '@msfa-models/api/params.model';
|
||||||
import { Avrop } from '@msfa-models/avrop.model';
|
import { Avrop } from '@msfa-models/avrop.model';
|
||||||
|
import { PeriodiskRedovisning, PeriodiskRedovisningActivity } from '@msfa-models/periodisk-redovisning.model';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
||||||
import { PeriodiskRedovisningViewService } from './periodisk-redovisning-view.service';
|
import { PeriodiskRedovisningViewService } from './periodisk-redovisning-view.service';
|
||||||
import { PeriodiskRedovisning } from '@msfa-models/periodisk-redovisning.model';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'msfa-periodisk-redovisning-view',
|
selector: 'msfa-periodisk-redovisning-view',
|
||||||
@@ -34,6 +34,17 @@ export class PeriodiskRedovisningViewComponent {
|
|||||||
shareReplay(1)
|
shareReplay(1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
getActivityInfoAsString(activity: PeriodiskRedovisningActivity): string {
|
||||||
|
const hours = activity.hours === 1 ? '1 timme' : `${activity.hours} timmar`;
|
||||||
|
const location =
|
||||||
|
activity.performedRemotely && activity.performedPhysically
|
||||||
|
? 'på distans och på plats'
|
||||||
|
: activity.performedRemotely
|
||||||
|
? 'på distans'
|
||||||
|
: 'på plats';
|
||||||
|
return `${activity.name}: ${hours} ${location}`;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private periodiskRedovisningViewService: PeriodiskRedovisningViewService,
|
private periodiskRedovisningViewService: PeriodiskRedovisningViewService,
|
||||||
private activatedRoute: ActivatedRoute
|
private activatedRoute: ActivatedRoute
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export interface PeriodiskRedovisningActivityRequest {
|
|||||||
id: number;
|
id: number;
|
||||||
performedRemotely: boolean;
|
performedRemotely: boolean;
|
||||||
performedPhysically: boolean;
|
performedPhysically: boolean;
|
||||||
|
hours: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeriodiskRedovisningRequest {
|
export interface PeriodiskRedovisningRequest {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export interface PeriodiskRedovisningActivityResponse {
|
|||||||
name: string;
|
name: string;
|
||||||
performedRemotely: boolean;
|
performedRemotely: boolean;
|
||||||
performedPhysically: boolean;
|
performedPhysically: boolean;
|
||||||
|
hours: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeriodiskRedovisningResponse {
|
export interface PeriodiskRedovisningResponse {
|
||||||
@@ -25,18 +26,21 @@ export function mockOnePeriodiskRedovisningResponse(): PeriodiskRedovisningRespo
|
|||||||
name: 'Aktivitet 1',
|
name: 'Aktivitet 1',
|
||||||
performedRemotely: false,
|
performedRemotely: false,
|
||||||
performedPhysically: true,
|
performedPhysically: true,
|
||||||
|
hours: 25,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 19,
|
id: 19,
|
||||||
name: 'Aktivitet 2',
|
name: 'Aktivitet 2',
|
||||||
performedRemotely: true,
|
performedRemotely: true,
|
||||||
performedPhysically: false,
|
performedPhysically: false,
|
||||||
|
hours: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 31,
|
id: 31,
|
||||||
name: 'Aktivitet 3',
|
name: 'Aktivitet 3',
|
||||||
performedRemotely: true,
|
performedRemotely: true,
|
||||||
performedPhysically: true,
|
performedPhysically: true,
|
||||||
|
hours: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export interface PeriodiskRedovisningActivity {
|
|||||||
name: string;
|
name: string;
|
||||||
performedRemotely: boolean;
|
performedRemotely: boolean;
|
||||||
performedPhysically: boolean;
|
performedPhysically: boolean;
|
||||||
|
hours: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeriodiskRedovisning {
|
export interface PeriodiskRedovisning {
|
||||||
|
|||||||
Reference in New Issue
Block a user