Renamed staff to employees
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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]);
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
@@ -1,7 +1,7 @@
|
||||
@import 'variables/gutters';
|
||||
@import 'mixins/list';
|
||||
|
||||
.staff-card {
|
||||
.employee-card {
|
||||
&__contents {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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 {
|
||||
@@ -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 {}
|
||||
@@ -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>
|
||||
@@ -1,6 +1,6 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
.staff-list {
|
||||
.employees-list {
|
||||
&__column-head {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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>
|
||||
@@ -1,5 +1,6 @@
|
||||
@import 'variables/gutters';
|
||||
.staff {
|
||||
|
||||
.employees {
|
||||
&__cta-wrapper {
|
||||
margin-top: var(--digi--layout--gutter);
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
69
apps/dafa-web/src/app/services/api/employee.service.ts
Normal file
69
apps/dafa-web/src/app/services/api/employee.service.ts
Normal 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);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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,
|
||||
})),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user