feat(deltagare): Matched deltagareinformation page to the design. (TV-269)
Squashed commit of the following:
commit f850837fb7629ca9acbd7e9e9d6b8e3a9b356e6d
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Tue Aug 3 12:42:46 2021 +0200
Removed some unnecessary null-checks
commit 2817775633dc9ed546c48cfdd2092eafb0679686
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Tue Aug 3 12:20:58 2021 +0200
Some template changes
commit 9305a1dce85bf177964ec3ad6bb6fe58b7c52332
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Mon Aug 2 15:21:53 2021 +0200
Added some fixes to layout
commit 69d5847a0f0ff4aa9fac39ef202edecc28bcfe0f
Merge: c06d16d fe89d57
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Mon Aug 2 11:36:45 2021 +0200
Merged develop and fixed conflicts
commit c06d16debbe933c1c7f7c927c0f0c32034c6f011
Author: panpe <perham.panbehchi@arbetsformedlingen.se>
Date: Fri Jul 16 12:56:05 2021 +0200
fixed some small issues such as disability was not caught. Connected this to the swagger backend. But it needs some better null checks
commit c6a933b3bc2658816bbab5c8399a2de9d3a0bc4a
Author: Cecilia Varnava <cecilia.varnava@arbetsformedlingen.se>
Date: Mon Jul 12 01:12:35 2021 +0200
TV-269 wip
commit 5e7252d0dbe33ca3aca0e2e82860fa5b799745cc
Author: Cecilia Varnava <cecilia.varnava@arbetsformedlingen.se>
Date: Mon Jul 12 01:03:47 2021 +0200
TV-269 Deltagare - mocked workexperiences
commit f50fa65e2e297f7f551be53a2c181983b53119e4
Author: Cecilia Varnava <cecilia.varnava@arbetsformedlingen.se>
Date: Thu Jul 8 11:15:47 2021 +0200
TV-269 added tabs style and deltagare data
This commit is contained in:
@@ -57,6 +57,7 @@ export class AvropComponent {
|
||||
this.avropService.setHandledareState(handledareId);
|
||||
}
|
||||
|
||||
|
||||
goToStep1(): void {
|
||||
this.avropService.goToStep1();
|
||||
}
|
||||
|
||||
@@ -1,59 +1,161 @@
|
||||
<dafa-layout>
|
||||
<section class="deltagare-card">
|
||||
<digi-typography *ngIf="deltagare$ | async as deltagare; else loadingRef">
|
||||
<div *ngIf="deltagare$ | async as deltagare; else loadingRef">
|
||||
<digi-typography>
|
||||
<header class="deltagare-card__header">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
<h1>{{ deltagare.fullName }}</h1>
|
||||
<h1>Deltagarinformation</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">
|
||||
<digi-navigation-tabs af-aria-label="Deltagarinformation">
|
||||
<digi-navigation-tab af-aria-label="Personuppgifter" af-id="deltagare-card-personuppgifter">
|
||||
<div class="deltagare-card__tab-contents">
|
||||
<div class="deltagare-card__tab-column">
|
||||
<h2>Personuppgifter</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Namn</dt>
|
||||
<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>
|
||||
<dt>Personnummer:</dt>
|
||||
<dd *ngIf="deltagare.ssn; else emptyDD">
|
||||
<dafa-hide-text
|
||||
symbols="********-****"
|
||||
[changingText]="deltagare.ssn"
|
||||
ariaLabelType="personnummer"
|
||||
></dafa-hide-text>
|
||||
</dd>
|
||||
<ng-container *ngFor="let address of deltagare.addresses">
|
||||
<dt>{{address.type}}</dt>
|
||||
<dd>
|
||||
<address>
|
||||
{{ address.street }}<br />
|
||||
{{ address.postalCode }} {{ address.city }}
|
||||
</address>
|
||||
</dd>
|
||||
</ng-container>
|
||||
<dt>Telefon:</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>
|
||||
<dt>Epostadress:</dt>
|
||||
<dd *ngIf="deltagare.email; else emptyDD">{{ deltagare.email }}</dd>
|
||||
</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">
|
||||
<div class="deltagare-card__tab-column">
|
||||
<h2>Särskilda behov</h2>
|
||||
<dl>
|
||||
<dt>Funktionsnedsättningar:</dt>
|
||||
<ng-container *ngIf="deltagare.disabilities; else emptyDD">
|
||||
<dd *ngFor="let disability of deltagare.disabilities">
|
||||
<span>{{ disability.title }}</span>
|
||||
<digi-ng-popover class="deltagare-card__popover" [afRelativeIconSize]="true"
|
||||
>{{ disability.description }}</digi-ng-popover
|
||||
>
|
||||
</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Tolk:</dt>
|
||||
<dd>{{deltagare.translator ? 'Ja ({{deltagare.translator}})' : 'Nej'}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="deltagare-card__tab-column">
|
||||
<h2>Om tjänsten</h2>
|
||||
<dl>
|
||||
<dt>Tillhörande tjänst:</dt>
|
||||
<dd *ngIf="deltagare.service; else emptyDD">{{ deltagare.service }}</dd>
|
||||
<dt>Datum för tjänstens början:</dt>
|
||||
<dd *ngIf="deltagare.startDate; else emptyDD">{{ deltagare.startDate | localDate }}</dd>
|
||||
<dt>Datum för tjänstens slut:</dt>
|
||||
<dd *ngIf="deltagare.endDate; else emptyDD">{{ deltagare.endDate | localDate }}</dd>
|
||||
<dt>Deltagandefrekvens:</dt>
|
||||
<dd *ngIf="deltagare.service?.frequency; else emptyDD">{{ deltagare.service.frequency }}</dd>
|
||||
<dt>Utförande verksamhet:</dt>
|
||||
<dd *ngIf="deltagare.service?.organisation; else emptyDD">{{ deltagare.service.organisation }}</dd>
|
||||
<dt>Utförande adress:</dt>
|
||||
<dd
|
||||
*ngIf="
|
||||
deltagare.service?.organisation &&
|
||||
deltagare.service?.organisation.adress;
|
||||
else emptyDD
|
||||
"
|
||||
>
|
||||
{{ deltagare.service.organisation.adress }}
|
||||
</dd>
|
||||
<dt>Genomförandereferens:</dt>
|
||||
<dd *ngIf="deltagare.service?.reference; else emptyDD">{{ deltagare.service.reference }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="deltagare-card__column">
|
||||
<h2>Matchningsuppgifter</h2>
|
||||
</div>
|
||||
|
||||
<div class="deltagare-card__column">
|
||||
</digi-navigation-tab>
|
||||
<digi-navigation-tab af-aria-label="Matchningsuppgifter" af-id="deltagare-card-matchningsuppgifter">
|
||||
<div class="deltagare-card__tab-contents">
|
||||
<div class="deltagare-card__tab-column">
|
||||
<h2>Arbetslivserfarenhet</h2>
|
||||
<dl>
|
||||
<dt>Arbetsgivare:</dt>
|
||||
<ng-container *ngIf="firstVisibleWorkExperiences$ | async as firstVisibleWorkExperiences;">
|
||||
<ng-container *ngIf="firstVisibleWorkExperiences.length; else emptyDD">
|
||||
<dd *ngFor="let workExperience of firstVisibleWorkExperiences">
|
||||
<digi-typography-time [afDateTime]="workExperience.dateFrom"></digi-typography-time>
|
||||
- <digi-typography-time [afDateTime]="workExperience.dateTo"></digi-typography-time><br />
|
||||
{{ workExperience.employer }}<br />
|
||||
{{ workExperience.profession }}<br />
|
||||
{{ workExperience.description }}
|
||||
</dd>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="hiddenWorkExperiences$ | async as hiddenWorkExperiences">
|
||||
<digi-ng-layout-expansion-panel
|
||||
class="deltagare-card__accordion"
|
||||
[afExpanded]="accordionExpanded"
|
||||
(click)="toggleAccordionExpanded()"
|
||||
*ngIf="hiddenWorkExperiences.length"
|
||||
>
|
||||
<span class="deltagare-card__accordion-trigger" data-slot-trigger
|
||||
>{{ accordionExpanded ? 'Dölj' : 'Visa' }} fler arbetsgivare</span
|
||||
>
|
||||
<dd *ngFor="let workExperience of hiddenWorkExperiences">
|
||||
<digi-typography-time [afDateTime]="workExperience.dateFrom"></digi-typography-time> -
|
||||
<digi-typography-time [afDateTime]="workExperience.dateTo"></digi-typography-time><br />
|
||||
{{ workExperience.employer }}<br />
|
||||
{{ workExperience.profession }}<br />
|
||||
{{ workExperience.description }}
|
||||
</dd>
|
||||
</digi-ng-layout-expansion-panel>
|
||||
</ng-container>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="deltagare-card__tab-column-education">
|
||||
<h2>Utbildning</h2>
|
||||
<dl>
|
||||
<dt>Utbildningar:</dt>
|
||||
<ng-container *ngIf="deltagare.educations.length; else emptyDD">
|
||||
<dd *ngFor="let education of deltagare.educations">
|
||||
<digi-typography-time [afDateTime]="education.dateFrom"></digi-typography-time> -
|
||||
<digi-typography-time [afDateTime]="education.dateFrom"></digi-typography-time><br />
|
||||
{{ education.organizer }}<br />
|
||||
{{ education.education}}<br />
|
||||
{{ education.description }}
|
||||
</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Högsta utbildningsnivå:</dt>
|
||||
<dd *ngIf="deltagare.highestEducation.level; else emptyDD">
|
||||
{{ deltagare.highestEducation.level.description }}: {{ deltagare.highestEducation.sunKod.description
|
||||
}}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Språk jag kan använda på jobbet:</dt>
|
||||
<dd *ngIf="deltagare.workLanguages.length else emptyDD">{{ deltagare.workLanguages.join(', ')}}</dd>
|
||||
</dl>
|
||||
<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">
|
||||
<dd>{{deltagare.driversLicense.licenses ? 'Ja' : 'Nej'}}</dd>
|
||||
<ng-container *ngIf="deltagare.driversLicense.licenses">
|
||||
<dt>Körkortsklasser</dt>
|
||||
<dd>{{deltagare.driversLicense.licenses.join(', ')}}</dd>
|
||||
<dt>Tillgång till bil</dt>
|
||||
@@ -62,11 +164,14 @@
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</digi-navigation-tab>
|
||||
</digi-navigation-tabs>
|
||||
</digi-typography>
|
||||
|
||||
<footer class="deltagare-card__footer">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
</footer>
|
||||
</digi-typography>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #loadingRef>
|
||||
|
||||
@@ -1,45 +1,55 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.deltagare-card {
|
||||
&__contents {
|
||||
&__tab-contents {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $digi--layout--gutter--xl $digi--layout--gutter--l;
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
gap: $digi--layout--gutter--l;
|
||||
margin: 0 $digi--layout--gutter--l;
|
||||
}
|
||||
|
||||
&__column {
|
||||
width: 100%;
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
&__tab-column {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.5rem 2rem;
|
||||
}
|
||||
|
||||
dt,
|
||||
dd {
|
||||
margin: 0;
|
||||
margin: 0 0 var(--digi--layout--gutter--xs);
|
||||
|
||||
+ dd {
|
||||
margin-top: var(--digi--layout--gutter);
|
||||
}
|
||||
}
|
||||
|
||||
dt {
|
||||
grid-column: 1;
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
dd {
|
||||
grid-column: 2;
|
||||
&__accordion {
|
||||
max-width: 80%;
|
||||
min-width: 250px;
|
||||
|
||||
dd:first-of-type {
|
||||
margin-top: var(--digi--layout--gutter);
|
||||
}
|
||||
}
|
||||
|
||||
&__accordion-trigger {
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
&__popover {
|
||||
display: inline-block;
|
||||
margin-left: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__header,
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
margin-top: $digi--layout--gutter--l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ 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 { WorkExperience } from '@dafa-models/work-experience.model';
|
||||
import { DeltagareService } from '@dafa-services/api/deltagare.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
@@ -19,7 +20,19 @@ export class DeltagareCardComponent {
|
||||
deltagare$: Observable<Deltagare> = this._deltagareId$.pipe(
|
||||
switchMap(deltagareId => this.deltagaresService.deltagare$(deltagareId))
|
||||
);
|
||||
firstVisibleWorkExperiences$: Observable<WorkExperience[]> = this.deltagare$.pipe(
|
||||
map(deltagare => deltagare.workExperiences.slice(0, 2))
|
||||
);
|
||||
hiddenWorkExperiences$: Observable<WorkExperience[]> = this.deltagare$.pipe(
|
||||
map(deltagare => deltagare.workExperiences.slice(2))
|
||||
);
|
||||
|
||||
iconType = IconType;
|
||||
accordionExpanded = false;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private deltagaresService: DeltagareService) {}
|
||||
|
||||
toggleAccordionExpanded(): void {
|
||||
this.accordionExpanded = !this.accordionExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { DigiNgLayoutExpansionPanelModule } from '@af/digi-ng/_layout/layout-expansion-panel';
|
||||
import { DigiNgLinkInternalModule } from '@af/digi-ng/_link/link-internal';
|
||||
import { DigiNgNavigationTabModule } from '@af/digi-ng/_navigation/navigation-tab';
|
||||
import { DigiNgNavigationTabsModule } from '@af/digi-ng/_navigation/navigation-tabs';
|
||||
import { DigiNgPopoverModule } from '@af/digi-ng/_popover/popover';
|
||||
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 '@dafa-shared/components/back-link/back-link.module';
|
||||
import { HideTextModule } from '@dafa-shared/components/hide-text/hide-text.module';
|
||||
import { IconModule } from '@dafa-shared/components/icon/icon.module';
|
||||
import { LayoutModule } from '@dafa-shared/components/layout/layout.module';
|
||||
import { LocalDatePipeModule } from '@dafa-shared/pipes/local-date/local-date.module';
|
||||
import { DeltagareCardComponent } from './deltagare-card.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -17,6 +24,13 @@ import { DeltagareCardComponent } from './deltagare-card.component';
|
||||
DigiNgLinkInternalModule,
|
||||
IconModule,
|
||||
BackLinkModule,
|
||||
DigiNgNavigationTabsModule,
|
||||
DigiNgNavigationTabModule,
|
||||
DigiNgLayoutExpansionPanelModule,
|
||||
LocalDatePipeModule,
|
||||
HideTextModule,
|
||||
DigiNgSkeletonBaseModule,
|
||||
DigiNgPopoverModule,
|
||||
],
|
||||
exports: [DeltagareCardComponent],
|
||||
})
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
<digi-table af-variation="secondary">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('fullName')">
|
||||
Namn
|
||||
<ng-container *ngIf="sortBy?.key === 'fullName'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('errandNumber')">
|
||||
Ärendenummer
|
||||
<ng-container *ngIf="sortBy?.key === 'errandNumber'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('service')">
|
||||
Tjänst
|
||||
<ng-container *ngIf="sortBy?.key === 'service'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('startDate')">
|
||||
Startdatum
|
||||
<ng-container *ngIf="sortBy?.key === 'startDate'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('endDate')">
|
||||
Slutdatum
|
||||
<ng-container *ngIf="sortBy?.key === 'endDate'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="participants-list__column-head">
|
||||
<button class="participants-list__sort-button" (click)="handleSort('handleBefore')">
|
||||
Hantera innan
|
||||
<ng-container *ngIf="sortBy?.key === 'handleBefore'">
|
||||
<digi-icon-caret-up
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'asc'"
|
||||
></digi-icon-caret-up>
|
||||
<digi-icon-caret-down
|
||||
class="participants-list__sort-icon"
|
||||
*ngIf="sortBy.order === 'desc'"
|
||||
></digi-icon-caret-down>
|
||||
</ng-container>
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let participant of pagedParticipants">
|
||||
<th scope="row">
|
||||
<a [routerLink]="participant.id" class="participants-list__link">
|
||||
{{ participant.fullName }}
|
||||
</a>
|
||||
</th>
|
||||
<td>{{ participant.errandNumber }}</td>
|
||||
<td>{{ participant.service }}</td>
|
||||
<td>{{ participant.startDate | date: 'yyyy-MM-dd' }}</td>
|
||||
<td>{{ participant.endDate | date: 'yyyy-MM-dd' }}</td>
|
||||
<td>{{ participant.handleBefore | date: 'yyyy-MM-dd' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</digi-table>
|
||||
|
||||
<digi-navigation-pagination
|
||||
*ngIf="participants.length > pagedParticipants.length"
|
||||
class="participants-list__pagination"
|
||||
[afTotalPages]="totalPages"
|
||||
[afCurrentResultStart]="currentResultStart"
|
||||
[afCurrentResultEnd]="currentResultEnd"
|
||||
[afTotalResults]="participants.length"
|
||||
(afOnPageChange)="handlePagination($event.detail)"
|
||||
af-result-name="deltagare"
|
||||
></digi-navigation-pagination>
|
||||
@@ -1,35 +0,0 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.participants-list {
|
||||
&__column-head {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__sort-button {
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: var(--digi--layout--gutter--s) $digi--layout--gutter--l var(--digi--layout--gutter--s)
|
||||
var(--digi--layout--gutter);
|
||||
margin: 0;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--digi--layout--gutter);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&__sort-icon {
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
&__pagination {
|
||||
display: block;
|
||||
margin-top: var(--digi--layout--gutter);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import { DigiNgTableModule } from '@af/digi-ng/_table/table';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { ParticipantsListComponent } from './participants-list.component';
|
||||
|
||||
describe('ParticipantsListComponent', () => {
|
||||
let component: ParticipantsListComponent;
|
||||
let fixture: ComponentFixture<ParticipantsListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ParticipantsListComponent],
|
||||
imports: [RouterTestingModule, DigiNgTableModule],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ParticipantsListComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.participants = [];
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Participant } from '@dafa-models/participant.model';
|
||||
import { Sort } from '@dafa-models/sort.model';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-participants-list',
|
||||
templateUrl: './participants-list.component.html',
|
||||
styleUrls: ['./participants-list.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ParticipantsListComponent {
|
||||
@Input() participants: Participant[];
|
||||
@Input() sortBy: Sort<keyof Participant> | null;
|
||||
@Output() sorted = new EventEmitter<keyof Participant>();
|
||||
|
||||
private _currentPage$ = new BehaviorSubject<number>(1);
|
||||
private _participantsPerPage = 10;
|
||||
|
||||
get currentPage(): number {
|
||||
return this._currentPage$.getValue();
|
||||
}
|
||||
|
||||
get totalPages(): number {
|
||||
return Math.ceil(this.participants.length / this._participantsPerPage);
|
||||
}
|
||||
|
||||
get pagedParticipants(): Participant[] {
|
||||
return [...this.participants].slice(this.currentResultStart - 1, this.currentResultEnd - 1);
|
||||
}
|
||||
|
||||
get currentResultStart(): number {
|
||||
return (this.currentPage - 1) * this._participantsPerPage + 1;
|
||||
}
|
||||
|
||||
get currentResultEnd(): number {
|
||||
return this.currentResultStart + this._participantsPerPage;
|
||||
}
|
||||
|
||||
handleSort(key: keyof Participant): void {
|
||||
this.sorted.emit(key);
|
||||
}
|
||||
|
||||
handlePagination(page: number): void {
|
||||
this._currentPage$.next(page);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { DigiNgTableModule } from '@af/digi-ng/_table/table';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ParticipantsListComponent } from './participants-list.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ParticipantsListComponent],
|
||||
imports: [CommonModule, RouterModule, DigiNgTableModule],
|
||||
exports: [ParticipantsListComponent],
|
||||
})
|
||||
export class ParticipantsListModule {}
|
||||
@@ -1,202 +0,0 @@
|
||||
<dafa-layout>
|
||||
<section class="participant-card">
|
||||
<div *ngIf="detailedParticipantData$ | async as detailedParticipantData; else loadingRef">
|
||||
<header class="participant-card__header">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
<h1>Deltagarinformation</h1>
|
||||
</header>
|
||||
|
||||
<digi-ng-navigation-tabs afTablistLabel="Deltagarinformation">
|
||||
<digi-ng-navigation-tab afLabel="Personuppgifter" afId="tab1">
|
||||
<digi-ng-typography-base>
|
||||
<div class="participant-card__tab-contents">
|
||||
<div class="participant-card__tab-column">
|
||||
<h2>Personuppgifter</h2>
|
||||
<dl>
|
||||
<dt>Namn:</dt>
|
||||
<dd *ngIf="detailedParticipantData.fullName; else emptyDD">{{ detailedParticipantData.fullName }}</dd>
|
||||
<dt>Personnummer:</dt>
|
||||
<dd *ngIf="detailedParticipantData.ssn; else emptyDD">
|
||||
<dafa-hide-text
|
||||
symbols="********-****"
|
||||
[changingText]="detailedParticipantData.ssn"
|
||||
ariaLabelType="personnummer"
|
||||
></dafa-hide-text>
|
||||
</dd>
|
||||
<dt>Folkbokföringsadress:</dt>
|
||||
<dd *ngIf="detailedParticipantData.address; else emptyDD">
|
||||
{{ detailedParticipantData.address.street }} + ' ' + {{ detailedParticipantData.address.number }},
|
||||
{{ detailedParticipantData.address.postalcode }} + ' ' + {{ detailedParticipantData.address.city }}
|
||||
</dd>
|
||||
<dt>Postadress:</dt>
|
||||
<dd *ngIf="detailedParticipantData.postalAddress; else emptyDD">
|
||||
{{ detailedParticipantData.postalAddress.street }} + ' ' + {{
|
||||
detailedParticipantData.postalAddress.number }}, {{ detailedParticipantData.postalAddress.postalcode
|
||||
}} + ' ' + {{ detailedParticipantData.postalAddress.city }}
|
||||
</dd>
|
||||
<dt>Telefon:</dt>
|
||||
<dd *ngIf="detailedParticipantData.phoneMobile; else emptyDD"></dd>
|
||||
<dd>{{ detailedParticipantData.phoneMobile }}</dd>
|
||||
<dt>Mailadress:</dt>
|
||||
<dd *ngIf="detailedParticipantData.email; else emptyDD"></dd>
|
||||
<dd>{{ detailedParticipantData.email }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="participant-card__tab-column">
|
||||
<h2>Särskilda behov</h2>
|
||||
<dl>
|
||||
<dt>Funktionsnedsättningar</dt>
|
||||
<ng-container *ngIf="detailedParticipantData.disabilities; else emptyDD">
|
||||
<!--TODO när api klart: disabilities.length-->
|
||||
<dd *ngFor="let disability of detailedParticipantData.disabilities">
|
||||
{{ disability.name }} <br />
|
||||
{{ disability.description }}
|
||||
</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Tolk</dt>
|
||||
<dd *ngIf="detailedParticipantData.interpretorLanguage; else noDD">
|
||||
Ja ( {{ detailedParticipantData.interpretorLanguage }} )
|
||||
</dd>
|
||||
<dt>Språkstöd</dt>
|
||||
<dd *ngIf="detailedParticipantData.supportLanguage; else noDD">
|
||||
Ja ( {{ detailedParticipantData.supportLanguage }} )
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="participant-card__tab-column">
|
||||
<h2>Om tjänsten</h2>
|
||||
<dl>
|
||||
<dt>Tillhörande tjänst</dt>
|
||||
<dd *ngIf="detailedParticipantData.service; else emptyDD">{{ detailedParticipantData.service }}</dd>
|
||||
<dt>Datum för tjänstens början</dt>
|
||||
<dd *ngIf="detailedParticipantData.startDate; else emptyDD">
|
||||
{{ detailedParticipantData.startDate | localDate }}
|
||||
</dd>
|
||||
<dt>Datum för tjänstens slut</dt>
|
||||
<dd *ngIf="detailedParticipantData.endDate; else emptyDD">
|
||||
{{ detailedParticipantData.endDate | localDate }}
|
||||
</dd>
|
||||
<dt>Deltagandefrekvens</dt>
|
||||
<dd *ngIf="detailedParticipantData.service.frequency; else emptyDD">
|
||||
{{ detailedParticipantData.service.frequency }}
|
||||
</dd>
|
||||
<dt>Utförande verksamhet</dt>
|
||||
<dd *ngIf="detailedParticipantData.service.organisation; else emptyDD">
|
||||
{{ detailedParticipantData.service.organisation }}
|
||||
</dd>
|
||||
<dt>Utförande adress</dt>
|
||||
<dd
|
||||
*ngIf="
|
||||
detailedParticipantData.service.organisation &&
|
||||
detailedParticipantData.service.organisation.adress;
|
||||
else emptyDD
|
||||
"
|
||||
>
|
||||
{{ detailedParticipantData.service.organisation.adress }}
|
||||
</dd>
|
||||
<dt>Genomförandereferens</dt>
|
||||
<dd *ngIf="detailedParticipantData.service.reference; else emptyDD">
|
||||
{{ detailedParticipantData.service.reference }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</digi-ng-typography-base>
|
||||
</digi-ng-navigation-tab>
|
||||
<digi-ng-navigation-tab afLabel="Matchningsuppgifter" afId="tab2">
|
||||
<digi-ng-typography-base>
|
||||
<div class="participant-card__tab-contents">
|
||||
<div class="participant-card__tab-column">
|
||||
<h2>Arbetslivserfarenhet</h2>
|
||||
<dl>
|
||||
<dt>Arbetsgivare</dt>
|
||||
<ng-container *ngIf="detailedParticipantData.workExperiences; else emptyDD">
|
||||
<!--TODO när api finns: workExperiences.length-->
|
||||
<dd *ngFor="let workExperience of detailedParticipantData.workExperiences; index as i">
|
||||
<!-- TODO: workExperiences.length. index 0-2-->
|
||||
{{ workExperience.dateFrom | localDate }} - {{ workExperience.dateTo | localDate }} <br />
|
||||
{{ workExperience.company }} <br />
|
||||
{{ workExperience.direction }} <br />
|
||||
{{ workExperience.description }}
|
||||
</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
<div class="participant-card__employers-expansion">
|
||||
<digi-ng-layout-expansion-panel [afExpanded]="accordionExpanded" (click)="toggleAccordionExpanded()">
|
||||
<digi-ng-typography-base
|
||||
data-slot-trigger
|
||||
class="participant-card__employers-expansion__trigger-text"
|
||||
>
|
||||
{{ accordionExpanded ? 'Dölj' : 'Visa' }} fler arbetsgivare
|
||||
</digi-ng-typography-base>
|
||||
<digi-ng-typography-base>
|
||||
<dl>
|
||||
<dd *ngFor="let workExperience of detailedParticipantData.workExperiences">
|
||||
<!-- TODO: workExperiences.length. Från index 3 -->
|
||||
{{ workExperience.dateFrom | localDate }} - {{ workExperience.dateTo | localDate }} <br />
|
||||
{{ workExperience.company }} <br />
|
||||
{{ workExperience.direction }} <br />
|
||||
{{ workExperience.description }}
|
||||
</dd>
|
||||
</dl>
|
||||
</digi-ng-typography-base>
|
||||
</digi-ng-layout-expansion-panel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="participant-card__tab-column-education">
|
||||
<h2>Utbildning</h2>
|
||||
<dl>
|
||||
<dt>Utbildningar</dt>
|
||||
<ng-container *ngIf="detailedParticipantData.educations; else emptyDD">
|
||||
<!--TODO när api finns: educations.length-->
|
||||
<dd *ngFor="let education of detailedParticipantData.educations">
|
||||
{{ education.dateFrom | localDate }} - {{ education.dateTo | localDate }} <br />
|
||||
{{ education.organizer }} <br />
|
||||
{{ education.direction }} <br />
|
||||
{{ education.description }} <br />
|
||||
</dd>
|
||||
</ng-container>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Högsta utbildningsnivå</dt>
|
||||
<dd *ngIf="detailedParticipantData.highestEduction; else emptyDD">
|
||||
{{ detailedParticipantData.highestEduction }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Körkortsinformation</dt>
|
||||
<dd>Innehar körkort ( {{ detailedParticipantData.driversLicenses ? 'Ja' : 'Nej' }} )</dd>
|
||||
<dd *ngIf="detailedParticipantData.driversLicenses">
|
||||
<!-- TODO när api finns: .length -->
|
||||
Körkortsklasser ( {{ detailedParticipantData.driversLicenses.join(', ') }} )<br />
|
||||
Tillgång till bil ( {{ detailedParticipantData.accessToCar ? 'Ja' : 'Nej' }} )
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</digi-ng-typography-base>
|
||||
</digi-ng-navigation-tab>
|
||||
</digi-ng-navigation-tabs>
|
||||
<footer class="participant-card__footer">
|
||||
<dafa-back-link [route]="['/deltagare']">Tillbaka till deltagarlistan</dafa-back-link>
|
||||
</footer>
|
||||
</div>
|
||||
</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>
|
||||
<ng-template #noDD>
|
||||
<dd>
|
||||
<span>Nej</span>
|
||||
</dd>
|
||||
</ng-template>
|
||||
</dafa-layout>
|
||||
@@ -1,51 +0,0 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.participant-card {
|
||||
&__tab-contents {
|
||||
display: flex;
|
||||
gap: $digi--layout--gutter--xl $digi--layout--gutter--l;
|
||||
margin-left: $digi--layout--gutter--l;
|
||||
|
||||
h2 {
|
||||
margin-top: $digi--layout--gutter--l;
|
||||
}
|
||||
}
|
||||
|
||||
&__tab-column {
|
||||
flex: 1;
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
}
|
||||
|
||||
&__tab-column-education {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: block;
|
||||
}
|
||||
|
||||
dt,
|
||||
dd {
|
||||
margin: 0;
|
||||
padding-bottom: var(--digi--layout--gutter--xs);
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: var(--digi--typography--font-weight--semibold);
|
||||
}
|
||||
|
||||
&__employers-expansion {
|
||||
width: 70%;
|
||||
|
||||
&__trigger-text {
|
||||
font-weight: var(--digi--typography--font-weight--bold);
|
||||
}
|
||||
}
|
||||
|
||||
&__header,
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { IconType } from '@dafa-enums/icon-type.enum';
|
||||
import { Participant } from '@dafa-models/participant.model';
|
||||
import { ParticipantsService } from '@dafa-services/api/participants.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-participant-card',
|
||||
templateUrl: './participant-card.component.html',
|
||||
styleUrls: ['./participant-card.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ParticipantCardComponent {
|
||||
private _participantId$: Observable<string> = this.activatedRoute.params.pipe(
|
||||
map(({ participantId }) => participantId as string)
|
||||
);
|
||||
detailedParticipantData$: Observable<Participant> = this._participantId$.pipe(
|
||||
switchMap(participantId => this.participantsService.fetchDetailedParticipantData$(participantId))
|
||||
);
|
||||
iconType = IconType;
|
||||
accordionExpanded = false;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private participantsService: ParticipantsService) {}
|
||||
|
||||
toggleAccordionExpanded(): void {
|
||||
this.accordionExpanded = !this.accordionExpanded;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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 { ParticipantCardComponent } from './participant-card.component';
|
||||
import { HideTextModule } from '@dafa-shared/components/hide-text/hide-text.module';
|
||||
import { DigiNgNavigationTabsModule } from '@af/digi-ng/_navigation/navigation-tabs';
|
||||
import { DigiNgNavigationTabModule } from '@af/digi-ng/_navigation/navigation-tab';
|
||||
import { DigiNgLayoutExpansionPanelModule } from '@af/digi-ng/_layout/layout-expansion-panel';
|
||||
import { DigiNgTypographyBaseModule } from '@af/digi-ng/_typography/typography-base';
|
||||
import { LocalDatePipeModule } from '@dafa-shared/pipes/local-date/local-date.module';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ParticipantCardComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{ path: '', component: ParticipantCardComponent }]),
|
||||
LayoutModule,
|
||||
DigiNgLinkInternalModule,
|
||||
IconModule,
|
||||
BackLinkModule,
|
||||
HideTextModule,
|
||||
DigiNgNavigationTabsModule,
|
||||
DigiNgNavigationTabModule,
|
||||
DigiNgLayoutExpansionPanelModule,
|
||||
DigiNgTypographyBaseModule,
|
||||
LocalDatePipeModule,
|
||||
],
|
||||
exports: [ParticipantCardComponent],
|
||||
})
|
||||
export class ParticipantCardModule {}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ParticipantsComponent } from './participants.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ParticipantsComponent,
|
||||
},
|
||||
{
|
||||
path: ':participantId',
|
||||
loadChildren: () => import('./pages/participant-card/participant-card.module').then(m => m.ParticipantCardModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ParticipantsRoutingModule {}
|
||||
@@ -1,44 +0,0 @@
|
||||
<dafa-layout>
|
||||
<section class="participants">
|
||||
<digi-typography>
|
||||
<h1>Mina deltagare</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam magna neque, interdum vel massa eget, condimentum
|
||||
rutrum velit. Sed vitae ullamcorper sem. Aliquam malesuada nunc sed purus mollis scelerisque. Curabitur bibendum
|
||||
leo quis ante porttitor tincidunt. Nam tincidunt imperdiet tortor eu suscipit. Maecenas ut dui est.
|
||||
</p>
|
||||
</digi-typography>
|
||||
|
||||
<form class="participants__search-wrapper" (ngSubmit)="handleSearchSubmit()">
|
||||
<digi-form-input-search
|
||||
af-label="Sök deltagare"
|
||||
af-label-description="Sök på namn eller ärendenummer"
|
||||
(afOnInput)="handleSearchInput($event)"
|
||||
></digi-form-input-search>
|
||||
</form>
|
||||
|
||||
<section class="participants__list">
|
||||
<h2>Pågående tjänst</h2>
|
||||
<dafa-participants-list
|
||||
*ngIf="activeParticipants$ | async as participants; else loadingRef"
|
||||
[participants]="participants"
|
||||
[sortBy]="activeParticipantsSortBy$ | async"
|
||||
(sorted)="handleActiveParticipantsSort($event)"
|
||||
></dafa-participants-list>
|
||||
</section>
|
||||
|
||||
<section class="participants__list">
|
||||
<h2>För uppföljning</h2>
|
||||
<dafa-participants-list
|
||||
*ngIf="followUpParticipants$ | async as participants; else loadingRef"
|
||||
[participants]="participants"
|
||||
[sortBy]="followUpParticipantsSortBy$ | async"
|
||||
(sorted)="handleFollowUpParticipantsSort($event)"
|
||||
></dafa-participants-list>
|
||||
</section>
|
||||
|
||||
<ng-template #loadingRef>
|
||||
<digi-ng-skeleton-base [afCount]="3" afText="Laddar deltagare"></digi-ng-skeleton-base>
|
||||
</ng-template>
|
||||
</section>
|
||||
</dafa-layout>
|
||||
@@ -1,9 +0,0 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.participants {
|
||||
&__search-wrapper {
|
||||
max-width: var(--digi--typography--text--max-width);
|
||||
margin-top: $digi--layout--gutter--l;
|
||||
margin-bottom: $digi--layout--gutter--xl;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { ParticipantsListModule } from './components/participants-list/participants-list.module';
|
||||
import { ParticipantsComponent } from './participants.component';
|
||||
|
||||
describe('ParticipantsComponent', () => {
|
||||
let component: ParticipantsComponent;
|
||||
let fixture: ComponentFixture<ParticipantsComponent>;
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
void TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ParticipantsComponent],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule, DigiNgSkeletonBaseModule, ParticipantsListModule],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ParticipantsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Participant } from '@dafa-models/participant.model';
|
||||
import { Sort } from '@dafa-models/sort.model';
|
||||
import { ParticipantsService } from '@dafa-services/api/participants.service';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-participants',
|
||||
templateUrl: './participants.component.html',
|
||||
styleUrls: ['./participants.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ParticipantsComponent {
|
||||
private _searchValue$ = new BehaviorSubject<string>('');
|
||||
activeParticipants$: Observable<Participant[]> = this.participantsService.activeParticipants$;
|
||||
followUpParticipants$: Observable<Participant[]> = this.participantsService.followUpParticipants$;
|
||||
activeParticipantsSortBy$: Observable<Sort<keyof Participant> | null> = this.participantsService
|
||||
.activeParticipantsSortBy$;
|
||||
followUpParticipantsSortBy$: Observable<Sort<keyof Participant> | null> = this.participantsService
|
||||
.followUpParticipantsSortBy$;
|
||||
|
||||
constructor(private participantsService: ParticipantsService) {}
|
||||
|
||||
get searchValue(): string {
|
||||
return this._searchValue$.getValue();
|
||||
}
|
||||
|
||||
handleSearchSubmit(): void {
|
||||
this.participantsService.setSearchFilter(this.searchValue);
|
||||
}
|
||||
|
||||
handleSearchInput($event: CustomEvent): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
this._searchValue$.next($event.detail.target.value);
|
||||
}
|
||||
|
||||
handleActiveParticipantsSort(key: keyof Participant): void {
|
||||
this.participantsService.setActiveParticipantsSortKey(key);
|
||||
}
|
||||
|
||||
handleFollowUpParticipantsSort(key: keyof Participant): void {
|
||||
this.participantsService.setFollowUpParticipantsSortKey(key);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { LayoutModule } from '@dafa-shared/components/layout/layout.module';
|
||||
import { ParticipantsListModule } from './components/participants-list/participants-list.module';
|
||||
import { ParticipantsRoutingModule } from './participants-routing.module';
|
||||
import { ParticipantsComponent } from './participants.component';
|
||||
|
||||
@NgModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [ParticipantsComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
LayoutModule,
|
||||
ParticipantsRoutingModule,
|
||||
FormsModule,
|
||||
DigiNgSkeletonBaseModule,
|
||||
ParticipantsListModule,
|
||||
],
|
||||
})
|
||||
export class ParticipantsModule {}
|
||||
@@ -4,6 +4,7 @@ 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 { WorkExperiencesResponse } from './work-experiences.response.model';
|
||||
import { WorkLanguagesResponse } from './work-languages.response.model';
|
||||
|
||||
export interface DeltagareResponse {
|
||||
@@ -15,4 +16,5 @@ export interface DeltagareResponse {
|
||||
translator: TranslatorResponse;
|
||||
workLanguages: WorkLanguagesResponse;
|
||||
disabilities: DisabilitiesResponse;
|
||||
workExperiences: WorkExperiencesResponse;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export interface DisabilityResponse {
|
||||
|
||||
kod: string;
|
||||
funktionsnedsattning: string;
|
||||
beskrivning: string;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { DriversLicense, mapResponseToDriversLicense } from './drivers-license.m
|
||||
import { Education, mapResponseToEducation } from './education.model';
|
||||
import { HighestEducation, mapResponseToHighestEducation } from './highest-education.model';
|
||||
import { PhoneNumber } from './phonenumber.model';
|
||||
import { mapResponseToWorkExperience, WorkExperience } from './work-experience.model';
|
||||
|
||||
export interface DeltagareCompact {
|
||||
id: string;
|
||||
@@ -25,11 +26,21 @@ export interface Deltagare extends DeltagareCompact {
|
||||
translator: string;
|
||||
disabilities: Disability[];
|
||||
workLanguages: string[];
|
||||
// workExperiences: WorkExperience[]; // TODO: Missing from API
|
||||
workExperiences: WorkExperience[];
|
||||
}
|
||||
|
||||
export function mapResponseToDeltagare(data: DeltagareResponse): Deltagare {
|
||||
const { id, contact, driverlicense, highestEducation, educations, translator, workLanguages, disabilities } = data;
|
||||
const {
|
||||
id,
|
||||
contact,
|
||||
driverlicense,
|
||||
highestEducation,
|
||||
educations,
|
||||
translator,
|
||||
workLanguages,
|
||||
disabilities,
|
||||
workExperiences,
|
||||
} = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
@@ -41,5 +52,8 @@ export function mapResponseToDeltagare(data: DeltagareResponse): Deltagare {
|
||||
workLanguages: workLanguages && workLanguages.sprak.map(language => language.beskrivning),
|
||||
disabilities:
|
||||
disabilities && disabilities.funktionsnedsattningar.map(disability => mapResponseToDisability(disability)),
|
||||
workExperiences:
|
||||
workExperiences &&
|
||||
workExperiences.arbetslivserfarenheter.map(workExperience => mapResponseToWorkExperience(workExperience)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ export interface Disability {
|
||||
|
||||
export function mapResponseToDisability(data: DisabilityResponse): Disability {
|
||||
const { kod, funktionsnedsattning, beskrivning } = data;
|
||||
|
||||
return {
|
||||
code: kod,
|
||||
title: funktionsnedsattning, // TODO: Needed from API
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { formatToIsoDate } from '@dafa-utils/format-to-iso-date.util';
|
||||
import { formatToDate } from '@dafa-utils/format-to-date.util';
|
||||
import { EducationResponse } from './api/education.response.model';
|
||||
|
||||
export interface Education {
|
||||
education: string;
|
||||
description: string;
|
||||
organizer: string;
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
dateFrom: Date;
|
||||
dateTo: Date;
|
||||
}
|
||||
|
||||
export function mapResponseToEducation(data: EducationResponse): Education {
|
||||
@@ -16,7 +16,7 @@ export function mapResponseToEducation(data: EducationResponse): Education {
|
||||
education: utbildning,
|
||||
description: beskrivning,
|
||||
organizer: anordnare,
|
||||
dateFrom: formatToIsoDate(period_from),
|
||||
dateTo: formatToIsoDate(period_tom),
|
||||
dateFrom: formatToDate(period_from),
|
||||
dateTo: formatToDate(period_tom),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface UserApiResponseData {
|
||||
|
||||
export function mapUserApiResponseToUser(data: UserApiResponseData): User {
|
||||
const { id, firstName, lastName, ssn, organizations, authorizations } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
firstName,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { formatToIsoDate } from '@dafa-utils/format-to-iso-date.util';
|
||||
import { formatToDate } from '@dafa-utils/format-to-date.util';
|
||||
import { WorkExperienceResponse } from './api/work-experience.response.model';
|
||||
|
||||
export interface WorkExperience {
|
||||
profession: string;
|
||||
description: string;
|
||||
employer: string;
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
dateFrom: Date;
|
||||
dateTo: Date;
|
||||
}
|
||||
|
||||
export function mapResponseToWorkExperience(data: WorkExperienceResponse): WorkExperience {
|
||||
@@ -16,7 +16,7 @@ export function mapResponseToWorkExperience(data: WorkExperienceResponse): WorkE
|
||||
profession: yrke,
|
||||
description: beskrivning,
|
||||
employer: arbetsgivare,
|
||||
dateFrom: formatToIsoDate(period_from),
|
||||
dateTo: formatToIsoDate(period_tom),
|
||||
dateFrom: formatToDate(period_from),
|
||||
dateTo: formatToDate(period_tom),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ 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, tap } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
const API_HEADERS = { headers: environment.api.headers };
|
||||
|
||||
@@ -30,16 +30,10 @@ export class DeltagareService {
|
||||
|
||||
private _fetchAllDeltagare: Observable<DeltagareResponse[]> = this.httpClient
|
||||
.get<{ data: DeltagareResponse[] }>(`${this._apiBaseUrl}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
map(response => {
|
||||
return response.data;
|
||||
})
|
||||
);
|
||||
.pipe(map(response => response.data));
|
||||
|
||||
public allDeltagare$: Observable<Deltagare[]> = this._fetchAllDeltagare.pipe(
|
||||
map(data => {
|
||||
return data.map(deltagare => mapResponseToDeltagare(deltagare));
|
||||
})
|
||||
map(data => data.map(deltagare => mapResponseToDeltagare(deltagare)))
|
||||
);
|
||||
|
||||
private _fetchContactInformation$(id: string): Observable<ContactInformation> {
|
||||
@@ -47,16 +41,19 @@ export class DeltagareService {
|
||||
.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 })
|
||||
@@ -68,21 +65,23 @@ export class DeltagareService {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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<DisabilityResponse[][]>(`${this._apiBaseUrl}/work/disability/${id}`, { ...API_HEADERS })
|
||||
.pipe(
|
||||
tap(response => console.log(response)),
|
||||
map(response =>
|
||||
response ? response[0].map(funktionsnedsattning => mapResponseToDisability(funktionsnedsattning)) : []
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Takes either 6 or 8 characters string (YYYYMMDD) and formats it to ISO standard (YYYY-MM-DD).
|
||||
export function formatToIsoDate(date: string): string {
|
||||
export function formatToIsoString(date: string): string {
|
||||
if (date.length === 6) {
|
||||
return `${date.substring(0, 4)}-${date.substring(4)}`;
|
||||
} else if (date.length === 8) {
|
||||
@@ -8,3 +8,11 @@ export function formatToIsoDate(date: string): string {
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
export function formatToDate(date: string): Date {
|
||||
const year = date.substring(0, 4);
|
||||
const month = date.substring(4, 6) || '01';
|
||||
const day = date.substring(6, 8) || '01';
|
||||
|
||||
return new Date(`${year}-${month}-${day}`);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import educationLevels from './education-levels.js';
|
||||
import languages from './languages.js';
|
||||
import sunKoder from './sun-koder.js';
|
||||
import chooseRandom from './utils/choose-random.util.js';
|
||||
import workExperiences from './work-experiences.js';
|
||||
|
||||
faker.locale = 'sv';
|
||||
|
||||
@@ -12,6 +13,7 @@ const DRIVERS_LICENSES = ['AM', 'A1', 'A2', 'A', 'B', 'BE', 'B96', 'C1', 'C', 'C
|
||||
const EDUCATION_LEVELS = educationLevels.generate();
|
||||
const SUN_KODER = sunKoder.generate();
|
||||
const DISABILITIES = disabilities.generate();
|
||||
const WORK_EXPERIENCES = workExperiences.generate();
|
||||
const EDUCATIONS = [
|
||||
{
|
||||
utbildning: 'Lingvistik',
|
||||
@@ -107,6 +109,9 @@ function generateDeltagare(amount = 10) {
|
||||
disabilities: {
|
||||
funktionsnedsattningar: Math.random() > 0.3 ? chooseRandom(DISABILITIES, faker.datatype.number(3)) : [],
|
||||
},
|
||||
workExperiences: {
|
||||
arbetslivserfarenheter: chooseRandom(WORK_EXPERIENCES, faker.datatype.number(WORK_EXPERIENCES.length)),
|
||||
}
|
||||
};
|
||||
if (Math.random() > 0.8) {
|
||||
deltagare.contact.adresser.push({
|
||||
|
||||
38
mock-api/dafa-web/scripts/work-experiences.js
Normal file
38
mock-api/dafa-web/scripts/work-experiences.js
Normal file
@@ -0,0 +1,38 @@
|
||||
function generateWorkExperiences() {
|
||||
console.info('Work experiences generated...');
|
||||
return [
|
||||
{
|
||||
yrke: 'Revisorer m.fl.',
|
||||
beskrivning: 'asasaf',
|
||||
arbetsgivare: 'Jobbet AB',
|
||||
period_from: '20090501',
|
||||
period_tom: '20110430'
|
||||
},
|
||||
{
|
||||
yrke: 'Revisorer m.fl.',
|
||||
beskrivning: 'asasaf',
|
||||
arbetsgivare: 'Himmelsö AB',
|
||||
period_from: '20130829',
|
||||
period_tom: '20140128'
|
||||
},
|
||||
{
|
||||
yrke: 'Revisorer m.fl.',
|
||||
beskrivning: 'asasaf',
|
||||
arbetsgivare: 'Himmelsö AB',
|
||||
period_from: '20140129',
|
||||
period_tom: '20141126'
|
||||
},
|
||||
{
|
||||
yrke: 'Revisorer m.fl.',
|
||||
beskrivning: 'AFAsdfasdf',
|
||||
arbetsgivare: 'Distansutbildningsnämnden',
|
||||
period_from: '20140527',
|
||||
period_tom: '20141126'
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export default {
|
||||
generate: generateWorkExperiences,
|
||||
};
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -21,7 +21,7 @@
|
||||
"@angular/platform-browser": "^11.2.0",
|
||||
"@angular/platform-browser-dynamic": "^11.2.0",
|
||||
"@angular/router": "^11.2.0",
|
||||
"@digi/core": "^9.1.0",
|
||||
"@digi/core": "^9.4.0",
|
||||
"@digi/styles": "^6.0.2",
|
||||
"@nrwl/angular": "11.5.1",
|
||||
"date-fns": "^2.22.1",
|
||||
@@ -2716,9 +2716,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@digi/core": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@digi/core/-/core-9.1.0.tgz",
|
||||
"integrity": "sha512-d2qTtSWPq0XfIwMaTsVIBdD5gnof7kJcUo4mHTGDaoN7tKD624u8CbbhaYaE3BF/0awuDEQkwxYSzuYiprJmUg==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@digi/core/-/core-9.4.0.tgz",
|
||||
"integrity": "sha512-47n9gPOAatEKMDy5GPH0sM/xHCizPrKnyjxb9zAxeHntSQdqstsTvb5/03gntqxKY8YndpJd2ksPxhU6w1ri5g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@digi/styles": {
|
||||
@@ -35654,9 +35654,9 @@
|
||||
}
|
||||
},
|
||||
"@digi/core": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@digi/core/-/core-9.1.0.tgz",
|
||||
"integrity": "sha512-d2qTtSWPq0XfIwMaTsVIBdD5gnof7kJcUo4mHTGDaoN7tKD624u8CbbhaYaE3BF/0awuDEQkwxYSzuYiprJmUg=="
|
||||
"version": "9.4.0",
|
||||
"resolved": "http://nexus.arbetsformedlingen.se/repository/npm/@digi/core/-/core-9.4.0.tgz",
|
||||
"integrity": "sha512-47n9gPOAatEKMDy5GPH0sM/xHCizPrKnyjxb9zAxeHntSQdqstsTvb5/03gntqxKY8YndpJd2ksPxhU6w1ri5g=="
|
||||
},
|
||||
"@digi/styles": {
|
||||
"version": "6.0.2",
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
"@angular/platform-browser": "^11.2.0",
|
||||
"@angular/platform-browser-dynamic": "^11.2.0",
|
||||
"@angular/router": "^11.2.0",
|
||||
"@digi/core": "^9.1.0",
|
||||
"@digi/core": "^9.4.0",
|
||||
"@digi/styles": "^6.0.2",
|
||||
"@nrwl/angular": "11.5.1",
|
||||
"date-fns": "^2.22.1",
|
||||
|
||||
Reference in New Issue
Block a user