feat(reports): Added report views to view single reports. (TV-205)

Squashed commit of the following:

commit bb28714969a6ac2d2b57134179344169edc1dc1d
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Tue Oct 12 14:15:45 2021 +0200

    Updated routing for signal

commit deb5082659065089c7014c7114538851e13fd6e4
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Tue Oct 12 14:07:33 2021 +0200

    Moved around files

commit 2637261f21968e63fcab4b13cccd8d68ab2ac6fe
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Tue Oct 12 11:22:11 2021 +0200

    Added avvikelse to single report page... also started with refactoring models a bit

commit 53c6a59551bfa0887b22d03419b3434a8c213b50
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Tue Oct 12 09:56:22 2021 +0200

    Implemented frånvaro report

commit e8ccbf15885f0bfa6eb86a9681464a2e04457f99
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 11 16:42:16 2021 +0200

    Added gemensam planering page

commit ebbf6f43ca
Merge: 45aec375 eac45ebd
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 11 15:14:02 2021 +0200

    Merge branch 'next' into develop

commit 45aec3755f
Merge: e4cff086 99c0ac3a
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 11 13:24:11 2021 +0200

    Merge branch 'next' into develop

commit e4cff086c4
Merge: ef10270f 631418bc
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 11 09:47:05 2021 +0200

    Merge branch 'next' into develop

commit ef10270fa9
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Mon Oct 11 09:23:59 2021 +0200

    Removed test build from develop
This commit is contained in:
Erik Tiekstra
2021-10-12 14:23:27 +02:00
parent eac45ebd16
commit 0045cafd77
81 changed files with 1104 additions and 238 deletions

View File

@@ -12,17 +12,9 @@ const routes: Routes = [
loadChildren: () => loadChildren: () =>
import('./pages/deltagare-details/deltagare-details.module').then(m => m.DeltagareDetailsModule), import('./pages/deltagare-details/deltagare-details.module').then(m => m.DeltagareDetailsModule),
}, },
{
path: ':genomforandeReferens/signal',
data: { title: 'Skapa signal om arbete eller studier' },
loadChildren: () =>
import(
'./pages/deltagare-details/pages/deltagare-reports/deltagare-signal-arbete-studier/deltagare-signal-arbete-studier.module'
).then(m => m.DeltagareSignalArbeteStudierModule),
},
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule], exports: [RouterModule],
}) })
export class DeltagareRoutingModule { } export class DeltagareRoutingModule {}

View File

@@ -9,34 +9,68 @@ const routes: Routes = [
}, },
{ {
path: 'avvikelserapport', path: 'avvikelserapport',
data: { title: 'Skapa avvikelserapport' }, data: { title: 'Skapa Avvikelserapport (Avvikelse)' },
loadChildren: () => loadChildren: () =>
import('./pages/deltagare-reports/deltagare-avvikelserapport/deltagare-avvikelserapport.module').then( import('./pages/report-forms/avvikelse-report-form/avvikelse-report-form.module').then(
m => m.DeltagareAvvikelserapportModule m => m.AvvikelseReportFormModule
),
},
{
path: 'avvikelserapport/:reportId',
data: { title: 'Avvikelserapport (avvikelse)' },
loadChildren: () =>
import('./pages/report-views/avvikelse-report-view/avvikelse-report-view.module').then(
m => m.AvvikelseReportViewModule
), ),
}, },
{ {
path: 'franvarorapport', path: 'franvarorapport',
data: { title: 'Skapa rapport' }, data: { title: 'Skapa Avvikelserapport (frånvaro)' },
loadChildren: () => loadChildren: () =>
import('./pages/deltagare-reports/franvaro-report/franvaro-report.module').then(m => m.FranvaroReportModule), import('./pages/report-forms/franvaro-report-form/franvaro-report-form.module').then(
m => m.FranvaroReportFormModule
),
},
{
path: 'franvarorapport/:reportId',
data: { title: 'Avvikelserapport (frånvaro)' },
loadChildren: () =>
import('./pages/report-views/franvaro-report-view/franvaro-report-view.module').then(
m => m.FranvaroReportViewModule
),
}, },
{ {
path: 'gemensam-planering', path: 'gemensam-planering',
data: { title: 'Skapa Gemensam planering' }, data: { title: 'Skapa Gemensam planering' },
loadChildren: () => loadChildren: () =>
import('./pages/deltagare-reports/deltagare-gemensam-planering/deltagare-gemensam-planering.module').then( import('./pages/report-forms/gemensam-planering-form/gemensam-planering-form.module').then(
m => m.DeltagareGemensamPlaneringModule m => m.GemensamPlaneringFormModule
),
},
{
path: 'gemensam-planering/:reportId',
data: { title: 'Gemensam planering' },
loadChildren: () =>
import('./pages/report-views/gemensam-planering-view/gemensam-planering-view.module').then(
m => m.GemensamPlaneringViewModule
), ),
}, },
{ {
path: 'periodisk-redovisning', path: 'periodisk-redovisning',
data: { title: 'Skapa periodisk redovisning' }, data: { title: 'Skapa periodisk redovisning' },
loadChildren: () => loadChildren: () =>
import('./pages/deltagare-reports/deltagare-periodisk-redovisning/deltagare-periodisk-redovisning.module').then( import('./pages/report-forms/deltagare-periodisk-redovisning/deltagare-periodisk-redovisning.module').then(
m => m.DeltagarePeriodiskRedovisningModule m => m.DeltagarePeriodiskRedovisningModule
), ),
}, },
{
path: 'signal',
data: { title: 'Skapa signal om arbete eller studier' },
loadChildren: () =>
import('./pages/report-forms/deltagare-signal-arbete-studier/deltagare-signal-arbete-studier.module').then(
m => m.DeltagareSignalArbeteStudierModule
),
},
]; ];
@NgModule({ @NgModule({

View File

@@ -9,7 +9,12 @@
<tbody> <tbody>
<tr *ngFor="let report of reports"> <tr *ngFor="let report of reports">
<th scope="row">{{ report.type }}</th> <th scope="row">
<a *ngIf="getReportLink(report); else reportTypeTextRef" [routerLink]="getReportLink(report)"
>{{ report.type }}</a
>
<ng-template #reportTypeTextRef>{{report.type}}</ng-template>
</th>
<td>{{ report.date | date:'longDate' }} {{ report.date | date:'shortTime' }}</td> <td>{{ report.date | date:'longDate' }} {{ report.date | date:'shortTime' }}</td>
<td>{{ report.status }}</td> <td>{{ report.status }}</td>
</tr> </tr>

View File

@@ -1,4 +1,5 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { ReportType } from '@msfa-enums/report-type.enum';
import { PaginationMeta } from '@msfa-models/pagination-meta.model'; import { PaginationMeta } from '@msfa-models/pagination-meta.model';
import { Report } from '@msfa-models/report.model'; import { Report } from '@msfa-models/report.model';
@@ -49,6 +50,19 @@ export class ReportsListComponent {
return end < this.count ? end : this.count; return end < this.count ? end : this.count;
} }
getReportLink(report: Report): string {
switch (report.type) {
case ReportType.GemensamPlanering:
return `./gemensam-planering/${report.id}`;
case ReportType.Franvaro:
return `./franvarorapport/${report.id}`;
case ReportType.Avvikelse:
return `./avvikelserapport/${report.id}`;
default:
return null;
}
}
emitNewPage(page: number): void { emitNewPage(page: number): void {
this.paginated.emit(page); this.paginated.emit(page);
} }

View File

@@ -1,13 +0,0 @@
import { DayOrPartOfDay } from '@msfa-enums/day-or-part-of-day.enum';
import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group';
export const dayOrPartOfDay: RadiobuttonModel[] = [
{
label: 'Heldag',
value: DayOrPartOfDay.HELDAG,
},
{
label: 'Del av dag',
value: DayOrPartOfDay.DEL_AV_DAG,
},
];

View File

@@ -5,13 +5,13 @@
description="Här rapporterar du deltagarens avvikelser. Exempelvis kan du rapportera om tjänsten inte fungerar för deltagaren eller om deltagaren misskött sig under tjänsten." description="Här rapporterar du deltagarens avvikelser. Exempelvis kan du rapportera om tjänsten inte fungerar för deltagaren eller om deltagaren misskött sig under tjänsten."
reportTitle="Avvikelserapport (avvikelse)" reportTitle="Avvikelserapport (avvikelse)"
> >
<div class="deltagare-avvikelse"> <div class="avvikelse-report-form">
<div *ngIf="submittedDate$ | async as submittedDate; else formRef" class="deltagare-avvikelse__confirmation"> <div *ngIf="submittedDate$ | async as submittedDate; else formRef" class="avvikelse-report-form__confirmation">
<digi-notification-alert <digi-notification-alert
af-heading="Allt gick bra" af-heading="Allt gick bra"
af-heading-level="h3" af-heading-level="h3"
af-variation="success" af-variation="success"
class="deltagare-avvikelse__alert" class="avvikelse-report-form__alert"
> >
<p>Avvikelserapport (avvikelse) för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen.</p> <p>Avvikelserapport (avvikelse) för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen.</p>
<dl> <dl>
@@ -23,8 +23,8 @@
</div> </div>
<ng-template #formRef> <ng-template #formRef>
<form class="deltagare-avvikelse__form" [formGroup]="avvikelseFormGroup" (ngSubmit)="openConfirmDialog()"> <form class="avvikelse-report-form__form" [formGroup]="avvikelseFormGroup" (ngSubmit)="openConfirmDialog()">
<div class="deltagare-avvikelse__form-item"> <div class="avvikelse-report-form__form-item">
<digi-ng-form-select <digi-ng-form-select
*ngIf="reasonsAsNgDigiFormSelectItems$ | async; let reason; else loadingRef" *ngIf="reasonsAsNgDigiFormSelectItems$ | async; let reason; else loadingRef"
[formControlName]="reasonFormName" [formControlName]="reasonFormName"
@@ -40,12 +40,12 @@
</div> </div>
<div <div
class="deltagare-avvikelse__form-item deltagare-avvikelse__textareas" class="avvikelse-report-form__form-item avvikelse-report-form__textareas"
[formArrayName]="questionsFormName" [formArrayName]="questionsFormName"
*ngIf="questionsForChosenReason$ | async; let questions" *ngIf="questionsForChosenReason$ | async; let questions"
> >
<div <div
class="deltagare-avvikelse__form-item" class="avvikelse-report-form__form-item"
*ngFor="let question of questionsFormArray.controls; let i=index" *ngFor="let question of questionsFormArray.controls; let i=index"
> >
<digi-ng-form-textarea <digi-ng-form-textarea
@@ -61,7 +61,7 @@
</div> </div>
</div> </div>
<div class="deltagare-avvikelse__form-item" *ngIf="chosenReasonId$ | async"> <div class="avvikelse-report-form__form-item" *ngIf="chosenReasonId$ | async">
<digi-ng-form-datepicker <digi-ng-form-datepicker
[afDisableValidStyle]="true" [afDisableValidStyle]="true"
[afMinDate]="minDate(avrop)" [afMinDate]="minDate(avrop)"
@@ -75,7 +75,7 @@
></digi-ng-form-datepicker> ></digi-ng-form-datepicker>
</div> </div>
<div class="deltagare-avvikelse__cta-wrapper"> <div class="avvikelse-report-form__cta-wrapper">
<digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button> <digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button>
<msfa-back-link [showIcon]="false" [asButton]="true" route="../"> <msfa-back-link [showIcon]="false" [asButton]="true" route="../">
<span>Avbryt</span> <span>Avbryt</span>
@@ -134,7 +134,10 @@
</msfa-report-layout> </msfa-report-layout>
</msfa-layout> </msfa-layout>
<ng-template #skeletonRef> <ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar data för avvikelserapport"></digi-ng-skeleton-base> <digi-ng-skeleton-base
[afCount]="3"
afText="Laddar data för att kunna skapa Avvikelserapport (avvikelse)"
></digi-ng-skeleton-base>
</ng-template> </ng-template>
<ng-template #loadingRef> <ng-template #loadingRef>
<msfa-loader type="padded"></msfa-loader> <msfa-loader type="padded"></msfa-loader>

View File

@@ -1,6 +1,6 @@
@import 'variables/gutters'; @import 'variables/gutters';
.deltagare-avvikelse { .avvikelse-report-form {
max-width: var(--digi--typography--text--max-width); max-width: var(--digi--typography--text--max-width);
&__confirmation, &__confirmation,

View File

@@ -6,17 +6,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { DeltagareAvvikelserapportComponent } from './deltagare-avvikelserapport.component'; import { AvvikelseReportFormComponent } from './avvikelse-report-form.component';
import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; import { AvvikelseReportFormService } from './avvikelse-report-form.service';
describe('DeltagareAvvikelseComponent', () => { describe('AvvikelseReportFormComponent', () => {
let component: DeltagareAvvikelserapportComponent; let component: AvvikelseReportFormComponent;
let fixture: ComponentFixture<DeltagareAvvikelserapportComponent>; let fixture: ComponentFixture<AvvikelseReportFormComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareAvvikelserapportComponent, LayoutComponent], declarations: [AvvikelseReportFormComponent, LayoutComponent],
imports: [ imports: [
RouterTestingModule, RouterTestingModule,
HttpClientTestingModule, HttpClientTestingModule,
@@ -24,12 +24,12 @@ describe('DeltagareAvvikelseComponent', () => {
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
DigiNgFormDatepickerModule, DigiNgFormDatepickerModule,
], ],
providers: [DeltagareAvvikelserapportService], providers: [AvvikelseReportFormService],
}).compileComponents(); }).compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(DeltagareAvvikelserapportComponent); fixture = TestBed.createComponent(AvvikelseReportFormComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -3,17 +3,16 @@ import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Avrop } from '@msfa-models/avrop.model'; import { Avrop } from '@msfa-models/avrop.model';
import { AvvikelseAlternativ, AvvikelseRequestData } from '@msfa-models/avvikelse.model'; import { AvvikelseAlternativ_OLD, AvvikelseRequestData_OLD } from '@msfa-models/avvikelse.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model';
import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util';
import { RegexValidator } from '@msfa-utils/validators/regex.validator'; import { RegexValidator } from '@msfa-utils/validators/regex.validator';
import { RequiredValidator } from '@msfa-validators/required.validator'; import { RequiredValidator } from '@msfa-validators/required.validator';
import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs';
import { map, shareReplay, switchMap, take } from 'rxjs/operators'; import { map, shareReplay, switchMap, take } from 'rxjs/operators';
import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; import { AvvikelseReportFormService } from './avvikelse-report-form.service';
interface Params { interface Params {
genomforandeReferens: string; genomforandeReferens: string;
@@ -28,12 +27,12 @@ interface AvvikelseFormData {
type AvvikelseFormKeys = keyof AvvikelseFormData; type AvvikelseFormKeys = keyof AvvikelseFormData;
@Component({ @Component({
selector: 'msfa-deltagare-avvikelse', selector: 'msfa-avvikelse-report-form',
templateUrl: './deltagare-avvikelserapport.component.html', templateUrl: './avvikelse-report-form.component.html',
styleUrls: ['./deltagare-avvikelserapport.component.scss'], styleUrls: ['./avvikelse-report-form.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy { export class AvvikelseReportFormComponent implements OnInit, OnDestroy {
shouldValidate$ = new BehaviorSubject<boolean>(false); shouldValidate$ = new BehaviorSubject<boolean>(false);
reasonFormName: AvvikelseFormKeys = 'reason'; reasonFormName: AvvikelseFormKeys = 'reason';
@@ -46,20 +45,20 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy {
map((params: Params) => +params.genomforandeReferens) map((params: Params) => +params.genomforandeReferens)
); );
avrop$: Observable<Avrop> = this.genomforandeReferens$.pipe( avrop$: Observable<Avrop> = this.genomforandeReferens$.pipe(
switchMap(genomforandeReferens => this.deltagareAvvikelseService.fetchAvropInformation$(genomforandeReferens)), switchMap(genomforandeReferens => this.avvikelseReportFormService.fetchAvropInformation$(genomforandeReferens)),
shareReplay(1) shareReplay(1)
); );
reasons$: Observable<OrsaksKoderAvvikelse[]> = this.deltagareAvvikelseService.getAvvikelseOrsaker$; reasons$: Observable<OrsaksKoderAvvikelse[]> = this.avvikelseReportFormService.getAvvikelseOrsaker$;
reasonsAsNgDigiFormSelectItems$: Observable<FormSelectItem[]> = this.reasons$.pipe( reasonsAsNgDigiFormSelectItems$: Observable<FormSelectItem[]> = this.reasons$.pipe(
map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id }))) map(reasons => reasons.map(reason => ({ name: reason.name, value: reason.id })))
); );
allAvvikelseQuestions$ = this.deltagareAvvikelseService.fragorForAvvikelser$; allAvvikelseQuestions$ = this.avvikelseReportFormService.fragorForAvvikelser$;
chosenReasonId$: Observable<string>; chosenReasonId$: Observable<string>;
chosenReason$: Observable<OrsaksKoderAvvikelse>; chosenReason$: Observable<OrsaksKoderAvvikelse>;
questionsForChosenReason$: Observable<FragorForAvvikelser[]>; questionsForChosenReason$: Observable<FragorForAvvikelser[]>;
avvikelseSubmitData$: Observable<AvvikelseRequestData>; avvikelseSubmitData$: Observable<AvvikelseRequestData_OLD>;
confirmDialogIsOpen$ = new BehaviorSubject<boolean>(false); confirmDialogIsOpen$ = new BehaviorSubject<boolean>(false);
submittedDate$ = new BehaviorSubject<Date | null>(null); submittedDate$ = new BehaviorSubject<Date | null>(null);
private subscriptions: Subscription[] = []; private subscriptions: Subscription[] = [];
@@ -73,11 +72,7 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy {
.valueChanges as Observable<AvvikelseFormData>; .valueChanges as Observable<AvvikelseFormData>;
private currentQuestions: FragorForAvvikelser[]; private currentQuestions: FragorForAvvikelser[];
constructor( constructor(private avvikelseReportFormService: AvvikelseReportFormService, private activatedRoute: ActivatedRoute) {}
private deltagareAvvikelseService: DeltagareAvvikelserapportService,
private deltagareApiService: DeltagareApiService,
private activatedRoute: ActivatedRoute
) {}
get reasonFormControl(): AbstractControl | undefined { get reasonFormControl(): AbstractControl | undefined {
return this.avvikelseFormGroup.get(this.reasonFormName); return this.avvikelseFormGroup.get(this.reasonFormName);
@@ -154,7 +149,7 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy {
submitAndCloseConfirmDialog(): void { submitAndCloseConfirmDialog(): void {
this.submitIsLoading$.next(true); this.submitIsLoading$.next(true);
this.avvikelseSubmitData$.pipe(take(1)).subscribe(avvikelseSubmitData => this.avvikelseSubmitData$.pipe(take(1)).subscribe(avvikelseSubmitData =>
this.deltagareAvvikelseService.createAvvikelse$(avvikelseSubmitData).subscribe({ this.avvikelseReportFormService.createAvvikelse$(avvikelseSubmitData).subscribe({
next: () => { next: () => {
this.submitIsLoading$.next(false); this.submitIsLoading$.next(false);
this.submittedDate$.next(new Date()); this.submittedDate$.next(new Date());
@@ -180,15 +175,15 @@ export class DeltagareAvvikelserapportComponent implements OnInit, OnDestroy {
genomforandeReferens: number, genomforandeReferens: number,
chosenReason: string, chosenReason: string,
formData: AvvikelseFormData formData: AvvikelseFormData
): AvvikelseRequestData { ): AvvikelseRequestData_OLD {
const avvikelseAlternativ: AvvikelseAlternativ = { const avvikelseAlternativ: AvvikelseAlternativ_OLD = {
avvikelseorsakskod: chosenReason, avvikelseorsakskod: chosenReason,
frageformular: formData.questions.map((question, index) => ({ frageformular: formData.questions.map((question, index) => ({
fraga: this.currentQuestions[index].id, fraga: this.currentQuestions[index].id,
svar: question, svar: question,
})), })),
rapporteringsdatum: formData.reportingDate, rapporteringsdatum: formData.reportingDate,
} as AvvikelseAlternativ; } as AvvikelseAlternativ_OLD;
return { genomforandeReferens, avvikelseAlternativ }; return { genomforandeReferens, avvikelseAlternativ };
} }

View File

@@ -15,16 +15,16 @@ import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/conf
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module'; import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { DeltagareAvvikelserapportComponent } from './deltagare-avvikelserapport.component'; import { AvvikelseReportFormComponent } from './avvikelse-report-form.component';
import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.service'; import { AvvikelseReportFormService } from './avvikelse-report-form.service';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareAvvikelserapportComponent], declarations: [AvvikelseReportFormComponent],
imports: [ imports: [
CommonModule, CommonModule,
RouterModule.forChild([{ path: '', component: DeltagareAvvikelserapportComponent }]), RouterModule.forChild([{ path: '', component: AvvikelseReportFormComponent }]),
LayoutModule, LayoutModule,
ReactiveFormsModule, ReactiveFormsModule,
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
@@ -41,7 +41,7 @@ import { DeltagareAvvikelserapportService } from './deltagare-avvikelserapport.s
DigiNgFormInputModule, DigiNgFormInputModule,
DigiNgDialogModule, DigiNgDialogModule,
], ],
providers: [DeltagareAvvikelserapportService], providers: [AvvikelseReportFormService],
exports: [DeltagareAvvikelserapportComponent], exports: [AvvikelseReportFormComponent],
}) })
export class DeltagareAvvikelserapportModule {} export class AvvikelseReportFormModule {}

View File

@@ -1,14 +1,14 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Avvikelse } from '@msfa-models/avvikelse.model'; import { Avvikelse_OLD } from '@msfa-models/avvikelse.model';
import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model';
import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model';
import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service'; import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { shareReplay } from 'rxjs/operators'; import { shareReplay } from 'rxjs/operators';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
@Injectable() @Injectable()
export class DeltagareAvvikelserapportService { export class AvvikelseReportFormService {
fragorForAvvikelser$: Observable<FragorForAvvikelser[]> = this.avvikelseApiService fragorForAvvikelser$: Observable<FragorForAvvikelser[]> = this.avvikelseApiService
.getFragorForAvvikelser$() .getFragorForAvvikelser$()
.pipe(shareReplay(1)); .pipe(shareReplay(1));
@@ -17,7 +17,7 @@ export class DeltagareAvvikelserapportService {
constructor(private avvikelseApiService: AvvikelseApiService, private deltagareApiService: DeltagareApiService) {} constructor(private avvikelseApiService: AvvikelseApiService, private deltagareApiService: DeltagareApiService) {}
createAvvikelse$(avvikelse: Avvikelse): Observable<unknown> { createAvvikelse$(avvikelse: Avvikelse_OLD): Observable<unknown> {
return this.avvikelseApiService.createAvvikelse$(avvikelse); return this.avvikelseApiService.createAvvikelse$(avvikelse);
} }

View File

@@ -4,7 +4,7 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { PeriodiskRedovisningFormModule } from './components/periodisk-redovisning-form/periodisk-redovisning-form.module'; import { PeriodiskRedovisningFormModule } from './components/periodisk-redovisning-form/periodisk-redovisning-form.module';
import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component'; import { DeltagarePeriodiskRedovisningComponent } from './deltagare-periodisk-redovisning.component';

View File

@@ -10,7 +10,7 @@ import { RouterModule } from '@angular/router';
import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module'; import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { DeltagareConfirmSignalFormModule } from './components/deltagare-confirm-signal-form/deltagare-confirm-signal-form.module'; import { DeltagareConfirmSignalFormModule } from './components/deltagare-confirm-signal-form/deltagare-confirm-signal-form.module';
import { DeltagareSignalArbeteStudierComponent } from './deltagare-signal-arbete-studier.component'; import { DeltagareSignalArbeteStudierComponent } from './deltagare-signal-arbete-studier.component';
@@ -30,8 +30,8 @@ import { DeltagareSignalArbeteStudierComponent } from './deltagare-signal-arbete
ReportLayoutModule, ReportLayoutModule,
ConfirmDialogModule, ConfirmDialogModule,
DigiNgSkeletonBaseModule, DigiNgSkeletonBaseModule,
BackLinkModule BackLinkModule,
], ],
exports: [DeltagareSignalArbeteStudierComponent], exports: [DeltagareSignalArbeteStudierComponent],
}) })
export class DeltagareSignalArbeteStudierModule { } export class DeltagareSignalArbeteStudierModule {}

View File

@@ -5,8 +5,8 @@
description="Här rapporterar du deltagarens frånvaro i tjänsten." description="Här rapporterar du deltagarens frånvaro i tjänsten."
reportTitle="Avvikelserapport (frånvaro)" reportTitle="Avvikelserapport (frånvaro)"
> >
<div class="franvaro-report" *ngIf="currentGenomforandeReferens$ | async as genomforandeReferens"> <div class="franvaro-report-form" *ngIf="currentGenomforandeReferens$ | async as genomforandeReferens">
<div class="franvaro-report__warning" *ngIf="maxDate < avrop.startDate; else reportRef"> <div class="franvaro-report-form__warning" *ngIf="maxDate < avrop.startDate; else reportRef">
<digi-notification-alert af-variation="warning" af-heading="Kan inte skapa Avvikelserapport (frånvaro)"> <digi-notification-alert af-variation="warning" af-heading="Kan inte skapa Avvikelserapport (frånvaro)">
<p>Det går inte att rapportera frånvaro eftersom tjänsten inte har startat ännu.</p> <p>Det går inte att rapportera frånvaro eftersom tjänsten inte har startat ännu.</p>
</digi-notification-alert> </digi-notification-alert>
@@ -16,7 +16,7 @@
<ng-template #reportRef> <ng-template #reportRef>
<div <div
class="franvaro-report__confirmation" class="franvaro-report-form__confirmation"
*ngIf="lastSubmittedFranvaroReport$ | async as lastSubmittedFranvaroReport; else formRef" *ngIf="lastSubmittedFranvaroReport$ | async as lastSubmittedFranvaroReport; else formRef"
> >
<digi-notification-alert af-variation="success" af-heading="Allt gick bra" af-heading-level="h3"> <digi-notification-alert af-variation="success" af-heading="Allt gick bra" af-heading-level="h3">
@@ -32,12 +32,12 @@
</div> </div>
<ng-template #formRef> <ng-template #formRef>
<form <form
class="franvaro-report__form" class="franvaro-report-form__form"
[formGroup]="franvaroFormGroup" [formGroup]="franvaroFormGroup"
(ngSubmit)="openConfirmDialog()" (ngSubmit)="openConfirmDialog()"
id="franvaro-report-form" id="franvaro-report-form"
> >
<div class="franvaro-report__form-item"> <div class="franvaro-report-form__form-item">
<digi-ng-form-select <digi-ng-form-select
*ngIf="reasons$ | async as reasons; else loadingRef" *ngIf="reasons$ | async as reasons; else loadingRef"
[formControl]="reasonFormControl" [formControl]="reasonFormControl"
@@ -53,7 +53,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['reason'])" *ngIf="formControlIsInvalid(['reason'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.reason" [afValidationText]="formErrors.reason"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -63,7 +63,7 @@
<ng-container *ngIf="reasonFormControl.value"> <ng-container *ngIf="reasonFormControl.value">
<ng-container *ngIf="showOtherKnownReasonsSelect"> <ng-container *ngIf="showOtherKnownReasonsSelect">
<div <div
class="franvaro-report__form-item" class="franvaro-report-form__form-item"
*ngIf="otherKnownReasons$ | async as otherKnownReasons; else loadingRef" *ngIf="otherKnownReasons$ | async as otherKnownReasons; else loadingRef"
> >
<digi-ng-form-select <digi-ng-form-select
@@ -79,14 +79,14 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['otherKnownReason'])" *ngIf="formControlIsInvalid(['otherKnownReason'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.otherKnownReason" [afValidationText]="formErrors.otherKnownReason"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
</div> </div>
</div> </div>
<div class="franvaro-report__form-item" *ngIf="showKnownReasonTextArea"> <div class="franvaro-report-form__form-item" *ngIf="showKnownReasonTextArea">
<digi-ng-form-textarea <digi-ng-form-textarea
[afDisableValidStyle]="true" [afDisableValidStyle]="true"
[afInvalid]="formControlIsInvalid(['knownReasonComment'])" [afInvalid]="formControlIsInvalid(['knownReasonComment'])"
@@ -100,7 +100,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['knownReasonComment'])" *ngIf="formControlIsInvalid(['knownReasonComment'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.knownReasonComment" [afValidationText]="formErrors.knownReasonComment"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -108,7 +108,7 @@
</div> </div>
</ng-container> </ng-container>
<div class="franvaro-report__form-item"> <div class="franvaro-report-form__form-item">
<digi-ng-form-datepicker <digi-ng-form-datepicker
[afDisableValidStyle]="true" [afDisableValidStyle]="true"
[afMinDate]="avrop.startDate" [afMinDate]="avrop.startDate"
@@ -122,14 +122,14 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['date'])" *ngIf="formControlIsInvalid(['date'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.date" [afValidationText]="formErrors.date"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
</div> </div>
</div> </div>
<div class="franvaro-report__form-item"> <div class="franvaro-report-form__form-item">
<h2>Tiden deltagaren var frånvarande</h2> <h2>Tiden deltagaren var frånvarande</h2>
<digi-form-fieldset <digi-form-fieldset
af-legend="Heldag eller del av dag" af-legend="Heldag eller del av dag"
@@ -145,8 +145,8 @@
</div> </div>
<ng-container *ngIf="showTimePickers"> <ng-container *ngIf="showTimePickers">
<div class="franvaro-report__time-pickers"> <div class="franvaro-report-form__time-pickers">
<div class="franvaro-report__time-picker"> <div class="franvaro-report-form__time-picker">
<digi-ng-form-input <digi-ng-form-input
afLabel="Starttid" afLabel="Starttid"
[formControl]="startTimeFormControl" [formControl]="startTimeFormControl"
@@ -159,13 +159,13 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['startTime'])" *ngIf="formControlIsInvalid(['startTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.startTime" [afValidationText]="formErrors.startTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
</div> </div>
</div> </div>
<div class="franvaro-report__time-picker"> <div class="franvaro-report-form__time-picker">
<digi-ng-form-input <digi-ng-form-input
afLabel="Sluttid" afLabel="Sluttid"
[formControl]="endTimeFormControl" [formControl]="endTimeFormControl"
@@ -178,7 +178,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['endTime'])" *ngIf="formControlIsInvalid(['endTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.endTime" [afValidationText]="formErrors.endTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -188,7 +188,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['expectedEndTimeIsBeforeStartTime'])" *ngIf="formControlIsInvalid(['expectedEndTimeIsBeforeStartTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.expectedEndTimeIsBeforeStartTime" [afValidationText]="formErrors.expectedEndTimeIsBeforeStartTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -197,8 +197,8 @@
<div> <div>
<h2>Tiden deltagaren skulle varit närvarande</h2> <h2>Tiden deltagaren skulle varit närvarande</h2>
<div class="franvaro-report__time-pickers"> <div class="franvaro-report-form__time-pickers">
<div class="franvaro-report__time-picker"> <div class="franvaro-report-form__time-picker">
<digi-ng-form-input <digi-ng-form-input
afLabel="Starttid" afLabel="Starttid"
[formControl]="expectedPresenceStartTimeFormControl" [formControl]="expectedPresenceStartTimeFormControl"
@@ -211,13 +211,13 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['expectedPresenceStartTime'])" *ngIf="formControlIsInvalid(['expectedPresenceStartTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.expectedPresenceStartTime" [afValidationText]="formErrors.expectedPresenceStartTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
</div> </div>
</div> </div>
<div class="franvaro-report__time-picker"> <div class="franvaro-report-form__time-picker">
<digi-ng-form-input <digi-ng-form-input
afLabel="Sluttid" afLabel="Sluttid"
[formControl]="expectedPresenceEndTimeFormControl" [formControl]="expectedPresenceEndTimeFormControl"
@@ -230,7 +230,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['expectedPresenceEndTime'])" *ngIf="formControlIsInvalid(['expectedPresenceEndTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.expectedPresenceEndTime" [afValidationText]="formErrors.expectedPresenceEndTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -240,7 +240,7 @@
<div aria-atomic="true" role="alert"> <div aria-atomic="true" role="alert">
<digi-ng-form-validation-message <digi-ng-form-validation-message
*ngIf="formControlIsInvalid(['expectedPresenceEndTimeIsBeforeStartTime'])" *ngIf="formControlIsInvalid(['expectedPresenceEndTimeIsBeforeStartTime'])"
class="franvaro-report__validation-message" class="franvaro-report-form__validation-message"
[afPositive]="false" [afPositive]="false"
[afValidationText]="formErrors.expectedPresenceEndTimeIsBeforeStartTime" [afValidationText]="formErrors.expectedPresenceEndTimeIsBeforeStartTime"
></digi-ng-form-validation-message> ></digi-ng-form-validation-message>
@@ -248,17 +248,17 @@
</div> </div>
</ng-container> </ng-container>
<footer class="franvaro-report__footer"> <footer class="franvaro-report-form__footer">
<digi-notification-alert <digi-notification-alert
*ngIf="error$ | async as error" *ngIf="error$ | async as error"
class="franvaro-report__alert" class="franvaro-report-form__alert"
af-variation="danger" af-variation="danger"
af-heading="Någonting gick fel" af-heading="Någonting gick fel"
> >
<p>Kunde inte spara Avvikelserapport (frånvaro). Ladda om sidan och försök igen.</p> <p>Kunde inte spara Avvikelserapport (frånvaro). Ladda om sidan och försök igen.</p>
<p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p> <p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p>
</digi-notification-alert> </digi-notification-alert>
<div class="franvaro-report__cta-wrapper"> <div class="franvaro-report-form__cta-wrapper">
<digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button> <digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button>
<msfa-back-link [showIcon]="false" [asButton]="true" route="../"> <msfa-back-link [showIcon]="false" [asButton]="true" route="../">
<span>Avbryt</span> <span>Avbryt</span>
@@ -334,7 +334,10 @@
</msfa-layout> </msfa-layout>
<ng-template #skeletonRef> <ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar data för Avvikelserapport (frånvaro)"></digi-ng-skeleton-base> <digi-ng-skeleton-base
[afCount]="3"
afText="Laddar data för att kunna skapa Avvikelserapport (frånvaro)"
></digi-ng-skeleton-base>
</ng-template> </ng-template>
<ng-template #loadingRef> <ng-template #loadingRef>

View File

@@ -1,7 +1,7 @@
@import 'variables/gutters'; @import 'variables/gutters';
@import 'variables/z-index'; @import 'variables/z-index';
.franvaro-report { .franvaro-report-form {
max-width: var(--digi--typography--text--max-width); max-width: var(--digi--typography--text--max-width);
&__confirmation, &__confirmation,

View File

@@ -3,24 +3,24 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { FranvaroReportComponent } from './franvaro-report.component'; import { FranvaroReportFormComponent } from './franvaro-report-form.component';
import { FranvaroReportService } from './franvaro-report.service'; import { FranvaroReportFormService } from './franvaro-report-form.service';
describe('FranvaroReportComponent', () => { describe('FranvaroReportFormComponent', () => {
let component: FranvaroReportComponent; let component: FranvaroReportFormComponent;
let fixture: ComponentFixture<FranvaroReportComponent>; let fixture: ComponentFixture<FranvaroReportFormComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [FranvaroReportComponent, LayoutComponent], declarations: [FranvaroReportFormComponent, LayoutComponent],
imports: [RouterTestingModule, HttpClientTestingModule], imports: [RouterTestingModule, HttpClientTestingModule],
providers: [FranvaroReportService], providers: [FranvaroReportFormService],
}).compileComponents(); }).compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(FranvaroReportComponent); fixture = TestBed.createComponent(FranvaroReportFormComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -5,23 +5,23 @@ import { ActivatedRoute } from '@angular/router';
import { ANNAN_KAND_ORSAK_ID, ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons'; import { ANNAN_KAND_ORSAK_ID, ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons';
import { ErrorType } from '@msfa-enums/error-type.enum'; import { ErrorType } from '@msfa-enums/error-type.enum';
import { Avrop } from '@msfa-models/avrop.model'; import { Avrop } from '@msfa-models/avrop.model';
import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; import { FranvaroRequestData_OLD } from '@msfa-models/avvikelse.model';
import { CustomError } from '@msfa-models/error/custom-error'; import { CustomError } from '@msfa-models/error/custom-error';
import { Franvaro } from '@msfa-models/franvaro.model'; import { Franvaro } from '@msfa-models/franvaro.model';
import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { dateToIsoString } from '@msfa-utils/format-to-date.util'; import { dateToIsoString } from '@msfa-utils/format-to-date.util';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators'; import { map, shareReplay, switchMap } from 'rxjs/operators';
import { FranvaroReportService } from './franvaro-report.service'; import { FranvaroReportFormService } from './franvaro-report-form.service';
import { FranvaroReportValidator } from './franvaro-report.validator'; import { FranvaroReportFormValidator } from './franvaro-report-form.validator';
@Component({ @Component({
selector: 'msfa-franvaro-report', selector: 'msfa-franvaro-report-form',
templateUrl: './franvaro-report.component.html', templateUrl: './franvaro-report-form.component.html',
styleUrls: ['./franvaro-report.component.scss'], styleUrls: ['./franvaro-report-form.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class FranvaroReportComponent { export class FranvaroReportFormComponent {
maxDate = new Date(); maxDate = new Date();
shouldValidate$ = new BehaviorSubject<boolean>(false); shouldValidate$ = new BehaviorSubject<boolean>(false);
confirmDialogOpen$ = new BehaviorSubject<boolean>(false); confirmDialogOpen$ = new BehaviorSubject<boolean>(false);
@@ -37,7 +37,7 @@ export class FranvaroReportComponent {
expectedPresenceStartTime: new FormControl(null), expectedPresenceStartTime: new FormControl(null),
expectedPresenceEndTime: new FormControl(null), expectedPresenceEndTime: new FormControl(null),
}, },
[FranvaroReportValidator.isFranvaroReportValid()] [FranvaroReportFormValidator.isFranvaroReportValid()]
); );
error$ = new BehaviorSubject<CustomError>(null); error$ = new BehaviorSubject<CustomError>(null);
@@ -47,18 +47,18 @@ export class FranvaroReportComponent {
map(params => params.genomforandeReferens as string) map(params => params.genomforandeReferens as string)
); );
avrop$: Observable<Avrop> = this.currentGenomforandeReferens$.pipe( avrop$: Observable<Avrop> = this.currentGenomforandeReferens$.pipe(
switchMap(genomforandeReferens => this.franvaroReportService.fetchAvropInformation$(+genomforandeReferens)), switchMap(genomforandeReferens => this.franvaroReportFormService.fetchAvropInformation$(+genomforandeReferens)),
shareReplay(1) shareReplay(1)
); );
reasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportService.reasons$; reasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportFormService.reasons$;
otherKnownReasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportService.otherKnownReasons$; otherKnownReasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportFormService.otherKnownReasons$;
wholeDayOrPartOfDayRadiobuttons: RadiobuttonModel[] = [ wholeDayOrPartOfDayRadiobuttons: RadiobuttonModel[] = [
{ label: 'Heldag', value: true }, { label: 'Heldag', value: true },
{ label: 'Del av dag', value: false }, { label: 'Del av dag', value: false },
]; ];
constructor(private franvaroReportService: FranvaroReportService, private activatedRoute: ActivatedRoute) { constructor(private franvaroReportFormService: FranvaroReportFormService, private activatedRoute: ActivatedRoute) {
this.dateFormControl.valueChanges.subscribe(value => console.log(value)); this.dateFormControl.valueChanges.subscribe(value => console.log(value));
} }
@@ -160,7 +160,7 @@ export class FranvaroReportComponent {
expectedPresenceEndTime, expectedPresenceEndTime,
} = this.franvaroFormGroup.value as Franvaro; } = this.franvaroFormGroup.value as Franvaro;
const postRequest: FranvaroRequestData = { const postRequest: FranvaroRequestData_OLD = {
genomforandeReferens, genomforandeReferens,
franvaro: { franvaro: {
avvikelseOrsaksKod: reason, avvikelseOrsaksKod: reason,
@@ -181,7 +181,7 @@ export class FranvaroReportComponent {
}, },
}; };
return this.franvaroReportService return this.franvaroReportFormService
.postFranvaroReport(postRequest) .postFranvaroReport(postRequest)
.then(() => { .then(() => {
this.lastSubmittedFranvaroReport$.next(new Date()); this.lastSubmittedFranvaroReport$.next(new Date());

View File

@@ -14,16 +14,16 @@ import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.modu
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module'; import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { FranvaroReportComponent } from './franvaro-report.component'; import { FranvaroReportFormComponent } from './franvaro-report-form.component';
import { FranvaroReportService } from './franvaro-report.service'; import { FranvaroReportFormService } from './franvaro-report-form.service';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [FranvaroReportComponent], declarations: [FranvaroReportFormComponent],
imports: [ imports: [
CommonModule, CommonModule,
RouterModule.forChild([{ path: '', component: FranvaroReportComponent }]), RouterModule.forChild([{ path: '', component: FranvaroReportFormComponent }]),
ReactiveFormsModule, ReactiveFormsModule,
LayoutModule, LayoutModule,
ReportLayoutModule, ReportLayoutModule,
@@ -39,7 +39,7 @@ import { FranvaroReportService } from './franvaro-report.service';
DigiNgFormValidationMessageModule, DigiNgFormValidationMessageModule,
DigiNgDialogModule, DigiNgDialogModule,
], ],
providers: [FranvaroReportService], providers: [FranvaroReportFormService],
exports: [FranvaroReportComponent], exports: [FranvaroReportFormComponent],
}) })
export class FranvaroReportModule {} export class FranvaroReportFormModule {}

View File

@@ -1,12 +1,12 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Avrop } from '@msfa-models/avrop.model'; import { Avrop } from '@msfa-models/avrop.model';
import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; import { FranvaroRequestData_OLD } from '@msfa-models/avvikelse.model';
import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { FranvaroReportApiService } from '@msfa-services/api/franvaro-report.api.service'; import { FranvaroReportApiService } from '@msfa-services/api/franvaro-report.api.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@Injectable() @Injectable()
export class FranvaroReportService { export class FranvaroReportFormService {
public reasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportApiService.fetchReasons$(); public reasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportApiService.fetchReasons$();
public otherKnownReasons$: Observable< public otherKnownReasons$: Observable<
OrsaksKoderFranvaro[] OrsaksKoderFranvaro[]
@@ -18,7 +18,7 @@ export class FranvaroReportService {
return this.franvaroReportApiService.fetchAvropInformation$(genomforandeReferens); return this.franvaroReportApiService.fetchAvropInformation$(genomforandeReferens);
} }
public async postFranvaroReport(requestData: FranvaroRequestData): Promise<void> { public async postFranvaroReport(requestData: FranvaroRequestData_OLD): Promise<void> {
return this.franvaroReportApiService.postFranvaroReport$(requestData); return this.franvaroReportApiService.postFranvaroReport$(requestData);
} }
} }

View File

@@ -9,7 +9,7 @@ function isTimeValid(value: string): boolean {
return TIME_REGEX.test(value); return TIME_REGEX.test(value);
} }
export class FranvaroReportValidator { export class FranvaroReportFormValidator {
static isFranvaroReportValid(): ValidatorFn { static isFranvaroReportValid(): ValidatorFn {
return (c: AbstractControl): { [key: string]: string } => { return (c: AbstractControl): { [key: string]: string } => {
let errors: { [key: string]: string } = null; let errors: { [key: string]: string } = null;

View File

@@ -1,11 +1,11 @@
<msfa-layout> <msfa-layout>
<msfa-report-layout <msfa-report-layout
*ngIf="avrop$ | async as avrop; else skeletonRef" *ngIf="avrop$ | async as avrop; else skeletonRef"
reportTitle="Gemensam planering" reportTitle="Skapa Gemensam planering"
[avrop]="avrop" [avrop]="avrop"
> >
<div class="gemensam-planering" *ngIf="currentGenomforandeReferens$ | async as genomforandeReferens"> <div class="gemensam-planering-form" *ngIf="currentGenomforandeReferens$ | async as genomforandeReferens">
<div class="gemensam-planering__warning" *ngIf="today < avrop.startDate; else reportRef"> <div class="gemensam-planering-form__warning" *ngIf="today < avrop.startDate; else reportRef">
<digi-notification-alert af-variation="warning" af-heading="Kan inte skapa Gemensam planering"> <digi-notification-alert af-variation="warning" af-heading="Kan inte skapa Gemensam planering">
<p>Det går inte att skicka Gemensam planering eftersom tjänsten inte har startat ännu.</p> <p>Det går inte att skicka Gemensam planering eftersom tjänsten inte har startat ännu.</p>
</digi-notification-alert> </digi-notification-alert>
@@ -13,9 +13,12 @@
<msfa-back-link route="../">Tillbaka till deltagaren</msfa-back-link> <msfa-back-link route="../">Tillbaka till deltagaren</msfa-back-link>
</div> </div>
<ng-template #reportRef> <ng-template #reportRef>
<div class="gemensam-planering__confirmation" *ngIf="lastSubmittedGP$ | async as lastSubmittedGP; else formRef"> <div
class="gemensam-planering-form__confirmation"
*ngIf="lastSubmittedGP$ | async as lastSubmittedGP; else formRef"
>
<digi-notification-alert <digi-notification-alert
class="gemensam-planering__alert" class="gemensam-planering-form__alert"
af-variation="success" af-variation="success"
af-heading="Allt gick bra" af-heading="Allt gick bra"
af-heading-level="h3" af-heading-level="h3"
@@ -33,15 +36,15 @@
</div> </div>
<ng-template #formRef> <ng-template #formRef>
<form <form
class="gemensam-planering__form" class="gemensam-planering-form__form"
[formGroup]="gpFormGroup" [formGroup]="gpFormGroup"
(ngSubmit)="openConfirmDialog()" (ngSubmit)="openConfirmDialog()"
id="gemensam-planering-form" id="gemensam-planering-form-form"
> >
<digi-form-fieldset <digi-form-fieldset
af-legend="Deltar arbetssökande på distans?" af-legend="Deltar arbetssökande på distans?"
af-name="distance" af-name="distance"
af-form="gemensam-planering-form" af-form="gemensam-planering-form-form"
> >
<digi-ng-form-radiobutton-group <digi-ng-form-radiobutton-group
[afRadiobuttons]="distanceRadiobuttons" [afRadiobuttons]="distanceRadiobuttons"
@@ -50,15 +53,15 @@
[afRadiobuttonGroupDirection]="RadiobuttonGroupDirection.HORIZONTAL" [afRadiobuttonGroupDirection]="RadiobuttonGroupDirection.HORIZONTAL"
></digi-ng-form-radiobutton-group> ></digi-ng-form-radiobutton-group>
</digi-form-fieldset> </digi-form-fieldset>
<digi-form-fieldset af-legend="Aktiviteter" af-name="aktivitetsIds" af-form="gemensam-planering-form"> <digi-form-fieldset af-legend="Aktiviteter" af-name="aktivitetsIds" af-form="gemensam-planering-form-form">
<p> <p>
Varje Gemensam planering måste innehålla de två obligatoriska aktiviteterna samt en frivillig aktivitet 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. som en del av det individuella stödet för varje deltagare.
</p> </p>
<ng-container *ngIf="activities$ | async as activities; else loadingRef"> <ng-container *ngIf="activities$ | async as activities; else loadingRef">
<ul class="gemensam-planering__activity-list"> <ul class="gemensam-planering-form__activity-list">
<li class="gemensam-planering__activity-item" *ngFor="let activity of activities;"> <li class="gemensam-planering-form__activity-item" *ngFor="let activity of activities;">
<digi-form-checkbox <digi-form-checkbox
[afLabel]="activity.name + (isActivityObligatory(activity.id) ? ' (obligatorisk)' : '')" [afLabel]="activity.name + (isActivityObligatory(activity.id) ? ' (obligatorisk)' : '')"
[afValue]="activity.id" [afValue]="activity.id"
@@ -74,17 +77,17 @@
</ng-container> </ng-container>
</digi-form-fieldset> </digi-form-fieldset>
<footer class="gemensam-planering__footer"> <footer class="gemensam-planering-form__footer">
<digi-notification-alert <digi-notification-alert
*ngIf="error$ | async as error" *ngIf="error$ | async as error"
class="gemensam-planering__alert" class="gemensam-planering-form__alert"
af-variation="danger" af-variation="danger"
af-heading="Någonting gick fel" af-heading="Någonting gick fel"
> >
<p>Kunde inte spara Gemensam planering. Ladda om sidan och försök igen.</p> <p>Kunde inte spara Gemensam planering. Ladda om sidan och försök igen.</p>
<p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p> <p class="msfa__small-text" *ngIf="error.message">{{error.message}}</p>
</digi-notification-alert> </digi-notification-alert>
<div class="gemensam-planering__cta-wrapper"> <div class="gemensam-planering-form__cta-wrapper">
<digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button> <digi-button af-type="submit" af-size="m">Förhandsgranska</digi-button>
<msfa-back-link [showIcon]="false" [asButton]="true" route="../"> <msfa-back-link [showIcon]="false" [asButton]="true" route="../">
<span>Avbryt</span> <span>Avbryt</span>
@@ -103,7 +106,7 @@
(afOnSecondaryClick)="cancelConfirmDialog()" (afOnSecondaryClick)="cancelConfirmDialog()"
afHeading="Vill du skicka in Gemensam planering" afHeading="Vill du skicka in Gemensam planering"
afAriaLabel="Förhandsgranska och skicka in Gemensam planering" afAriaLabel="Förhandsgranska och skicka in Gemensam planering"
id="confirm-gemensam-planering" id="confirm-gemensam-planering-form"
> >
<msfa-loader *ngIf="submitLoading$ | async" type="absolute"></msfa-loader> <msfa-loader *ngIf="submitLoading$ | async" type="absolute"></msfa-loader>
<dl> <dl>
@@ -131,13 +134,13 @@
<dd>{{gpFormGroup.value.distance ? 'Ja' : 'Nej'}}</dd> <dd>{{gpFormGroup.value.distance ? 'Ja' : 'Nej'}}</dd>
<dt>Aktiviteter</dt> <dt>Aktiviteter</dt>
<dd> <dd>
<ul class="gemensam-planering__activity-list" *ngFor="let activity of activities$ | async"> <ul class="gemensam-planering-form__activity-list" *ngFor="let activity of activities$ | async">
<li <li
class="gemensam-planering__activity-item" class="gemensam-planering-form__activity-item"
*ngIf="activityIdsFormArray.value.includes(activity.id)" *ngIf="activityIdsFormArray.value.includes(activity.id)"
> >
<digi-icon-check-circle <digi-icon-check-circle
class="msfa__digi-icon gemensam-planering__activity-check" class="msfa__digi-icon gemensam-planering-form__activity-check"
aria-hidden="true" aria-hidden="true"
></digi-icon-check-circle> ></digi-icon-check-circle>
{{activity.name}} {{activity.name}}
@@ -153,7 +156,10 @@
</msfa-layout> </msfa-layout>
<ng-template #skeletonRef> <ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar data för Gemensam planering"></digi-ng-skeleton-base> <digi-ng-skeleton-base
[afCount]="3"
afText="Laddar data för att kunna skapa Gemensam planering"
></digi-ng-skeleton-base>
</ng-template> </ng-template>
<ng-template #loadingRef> <ng-template #loadingRef>

View File

@@ -1,7 +1,7 @@
@import 'mixins/list'; @import 'mixins/list';
@import 'variables/gutters'; @import 'variables/gutters';
.gemensam-planering { .gemensam-planering-form {
max-width: var(--digi--typography--text--max-width); max-width: var(--digi--typography--text--max-width);
&__confirmation, &__confirmation,

View File

@@ -1,31 +1,33 @@
import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planering.component'; import { GemensamPlaneringFormComponent } from './gemensam-planering-form.component';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; import { GemensamPlaneringFormService } from './gemensam-planering-form.service';
import { DigiNgFormCheckboxModule } from '@af/digi-ng/_form/form-checkbox';
describe('DeltagareGemensamPlaneringComponent', () => { describe('GemensamPlaneringFormComponent', () => {
let component: DeltagareGemensamPlaneringComponent; let component: GemensamPlaneringFormComponent;
let fixture: ComponentFixture<DeltagareGemensamPlaneringComponent>; let fixture: ComponentFixture<GemensamPlaneringFormComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareGemensamPlaneringComponent, LayoutComponent], declarations: [GemensamPlaneringFormComponent, LayoutComponent],
imports: [ imports: [
RouterTestingModule, RouterTestingModule,
HttpClientTestingModule, HttpClientTestingModule,
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
DigiNgFormCheckboxModule, DigiNgFormCheckboxModule,
], ],
providers: [GemensamPlaneringFormService],
}).compileComponents(); }).compileComponents();
}); });
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(DeltagareGemensamPlaneringComponent); fixture = TestBed.createComponent(GemensamPlaneringFormComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -11,17 +11,17 @@ import {
mapGemensamPlaneringToGemensamPlaneringPostRequest, mapGemensamPlaneringToGemensamPlaneringPostRequest,
} from '@msfa-models/gemensam-planering.model'; } from '@msfa-models/gemensam-planering.model';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, map, shareReplay, switchMap } from 'rxjs/operators'; import { map, shareReplay, switchMap } from 'rxjs/operators';
import { GemensamPlaneringService } from './gemensam-planering.service'; import { GemensamPlaneringFormService } from './gemensam-planering-form.service';
import { GemensamPlaneringValidator } from './gemensam-planering.validator'; import { GemensamPlaneringValidator } from './gemensam-planering.validator';
@Component({ @Component({
selector: 'msfa-deltagare-gemensam-planering', selector: 'msfa-gemensam-planering-form',
templateUrl: './deltagare-gemensam-planering.component.html', templateUrl: './gemensam-planering-form.component.html',
styleUrls: ['./deltagare-gemensam-planering.component.scss'], styleUrls: ['./gemensam-planering-form.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class DeltagareGemensamPlaneringComponent { export class GemensamPlaneringFormComponent {
obligatoryActivityIds = [165, 188]; obligatoryActivityIds = [165, 188];
shouldValidate$ = new BehaviorSubject<boolean>(false); shouldValidate$ = new BehaviorSubject<boolean>(false);
RadiobuttonGroupDirection = RadiobuttonGroupDirection; RadiobuttonGroupDirection = RadiobuttonGroupDirection;
@@ -31,16 +31,12 @@ export class DeltagareGemensamPlaneringComponent {
lastSubmittedGP$ = new BehaviorSubject<Date>(null); lastSubmittedGP$ = new BehaviorSubject<Date>(null);
submitLoading$ = new BehaviorSubject<boolean>(false); submitLoading$ = new BehaviorSubject<boolean>(false);
activities$: Observable<Activity[]> = this.gemensamPlaneringService.activities$; activities$: Observable<Activity[]> = this.gemensamPlaneringFormService.activities$;
currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe( currentGenomforandeReferens$: Observable<string> = this.activatedRoute.params.pipe(
map(params => params.genomforandeReferens as string), map(params => params.genomforandeReferens as string)
distinctUntilChanged(
([prevGenomforandeReferens], [currGenomforandeReferens]) => prevGenomforandeReferens === currGenomforandeReferens
),
map(genomforandeReferens => +genomforandeReferens)
); );
avrop$: Observable<Avrop> = this.currentGenomforandeReferens$.pipe( avrop$: Observable<Avrop> = this.currentGenomforandeReferens$.pipe(
switchMap(genomforandeReferens => this.gemensamPlaneringService.fetchAvropInformation$(genomforandeReferens)), switchMap(genomforandeReferens => this.gemensamPlaneringFormService.fetchAvropInformation$(+genomforandeReferens)),
shareReplay(1) shareReplay(1)
); );
@@ -94,7 +90,10 @@ export class DeltagareGemensamPlaneringComponent {
return this.gpFormGroup.errors && this.gpFormGroup.errors[formControlName] && this.shouldValidate$.getValue(); return this.gpFormGroup.errors && this.gpFormGroup.errors[formControlName] && this.shouldValidate$.getValue();
} }
constructor(private gemensamPlaneringService: GemensamPlaneringService, private activatedRoute: ActivatedRoute) {} constructor(
private gemensamPlaneringFormService: GemensamPlaneringFormService,
private activatedRoute: ActivatedRoute
) {}
updateActivityIds(activityId: string, checked: boolean): void { updateActivityIds(activityId: string, checked: boolean): void {
if (checked) { if (checked) {
@@ -132,7 +131,7 @@ export class DeltagareGemensamPlaneringComponent {
genomforandeReferens, genomforandeReferens,
}; };
return this.gemensamPlaneringService return this.gemensamPlaneringFormService
.postGemensamPlanering(mapGemensamPlaneringToGemensamPlaneringPostRequest(postRequest)) .postGemensamPlanering(mapGemensamPlaneringToGemensamPlaneringPostRequest(postRequest))
.then(() => { .then(() => {
this.lastSubmittedGP$.next(new Date()); this.lastSubmittedGP$.next(new Date());

View File

@@ -11,15 +11,16 @@ import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.modu
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module'; import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { LoaderModule } from '@msfa-shared/components/loader/loader.module'; import { LoaderModule } from '@msfa-shared/components/loader/loader.module';
import { ReportLayoutModule } from '../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planering.component'; import { GemensamPlaneringFormComponent } from './gemensam-planering-form.component';
import { GemensamPlaneringFormService } from './gemensam-planering-form.service';
@NgModule({ @NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [DeltagareGemensamPlaneringComponent], declarations: [GemensamPlaneringFormComponent],
imports: [ imports: [
CommonModule, CommonModule,
RouterModule.forChild([{ path: '', component: DeltagareGemensamPlaneringComponent }]), RouterModule.forChild([{ path: '', component: GemensamPlaneringFormComponent }]),
LayoutModule, LayoutModule,
DigiNgProgressProgressbarModule, DigiNgProgressProgressbarModule,
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
@@ -32,6 +33,7 @@ import { DeltagareGemensamPlaneringComponent } from './deltagare-gemensam-planer
DigiNgFormCheckboxModule, DigiNgFormCheckboxModule,
DigiNgDialogModule, DigiNgDialogModule,
], ],
exports: [DeltagareGemensamPlaneringComponent], providers: [GemensamPlaneringFormService],
exports: [GemensamPlaneringFormComponent],
}) })
export class DeltagareGemensamPlaneringModule {} export class GemensamPlaneringFormModule {}

View File

@@ -5,10 +5,8 @@ import { Avrop } from '@msfa-models/avrop.model';
import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@Injectable({ @Injectable()
providedIn: 'root', export class GemensamPlaneringFormService {
})
export class GemensamPlaneringService {
public activities$: Observable<Activity[]> = this.gemensamPlaneringApiService.fetchActivities$(); public activities$: Observable<Activity[]> = this.gemensamPlaneringApiService.fetchActivities$();
constructor(private gemensamPlaneringApiService: GemensamPlaneringApiService) {} constructor(private gemensamPlaneringApiService: GemensamPlaneringApiService) {}

View File

@@ -0,0 +1,31 @@
<msfa-layout>
<msfa-report-layout
*ngIf="avrop$ | async as avrop; else skeletonRef"
reportTitle="Avvikelserapport (avvikelse)"
[avrop]="avrop"
>
<div class="avvikelse-report-view" *ngIf="avvikelseReport$ | async as report; else loadingRef">
<dl *ngIf="report.avvikelse as avvikelse">
<dt>Orsak till avvikelse:</dt>
<dd>{{avvikelse.reason}}</dd>
<ng-container *ngFor="let question of avvikelse.questions">
<dt>{{question.question}}</dt>
<dd>{{question.answer || 'Inget svar' }}</dd>
</ng-container>
<dt>Dag för avvikelse:</dt>
<dd><digi-typography-time [afDateTime]="avvikelse.date"></digi-typography-time></dd>
</dl>
<footer class="avvikelse-report-view__footer">
<msfa-back-link route="../../">Tillbaka till deltagaren</msfa-back-link>
</footer>
</div>
</msfa-report-layout>
</msfa-layout>
<ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar Avvikelserapport (avvikelse)"></digi-ng-skeleton-base>
</ng-template>
<ng-template #loadingRef>
<msfa-loader type="padded"></msfa-loader>
</ng-template>

View File

@@ -0,0 +1,31 @@
@import 'mixins/list';
@import 'variables/gutters';
.avvikelse-report-view {
max-width: var(--digi--typography--text--max-width);
display: flex;
flex-direction: column;
gap: $digi--layout--gutter--l;
&__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;
flex-direction: column;
gap: var(--digi--layout--gutter);
}
}

View File

@@ -0,0 +1,31 @@
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { AvvikelseReportViewComponent } from './avvikelse-report-view.component';
import { AvvikelseReportViewService } from './avvikelse-report-view.service';
describe('AvvikelseReportViewComponent', () => {
let component: AvvikelseReportViewComponent;
let fixture: ComponentFixture<AvvikelseReportViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [AvvikelseReportViewComponent, LayoutComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [AvvikelseReportViewService],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AvvikelseReportViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,37 @@
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 { AvvikelseReport } from '@msfa-models/avvikelse.model';
import { Observable } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators';
import { AvvikelseReportViewService } from './avvikelse-report-view.service';
@Component({
selector: 'msfa-avvikelse-report-view',
templateUrl: './avvikelse-report-view.component.html',
styleUrls: ['./avvikelse-report-view.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AvvikelseReportViewComponent {
params$: Observable<Params> = this.activatedRoute.params.pipe(
map(params => ({
reportId: params.reportId as string,
genomforandeReferens: params.genomforandeReferens as string,
}))
);
avrop$: Observable<Avrop> = this.params$.pipe(
switchMap(({ genomforandeReferens }) =>
this.avvikelseReportViewService.fetchAvropInformation$(+genomforandeReferens)
),
shareReplay(1)
);
avvikelseReport$: Observable<AvvikelseReport> = this.params$.pipe(
switchMap(({ genomforandeReferens, reportId }) =>
this.avvikelseReportViewService.fetchAvvikelseReport$(+genomforandeReferens, reportId as string)
),
shareReplay(1)
);
constructor(private avvikelseReportViewService: AvvikelseReportViewService, private activatedRoute: ActivatedRoute) {}
}

View File

@@ -0,0 +1,29 @@
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 { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.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 { AvvikelseReportViewComponent } from './avvikelse-report-view.component';
import { AvvikelseReportViewService } from './avvikelse-report-view.service';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [AvvikelseReportViewComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: AvvikelseReportViewComponent }]),
LayoutModule,
ReportLayoutModule,
BackLinkModule,
LoaderModule,
HideTextModule,
DigiNgSkeletonBaseModule,
],
providers: [AvvikelseReportViewService],
exports: [AvvikelseReportViewComponent],
})
export class AvvikelseReportViewModule {}

View File

@@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import { Avrop } from '@msfa-models/avrop.model';
import { AvvikelseReport } from '@msfa-models/avvikelse.model';
import { ReportApiService } from '@msfa-services/api/report.api.service';
import { Observable } from 'rxjs';
@Injectable()
export class AvvikelseReportViewService {
constructor(private reportApiService: ReportApiService) {}
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
return this.reportApiService.fetchAvropInformation$(genomforandeReferens);
}
public fetchAvvikelseReport$(genomforandeReferens: number, reportId: string): Observable<AvvikelseReport> {
return this.reportApiService.fetchAvvikelseReport$(genomforandeReferens, reportId);
}
}

View File

@@ -0,0 +1,47 @@
<msfa-layout>
<msfa-report-layout
*ngIf="avrop$ | async as avrop; else skeletonRef"
reportTitle="Avvikelserapport (frånvaro)"
[avrop]="avrop"
>
<div class="franvaro-report-view" *ngIf="franvaroReport$ | async as report; else loadingRef">
<dl>
<ng-container *ngIf="report.franvaro as franvaro">
<dt>Orsak till frånvaro</dt>
<dd>{{franvaro.reason}}</dd>
<ng-container *ngIf="franvaro.otherKnownReason">
<dt>Annan känd orsak</dt>
<dd>{{franvaro.otherKnownReason}}</dd>
</ng-container>
<ng-container *ngIf="franvaro.knownReasonComment">
<dt>Beskrivning för frånvaro</dt>
<dd>{{franvaro.knownReasonComment}}</dd>
</ng-container>
<dt>Dag för frånvaro</dt>
<dd>
<digi-typography-time [afDateTime]="franvaro.date"></digi-typography-time>
</dd>
<dt>Heldag eller del av dag</dt>
<dd>{{franvaro.wholeDay ? 'Heldag' : 'Del av dag'}}</dd>
<ng-container *ngIf="!franvaro.wholeDay">
<dt>Tid för frånvaro</dt>
<dd>{{franvaro.startTime}} - {{franvaro.endTime}}</dd>
</ng-container>
<dt>Tid för förväntad närvaro</dt>
<dd>{{franvaro.expectedPresenceStartTime}} - {{franvaro.expectedPresenceEndTime}}</dd>
</ng-container>
</dl>
<footer class="franvaro-report-view__footer">
<msfa-back-link route="../../">Tillbaka till deltagaren</msfa-back-link>
</footer>
</div>
</msfa-report-layout>
</msfa-layout>
<ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar Avvikelserapport (frånvaro)"></digi-ng-skeleton-base>
</ng-template>
<ng-template #loadingRef>
<msfa-loader type="padded"></msfa-loader>
</ng-template>

View File

@@ -0,0 +1,31 @@
@import 'mixins/list';
@import 'variables/gutters';
.franvaro-report-view {
max-width: var(--digi--typography--text--max-width);
display: flex;
flex-direction: column;
gap: $digi--layout--gutter--l;
&__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;
flex-direction: column;
gap: var(--digi--layout--gutter);
}
}

View File

@@ -0,0 +1,31 @@
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { FranvaroReportViewComponent } from './franvaro-report-view.component';
import { FranvaroReportViewService } from './franvaro-report-view.service';
describe('FranvaroReportViewComponent', () => {
let component: FranvaroReportViewComponent;
let fixture: ComponentFixture<FranvaroReportViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [FranvaroReportViewComponent, LayoutComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [FranvaroReportViewService],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FranvaroReportViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,37 @@
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 { FranvaroReport } from '@msfa-models/franvaro.model';
import { Observable } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators';
import { FranvaroReportViewService } from './franvaro-report-view.service';
@Component({
selector: 'msfa-franvaro-report-view',
templateUrl: './franvaro-report-view.component.html',
styleUrls: ['./franvaro-report-view.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FranvaroReportViewComponent {
params$: Observable<Params> = this.activatedRoute.params.pipe(
map(params => ({
reportId: params.reportId as string,
genomforandeReferens: params.genomforandeReferens as string,
}))
);
avrop$: Observable<Avrop> = this.params$.pipe(
switchMap(({ genomforandeReferens }) =>
this.franvaroReportViewService.fetchAvropInformation$(+genomforandeReferens)
),
shareReplay(1)
);
franvaroReport$: Observable<FranvaroReport> = this.params$.pipe(
switchMap(({ genomforandeReferens, reportId }) =>
this.franvaroReportViewService.fetchFranvaroReport$(+genomforandeReferens, reportId as string)
),
shareReplay(1)
);
constructor(private franvaroReportViewService: FranvaroReportViewService, private activatedRoute: ActivatedRoute) {}
}

View File

@@ -0,0 +1,29 @@
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 { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.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 { FranvaroReportViewComponent } from './franvaro-report-view.component';
import { FranvaroReportViewService } from './franvaro-report-view.service';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [FranvaroReportViewComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: FranvaroReportViewComponent }]),
LayoutModule,
ReportLayoutModule,
BackLinkModule,
LoaderModule,
HideTextModule,
DigiNgSkeletonBaseModule,
],
providers: [FranvaroReportViewService],
exports: [FranvaroReportViewComponent],
})
export class FranvaroReportViewModule {}

View File

@@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import { Avrop } from '@msfa-models/avrop.model';
import { FranvaroReport } from '@msfa-models/franvaro.model';
import { ReportApiService } from '@msfa-services/api/report.api.service';
import { Observable } from 'rxjs';
@Injectable()
export class FranvaroReportViewService {
constructor(private reportApiService: ReportApiService) {}
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
return this.reportApiService.fetchAvropInformation$(genomforandeReferens);
}
public fetchFranvaroReport$(genomforandeReferens: number, reportId: string): Observable<FranvaroReport> {
return this.reportApiService.fetchFranvaroReport$(genomforandeReferens, reportId);
}
}

View File

@@ -0,0 +1,37 @@
<msfa-layout>
<msfa-report-layout
*ngIf="avrop$ | async as avrop; else skeletonRef"
reportTitle="Gemensam planering"
[avrop]="avrop"
>
<div class="gemensam-planering-view" *ngIf="gemensamPlanering$ | async as report; else loadingRef">
<dl>
<dt>Deltar arbetssökande på distans?</dt>
<dd>{{report.distance ? 'Ja' : 'Nej'}}</dd>
<dt>Aktiviteter</dt>
<dd>
<ul class="gemensam-planering-view__activity-list">
<li class="gemensam-planering-view__activity-item" *ngFor="let activity of report.activities">
<digi-icon-check-circle
class="msfa__digi-icon gemensam-planering-view__activity-check"
aria-hidden="true"
></digi-icon-check-circle>
{{activity}}
</li>
</ul>
</dd>
</dl>
<footer class="gemensam-planering-view__footer">
<msfa-back-link route="../../">Tillbaka till deltagaren</msfa-back-link>
</footer>
</div>
</msfa-report-layout>
</msfa-layout>
<ng-template #skeletonRef>
<digi-ng-skeleton-base [afCount]="3" afText="Laddar Gemensam planering"></digi-ng-skeleton-base>
</ng-template>
<ng-template #loadingRef>
<msfa-loader type="padded"></msfa-loader>
</ng-template>

View File

@@ -0,0 +1,31 @@
@import 'mixins/list';
@import 'variables/gutters';
.gemensam-planering-view {
max-width: var(--digi--typography--text--max-width);
display: flex;
flex-direction: column;
gap: $digi--layout--gutter--l;
&__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;
flex-direction: column;
gap: var(--digi--layout--gutter);
}
}

View File

@@ -0,0 +1,31 @@
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LayoutComponent } from '@msfa-shared/components/layout/layout.component';
import { GemensamPlaneringViewComponent } from './gemensam-planering-view.component';
import { GemensamPlaneringViewService } from './gemensam-planering-view.service';
describe('GemensamPlaneringViewComponent', () => {
let component: GemensamPlaneringViewComponent;
let fixture: ComponentFixture<GemensamPlaneringViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [GemensamPlaneringViewComponent, LayoutComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [GemensamPlaneringViewService],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(GemensamPlaneringViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,40 @@
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 { GemensamPlaneringDetailed } from '@msfa-models/gemensam-planering.model';
import { Observable } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators';
import { GemensamPlaneringViewService } from './gemensam-planering-view.service';
@Component({
selector: 'msfa-gemensam-planering-view',
templateUrl: './gemensam-planering-view.component.html',
styleUrls: ['./gemensam-planering-view.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GemensamPlaneringViewComponent {
params$: Observable<Params> = this.activatedRoute.params.pipe(
map(params => ({
reportId: params.reportId as string,
genomforandeReferens: params.genomforandeReferens as string,
}))
);
avrop$: Observable<Avrop> = this.params$.pipe(
switchMap(({ genomforandeReferens }) =>
this.gemensamPlaneringViewService.fetchAvropInformation$(+genomforandeReferens)
),
shareReplay(1)
);
gemensamPlanering$: Observable<GemensamPlaneringDetailed> = this.params$.pipe(
switchMap(({ genomforandeReferens, reportId }) =>
this.gemensamPlaneringViewService.fetchGemensamPlanering$(+genomforandeReferens, reportId as string)
),
shareReplay(1)
);
constructor(
private gemensamPlaneringViewService: GemensamPlaneringViewService,
private activatedRoute: ActivatedRoute
) {}
}

View File

@@ -0,0 +1,29 @@
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 { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.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 { GemensamPlaneringViewComponent } from './gemensam-planering-view.component';
import { GemensamPlaneringViewService } from './gemensam-planering-view.service';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [GemensamPlaneringViewComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: GemensamPlaneringViewComponent }]),
LayoutModule,
ReportLayoutModule,
BackLinkModule,
LoaderModule,
HideTextModule,
DigiNgSkeletonBaseModule,
],
providers: [GemensamPlaneringViewService],
exports: [GemensamPlaneringViewComponent],
})
export class GemensamPlaneringViewModule {}

View File

@@ -0,0 +1,21 @@
import { Injectable } from '@angular/core';
import { Avrop } from '@msfa-models/avrop.model';
import { GemensamPlaneringDetailed } from '@msfa-models/gemensam-planering.model';
import { ReportApiService } from '@msfa-services/api/report.api.service';
import { Observable } from 'rxjs';
@Injectable()
export class GemensamPlaneringViewService {
constructor(private reportApiService: ReportApiService) {}
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
return this.reportApiService.fetchAvropInformation$(genomforandeReferens);
}
public fetchGemensamPlanering$(
genomforandeReferens: number,
reportId: string
): Observable<GemensamPlaneringDetailed> {
return this.reportApiService.fetchGemensamPlanering$(genomforandeReferens, reportId);
}
}

View File

@@ -0,0 +1,15 @@
export interface AvvikelseQuestionResponse {
fraga: string;
svar: string;
}
export interface AvvikelseResponse {
avvikelseOrsakskod: string;
frageformular: AvvikelseQuestionResponse[];
rapporteringsdatum: string;
}
export interface AvvikelseReportResponse {
genomforandeReferens: number;
avvikelseAlternativ: AvvikelseResponse;
}

View File

@@ -0,0 +1,20 @@
export interface FranvaroResponse {
avvikelseOrsaksKod: string;
datum: string;
heldag: boolean;
startTid: string;
slutTid: string;
alternativForKandaOrsaker: {
typ: string;
motivering: string;
} | null;
forvantadNarvaro: {
startTid: string;
slutTid: string;
};
}
export interface FranvaroReportResponse {
genomforandeReferens: number;
franvaro: FranvaroResponse;
}

View File

@@ -0,0 +1,5 @@
export interface GemensamPlaneringResponse {
genomforandeReferens: string;
distans: boolean;
aktivitetsIds: number[];
}

View File

@@ -1,29 +1,64 @@
import { FranvaroAlternativ } from './franvaro-alternativ.model';
import { Fraga } from '@msfa-models/fraga.model'; import { Fraga } from '@msfa-models/fraga.model';
import { AvvikelseResponse } from './api/avvikelse-response.model';
import { FragorForAvvikelser } from './fragor-for-avvikelser.model';
import { FranvaroAlternativ } from './franvaro-alternativ.model';
import { OrsaksKoderAvvikelse } from './orsaks-koder-avvikelse.model';
export interface AvvikelseAlternativ { export interface AvvikelseQuestion {
question: string;
answer: string;
}
export interface Avvikelse {
reason: string;
questions: AvvikelseQuestion[];
date: Date;
}
export interface AvvikelseReport {
genomforandeReferens: number;
avvikelse: Avvikelse;
}
export interface AvvikelseAlternativ_OLD {
avvikelseorsakskod: string; avvikelseorsakskod: string;
frageformular: Fraga[]; frageformular: Fraga[];
rapporteringsdatum: string; rapporteringsdatum: string;
} }
export interface Avvikelse { export interface Avvikelse_OLD {
genomforandeReferens: number; genomforandeReferens: number;
avvikelseAlternativ?: AvvikelseAlternativ; avvikelseAlternativ?: AvvikelseAlternativ_OLD;
franvaro?: FranvaroAlternativ;
} }
export interface AvvikelseRequestData { export interface AvvikelseRequestData_OLD {
genomforandeReferens: number; genomforandeReferens: number;
avvikelseAlternativ: AvvikelseAlternativ; avvikelseAlternativ: AvvikelseAlternativ_OLD;
} }
export interface FranvaroRequestData { export interface FranvaroRequestData_OLD {
genomforandeReferens: number; genomforandeReferens: number;
franvaro: FranvaroAlternativ; franvaro: FranvaroAlternativ;
} }
export function mapAvvikelseRequestDataToAvvikelse(data: AvvikelseRequestData): Avvikelse { export function mapResponseToAvvikelse(
data: AvvikelseResponse,
reasons: OrsaksKoderAvvikelse[],
questions: FragorForAvvikelser[]
): Avvikelse {
const { avvikelseOrsakskod, rapporteringsdatum, frageformular } = data;
return {
reason: reasons.find(reason => reason.id === avvikelseOrsakskod).name,
questions: frageformular.map(fraga => ({
question: questions.find(question => question.id === fraga.fraga).name,
answer: fraga.svar,
})),
date: new Date(rapporteringsdatum),
};
}
export function mapAvvikelseRequestDataToAvvikelse_OLD(data: AvvikelseRequestData_OLD): Avvikelse_OLD {
return data; return data;
// const { genomforandeReferens, avvikelseAlternativ } = data; // const { genomforandeReferens, avvikelseAlternativ } = data;
// //

View File

@@ -1,3 +1,6 @@
import { FranvaroResponse } from './api/franvaro-response.model';
import { OrsaksKoderFranvaro } from './orsaks-koder-franvaro.model';
export interface Franvaro { export interface Franvaro {
reason: string; reason: string;
date: Date; date: Date;
@@ -9,3 +12,30 @@ export interface Franvaro {
otherKnownReason: string; otherKnownReason: string;
knownReasonComment: string; knownReasonComment: string;
} }
export interface FranvaroReport {
genomforandeReferens: number;
franvaro: Franvaro;
}
export function mapResponseToFranvaro(
data: FranvaroResponse,
reasons: OrsaksKoderFranvaro[],
otherKnownReasons: OrsaksKoderFranvaro[]
): Franvaro {
const { avvikelseOrsaksKod, datum, heldag, startTid, slutTid, alternativForKandaOrsaker, forvantadNarvaro } = data;
return {
reason: reasons.find(reason => reason.value.toString() === avvikelseOrsaksKod).name,
date: new Date(datum),
wholeDay: heldag,
startTime: startTid,
endTime: slutTid,
otherKnownReason: alternativForKandaOrsaker
? otherKnownReasons.find(reason => reason.value.toString() === alternativForKandaOrsaker.typ).name
: null,
knownReasonComment: alternativForKandaOrsaker?.motivering || null,
expectedPresenceStartTime: forvantadNarvaro.startTid,
expectedPresenceEndTime: forvantadNarvaro.slutTid,
};
}

View File

@@ -1,4 +1,6 @@
import { Activity } from './activity.model';
import { GemensamPlaneringPostRequest } from './api/gemensam-planering.request.model'; import { GemensamPlaneringPostRequest } from './api/gemensam-planering.request.model';
import { GemensamPlaneringResponse } from './api/gemensam-planering.response.model';
export interface GemensamPlanering { export interface GemensamPlanering {
genomforandeReferens: number; genomforandeReferens: number;
@@ -6,6 +8,12 @@ export interface GemensamPlanering {
activityIds: number[]; activityIds: number[];
} }
export interface GemensamPlaneringDetailed {
genomforandeReferens: number;
distance: boolean;
activities: string[];
}
export function mapGemensamPlaneringToGemensamPlaneringPostRequest( export function mapGemensamPlaneringToGemensamPlaneringPostRequest(
gemensamPlanering: GemensamPlanering gemensamPlanering: GemensamPlanering
): GemensamPlaneringPostRequest { ): GemensamPlaneringPostRequest {
@@ -17,3 +25,16 @@ export function mapGemensamPlaneringToGemensamPlaneringPostRequest(
aktivitetsIds: activityIds, aktivitetsIds: activityIds,
}; };
} }
export function mapResponseToGemensamPlaneringDetailed(
data: GemensamPlaneringResponse,
activities: Activity[]
): GemensamPlaneringDetailed {
const { genomforandeReferens, distans, aktivitetsIds } = data;
return {
genomforandeReferens: +genomforandeReferens,
distance: distans,
activities: aktivitetsIds.map(id => activities.find(activity => activity.id === id).name),
};
}

View File

@@ -1,5 +1,6 @@
import { ReportType } from '@msfa-enums/report-type.enum'; import { ReportType } from '@msfa-enums/report-type.enum';
import { ReportResponse } from './api/report.response.model'; import { ReportResponse } from './api/report.response.model';
import { Franvaro } from './franvaro.model';
import { PaginationMeta } from './pagination-meta.model'; import { PaginationMeta } from './pagination-meta.model';
export interface Report { export interface Report {
@@ -11,6 +12,11 @@ export interface Report {
ciamUserId: string; ciamUserId: string;
} }
export interface ReportDetail {
genomforandeReferens: string;
franvaro?: Franvaro;
}
export interface ReportsData { export interface ReportsData {
data: Report[]; data: Report[];
meta: PaginationMeta; meta: PaginationMeta;

View File

@@ -1,10 +1,12 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ErrorType } from '@msfa-enums/error-type.enum';
import { environment } from '@msfa-environment'; import { environment } from '@msfa-environment';
import { FragorForAvvikelserResponse } from '@msfa-models/api/fragor-for-avvikelser.response'; import { FragorForAvvikelserResponse } from '@msfa-models/api/fragor-for-avvikelser.response';
import { KandaAvvikelseKoderResponse } from '@msfa-models/api/kanda-avvikelse-koder.response.model'; import { KandaAvvikelseKoderResponse } from '@msfa-models/api/kanda-avvikelse-koder.response.model';
import { OrsaksKoderAvvikelseResponse } from '@msfa-models/api/orsaks-koder-avvikelse.response.model'; import { OrsaksKoderAvvikelseResponse } from '@msfa-models/api/orsaks-koder-avvikelse.response.model';
import { Avvikelse } from '@msfa-models/avvikelse.model'; import { Avvikelse_OLD } from '@msfa-models/avvikelse.model';
import { CustomError } from '@msfa-models/error/custom-error';
import { FragorForAvvikelser, mapResponseToFragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model'; import { FragorForAvvikelser, mapResponseToFragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model';
import { mapResponseToOrsaksKoderAvvikelse, OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model'; import { mapResponseToOrsaksKoderAvvikelse, OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model';
import { import {
@@ -15,8 +17,6 @@ import {
} from '@msfa-models/orsaks-koder-franvaro.model'; } from '@msfa-models/orsaks-koder-franvaro.model';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators'; import { catchError, filter, map } from 'rxjs/operators';
import { CustomError } from '@msfa-models/error/custom-error';
import { ErrorType } from '@msfa-enums/error-type.enum';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@@ -58,7 +58,7 @@ export class AvvikelseApiService {
); );
} }
public createAvvikelse$(avvikelse: Avvikelse): Observable<unknown> { public createAvvikelse$(avvikelse: Avvikelse_OLD): Observable<unknown> {
return this.httpClient.post<void>(`${this._apiBaseUrl}/avvikelse`, avvikelse).pipe( return this.httpClient.post<void>(`${this._apiBaseUrl}/avvikelse`, avvikelse).pipe(
catchError((error: Error) => { catchError((error: Error) => {
throw new CustomError({ throw new CustomError({
@@ -70,7 +70,7 @@ export class AvvikelseApiService {
); );
} }
public createFranvaro$(avvikelse: Avvikelse): Promise<void> { public createFranvaro$(avvikelse: Avvikelse_OLD): Promise<void> {
return this.httpClient.post<void>(`${this._apiBaseUrl}/franvaro`, avvikelse).toPromise(); return this.httpClient.post<void>(`${this._apiBaseUrl}/franvaro`, avvikelse).toPromise();
} }
} }

View File

@@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { environment } from '@msfa-environment'; import { environment } from '@msfa-environment';
import { OrsaksKoderFranvaroResponse } from '@msfa-models/api/orsaks-koder-franvaro.response.model'; import { OrsaksKoderFranvaroResponse } from '@msfa-models/api/orsaks-koder-franvaro.response.model';
import { Avrop } from '@msfa-models/avrop.model'; import { Avrop } from '@msfa-models/avrop.model';
import { FranvaroRequestData } from '@msfa-models/avvikelse.model'; import { FranvaroRequestData_OLD } from '@msfa-models/avvikelse.model';
import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error';
import { mapResponseToOrsaksKoderFranvaro, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model'; import { mapResponseToOrsaksKoderFranvaro, OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
@@ -47,7 +47,7 @@ export class FranvaroReportApiService {
return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens);
} }
public async postFranvaroReport$(requestData: FranvaroRequestData): Promise<void> { public async postFranvaroReport$(requestData: FranvaroRequestData_OLD): Promise<void> {
return this.httpClient.post<void>(`${this._apiBaseUrl}/franvaro`, requestData).toPromise(); return this.httpClient.post<void>(`${this._apiBaseUrl}/franvaro`, requestData).toPromise();
} }
} }

View File

@@ -4,17 +4,24 @@ import { environment } from '@msfa-environment';
import { Activity, mapResponseToActivity } from '@msfa-models/activity.model'; import { Activity, mapResponseToActivity } from '@msfa-models/activity.model';
import { ActivityResponse } from '@msfa-models/api/activity.response.model'; import { ActivityResponse } from '@msfa-models/api/activity.response.model';
import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model'; import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model';
import { GemensamPlaneringResponse } from '@msfa-models/api/gemensam-planering.response.model';
import { Params } from '@msfa-models/api/params.model';
import { Avrop } from '@msfa-models/avrop.model'; import { Avrop } from '@msfa-models/avrop.model';
import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error';
import {
GemensamPlaneringDetailed,
mapResponseToGemensamPlaneringDetailed,
} from '@msfa-models/gemensam-planering.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { catchError, filter, map, shareReplay } from 'rxjs/operators'; import { catchError, filter, map, shareReplay, switchMap } from 'rxjs/operators';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class GemensamPlaneringApiService { export class GemensamPlaneringApiService {
private _apiBaseUrl = `${environment.api.url}/rapporter/gemensam-planering`; private _apiBaseUrl = `${environment.api.url}/rapporter/gemensam-planering`;
private _apiHandlingarUrl = `${environment.api.url}/handlingar`;
public fetchActivities$(): Observable<Activity[]> { public fetchActivities$(): Observable<Activity[]> {
return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/aktiviteter`).pipe( return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/aktiviteter`).pipe(
@@ -33,6 +40,19 @@ export class GemensamPlaneringApiService {
return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens);
} }
public fetchReport$(genomforandeReferens: number, reportId: string): Observable<GemensamPlaneringDetailed> {
const params: Params = {
genomforandereferens: genomforandeReferens.toString(),
};
return this.fetchActivities$().pipe(
switchMap(activities =>
this.httpClient
.get<{ data: GemensamPlaneringResponse }>(`${this._apiHandlingarUrl}/${reportId}`, { params })
.pipe(map(({ data }) => mapResponseToGemensamPlaneringDetailed(data, activities)))
)
);
}
public async postGemensamPlanering$(requestData: GemensamPlaneringPostRequest): Promise<void> { public async postGemensamPlanering$(requestData: GemensamPlaneringPostRequest): Promise<void> {
return this.httpClient.post<void>(`${this._apiBaseUrl}`, requestData).toPromise(); return this.httpClient.post<void>(`${this._apiBaseUrl}`, requestData).toPromise();
} }

View File

@@ -0,0 +1,107 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '@msfa-environment';
import { Activity } from '@msfa-models/activity.model';
import { AvvikelseReportResponse } from '@msfa-models/api/avvikelse-response.model';
import { FranvaroReportResponse } from '@msfa-models/api/franvaro-response.model';
import { GemensamPlaneringResponse } from '@msfa-models/api/gemensam-planering.response.model';
import { Params } from '@msfa-models/api/params.model';
import { Avrop } from '@msfa-models/avrop.model';
import { AvvikelseReport, mapResponseToAvvikelse } from '@msfa-models/avvikelse.model';
import { FragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model';
import { FranvaroReport, mapResponseToFranvaro } from '@msfa-models/franvaro.model';
import {
GemensamPlaneringDetailed,
mapResponseToGemensamPlaneringDetailed,
} from '@msfa-models/gemensam-planering.model';
import { OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model';
import { OrsaksKoderFranvaro } from '@msfa-models/orsaks-koder-franvaro.model';
import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service';
import { combineLatest, Observable } from 'rxjs';
import { filter, map, switchMap } from 'rxjs/operators';
import { AvvikelseApiService } from './avvikelse-api.service';
import { FranvaroReportApiService } from './franvaro-report.api.service';
import { GemensamPlaneringApiService } from './gemensam-planering-api.service';
@Injectable({
providedIn: 'root',
})
export class ReportApiService {
private _apiBaseUrl = `${environment.api.url}/handlingar`;
private _avvikelseReasons$: Observable<OrsaksKoderAvvikelse[]> = this.avvikelseApiService.getOrsaksKoderAvvikelse$();
private _avvikelseQuestions$: Observable<FragorForAvvikelser[]> = this.avvikelseApiService.getFragorForAvvikelser$();
private _activities$: Observable<Activity[]> = this.gemensamPlaneringApiService.fetchActivities$();
private _franvaroReasons$: Observable<OrsaksKoderFranvaro[]> = this.franvaroReportApiService.fetchReasons$();
private _otherFranvaroReasons$: Observable<
OrsaksKoderFranvaro[]
> = this.franvaroReportApiService.fetchOtherKnownReasons$();
constructor(
private httpClient: HttpClient,
private deltagareApiService: DeltagareApiService,
private gemensamPlaneringApiService: GemensamPlaneringApiService,
private franvaroReportApiService: FranvaroReportApiService,
private avvikelseApiService: AvvikelseApiService
) {}
public fetchAvropInformation$(genomforandeReferens: number): Observable<Avrop> {
return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens);
}
public fetchGemensamPlanering$(
genomforandeReferens: number,
reportId: string
): Observable<GemensamPlaneringDetailed> {
const params: Params = {
genomforandereferens: genomforandeReferens.toString(),
};
return this._activities$.pipe(
switchMap(activities =>
this.httpClient
.get<{ data: GemensamPlaneringResponse }>(`${this._apiBaseUrl}/${reportId}`, { params })
.pipe(map(({ data }) => mapResponseToGemensamPlaneringDetailed(data, activities)))
)
);
}
public fetchFranvaroReport$(genomforandeReferens: number, reportId: string): Observable<FranvaroReport> {
const params: Params = {
genomforandereferens: genomforandeReferens.toString(),
};
return combineLatest([this._franvaroReasons$, this._otherFranvaroReasons$]).pipe(
filter(([reasons, otherReasons]) => !!(reasons && otherReasons)),
switchMap(([reasons, otherReasons]) => {
return this.httpClient
.get<{ data: FranvaroReportResponse }>(`${this._apiBaseUrl}/${reportId}`, { params })
.pipe(
map(({ data }) => ({
genomforandeReferens: data.genomforandeReferens,
franvaro: mapResponseToFranvaro(data.franvaro, reasons, otherReasons),
}))
);
})
);
}
public fetchAvvikelseReport$(genomforandeReferens: number, reportId: string): Observable<AvvikelseReport> {
const params: Params = {
genomforandereferens: genomforandeReferens.toString(),
};
return combineLatest([this._avvikelseReasons$, this._avvikelseQuestions$]).pipe(
filter(([reasons, questions]) => !!(reasons && questions)),
switchMap(([reasons, questions]) => {
return this.httpClient
.get<{ data: AvvikelseReportResponse }>(`${this._apiBaseUrl}/${reportId}`, { params })
.pipe(
map(({ data }) => ({
genomforandeReferens: data.genomforandeReferens,
avvikelse: mapResponseToAvvikelse(data.avvikelseAlternativ, reasons, questions),
}))
);
})
);
}
}

View File

@@ -6,7 +6,7 @@ export function mapPathsToBreadcrumbs(
paths: string[], paths: string[],
startBreadcrumb?: NavigationBreadcrumbsItem startBreadcrumb?: NavigationBreadcrumbsItem
): NavigationBreadcrumbsItem[] { ): NavigationBreadcrumbsItem[] {
const breadcrumbs = [ let breadcrumbs = [
...(startBreadcrumb ? [startBreadcrumb] : []), ...(startBreadcrumb ? [startBreadcrumb] : []),
...paths.map((path, index) => ({ ...paths.map((path, index) => ({
text: mapPathToPageName(path), text: mapPathToPageName(path),
@@ -24,7 +24,11 @@ export function mapPathsToBreadcrumbs(
breadcrumbs[breadcrumbs.length - 1].text = 'Redigera personalkonto'; breadcrumbs[breadcrumbs.length - 1].text = 'Redigera personalkonto';
} else if (isDeltagareCardRoute(paths)) { } else if (isDeltagareCardRoute(paths)) {
breadcrumbs[breadcrumbs.length - 1].text = 'Deltagarinformation'; breadcrumbs[breadcrumbs.length - 1].text = 'Deltagarinformation';
} else if (isDeltagareReportingFormRoute(paths)) {
breadcrumbs[breadcrumbs.length - 2].text = 'Deltagarinformation';
breadcrumbs[breadcrumbs.length - 1].text = `Skapa ${DELTAGARE_REPORTING_ROUTES[paths[paths.length - 1]] as string}`;
} else if (isDeltagareReportingRoute(paths)) { } else if (isDeltagareReportingRoute(paths)) {
breadcrumbs = breadcrumbs.slice(0, -1);
breadcrumbs[breadcrumbs.length - 2].text = 'Deltagarinformation'; breadcrumbs[breadcrumbs.length - 2].text = 'Deltagarinformation';
} }
@@ -43,6 +47,10 @@ function isDeltagareCardRoute(paths: string[]): boolean {
return paths.length === 2 && paths[0] === 'deltagare'; return paths.length === 2 && paths[0] === 'deltagare';
} }
function isDeltagareReportingRoute(paths: string[]): boolean { function isDeltagareReportingFormRoute(paths: string[]): boolean {
return paths.length === 3 && paths[0] === 'deltagare' && paths[2] in DELTAGARE_REPORTING_ROUTES; return paths.length === 3 && paths[0] === 'deltagare' && paths[2] in DELTAGARE_REPORTING_ROUTES;
} }
function isDeltagareReportingRoute(paths: string[]): boolean {
return paths.length === 4 && paths[0] === 'deltagare' && paths[2] in DELTAGARE_REPORTING_ROUTES;
}

View File

@@ -152,21 +152,21 @@ pipeline {
} }
// Temporary while data in sys is so bad // Temporary while data in sys is so bad
stage('Deploy to "test"') { // stage('Deploy to "test"') {
steps { // steps {
echo '### Deploying to "test"... ###' // echo '### Deploying to "test"... ###'
script { // script {
openshift.withCluster() { // openshift.withCluster() {
openshift.withProject(test_project) { // openshift.withProject(test_project) {
openshift.raw("set image dc/${ appname } ${ appname }=docker-registry.default.svc:5000/${utv_project}/${ appname }:${BUILD_TAG} --record=true --source=docker") // openshift.raw("set image dc/${ appname } ${ appname }=docker-registry.default.svc:5000/${utv_project}/${ appname }:${BUILD_TAG} --record=true --source=docker")
openshift.raw("annotate dc ${ appname } version=${BUILD_TAG} --overwrite=true") // openshift.raw("annotate dc ${ appname } version=${BUILD_TAG} --overwrite=true")
openshift.selector("dc", "${ appname }").rollout().status(); // openshift.selector("dc", "${ appname }").rollout().status();
} // }
} // }
} // }
echo '### Deployed to "test"! ###' // echo '### Deployed to "test"! ###'
} // }
} // }
} }
} }