feat(deltagare): Added deltagare data and models (TV-268)
Squashed commit of the following:
commit 8b61e3edeb644d7a27d322a569e85a7f76667243
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 14:26:13 2021 +0200
Removed comments
commit 40dd5f0c186ab4b7b239c054d468f33bd550e0a4
Merge: 3a51568 a11d166
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 13:00:59 2021 +0200
Merge branch 'develop' into feature/TV-268-deltagare-data
commit 3a515683513e8152507a744489d79dc62efbc64c
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 12:53:03 2021 +0200
Removed wrong data-structure from deltagare-card component
commit 2b2da9fb6b25c980bacfe3f37201f569c05fce8c
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 12:19:37 2021 +0200
Added more mock-data to deltagare api
commit 8c52ba5a3a259eb0a4c084eb516180a333bafb45
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 11:01:47 2021 +0200
Added highestEducation to mock-api and fixed dynamic mock-api paths
commit a6b372bf05900698dc592ca15853def26cebe841
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Fri Jul 2 08:33:06 2021 +0200
Added fallbackvalues for deltagare
commit 6bbad6826620fc4d95877884fefbb0951216fab0
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu Jul 1 16:05:05 2021 +0200
WIP adding mock-data
commit b20e3b057ac50c7f929e8eeaff3a06c5372280a9
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu Jul 1 10:30:32 2021 +0200
Added some data to deltagarekort
commit ac15170c089be760bd72a470e9f83603dedba945
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu Jul 1 09:40:56 2021 +0200
Added deltagare page and components. Also mapped drivers-licenses
commit 80785b31453553ce78e75b8a76a9ca2758870a0e
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed Jun 30 15:52:28 2021 +0200
Added mapping
commit 1b15d0d621b2bb0b3d44d695df12f68637205223
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed Jun 30 15:20:53 2021 +0200
Added deltagareCompact in service
commit 20f7de869d0343a5af59acb83964eea224bcf926
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed Jun 30 14:57:59 2021 +0200
Added deltagare models and started with service
This commit is contained in:
@@ -19,7 +19,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: 'deltagare',
|
||||
data: { title: 'Deltagare' },
|
||||
loadChildren: () => import('./pages/participants/participants.module').then(m => m.ParticipantsModule),
|
||||
loadChildren: () => import('./pages/deltagare/deltagare.module').then(m => m.DeltagareModule),
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { DeltagareComponent } from './deltagare.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DeltagareComponent,
|
||||
},
|
||||
{
|
||||
path: ':deltagareId',
|
||||
loadChildren: () => import('./pages/deltagare-card/deltagare-card.module').then(m => m.DeltagareCardModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class DeltagareRoutingModule {}
|
||||
@@ -0,0 +1,17 @@
|
||||
<dafa-layout>
|
||||
<digi-typography>
|
||||
<section class="deltagare">
|
||||
<h1>Deltagarlista</h1>
|
||||
<p>
|
||||
Här ser du en lista på de deltagare du är tilldelad. Klicka på deltagarens namn för att öppna och se mer
|
||||
information om deltagarna.
|
||||
</p>
|
||||
|
||||
<a routerLink="1">Klicka för att gå till en test-deltagare från API:et</a>
|
||||
|
||||
<ul *ngIf="allDeltagare$ | async as allDeltagare">
|
||||
<li *ngFor="let deltagare of allDeltagare"><a [routerLink]="deltagare.id">{{deltagare.fullName}}</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</digi-typography>
|
||||
</dafa-layout>
|
||||
@@ -0,0 +1,2 @@
|
||||
.deltagare {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { DeltagareComponent } from './deltagare.component';
|
||||
|
||||
describe('DeltagareComponent', () => {
|
||||
let component: DeltagareComponent;
|
||||
let fixture: ComponentFixture<DeltagareComponent>;
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [DeltagareComponent],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DeltagareComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
16
apps/dafa-web/src/app/pages/deltagare/deltagare.component.ts
Normal file
16
apps/dafa-web/src/app/pages/deltagare/deltagare.component.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Deltagare } from '@dafa-models/deltagare.model';
|
||||
import { DeltagareService } from '@dafa-services/api/deltagare.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-deltagare',
|
||||
templateUrl: './deltagare.component.html',
|
||||
styleUrls: ['./deltagare.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagareComponent {
|
||||
allDeltagare$: Observable<Deltagare[]> = this.deltagareService.allDeltagare$;
|
||||
|
||||
constructor(private deltagareService: DeltagareService) {}
|
||||
}
|
||||
12
apps/dafa-web/src/app/pages/deltagare/deltagare.module.ts
Normal file
12
apps/dafa-web/src/app/pages/deltagare/deltagare.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { LayoutModule } from '@dafa-shared/components/layout/layout.module';
|
||||
import { DeltagareRoutingModule } from './deltagare-routing.module';
|
||||
import { DeltagareComponent } from './deltagare.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareComponent],
|
||||
imports: [CommonModule, DeltagareRoutingModule, LayoutModule],
|
||||
})
|
||||
export class DeltagareModule {}
|
||||
@@ -0,0 +1,81 @@
|
||||
<dafa-layout>
|
||||
<section class="deltagare-card">
|
||||
<digi-typography *ngIf="deltagare$ | async as deltagare; else loadingRef">
|
||||
<header class="deltagare-card__header">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
<h1>{{ deltagare.fullName }}</h1>
|
||||
</header>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus accusantium sit, reprehenderit, esse suscipit
|
||||
quis similique harum est eum eveniet aspernatur delectus magni asperiores porro aliquam voluptate! Architecto,
|
||||
perferendis commodi.
|
||||
</p>
|
||||
|
||||
<pre>{{deltagare | json}}</pre>
|
||||
|
||||
<div class="deltagare-card__contents">
|
||||
<div class="deltagare-card__column">
|
||||
<h2>Personuppgifter</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Namn</dt>
|
||||
<dd *ngIf="deltagare.fullName; else emptyDD">{{ deltagare.fullName }}</dd>
|
||||
<dt>Personnummer</dt>
|
||||
<dd *ngIf="deltagare.ssn; else emptyDD">{{ deltagare.ssn }}</dd>
|
||||
<dt>Epostadress</dt>
|
||||
<dd *ngIf="deltagare.email; else emptyDD">{{ deltagare.email }}</dd>
|
||||
<dt>Telefonnummer</dt>
|
||||
<ng-container *ngIf="deltagare.phoneNumbers.length; else emptyDD">
|
||||
<ng-container *ngFor="let phoneNumber of deltagare.phoneNumbers">
|
||||
<dd>{{ phoneNumber.type }}: {{phoneNumber.number}}</dd>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</dl>
|
||||
|
||||
<h3>Särskilda behov</h3>
|
||||
<p>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus, voluptatum quibusdam repellendus animi,
|
||||
quidem, commodi quos porro quia incidunt saepe veritatis voluptatem. Cupiditate, accusamus atque! Illum,
|
||||
quisquam esse? Omnis, quasi!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="deltagare-card__column">
|
||||
<h2>Om tjänsten</h2>
|
||||
</div>
|
||||
|
||||
<div class="deltagare-card__column">
|
||||
<h2>Matchningsuppgifter</h2>
|
||||
</div>
|
||||
|
||||
<div class="deltagare-card__column">
|
||||
<h2>Körkortsinformation</h2>
|
||||
<dl>
|
||||
<dt>Har körkort</dt>
|
||||
<dd>{{deltagare.driversLicense.licenses.length ? 'Ja' : 'Nej'}}</dd>
|
||||
<ng-container *ngIf="deltagare.driversLicense.licenses.length">
|
||||
<dt>Körkortsklasser</dt>
|
||||
<dd>{{deltagare.driversLicense.licenses.join(', ')}}</dd>
|
||||
<dt>Tillgång till bil</dt>
|
||||
<dd>{{deltagare.driversLicense.accessToCar ? 'Ja' : 'Nej'}}</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="deltagare-card__footer">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
</footer>
|
||||
</digi-typography>
|
||||
</section>
|
||||
|
||||
<ng-template #loadingRef>
|
||||
<digi-ng-skeleton-base [afCount]="3" afText="Laddar deltagarinformation"></digi-ng-skeleton-base>
|
||||
</ng-template>
|
||||
<ng-template #emptyDD>
|
||||
<dd>
|
||||
<span aria-hidden="true">-</span>
|
||||
<span class="dafa__a11y-sr-only">Info saknas</span>
|
||||
</dd>
|
||||
</ng-template>
|
||||
</dafa-layout>
|
||||
@@ -0,0 +1,45 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.deltagare-card {
|
||||
&__contents {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $digi--layout--gutter--xl $digi--layout--gutter--l;
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__column {
|
||||
width: 100%;
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
}
|
||||
|
||||
dl {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.5rem 2rem;
|
||||
}
|
||||
|
||||
dt,
|
||||
dd {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
grid-column: 1;
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
dd {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
&__header,
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { DeltagareCardComponent } from './deltagare-card.component';
|
||||
|
||||
describe('DeltagareCardComponent', () => {
|
||||
let component: DeltagareCardComponent;
|
||||
let fixture: ComponentFixture<DeltagareCardComponent>;
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [DeltagareCardComponent],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DeltagareCardComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { IconType } from '@dafa-enums/icon-type.enum';
|
||||
import { Deltagare } from '@dafa-models/deltagare.model';
|
||||
import { DeltagareService } from '@dafa-services/api/deltagare.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-deltagare-card',
|
||||
templateUrl: './deltagare-card.component.html',
|
||||
styleUrls: ['./deltagare-card.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DeltagareCardComponent {
|
||||
private _deltagareId$: Observable<string> = this.activatedRoute.params.pipe(
|
||||
map(({ deltagareId }) => deltagareId as string)
|
||||
);
|
||||
deltagare$: Observable<Deltagare> = this._deltagareId$.pipe(
|
||||
switchMap(deltagareId => this.deltagaresService.deltagare$(deltagareId))
|
||||
);
|
||||
iconType = IconType;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private deltagaresService: DeltagareService) {}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { DigiNgLinkInternalModule } from '@af/digi-ng/_link/link-internal';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { BackLinkModule } from '@dafa-shared/components/back-link/back-link.module';
|
||||
import { IconModule } from '@dafa-shared/components/icon/icon.module';
|
||||
import { LayoutModule } from '@dafa-shared/components/layout/layout.module';
|
||||
import { DeltagareCardComponent } from './deltagare-card.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [DeltagareCardComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{ path: '', component: DeltagareCardComponent }]),
|
||||
LayoutModule,
|
||||
DigiNgLinkInternalModule,
|
||||
IconModule,
|
||||
BackLinkModule,
|
||||
],
|
||||
exports: [DeltagareCardComponent],
|
||||
})
|
||||
export class DeltagareCardModule {}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { LogoutComponent } from './logout.component';
|
||||
|
||||
describe('LogoutComponent', () => {
|
||||
let component: LogoutComponent;
|
||||
let fixture: ComponentFixture<LogoutComponent>;
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [LogoutComponent],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LogoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
17
apps/dafa-web/src/app/shared/constants/drivers-licenses.ts
Normal file
17
apps/dafa-web/src/app/shared/constants/drivers-licenses.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export const DRIVERS_LICENSES = [
|
||||
'AM',
|
||||
'A1',
|
||||
'A2',
|
||||
'A',
|
||||
'B',
|
||||
'BE',
|
||||
'B96',
|
||||
'C1',
|
||||
'C',
|
||||
'C1E',
|
||||
'CE',
|
||||
'D1',
|
||||
'D',
|
||||
'D1E',
|
||||
'DE',
|
||||
];
|
||||
@@ -1,4 +1,4 @@
|
||||
export const Navigation = {
|
||||
export const NAVIGATION = {
|
||||
administration: 'Administration',
|
||||
'skapa-konto': 'Skapa nytt konto',
|
||||
personal: 'Hantera personal',
|
||||
|
||||
16
apps/dafa-web/src/app/shared/enums/address-type.enum.ts
Normal file
16
apps/dafa-web/src/app/shared/enums/address-type.enum.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export enum AddressType {
|
||||
OFFICIAL = 'Folkbokföringsadress',
|
||||
POSTAL = 'Postadress',
|
||||
UNSPECIFIED = 'Ospecificerad adress',
|
||||
}
|
||||
|
||||
export function getAddressType(addressType: 'FBF' | 'EgenAngiven'): AddressType {
|
||||
switch (addressType) {
|
||||
case 'FBF':
|
||||
return AddressType.OFFICIAL;
|
||||
case 'EgenAngiven':
|
||||
return AddressType.POSTAL;
|
||||
default:
|
||||
return AddressType.UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
17
apps/dafa-web/src/app/shared/enums/phonenumber-type.enum.ts
Normal file
17
apps/dafa-web/src/app/shared/enums/phonenumber-type.enum.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export enum PhoneNumberType {
|
||||
CELL = 'Mobil',
|
||||
DOMESTIC = 'Hem',
|
||||
WORK = 'Arbete',
|
||||
UNKNOWN = 'Okänd',
|
||||
}
|
||||
|
||||
export function getPhoneNumberType(phoneNumberType: 'Mobil' | 'Bostad'): PhoneNumberType {
|
||||
switch (phoneNumberType) {
|
||||
case 'Mobil':
|
||||
return PhoneNumberType.CELL;
|
||||
case 'Bostad':
|
||||
return PhoneNumberType.DOMESTIC;
|
||||
default:
|
||||
return PhoneNumberType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
20
apps/dafa-web/src/app/shared/models/address.model.ts
Normal file
20
apps/dafa-web/src/app/shared/models/address.model.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { AddressType, getAddressType } from '@dafa-enums/address-type.enum';
|
||||
import { AddressResponse } from './api/address.response.model';
|
||||
|
||||
export interface Address {
|
||||
type: AddressType;
|
||||
street: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
}
|
||||
|
||||
export function mapResponseToAddress(data: AddressResponse): Address {
|
||||
return {
|
||||
type: getAddressType(data.adresstyp),
|
||||
street: data.gatuadress,
|
||||
postalCode: data.postnummer,
|
||||
city: data.postort,
|
||||
country: data.land,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface AddressResponse {
|
||||
adresstyp: 'FBF' | 'EgenAngiven';
|
||||
gatuadress: string;
|
||||
postnummer: string;
|
||||
postort: string;
|
||||
land: string;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { AddressResponse } from './address.response.model';
|
||||
import { PhoneNumberResponse } from './phonenumber.response.model';
|
||||
|
||||
export interface ContactInformationResponse {
|
||||
fornamn: string;
|
||||
efternamn: string;
|
||||
personnummer: string;
|
||||
epost: string;
|
||||
telekomadresser: PhoneNumberResponse[];
|
||||
adresser: AddressResponse[];
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { ContactInformationResponse } from './contact-information.response.model';
|
||||
import { DisabilitiesResponse } from './disabilities.response.model';
|
||||
import { DriversLicenseResponse } from './drivers-license.response.model';
|
||||
import { EducationsResponse } from './educations.response.model';
|
||||
import { HighestEducationResponse } from './highest-education.response.model';
|
||||
import { TranslatorResponse } from './translator.response.model';
|
||||
import { WorkLanguagesResponse } from './work-languages.response.model';
|
||||
|
||||
export interface DeltagareResponse {
|
||||
id: string;
|
||||
contact: ContactInformationResponse;
|
||||
driverlicense: DriversLicenseResponse;
|
||||
highestEducation: HighestEducationResponse;
|
||||
educations: EducationsResponse;
|
||||
translator: TranslatorResponse;
|
||||
workLanguages: WorkLanguagesResponse;
|
||||
disabilities: DisabilitiesResponse;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { DisabilityResponse } from './disability.response.model';
|
||||
|
||||
export interface DisabilitiesResponse {
|
||||
funktionsnedsattningar: DisabilityResponse[];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface DisabilityResponse {
|
||||
kod: string;
|
||||
funktionsnedsattning: string;
|
||||
beskrivning: string;
|
||||
utgatt: boolean;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface DriversLicenseResponse {
|
||||
korkort: { behorighet: string };
|
||||
tillgang_till_bil: boolean;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface EducationLevelResponse {
|
||||
utbildningsniva: string;
|
||||
beskrivning: string;
|
||||
taxonomy_id: number;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface EducationResponse {
|
||||
utbildning: string;
|
||||
beskrivning: string;
|
||||
anordnare: string;
|
||||
period_from: string;
|
||||
period_tom: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { EducationResponse } from './education.response.model';
|
||||
|
||||
export interface EducationsResponse {
|
||||
utbildningar: EducationResponse[];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface HighestEducationResponse {
|
||||
utbildningsniva: string;
|
||||
beskrivning_utbildningsniva: string;
|
||||
sun_kod: string;
|
||||
beskrivning_sun_kod: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface LanguageResponse {
|
||||
beskrivning: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface PhoneNumberResponse {
|
||||
landskod: number;
|
||||
nummer_utan_inledande_nolla: number;
|
||||
telekomtyp: 'Mobil' | 'Bostad';
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface SunKodResponse {
|
||||
sun_kod: string;
|
||||
beskrivning: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { LanguageResponse } from './language.response.model';
|
||||
|
||||
export interface TranslatorResponse {
|
||||
sprak: LanguageResponse;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface WorkExperienceResponse {
|
||||
yrke: string;
|
||||
beskrivning: string;
|
||||
arbetsgivare: string;
|
||||
period_from: string;
|
||||
period_tom: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { WorkExperienceResponse } from './work-experience.response.model';
|
||||
|
||||
export interface WorkExperiencesResponse {
|
||||
arbetslivserfarenheter: WorkExperienceResponse[];
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { LanguageResponse } from './language.response.model';
|
||||
|
||||
export interface WorkLanguagesResponse {
|
||||
sprak: LanguageResponse[];
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Address, mapResponseToAddress } from './address.model';
|
||||
import { ContactInformationResponse } from './api/contact-information.response.model';
|
||||
import { mapResponseToPhoneNumber, PhoneNumber } from './phonenumber.model';
|
||||
|
||||
export interface ContactInformation {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
fullName: string;
|
||||
ssn: string;
|
||||
email: string;
|
||||
phoneNumbers: PhoneNumber[];
|
||||
addresses: Address[];
|
||||
}
|
||||
|
||||
export function mapResponseToContactInformation(contactInformation: ContactInformationResponse): ContactInformation {
|
||||
return {
|
||||
firstName: contactInformation.fornamn,
|
||||
lastName: contactInformation.efternamn,
|
||||
fullName: `${contactInformation.fornamn} ${contactInformation.efternamn}`,
|
||||
ssn: `${contactInformation.personnummer.substring(
|
||||
0,
|
||||
contactInformation.personnummer.length - 4
|
||||
)}-${contactInformation.personnummer.substring(contactInformation.personnummer.length - 4)}`,
|
||||
email: contactInformation.epost,
|
||||
phoneNumbers: contactInformation.telekomadresser
|
||||
? contactInformation.telekomadresser.map(phoneNumber => {
|
||||
return mapResponseToPhoneNumber(phoneNumber);
|
||||
})
|
||||
: [],
|
||||
addresses: contactInformation.adresser
|
||||
? contactInformation.adresser.map(address => mapResponseToAddress(address))
|
||||
: null,
|
||||
};
|
||||
}
|
||||
45
apps/dafa-web/src/app/shared/models/deltagare.model.ts
Normal file
45
apps/dafa-web/src/app/shared/models/deltagare.model.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Address } from './address.model';
|
||||
import { DeltagareResponse } from './api/deltagare.response.model';
|
||||
import { mapResponseToContactInformation } from './contact-information.model';
|
||||
import { Disability, mapResponseToDisability } from './disability.model';
|
||||
import { DriversLicense, mapResponseToDriversLicense } from './drivers-license.model';
|
||||
import { Education, mapResponseToEducation } from './education.model';
|
||||
import { HighestEducation, mapResponseToHighestEducation } from './highest-education.model';
|
||||
import { PhoneNumber } from './phonenumber.model';
|
||||
|
||||
export interface DeltagareCompact {
|
||||
id: string;
|
||||
fullName: string;
|
||||
}
|
||||
|
||||
export interface Deltagare extends DeltagareCompact {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
ssn: string;
|
||||
email: string;
|
||||
phoneNumbers: PhoneNumber[];
|
||||
addresses: Address[];
|
||||
driversLicense: DriversLicense;
|
||||
educations: Education[];
|
||||
highestEducation: HighestEducation;
|
||||
translator: string;
|
||||
disabilities: Disability[];
|
||||
workLanguages: string[];
|
||||
// workExperiences: WorkExperience[]; // TODO: Missing from API
|
||||
}
|
||||
|
||||
export function mapResponseToDeltagare(data: DeltagareResponse): Deltagare {
|
||||
const { id, contact, driverlicense, highestEducation, educations, translator, workLanguages, disabilities } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
...mapResponseToContactInformation(contact),
|
||||
driversLicense: mapResponseToDriversLicense(driverlicense),
|
||||
highestEducation: highestEducation && mapResponseToHighestEducation(highestEducation),
|
||||
educations: educations && educations.utbildningar.map(education => mapResponseToEducation(education)),
|
||||
translator: translator && translator.sprak.beskrivning,
|
||||
workLanguages: workLanguages && workLanguages.sprak.map(language => language.beskrivning),
|
||||
disabilities:
|
||||
disabilities && disabilities.funktionsnedsattningar.map(disability => mapResponseToDisability(disability)),
|
||||
};
|
||||
}
|
||||
17
apps/dafa-web/src/app/shared/models/disability.model.ts
Normal file
17
apps/dafa-web/src/app/shared/models/disability.model.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DisabilityResponse } from './api/disability.response.model';
|
||||
|
||||
export interface Disability {
|
||||
code: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export function mapResponseToDisability(data: DisabilityResponse): Disability {
|
||||
const { kod, funktionsnedsattning, beskrivning } = data;
|
||||
|
||||
return {
|
||||
code: kod,
|
||||
title: funktionsnedsattning, // TODO: Needed from API
|
||||
description: beskrivning || null, //TODO: Needed from API
|
||||
};
|
||||
}
|
||||
29
apps/dafa-web/src/app/shared/models/drivers-license.model.ts
Normal file
29
apps/dafa-web/src/app/shared/models/drivers-license.model.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { DRIVERS_LICENSES } from '@dafa-constants/drivers-licenses';
|
||||
import { DriversLicenseResponse } from './api/drivers-license.response.model';
|
||||
|
||||
export interface DriversLicense {
|
||||
licenses: string[];
|
||||
accessToCar: boolean;
|
||||
}
|
||||
|
||||
function mapLicensesAsStringToArray(licenses = ''): string[] {
|
||||
const allLicenses = DRIVERS_LICENSES.sort((a, b) => b.length - a.length);
|
||||
let search = licenses;
|
||||
const found: string[] = [];
|
||||
|
||||
allLicenses.forEach(license => {
|
||||
if (search.indexOf(license) >= 0) {
|
||||
found.push(license);
|
||||
search = search.replace(license, '');
|
||||
}
|
||||
});
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
export function mapResponseToDriversLicense(data: DriversLicenseResponse): DriversLicense {
|
||||
return {
|
||||
licenses: mapLicensesAsStringToArray(data.korkort.behorighet),
|
||||
accessToCar: data.tillgang_till_bil,
|
||||
};
|
||||
}
|
||||
21
apps/dafa-web/src/app/shared/models/education.model.ts
Normal file
21
apps/dafa-web/src/app/shared/models/education.model.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { EducationResponse } from './api/education.response.model';
|
||||
|
||||
export interface Education {
|
||||
education: string;
|
||||
description: string;
|
||||
organizer: string;
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
}
|
||||
|
||||
export function mapResponseToEducation(data: EducationResponse): Education {
|
||||
const { utbildning, beskrivning, anordnare, period_from, period_tom } = data;
|
||||
|
||||
return {
|
||||
education: utbildning,
|
||||
description: beskrivning,
|
||||
organizer: anordnare,
|
||||
dateFrom: period_from,
|
||||
dateTo: period_tom,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { HighestEducationResponse } from './api/highest-education.response.model';
|
||||
|
||||
export interface HighestEducation {
|
||||
level: {
|
||||
code: string;
|
||||
description: string;
|
||||
};
|
||||
sunKod: {
|
||||
code: string;
|
||||
description: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function mapResponseToHighestEducation(data: HighestEducationResponse): HighestEducation {
|
||||
const { utbildningsniva, beskrivning_utbildningsniva, sun_kod, beskrivning_sun_kod } = data;
|
||||
|
||||
return {
|
||||
level: {
|
||||
code: utbildningsniva,
|
||||
description: beskrivning_utbildningsniva,
|
||||
},
|
||||
sunKod: {
|
||||
code: sun_kod,
|
||||
description: beskrivning_sun_kod,
|
||||
},
|
||||
};
|
||||
}
|
||||
14
apps/dafa-web/src/app/shared/models/phonenumber.model.ts
Normal file
14
apps/dafa-web/src/app/shared/models/phonenumber.model.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { getPhoneNumberType, PhoneNumberType } from '@dafa-enums/phonenumber-type.enum';
|
||||
import { PhoneNumberResponse } from './api/phonenumber.response.model';
|
||||
|
||||
export interface PhoneNumber {
|
||||
type: PhoneNumberType;
|
||||
number: string;
|
||||
}
|
||||
|
||||
export function mapResponseToPhoneNumber(data: PhoneNumberResponse): PhoneNumber {
|
||||
return {
|
||||
type: getPhoneNumberType(data.telekomtyp),
|
||||
number: `+${data.landskod}${data.nummer_utan_inledande_nolla}`,
|
||||
};
|
||||
}
|
||||
21
apps/dafa-web/src/app/shared/models/work-experience.model.ts
Normal file
21
apps/dafa-web/src/app/shared/models/work-experience.model.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { WorkExperienceResponse } from './api/work-experience.response.model';
|
||||
|
||||
export interface WorkExperience {
|
||||
profession: string;
|
||||
description: string;
|
||||
employer: string;
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
}
|
||||
|
||||
export function mapResponseToWorkExperience(data: WorkExperienceResponse): WorkExperience {
|
||||
const { yrke, beskrivning, arbetsgivare, period_from, period_tom } = data;
|
||||
|
||||
return {
|
||||
profession: yrke,
|
||||
description: beskrivning,
|
||||
employer: arbetsgivare,
|
||||
dateFrom: period_from,
|
||||
dateTo: period_tom,
|
||||
};
|
||||
}
|
||||
152
apps/dafa-web/src/app/shared/services/api/deltagare.service.ts
Normal file
152
apps/dafa-web/src/app/shared/services/api/deltagare.service.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '@dafa-environment';
|
||||
import { ContactInformationResponse } from '@dafa-models/api/contact-information.response.model';
|
||||
import { DeltagareResponse } from '@dafa-models/api/deltagare.response.model';
|
||||
import { DisabilitiesResponse } from '@dafa-models/api/disabilities.response.model';
|
||||
import { DriversLicenseResponse } from '@dafa-models/api/drivers-license.response.model';
|
||||
import { EducationsResponse } from '@dafa-models/api/educations.response.model';
|
||||
import { HighestEducationResponse } from '@dafa-models/api/highest-education.response.model';
|
||||
import { TranslatorResponse } from '@dafa-models/api/translator.response.model';
|
||||
import { WorkExperiencesResponse } from '@dafa-models/api/work-experiences.response.model';
|
||||
import { WorkLanguagesResponse } from '@dafa-models/api/work-languages.response.model';
|
||||
import { ContactInformation, mapResponseToContactInformation } from '@dafa-models/contact-information.model';
|
||||
import { Deltagare, DeltagareCompact, mapResponseToDeltagare } from '@dafa-models/deltagare.model';
|
||||
import { Disability, mapResponseToDisability } from '@dafa-models/disability.model';
|
||||
import { DriversLicense, mapResponseToDriversLicense } from '@dafa-models/drivers-license.model';
|
||||
import { Education, mapResponseToEducation } from '@dafa-models/education.model';
|
||||
import { HighestEducation, mapResponseToHighestEducation } from '@dafa-models/highest-education.model';
|
||||
import { mapResponseToWorkExperience, WorkExperience } from '@dafa-models/work-experience.model';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
const API_HEADERS = { headers: environment.api.headers };
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DeltagareService {
|
||||
private _apiBaseUrl = `${environment.api.url}/customerinfo`;
|
||||
|
||||
private _fetchAllDeltagare: Observable<DeltagareResponse[]> = this.httpClient
|
||||
.get<{ data: DeltagareResponse[] }>(`${this._apiBaseUrl}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
map(response => {
|
||||
return response.data;
|
||||
})
|
||||
);
|
||||
|
||||
public allDeltagare$: Observable<Deltagare[]> = this._fetchAllDeltagare.pipe(
|
||||
map(data => {
|
||||
return data.map(deltagare => mapResponseToDeltagare(deltagare));
|
||||
})
|
||||
);
|
||||
|
||||
private _fetchContactInformation$(id: string): Observable<ContactInformation> {
|
||||
return this.httpClient
|
||||
.get<{ data: ContactInformationResponse }>(`${this._apiBaseUrl}/contact/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(response => mapResponseToContactInformation(response.data)));
|
||||
}
|
||||
private _fetchDriversLicense$(id: string): Observable<DriversLicense> {
|
||||
return this.httpClient
|
||||
.get<{ data: DriversLicenseResponse }>(`${this._apiBaseUrl}/driverlicense/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(response => mapResponseToDriversLicense(response.data)));
|
||||
}
|
||||
private _fetchHighestEducation$(id: string): Observable<HighestEducation> {
|
||||
return this.httpClient
|
||||
.get<{ data: HighestEducationResponse }>(`${this._apiBaseUrl}/education/highest/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(response => mapResponseToHighestEducation(response.data)));
|
||||
}
|
||||
private _fetchEducations$(id: string): Observable<Education[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: EducationsResponse }>(`${this._apiBaseUrl}/education/${id}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
map(response =>
|
||||
response.data.utbildningar
|
||||
? response.data.utbildningar.map(utbildning => mapResponseToEducation(utbildning))
|
||||
: []
|
||||
)
|
||||
);
|
||||
}
|
||||
private _fetchTranslator$(id: string): Observable<string> {
|
||||
return this.httpClient
|
||||
.get<{ data: TranslatorResponse }>(`${this._apiBaseUrl}/translator/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(response => (response.data.sprak ? response.data.sprak.beskrivning : null)));
|
||||
}
|
||||
private _fetchWorkLanguages$(id: string): Observable<string[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: WorkLanguagesResponse }>(`${this._apiBaseUrl}/work/languages/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(response => (response.data.sprak ? response.data.sprak.map(sprak => sprak.beskrivning) : [])));
|
||||
}
|
||||
private _fetchDisabilities$(id: string): Observable<Disability[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: DisabilitiesResponse }>(`${this._apiBaseUrl}/work/disability/${id}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
map(response =>
|
||||
response.data.funktionsnedsattningar
|
||||
? response.data.funktionsnedsattningar.map(funktionsnedsattning =>
|
||||
mapResponseToDisability(funktionsnedsattning)
|
||||
)
|
||||
: []
|
||||
)
|
||||
);
|
||||
}
|
||||
private _fetchWorkExperiences$(id: string): Observable<WorkExperience[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: WorkExperiencesResponse }>(`${this._apiBaseUrl}/work/${id}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
map(response =>
|
||||
response.data.arbetslivserfarenheter
|
||||
? response.data.arbetslivserfarenheter.map(erfarenhet => mapResponseToWorkExperience(erfarenhet))
|
||||
: []
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public deltagareCompact$(id: string): Observable<DeltagareCompact> {
|
||||
return this._fetchContactInformation$(id).pipe(
|
||||
map(contactInformation => ({
|
||||
id,
|
||||
fullName: contactInformation.fullName,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
// 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
|
||||
public deltagare$(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),
|
||||
]).pipe(
|
||||
map(
|
||||
([contactInformation, driversLicense, highestEducation, educations, translator, workLanguages, disabilities]: [
|
||||
ContactInformation,
|
||||
DriversLicense,
|
||||
HighestEducation,
|
||||
Education[],
|
||||
string,
|
||||
string[],
|
||||
Disability[]
|
||||
]) => ({
|
||||
id,
|
||||
...contactInformation,
|
||||
driversLicense,
|
||||
highestEducation,
|
||||
educations,
|
||||
translator,
|
||||
workLanguages,
|
||||
disabilities,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Navigation } from '@dafa-constants/navigation';
|
||||
import { NAVIGATION } from '@dafa-constants/navigation';
|
||||
|
||||
export function mapPathToPageName(path: string): string {
|
||||
return (Navigation[path] || `${path.charAt(0).toUpperCase()}${path.slice(1)}`) as string;
|
||||
return (NAVIGATION[path] || `${path.charAt(0).toUpperCase()}${path.slice(1)}`) as string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user