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"
|
||||
[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)">
|
||||
<div class="periodisk-redovisning-form__activity-details" *ngIf="isSelected.currentValue">
|
||||
<div class="periodisk-redovisning-form__activity-group">
|
||||
<digi-form-input
|
||||
class="periodisk-redovisning-form__activity-hours"
|
||||
af-label="Antal timmar under perioden"
|
||||
af-type="number"
|
||||
af-max="200"
|
||||
af-min="0"
|
||||
[afValidation]="activityHoursIsInvalid(activityFormGroup) ? 'error' : 'neutral'"
|
||||
formControlName="hours"
|
||||
ngDefaultControl
|
||||
></digi-form-input>
|
||||
<div aria-atomic="true" role="alert">
|
||||
<digi-form-validation-message
|
||||
*ngFor="let errorText of errorsToArray(activityFormGroup.errors)"
|
||||
*ngIf="activityHoursIsInvalid(activityFormGroup)"
|
||||
af-variation="error"
|
||||
>
|
||||
{{errorText}}
|
||||
{{activityFormGroup.errors.hours}}
|
||||
</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>
|
||||
</ng-container>
|
||||
@@ -208,11 +229,7 @@
|
||||
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>
|
||||
<span>{{getActivityInfoAsString(activity)}}</span>
|
||||
</dd>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
@@ -42,18 +42,27 @@
|
||||
|
||||
&__no-activities-has-been-conducted-checkbox,
|
||||
&__activity,
|
||||
&__activity-location {
|
||||
&__activity-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__activity-hours {
|
||||
::ng-deep .digi-form-input__content {
|
||||
max-width: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__no-activities-has-been-conducted-checkbox {
|
||||
margin-bottom: $digi--layout--gutter--l;
|
||||
}
|
||||
|
||||
&__activity-location {
|
||||
margin-left: var(--digi--layout--gutter);
|
||||
&__activity-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--digi--layout--gutter);
|
||||
margin-left: 1.875rem;
|
||||
margin-bottom: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
||||
isSelected: new FormControl(),
|
||||
performedRemotely: new FormControl(),
|
||||
performedPhysically: new FormControl(),
|
||||
hours: new FormControl(),
|
||||
},
|
||||
PeriodiskRedovisningValidator.activityIsValid()
|
||||
)
|
||||
@@ -200,14 +201,20 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
||||
): PeriodiskRedovisningRequest {
|
||||
const { period, hasOfferedJob, hasOfferedLanguageSupport } = formData;
|
||||
const activities: PeriodiskRedovisningActivityRequest[] = formData.activities
|
||||
.map(({ performedPhysically, performedRemotely, isSelected }, index) => ({
|
||||
.map(({ performedPhysically, performedRemotely, isSelected, hours }, index) => ({
|
||||
id: this.activitiesFormArrayMetadata[index].id,
|
||||
performedPhysically: performedPhysically ?? false,
|
||||
performedRemotely: performedRemotely ?? false,
|
||||
hours: +hours,
|
||||
isSelected,
|
||||
}))
|
||||
.filter(activity => activity.isSelected)
|
||||
.map(({ id, performedPhysically, performedRemotely }) => ({ id, performedPhysically, performedRemotely }));
|
||||
.map(({ id, performedPhysically, performedRemotely, hours }) => ({
|
||||
id,
|
||||
performedPhysically,
|
||||
performedRemotely,
|
||||
hours,
|
||||
}));
|
||||
return {
|
||||
genomforandeReferens,
|
||||
period,
|
||||
@@ -226,10 +233,27 @@ export class PeriodiskRedovisningFormComponent implements OnInit {
|
||||
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 {
|
||||
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 {
|
||||
const { activities, hasOfferedJob, hasOfferedLanguageSupport, noActivitiesHasBeenConducted } = this.formGroup
|
||||
.value as PeriodiskRedovisningFormData;
|
||||
|
||||
@@ -2,6 +2,7 @@ export interface PeriodiskRedovisningFormActivity {
|
||||
isSelected: boolean;
|
||||
performedRemotely: boolean;
|
||||
performedPhysically: boolean;
|
||||
hours: string;
|
||||
}
|
||||
|
||||
export interface PeriodiskRedovisningFormData {
|
||||
@@ -20,4 +21,5 @@ export interface PeriodiskRedovisningFormErrors {
|
||||
|
||||
export interface ActivityFormErrors {
|
||||
locationCheckboxes?: string;
|
||||
hours?: string;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,10 @@ export class PeriodiskRedovisningValidator {
|
||||
static activityIsValid(): ValidatorFn {
|
||||
return (c: AbstractControl): 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) {
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
class="msfa__digi-icon periodisk-redovisning-view__activity-check"
|
||||
aria-hidden="true"
|
||||
></digi-icon-check-circle>
|
||||
{{activity.name}}: {{ activity.performedRemotely && activity.performedPhysically ? 'På distans och på
|
||||
plats' : activity.performedRemotely ? 'På distans' : 'På plats'}}
|
||||
{{getActivityInfoAsString(activity)}}
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
@@ -2,10 +2,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import { Avrop } from '@msfa-models/avrop.model';
|
||||
import { PeriodiskRedovisning, PeriodiskRedovisningActivity } from '@msfa-models/periodisk-redovisning.model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import { PeriodiskRedovisningViewService } from './periodisk-redovisning-view.service';
|
||||
import { PeriodiskRedovisning } from '@msfa-models/periodisk-redovisning.model';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-periodisk-redovisning-view',
|
||||
@@ -34,6 +34,17 @@ export class PeriodiskRedovisningViewComponent {
|
||||
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(
|
||||
private periodiskRedovisningViewService: PeriodiskRedovisningViewService,
|
||||
private activatedRoute: ActivatedRoute
|
||||
|
||||
@@ -2,6 +2,7 @@ export interface PeriodiskRedovisningActivityRequest {
|
||||
id: number;
|
||||
performedRemotely: boolean;
|
||||
performedPhysically: boolean;
|
||||
hours: number;
|
||||
}
|
||||
|
||||
export interface PeriodiskRedovisningRequest {
|
||||
|
||||
@@ -3,6 +3,7 @@ export interface PeriodiskRedovisningActivityResponse {
|
||||
name: string;
|
||||
performedRemotely: boolean;
|
||||
performedPhysically: boolean;
|
||||
hours: number;
|
||||
}
|
||||
|
||||
export interface PeriodiskRedovisningResponse {
|
||||
@@ -25,18 +26,21 @@ export function mockOnePeriodiskRedovisningResponse(): PeriodiskRedovisningRespo
|
||||
name: 'Aktivitet 1',
|
||||
performedRemotely: false,
|
||||
performedPhysically: true,
|
||||
hours: 25,
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
name: 'Aktivitet 2',
|
||||
performedRemotely: true,
|
||||
performedPhysically: false,
|
||||
hours: 3,
|
||||
},
|
||||
{
|
||||
id: 31,
|
||||
name: 'Aktivitet 3',
|
||||
performedRemotely: true,
|
||||
performedPhysically: true,
|
||||
hours: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ export interface PeriodiskRedovisningActivity {
|
||||
name: string;
|
||||
performedRemotely: boolean;
|
||||
performedPhysically: boolean;
|
||||
hours: number;
|
||||
}
|
||||
|
||||
export interface PeriodiskRedovisning {
|
||||
|
||||
Reference in New Issue
Block a user