Added more staff data
This commit is contained in:
12
apps/dafa-web/src/app/data/models/agency.model.ts
Normal file
12
apps/dafa-web/src/app/data/models/agency.model.ts
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { Agency } from '@dafa-models/agency.model';
|
||||||
|
import { Participant } from './participant.model';
|
||||||
|
|
||||||
export interface Staff {
|
export interface Staff {
|
||||||
id: string;
|
id: string;
|
||||||
staffId: string;
|
staffId: string;
|
||||||
@@ -19,4 +22,6 @@ export interface StaffDetail extends Staff {
|
|||||||
phone: string;
|
phone: string;
|
||||||
email: string;
|
email: string;
|
||||||
ssn: string;
|
ssn: string;
|
||||||
|
agencies: Agency[];
|
||||||
|
participants: Participant[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,13 @@
|
|||||||
<dt>Personal-ID</dt>
|
<dt>Personal-ID</dt>
|
||||||
<dd>{{ detailedStaffData.staffId || '' }}</dd>
|
<dd>{{ detailedStaffData.staffId || '' }}</dd>
|
||||||
<dt>Telefon arbete</dt>
|
<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>
|
<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>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -47,6 +51,61 @@
|
|||||||
<dd>{{ detailedStaffData.languages?.join(', ') }}</dd>
|
<dd>{{ detailedStaffData.languages?.join(', ') }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</digi-typography>
|
</digi-typography>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
@import 'variables/gutters';
|
@import 'variables/gutters';
|
||||||
|
@import 'mixins/list';
|
||||||
|
|
||||||
.staff-card {
|
.staff-card {
|
||||||
&__contents {
|
&__contents {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
gap: $digi--layout--gutter--l;
|
gap: $digi--layout--gutter--l;
|
||||||
padding: $digi--layout--gutter--l;
|
|
||||||
background-color: var(--digi--ui--color--background--secondary);
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
&__column {
|
&__column {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: var(--digi--typography--text--max-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
dl {
|
dl {
|
||||||
@@ -35,4 +36,33 @@
|
|||||||
dd {
|
dd {
|
||||||
grid-column: 2;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive';
|
import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive';
|
||||||
|
import { Participant } from '@dafa-models/participant.model';
|
||||||
import { Staff } from '@dafa-models/staff.model';
|
import { Staff } from '@dafa-models/staff.model';
|
||||||
import { StaffService } from '@dafa-services/api/staff.service';
|
import { StaffService } from '@dafa-services/api/staff.service';
|
||||||
import { Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dafa-staff-card',
|
selector: 'dafa-staff-card',
|
||||||
@@ -13,6 +14,7 @@ import { Observable } from 'rxjs';
|
|||||||
})
|
})
|
||||||
export class StaffCardComponent extends UnsubscribeDirective {
|
export class StaffCardComponent extends UnsubscribeDirective {
|
||||||
detailedStaffData$: Observable<Staff>;
|
detailedStaffData$: Observable<Staff>;
|
||||||
|
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
|
||||||
|
|
||||||
constructor(private activatedRoute: ActivatedRoute, private staffService: StaffService) {
|
constructor(private activatedRoute: ActivatedRoute, private staffService: StaffService) {
|
||||||
super();
|
super();
|
||||||
@@ -21,7 +23,30 @@ export class StaffCardComponent extends UnsubscribeDirective {
|
|||||||
this.activatedRoute.params.subscribe(({ id }) => {
|
this.activatedRoute.params.subscribe(({ id }) => {
|
||||||
console.log(id);
|
console.log(id);
|
||||||
this.detailedStaffData$ = this.staffService.getDetailedStaffData(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) : []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DigiNgLayoutExpansionPanelModule } from '@af/digi-ng/_layout/layout-expansion-panel';
|
||||||
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||||
@@ -12,6 +13,7 @@ import { StaffCardComponent } from './staff-card.component';
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
RouterModule.forChild([{ path: '', component: StaffCardComponent }]),
|
RouterModule.forChild([{ path: '', component: StaffCardComponent }]),
|
||||||
DigiNgSkeletonBaseModule,
|
DigiNgSkeletonBaseModule,
|
||||||
|
DigiNgLayoutExpansionPanelModule,
|
||||||
LocalDatePipeModule,
|
LocalDatePipeModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,16 +21,9 @@ function filterParticipants(participants: Participant[], searchFilter: string):
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ParticipantsService {
|
export class ParticipantsService {
|
||||||
private _allParticipants$: Observable<Participant[]> = this.httpClient
|
private _allParticipants$: Observable<Participant[]> = this.httpClient.get<Participant[]>(
|
||||||
.get<Participant[]>(`${environment.apiBase}/participants`)
|
`${environment.apiBase}/participants`
|
||||||
.pipe(
|
);
|
||||||
map(participants =>
|
|
||||||
participants.map(participant => ({
|
|
||||||
...participant,
|
|
||||||
fullName: `${participant.firstName} ${participant.lastName}`,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
private _activeParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
|
private _activeParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
|
||||||
public activeParticipantsSortBy$: Observable<SortBy> = this._activeParticipantsSortBy$.asObservable();
|
public activeParticipantsSortBy$: Observable<SortBy> = this._activeParticipantsSortBy$.asObservable();
|
||||||
private _followUpParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
|
private _followUpParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
|
||||||
|
|||||||
@@ -19,14 +19,9 @@ function filterStaff(staff: Staff[], searchFilter: string): Staff[] {
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class StaffService {
|
export class StaffService {
|
||||||
private _allStaff$: Observable<Staff[]> = this.httpClient.get<Staff[]>(`${environment.apiBase}/staff`).pipe(
|
private _allStaff$: Observable<Staff[]> = this.httpClient.get<Staff[]>(`${environment.apiBase}/staff`, {
|
||||||
map(staff =>
|
params: { _embed: 'participants' },
|
||||||
staff.map(person => ({
|
});
|
||||||
...person,
|
|
||||||
fullName: `${person.firstName} ${person.lastName}`,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private _staffSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
|
private _staffSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
|
||||||
public staffSortBy$: Observable<SortBy> = this._staffSortBy$.asObservable();
|
public staffSortBy$: Observable<SortBy> = this._staffSortBy$.asObservable();
|
||||||
@@ -44,12 +39,7 @@ export class StaffService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
public getDetailedStaffData(id: string): Observable<Staff> {
|
public getDetailedStaffData(id: string): Observable<Staff> {
|
||||||
return this.httpClient.get<Staff>(`${environment.apiBase}/staff/${id}`).pipe(
|
return this.httpClient.get<Staff>(`${environment.apiBase}/staff/${id}`, { params: { _embed: 'participants' } });
|
||||||
map(staff => ({
|
|
||||||
...staff,
|
|
||||||
fullName: `${staff.firstName} ${staff.lastName}`,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSearchFilter(value: string) {
|
public setSearchFilter(value: string) {
|
||||||
|
|||||||
31
mock-api/dafa-web/scripts/agencies.js
Normal file
31
mock-api/dafa-web/scripts/agencies.js
Normal 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,
|
||||||
|
};
|
||||||
@@ -1,14 +1,21 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import agencies from './agencies.js';
|
||||||
import kommuner from './kommuner.js';
|
import kommuner from './kommuner.js';
|
||||||
import participants from './participants.js';
|
import participants from './participants.js';
|
||||||
import services from './services.js';
|
import services from './services.js';
|
||||||
import staff from './staff.js';
|
import staff from './staff.js';
|
||||||
|
|
||||||
|
const generatedStaff = staff.generate(20);
|
||||||
|
|
||||||
const apiData = {
|
const apiData = {
|
||||||
participants: participants.generate(50),
|
|
||||||
services: services.generate(),
|
services: services.generate(),
|
||||||
staff: staff.generate(50),
|
staff: generatedStaff,
|
||||||
kommuner: kommuner.generate(),
|
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'));
|
fs.writeFileSync('api.json', JSON.stringify(apiData, null, '\t'));
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ function generateParticipants(amount = 10) {
|
|||||||
const participants = [];
|
const participants = [];
|
||||||
|
|
||||||
for (let i = 1; i <= amount; ++i) {
|
for (let i = 1; i <= amount; ++i) {
|
||||||
participants.push({
|
const participant = {
|
||||||
id: faker.random.uuid(),
|
id: faker.random.uuid(),
|
||||||
firstName: faker.name.firstName(),
|
firstName: faker.name.firstName(),
|
||||||
lastName: faker.name.lastName(),
|
lastName: faker.name.lastName(),
|
||||||
@@ -22,7 +22,8 @@ function generateParticipants(amount = 10) {
|
|||||||
startDate: faker.date.recent(),
|
startDate: faker.date.recent(),
|
||||||
endDate: faker.date.future(),
|
endDate: faker.date.future(),
|
||||||
handleBefore: faker.date.soon(),
|
handleBefore: faker.date.soon(),
|
||||||
});
|
};
|
||||||
|
participants.push({ ...participant, fullName: `${participant.firstName} ${participant.lastName}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
return participants;
|
return participants;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import faker from 'faker';
|
import faker from 'faker';
|
||||||
|
import agencies from './agencies.js';
|
||||||
import kommuner from './kommuner.js';
|
import kommuner from './kommuner.js';
|
||||||
import services from './services.js';
|
import services from './services.js';
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ faker.locale = 'sv';
|
|||||||
|
|
||||||
const SERVICES = services.generate();
|
const SERVICES = services.generate();
|
||||||
const KOMMUN = kommuner.generate();
|
const KOMMUN = kommuner.generate();
|
||||||
|
const AGENCIES = agencies.generate();
|
||||||
const STATUSES = [true, false];
|
const STATUSES = [true, false];
|
||||||
const LANGUAGES = ['Franska', 'Nederländska', 'Arabiska', 'Spanska', 'Tyska', 'Italienska'];
|
const LANGUAGES = ['Franska', 'Nederländska', 'Arabiska', 'Spanska', 'Tyska', 'Italienska'];
|
||||||
const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
|
const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
|
||||||
@@ -14,7 +16,7 @@ function generateStaff(amount = 10) {
|
|||||||
const staff = [];
|
const staff = [];
|
||||||
|
|
||||||
for (let i = 1; i <= amount; ++i) {
|
for (let i = 1; i <= amount; ++i) {
|
||||||
staff.push({
|
const person = {
|
||||||
id: faker.random.uuid(),
|
id: faker.random.uuid(),
|
||||||
staffId: faker.random.number(),
|
staffId: faker.random.number(),
|
||||||
firstName: faker.name.firstName(),
|
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;
|
return staff;
|
||||||
|
|||||||
Reference in New Issue
Block a user