Added more staff data

This commit is contained in:
Erik Tiekstra
2021-04-14 08:46:35 +02:00
parent 0b0dd8e107
commit acfe221bab
12 changed files with 196 additions and 36 deletions

View File

@@ -0,0 +1,12 @@
export interface Agency {
id: string;
name: string;
kaNumber: number;
address: {
street: string;
houseNumber: number;
postalCode: number;
city: string;
kommun: string;
};
}

View File

@@ -1,3 +1,6 @@
import { Agency } from '@dafa-models/agency.model';
import { Participant } from './participant.model';
export interface Staff {
id: string;
staffId: string;
@@ -19,4 +22,6 @@ export interface StaffDetail extends Staff {
phone: string;
email: string;
ssn: string;
agencies: Agency[];
participants: Participant[];
}

View File

@@ -17,9 +17,13 @@
<dt>Personal-ID</dt>
<dd>{{ detailedStaffData.staffId || '' }}</dd>
<dt>Telefon arbete</dt>
<dd>{{ detailedStaffData.phone || '' }}</dd>
<dd *ngIf="detailedStaffData.phone; else emptyDD">
<a [attr.href]="'tel:' + detailedStaffData.phone">{{ detailedStaffData.phone }}</a>
</dd>
<dt>Mailadress arbete</dt>
<dd>{{ detailedStaffData.email || '' }}</dd>
<dd *ngIf="detailedStaffData.email; else emptyDD">
<a [attr.href]="'mailto:' + detailedStaffData.email">{{ detailedStaffData.email }}</a>
</dd>
</dl>
</div>
@@ -47,6 +51,61 @@
<dd>{{ detailedStaffData.languages?.join(', ') }}</dd>
</dl>
</div>
<div class="staff-card__column">
<h2>Utförande verksamhet</h2>
<ul *ngIf="detailedStaffData.agencies?.length" class="staff-card__agencies">
<li *ngFor="let agency of detailedStaffData.agencies" class="staff-card__agency">
<h3>{{ agency.name }}</h3>
<dl>
<dt>KA-nummer</dt>
<dd>{{ agency.kaNumber }}</dd>
<dt>Adress</dt>
<dd>{{ agency.address.street }} {{ agency.address.houseNumber }}</dd>
<dd>{{ agency.address.postalCode }} {{ agency.address.city }}</dd>
</dl>
</li>
</ul>
</div>
<div class="staff-card__column">
<digi-ng-layout-expansion-panel>
<h3 style="margin-bottom: 0" data-slot-trigger>
Tilldelade deltagare ({{ detailedStaffData.participants.length }})
</h3>
<ng-container *ngIf="detailedStaffData.participants.length; else noParticipantsInfo">
<ul class="staff-card__participants">
<li *ngIf="detailedStaffData.participants.length > 1" class="staff-card__participant">
<digi-form-checkbox
af-variation="primary"
af-label="Välj alla"
af-value="all"
[afChecked]="pendingSelectedParticipants.length"
[afIndeterminate]="pendingSelectedParticipants.length !== detailedStaffData.participants.length"
(afOnChange)="
handleChangeAllParticipants(detailedStaffData.participants, $event.detail.target.checked)
"
></digi-form-checkbox>
</li>
<li *ngFor="let participant of detailedStaffData.participants" class="staff-card__participant">
<digi-form-checkbox
af-variation="primary"
[afLabel]="participant.fullName + ' - ' + participant.id"
[afValue]="participant.id"
[afChecked]="pendingSelectedParticipants.includes(participant.id)"
(afOnChange)="handleChangeParticipant(participant.id, $event.detail.target.checked)"
></digi-form-checkbox>
</li>
</ul>
<digi-button af-size="s" (afOnClick)="handleChangeStaff()">Byt handledare</digi-button>
</ng-container>
<ng-template #noParticipantsInfo>
<p>Inga deltagare har kopplats till {{ detailedStaffData.fullName }}.</p>
</ng-template>
</digi-ng-layout-expansion-panel>
</div>
</div>
</digi-typography>
</section>

View File

@@ -1,11 +1,11 @@
@import 'variables/gutters';
@import 'mixins/list';
.staff-card {
&__contents {
display: flex;
flex-direction: column;
gap: $digi--layout--gutter--l;
padding: $digi--layout--gutter--l;
background-color: var(--digi--ui--color--background--secondary);
h2 {
margin-top: 0;
@@ -14,6 +14,7 @@
&__column {
width: 100%;
max-width: var(--digi--typography--text--max-width);
}
dl {
@@ -35,4 +36,33 @@
dd {
grid-column: 2;
}
&__agencies {
@include dafa__reset-list;
display: flex;
flex-direction: column;
gap: 1rem;
}
&__agency {
border: 1px solid #333;
padding: var(--digi--layout--gutter);
h3 {
margin-top: 0;
}
}
&__participants {
@include dafa__reset-list;
margin: var(--digi--layout--gutter) 0;
}
&__participant {
padding: var(--digi--layout--gutter--s) var(--digi--layout--gutter--xs);
&:nth-child(even) {
background-color: var(--digi--ui--color--background--tertiary);
}
}
}

View File

@@ -1,9 +1,10 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive';
import { Participant } from '@dafa-models/participant.model';
import { Staff } from '@dafa-models/staff.model';
import { StaffService } from '@dafa-services/api/staff.service';
import { Observable } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
@Component({
selector: 'dafa-staff-card',
@@ -13,6 +14,7 @@ import { Observable } from 'rxjs';
})
export class StaffCardComponent extends UnsubscribeDirective {
detailedStaffData$: Observable<Staff>;
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
constructor(private activatedRoute: ActivatedRoute, private staffService: StaffService) {
super();
@@ -21,7 +23,30 @@ export class StaffCardComponent extends UnsubscribeDirective {
this.activatedRoute.params.subscribe(({ id }) => {
console.log(id);
this.detailedStaffData$ = this.staffService.getDetailedStaffData(id);
})
}),
this._pendingSelectedParticipants$.subscribe(ids => console.log(ids))
);
}
get pendingSelectedParticipants(): string[] {
return this._pendingSelectedParticipants$.getValue();
}
handleChangeStaff(): void {
console.log('change staff: ', this.pendingSelectedParticipants);
}
handleChangeParticipant(id: string, checked: boolean): void {
const currentPendingSelectedParticipants = this.pendingSelectedParticipants;
if (checked) {
this._pendingSelectedParticipants$.next([...this.pendingSelectedParticipants, id]);
} else {
this._pendingSelectedParticipants$.next(currentPendingSelectedParticipants.filter(currentId => currentId !== id));
}
}
handleChangeAllParticipants(participants: Participant[], checked: boolean): void {
this._pendingSelectedParticipants$.next(checked ? participants.map(participant => participant.id) : []);
}
}

View File

@@ -1,3 +1,4 @@
import { DigiNgLayoutExpansionPanelModule } from '@af/digi-ng/_layout/layout-expansion-panel';
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
@@ -12,6 +13,7 @@ import { StaffCardComponent } from './staff-card.component';
CommonModule,
RouterModule.forChild([{ path: '', component: StaffCardComponent }]),
DigiNgSkeletonBaseModule,
DigiNgLayoutExpansionPanelModule,
LocalDatePipeModule,
],
})

View File

@@ -21,16 +21,9 @@ function filterParticipants(participants: Participant[], searchFilter: string):
providedIn: 'root',
})
export class ParticipantsService {
private _allParticipants$: Observable<Participant[]> = this.httpClient
.get<Participant[]>(`${environment.apiBase}/participants`)
.pipe(
map(participants =>
participants.map(participant => ({
...participant,
fullName: `${participant.firstName} ${participant.lastName}`,
}))
)
);
private _allParticipants$: Observable<Participant[]> = this.httpClient.get<Participant[]>(
`${environment.apiBase}/participants`
);
private _activeParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
public activeParticipantsSortBy$: Observable<SortBy> = this._activeParticipantsSortBy$.asObservable();
private _followUpParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });

View File

@@ -19,14 +19,9 @@ function filterStaff(staff: Staff[], searchFilter: string): Staff[] {
providedIn: 'root',
})
export class StaffService {
private _allStaff$: Observable<Staff[]> = this.httpClient.get<Staff[]>(`${environment.apiBase}/staff`).pipe(
map(staff =>
staff.map(person => ({
...person,
fullName: `${person.firstName} ${person.lastName}`,
}))
)
);
private _allStaff$: Observable<Staff[]> = this.httpClient.get<Staff[]>(`${environment.apiBase}/staff`, {
params: { _embed: 'participants' },
});
private _staffSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
public staffSortBy$: Observable<SortBy> = this._staffSortBy$.asObservable();
@@ -44,12 +39,7 @@ export class StaffService {
);
public getDetailedStaffData(id: string): Observable<Staff> {
return this.httpClient.get<Staff>(`${environment.apiBase}/staff/${id}`).pipe(
map(staff => ({
...staff,
fullName: `${staff.firstName} ${staff.lastName}`,
}))
);
return this.httpClient.get<Staff>(`${environment.apiBase}/staff/${id}`, { params: { _embed: 'participants' } });
}
public setSearchFilter(value: string) {

View File

@@ -0,0 +1,31 @@
import faker from 'faker';
import kommuner from './kommuner.js';
faker.locale = 'sv';
const KOMMUN = kommuner.generate();
function generateAgencies(amount = 10) {
const agencies = [];
for (let i = 1; i <= amount; ++i) {
agencies.push({
id: faker.random.uuid(),
name: faker.company.companyName(),
kaNumber: faker.random.number({ min: 100000, max: 999999 }),
address: {
street: faker.address.streetName(),
houseNumber: faker.random.number(100),
postalCode: faker.address.zipCode(),
city: faker.address.city(),
kommun: KOMMUN[Math.floor(Math.random() * KOMMUN.length)].kommun,
},
});
}
return agencies;
}
export default {
generate: generateAgencies,
};

View File

@@ -1,14 +1,21 @@
import fs from 'fs';
import agencies from './agencies.js';
import kommuner from './kommuner.js';
import participants from './participants.js';
import services from './services.js';
import staff from './staff.js';
const generatedStaff = staff.generate(20);
const apiData = {
participants: participants.generate(50),
services: services.generate(),
staff: staff.generate(50),
staff: generatedStaff,
kommuner: kommuner.generate(),
agencies: agencies.generate(),
participants: participants.generate(50).map(participant => ({
...participant,
staffId: generatedStaff[Math.floor(Math.random() * generatedStaff.length)].id,
})),
};
fs.writeFileSync('api.json', JSON.stringify(apiData, null, '\t'));

View File

@@ -11,7 +11,7 @@ function generateParticipants(amount = 10) {
const participants = [];
for (let i = 1; i <= amount; ++i) {
participants.push({
const participant = {
id: faker.random.uuid(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
@@ -22,7 +22,8 @@ function generateParticipants(amount = 10) {
startDate: faker.date.recent(),
endDate: faker.date.future(),
handleBefore: faker.date.soon(),
});
};
participants.push({ ...participant, fullName: `${participant.firstName} ${participant.lastName}` });
}
return participants;

View File

@@ -1,4 +1,5 @@
import faker from 'faker';
import agencies from './agencies.js';
import kommuner from './kommuner.js';
import services from './services.js';
@@ -6,6 +7,7 @@ faker.locale = 'sv';
const SERVICES = services.generate();
const KOMMUN = kommuner.generate();
const AGENCIES = agencies.generate();
const STATUSES = [true, false];
const LANGUAGES = ['Franska', 'Nederländska', 'Arabiska', 'Spanska', 'Tyska', 'Italienska'];
const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
@@ -14,7 +16,7 @@ function generateStaff(amount = 10) {
const staff = [];
for (let i = 1; i <= amount; ++i) {
staff.push({
const person = {
id: faker.random.uuid(),
staffId: faker.random.number(),
firstName: faker.name.firstName(),
@@ -40,7 +42,10 @@ function generateStaff(amount = 10) {
},
]
: [],
});
agencies: chooseRandom(AGENCIES, faker.random.number(3)),
};
staff.push({ ...person, fullName: `${person.firstName} ${person.lastName}` });
}
return staff;