feat(employee): Now possible to submit edit employee form. (TV-513)
Squashed commit of the following: commit fc79d20601988735b407a54009426e10e233df39 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 13:24:30 2021 +0200 Small fixes commit bc8741bab9b3161d356d1375b7ab869b202a8195 Merge: 1ad9db8cac0515Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 13:16:21 2021 +0200 Merged develop commit 1ad9db87e7f1f19fdb2cd3e2cfcc17e08c9ccfef Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 12:49:37 2021 +0200 Stylechanges commit 5a3b863f87f956ed90564fecbef9abe9460558bd Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 11:26:35 2021 +0200 Now possible to edit employee-accounts commit 0677f2ebeee12adeba6cb65a673781dea7a6c06d Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 10:05:35 2021 +0200 Updated models to include new structure commit 76bde9e0afbbf44a09348ee8e4849b4816b0c39d Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Tue Sep 7 08:43:25 2021 +0200 edit employee commit c8cf93b6bbeef0a3b4b6f141f36aea7ea86f399e Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 16:22:46 2021 +0200 WIP commit fe5cff4aa209c4da0025ebfb70b79d6a95c8d1f1 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 15:46:26 2021 +0200 Fixed issue not fetching new utforande verksamheter on page load commit c997dbe80c8f9f5ec84aad2ac18805918b7ab6f5 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 15:35:34 2021 +0200 Added scrollPositionRestoration commit 58ee0147ff553f2a97fdf143ddcbdf1b0241d26f Merge: 27b595c9a73ffeAuthor: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 15:30:08 2021 +0200 Merge branch 'develop' into feature/TV-513 commit 27b595cbf94dc1d95ad32a0da1943e2e6fce61c4 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 14:28:10 2021 +0200 WIP commit 81cb9df1869784a80f6747ac68bfdc81ae5d777a Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Mon Sep 6 13:21:41 2021 +0200 Fixed roles
This commit is contained in:
@@ -48,7 +48,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'releases',
|
||||
data: { title: 'Releases' },
|
||||
data: { title: 'Releaser' },
|
||||
loadChildren: () => import('./pages/releases/releases.module').then(m => m.ReleasesModule),
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
@@ -89,6 +89,7 @@ routes.push({
|
||||
|
||||
const options: ExtraOptions = {
|
||||
useHash: false,
|
||||
scrollPositionRestoration: 'enabled',
|
||||
};
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -9,12 +9,12 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'personal',
|
||||
data: { title: 'Personalinformation' },
|
||||
data: { title: 'Hantera personal' },
|
||||
loadChildren: () => import('./pages/employees/employees.module').then(m => m.EmployeesModule),
|
||||
},
|
||||
{
|
||||
path: 'personal/:employeeId',
|
||||
data: { title: 'Personalinformation' },
|
||||
data: { title: 'Personalkonto' },
|
||||
loadChildren: () => import('./pages/employee-card/employee-card.module').then(m => m.EmployeeCardModule),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<msfa-layout>
|
||||
<section class="employee-card">
|
||||
<digi-typography *ngIf="employee$ | async as employee; else loadingRef">
|
||||
<ng-container *ngIf="lastUpdatedEmployeeId$ | async as lastUpdatedEmployeeId">
|
||||
<digi-notification-alert
|
||||
*ngIf="employee.id === lastUpdatedEmployeeId"
|
||||
af-variation="success"
|
||||
af-heading="Allt gick bra"
|
||||
af-heading-level="h2"
|
||||
[afCloseable]="true"
|
||||
(afOnClose)="closeUpdatedNotificationAlert()"
|
||||
>
|
||||
<p>Personalkontot för {{employee.fullName}} har uppdaterats.</p>
|
||||
</digi-notification-alert>
|
||||
</ng-container>
|
||||
<header class="employee-card__header">
|
||||
<a class="employee-card__edit-button" [routerLink]="['/administration/redigera-personalkonto', employee.id]"
|
||||
>Redigera</a
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Employee } from '@msfa-models/employee.model';
|
||||
import { Role } from '@msfa-models/role.model';
|
||||
@@ -11,16 +11,30 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||
styleUrls: ['./employee-card.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class EmployeeCardComponent {
|
||||
export class EmployeeCardComponent implements OnDestroy {
|
||||
private _employeeId$ = new BehaviorSubject<string>(this.activatedRoute.snapshot.params['employeeId']);
|
||||
private _pendingSelectedParticipants$ = new BehaviorSubject<string[]>([]);
|
||||
employee$: Observable<Employee> = this.employeeService.employee$;
|
||||
lastUpdatedEmployeeId$: Observable<string> = this.employeeService.lastUpdatedEmployeeId$;
|
||||
allRoles: Role[] = this.employeeService.allRoles;
|
||||
|
||||
constructor(private activatedRoute: ActivatedRoute, private employeeService: EmployeeService) {
|
||||
this.employeeService.setCurrentEmployeeId(this.activatedRoute.snapshot.params.employeeId);
|
||||
this.employeeService.setCurrentEmployeeId(this.employeeId);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.employeeService.resetLastUpdatedEmployeeId();
|
||||
}
|
||||
|
||||
get employeeId(): string {
|
||||
return this._employeeId$.getValue();
|
||||
}
|
||||
|
||||
get pendingSelectedParticipants(): string[] {
|
||||
return this._pendingSelectedParticipants$.getValue();
|
||||
}
|
||||
|
||||
closeUpdatedNotificationAlert(): void {
|
||||
this.employeeService.resetLastUpdatedEmployeeId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +45,14 @@
|
||||
</p>
|
||||
<div class="edit-employee-form__choose_all-utforande-verksamh">
|
||||
<digi-ng-form-checkbox
|
||||
[formControlName]="toggleAllUtforandeVerksamhetFormControlName"
|
||||
[formControl]="toggleAllUtforandeVerksamhetFormControl"
|
||||
[afLabel]="'Välj alla utförande verksamheter och alla utförande adresser'"
|
||||
(afOnChange)="toggleAllUtforandeVerksamheter($event)"
|
||||
>
|
||||
</digi-ng-form-checkbox>
|
||||
</div>
|
||||
<msfa-tree-nodes-selector
|
||||
*ngIf="!toggleAllUtforandeVerksamhetFormControl.value"
|
||||
[headingText]="'Välj utförande verksamheter och adresser'"
|
||||
[formControlName]="utforandeVerksamhetFormControlName"
|
||||
[isInvalid]="utforandeVerksamhetFormControl?.invalid"
|
||||
@@ -99,7 +100,10 @@
|
||||
</fieldset>
|
||||
|
||||
<div class="edit-employee-form__footer">
|
||||
<a class="edit-employee-form__link-btn edit-employee-form__link-btn--secondary" routerLink="/administration/">
|
||||
<a
|
||||
class="edit-employee-form__link-btn edit-employee-form__link-btn--secondary"
|
||||
[routerLink]="['/administration/personal', employee.id]"
|
||||
>
|
||||
Avbryt
|
||||
</a>
|
||||
<digi-button af-type="submit">Spara ändringar</digi-button>
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import { ButtonSize, ButtonType, ButtonVariation } from '@af/digi-ng/_button/button';
|
||||
import { FormSelectItem } from '@af/digi-ng/_form/form-select';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
EventEmitter,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
} from '@angular/core';
|
||||
import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { EmployeeEditRequest } from '@msfa-models/api/employee-edit.request.model';
|
||||
import { Employee } from '@msfa-models/employee.model';
|
||||
import { Role } from '@msfa-models/role.model';
|
||||
import { Tjanst } from '@msfa-models/tjanst.model';
|
||||
import { FormSelectItem } from '@af/digi-ng/_form/form-select';
|
||||
import { TreeNodeValidator } from '@msfa-utils/validators/tree-node.validator';
|
||||
import {
|
||||
UtforandeVerksamhet,
|
||||
UtforandeVerksamheterService,
|
||||
@@ -22,6 +23,9 @@ import {
|
||||
TreeNode,
|
||||
TreeNodesSelectorService,
|
||||
} from '@msfa-shared/components/tree-nodes-selector/services/tree-nodes-selector.service';
|
||||
import { EmailValidator } from '@msfa-utils/validators/email.validator';
|
||||
import { RequiredValidator } from '@msfa-utils/validators/required.validator';
|
||||
import { TreeNodeValidator } from '@msfa-utils/validators/tree-node.validator';
|
||||
import { EmployeeFormService } from '../services/employee-form.service';
|
||||
|
||||
export interface EditEmployeeFormData {
|
||||
@@ -38,15 +42,13 @@ export interface EditEmployeeFormData {
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
@Input() currentEmail: string;
|
||||
@Input() employee: Employee;
|
||||
@Input() availableRoles: Role[];
|
||||
@Input() currentEmployeeRoles: string[];
|
||||
@Input() availableTjanster: Tjanst[];
|
||||
@Input() currentEmployeeTjanster: Tjanst[];
|
||||
@Input() availableUtforandeVerksamheter: UtforandeVerksamhet[];
|
||||
|
||||
@Output() tjansterSelected = new EventEmitter<Tjanst[]>();
|
||||
@Output() formSubmitted = new EventEmitter<EditEmployeeFormData>();
|
||||
@Output() formSubmitted = new EventEmitter<EmployeeEditRequest>();
|
||||
|
||||
readonly ButtonVariation = ButtonVariation;
|
||||
readonly ButtonType = ButtonType;
|
||||
@@ -55,10 +57,9 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
readonly emailFormControlName = 'email';
|
||||
readonly tjansterFormControlName = 'tjanster';
|
||||
readonly utforandeVerksamhetFormControlName = 'utforandeVerksamheter';
|
||||
readonly toggleAllUtforandeVerksamhetFormControlName = 'toggleAllUtforandeVerksamhet';
|
||||
readonly toggleAllUtforandeVerksamhetFormControlName = 'allaUtforandeVerksamheter';
|
||||
|
||||
editEmployeeFormGroup: FormGroup | null = null;
|
||||
rolesFormGroup: FormGroup | null = null;
|
||||
|
||||
displayRolesDialog = false;
|
||||
|
||||
@@ -68,11 +69,13 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
private employeeFormService: EmployeeFormService,
|
||||
private utforandeVerksamheterService: UtforandeVerksamheterService,
|
||||
private treeNodesSelectorService: TreeNodesSelectorService
|
||||
) {}
|
||||
) {
|
||||
this.updateSelectableTjansterFormItems();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.initializeEditEmployeeFormGroup();
|
||||
this.updateSelectableTjansterFormItems();
|
||||
this.toggleTjanst();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
@@ -96,24 +99,8 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
])
|
||||
);
|
||||
|
||||
this.editEmployeeFormGroup.patchValue(
|
||||
Object.fromEntries([[this.toggleAllUtforandeVerksamhetFormControlName, false]])
|
||||
);
|
||||
|
||||
this.updateUtforandeVerksamhetStatus();
|
||||
}
|
||||
|
||||
if (changes.currentEmployeeRoles) {
|
||||
this.updateRolesFormGroup();
|
||||
}
|
||||
|
||||
if (changes.currentEmail) {
|
||||
this.editEmployeeFormGroup.patchValue(Object.fromEntries([[this.emailFormControlName, this.currentEmail]]));
|
||||
}
|
||||
|
||||
if (changes.currentEmployeeTjanster) {
|
||||
this.editEmployeeFormGroup.patchValue(Object.fromEntries([[this.tjansterFormControlName, '']]));
|
||||
}
|
||||
}
|
||||
|
||||
get emailFormControl(): AbstractControl | undefined {
|
||||
@@ -124,6 +111,10 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
return this.editEmployeeFormGroup?.get(this.tjansterFormControlName);
|
||||
}
|
||||
|
||||
get rolesFormGroup(): AbstractControl {
|
||||
return this.editEmployeeFormGroup.get('roles');
|
||||
}
|
||||
|
||||
get utforandeVerksamhetFormControl(): AbstractControl | undefined {
|
||||
return this.editEmployeeFormGroup?.get(this.utforandeVerksamhetFormControlName);
|
||||
}
|
||||
@@ -150,45 +141,25 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
private initializeEditEmployeeFormGroup(): void {
|
||||
this.rolesFormGroup = this.employeeFormService.getRolesFormGroup(this.availableRoles, this.currentEmployeeRoles);
|
||||
|
||||
this.editEmployeeFormGroup = new FormGroup({
|
||||
// eslint-disable-next-line
|
||||
email: new FormControl(this.currentEmail, [Validators.required, Validators.email]),
|
||||
// eslint-disable-next-line
|
||||
tjanster: new FormControl('', [Validators.required]),
|
||||
roles: this.rolesFormGroup,
|
||||
email: new FormControl(this.employee.email, [RequiredValidator('E-postadress'), EmailValidator()]),
|
||||
tjanster: new FormControl(this.employee.tjanster[0]?.tjanstId, [RequiredValidator('Tjänst')]),
|
||||
roles: this.employeeFormService.getRolesFormGroup(this.availableRoles, this.employee.roles),
|
||||
utforandeVerksamheter: new FormControl(
|
||||
this.utforandeVerksamheterService.getTreeNodeDataFromUtforandeVerksamheter(this.availableUtforandeVerksamheter),
|
||||
[
|
||||
// eslint-disable-next-line
|
||||
TreeNodeValidator.IsValidTreeNode(
|
||||
this.utforandeVerksamheterService.hasSelectedUtforandeVerksamhet,
|
||||
'required'
|
||||
),
|
||||
]
|
||||
),
|
||||
toggleAllUtforandeVerksamhet: new FormControl(false, []),
|
||||
allaUtforandeVerksamheter: new FormControl(this.employee.allaUtforandeVerksamheter),
|
||||
});
|
||||
|
||||
this.updateUtforandeVerksamhetStatus();
|
||||
}
|
||||
|
||||
private updateRolesFormGroup(): void {
|
||||
if (!this.rolesFormGroup || !this.availableRoles) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rolesFormGroup.patchValue(
|
||||
Object.fromEntries(
|
||||
this.availableRoles.map(role => [
|
||||
this.employeeFormService.getFormControlName(role),
|
||||
this.employeeFormService.isSelectedRole(role, this.currentEmployeeRoles),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getFormControlName(role: Role): string {
|
||||
return this.employeeFormService.getFormControlName(role);
|
||||
}
|
||||
@@ -206,21 +177,26 @@ export class EditEmployeeFormComponent implements OnInit, OnChanges {
|
||||
|
||||
this.formSubmitted.emit({
|
||||
email: this.emailFormControl?.value as string,
|
||||
tjanster: this.employeeFormService.getSelectedTjanster(
|
||||
this.availableTjanster,
|
||||
parseInt(this.tjansterFormControl?.value, 10)
|
||||
),
|
||||
tjanstIds: this.employeeFormService
|
||||
.getSelectedTjanster(this.availableTjanster, +this.tjansterFormControl?.value)
|
||||
.map(tjanst => tjanst.tjanstId),
|
||||
roles: this.employeeFormService.getRolesFromFormGroup(this.rolesFormGroup, this.availableRoles),
|
||||
utforandeVerksamheter: this.utforandeVerksamheterService.getSelectedUtforandeVerksamheterFromTreeNode(
|
||||
this.utforandeVerksamhetFormControl?.value
|
||||
),
|
||||
adressIds: this.toggleAllUtforandeVerksamhetFormControl.value
|
||||
? []
|
||||
: this.utforandeVerksamheterService.getSelectedAdressIdsFromTreeNode(
|
||||
this.utforandeVerksamhetFormControl?.value
|
||||
),
|
||||
allaUtforandeVerksamheter: !!this.toggleAllUtforandeVerksamhetFormControl.value,
|
||||
utforandeVerksamhetIds: [],
|
||||
});
|
||||
}
|
||||
|
||||
toggleTjanst(): void {
|
||||
this.tjansterSelected.emit(
|
||||
this.employeeFormService.getSelectedTjanster(this.availableTjanster, parseInt(this.tjansterFormControl.value, 10))
|
||||
);
|
||||
if (this.tjansterFormControl.value) {
|
||||
this.tjansterSelected.emit(
|
||||
this.employeeFormService.getSelectedTjanster(this.availableTjanster, +this.tjansterFormControl.value)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
openRolesDialog(): void {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<section class="employee-form" *ngIf="employee$ | async as employee">
|
||||
<digi-typography>
|
||||
<header class="employee-form__header">
|
||||
<h1>{{ employee.fullName }}</h1>
|
||||
<h1>Redigera personalkonto</h1>
|
||||
<msfa-employee-delete [returnToEmployeeList]="true"></msfa-employee-delete>
|
||||
<!-- <digi-button
|
||||
class="employee-card__delete-account-button"
|
||||
@@ -15,7 +15,6 @@
|
||||
</header>
|
||||
</digi-typography>
|
||||
|
||||
<!--### Personuppgifter ###-->
|
||||
<div class="employee-form__block">
|
||||
<digi-typography>
|
||||
<h2>Personuppgifter</h2>
|
||||
@@ -40,18 +39,13 @@
|
||||
</digi-typography>
|
||||
</ng-container>
|
||||
</div>
|
||||
<!-- Component för att hantera formuläret -->
|
||||
<ng-container>
|
||||
<msfa-edit-employee-form
|
||||
[currentEmail]="employee?.email"
|
||||
[availableRoles]="selectableRoles"
|
||||
[currentEmployeeRoles]="currentEmployeeRoles$ | async"
|
||||
[availableTjanster]="tjanster$ | async"
|
||||
[currentEmployeeTjanster]="employee.tjanster"
|
||||
[availableUtforandeVerksamheter]="availableUtforandeVerksamheter$ | async"
|
||||
(tjansterSelected)="setupAvailableUtforandeVerksamheter($event)"
|
||||
(formSubmitted)="updateEmployee($event)"
|
||||
></msfa-edit-employee-form>
|
||||
</ng-container>
|
||||
<msfa-edit-employee-form
|
||||
[employee]="employee"
|
||||
[availableRoles]="availableRoles"
|
||||
[availableTjanster]="tjanster$ | async"
|
||||
[availableUtforandeVerksamheter]="availableUtforandeVerksamheter$ | async"
|
||||
(tjansterSelected)="setupAvailableUtforandeVerksamheter($event)"
|
||||
(formSubmitted)="updateEmployee($event)"
|
||||
></msfa-edit-employee-form>
|
||||
</section>
|
||||
</msfa-layout>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { EmployeeEditRequest } from '@msfa-models/api/employee-edit.request.model';
|
||||
import { Employee } from '@msfa-models/employee.model';
|
||||
import { mapRoleResponseToRoleObject, Role } from '@msfa-models/role.model';
|
||||
import { Role } from '@msfa-models/role.model';
|
||||
import { Tjanst } from '@msfa-models/tjanst.model';
|
||||
import { EmployeeService } from '@msfa-services/api/employee.service';
|
||||
import { TjanstService } from '@msfa-services/api/tjanst.service';
|
||||
@@ -9,9 +10,8 @@ import {
|
||||
UtforandeVerksamhet,
|
||||
UtforandeVerksamheterService,
|
||||
} from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { EditEmployeeFormData } from './edit-employee-form/edit-employee-form.component';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { filter, switchMap } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'msfa-employee-form',
|
||||
@@ -20,40 +20,48 @@ import { EditEmployeeFormData } from './edit-employee-form/edit-employee-form.co
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class EmployeeFormComponent implements OnInit {
|
||||
private _employeeId$ = new BehaviorSubject<string>(this.activatedRoute.snapshot.params['employeeId']);
|
||||
private _selectedTjanstIds$ = new BehaviorSubject<number[]>(null);
|
||||
employee$ = this.employeeService.employee$;
|
||||
tjanster$: Observable<Tjanst[]> = this.tjanstService.tjanster$;
|
||||
currentEmployeeRoles$: Observable<string[] | undefined | null> = null;
|
||||
availableUtforandeVerksamheter$: Observable<Array<UtforandeVerksamhet>> | null = null;
|
||||
availableUtforandeVerksamheter$: Observable<UtforandeVerksamhet[]> = this._selectedTjanstIds$.pipe(
|
||||
filter(selectedTjanstIds => !!selectedTjanstIds?.length),
|
||||
switchMap(selectedTjanstIds => this.utforandeVerksamheterService.getUtforandeVerksamheter(selectedTjanstIds))
|
||||
);
|
||||
|
||||
selectableRoles: Role[] = this.employeeService.allRoles;
|
||||
availableRoles: Role[] = this.employeeService.allRoles;
|
||||
|
||||
constructor(
|
||||
private employeeService: EmployeeService,
|
||||
private tjanstService: TjanstService,
|
||||
private utforandeVerksamheterService: UtforandeVerksamheterService,
|
||||
private activatedRoute: ActivatedRoute
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
get employeeId(): string {
|
||||
return this._employeeId$.getValue();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.employeeService.setCurrentEmployeeId(this.activatedRoute.snapshot.params['employeeId']);
|
||||
|
||||
this.currentEmployeeRoles$ = this.employee$.pipe(
|
||||
map(employee => employee?.roles?.map(role => mapRoleResponseToRoleObject(role)?.type))
|
||||
);
|
||||
this.employeeService.setCurrentEmployeeId(this.employeeId);
|
||||
}
|
||||
|
||||
updateEmployee(editEmployeeFormData: EditEmployeeFormData): void {
|
||||
console.log(editEmployeeFormData);
|
||||
updateEmployee(employeeFormData: EmployeeEditRequest): void {
|
||||
const updateEmployeeSubscription = this.employeeService
|
||||
.updateEmployee$(this.employeeId, employeeFormData)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
void this.router.navigateByUrl(`/administration/personal/${this.employeeId}`);
|
||||
},
|
||||
complete: () => {
|
||||
updateEmployeeSubscription.unsubscribe();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
setupAvailableUtforandeVerksamheter(selectedTjanster: Array<Tjanst>): void {
|
||||
if (!selectedTjanster) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.availableUtforandeVerksamheter$ = this.utforandeVerksamheterService.getUtforandeVerksamheter(
|
||||
selectedTjanster.map(tjanst => tjanst.tjanstId)
|
||||
);
|
||||
setupAvailableUtforandeVerksamheter(selectedTjanster: Tjanst[]): void {
|
||||
this._selectedTjanstIds$.next(selectedTjanster.map(tjanst => tjanst.tjanstId));
|
||||
}
|
||||
setEmployeeToDelete(employee: Employee): void {
|
||||
this.employeeService.setEmployeeToDelete(employee);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { Role } from '@msfa-models/role.model';
|
||||
import { Tjanst } from '@msfa-models/tjanst.model';
|
||||
@@ -9,7 +9,7 @@ import { EmployeeValidator } from '@msfa-utils/validators/employee.validator';
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EmployeeFormService {
|
||||
isSelectedRole(role: Role, selectedRoles: Array<string> | null): boolean {
|
||||
isSelectedRole(role: Role, selectedRoles: RoleEnum[]): boolean {
|
||||
if (!selectedRoles || !role) {
|
||||
return false;
|
||||
}
|
||||
@@ -29,15 +29,15 @@ export class EmployeeFormService {
|
||||
return selectedTjanst ? [selectedTjanst] : [];
|
||||
}
|
||||
|
||||
getRolesFromFormGroup(formGroup: FormGroup | null, roles: Array<Role> | null): Array<Role> {
|
||||
getRolesFromFormGroup(formGroup: AbstractControl | null, roles: Array<Role> | null): Array<RoleEnum> {
|
||||
if (!formGroup || !roles) {
|
||||
return;
|
||||
}
|
||||
|
||||
return roles.filter(role => formGroup.get(this.getFormControlName(role))?.value === true);
|
||||
return roles.filter(role => formGroup.get(this.getFormControlName(role))?.value).map(role => role.type);
|
||||
}
|
||||
|
||||
getRolesFormGroup(roles: Array<Role> | null, selectedRoles: Array<string> | null): FormGroup {
|
||||
getRolesFormGroup(roles: Array<Role> | null, selectedRoles: RoleEnum[]): FormGroup {
|
||||
if (!roles) {
|
||||
return new FormGroup({});
|
||||
}
|
||||
|
||||
@@ -9,16 +9,18 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: ':deltagareId',
|
||||
loadChildren: () => import('./pages/deltagare-card/deltagare-card.module').then(m => m.DeltagareCardModule)
|
||||
data: { title: 'Deltagareinformation' },
|
||||
loadChildren: () => import('./pages/deltagare-card/deltagare-card.module').then(m => m.DeltagareCardModule),
|
||||
},
|
||||
{
|
||||
path: 'rapportera/:deltagareId',
|
||||
loadChildren: () => import('./pages/deltagare-report/deltagare-report.module').then(m => m.DeltagareReportModule)
|
||||
}
|
||||
data: { title: 'Skapa rapport' },
|
||||
loadChildren: () => import('./pages/deltagare-report/deltagare-report.module').then(m => m.DeltagareReportModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class DeltagareRoutingModule { }
|
||||
export class DeltagareRoutingModule {}
|
||||
|
||||
@@ -36,7 +36,7 @@ export class OrganizationPickerComponent extends UnsubscribeDirective {
|
||||
|
||||
const pageTitle = this.activatedRoute?.snapshot?.data?.title as string;
|
||||
|
||||
this.titleService.setTitle(`Mina sidor FA${pageTitle ? ` - ${pageTitle}` : ''}`);
|
||||
this.titleService.setTitle(`Mina sidor för fristående aktörer${pageTitle ? ` - ${pageTitle}` : ''}`);
|
||||
}
|
||||
|
||||
loginWithOrganization(organization: Organization): void {
|
||||
|
||||
@@ -45,7 +45,7 @@ export class LayoutComponent extends UnsubscribeDirective {
|
||||
const pageTitle = this.activatedRoute?.snapshot?.data?.title as string;
|
||||
const urlTree = this.router.parseUrl(this.router.url);
|
||||
|
||||
this.titleService.setTitle(`Mina sidor FA${pageTitle ? ` - ${pageTitle}` : ''}`);
|
||||
this.titleService.setTitle(`Mina sidor för fristående aktörer${pageTitle ? ` - ${pageTitle}` : ''}`);
|
||||
|
||||
if (urlTree.queryParams.code) {
|
||||
void this.router.navigate([], {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@import 'variables/colors';
|
||||
@import 'functions/rem';
|
||||
@import 'mixins/list';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
|
||||
.expanded-tree-node {
|
||||
@@ -50,8 +51,8 @@
|
||||
|
||||
&__node {
|
||||
&--leaf {
|
||||
margin-top: 0.625rem;
|
||||
padding-left: 0.625rem;
|
||||
margin-top: $digi--layout--gutter--s;
|
||||
padding-left: $digi--layout--gutter;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
@@ -60,7 +61,7 @@
|
||||
}
|
||||
|
||||
&__node-checkbox-presentation {
|
||||
font-size: 1rem;
|
||||
font-size: var(--digi--typography--font-size--s);
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
position: relative;
|
||||
@@ -80,7 +81,7 @@
|
||||
}
|
||||
|
||||
&--toggle-all {
|
||||
margin: 1.25rem 0.625rem;
|
||||
margin: 1.25rem $digi--layout--gutter;
|
||||
}
|
||||
|
||||
&--checked &__box {
|
||||
@@ -116,7 +117,7 @@
|
||||
background-color: transparent;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
font-size: 0.875rem;
|
||||
font-size: var(--digi--typography--font-size--s);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
@@ -125,11 +126,6 @@
|
||||
background-color: var(--digi--ui--color--background--secondary);
|
||||
}
|
||||
|
||||
&--focus {
|
||||
border-top: 1px solid var(--digi--typography--color--text--disabled);
|
||||
border-bottom: 1px solid var(--digi--typography--color--text--disabled);
|
||||
}
|
||||
|
||||
&--active {
|
||||
background-color: var(--digi--ui--color--primary);
|
||||
color: var(--digi--ui--color--background);
|
||||
@@ -143,7 +139,8 @@
|
||||
&__text {
|
||||
text-align: left;
|
||||
flex-grow: 1;
|
||||
max-width: 250px;
|
||||
max-width: rem(450);
|
||||
margin-right: $digi--layout--gutter--s;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
@@ -155,7 +152,7 @@
|
||||
height: 1rem;
|
||||
border-radius: 50%;
|
||||
background-color: var(--digi--ui--color--success);
|
||||
margin-right: 10px;
|
||||
margin-right: $digi--layout--gutter--s;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
@import 'variables/colors';
|
||||
@import 'functions/rem';
|
||||
@import 'mixins/list';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/shadows';
|
||||
|
||||
.tree-nodes-selector-panel {
|
||||
position: relative;
|
||||
background-color: var(--digi--ui--color--background);
|
||||
min-width: 710px;
|
||||
min-height: 144px;
|
||||
box-shadow: 0 0.2rem 0.6rem 0 var(--digi--ui--color--shadow);
|
||||
border-radius: 4px;
|
||||
min-width: rem(710);
|
||||
box-shadow: $msfa__shadow;
|
||||
border-radius: var(--digi--ui--border--radius);
|
||||
|
||||
header {
|
||||
margin: 0;
|
||||
@@ -18,13 +20,11 @@
|
||||
|
||||
&__heading {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
padding: 0.625rem 0.9375rem;
|
||||
font-size: var(--digi--typography--font-size--h4);
|
||||
padding: $digi--layout--gutter--m $digi--layout--gutter;
|
||||
border-bottom: 1px solid var(--digi--typography--color--text--disabled);
|
||||
}
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: block;
|
||||
background-image: none;
|
||||
background-color: transparent;
|
||||
border: 0 none transparent;
|
||||
border-width: 0;
|
||||
color: var(--digi--ui--color--danger);
|
||||
padding: 0.625rem 0.9375rem;
|
||||
font-size: 0.875rem;
|
||||
padding: $digi--layout--gutter--m $digi--layout--gutter;
|
||||
font-size: var(--digi--typography--font-size--xs);
|
||||
}
|
||||
|
||||
&__expanded-nodes {
|
||||
@@ -57,11 +56,12 @@
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
overflow: auto;
|
||||
padding-top: 15px;
|
||||
padding-top: $digi--layout--gutter--m;
|
||||
padding-bottom: $digi--layout--gutter--l;
|
||||
border-left: 1px solid var(--digi--typography--color--text--disabled);
|
||||
|
||||
&:first-child {
|
||||
border-left: 0 none transparent;
|
||||
border-left-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--digi--ui--color--background--tertiary);
|
||||
height: 60px;
|
||||
padding: $digi--layout--gutter--m $digi--layout--gutter--l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ButtonSize } from '@af/digi-ng/_button/button';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
Input,
|
||||
Component,
|
||||
ElementRef,
|
||||
ViewChild,
|
||||
Output,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
FilterTreeNodeData,
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
export class TreeNodesSelectorPanelComponent implements OnInit {
|
||||
@Input() rootNode: TreeNodeModel | null = null;
|
||||
@Input() headingText: string;
|
||||
@Input() confirmationButtonText = 'Stäng';
|
||||
@Input() confirmationButtonText = 'Spara';
|
||||
@Output() selectedChangesConfirmed = new EventEmitter<TreeNodeModel>();
|
||||
@Output() closePanelRequested = new EventEmitter<void>();
|
||||
|
||||
|
||||
@@ -8,17 +8,19 @@
|
||||
}
|
||||
|
||||
&__toggle-panel-btn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
border-radius: 0.375rem;
|
||||
border: 1px solid var(--digi--ui--input--border--color);
|
||||
background-color: var(--digi--ui--color--background);
|
||||
color: var(--digi--ui--color--primary);
|
||||
padding: 6px 12px;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: var(--digi--typography--font-size--xs);
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: var(--digi--ui--input--height);
|
||||
padding: var(--digi--ui--input--padding);
|
||||
border: 0.0625rem solid var(--digi--ui--input--border--color);
|
||||
cursor: pointer;
|
||||
font-size: var(--digi--typography--font-size--m);
|
||||
color: var(--digi--ui--color--background--overlay--opaque);
|
||||
background-color: var(--digi--ui--color--background);
|
||||
border-color: var(--digi-form-select--border-color);
|
||||
|
||||
&:focus {
|
||||
border-color: var(--digi--ui--color--focus--light);
|
||||
@@ -60,5 +62,6 @@
|
||||
z-index: 10;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
margin-top: $digi--layout--gutter--xs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
forwardRef,
|
||||
Input,
|
||||
Output,
|
||||
Renderer2,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef,
|
||||
} from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { UUID } from 'angular2-uuid';
|
||||
@@ -37,7 +37,7 @@ interface PropagateTouchedFn {
|
||||
})
|
||||
export class TreeNodesSelectorComponent implements ControlValueAccessor {
|
||||
@Input() headingText: string;
|
||||
@Input() confirmationButtonText = 'Stäng';
|
||||
@Input() confirmationButtonText = 'Spara';
|
||||
@Input() isInvalid = false;
|
||||
@Input() showValidation = false;
|
||||
@Input() validationMessages: Array<string>;
|
||||
|
||||
@@ -2,5 +2,5 @@ export enum RoleEnum {
|
||||
MSFA_AuthAdmin = 'MSFA_AuthAdmin',
|
||||
MSFA_ReceiveDeltagare = 'MSFA_ReceiveDeltagare',
|
||||
MSFA_ReportAndPlanning = 'MSFA_ReportAndPlanning',
|
||||
// MSFA_Standard = 'MSFA_Standard', // Default role
|
||||
MSFA_Standard = 'MSFA_Standard', // Default role
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface AvropTjanstResponse {
|
||||
export interface AvropFilterResponse {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
|
||||
export interface EmployeeEditRequest {
|
||||
email: string;
|
||||
roles: RoleEnum[];
|
||||
tjanstIds: number[];
|
||||
allaUtforandeVerksamheter: boolean;
|
||||
utforandeVerksamhetIds?: number[];
|
||||
adressIds: number[];
|
||||
}
|
||||
@@ -1,5 +1,18 @@
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { PaginationMeta } from '@msfa-models/pagination-meta.model';
|
||||
import { TjanstResponse } from './tjanst.response.model';
|
||||
|
||||
interface UtforandeVerksamhetResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
allaAdresser: boolean;
|
||||
adresser?: AdressResponse[];
|
||||
}
|
||||
|
||||
interface AdressResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface EmployeeCompactResponse {
|
||||
ciamUserId: string;
|
||||
@@ -14,16 +27,19 @@ export interface EmployeeResponse {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
personnummer: string;
|
||||
ssn: string;
|
||||
roles: RoleEnum[];
|
||||
tjansteKoder: string[];
|
||||
tjanster: TjanstResponse[];
|
||||
allaUtforandeVerksamheter: boolean;
|
||||
utforandeVerksamhet: string[];
|
||||
utforandeVerksamheter: UtforandeVerksamhetResponse[];
|
||||
|
||||
// Will be removed
|
||||
tjansteKoder: string[];
|
||||
utforandeVerksamhetIds: number[];
|
||||
adressIds: number[];
|
||||
}
|
||||
|
||||
export interface EmployeesApiResponse {
|
||||
export interface EmployeesDataResponse {
|
||||
data: EmployeeCompactResponse[];
|
||||
meta: PaginationMeta;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export interface KommunResponse {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
export interface TjanstResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
tjanstekod: string;
|
||||
tjanstId: number;
|
||||
id?: string;
|
||||
tjanstId?: number;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export interface UtforandeVerksamhetResponse {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { AvropFilterResponse } from './api/avrop-filter.response.model';
|
||||
|
||||
export interface AvropFilter {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export function mapResponseToAvropFilter(data: AvropFilterResponse): AvropFilter {
|
||||
const { id, label, count } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
label,
|
||||
count,
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { AvropTjanstResponse } from './api/avrop-tjanst.response.model';
|
||||
|
||||
export interface AvropTjanst {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export function mapResponseToAvropTjanst(data: AvropTjanstResponse): AvropTjanst {
|
||||
const { id, label, count } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
label,
|
||||
count,
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,21 @@
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { EmployeeCompactResponse, EmployeeResponse } from './api/employee.response.model';
|
||||
import { PaginationMeta } from './pagination-meta.model';
|
||||
import { Tjanst } from './tjanst.model';
|
||||
import { mapResponseToTjanst, Tjanst } from './tjanst.model';
|
||||
|
||||
const CURRENT_YEAR = new Date().getFullYear().toString().slice(2, 4);
|
||||
|
||||
interface UtforandeVerksamhet {
|
||||
id: number;
|
||||
name: string;
|
||||
allaAdresser: boolean;
|
||||
adresser?: Adress[];
|
||||
}
|
||||
|
||||
interface Adress {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface EmployeeCompact {
|
||||
id: string;
|
||||
@@ -19,9 +33,11 @@ export interface Employee {
|
||||
email: string;
|
||||
ssn: string;
|
||||
roles: RoleEnum[];
|
||||
tjanstCodes: string[];
|
||||
tjanster?: Tjanst[];
|
||||
tjanster: Tjanst[];
|
||||
allaUtforandeVerksamheter: boolean;
|
||||
utforandeVerksamheter: UtforandeVerksamhet[];
|
||||
|
||||
tjanstCodes: string[];
|
||||
utforandeVerksamhetIds: number[];
|
||||
utforandeAdressIds: number[];
|
||||
}
|
||||
@@ -31,26 +47,15 @@ export interface EmployeesData {
|
||||
meta: PaginationMeta;
|
||||
}
|
||||
|
||||
export interface EmployeeRequestData {
|
||||
email: string;
|
||||
roles: string[];
|
||||
tjansteKoder: string[];
|
||||
allaUtforandeVerksamheter: boolean;
|
||||
utforandeVerksamhetIds: number[];
|
||||
adressIds: number[];
|
||||
}
|
||||
|
||||
export function mapEmployeeToRequestData(data: Employee): EmployeeRequestData {
|
||||
const { email, roles, tjanstCodes, allaUtforandeVerksamheter, utforandeVerksamhetIds, utforandeAdressIds } = data;
|
||||
|
||||
return {
|
||||
email,
|
||||
roles,
|
||||
tjansteKoder: tjanstCodes,
|
||||
utforandeVerksamhetIds,
|
||||
adressIds: utforandeAdressIds,
|
||||
allaUtforandeVerksamheter: allaUtforandeVerksamheter,
|
||||
};
|
||||
function mapResponseToSsn(ssn: string): string {
|
||||
if (ssn.length === 10) {
|
||||
const century = +CURRENT_YEAR - +ssn.slice(0, 2) > 0 ? '20' : '19';
|
||||
ssn = ssn.padStart(12, century);
|
||||
}
|
||||
if (ssn.length === 12) {
|
||||
ssn = `${ssn.slice(0, 8)}-${ssn.slice(8, 12)}`;
|
||||
}
|
||||
return ssn;
|
||||
}
|
||||
|
||||
export function mapResponseToEmployeeCompact(data: EmployeeCompactResponse): EmployeeCompact {
|
||||
@@ -70,10 +75,12 @@ export function mapResponseToEmployee(data: EmployeeResponse): Employee {
|
||||
firstName,
|
||||
lastName,
|
||||
email,
|
||||
personnummer,
|
||||
ssn,
|
||||
roles,
|
||||
tjansteKoder,
|
||||
tjanster,
|
||||
allaUtforandeVerksamheter,
|
||||
utforandeVerksamheter,
|
||||
tjansteKoder,
|
||||
utforandeVerksamhetIds,
|
||||
adressIds,
|
||||
} = data;
|
||||
@@ -83,10 +90,12 @@ export function mapResponseToEmployee(data: EmployeeResponse): Employee {
|
||||
lastName,
|
||||
fullName: `${firstName} ${lastName}`,
|
||||
email,
|
||||
ssn: personnummer,
|
||||
ssn: ssn ? mapResponseToSsn(ssn) : null,
|
||||
roles: roles || [],
|
||||
tjanstCodes: tjansteKoder || [],
|
||||
tjanster: tjanster?.map(tjanst => mapResponseToTjanst(tjanst)),
|
||||
allaUtforandeVerksamheter,
|
||||
utforandeVerksamheter,
|
||||
tjanstCodes: tjansteKoder || [],
|
||||
utforandeVerksamhetIds: utforandeVerksamhetIds || [],
|
||||
utforandeAdressIds: adressIds || [],
|
||||
};
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { KommunResponse } from './api/kommun.response.model';
|
||||
|
||||
export interface Kommun {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export function mapKommunResponseToKommun(data: KommunResponse): Kommun {
|
||||
const { id, label, count } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
label,
|
||||
count,
|
||||
};
|
||||
}
|
||||
@@ -5,29 +5,31 @@ export interface Role {
|
||||
type: RoleEnum;
|
||||
}
|
||||
|
||||
export function mapRoleResponseToRoleObject(type: string): Role {
|
||||
switch (type) {
|
||||
// case 'MSFA_Standard':
|
||||
// return {
|
||||
// name: 'Basanvändare',
|
||||
// type: RoleEnum[type],
|
||||
// };
|
||||
case 'MSFA_ReportAndPlanning':
|
||||
return {
|
||||
name: 'Rapportering, planering och information om deltagare',
|
||||
type: RoleEnum[type],
|
||||
};
|
||||
case 'MSFA_ReceiveDeltagare':
|
||||
return {
|
||||
name: 'Ta emot deltagare',
|
||||
type: RoleEnum[RoleEnum[type]],
|
||||
};
|
||||
case 'MSFA_AuthAdmin':
|
||||
return {
|
||||
name: 'Administrera behörigheter',
|
||||
type: RoleEnum[RoleEnum[type]],
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
export function mapResponseToRoles(types: RoleEnum[] = []): Role[] {
|
||||
return types.map(type => {
|
||||
switch (type) {
|
||||
case 'MSFA_Standard':
|
||||
return {
|
||||
name: 'Basanvändare',
|
||||
type: RoleEnum[type],
|
||||
};
|
||||
case 'MSFA_ReportAndPlanning':
|
||||
return {
|
||||
name: 'Rapportering, planering och information om deltagare',
|
||||
type: RoleEnum[type],
|
||||
};
|
||||
case 'MSFA_ReceiveDeltagare':
|
||||
return {
|
||||
name: 'Ta emot deltagare',
|
||||
type: RoleEnum[RoleEnum[type]],
|
||||
};
|
||||
case 'MSFA_AuthAdmin':
|
||||
return {
|
||||
name: 'Administrera behörigheter',
|
||||
type: RoleEnum[RoleEnum[type]],
|
||||
};
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { TjanstResponse } from './api/tjanst.response.model';
|
||||
|
||||
export interface Tjanst {
|
||||
id: string;
|
||||
id?: string;
|
||||
name: string;
|
||||
code: string;
|
||||
tjanstId: number;
|
||||
tjanstId?: number;
|
||||
}
|
||||
|
||||
export function mapResponseToTjanst(data: TjanstResponse): Tjanst {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { UtforandeVerksamhetResponse } from './api/utforande-verksamhet.response.model';
|
||||
|
||||
export interface UtforandeVerksamhet {
|
||||
id: string;
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export function mapUtforandeVerksamhetResponseToUtforandeVerksamhet(
|
||||
data: UtforandeVerksamhetResponse
|
||||
): UtforandeVerksamhet {
|
||||
const { id, label, count } = data;
|
||||
|
||||
return {
|
||||
id,
|
||||
label,
|
||||
count,
|
||||
};
|
||||
}
|
||||
@@ -1,20 +1,13 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AvropTjanstResponse } from '@msfa-models/api/avrop-tjanst.response.model';
|
||||
import { AvropFilterResponse } from '@msfa-models/api/avrop-filter.response.model';
|
||||
import { AvropApiResponse } from '@msfa-models/api/avrop.response.model';
|
||||
import { HandledareResponse } from '@msfa-models/api/handledare.response.model';
|
||||
import { KommunResponse } from '@msfa-models/api/kommun.response.model';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import { UtforandeVerksamhetResponse } from '@msfa-models/api/utforande-verksamhet.response.model';
|
||||
import { AvropTjanst, mapResponseToAvropTjanst } from '@msfa-models/avrop-tjanst.model';
|
||||
import { AvropFilter, mapResponseToAvropFilter } from '@msfa-models/avrop-filter.model';
|
||||
import { AvropCompact, AvropCompactData, mapAvropResponseToAvrop } from '@msfa-models/avrop.model';
|
||||
import { Handledare, mapHandledareResponseToHandledare } from '@msfa-models/handledare.model';
|
||||
import { Kommun, mapKommunResponseToKommun } from '@msfa-models/kommun.model';
|
||||
import {
|
||||
mapUtforandeVerksamhetResponseToUtforandeVerksamhet,
|
||||
UtforandeVerksamhet,
|
||||
} from '@msfa-models/utforande-verksamhet.model';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
import { filter, map, tap } from 'rxjs/operators';
|
||||
|
||||
@@ -62,32 +55,30 @@ export class AvropApiService {
|
||||
);
|
||||
}
|
||||
|
||||
fetchAvailableTjanster$(params: Params): Observable<AvropTjanst[]> {
|
||||
fetchAvailableTjanster$(params: Params): Observable<AvropFilter[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: AvropTjanstResponse[] }>(`${this._apiBaseUrl}/tjanster`, { params })
|
||||
.get<{ data: AvropFilterResponse[] }>(`${this._apiBaseUrl}/tjanster`, { params })
|
||||
.pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(tjanster => mapResponseToAvropTjanst(tjanster)))
|
||||
map(({ data }) => data.map(tjanster => mapResponseToAvropFilter(tjanster)))
|
||||
);
|
||||
}
|
||||
|
||||
fetchAvailableUtforandeVerksamheter$(params: Params): Observable<UtforandeVerksamhet[]> {
|
||||
fetchAvailableUtforandeVerksamheter$(params: Params): Observable<AvropFilter[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: UtforandeVerksamhetResponse[] }>(`${this._apiBaseUrl}/utforandeverksamheter`, { params })
|
||||
.get<{ data: AvropFilterResponse[] }>(`${this._apiBaseUrl}/utforandeverksamheter`, { params })
|
||||
.pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) =>
|
||||
data.map(utforandeverksamheter => mapUtforandeVerksamhetResponseToUtforandeVerksamhet(utforandeverksamheter))
|
||||
)
|
||||
map(({ data }) => data.map(utforandeverksamheter => mapResponseToAvropFilter(utforandeverksamheter)))
|
||||
);
|
||||
}
|
||||
|
||||
fetchAvailableKommuner$(params: Params): Observable<Kommun[]> {
|
||||
fetchAvailableKommuner$(params: Params): Observable<AvropFilter[]> {
|
||||
return this.httpClient
|
||||
.get<{ data: KommunResponse[] }>(`${this._apiBaseUrl}/kommuner`, { params })
|
||||
.get<{ data: AvropFilterResponse[] }>(`${this._apiBaseUrl}/kommuner`, { params })
|
||||
.pipe(
|
||||
filter(response => !!response?.data),
|
||||
map(({ data }) => data.map(kommun => mapKommunResponseToKommun(kommun)))
|
||||
map(({ data }) => data.map(kommun => mapResponseToAvropFilter(kommun)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive';
|
||||
import { ErrorType } from '@msfa-enums/error-type.enum';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { SortOrder } from '@msfa-enums/sort-order.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { EmployeeEditRequest } from '@msfa-models/api/employee-edit.request.model';
|
||||
import { EmployeeInviteResponse } from '@msfa-models/api/employee-invite.response.model';
|
||||
import {
|
||||
EmployeeCompactResponse,
|
||||
EmployeeResponse,
|
||||
EmployeesApiResponse,
|
||||
EmployeesDataResponse,
|
||||
} from '@msfa-models/api/employee.response.model';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import {
|
||||
Employee,
|
||||
EmployeesData,
|
||||
mapEmployeeToRequestData,
|
||||
mapResponseToEmployee,
|
||||
mapResponseToEmployeeCompact,
|
||||
} from '@msfa-models/employee.model';
|
||||
import { errorToCustomError } from '@msfa-models/error/custom-error';
|
||||
import { mapRoleResponseToRoleObject, Role } from '@msfa-models/role.model';
|
||||
import { mapResponseToRoles, Role } from '@msfa-models/role.model';
|
||||
import { Sort } from '@msfa-models/sort.model';
|
||||
import { ErrorService } from '@msfa-services/error.service';
|
||||
import { BehaviorSubject, combineLatest, Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, filter, map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { catchError, distinctUntilChanged, filter, map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { TjanstService } from './tjanst.service';
|
||||
|
||||
@Injectable({
|
||||
@@ -42,6 +41,8 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
public onlyEmployeesWithoutAuthorization$: Observable<boolean> = this._onlyEmployeesWithoutAuthorization$.asObservable();
|
||||
private _employee$ = new BehaviorSubject<Employee>(null);
|
||||
public employee$: Observable<Employee> = this._employee$.asObservable();
|
||||
private _lastUpdatedEmployeeId$ = new BehaviorSubject<string>(null);
|
||||
public lastUpdatedEmployeeId$: Observable<string> = this._lastUpdatedEmployeeId$.asObservable();
|
||||
private _lastDeletedEmployee$ = new BehaviorSubject<Employee>(null);
|
||||
public lastDeletedEmployee$: Observable<Employee> = this._lastDeletedEmployee$.asObservable();
|
||||
private _employeeToDelete$ = new BehaviorSubject<Employee>(null);
|
||||
@@ -54,10 +55,14 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
) {
|
||||
super();
|
||||
super.unsubscribeOnDestroy(
|
||||
this._currentEmployeeId$
|
||||
combineLatest([this._currentEmployeeId$, this._lastUpdatedEmployeeId$])
|
||||
.pipe(
|
||||
filter(currentEmployeeId => !!currentEmployeeId),
|
||||
switchMap(currentEmployeeId =>
|
||||
filter(([currentEmployeeId]) => !!currentEmployeeId),
|
||||
distinctUntilChanged(
|
||||
([prevEmployeeId], [currEmployeeId, currLastUpdatedEmployeeId]) =>
|
||||
!currLastUpdatedEmployeeId && prevEmployeeId === currEmployeeId
|
||||
),
|
||||
switchMap(([currentEmployeeId]) =>
|
||||
combineLatest([this._fetchEmployee$(currentEmployeeId), this.tjanstService.tjanster$]).pipe(
|
||||
filter(([employee, allTjanster]) => !!(employee && allTjanster?.length)),
|
||||
map(([employee, allTjanster]) => {
|
||||
@@ -77,6 +82,29 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
.subscribe(employee => {
|
||||
this._employee$.next(employee as Employee);
|
||||
})
|
||||
// this._currentEmployeeId$
|
||||
// .pipe(
|
||||
// filter(currentEmployeeId => !!currentEmployeeId),
|
||||
// switchMap(currentEmployeeId =>
|
||||
// combineLatest([this._fetchEmployee$(currentEmployeeId), this.tjanstService.tjanster$]).pipe(
|
||||
// filter(([employee, allTjanster]) => !!(employee && allTjanster?.length)),
|
||||
// map(([employee, allTjanster]) => {
|
||||
// const tjanster = [];
|
||||
// employee.tjanstCodes?.forEach(code => {
|
||||
// const currentTjanst = allTjanster.find(tjanst => tjanst.code === code);
|
||||
|
||||
// if (currentTjanst) {
|
||||
// tjanster.push(currentTjanst);
|
||||
// }
|
||||
// });
|
||||
// return { ...employee, tjanster };
|
||||
// })
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// .subscribe(employee => {
|
||||
// this._employee$.next(employee as Employee);
|
||||
// })
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,6 +128,10 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
}
|
||||
}
|
||||
|
||||
public resetLastUpdatedEmployeeId(): void {
|
||||
this._lastUpdatedEmployeeId$.next(null);
|
||||
}
|
||||
|
||||
private _fetchEmployees$(
|
||||
limit: number,
|
||||
page: number,
|
||||
@@ -123,7 +155,7 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
}
|
||||
|
||||
return this.httpClient
|
||||
.get<EmployeesApiResponse>(this._apiBaseUrl, { params })
|
||||
.get<EmployeesDataResponse>(this._apiBaseUrl, { params })
|
||||
.pipe(
|
||||
map(({ data, meta }) => {
|
||||
return { data: data.map(employee => mapResponseToEmployeeCompact(employee)), meta };
|
||||
@@ -175,14 +207,7 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
this._page$.next(page);
|
||||
}
|
||||
|
||||
public postNewEmployee(employeeData: Employee): Observable<string> {
|
||||
return this.httpClient.post<{ id: string }>(this._apiBaseUrl, mapEmployeeToRequestData(employeeData)).pipe(
|
||||
map(({ id }) => id),
|
||||
catchError(error => throwError({ message: error as string, type: ErrorType.API }))
|
||||
);
|
||||
}
|
||||
|
||||
public postEmployeeInvitation(emails: string[]): Observable<EmployeeInviteResponse> {
|
||||
public postEmployeeInvitation(emails: string[]): Observable<EmployeeInviteResponse | null> {
|
||||
return this.httpClient
|
||||
.patch<{ data: EmployeeInviteResponse }>(`${this._apiBaseUrl}/invite`, { emails })
|
||||
.pipe(
|
||||
@@ -195,18 +220,22 @@ export class EmployeeService extends UnsubscribeDirective {
|
||||
);
|
||||
}
|
||||
|
||||
public updateEmployeeData(employeeData: Employee): Observable<string> {
|
||||
return; /* this.httpClient.put<{ id: string }>(`${this._apiBaseUrl}/${employeeData.id}`,
|
||||
mapEmployeeToRequestData(employeeData), API_HEADERS).pipe(
|
||||
map(({ id }) => id),
|
||||
catchError(error => throwError({ message: error as string, type: ErrorType.API }))
|
||||
); */
|
||||
public updateEmployee$(id: string, data: EmployeeEditRequest): Observable<boolean> {
|
||||
return this.httpClient.put<boolean>(`${this._apiBaseUrl}/${id}`, data).pipe(
|
||||
take(1),
|
||||
tap(() => {
|
||||
this._employee$.next(null);
|
||||
this._lastUpdatedEmployeeId$.next(id);
|
||||
}),
|
||||
map(() => true),
|
||||
catchError(error => {
|
||||
this.errorService.add(errorToCustomError(error));
|
||||
return of(false);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public get allRoles(): Role[] {
|
||||
const allAuths: string[] = Object.keys(RoleEnum).filter(item => {
|
||||
return isNaN(Number(item));
|
||||
});
|
||||
return allAuths.map(key => mapRoleResponseToRoleObject(key));
|
||||
return mapResponseToRoles(Object.keys(RoleEnum) as RoleEnum[]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { Params } from '@msfa-models/api/params.model';
|
||||
import {
|
||||
TreeNode,
|
||||
TreeNodesSelectorService,
|
||||
@@ -27,20 +28,21 @@ export class UtforandeVerksamheterService {
|
||||
constructor(private treeNodesSelectorService: TreeNodesSelectorService, private httpClient: HttpClient) {}
|
||||
|
||||
getUtforandeVerksamheter(tjanstIds: Array<number>): Observable<Array<UtforandeVerksamhet>> {
|
||||
let params = new HttpParams();
|
||||
let i: number;
|
||||
|
||||
if (!tjanstIds) {
|
||||
if (!tjanstIds.length) {
|
||||
return of<Array<UtforandeVerksamhet>>([]);
|
||||
}
|
||||
|
||||
for (i = 0; i < tjanstIds.length; i++) {
|
||||
params = params.append('tjansteIds', tjanstIds[i].toString());
|
||||
}
|
||||
const params: Params = { tjansteIds: tjanstIds.map(tjanstId => tjanstId.toString()) };
|
||||
|
||||
return this.httpClient.get<Array<UtforandeVerksamhet>>(`${this.apiBaseUrl}`, { params });
|
||||
}
|
||||
|
||||
getSelectedAdressIdsFromTreeNode(treeNode: TreeNode): number[] {
|
||||
const selectedUtforandeVerksamheter = this.getSelectedUtforandeVerksamheterFromTreeNode(treeNode);
|
||||
|
||||
return selectedUtforandeVerksamheter.map(uv => uv.adresser.map(adress => adress.id)).flat();
|
||||
}
|
||||
|
||||
getTreeNodeDataFromUtforandeVerksamheter(utforandeVerksamhetList: Array<UtforandeVerksamhet>): TreeNode | null {
|
||||
let treeNode: TreeNode | null = null;
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
import { ValidationError } from '@msfa-models/validation-error.model';
|
||||
|
||||
export function RequiredValidator(label = 'Fältet'): ValidatorFn {
|
||||
export function RequiredValidator(label = 'Fältet', arrayValue = false): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationError => {
|
||||
if (control) {
|
||||
if (!control.value) {
|
||||
return { type: 'required', message: `${label} är obligatoriskt` };
|
||||
if ((arrayValue && !control.value) || (Array.isArray(control.value) && !control.value.length)) {
|
||||
return { type: 'required', message: `Minst ${label} behöver väljas` };
|
||||
}
|
||||
|
||||
if (Array.isArray(control.value) && !control.value.length) {
|
||||
return { type: 'required', message: `Minst ${label} behöver väljas` };
|
||||
if (!control.value) {
|
||||
return { type: 'required', message: `${label} är obligatoriskt` };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
@import 'functions/rem';
|
||||
|
||||
// AF DIGI Variables
|
||||
$digi--layout--gutter--xs: var(--digi--layout--gutter--xs);
|
||||
$digi--layout--gutter--s: var(--digi--layout--gutter--s);
|
||||
$digi--layout--gutter--m: rem(12);
|
||||
$digi--layout--gutter: var(--digi--layout--gutter);
|
||||
$digi--layout--gutter--l: rem(25);
|
||||
$digi--layout--gutter--xl: rem(40);
|
||||
$digi--layout--gutter--xxl: rem(60);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "https://mina-sidor-fa-test.tocp.arbetsformedlingen.se",
|
||||
"target": "https://mina-sidor-fa-utv.tocp.arbetsformedlingen.se",
|
||||
"secure": false,
|
||||
"changeOrigin": true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user