Merge pull request #90 in TEA/mina-sidor-fa-web from feature/TV-407 to develop
Squashed commit of the following: commit f4fe49b7e5602b7041573c70b85b22bd978d237b Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Thu Sep 16 18:01:24 2021 +0200 TV-407 cleanup commit 141cd9afa8d73e5ad4860456da926ad1468de874 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Thu Sep 16 16:32:07 2021 +0200 TV-407 updated heading text commit 2d778bd4dd7982e0736bc8c720a69499662a2164 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Thu Sep 16 14:33:04 2021 +0200 TV-407 fixed run test issues, some refactoring commit 9f4cc2c3ad2572eef80923ae465e4d2218acb0cc Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 18:51:58 2021 +0200 TV-407 removed afInvalid on timepicker commit f10923c92ebab2c51593682de4748fc443699c28 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 17:54:49 2021 +0200 TV 407 service name commit cdf02cd956e9f75d8415d525645a5d2ecbeb7e41 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 17:51:39 2021 +0200 TV-407 changed api service name to AvvikelseApiService commit 0ebaddc235ba506aec7cf23ebf96c03cb7a0a79f Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 16:51:02 2021 +0200 TV-407 renaming service name to DeltagareAvvikelseService commit 60e59881099c99a550b70e310930b1f708fa7f70 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 16:40:57 2021 +0200 TV-407 digi-ng timepicker, fixed some pr reviews comments commit b80e79e915d3baa11d7850ddf9ef506b4dd1d1cd Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 15 01:42:42 2021 +0200 TV-407 restructoring files, some cleaning commit 1c92ccefa2f3441c55fd4beacbf38b2ce465aee0 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Tue Sep 14 14:54:53 2021 +0200 TV-407 refactoring, cleaning commit 02904debb8f8dc70c817d2b18b79c0da1b9fd102 Merge: f1ad09a2a37566Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Tue Sep 14 11:51:31 2021 +0200 Merge branch 'develop' into feature/TV-407 commit f1ad09ac823a909b2d6503677314850235670838 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Tue Sep 14 11:50:50 2021 +0200 TV-407 updating report-api service commit 1f766fba089ac0e1f9bd3e00d2a7f81bb5b979e9 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Tue Sep 14 11:40:10 2021 +0200 TV-407 sorting franvaro, validating, cleaning commit f153e574007dfcfe7a65cbd5034370ed31202a34 Merge: ff4011c92272e4Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Mon Sep 13 14:42:38 2021 +0200 Merge branch 'develop' into feature/TV-407 commit ff4011c86f1222c677b2d027ef479b2f82aff5e3 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Mon Sep 13 13:58:05 2021 +0200 TV-407 structoring code to reactive style, validation implemnted commit 25f9debe6216a7bf0a3c6d9a59e6b4499699e380 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 8 22:46:33 2021 +0200 TV-407 changed file structure and renaming commit 9f6f6d4a9f63698d7912668db542eefe285a3b83 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 8 20:11:20 2021 +0200 TV-407 conditions fixes commit 29c1a9536f799795712ded15a3ac746b807f8f94 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 8 15:02:26 2021 +0200 TV-407 reactive error messages, sokandeId to model, cleaning commit ba7a031b3e253cb05ecd1a96920bc8439884dec1 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 8 09:17:16 2021 +0200 TV-407 setTimeout, timepicker condition commit 2eb2c48bc89bc310d2b2e9de4e909fbb5f3bdcb4 Author: fueno <nicolas.fuentes-maturana@arbetsformedlingen.se> Date: Wed Sep 8 09:03:41 2021 +0200 TV-407 corrections ... and 34 more commits
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
export enum Alternative {
|
||||
FRANVARO = 'franvaro',
|
||||
AVVIKELSE = 'avvikelse'
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export enum AvvikelseOrsaksKodEnum {
|
||||
TackatNejTillInsatsEllerAktivitet = 19,
|
||||
TackatNejTillErbjudetArbete = 20,
|
||||
KanInteTillGodoGoraSigProgrammet = 21,
|
||||
MisskottSigEllerStortVerksamheten = 22,
|
||||
SerTillAttErbjudetArbeteInteKommerTillStand = 28
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum DayOrPartOfDay {
|
||||
HELDAG = 'HELDAG',
|
||||
DEL_AV_DAG = 'DEL_AV_DAG'
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export enum FranvaroOrsaksKodEnum {
|
||||
Sjuk = 15,
|
||||
Arbete = 16,
|
||||
OkandOrsak = 17,
|
||||
AnnanKandOrsak = 18,
|
||||
VAB = 26,
|
||||
Utbildning = 27,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export enum KandaOrsakerEnum {
|
||||
LakarbesokTandlakarbesok = 1,
|
||||
Familjeangelagenhet = 2,
|
||||
MoteMedMyndighet = 3,
|
||||
Anstallningsintervju = 4,
|
||||
AnnanOrsak = 5
|
||||
}
|
||||
@@ -9,3 +9,19 @@ export interface ContactInformationResponse {
|
||||
telekomadresser: PhoneNumberResponse[];
|
||||
adresser: AddressResponse[];
|
||||
}
|
||||
|
||||
export interface ContactInformationCompact {
|
||||
fornamn: string;
|
||||
efternamn: string;
|
||||
personnummer: string;
|
||||
}
|
||||
|
||||
export function mapResponseToContactInformationCompact(data: ContactInformationResponse): ContactInformationCompact {
|
||||
const { fornamn, efternamn, personnummer } = data;
|
||||
|
||||
return {
|
||||
fornamn,
|
||||
efternamn,
|
||||
personnummer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface FragorForAvvikelserResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface KandaAvvikelseKoderResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
export interface OrsakResponse {
|
||||
name: string;
|
||||
id: number;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface OrsaksKoderAvvikelseResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
state: number
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface OrsaksKoderFranvaroResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
state: number;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface Arbetssokande {
|
||||
personnummer: string,
|
||||
fornamn: string,
|
||||
efternamn: string
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { Fraga } from './fraga.model';
|
||||
|
||||
export interface AvvikelseAlternativ {
|
||||
avvikelseorsakskod: string,
|
||||
frageformular: Array<Fraga>,
|
||||
rapporteringsdatum: string
|
||||
}
|
||||
36
apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts
Normal file
36
apps/mina-sidor-fa/src/app/shared/models/avvikelse.model.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Arbetssokande } from './arbetssokande.model';
|
||||
import { AvvikelseAlternativ } from './avvikelse-alternativ.model';
|
||||
import { FranvaroAlternativ } from './franvaro-alternativ.model';
|
||||
|
||||
export interface Avvikelse {
|
||||
datum_for_rapportering: string,
|
||||
arbetssokande: Arbetssokande,
|
||||
sokandeId: number;
|
||||
avvikelsealternativ?: AvvikelseAlternativ,
|
||||
franvaro?: FranvaroAlternativ
|
||||
}
|
||||
|
||||
export interface AvvikelseRequestData {
|
||||
datum_for_rapportering: string,
|
||||
arbetssokande: Arbetssokande,
|
||||
sokandeId: number;
|
||||
avvikelsealternativ: AvvikelseAlternativ,
|
||||
}
|
||||
|
||||
export interface FranvaroRequestData {
|
||||
datum_for_rapportering: string,
|
||||
arbetssokande: Arbetssokande,
|
||||
sokandeId: number;
|
||||
franvaro: FranvaroAlternativ
|
||||
}
|
||||
|
||||
export function mapAvvikelseRequestDataToAvvikelse(data: AvvikelseRequestData): Avvikelse {
|
||||
const { datum_for_rapportering, arbetssokande, sokandeId, avvikelsealternativ } = data;
|
||||
|
||||
return {
|
||||
datum_for_rapportering,
|
||||
arbetssokande,
|
||||
sokandeId,
|
||||
avvikelsealternativ
|
||||
}
|
||||
}
|
||||
4
apps/mina-sidor-fa/src/app/shared/models/fraga.model.ts
Normal file
4
apps/mina-sidor-fa/src/app/shared/models/fraga.model.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface Fraga {
|
||||
fraga: string,
|
||||
svar: string
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { FragorForAvvikelserResponse } from './api/fragor-for-avvikelser.response';
|
||||
|
||||
export interface FragorForAvvikelser {
|
||||
name: string;
|
||||
id: string;
|
||||
descriptionIsRequired?: boolean
|
||||
}
|
||||
|
||||
export function mapResponseToFragorForAvvikelser(data: FragorForAvvikelserResponse): FragorForAvvikelser {
|
||||
const { name, id } = data;
|
||||
|
||||
return {
|
||||
name: name,
|
||||
id: id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export interface FranvaroAlternativ {
|
||||
avvikelseorsakskod: string;
|
||||
datum: string;
|
||||
heldag: boolean;
|
||||
starttid: string;
|
||||
sluttid: string;
|
||||
forvantad_narvaro: {
|
||||
starttid: string;
|
||||
sluttid: string;
|
||||
},
|
||||
alternativ_for_kanda_orsaker: {
|
||||
typ: string,
|
||||
motivering: string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { AvvikelseOrsaksKodEnum } from '@msfa-enums/avvikelse-orsak-kod.enum';
|
||||
import { OrsaksKoderAvvikelseResponse } from './api/orsaks-koder-avvikelse.response.model';
|
||||
|
||||
export interface OrsaksKoderAvvikelse {
|
||||
name: string;
|
||||
value: AvvikelseOrsaksKodEnum;
|
||||
state: number;
|
||||
}
|
||||
|
||||
export function mapResponseToOrsaksKoderAvvikelse(data: OrsaksKoderAvvikelseResponse): OrsaksKoderAvvikelse {
|
||||
const { name, id, state } = data;
|
||||
|
||||
return {
|
||||
name,
|
||||
value: id,
|
||||
state
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { AvvikelseOrsaksKodEnum } from '@msfa-enums/avvikelse-orsak-kod.enum';
|
||||
import { KandaOrsakerEnum } from '@msfa-enums/kanda-orsaker-kod.enum';
|
||||
import { KandaAvvikelseKoderResponse } from './api/kanda-avvikelse-koder.response.model';
|
||||
import { OrsaksKoderFranvaroResponse } from './api/orsaks-koder-franvaro.response.model';
|
||||
|
||||
export interface OrsaksKoderFranvaro {
|
||||
name: string;
|
||||
value: AvvikelseOrsaksKodEnum | KandaOrsakerEnum;
|
||||
state: number;
|
||||
index?: number;
|
||||
}
|
||||
|
||||
export interface KandaAvvikelseKoder {
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export function mapResponseToOrsaksKoderFranvaro(data: OrsaksKoderFranvaroResponse): OrsaksKoderFranvaro {
|
||||
const { name, id, state } = data;
|
||||
|
||||
return {
|
||||
name,
|
||||
value: id,
|
||||
state
|
||||
}
|
||||
}
|
||||
|
||||
export function mapResponseToAndraKandaOrsaker(data: KandaAvvikelseKoderResponse): KandaAvvikelseKoder {
|
||||
const { name, id } = data;
|
||||
|
||||
return {
|
||||
name,
|
||||
value: id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Alternative } from '@msfa-enums/alternative.enum';
|
||||
import { ErrorType } from '@msfa-enums/error-type.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
|
||||
import {
|
||||
ContactInformationCompact,
|
||||
ContactInformationResponse,
|
||||
mapResponseToContactInformationCompact
|
||||
} from '@msfa-models/api/contact-information.response.model';
|
||||
import { FragorForAvvikelserResponse } from '@msfa-models/api/fragor-for-avvikelser.response';
|
||||
import { KandaAvvikelseKoderResponse } from '@msfa-models/api/kanda-avvikelse-koder.response.model';
|
||||
import { OrsaksKoderAvvikelseResponse } from '@msfa-models/api/orsaks-koder-avvikelse.response.model';
|
||||
import { Avvikelse, AvvikelseRequestData, mapAvvikelseRequestDataToAvvikelse } from '@msfa-models/avvikelse.model';
|
||||
import { errorToCustomError } from '@msfa-models/error/custom-error';
|
||||
import { FragorForAvvikelser, mapResponseToFragorForAvvikelser } from '@msfa-models/fragor-for-avvikelser.model';
|
||||
import { mapResponseToOrsaksKoderAvvikelse, OrsaksKoderAvvikelse } from '@msfa-models/orsaks-koder-avvikelse.model';
|
||||
import {
|
||||
KandaAvvikelseKoder,
|
||||
mapResponseToAndraKandaOrsaker,
|
||||
mapResponseToOrsaksKoderFranvaro,
|
||||
OrsaksKoderFranvaro
|
||||
} from '@msfa-models/orsaks-koder-franvaro.model';
|
||||
import { ErrorService } from '@msfa-services/error.service';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, filter, map, take } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
||||
export class AvvikelseApiService {
|
||||
|
||||
private _apiBaseUrl = `${environment.api.url}`;
|
||||
|
||||
public getOrsaksKoderFranvaro$(): Observable<OrsaksKoderFranvaro[]> {
|
||||
return this.httpClient.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderfranvaro`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(orsak => mapResponseToOrsaksKoderFranvaro(orsak)))
|
||||
)
|
||||
}
|
||||
|
||||
public getOrsaksKoderAvvikelse$(): Observable<OrsaksKoderAvvikelse[]> {
|
||||
return this.httpClient.get<{ data: OrsaksKoderAvvikelseResponse[] }>(`${this._apiBaseUrl}/orsakskoderavvikelse`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(avvikelse => mapResponseToOrsaksKoderAvvikelse(avvikelse)))
|
||||
)
|
||||
}
|
||||
|
||||
public getAndraKandaOrsaker$(): Observable<KandaAvvikelseKoder[]> {
|
||||
return this.httpClient.get<{ data: KandaAvvikelseKoderResponse[] }>(`${this._apiBaseUrl}/kandaavvikelsekoder`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(annanKandOrsak => mapResponseToAndraKandaOrsaker(annanKandOrsak)))
|
||||
)
|
||||
}
|
||||
|
||||
public getFragorForAvvikelser$(): Observable<FragorForAvvikelser[]> {
|
||||
return this.httpClient.get<{ data: FragorForAvvikelserResponse[] }>(`${this._apiBaseUrl}/fragorforavvikelser`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(fraga => mapResponseToFragorForAvvikelser(fraga)))
|
||||
)
|
||||
}
|
||||
|
||||
public getContactInformation$(id: number): Observable<ContactInformationCompact> {
|
||||
return this.httpClient.get<{ data: ContactInformationResponse }>(`${this._apiBaseUrl}/deltagare/${id}/contact`).pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => mapResponseToContactInformationCompact(data),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of({});
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
public createAvvikelse$(avvikelse: Avvikelse, alternative: string): Observable<Avvikelse> {
|
||||
|
||||
return this.httpClient
|
||||
.post<{ data: AvvikelseRequestData }>(`${this._apiBaseUrl}/${this.setEndPoint(alternative)}`, avvikelse).pipe(
|
||||
filter(response => !!response?.data),
|
||||
take(1),
|
||||
map(({ data }) => mapAvvikelseRequestDataToAvvikelse(data)),
|
||||
catchError(error => throwError({ message: error as string, type: ErrorType.API }))
|
||||
)
|
||||
}
|
||||
|
||||
private setEndPoint(alternative: string): string {
|
||||
let endpoint = '';
|
||||
|
||||
switch (alternative) {
|
||||
case Alternative.AVVIKELSE:
|
||||
endpoint = 'avvikelse';
|
||||
break;
|
||||
case Alternative.FRANVARO:
|
||||
endpoint = 'franvaro';
|
||||
break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
constructor(private httpClient: HttpClient, private errorService: ErrorService) { }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive';
|
||||
import { SortOrder } from '@msfa-enums/sort-order.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AvropResponse } from '@msfa-models/api/avrop.response.model';
|
||||
import { ContactInformationResponse } from '@msfa-models/api/contact-information.response.model';
|
||||
import { DeltagareCompactApiResponse } from '@msfa-models/api/deltagare.response.model';
|
||||
import { DisabilityResponse } from '@msfa-models/api/disability.response.model';
|
||||
import { DriversLicenseResponse } from '@msfa-models/api/drivers-license.response.model';
|
||||
import { EducationsResponse } from '@msfa-models/api/educations.response.model';
|
||||
import { HighestEducationResponse } from '@msfa-models/api/highest-education.response.model';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import { TranslatorResponse } from '@msfa-models/api/translator.response.model';
|
||||
import { WorkExperiencesResponse } from '@msfa-models/api/work-experiences.response.model';
|
||||
import { WorkLanguagesResponse } from '@msfa-models/api/work-languages.response.model';
|
||||
import { Avrop, mapAvropResponseToAvrop } from '@msfa-models/avrop.model';
|
||||
import { ContactInformation, mapResponseToContactInformation } from '@msfa-models/contact-information.model';
|
||||
import {
|
||||
Deltagare,
|
||||
DeltagareCompact,
|
||||
DeltagareCompactData,
|
||||
mapResponseToDeltagareCompact
|
||||
} from '@msfa-models/deltagare.model';
|
||||
import { Disability, mapResponseToDisability } from '@msfa-models/disability.model';
|
||||
import { DriversLicense, mapResponseToDriversLicense } from '@msfa-models/drivers-license.model';
|
||||
import { Education, mapResponseToEducation } from '@msfa-models/education.model';
|
||||
import { errorToCustomError } from '@msfa-models/error/custom-error';
|
||||
import { HighestEducation, mapResponseToHighestEducation } from '@msfa-models/highest-education.model';
|
||||
import { Sort } from '@msfa-models/sort.model';
|
||||
import { mapResponseToWorkExperience, WorkExperience } from '@msfa-models/work-experience.model';
|
||||
import { ErrorService } from '@msfa-services/error.service';
|
||||
import { sortFromToDates } from '@msfa-utils/sort.util';
|
||||
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
|
||||
import { catchError, filter, map, switchMap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DeltagareApiService extends UnsubscribeDirective {
|
||||
private _apiBaseUrl = `${environment.api.url}/deltagare`;
|
||||
private _currentDeltagareId$ = new BehaviorSubject<string>(null);
|
||||
private _limit$ = new BehaviorSubject<number>(20);
|
||||
private _page$ = new BehaviorSubject<number>(1);
|
||||
private _sort$ = new BehaviorSubject<Sort<keyof DeltagareCompact>>({ key: 'fullName', order: SortOrder.ASC });
|
||||
public sort$: Observable<Sort<keyof DeltagareCompact>> = this._sort$.asObservable();
|
||||
|
||||
constructor(private httpClient: HttpClient, private errorService: ErrorService) {
|
||||
super();
|
||||
super.unsubscribeOnDestroy(
|
||||
this._currentDeltagareId$
|
||||
.pipe(
|
||||
filter(currentDeltagareId => !!currentDeltagareId),
|
||||
switchMap(currentDeltagareId => this._fetchDeltagare$(currentDeltagareId))
|
||||
)
|
||||
.subscribe(deltagare => {
|
||||
this._deltagare$.next(deltagare);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _deltagare$ = new BehaviorSubject<Deltagare>(null);
|
||||
public deltagare$: Observable<Deltagare> = this._deltagare$.asObservable();
|
||||
|
||||
public allDeltagareData$: Observable<DeltagareCompactData> = combineLatest([
|
||||
this._limit$,
|
||||
this._page$,
|
||||
this._sort$,
|
||||
]).pipe(switchMap(([limit, page, sort]) => this._fetchAllDeltagare$(limit, page, sort)));
|
||||
|
||||
public setSort(newSortKey: keyof DeltagareCompact): void {
|
||||
const currentSort = this._sort$.getValue();
|
||||
const order =
|
||||
currentSort.key === newSortKey && currentSort.order === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
||||
|
||||
this._sort$.next({ key: newSortKey, order });
|
||||
}
|
||||
|
||||
public setPage(page: number): void {
|
||||
this._page$.next(page);
|
||||
}
|
||||
|
||||
private _fetchAllDeltagare$(
|
||||
limit: number,
|
||||
page: number,
|
||||
sort: Sort<keyof DeltagareCompact>
|
||||
): Observable<DeltagareCompactData> {
|
||||
const params: Params = {
|
||||
sort: sort.key as string,
|
||||
order: sort.order as string,
|
||||
limit: limit.toString(),
|
||||
page: page.toString(),
|
||||
};
|
||||
|
||||
return this.httpClient
|
||||
.get<DeltagareCompactApiResponse>(this._apiBaseUrl, {
|
||||
params,
|
||||
})
|
||||
.pipe(
|
||||
map(({ data, meta }) => {
|
||||
return { data: data.map(deltagare => mapResponseToDeltagareCompact(deltagare)), meta };
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public setCurrentDeltagareId(currentDeltagareId: string): void {
|
||||
this._deltagare$.next(null);
|
||||
this._currentDeltagareId$.next(currentDeltagareId);
|
||||
}
|
||||
|
||||
private _fetchContactInformation$(id: string): Observable<ContactInformation | Partial<ContactInformation>> {
|
||||
return this.httpClient.get<{ data: ContactInformationResponse }>(`${this._apiBaseUrl}/${id}/contact`).pipe(
|
||||
map(({ data }) => mapResponseToContactInformation(data)),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of({});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchDriversLicense$(id: string): Observable<DriversLicense | Partial<DriversLicense>> {
|
||||
return this.httpClient.get<{ data: DriversLicenseResponse }>(`${this._apiBaseUrl}/${id}/driverlicense`).pipe(
|
||||
map(({ data }) => mapResponseToDriversLicense(data)),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of({});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchHighestEducation$(id: string): Observable<HighestEducation | Partial<HighestEducation>> {
|
||||
return this.httpClient
|
||||
.get<{ data: HighestEducationResponse }>(`${this._apiBaseUrl}/${id}/educationlevels/highest`)
|
||||
.pipe(
|
||||
map(({ data }) => mapResponseToHighestEducation(data)),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of({});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchEducations$(id: string): Observable<Education[]> {
|
||||
return this.httpClient.get<{ data: EducationsResponse }>(`${this._apiBaseUrl}/${id}/educations`).pipe(
|
||||
map(({ data }) =>
|
||||
data.utbildningar
|
||||
? data.utbildningar.sort((a, b) =>
|
||||
sortFromToDates({ from: a.period_from, to: a.period_tom }, { from: b.period_from, to: b.period_tom })
|
||||
)
|
||||
: []
|
||||
),
|
||||
map(educations => educations.map(utbildning => mapResponseToEducation(utbildning))),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of([]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchTranslator$(id: string): Observable<string> {
|
||||
return this.httpClient.get<{ data: TranslatorResponse }>(`${this._apiBaseUrl}/${id}/translator`).pipe(
|
||||
map(({ data }) => data.sprak?.beskrivning || null),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of('');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchWorkLanguages$(id: string): Observable<string[]> {
|
||||
return this.httpClient.get<{ data: WorkLanguagesResponse }>(`${this._apiBaseUrl}/${id}/work/languages`).pipe(
|
||||
map(({ data }) => data?.sprak?.map(sprak => sprak.beskrivning) || []),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of([]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchDisabilities$(id: string): Observable<Disability[]> {
|
||||
return this.httpClient.get<{ data: DisabilityResponse[] }>(`${this._apiBaseUrl}/${id}/work/disabilities`).pipe(
|
||||
map(({ data }) => data?.map(funktionsnedsattning => mapResponseToDisability(funktionsnedsattning)) || []),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of([]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchWorkExperiences$(id: string): Observable<WorkExperience[]> {
|
||||
return this.httpClient.get<{ data: WorkExperiencesResponse }>(`${this._apiBaseUrl}/${id}/work/experiences`).pipe(
|
||||
map(
|
||||
({ data }) =>
|
||||
data?.arbetslivserfarenheter?.sort((a, b) =>
|
||||
sortFromToDates({ from: a.period_from, to: a.period_tom }, { from: b.period_from, to: b.period_tom })
|
||||
) || []
|
||||
),
|
||||
map(workExperiences => workExperiences.map(erfarenhet => mapResponseToWorkExperience(erfarenhet))),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of([]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _fetchAvropInformation$(id: string): Observable<Avrop | Partial<Avrop>> {
|
||||
return this.httpClient.get<{ data: AvropResponse }>(`${this._apiBaseUrl}/${id}/avrop`).pipe(
|
||||
map(({ data }) => (data ? mapAvropResponseToAvrop(data) : {})),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of({});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// As TypeScript has some limitations regarding combining Observables this way,
|
||||
// we need to type it manually when exceeding 6 Observables inside a combineLatest.
|
||||
// Read: https://github.com/ReactiveX/rxjs/issues/3601#issuecomment-384711601
|
||||
private _fetchDeltagare$(id: string): Observable<Deltagare> {
|
||||
return combineLatest([
|
||||
this._fetchContactInformation$(id),
|
||||
this._fetchDriversLicense$(id),
|
||||
this._fetchHighestEducation$(id),
|
||||
this._fetchEducations$(id),
|
||||
this._fetchTranslator$(id),
|
||||
this._fetchWorkLanguages$(id),
|
||||
this._fetchDisabilities$(id),
|
||||
this._fetchWorkExperiences$(id),
|
||||
this._fetchAvropInformation$(id),
|
||||
]).pipe(
|
||||
map(
|
||||
([
|
||||
contactInformation,
|
||||
driversLicense,
|
||||
highestEducation,
|
||||
educations,
|
||||
translator,
|
||||
workLanguages,
|
||||
disabilities,
|
||||
workExperiences,
|
||||
avropInformation,
|
||||
]: [
|
||||
ContactInformation,
|
||||
DriversLicense,
|
||||
HighestEducation,
|
||||
Education[],
|
||||
string,
|
||||
string[],
|
||||
Disability[],
|
||||
WorkExperience[],
|
||||
Avrop
|
||||
]) => ({
|
||||
id,
|
||||
...contactInformation,
|
||||
driversLicense,
|
||||
highestEducation,
|
||||
educations,
|
||||
translator,
|
||||
workLanguages,
|
||||
disabilities,
|
||||
workExperiences,
|
||||
avropInformation,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
import { Alternative } from '@msfa-enums/alternative.enum';
|
||||
import { DayOrPartOfDay } from '@msfa-enums/day-or-part-of-day.enum';
|
||||
import { FranvaroOrsaksKodEnum } from '@msfa-enums/franvaro-orsak-kod.enum';
|
||||
import { KandaOrsakerEnum } from '@msfa-enums/kanda-orsaker-kod.enum';
|
||||
|
||||
export class DescriptionIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
controlToValidateName: string,
|
||||
nestedFormGroupName: string,
|
||||
nestedFormGroupControlName: string,
|
||||
valueForWhichTheControlShouldBeRequired: KandaOrsakerEnum
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfControlToValidate = fg?.get(controlToValidateName)?.value as string;
|
||||
const valueOfNestedFormControl = fg?.get(nestedFormGroupName)?.get(nestedFormGroupControlName)?.value as string;
|
||||
const isRequired = +valueOfNestedFormControl === valueForWhichTheControlShouldBeRequired && valueOfControlToValidate === '';
|
||||
|
||||
return isRequired ? { descriptionIsRequired: true } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class DayOrPartOfDayIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
controlToValidateName: string,
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfControlToValidate = fg?.get(controlToValidateName)?.value as string;
|
||||
const isRequired = valueOfControlToValidate === null && fg?.get('alternative').value === Alternative.FRANVARO;
|
||||
|
||||
return isRequired ? { dayOrPartOfDayIsRequired: true } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class OrsakerIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
nestedFormGroupName: string,
|
||||
controlToValidateName: string,
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfNestedFormControl = fg?.get(nestedFormGroupName)?.get(controlToValidateName)?.value as string;
|
||||
const isRequired = valueOfNestedFormControl === null && fg?.get(nestedFormGroupName)?.get('andraKandaOrsaker')?.value === null;
|
||||
|
||||
return isRequired ? { orsakerIsRequired: true } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class AnnanKandOrsakeIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
nestedFormGroupName: string,
|
||||
controlToValidateName: string,
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfNestedFormControl = fg?.get(nestedFormGroupName)?.get(controlToValidateName)?.value as string;
|
||||
const isRequired = +fg?.get(nestedFormGroupName).get('orsaker').value === FranvaroOrsaksKodEnum.AnnanKandOrsak &&
|
||||
valueOfNestedFormControl === null;
|
||||
|
||||
return isRequired ? { annanKandorsakIsRequired: true } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class StartTimeIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
nestedFormGroupName: string,
|
||||
startTimeControlToValidateName: string,
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfStartTimeFormControl = fg?.get(nestedFormGroupName)?.get(startTimeControlToValidateName)?.value as string;
|
||||
const isRequired = fg?.get('alternative')?.value as string === Alternative.FRANVARO &&
|
||||
fg?.get('dayOrPartOfDay').value === DayOrPartOfDay.DEL_AV_DAG && !valueOfStartTimeFormControl;
|
||||
|
||||
return isRequired ? { startTimeIsRequired: true } : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class EndTimeIsRequiredCheck {
|
||||
static CheckIfRequired(
|
||||
nestedFormGroupName: string,
|
||||
endTimeControlToValidateName: string
|
||||
): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfEndTimeFormControl = fg?.get(nestedFormGroupName)?.get(endTimeControlToValidateName)?.value as string;
|
||||
const isRequired = fg?.get('alternative').value as string === Alternative.FRANVARO &&
|
||||
fg?.get('dayOrPartOfDay').value === DayOrPartOfDay.DEL_AV_DAG && !valueOfEndTimeFormControl;
|
||||
|
||||
return isRequired ? { endTimeIsRequired: true } : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class MotiveringIsRequiredCheck {
|
||||
static CheckIfRequired(controlToValidateName: string): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: boolean } => {
|
||||
const valueOfControlToValidate = fg?.get('fragorFormGroup').get(controlToValidateName)?.value as string;
|
||||
const isRequired = fg?.get('alternative').value as string === Alternative.AVVIKELSE && valueOfControlToValidate === '';
|
||||
|
||||
return isRequired ? { motiveringIsRequired: true } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
export class DateIsRequiredCheck {
|
||||
static CheckIfRequired(controlToValidateName: string): ValidatorFn {
|
||||
return (fg: AbstractControl): { [key: string]: string } => {
|
||||
const valueOfControlToValidate = fg?.get(controlToValidateName).value as string;
|
||||
const isRequired = valueOfControlToValidate === '';
|
||||
|
||||
return isRequired ? { dateIsRequired: 'Datum är obligatoriskt' } : null;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user