feat(gemensam-planering): Implemented gemensam-planering form. (TV-700)
Squashed commit of the following: commit 2d07f37e30009c7f701af35aed65839535044bb3 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 09:33:21 2021 +0200 Updated error handling commit 12290b9436a06ecf0b2b8509016b14748ca17a18 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 09:10:48 2021 +0200 Updated after PR commit cc2fb38528069819acbc39c7b1f6d71ecae666a1 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 08:46:33 2021 +0200 Updated proxy.conf commit ee919de929d7b7316cd7050015fbad9c662b8718 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 08:44:00 2021 +0200 Updated api-endpoint commit 249ef70e14fa8db0c388ffb27f5173815a07c768 Merge: c8296cbfcc0a9aaeAuthor: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 08:39:43 2021 +0200 Merge branch 'develop' into feature/TV-700-erik commit c8296cbff42d747df8c17cf3858f22956fd1e910 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 07:44:41 2021 +0200 Fixed some linting and tests commit ec0bf7cd3616859742e461ffd65a2289f5c50cd6 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Wed Oct 6 07:37:28 2021 +0200 Changes after PR commit aa6cee5248299056e043170b8803335529277062 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Oct 5 14:56:45 2021 +0200 Fixed some styling commit 86de8306679fcff5ed8595f97f696cb43f38f4ac Merge: 3b1822d85cee9695Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Oct 5 14:46:52 2021 +0200 Merged develop and resolved conflicts commit 3b1822d8c8f197b789d1db5832b8e99351e8afa3 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Oct 5 14:22:06 2021 +0200 Updated GP commit a63dfb716a3888f3e5830fe224de4cd16b1922c2 Merge: e2a8cb1c07ec3c4aAuthor: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Oct 5 07:29:23 2021 +0200 Merge branch 'develop' into feature/TV-700 commit e2a8cb1cef2ada931f8a82ae0e9849aabb77ac4d Author: Chingiz <chingiz.esenbaev@arbetsformedlingen.se> Date: Mon Oct 4 20:16:42 2021 +0200 lamnas over till team 1
This commit is contained in:
@@ -42,12 +42,12 @@
|
||||
</ng-container>
|
||||
</h2>
|
||||
|
||||
<div class="avrop__progress-bar" *ngIf="currentStep < 4">
|
||||
<span>Steg {{ currentStep }} av {{ totalAmountOfSteps }}:</span>
|
||||
<digi-ng-progress-progressbar
|
||||
[afSteps]="totalAmountOfSteps"
|
||||
[afActiveStep]="currentStep"
|
||||
></digi-ng-progress-progressbar>
|
||||
<div class="avrop__progress-bar">
|
||||
<digi-progressbar
|
||||
[afTotalSteps]="totalAmountOfSteps"
|
||||
[afCompletedSteps]="currentStep - 1"
|
||||
af-steps-label="steg avklarade"
|
||||
></digi-progressbar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="avrop__content" *ngIf="avropData.data.length; else noAvrop">
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
&__progress-bar {
|
||||
z-index: $msfa__z-index-default;
|
||||
min-width: 12rem;
|
||||
}
|
||||
|
||||
&__select-handledare {
|
||||
|
||||
@@ -1,55 +1,47 @@
|
||||
<section class="report-layout" *ngIf="contactInformation$ | async as contactInformation; else skeletonRef">
|
||||
<section class="report-layout">
|
||||
<digi-typography>
|
||||
<h1>{{ reportTitle }}</h1>
|
||||
<p class="report-layout__description">{{description}}</p>
|
||||
<div class="report-layout__deltagare-info">
|
||||
<h2>{{reportSubTitle}}</h2>
|
||||
<div class="report-layout__name">{{contactInformation.firstName + ' ' + contactInformation.lastName}}</div>
|
||||
<div class="report-layout__personnummer">
|
||||
<span>Personnummer:</span>
|
||||
<msfa-hide-text
|
||||
symbols="********-****"
|
||||
[changingText]="contactInformation.ssn"
|
||||
ariaLabelType="Personnumer"
|
||||
></msfa-hide-text>
|
||||
</div>
|
||||
<span *ngIf="service">Tjänst: KROM</span>
|
||||
<ng-container *ngIf="startDate && endDate && !isPeriodDate">
|
||||
<span>Startdatum: {{startDate}}</span>
|
||||
<span>Slutdatum: {{endDate}}</span>
|
||||
</ng-container>
|
||||
<span *ngIf="startDate && endDate && isPeriodDate">Avser period: {{startDate}} - {{endDate}}</span>
|
||||
<p class="report-layout__description" *ngIf="description">{{description}}</p>
|
||||
<div class="report-layout__deltagare-info" *ngIf="avrop">
|
||||
<h2 *ngIf="reportSubTitle">{{reportSubTitle}}</h2>
|
||||
<dl>
|
||||
<dt>Namn</dt>
|
||||
<dd>{{avrop.fullName}}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Personnummer</dt>
|
||||
<dd>
|
||||
<msfa-hide-text
|
||||
symbols="********-****"
|
||||
[changingText]="avrop.ssn"
|
||||
ariaLabelType="Personnummer"
|
||||
></msfa-hide-text>
|
||||
</dd>
|
||||
<dt>Tjänst</dt>
|
||||
<dd>{{avrop.tjanst}}</dd>
|
||||
<ng-container *ngIf="!isPeriodDate; else periodDateRef">
|
||||
<dt>Startdatum</dt>
|
||||
<dd>{{avrop.startDate | date:'longDate'}}</dd>
|
||||
<dt>Slutdatum</dt>
|
||||
<dd>{{avrop.endDate | date:'longDate'}}</dd>
|
||||
</ng-container>
|
||||
<ng-template #periodDateRef>
|
||||
<dt>Avser period</dt>
|
||||
<dd>{{avrop.startDate | date:'longDate'}} - {{avrop.endDate | date:'longDate'}}</dd>
|
||||
</ng-template>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="report-layout__notification-alert">
|
||||
<digi-notification-alert
|
||||
*ngIf="showSuccessNotification"
|
||||
af-variation="success"
|
||||
af-heading="Allt gick bra"
|
||||
af-heading-level="h3"
|
||||
>
|
||||
<p>Din {{reportTitle.toLocaleLowerCase()}} är nu inskickad till Arbetsförmedlingen.</p>
|
||||
</digi-notification-alert>
|
||||
|
||||
<digi-notification-alert
|
||||
*ngIf="showDangerNotification"
|
||||
af-variation="danger"
|
||||
af-heading="Någonting gick fel"
|
||||
af-heading-level="h3"
|
||||
>
|
||||
<p>Vi kunde inte skicka in din {{reportTitle.toLocaleLowerCase()}}.</p>
|
||||
</digi-notification-alert>
|
||||
<div class="report-layout__progress-bar">
|
||||
<digi-progressbar
|
||||
[afTotalSteps]="totalAmountOfSteps"
|
||||
[afCompletedSteps]="currentStep - 1"
|
||||
af-steps-label="steg avklarade"
|
||||
></digi-progressbar>
|
||||
</div>
|
||||
|
||||
<digi-ng-progress-progressbar
|
||||
[afSteps]="totalAmountOfSteps"
|
||||
[afActiveStep]="currentStep"
|
||||
></digi-ng-progress-progressbar>
|
||||
|
||||
<div class="report-layout__main-content">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</digi-typography>
|
||||
</section>
|
||||
|
||||
<ng-template #skeletonRef>
|
||||
<digi-ng-skeleton-base [afCount]="3" afText="Laddar skapa rapportsida"></digi-ng-skeleton-base>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,32 +1,11 @@
|
||||
@import 'apps/mina-sidor-fa/src/styles/variables/gutters';
|
||||
|
||||
.report-layout {
|
||||
&__name {
|
||||
margin-top: 0;
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
&__deltagare-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: $digi--layout--gutter--xl;
|
||||
font-size: var(--digi--typography--font-size--m);
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
&__personnummer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__personnummer msfa-hide-text {
|
||||
margin-left: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__notification-alert {
|
||||
margin-bottom: $digi--layout--gutter--xl;
|
||||
}
|
||||
|
||||
&__main-content {
|
||||
&__progress-bar {
|
||||
margin: $digi--layout--gutter--xl 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ContactInformation } from '@msfa-models/contact-information.model';
|
||||
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { Avrop } from '@msfa-models/avrop.model';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-report-layout',
|
||||
@@ -12,23 +8,17 @@ import { switchMap } from 'rxjs/operators';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ReportLayoutComponent {
|
||||
@Input() reportTitle = 'Report Title';
|
||||
@Input() reportSubTitle = 'Report Sub Title';
|
||||
@Input() description = 'Report description ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem';
|
||||
@Input() reportTitle: string;
|
||||
@Input() reportSubTitle: string;
|
||||
@Input() description: string;
|
||||
@Input() startDate: string;
|
||||
@Input() endDate: string;
|
||||
@Input() service: string;
|
||||
@Input() isPeriodDate = false;
|
||||
@Input() avrop: Avrop;
|
||||
@Input() totalAmountOfSteps = 3;
|
||||
@Input() currentStep = 1;
|
||||
@Input() showSuccessNotification = false;
|
||||
@Input() showDangerNotification = false;
|
||||
|
||||
contactInformation$: Observable<ContactInformation> = this.activatedRoute.params.pipe(
|
||||
switchMap(({ genomforandeReferens }) =>
|
||||
this.deltagareApiService.fetchContactInformation$(genomforandeReferens)
|
||||
)
|
||||
);
|
||||
|
||||
constructor(private deltagareApiService: DeltagareApiService, private activatedRoute: ActivatedRoute) { }
|
||||
@Input() submitted = false;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { ReportLayoutComponent } from './report-layout.component';
|
||||
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
|
||||
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ReportLayoutComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
LayoutModule,
|
||||
DigiNgProgressProgressbarModule,
|
||||
DigiNgSkeletonBaseModule,
|
||||
HideTextModule],
|
||||
imports: [CommonModule, RouterModule, LayoutModule, DigiNgProgressProgressbarModule, HideTextModule],
|
||||
exports: [ReportLayoutComponent],
|
||||
})
|
||||
export class ReportLayoutModule {}
|
||||
|
||||
@@ -7,7 +7,7 @@ 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';
|
||||
|
||||
describe('DeltagareAvvikelseComponent', () => {
|
||||
let component: DeltagareAvvikelseComponent;
|
||||
@@ -22,8 +22,9 @@ describe('DeltagareAvvikelseComponent', () => {
|
||||
HttpClientTestingModule,
|
||||
ReactiveFormsModule,
|
||||
DigiNgFormRadiobuttonGroupModule,
|
||||
DigiNgFormDatepickerModule
|
||||
]
|
||||
DigiNgFormDatepickerModule,
|
||||
],
|
||||
providers: [DeltagareAvvikelseService],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,43 +1,126 @@
|
||||
<msfa-layout>
|
||||
<form [formGroup]="planeringFormGroup" (ngSubmit)="onFormSubmitted()">
|
||||
<msfa-report-layout
|
||||
reportTitle="Gemensam Planering"
|
||||
reportSubTitle="Aktiviteter"
|
||||
[totalAmountOfSteps]="totalAmountOfSteps"
|
||||
[isPeriodDate]="true"
|
||||
[currentStep]="currentStep"
|
||||
[startDate]="'2021-09-01'"
|
||||
[endDate]="'2021-09-30'"
|
||||
(currentStepEvent)="currentStep = $event"
|
||||
(sendRequestEvent)="sendRequest = $event"
|
||||
>
|
||||
<div class="gemensam-planering_activity" *ngIf="currentStep === 1">
|
||||
<h3>Deltar arbetssökande på distans?</h3>
|
||||
<digi-ng-form-radiobutton-group
|
||||
[afRadiobuttons]="distanceChoice"
|
||||
[formControlName]="participatedOnDistansFormControlName"
|
||||
[afRadiobuttonGroupDirection]="direction"
|
||||
></digi-ng-form-radiobutton-group>
|
||||
<msfa-report-layout
|
||||
*ngIf="avrop$ | async as avrop; else skeletonRef"
|
||||
reportTitle="Gemensam planering"
|
||||
[totalAmountOfSteps]="totalAmountOfSteps"
|
||||
[currentStep]="currentStep"
|
||||
[avrop]="avrop"
|
||||
[submitted]="lastSubmittedGP$ | async"
|
||||
[isPeriodDate]="true"
|
||||
>
|
||||
<div class="gemensam-planering" *ngIf="currentGenomforandeReferens$ | async as genomforandeReferens">
|
||||
<div class="gemensam-planering__confirmation" *ngIf="lastSubmittedGP$ | async as lastSubmittedGP; else formRef">
|
||||
<digi-notification-alert af-variation="success" af-heading="Allt gick bra" af-heading-level="h3">
|
||||
<p>
|
||||
Gemensam planering för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen och inväntar
|
||||
godkännande.
|
||||
</p>
|
||||
<dl>
|
||||
<dt>Datum</dt>
|
||||
<dd>{{lastSubmittedGP | date:'longDate'}} kl {{lastSubmittedGP | date:'shortTime'}}</dd>
|
||||
</dl>
|
||||
</digi-notification-alert>
|
||||
<msfa-back-link [route]="['/deltagare/'+ genomforandeReferens]">Tillbaka till deltagaren</msfa-back-link>
|
||||
</div>
|
||||
<div class="gemensam-planering_activity" *ngIf="currentStep === 2">Förhandsgranska</div>
|
||||
<div class="gemensam-planering__step-buttons-wrapper">
|
||||
<ng-container *ngIf="currentStep > 1">
|
||||
<digi-button
|
||||
class="gemensam-planering__step-buttons-wrapper--space-right"
|
||||
af-variation="secondary"
|
||||
af-size="m"
|
||||
(afOnClick)="previousStep()"
|
||||
>
|
||||
Tillbaka
|
||||
</digi-button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentStep === (totalAmountOfSteps -1)">
|
||||
<digi-button af-size="m" (afOnClick)="nextStep()"> Förhandsgranska </digi-button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentStep === totalAmountOfSteps">
|
||||
<digi-button af-size="m" (afOnClick)="sendRequest(true)"> Skicka in </digi-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
</msfa-report-layout>
|
||||
</form>
|
||||
<ng-template #formRef>
|
||||
<form
|
||||
class="gemensam-planering__form"
|
||||
[formGroup]="gpFormGroup"
|
||||
(ngSubmit)="openConfirmDialog()"
|
||||
id="gemensam-planering-form"
|
||||
>
|
||||
<ng-container *ngIf="currentStep === 1">
|
||||
<digi-form-fieldset
|
||||
af-legend="Deltar arbetssökande på distans?"
|
||||
af-name="distance"
|
||||
af-form="gemensam-planering-form"
|
||||
>
|
||||
<digi-ng-form-radiobutton-group
|
||||
[afRadiobuttons]="distanceRadiobuttons"
|
||||
formControlName="distance"
|
||||
[afRequired]="true"
|
||||
[afRadiobuttonGroupDirection]="RadiobuttonGroupDirection.HORIZONTAL"
|
||||
></digi-ng-form-radiobutton-group>
|
||||
</digi-form-fieldset>
|
||||
<digi-form-fieldset af-legend="Aktiviteter" af-name="aktivitetsIds" af-form="gemensam-planering-form">
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<ng-container *ngIf="activities$ | async as activities; else loadingRef">
|
||||
<ul class="gemensam-planering__activity-list">
|
||||
<li class="gemensam-planering__activity-item" *ngFor="let activity of activities;">
|
||||
<digi-form-checkbox
|
||||
[afLabel]="activity.name + (isActivityObligatory(activity.id) ? ' (obligatorisk)' : '')"
|
||||
[afValue]="activity.id"
|
||||
[afValidation]="showActivityAsInvalid(activity.id) ? 'error' : 'neutral'"
|
||||
[afChecked]="isActivityChecked(activity.id) || isActivityObligatory(activity.id)"
|
||||
(afOnChange)="updateActivityIds(activity.id, $event.detail.target.checked)"
|
||||
></digi-form-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
<digi-form-validation-message
|
||||
*ngIf="shouldValidate && gpFormGroup.errors?.activityIds"
|
||||
af-variation="error"
|
||||
>{{gpFormGroup.errors.activityIds}}</digi-form-validation-message
|
||||
>
|
||||
</ng-container>
|
||||
</digi-form-fieldset>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentStep === 2">
|
||||
<dl>
|
||||
<dt>Deltar arbetssökande på distans?</dt>
|
||||
<dd>{{gpFormGroup.value.distance ? 'Ja' : 'Nej'}}</dd>
|
||||
<dt>Aktiviteter</dt>
|
||||
<dd>
|
||||
<ul class="gemensam-planering__activity-list" *ngFor="let activity of activities$ | async">
|
||||
<li
|
||||
class="gemensam-planering__activity-item"
|
||||
*ngIf="activityIdsFormArray.value.includes(activity.id)"
|
||||
>
|
||||
<digi-icon-check-circle
|
||||
class="msfa__digi-icon gemensam-planering__activity-check"
|
||||
aria-hidden="true"
|
||||
></digi-icon-check-circle>
|
||||
{{activity.name}}
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</ng-container>
|
||||
<footer class="gemensam-planering__footer">
|
||||
<ng-container *ngIf="currentStep > 1">
|
||||
<digi-button
|
||||
class="gemensam-planering__step-buttons-wrapper--space-right"
|
||||
af-variation="secondary"
|
||||
af-size="m"
|
||||
(afOnClick)="goToStep1()"
|
||||
>Tillbaka</digi-button
|
||||
>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentStep === 1">
|
||||
<digi-button af-size="m" (afOnClick)="goToPreview()">Förhandsgranska</digi-button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentStep === 2">
|
||||
<digi-button af-type="submit" af-size="m">Bekräfta och skicka in</digi-button>
|
||||
</ng-container>
|
||||
</footer>
|
||||
</form>
|
||||
<msfa-confirm-dialog
|
||||
[openConfirmDialog]="confirmDialogOpen"
|
||||
reportToConfirm="gemensam planering"
|
||||
(confirmDialogChanged)="closeConfirmDialogAndProceed($event, genomforandeReferens)"
|
||||
></msfa-confirm-dialog>
|
||||
</ng-template>
|
||||
</div>
|
||||
</msfa-report-layout>
|
||||
</msfa-layout>
|
||||
|
||||
<ng-template #skeletonRef>
|
||||
<digi-ng-skeleton-base [afCount]="3" afText="Laddar data för gemensam planering"></digi-ng-skeleton-base>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #loadingRef>
|
||||
<msfa-loader type="padded"></msfa-loader>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,8 +1,43 @@
|
||||
@import 'mixins/list';
|
||||
@import 'variables/gutters';
|
||||
|
||||
.gemensam-planering {
|
||||
&__pages {
|
||||
margin: 5rem 0rem;
|
||||
&__confirmation,
|
||||
&__form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $digi--layout--gutter--l;
|
||||
}
|
||||
&__step-buttons-wrapper--space-right {
|
||||
margin-right: 1rem;
|
||||
|
||||
&__activity-list {
|
||||
@include msfa__reset-list;
|
||||
margin-bottom: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__activity-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--digi--layout--gutter--s);
|
||||
margin-top: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__activity-check {
|
||||
color: var(--digi--ui--color--border--success);
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
gap: var(--digi--layout--gutter);
|
||||
}
|
||||
|
||||
::ng-deep {
|
||||
.digi-form-fieldset {
|
||||
margin: 0;
|
||||
|
||||
&__legend {
|
||||
margin-bottom: var(--digi--layout--gutter--s);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { RadiobuttonGroupDirection, RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { RequiredValidator } from '@msfa-validators/required.validator';
|
||||
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ConfirmDialog } from '@msfa-enums/confirm-dialog.enum';
|
||||
import { Activity } from '@msfa-models/activity.model';
|
||||
import { Avrop } from '@msfa-models/avrop.model';
|
||||
import {
|
||||
GemensamPlanering,
|
||||
mapGemensamPlaneringToGemensamPlaneringPostRequest,
|
||||
} from '@msfa-models/gemensam-planering.model';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import { GemensamPlaneringService } from './gemensam-planering.service';
|
||||
import { GemensamPlaneringValidator } from './gemensam-planering.validator';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-deltagare-gemensam-planering',
|
||||
@@ -10,54 +20,124 @@ import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planeri
|
||||
styleUrls: ['./deltagare-gemensam-planering.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagareGemensamPlaneringComponent implements OnInit {
|
||||
export class DeltagareGemensamPlaneringComponent {
|
||||
totalAmountOfSteps = 2;
|
||||
currentStep = 1;
|
||||
direction = RadiobuttonGroupDirection.HORIZONTAL;
|
||||
planeringFormGroup: FormGroup | null = null;
|
||||
obligatoryActivityIds = [165, 188];
|
||||
shouldValidate = false;
|
||||
RadiobuttonGroupDirection = RadiobuttonGroupDirection;
|
||||
confirmDialogOpen = false;
|
||||
private _lastSubmittedGP$ = new BehaviorSubject<Date>(null);
|
||||
lastSubmittedGP$: Observable<Date> = this._lastSubmittedGP$.asObservable();
|
||||
|
||||
readonly participatedOnDistansFormControlName = 'participatedOnDistans';
|
||||
distanceChoice: RadiobuttonModel[] = [
|
||||
activities$: Observable<Activity[]> = this.gemensamPlaneringService.activities$;
|
||||
currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe(
|
||||
map(params => params.genomforandeReferens as string),
|
||||
distinctUntilChanged(
|
||||
([prevGenomforandeReferens], [currGenomforandeReferens]) => prevGenomforandeReferens === currGenomforandeReferens
|
||||
),
|
||||
map(genomforandeReferens => +genomforandeReferens)
|
||||
);
|
||||
avrop$: Observable<Avrop> = this.currentGenomforandeReferens$.pipe(
|
||||
switchMap(genomforandeReferens => this.gemensamPlaneringService.fetchAvropInformation$(genomforandeReferens)),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
gpFormGroup = new FormGroup(
|
||||
{
|
||||
label: 'Ja',
|
||||
value: 'Ja',
|
||||
},
|
||||
{
|
||||
label: 'Nej',
|
||||
value: 'Nej',
|
||||
distance: new FormControl(false),
|
||||
activityIds: new FormArray(this.obligatoryActivityIds.map(id => new FormControl(id))),
|
||||
},
|
||||
[GemensamPlaneringValidator.isGemensamPlaneringValid(this.obligatoryActivityIds)]
|
||||
);
|
||||
|
||||
distanceRadiobuttons: RadiobuttonModel[] = [
|
||||
{ label: 'Ja', value: true },
|
||||
{ label: 'Nej', value: false },
|
||||
];
|
||||
|
||||
constructor(private gemensamPlaneringService: GemensamPlaneringApiService) {}
|
||||
|
||||
get participatedOnDistansFormControl(): AbstractControl | undefined {
|
||||
return this.planeringFormGroup?.get(this.participatedOnDistansFormControlName);
|
||||
get activityIdsFormArray(): FormArray {
|
||||
return this.gpFormGroup.get('activityIds') as FormArray;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.planeringFormGroup = new FormGroup({
|
||||
participatedOnDistans: new FormControl('', [RequiredValidator()]),
|
||||
});
|
||||
get selectedActivityIds(): number[] {
|
||||
return this.activityIdsFormArray.value as number[];
|
||||
}
|
||||
|
||||
nextStep(): void {
|
||||
if (this.planeringFormGroup?.valid && this.currentStep < this.totalAmountOfSteps) {
|
||||
console.log(this.participatedOnDistansFormControl.value);
|
||||
this.currentStep++;
|
||||
console.log(this.currentStep);
|
||||
get selectedActivityIdsExcludingObligatory(): number[] {
|
||||
return this.selectedActivityIds.filter(id => this.obligatoryActivityIds.indexOf(id) === -1);
|
||||
}
|
||||
|
||||
isActivityChecked(id: number): boolean {
|
||||
return this.selectedActivityIds.includes(id);
|
||||
}
|
||||
|
||||
isActivityObligatory(id: number): boolean {
|
||||
return this.obligatoryActivityIds.includes(id);
|
||||
}
|
||||
|
||||
showActivityAsInvalid(id: number): boolean {
|
||||
if (this.shouldValidate) {
|
||||
if (this.isActivityObligatory(id) && !this.isActivityChecked(id)) {
|
||||
return true;
|
||||
}
|
||||
if (!this.isActivityObligatory(id) && !this.selectedActivityIdsExcludingObligatory.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constructor(private gemensamPlaneringService: GemensamPlaneringService, private activatedRoute: ActivatedRoute) {}
|
||||
|
||||
updateActivityIds(activityId: string, checked: boolean): void {
|
||||
if (checked) {
|
||||
this.activityIdsFormArray.push(new FormControl(+activityId));
|
||||
} else {
|
||||
const index: number = this.selectedActivityIds.findIndex(id => id === +activityId);
|
||||
|
||||
if (index > -1) {
|
||||
this.activityIdsFormArray.removeAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
previousStep(): void {
|
||||
if (this.currentStep > 1) {
|
||||
this.currentStep--;
|
||||
console.log(this.currentStep);
|
||||
goToPreview(): 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;
|
||||
}
|
||||
|
||||
closeConfirmDialogAndProceed(confirmDialogAnswer: ConfirmDialog, genomforandeReferens: number): void {
|
||||
if (confirmDialogAnswer === ConfirmDialog.ACCEPTED) {
|
||||
const distance = this.gpFormGroup.get('distance').value as boolean;
|
||||
const activityIds = this.gpFormGroup.get('activityIds').value as number[];
|
||||
|
||||
void this.postGemensamPlanering({ distance, activityIds, genomforandeReferens });
|
||||
} else {
|
||||
this.confirmDialogOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
sendRequest(val: boolean): boolean {
|
||||
return val;
|
||||
async postGemensamPlanering(postRequest: GemensamPlanering): Promise<void> {
|
||||
return this.gemensamPlaneringService
|
||||
.postGemensamPlanering(mapGemensamPlaneringToGemensamPlaneringPostRequest(postRequest))
|
||||
.then(() => {
|
||||
this._lastSubmittedGP$.next(new Date());
|
||||
});
|
||||
}
|
||||
|
||||
onFormSubmitted(): void {}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
|
||||
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
|
||||
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
|
||||
import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planering.component';
|
||||
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
|
||||
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||
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 { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
|
||||
import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planering.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
@@ -20,6 +24,10 @@ import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
|
||||
DigiNgFormRadiobuttonGroupModule,
|
||||
ReactiveFormsModule,
|
||||
ReportLayoutModule,
|
||||
ConfirmDialogModule,
|
||||
BackLinkModule,
|
||||
LoaderModule,
|
||||
DigiNgSkeletonBaseModule,
|
||||
DigiNgFormCheckboxModule,
|
||||
],
|
||||
exports: [DeltagareGemensamPlaneringComponent],
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Activity } from '@msfa-models/activity.model';
|
||||
import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model';
|
||||
import { Avrop } from '@msfa-models/avrop.model';
|
||||
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class GemensamPlaneringService {
|
||||
public activities$: Observable<Activity[]> = this.gemensamPlaneringApiService.fetchActivities$();
|
||||
private _error$ = new BehaviorSubject<string>(null);
|
||||
public error$: Observable<string> = this._error$.asObservable();
|
||||
|
||||
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
|
||||
return this.gemensamPlaneringApiService.fetchAvropInformation$(genomforandeReferens);
|
||||
}
|
||||
|
||||
public async postGemensamPlanering(requestData: GemensamPlaneringPostRequest): Promise<void> {
|
||||
// TODO: When API has been updated we can activate the real post
|
||||
return of(undefined as void).toPromise();
|
||||
return this.gemensamPlaneringApiService.postGemensamPlanering(requestData);
|
||||
}
|
||||
|
||||
constructor(private gemensamPlaneringApiService: GemensamPlaneringApiService) {}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
|
||||
export class GemensamPlaneringValidator {
|
||||
static isGemensamPlaneringValid(obligatoryActivityIds: number[] = []): ValidatorFn {
|
||||
return (c: AbstractControl): { [key: string]: string } => {
|
||||
let errors: { [key: string]: string } = null;
|
||||
const activityIds = (c.get('activityIds')?.value as number[]) || [];
|
||||
const obligatoryActivityIdsMissing = !obligatoryActivityIds.every(id => activityIds.includes(id));
|
||||
const activityIdsWithoutObligatoryActivityIds = activityIds.filter(
|
||||
id => obligatoryActivityIds.indexOf(id) === -1
|
||||
);
|
||||
|
||||
if (obligatoryActivityIdsMissing && !activityIdsWithoutObligatoryActivityIds.length) {
|
||||
errors = {
|
||||
...errors,
|
||||
activityIds: 'Obligatoriska aktiviteter och minst en frivillig aktivitet måste väljas',
|
||||
};
|
||||
} else {
|
||||
if (obligatoryActivityIdsMissing) {
|
||||
errors = {
|
||||
...errors,
|
||||
activityIds: 'Obligatoriska aktiviteter måste väljas',
|
||||
};
|
||||
}
|
||||
|
||||
if (!activityIdsWithoutObligatoryActivityIds.length) {
|
||||
errors = {
|
||||
...errors,
|
||||
activityIds: 'Minst en frivillig aktivitet måste väljas',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
|
||||
|
||||
describe('PeriodiskRedovisningComponent', () => {
|
||||
describe('DeltagarePeriodiskRedovisningComponent', () => {
|
||||
let component: DeltagarePeriodiskRedovisningComponent;
|
||||
let fixture: ComponentFixture<DeltagarePeriodiskRedovisningComponent>;
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { RadiobuttonGroupDirection } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { Activity, SubActivity } from '@msfa-models/activity.model';
|
||||
import { ActivitiesApiService } from '@msfa-services/api/activities-api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-deltagare-periodisk-redovisning',
|
||||
@@ -10,7 +9,7 @@ import { ActivitiesApiService } from '@msfa-services/api/activities-api.service'
|
||||
styleUrls: ['./deltagare-periodisk-redovisning.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagarePeriodiskRedovisningComponent implements OnInit {
|
||||
export class DeltagarePeriodiskRedovisningComponent {
|
||||
radiobuttonGroupDirection = RadiobuttonGroupDirection;
|
||||
totalAmountOfSteps = 3;
|
||||
currentStep = 1;
|
||||
@@ -25,8 +24,6 @@ export class DeltagarePeriodiskRedovisningComponent implements OnInit {
|
||||
readonly datesForActivitiesFormArrayName = 'datesForActivities';
|
||||
readonly subActivitiesFormArrayName = 'subActivities';
|
||||
|
||||
constructor(private activitiesApiService: ActivitiesApiService) {}
|
||||
|
||||
get lamnatJobbForslagFormControl(): AbstractControl {
|
||||
return this.periodiskRedovisningFormGroup.get(this.lamnatJobbForslagFormControlName);
|
||||
}
|
||||
@@ -39,12 +36,6 @@ export class DeltagarePeriodiskRedovisningComponent implements OnInit {
|
||||
return this.periodiskRedovisningFormGroup.get(this.activitiesFormArrayName) as FormArray;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.activitiesApiService
|
||||
.getActivities$()
|
||||
.subscribe(activities => this.initializePeriodiskRedovisningFormGroup(activities));
|
||||
}
|
||||
|
||||
initializePeriodiskRedovisningFormGroup(activitiesList: Activity[]): void {
|
||||
this.periodiskRedovisningFormGroup = new FormGroup({
|
||||
lamnatJobbForslag: new FormControl(null, [Validators.required]),
|
||||
@@ -70,9 +61,8 @@ export class DeltagarePeriodiskRedovisningComponent implements OnInit {
|
||||
getActivtiesFormField(formCtrlName: string, activity: Activity): FormArray | FormControl {
|
||||
if (formCtrlName === 'datesForActivities') {
|
||||
return new FormArray([]);
|
||||
} else if (formCtrlName === 'subActivities') {
|
||||
return this.addSubActivitesFormArray(activity?.subActivities, activity.id);
|
||||
}
|
||||
|
||||
return new FormControl(null, []);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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 { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
|
||||
import { PeriodiskRedovisningFormModule } from './components/periodisk-redovisning-form/periodisk-redovisning-form.module';
|
||||
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
<msfa-layout>
|
||||
<ng-container *ngIf="(showUnauthorizedError$ | async) === false; else roleError">
|
||||
<section *ngIf="allDeltagareData$ | async as allDeltagareData; else loadingRef" class="deltagare">
|
||||
<header class="deltagare__header">
|
||||
<h1>Deltagarlista</h1>
|
||||
<p>
|
||||
Här ser du en lista på de deltagare som tillhör din organisation. Klicka på deltagarens namn för att öppna
|
||||
och se mer information om deltagarna.
|
||||
</p>
|
||||
</header>
|
||||
<div class="deltagare__filter">
|
||||
<digi-form-checkbox
|
||||
(afOnChange)="setOnlyMyDeltagare($event.detail.target.checked)"
|
||||
[afChecked]="onlyMyDeltagare$ | async"
|
||||
af-label="Visa endast mina tilldelade deltagare"
|
||||
class="deltagare__only-my-deltagare"
|
||||
></digi-form-checkbox>
|
||||
</div>
|
||||
<msfa-deltagare-list-table
|
||||
(paginated)="setNewPage($event)"
|
||||
(sorted)="handleDeltagareSort($event)"
|
||||
*ngIf="allDeltagareData.data.length; else noDeltagare"
|
||||
[deltagareLoading]="deltagareLoading$ | async"
|
||||
[deltagare]="allDeltagareData.data"
|
||||
[paginationMeta]="allDeltagareData.meta"
|
||||
[sort]="sort$ | async"
|
||||
></msfa-deltagare-list-table>
|
||||
</section>
|
||||
<digi-typography>
|
||||
<section *ngIf="allDeltagareData$ | async as allDeltagareData; else loadingRef" class="deltagare">
|
||||
<header class="deltagare__header">
|
||||
<h1>Deltagarlista</h1>
|
||||
<p>
|
||||
Här ser du en lista på de deltagare som tillhör din organisation. Klicka på deltagarens namn för att öppna
|
||||
och se mer information om deltagarna.
|
||||
</p>
|
||||
</header>
|
||||
<div class="deltagare__filter">
|
||||
<digi-form-checkbox
|
||||
(afOnChange)="setOnlyMyDeltagare($event.detail.target.checked)"
|
||||
[afChecked]="onlyMyDeltagare$ | async"
|
||||
af-label="Visa endast mina tilldelade deltagare"
|
||||
class="deltagare__only-my-deltagare"
|
||||
></digi-form-checkbox>
|
||||
</div>
|
||||
<msfa-deltagare-list-table
|
||||
(paginated)="setNewPage($event)"
|
||||
(sorted)="handleDeltagareSort($event)"
|
||||
*ngIf="allDeltagareData.data.length; else noDeltagare"
|
||||
[deltagareLoading]="deltagareLoading$ | async"
|
||||
[deltagare]="allDeltagareData.data"
|
||||
[paginationMeta]="allDeltagareData.meta"
|
||||
[sort]="sort$ | async"
|
||||
></msfa-deltagare-list-table>
|
||||
</section>
|
||||
</digi-typography>
|
||||
</ng-container>
|
||||
</msfa-layout>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ConfirmDialog } from '@msfa-enums/confirm-dialog.enum';
|
||||
selector: 'msfa-confirm-dialog',
|
||||
templateUrl: './confirm-dialog.component.html',
|
||||
styleUrls: ['./confirm-dialog.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ConfirmDialogComponent {
|
||||
@Input() openConfirmDialog: boolean;
|
||||
@@ -21,5 +21,4 @@ export class ConfirmDialogComponent {
|
||||
this.openConfirmDialog = false;
|
||||
this.confirmDialogChanged.emit(ConfirmDialog.DISMISSED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
export interface Activity {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
subActivities: SubActivity[];
|
||||
}
|
||||
export interface SubActivity {
|
||||
id: number;
|
||||
@@ -12,15 +10,12 @@ export interface SubActivity {
|
||||
export interface ActivityResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
subActivities: SubActivity[];
|
||||
}
|
||||
|
||||
export function mapResponseToActivity(data: ActivityResponse): Activity {
|
||||
const { id, name, description, subActivities } = data;
|
||||
const { id, name } = data;
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
subActivities,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface GemensamPlaneringPostRequest {
|
||||
genomforandeReferens: string;
|
||||
distans: boolean;
|
||||
aktivitetsIds: number[];
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { TrackName } from '@msfa-enums/track-name.enum';
|
||||
import { mapStringToSsn } from '@msfa-utils/map-string-to-ssn.util';
|
||||
import { AvropResponse } from './api/avrop.response.model';
|
||||
import { PaginationMeta } from './pagination-meta.model';
|
||||
|
||||
@@ -17,6 +18,7 @@ export interface AvropCompact {
|
||||
}
|
||||
|
||||
export interface Avrop extends AvropCompact {
|
||||
ssn: string; // personnummer
|
||||
genomforandeReferens: number; // genomforandeReferens
|
||||
participationFrequency: number; // deltagandeGrad
|
||||
utforandeVerksamhet: string; // utforandeverksamhet
|
||||
@@ -41,6 +43,7 @@ export function mapAvropResponseToAvrop(data: AvropResponse): Avrop {
|
||||
sprakstod,
|
||||
adress,
|
||||
sparkod,
|
||||
personnummer,
|
||||
genomforandeReferens,
|
||||
deltagandeGrad,
|
||||
utforandeverksamhet,
|
||||
@@ -60,6 +63,7 @@ export function mapAvropResponseToAvrop(data: AvropResponse): Avrop {
|
||||
utforandeAdress: adress,
|
||||
trackCode: sparkod,
|
||||
trackName: (TrackName[sparkod] || TrackName.UNKNOWN) as TrackName,
|
||||
ssn: mapStringToSsn(personnummer),
|
||||
genomforandeReferens,
|
||||
participationFrequency: deltagandeGrad,
|
||||
utforandeVerksamhet: utforandeverksamhet,
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import { GemensamPlaneringPostRequest } from './api/gemensam-planering.request.model';
|
||||
|
||||
export interface GemensamPlanering {
|
||||
genomforandeReferens: number;
|
||||
distance: boolean;
|
||||
activityIds: number[];
|
||||
}
|
||||
|
||||
export interface Activity {
|
||||
activityId: string;
|
||||
name: string;
|
||||
@@ -9,3 +17,15 @@ export interface SubActivity {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export function mapGemensamPlaneringToGemensamPlaneringPostRequest(
|
||||
gemensamPlanering: GemensamPlanering
|
||||
): GemensamPlaneringPostRequest {
|
||||
const { genomforandeReferens, distance, activityIds } = gemensamPlanering;
|
||||
|
||||
return {
|
||||
genomforandeReferens: genomforandeReferens.toString(),
|
||||
distans: distance,
|
||||
aktivitetsIds: activityIds,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,21 +2,48 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { Activity, ActivityResponse, mapResponseToActivity } from '@msfa-models/activity.model';
|
||||
import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model';
|
||||
import { Avrop } from '@msfa-models/avrop.model';
|
||||
import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error';
|
||||
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { catchError, filter, map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class GemensamPlaneringApiService {
|
||||
private _apiBaseUrl = `${environment.api.url}`;
|
||||
private _apiBaseUrl = `${environment.api.url}/rapporter/gemensam-planering`;
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
|
||||
public getActivities$(): Observable<Activity[]> {
|
||||
return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/activities`).pipe(
|
||||
public fetchActivities$(): Observable<Activity[]> {
|
||||
return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/aktiviteter`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(aktivitet => mapResponseToActivity(aktivitet)))
|
||||
map(({ data }) => data.map(activity => mapResponseToActivity(activity))),
|
||||
catchError((error: Error & { status: number }) => {
|
||||
throw new CustomError(
|
||||
errorToCustomError({ ...error, message: `Kunde inte hämta aktiviteter.\n\n${error.message}` })
|
||||
);
|
||||
}),
|
||||
shareReplay(1)
|
||||
);
|
||||
}
|
||||
|
||||
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
|
||||
return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens);
|
||||
}
|
||||
|
||||
public async postGemensamPlanering(requestData: GemensamPlaneringPostRequest): Promise<void> {
|
||||
return this.httpClient
|
||||
.post<void>(`${this._apiBaseUrl}`, requestData)
|
||||
.pipe(
|
||||
catchError((error: Error & { status: number }) => {
|
||||
throw new CustomError(
|
||||
errorToCustomError({ ...error, message: `Kunde inte spara gemensam planering.\n\n${error.message}` })
|
||||
);
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
}
|
||||
|
||||
constructor(private httpClient: HttpClient, private deltagareApiService: DeltagareApiService) {}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"/api/rapporter/gemensam-planering": {
|
||||
"target": "https://mina-sidor-fa-utv.tocp.arbetsformedlingen.se",
|
||||
"secure": false,
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/api": {
|
||||
"target": "https://mina-sidor-fa-test.tocp.arbetsformedlingen.se",
|
||||
"secure": false,
|
||||
|
||||
Reference in New Issue
Block a user