From 0b0dd8e107390e80ee000fbc86c5282c3b62b8d2 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Mon, 12 Apr 2021 13:52:20 +0200 Subject: [PATCH] Added more staff data and staff-card page --- apps/dafa-web/src/app/app.component.html | 2 +- apps/dafa-web/src/app/app.component.ts | 22 +------ .../src/app/data/constants/navigation.ts | 2 +- .../data/models/date-format-options.model.ts | 6 ++ .../src/app/data/models/staff.model.ts | 12 ++++ .../administration-routing.module.ts | 4 ++ .../staff-card/staff-card.component.html | 63 +++++++++++++++++++ .../staff-card/staff-card.component.scss | 38 +++++++++++ .../staff-card/staff-card.component.spec.ts | 27 ++++++++ .../pages/staff-card/staff-card.component.ts | 27 ++++++++ .../pages/staff-card/staff-card.module.ts | 18 ++++++ .../staff-list/staff-list.component.html | 4 +- .../staff-list/staff-list.module.ts | 3 +- .../src/app/services/api/staff.service.ts | 10 +++ .../pipes/local-date/local-date.module.ts | 11 ++++ .../pipes/local-date/local-date.pipe.ts | 26 ++++++++ .../utils/map-paths-to-breadcrumbs.util.ts | 25 ++++++++ mock-api/dafa-web/scripts/staff.js | 33 ++++++++++ 18 files changed, 310 insertions(+), 23 deletions(-) create mode 100644 apps/dafa-web/src/app/data/models/date-format-options.model.ts create mode 100644 apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.html create mode 100644 apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.scss create mode 100644 apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.spec.ts create mode 100644 apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.ts create mode 100644 apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.module.ts create mode 100644 apps/dafa-web/src/app/shared/pipes/local-date/local-date.module.ts create mode 100644 apps/dafa-web/src/app/shared/pipes/local-date/local-date.pipe.ts create mode 100644 apps/dafa-web/src/app/utils/map-paths-to-breadcrumbs.util.ts diff --git a/apps/dafa-web/src/app/app.component.html b/apps/dafa-web/src/app/app.component.html index c88e4a1..7c770c7 100644 --- a/apps/dafa-web/src/app/app.component.html +++ b/apps/dafa-web/src/app/app.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/apps/dafa-web/src/app/app.component.ts b/apps/dafa-web/src/app/app.component.ts index 396a63d..f09eb32 100644 --- a/apps/dafa-web/src/app/app.component.ts +++ b/apps/dafa-web/src/app/app.component.ts @@ -2,7 +2,7 @@ import { NavigationBreadcrumbsItem } from '@af/digi-ng/_navigation/navigation-br import { ChangeDetectionStrategy, Component } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; import { User } from '@dafa-models/user.model'; -import { mapPathToPageName } from '@dafa-utils/map-path-to-page-name.util'; +import { mapPathsToBreadcrumbs } from '@dafa-utils/map-paths-to-breadcrumbs.util'; import { BehaviorSubject } from 'rxjs'; import { filter } from 'rxjs/operators'; import { UnsubscribeDirective } from './directives/unsubscribe.directive'; @@ -14,7 +14,6 @@ import { UnsubscribeDirective } from './directives/unsubscribe.directive'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent extends UnsubscribeDirective { - path = ''; user: User = { id: 'fake-user', name: 'Fake user', @@ -35,24 +34,9 @@ export class AppComponent extends UnsubscribeDirective { super(); super.unsubscribeOnDestroy( this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => { - const paths = this.router.url.split('/'); - - this._breadcrumbsItems$.next([ - this.startBreadcrumb, - ...[...paths] - .filter(path => !!path) - .map(path => ({ - text: mapPathToPageName(path), - routerLink: paths.slice(0, paths.length - 1).join('/'), - })), - ]); - - this.path = paths[1].split('?')[0] || ''; + const paths = this.router.url.split('/').filter(path => !!path); + this._breadcrumbsItems$.next(mapPathsToBreadcrumbs(paths, this.startBreadcrumb)); }) ); } - - get appClass(): string { - return `dafa dafa--${this.path.length ? this.path : 'home'}`; - } } diff --git a/apps/dafa-web/src/app/data/constants/navigation.ts b/apps/dafa-web/src/app/data/constants/navigation.ts index a526647..7090bdd 100644 --- a/apps/dafa-web/src/app/data/constants/navigation.ts +++ b/apps/dafa-web/src/app/data/constants/navigation.ts @@ -1,7 +1,7 @@ export const Navigation = { administration: 'Administration', 'skapa-konto': 'Skapa nytt konto', - personal: 'Personal', + personal: 'Hantera personal', 'mina-deltagare': 'Mina deltagare', avrop: 'Avrop', meddelanden: 'Meddelanden', diff --git a/apps/dafa-web/src/app/data/models/date-format-options.model.ts b/apps/dafa-web/src/app/data/models/date-format-options.model.ts new file mode 100644 index 0000000..b81b130 --- /dev/null +++ b/apps/dafa-web/src/app/data/models/date-format-options.model.ts @@ -0,0 +1,6 @@ +export interface DateFormatOptions { + year?: 'short' | 'long' | 'numeric'; + month?: 'short' | 'long' | 'numeric'; + day?: 'short' | 'long' | 'numeric'; + weekday?: 'short' | 'long' | 'numeric'; +} diff --git a/apps/dafa-web/src/app/data/models/staff.model.ts b/apps/dafa-web/src/app/data/models/staff.model.ts index ae8cd11..1f4db85 100644 --- a/apps/dafa-web/src/app/data/models/staff.model.ts +++ b/apps/dafa-web/src/app/data/models/staff.model.ts @@ -8,3 +8,15 @@ export interface Staff { service: string; fullName?: string; } + +export interface StaffDetail extends Staff { + languages: string[]; + outOfOffice: { + start: Date; + end: Date; + }[]; + authorisations: string[]; + phone: string; + email: string; + ssn: string; +} diff --git a/apps/dafa-web/src/app/pages/administration/administration-routing.module.ts b/apps/dafa-web/src/app/pages/administration/administration-routing.module.ts index da00e40..52845bd 100644 --- a/apps/dafa-web/src/app/pages/administration/administration-routing.module.ts +++ b/apps/dafa-web/src/app/pages/administration/administration-routing.module.ts @@ -13,6 +13,10 @@ const routes: Routes = [ path: 'personal', loadChildren: () => import('./pages/staff/staff.module').then(m => m.StaffModule), }, + { + path: 'personal/:id', + loadChildren: () => import('./pages/staff-card/staff-card.module').then(m => m.StaffCardModule), + }, { path: 'skapa-konto', loadChildren: () => import('./pages/create-account/create-account.module').then(m => m.CreateAccountModule), diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.html b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.html new file mode 100644 index 0000000..4d2db17 --- /dev/null +++ b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.html @@ -0,0 +1,63 @@ +
+ +

{{ detailedStaffData.fullName }}

+

+ 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. +

+ +
+
+

Kontaktuppgifter

+ +
+
Personnummer
+
{{ detailedStaffData.ssn || '' }}
+
Personal-ID
+
{{ detailedStaffData.staffId || '' }}
+
Telefon arbete
+
{{ detailedStaffData.phone || '' }}
+
Mailadress arbete
+
{{ detailedStaffData.email || '' }}
+
+
+ +
+

Uppgifter om arbete

+ +
+
Behörighet
+ +
+ {{ item }} +
+
+
Aktivt i arbete
+
{{ detailedStaffData.active ? 'Ja' : 'Nej' }}
+
Frånvaroperiod
+ +
+ {{ date.start | localDate }} - {{ date.end | localDate }} +
+
+
Tjänst
+
{{ detailedStaffData.service || '' }}
+
Språk
+
{{ detailedStaffData.languages?.join(', ') }}
+
+
+
+
+
+ + + + + + +
+ + Info saknas +
+
diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.scss b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.scss new file mode 100644 index 0000000..0b7e66d --- /dev/null +++ b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.scss @@ -0,0 +1,38 @@ +@import 'variables/gutters'; + +.staff-card { + &__contents { + display: flex; + gap: $digi--layout--gutter--l; + padding: $digi--layout--gutter--l; + background-color: var(--digi--ui--color--background--secondary); + + h2 { + margin-top: 0; + } + } + + &__column { + width: 100%; + } + + 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; + } +} diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.spec.ts b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.spec.ts new file mode 100644 index 0000000..6a31771 --- /dev/null +++ b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { StaffCardComponent } from './staff-card.component'; + +describe('StaffCardComponent', () => { + let component: StaffCardComponent; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [StaffCardComponent], + imports: [RouterTestingModule], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(StaffCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.ts b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.ts new file mode 100644 index 0000000..59c65fb --- /dev/null +++ b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.component.ts @@ -0,0 +1,27 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive'; +import { Staff } from '@dafa-models/staff.model'; +import { StaffService } from '@dafa-services/api/staff.service'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'dafa-staff-card', + templateUrl: './staff-card.component.html', + styleUrls: ['./staff-card.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class StaffCardComponent extends UnsubscribeDirective { + detailedStaffData$: Observable; + + constructor(private activatedRoute: ActivatedRoute, private staffService: StaffService) { + super(); + + super.unsubscribeOnDestroy( + this.activatedRoute.params.subscribe(({ id }) => { + console.log(id); + this.detailedStaffData$ = this.staffService.getDetailedStaffData(id); + }) + ); + } +} diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.module.ts b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.module.ts new file mode 100644 index 0000000..4c334ed --- /dev/null +++ b/apps/dafa-web/src/app/pages/administration/pages/staff-card/staff-card.module.ts @@ -0,0 +1,18 @@ +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 { LocalDatePipeModule } from '@dafa-shared/pipes/local-date/local-date.module'; +import { StaffCardComponent } from './staff-card.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [StaffCardComponent], + imports: [ + CommonModule, + RouterModule.forChild([{ path: '', component: StaffCardComponent }]), + DigiNgSkeletonBaseModule, + LocalDatePipeModule, + ], +}) +export class StaffCardModule {} diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.component.html b/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.component.html index 9ab8442..d7a4fc0 100644 --- a/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.component.html +++ b/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.component.html @@ -51,7 +51,9 @@ - {{ staff.firstName }} {{ staff.lastName }} + + {{ staff.fullName }} + {{ staff.staffId }} {{ staff.kommun }} {{ staff.active ? 'Ja' : 'Nej' }} diff --git a/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.module.ts b/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.module.ts index bfc02fa..0360b2d 100644 --- a/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.module.ts +++ b/apps/dafa-web/src/app/pages/administration/pages/staff/components/staff-list/staff-list.module.ts @@ -1,12 +1,13 @@ 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 { StaffListComponent } from './staff-list.component'; @NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [StaffListComponent], - imports: [CommonModule, DigiNgTableModule], + imports: [CommonModule, RouterModule, DigiNgTableModule], exports: [StaffListComponent], }) export class StaffListModule {} diff --git a/apps/dafa-web/src/app/services/api/staff.service.ts b/apps/dafa-web/src/app/services/api/staff.service.ts index 0f791c2..ca4a503 100644 --- a/apps/dafa-web/src/app/services/api/staff.service.ts +++ b/apps/dafa-web/src/app/services/api/staff.service.ts @@ -27,6 +27,7 @@ export class StaffService { })) ) ); + private _staffSortBy$ = new BehaviorSubject({ key: 'fullName', reverse: false }); public staffSortBy$: Observable = this._staffSortBy$.asObservable(); private _searchFilter$ = new BehaviorSubject(''); @@ -42,6 +43,15 @@ export class StaffService { }) ); + public getDetailedStaffData(id: string): Observable { + return this.httpClient.get(`${environment.apiBase}/staff/${id}`).pipe( + map(staff => ({ + ...staff, + fullName: `${staff.firstName} ${staff.lastName}`, + })) + ); + } + public setSearchFilter(value: string) { this._searchFilter$.next(value); } diff --git a/apps/dafa-web/src/app/shared/pipes/local-date/local-date.module.ts b/apps/dafa-web/src/app/shared/pipes/local-date/local-date.module.ts new file mode 100644 index 0000000..75c2578 --- /dev/null +++ b/apps/dafa-web/src/app/shared/pipes/local-date/local-date.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { LocalDatePipe } from './local-date.pipe'; + +@NgModule({ + declarations: [LocalDatePipe], + imports: [CommonModule], + exports: [LocalDatePipe], + providers: [LocalDatePipe], +}) +export class LocalDatePipeModule {} diff --git a/apps/dafa-web/src/app/shared/pipes/local-date/local-date.pipe.ts b/apps/dafa-web/src/app/shared/pipes/local-date/local-date.pipe.ts new file mode 100644 index 0000000..c00800a --- /dev/null +++ b/apps/dafa-web/src/app/shared/pipes/local-date/local-date.pipe.ts @@ -0,0 +1,26 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { DateFormatOptions } from '@dafa-models/date-format-options.model'; + +@Pipe({ + name: 'localDate', +}) +export class LocalDatePipe implements PipeTransform { + private defaultFormatOptions: DateFormatOptions = { + year: 'numeric', + month: 'numeric', + day: 'numeric', + }; + private defaultLocale = 'sv-SE'; + + transform( + date: string | Date, + formatOptions: DateFormatOptions = this.defaultFormatOptions, + locale: string = this.defaultLocale + ): string { + if (!date) { + console.warn('WARNING: No date provided.'); + return ''; + } + return new Date(date).toLocaleDateString(locale, formatOptions); + } +} diff --git a/apps/dafa-web/src/app/utils/map-paths-to-breadcrumbs.util.ts b/apps/dafa-web/src/app/utils/map-paths-to-breadcrumbs.util.ts new file mode 100644 index 0000000..5c233e1 --- /dev/null +++ b/apps/dafa-web/src/app/utils/map-paths-to-breadcrumbs.util.ts @@ -0,0 +1,25 @@ +import { NavigationBreadcrumbsItem } from '@af/digi-ng/_navigation/navigation-breadcrumbs'; +import { mapPathToPageName } from './map-path-to-page-name.util'; + +export function mapPathsToBreadcrumbs( + paths: string[], + startBreadcrumb?: NavigationBreadcrumbsItem +): NavigationBreadcrumbsItem[] { + const breadcrumbs = [ + ...(startBreadcrumb ? [startBreadcrumb] : []), + ...paths.map((path, index) => ({ + text: mapPathToPageName(path), + routerLink: paths.slice(0, index + 1).join('/'), + })), + ]; + + if (isStaffCardRoute(paths)) { + breadcrumbs[breadcrumbs.length - 1].text = 'Personalkort'; + } + + return breadcrumbs; +} + +function isStaffCardRoute(paths: string[]): boolean { + return paths.length === 3 && paths[1] === 'personal'; +} diff --git a/mock-api/dafa-web/scripts/staff.js b/mock-api/dafa-web/scripts/staff.js index 57f6bc7..0ea89af 100644 --- a/mock-api/dafa-web/scripts/staff.js +++ b/mock-api/dafa-web/scripts/staff.js @@ -7,6 +7,8 @@ faker.locale = 'sv'; const SERVICES = services.generate(); const KOMMUN = kommuner.generate(); const STATUSES = [true, false]; +const LANGUAGES = ['Franska', 'Nederländska', 'Arabiska', 'Spanska', 'Tyska', 'Italienska']; +const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi']; function generateStaff(amount = 10) { const staff = []; @@ -20,6 +22,24 @@ function generateStaff(amount = 10) { kommun: KOMMUN[Math.floor(Math.random() * KOMMUN.length)].kommun, active: STATUSES[Math.floor(Math.random() * STATUSES.length)], service: SERVICES[Math.floor(Math.random() * SERVICES.length)].name, + languages: ['Svenska', ...chooseRandom(LANGUAGES, faker.random.number(3))], + ssn: `${faker.date.between('1950', '2000').toISOString().split('T')[0].replaceAll('-', '')}-${faker.random.number( + { + min: 1000, + max: 9999, + } + )}`, + phone: `07${faker.random.number(9)}-${faker.random.number({ min: 1000000, max: 9999999 })}`, + email: faker.internet.email(), + authorisations: chooseRandom(AUTHORISATIONS, faker.random.number(3)), + outOfOffice: STATUSES[Math.floor(Math.random() * STATUSES.length)] + ? [ + { + start: new Date('2021-07-12'), + end: new Date('2021-07-24'), + }, + ] + : [], }); } @@ -29,3 +49,16 @@ function generateStaff(amount = 10) { export default { generate: generateStaff, }; + +function chooseRandom(arr, num = 1) { + const res = []; + for (let i = 0; i < num; ) { + const random = Math.floor(Math.random() * arr.length); + if (res.indexOf(arr[random]) !== -1) { + continue; + } + res.push(arr[random]); + i++; + } + return res; +}