Renamed staff to employees

This commit is contained in:
Erik Tiekstra
2021-05-04 14:44:48 +02:00
parent e56b92c0d9
commit 067b25c3aa
27 changed files with 289 additions and 287 deletions

View File

@@ -1,9 +1,9 @@
import { Agency } from '@dafa-models/agency.model';
import { Participant } from './participant.model';
export interface Staff {
export interface Employee {
id: string;
staffId: string;
employeeId: string;
firstName: string;
lastName: string;
utforandeverksamhet: string;
@@ -12,7 +12,7 @@ export interface Staff {
fullName?: string;
}
export interface StaffDetail extends Staff {
export interface EmployeeDetail extends Employee {
languages: string[];
outOfOffice: {
start: Date;

View File

@@ -1,7 +1,7 @@
import { Employee } from './employee.model';
import { Participant } from './participant.model';
import { Staff } from './staff.model';
export interface SortBy {
key: keyof Participant | keyof Staff;
key: keyof Participant | keyof Employee;
reverse: boolean;
}

View File

@@ -11,11 +11,11 @@ const routes: Routes = [
},
{
path: 'personal',
loadChildren: () => import('./pages/staff/staff.module').then(m => m.StaffModule),
loadChildren: () => import('./pages/employees/employees.module').then(m => m.EmployeesModule),
},
{
path: 'personal/:id',
loadChildren: () => import('./pages/staff-card/staff-card.module').then(m => m.StaffCardModule),
loadChildren: () => import('./pages/employee-card/employee-card.module').then(m => m.EmployeeCardModule),
},
{
path: 'skapa-konto',

View File

@@ -1,12 +1,9 @@
import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group';
import { FormSelectBaseItem } from '@af/digi-ng/_form/form-select-base';
import { PopoverDirection, PopoverOrientation } from '@af/digi-ng/_popover/popover';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { Service } from '@dafa-enums/service.enum';
import { OutOfOfficeDate } from '@dafa-models/out-of-office-date.model';
import { StaffService } from '@dafa-services/api/staff.service';
import { EmployeeService } from '@dafa-services/api/employee.service';
import { RequiredValidator } from '@dafa-validators/required.validator';
import { SocialSecurityNumberValidator } from '@dafa-validators/social-security-number.validator';
import { BehaviorSubject } from 'rxjs';
@@ -38,12 +35,12 @@ export class CreateAccountComponent {
},
];
constructor(private formBuilder: FormBuilder, private staffService: StaffService, private router: Router) {
constructor(private formBuilder: FormBuilder, private employeeService: EmployeeService, private router: Router) {
this.formGroup = this.formBuilder.group({
firstName: this.formBuilder.control('', [RequiredValidator('Förnamn')]),
lastName: this.formBuilder.control('', [RequiredValidator('Efternamn')]),
ssn: this.formBuilder.control('', [RequiredValidator('Personnummer'), SocialSecurityNumberValidator()]),
staffId: this.formBuilder.control('', [RequiredValidator('Personal-ID')]),
employeeId: this.formBuilder.control('', [RequiredValidator('Personal-ID')]),
service: this.formBuilder.control(''),
permissions: this.formBuilder.control(false),
participant: this.formBuilder.control(false),
@@ -104,7 +101,7 @@ export class CreateAccountComponent {
delete submittableValues.outOfOfficeStart;
delete submittableValues.outOfOfficeEnd;
const post = this.staffService.createAccount(submittableValues).subscribe({
const post = this.employeeService.createAccount(submittableValues).subscribe({
next: id => {
this.router.navigate(['/administration', 'personal', id]);
},

View File

@@ -1,6 +1,6 @@
<section class="staff-card">
<digi-typography *ngIf="detailedStaffData$ | async as detailedStaffData; else loadingRef">
<h1>{{ detailedStaffData.fullName }}</h1>
<section class="employee-card">
<digi-typography *ngIf="detailedEmployeeData$ | async as detailedEmployeeData; else loadingRef">
<h1>{{ detailedEmployeeData.fullName }}</h1>
<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,
@@ -13,16 +13,16 @@
<dl>
<dt>Personnummer</dt>
<dd>{{ detailedStaffData.ssn || '' }}</dd>
<dd>{{ detailedEmployeeData.ssn || '' }}</dd>
<dt>Personal-ID</dt>
<dd>{{ detailedStaffData.staffId || '' }}</dd>
<dd>{{ detailedEmployeeData.employeeId || '' }}</dd>
<dt>Telefon arbete</dt>
<dd *ngIf="detailedStaffData.phone; else emptyDD">
<a [attr.href]="'tel:' + detailedStaffData.phone">{{ detailedStaffData.phone }}</a>
<dd *ngIf="detailedEmployeeData.phone; else emptyDD">
<a [attr.href]="'tel:' + detailedEmployeeData.phone">{{ detailedEmployeeData.phone }}</a>
</dd>
<dt>Mailadress arbete</dt>
<dd *ngIf="detailedStaffData.email; else emptyDD">
<a [attr.href]="'mailto:' + detailedStaffData.email">{{ detailedStaffData.email }}</a>
<dd *ngIf="detailedEmployeeData.email; else emptyDD">
<a [attr.href]="'mailto:' + detailedEmployeeData.email">{{ detailedEmployeeData.email }}</a>
</dd>
</dl>
</div>
@@ -32,31 +32,31 @@
<dl>
<dt>Behörighet</dt>
<ng-container *ngIf="detailedStaffData.authorisations?.length; else emptyDD">
<dd *ngFor="let item of detailedStaffData.authorisations">
<ng-container *ngIf="detailedEmployeeData.authorisations?.length; else emptyDD">
<dd *ngFor="let item of detailedEmployeeData.authorisations">
{{ item }}
</dd>
</ng-container>
<dt>Aktivt i arbete</dt>
<dd>{{ detailedStaffData.active ? 'Ja' : 'Nej' }}</dd>
<dd>{{ detailedEmployeeData.active ? 'Ja' : 'Nej' }}</dd>
<dt>Frånvaroperiod</dt>
<ng-container *ngIf="detailedStaffData.outOfOffice?.length; else emptyDD">
<dd *ngFor="let date of detailedStaffData.outOfOffice">
<ng-container *ngIf="detailedEmployeeData.outOfOffice?.length; else emptyDD">
<dd *ngFor="let date of detailedEmployeeData.outOfOffice">
{{ date.start | localDate }} - {{ date.end | localDate }}
</dd>
</ng-container>
<dt>Tjänst</dt>
<dd>{{ detailedStaffData.service || '' }}</dd>
<dd>{{ detailedEmployeeData.service || '' }}</dd>
<dt>Språk</dt>
<dd>{{ detailedStaffData.languages?.join(', ') }}</dd>
<dd>{{ detailedEmployeeData.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">
<ul *ngIf="detailedEmployeeData.agencies?.length" class="staff-card__agencies">
<li *ngFor="let agency of detailedEmployeeData.agencies" class="staff-card__agency">
<h3>{{ agency.name }}</h3>
<dl>
<dt>KA-nummer</dt>
@@ -72,23 +72,23 @@
<div class="staff-card__column">
<digi-ng-layout-expansion-panel>
<h3 style="margin-bottom: 0" data-slot-trigger>
Tilldelade deltagare ({{ detailedStaffData.participants?.length || 0 }})
Tilldelade deltagare ({{ detailedEmployeeData.participants?.length || 0 }})
</h3>
<ng-container *ngIf="detailedStaffData.participants?.length; else noParticipantsInfo">
<ng-container *ngIf="detailedEmployeeData.participants?.length; else noParticipantsInfo">
<ul class="staff-card__participants">
<li *ngIf="detailedStaffData.participants.length > 1" class="staff-card__participant">
<li *ngIf="detailedEmployeeData.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"
[afIndeterminate]="pendingSelectedParticipants.length !== detailedEmployeeData.participants.length"
(afOnChange)="
handleChangeAllParticipants(detailedStaffData.participants, $event.detail.target.checked)
handleChangeAllParticipants(detailedEmployeeData.participants, $event.detail.target.checked)
"
></digi-form-checkbox>
</li>
<li *ngFor="let participant of detailedStaffData.participants" class="staff-card__participant">
<li *ngFor="let participant of detailedEmployeeData.participants" class="staff-card__participant">
<digi-form-checkbox
af-variation="primary"
[afLabel]="participant.fullName"
@@ -99,10 +99,10 @@
</li>
</ul>
<digi-button af-size="s" (afOnClick)="handleChangeStaff()">Byt handledare</digi-button>
<digi-button af-size="s" (afOnClick)="handleChangeEmployee()">Byt handledare</digi-button>
</ng-container>
<ng-template #noParticipantsInfo>
<p>Inga deltagare har kopplats till {{ detailedStaffData.fullName }}.</p>
<p>Inga deltagare har kopplats till {{ detailedEmployeeData.fullName }}.</p>
</ng-template>
</digi-ng-layout-expansion-panel>
</div>

View File

@@ -1,7 +1,7 @@
@import 'variables/gutters';
@import 'mixins/list';
.staff-card {
.employee-card {
&__contents {
display: flex;
flex-direction: column;

View File

@@ -1,22 +1,22 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StaffCardComponent } from './staff-card.component';
import { EmployeeCardComponent } from './employee-card.component';
describe('StaffCardComponent', () => {
let component: StaffCardComponent;
let fixture: ComponentFixture<StaffCardComponent>;
describe('EmployeeCardComponent', () => {
let component: EmployeeCardComponent;
let fixture: ComponentFixture<EmployeeCardComponent>;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [StaffCardComponent],
declarations: [EmployeeCardComponent],
imports: [RouterTestingModule],
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(StaffCardComponent);
fixture = TestBed.createComponent(EmployeeCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -1,28 +1,28 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive';
import { Employee } from '@dafa-models/employee.model';
import { Participant } from '@dafa-models/participant.model';
import { Staff } from '@dafa-models/staff.model';
import { StaffService } from '@dafa-services/api/staff.service';
import { EmployeeService } from '@dafa-services/api/employee.service';
import { BehaviorSubject, Observable } from 'rxjs';
@Component({
selector: 'dafa-staff-card',
templateUrl: './staff-card.component.html',
styleUrls: ['./staff-card.component.scss'],
selector: 'dafa-employee-card',
templateUrl: './employee-card.component.html',
styleUrls: ['./employee-card.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StaffCardComponent extends UnsubscribeDirective {
detailedStaffData$: Observable<Staff>;
export class EmployeeCardComponent extends UnsubscribeDirective {
detailedEmployeeData$: Observable<Employee>;
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
constructor(private activatedRoute: ActivatedRoute, private staffService: StaffService) {
constructor(private activatedRoute: ActivatedRoute, private employeeService: EmployeeService) {
super();
super.unsubscribeOnDestroy(
this.activatedRoute.params.subscribe(({ id }) => {
console.log(id);
this.detailedStaffData$ = this.staffService.getDetailedStaffData(id);
this.detailedEmployeeData$ = this.employeeService.getDetailedEmployeeData(id);
}),
this._pendingSelectedParticipants$.subscribe(ids => console.log(ids))
);
@@ -32,8 +32,8 @@ export class StaffCardComponent extends UnsubscribeDirective {
return this._pendingSelectedParticipants$.getValue();
}
handleChangeStaff(): void {
console.log('change staff: ', this.pendingSelectedParticipants);
handleChangeEmployee(): void {
console.log('change employee: ', this.pendingSelectedParticipants);
}
handleChangeParticipant(id: string, checked: boolean): void {

View File

@@ -4,17 +4,17 @@ 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';
import { EmployeeCardComponent } from './employee-card.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [StaffCardComponent],
declarations: [EmployeeCardComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: StaffCardComponent }]),
RouterModule.forChild([{ path: '', component: EmployeeCardComponent }]),
DigiNgSkeletonBaseModule,
DigiNgLayoutExpansionPanelModule,
LocalDatePipeModule,
],
})
export class StaffCardModule {}
export class EmployeeCardModule {}

View File

@@ -0,0 +1,58 @@
<div class="employees-list">
<digi-table af-variation="secondary">
<table>
<thead>
<tr>
<th scope="col" class="employees-list__column-head">
<button class="employees-list__sort-button" (click)="handleSort('fullName')">
Namn
<ng-container *ngIf="sortBy?.key === 'fullName'">
<digi-icon-caret-up class="employees-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="employees-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
<th scope="col" class="employees-list__column-head">
<button class="employees-list__sort-button" (click)="handleSort('service')">
Tjänst
<ng-container *ngIf="sortBy?.key === 'service'">
<digi-icon-caret-up class="employees-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="employees-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
<th scope="col" class="employees-list__column-head">
<button class="employees-list__sort-button" (click)="handleSort('utforandeverksamhet')">
Utförandeverksamhet
<ng-container *ngIf="sortBy?.key === 'utforandeverksamhet'">
<digi-icon-caret-up class="employees-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="employees-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let employees of pagedEmployees">
<th scope="row">
<a [routerLink]="employees.id" class="employees-list__link">{{ employees.fullName }}</a>
</th>
<td>{{ employees.service }}</td>
<td>{{ employees.kommun }}</td>
</tr>
</tbody>
</table>
</digi-table>
<digi-navigation-pagination
*ngIf="employees.length > pagedEmployees.length"
class="employees-list__pagination"
[afTotalPages]="totalPages"
[afCurrentResultStart]="currentResultStart"
[afCurrentResultEnd]="currentResultEnd"
[afTotalResults]="employees.length"
(afOnPageChange)="handlePagination($event.detail)"
af-result-name="deltagare"
>
</digi-navigation-pagination>
</div>

View File

@@ -1,23 +1,23 @@
import { DigiNgTableModule } from '@af/digi-ng/_table/table';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StaffListComponent } from './staff-list.component';
import { EmployeesListComponent } from './employees-list.component';
describe('StaffListComponent', () => {
let component: StaffListComponent;
let fixture: ComponentFixture<StaffListComponent>;
describe('EmployeesListComponent', () => {
let component: EmployeesListComponent;
let fixture: ComponentFixture<EmployeesListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [StaffListComponent],
declarations: [EmployeesListComponent],
imports: [RouterTestingModule, DigiNgTableModule],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(StaffListComponent);
fixture = TestBed.createComponent(EmployeesListComponent);
component = fixture.componentInstance;
component.staff = [];
component.employees = [];
fixture.detectChanges();
});

View File

@@ -1,21 +1,21 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { Employee } from '@dafa-models/employee.model';
import { SortBy } from '@dafa-models/sort-by.model';
import { Staff } from '@dafa-models/staff.model';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'dafa-staff-list',
templateUrl: './staff-list.component.html',
styleUrls: ['./staff-list.component.scss'],
selector: 'dafa-employees-list',
templateUrl: './employees-list.component.html',
styleUrls: ['./employees-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StaffListComponent {
@Input() staff: Staff[];
export class EmployeesListComponent {
@Input() employees: Employee[];
@Input() sortBy: SortBy | null;
@Output() sorted = new EventEmitter<keyof Staff>();
@Output() sorted = new EventEmitter<keyof Employee>();
private _currentPage$ = new BehaviorSubject<number>(1);
private _staffPerPage = 10;
private _employeesPerPage = 10;
private _searchValue$ = new BehaviorSubject<string>('');
@@ -24,22 +24,22 @@ export class StaffListComponent {
}
get totalPages(): number {
return Math.ceil(this.staff.length / this._staffPerPage);
return Math.ceil(this.employees.length / this._employeesPerPage);
}
get pagedStaff(): Staff[] {
return [...this.staff].slice(this.currentResultStart - 1, this.currentResultEnd - 1);
get pagedEmployees(): Employee[] {
return [...this.employees].slice(this.currentResultStart - 1, this.currentResultEnd - 1);
}
get currentResultStart(): number {
return (this.currentPage - 1) * this._staffPerPage + 1;
return (this.currentPage - 1) * this._employeesPerPage + 1;
}
get currentResultEnd(): number {
return this.currentResultStart + this._staffPerPage;
return this.currentResultStart + this._employeesPerPage;
}
handleSort(key: keyof Staff): void {
handleSort(key: keyof Employee): void {
this.sorted.emit(key);
}

View File

@@ -2,13 +2,12 @@ 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';
import { EmployeesListComponent } from './employees-list.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [StaffListComponent],
declarations: [EmployeesListComponent],
imports: [CommonModule, RouterModule, DigiNgTableModule],
exports: [StaffListComponent],
exports: [EmployeesListComponent],
})
export class StaffListModule {}
export class EmployeesListModule {}

View File

@@ -1,4 +1,4 @@
<section class="staff">
<section class="employees">
<digi-typography>
<h1>Personal</h1>
<p>
@@ -7,13 +7,13 @@
leo quis ante porttitor tincidunt. Nam tincidunt imperdiet tortor eu suscipit. Maecenas ut dui est.
</p>
<div class="staff__cta-wrapper">
<div class="employees__cta-wrapper">
<digi-ng-link-button afText="Skapa nytt konto" afRoute="/administration/skapa-konto"></digi-ng-link-button>
</div>
<h2>Personallista</h2>
<form class="staff__search-wrapper" (ngSubmit)="handleSearchSubmit()">
<form class="employees__search-wrapper" (ngSubmit)="handleSearchSubmit()">
<digi-form-input-search
af-label="Sök kunder"
af-label-description="Sök på namn eller ärendenummer"
@@ -21,12 +21,12 @@
></digi-form-input-search>
</form>
<dafa-staff-list
*ngIf="filteredStaff$ | async as staff; else loadingRef"
[staff]="staff"
[sortBy]="staffSortBy$ | async"
(sorted)="handleStaffSort($event)"
></dafa-staff-list>
<dafa-employees-list
*ngIf="filteredEmployees$ | async as employees; else loadingRef"
[employees]="employees"
[sortBy]="employeesSortBy$ | async"
(sorted)="handleEmployeesSort($event)"
></dafa-employees-list>
</digi-typography>
<ng-template #loadingRef>

View File

@@ -1,5 +1,6 @@
@import 'variables/gutters';
.staff {
.employees {
&__cta-wrapper {
margin-top: var(--digi--layout--gutter);
}

View File

@@ -1,22 +1,22 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StaffComponent } from './staff.component';
import { EmployeesComponent } from './employees.component';
describe('StaffComponent', () => {
let component: StaffComponent;
let fixture: ComponentFixture<StaffComponent>;
describe('EmployeesComponent', () => {
let component: EmployeesComponent;
let fixture: ComponentFixture<EmployeesComponent>;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [StaffComponent],
declarations: [EmployeesComponent],
imports: [RouterTestingModule],
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(StaffComponent);
fixture = TestBed.createComponent(EmployeesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -0,0 +1,37 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IconType } from '@dafa-enums/icon-type.enum';
import { Employee } from '@dafa-models/employee.model';
import { SortBy } from '@dafa-models/sort-by.model';
import { EmployeeService } from '@dafa-services/api/employee.service';
import { BehaviorSubject, Observable } from 'rxjs';
@Component({
selector: 'dafa-employees',
templateUrl: './employees.component.html',
styleUrls: ['./employees.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EmployeesComponent {
private _searchValue$ = new BehaviorSubject<string>('');
filteredEmployees$: Observable<Employee[]> = this.employeeService.filteredEmployees$;
employeesSortBy$: Observable<SortBy | null> = this.employeeService.employeesSortBy$;
iconType = IconType;
constructor(private employeeService: EmployeeService) {}
get searchValue(): string {
return this._searchValue$.getValue();
}
handleSearchSubmit(): void {
this.employeeService.setSearchFilter(this.searchValue);
}
handleSearchInput($event: CustomEvent): void {
this._searchValue$.next($event.detail.target.value);
}
handleEmployeesSort(key: keyof Employee): void {
this.employeeService.setEmployeesSortKey(key);
}
}

View File

@@ -1,24 +1,24 @@
import { DigiNgLinkButtonModule } from '@af/digi-ng/_link/link-button';
import { DigiNgLinkInternalModule } from '@af/digi-ng/_link/link-internal';
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 { StaffListModule } from './components/staff-list/staff-list.module';
import { StaffComponent } from './staff.component';
import { DigiNgLinkButtonModule } from '@af/digi-ng/_link/link-button';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { EmployeesListModule } from './components/employees-list/employees-list.module';
import { EmployeesComponent } from './employees.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [StaffComponent],
declarations: [EmployeesComponent],
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: StaffComponent }]),
RouterModule.forChild([{ path: '', component: EmployeesComponent }]),
DigiNgLinkInternalModule,
DigiNgSkeletonBaseModule,
StaffListModule,
EmployeesListModule,
DigiNgLinkButtonModule,
FormsModule,
],
})
export class StaffModule {}
export class EmployeesModule {}

View File

@@ -1,56 +0,0 @@
<digi-table af-variation="secondary">
<table>
<thead>
<tr>
<th scope="col" class="staff-list__column-head">
<button class="staff-list__sort-button" (click)="handleSort('fullName')">
Namn
<ng-container *ngIf="sortBy?.key === 'fullName'">
<digi-icon-caret-up class="staff-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="staff-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
<th scope="col" class="staff-list__column-head">
<button class="staff-list__sort-button" (click)="handleSort('service')">
Tjänst
<ng-container *ngIf="sortBy?.key === 'service'">
<digi-icon-caret-up class="staff-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="staff-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
<th scope="col" class="staff-list__column-head">
<button class="staff-list__sort-button" (click)="handleSort('utforandeverksamhet')">
Utförandeverksamhet
<ng-container *ngIf="sortBy?.key === 'utforandeverksamhet'">
<digi-icon-caret-up class="staff-list__sort-icon" *ngIf="!sortBy.reverse"></digi-icon-caret-up>
<digi-icon-caret-down class="staff-list__sort-icon" *ngIf="sortBy.reverse"></digi-icon-caret-down>
</ng-container>
</button>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let staff of pagedStaff">
<th scope="row">
<a [routerLink]="staff.id" class="staff-list__link">{{ staff.fullName }}</a>
</th>
<td>{{ staff.service }}</td>
<td>{{ staff.kommun }}</td>
</tr>
</tbody>
</table>
</digi-table>
<digi-navigation-pagination
*ngIf="staff.length > pagedStaff.length"
class="staff-list__pagination"
[afTotalPages]="totalPages"
[afCurrentResultStart]="currentResultStart"
[afCurrentResultEnd]="currentResultEnd"
[afTotalResults]="staff.length"
(afOnPageChange)="handlePagination($event.detail)"
af-result-name="deltagare"
>
</digi-navigation-pagination>

View File

@@ -1,37 +0,0 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IconType } from '@dafa-enums/icon-type.enum';
import { SortBy } from '@dafa-models/sort-by.model';
import { Staff } from '@dafa-models/staff.model';
import { StaffService } from '@dafa-services/api/staff.service';
import { BehaviorSubject, Observable } from 'rxjs';
@Component({
selector: 'dafa-staff',
templateUrl: './staff.component.html',
styleUrls: ['./staff.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StaffComponent {
private _searchValue$ = new BehaviorSubject<string>('');
filteredStaff$: Observable<Staff[]> = this.staffService.filteredStaff$;
staffSortBy$: Observable<SortBy | null> = this.staffService.staffSortBy$;
iconType = IconType;
constructor(private staffService: StaffService) {}
get searchValue(): string {
return this._searchValue$.getValue();
}
handleSearchSubmit(): void {
this.staffService.setSearchFilter(this.searchValue);
}
handleSearchInput($event: CustomEvent): void {
this._searchValue$.next($event.detail.target.value);
}
handleStaffSort(key: keyof Staff): void {
this.staffService.setStaffSortKey(key);
}
}

View File

@@ -0,0 +1,69 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '@dafa-environment';
import { Employee, EmployeeDetail } from '@dafa-models/employee.model';
import { SortBy } from '@dafa-models/sort-by.model';
import { sort } from '@dafa-utils/sort.util';
import { BehaviorSubject, combineLatest, Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
function filterEmployees(employees: Employee[], searchFilter: string): Employee[] {
return employees.filter(person => {
const searchValueExistsInName = person.fullName.toLowerCase().includes(searchFilter.toLowerCase());
return searchValueExistsInName;
});
}
@Injectable({
providedIn: 'root',
})
export class EmployeeService {
private _employeesApiUrl = `${environment.apiBase}/employees`;
private _allEmployees$: Observable<Employee[]> = this.httpClient.get<Employee[]>(this._employeesApiUrl, {
params: { _embed: 'participants' },
});
private _employeesSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
public employeesSortBy$: Observable<SortBy> = this._employeesSortBy$.asObservable();
private _searchFilter$ = new BehaviorSubject<string>('');
public searchFilter$: Observable<string> = this._searchFilter$.asObservable();
private _filteredEmployees$: Observable<Employee[]> = combineLatest([this._allEmployees$, this._searchFilter$]).pipe(
map(([employees, searchFilter]) => filterEmployees(employees, searchFilter))
);
public filteredEmployees$: Observable<Employee[]> = combineLatest([
this._filteredEmployees$,
this._employeesSortBy$,
]).pipe(
map(([employees, sortBy]) => {
return sortBy ? sort(employees, sortBy) : employees;
})
);
constructor(private httpClient: HttpClient) {}
public getDetailedEmployeeData(id: string): Observable<Employee> {
return this.httpClient.get<Employee>(`${this._employeesApiUrl}/${id}`, { params: { _embed: 'participants' } });
}
public setSearchFilter(value: string) {
this._searchFilter$.next(value);
}
public setEmployeesSortKey(key: keyof Employee) {
const currentSortBy = this._employeesSortBy$.getValue();
const reverse = currentSortBy?.key === key ? !currentSortBy.reverse : false;
this._employeesSortBy$.next({ key, reverse });
}
public createAccount(employeesData: EmployeeDetail): Observable<string> {
return this.httpClient.post<EmployeeDetail>(this._employeesApiUrl, employeesData).pipe(
map(data => data.id),
catchError(error => {
return throwError(error);
})
);
}
}

View File

@@ -1,66 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '@dafa-environment';
import { SortBy } from '@dafa-models/sort-by.model';
import { Staff, StaffDetail } from '@dafa-models/staff.model';
import { sort } from '@dafa-utils/sort.util';
import { BehaviorSubject, combineLatest, Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
function filterStaff(staff: Staff[], searchFilter: string): Staff[] {
return staff.filter(person => {
const searchValueExistsInName = person.fullName.toLowerCase().includes(searchFilter.toLowerCase());
return searchValueExistsInName;
});
}
@Injectable({
providedIn: 'root',
})
export class StaffService {
private _staffApiUrl = `${environment.apiBase}/staff`;
private _allStaff$: Observable<Staff[]> = this.httpClient.get<Staff[]>(this._staffApiUrl, {
params: { _embed: 'participants' },
});
private _staffSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
public staffSortBy$: Observable<SortBy> = this._staffSortBy$.asObservable();
private _searchFilter$ = new BehaviorSubject<string>('');
public searchFilter$: Observable<string> = this._searchFilter$.asObservable();
private _filteredStaff$: Observable<Staff[]> = combineLatest([this._allStaff$, this._searchFilter$]).pipe(
map(([staff, searchFilter]) => filterStaff(staff, searchFilter))
);
public filteredStaff$: Observable<Staff[]> = combineLatest([this._filteredStaff$, this._staffSortBy$]).pipe(
map(([staff, sortBy]) => {
return sortBy ? sort(staff, sortBy) : staff;
})
);
constructor(private httpClient: HttpClient) {}
public getDetailedStaffData(id: string): Observable<Staff> {
return this.httpClient.get<Staff>(`${this._staffApiUrl}/${id}`, { params: { _embed: 'participants' } });
}
public setSearchFilter(value: string) {
this._searchFilter$.next(value);
}
public setStaffSortKey(key: keyof Staff) {
const currentSortBy = this._staffSortBy$.getValue();
const reverse = currentSortBy?.key === key ? !currentSortBy.reverse : false;
this._staffSortBy$.next({ key, reverse });
}
public createAccount(staffData: StaffDetail): Observable<string> {
return this.httpClient.post<StaffDetail>(this._staffApiUrl, staffData).pipe(
map(data => data.id),
catchError(error => {
return throwError(error);
})
);
}
}

View File

@@ -13,13 +13,13 @@ export function mapPathsToBreadcrumbs(
})),
];
if (isStaffCardRoute(paths)) {
if (isEmployeeCardRoute(paths)) {
breadcrumbs[breadcrumbs.length - 1].text = 'Personalkort';
}
return breadcrumbs;
}
function isStaffCardRoute(paths: string[]): boolean {
function isEmployeeCardRoute(paths: string[]): boolean {
return paths.length === 3 && paths[1] === 'personal';
}

View File

@@ -1,5 +1,5 @@
{
"/api/*": "/$1",
"/participants": "/participants?_embed=staff",
"/participant/:id": "/participants/:id?_embed=staff"
"/participants": "/participants?_embed=employees",
"/participant/:id": "/participants/:id?_embed=employees"
}

View File

@@ -14,13 +14,13 @@ const STATUSES = [true, false];
const LANGUAGES = languages.generate();
const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
function generateStaff(amount = 10) {
const staff = [];
function generateEmployees(amount = 10) {
const employees = [];
for (let i = 1; i <= amount; ++i) {
const person = {
id: faker.datatype.uuid(),
staffId: faker.datatype.number(),
employeeId: faker.datatype.number(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
kommun: KOMMUN[Math.floor(Math.random() * KOMMUN.length)].kommun,
@@ -50,13 +50,13 @@ function generateStaff(amount = 10) {
agencies: chooseRandom(AGENCIES, faker.datatype.number(3)),
};
staff.push({ ...person, fullName: `${person.firstName} ${person.lastName}` });
employees.push({ ...person, fullName: `${person.firstName} ${person.lastName}` });
}
console.info('Staff generated...');
return staff;
console.info('Employees generated...');
return employees;
}
export default {
generate: generateStaff,
generate: generateEmployees,
};

View File

@@ -1,22 +1,22 @@
import fs from 'fs';
import agencies from './agencies.js';
import employees from './employees.js';
import kommuner from './kommuner.js';
import languages from './languages.js';
import participants from './participants.js';
import services from './services.js';
import staff from './staff.js';
const generatedStaff = staff.generate(5);
const generatedEmployees = employees.generate(5);
const apiData = {
services: services.generate(),
languages: languages.generate(),
staff: generatedStaff,
employees: generatedEmployees,
kommuner: kommuner.generate(),
agencies: agencies.generate(),
participants: participants.generate(50).map(participant => ({
...participant,
staffId: generatedStaff[Math.floor(Math.random() * generatedStaff.length)].id,
employeeId: generatedEmployees[Math.floor(Math.random() * generatedEmployees.length)].id,
})),
};