feat(api): Added connection to the dotnet api (TV-189)
Squashed commit of the following:
commit 6f06bf69b87c77473c21fbe5fcc5669964793b17
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu May 20 15:01:16 2021 +0200
Fixed issue with including qp insde breadcrumbs
commit 579b6105acc7a60864f07b6082329872a2105bd3
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu May 20 14:46:54 2021 +0200
Added some more data to the mock-api and fixed navigation-bar
commit f9b820136017584655fadafaf716155aec85316e
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Thu May 20 10:11:55 2021 +0200
Updated mock-api
commit 5367d2a475b1c0b8807cf5a9c3f8987b3a586de4
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed May 19 16:00:07 2021 +0200
Added different config for dotnet api
commit 47de5b8ad7c0924c82f07568aa2a4386613e3bd6
Merge: 22d5e9a dc40953
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed May 19 07:54:55 2021 +0200
Merged develop
commit 22d5e9a126e3c1237531407ec3e6d47fbfea55e8
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date: Wed May 12 11:48:25 2021 +0200
Added new configuration to talk with local API
This commit is contained in:
12
angular.json
12
angular.json
@@ -90,6 +90,14 @@
|
||||
"with": "apps/dafa-web/src/environments/environment.pega.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dotnet": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/dafa-web/src/environments/environment.ts",
|
||||
"with": "apps/dafa-web/src/environments/environment.dotnet.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -105,6 +113,10 @@
|
||||
},
|
||||
"pega": {
|
||||
"browserTarget": "dafa-web:build:pega"
|
||||
},
|
||||
"dotnet": {
|
||||
"proxyConfig": "./config/proxy.conf.dotnet.json",
|
||||
"browserTarget": "dafa-web:build:dotnet"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -30,7 +30,12 @@ export class AppComponent extends UnsubscribeDirective {
|
||||
super();
|
||||
super.unsubscribeOnDestroy(
|
||||
this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
||||
const paths = this.router.url.split('/').filter(path => !!path);
|
||||
const urlTree = this.router.parseUrl(this.router.url);
|
||||
urlTree.queryParams = {};
|
||||
const paths = urlTree
|
||||
.toString()
|
||||
.split('/')
|
||||
.filter(path => !!path);
|
||||
this._breadcrumbsItems$.next(mapPathsToBreadcrumbs(paths, this.startBreadcrumb));
|
||||
})
|
||||
);
|
||||
|
||||
@@ -5,6 +5,22 @@
|
||||
</a>
|
||||
</div>
|
||||
<ul class="navigation__list dafa__hide-on-print">
|
||||
<li class="navigation__item navigation__item--user" *ngIf="currentUser">
|
||||
<span class="navigation__text">{{ currentUser.fullName }}</span>
|
||||
<dafa-icon [icon]="iconType.USER" size="l"></dafa-icon>
|
||||
</li>
|
||||
<li class="navigation__item">
|
||||
<a routerLink="/" class="navigation__link">
|
||||
<dafa-icon [icon]="iconType.BELL" size="l"></dafa-icon>
|
||||
<span class="dafa__a11y-sr-only">Notifieringar</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="navigation__item">
|
||||
<a routerLink="installningar" class="navigation__link">
|
||||
<dafa-icon [icon]="iconType.SETTINGS" size="l"></dafa-icon>
|
||||
<span class="dafa__a11y-sr-only">Inställningar</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- <li class="navigation__item">
|
||||
<a
|
||||
class="navigation__link"
|
||||
@@ -16,11 +32,5 @@
|
||||
<span class="navigation__text">Startsida</span>
|
||||
</a>
|
||||
</li> -->
|
||||
<li class="navigation__item" *ngIf="currentUser">
|
||||
<div class="navigation__no-link">
|
||||
<dafa-icon [icon]="iconType.USER" size="l"></dafa-icon>
|
||||
<span class="navigation__text">{{ currentUser.fullName }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import 'mixins/list';
|
||||
@import 'variables/breakpoints';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/navigation';
|
||||
|
||||
.navigation {
|
||||
@@ -36,61 +37,35 @@
|
||||
@include dafa__reset-list;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
gap: $digi--layout--gutter--l;
|
||||
color: var(--digi--typography--color--text--light);
|
||||
margin-right: var(--digi--layout--gutter);
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-left: 1px solid var(--digi--ui--color--background--off);
|
||||
|
||||
&--no-link {
|
||||
padding: 0 var(--digi--layout--gutter);
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid var(--digi--ui--color--background--off);
|
||||
&--user {
|
||||
padding: var(--digi--layout--gutter--s);
|
||||
}
|
||||
}
|
||||
|
||||
&__link,
|
||||
&__no-link {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: --digi--typography--font-size--xs;
|
||||
color: var(--digi--typography--color--text--light);
|
||||
width: 7rem;
|
||||
height: 100%;
|
||||
font-weight: var(--digi--typography--font-weight);
|
||||
&__link {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
color: var(--digi--typography--color--text--light);
|
||||
padding: var(--digi--layout--gutter--s);
|
||||
}
|
||||
|
||||
&__link {
|
||||
&:hover {
|
||||
background-color: $digi--ui--color--primary-light;
|
||||
}
|
||||
|
||||
&--active {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 5px;
|
||||
background-color: $digi--ui--color--secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin-top: var(--digi--layout--gutter--xs);
|
||||
margin-right: var(--digi--layout--gutter);
|
||||
font-size: var(--digi--typography--font-size--xs);
|
||||
// margin-top: var(--digi--layout--gutter--xs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div [ngClass]="className">
|
||||
<div class="toast__icon-wrapper">
|
||||
<digi-icon-exclamation-circle *ngIf="error.severity === errorSeverity.HIGH"></digi-icon-exclamation-circle>
|
||||
<digi-icon-exclamation-triangle *ngIf="error.severity === errorSeverity.MEDIUM"></digi-icon-exclamation-triangle>
|
||||
<digi-icon-check-circle-reg *ngIf="error.severity === errorSeverity.LOW"></digi-icon-check-circle-reg>
|
||||
<dafa-icon [icon]="iconType.INFO" size="l" *ngIf="error.severity === errorSeverity.HIGH"></dafa-icon>
|
||||
<dafa-icon [icon]="iconType.WARNING" size="l" *ngIf="error.severity === errorSeverity.MEDIUM"></dafa-icon>
|
||||
<dafa-icon [icon]="iconType.APPROVED" size="l" *ngIf="error.severity === errorSeverity.LOW"></dafa-icon>
|
||||
</div>
|
||||
<div class="toast__content">
|
||||
<button class="toast__close-button" aria-label="Stäng meddelandet" (click)="emitCloseEvent()">
|
||||
<digi-icon-x></digi-icon-x>
|
||||
<dafa-icon [icon]="iconType.X" size="l"></dafa-icon>
|
||||
</button>
|
||||
<h3 class="toast__heading">{{ error.name }}</h3>
|
||||
<p class="toast__message">{{ error.message }}</p>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { ErrorSeverity } from '@dafa-enums/error-severity.enum';
|
||||
import { IconType } from '@dafa-enums/icon-type.enum';
|
||||
import { CustomError } from '@dafa-models/error/custom-error';
|
||||
|
||||
@Component({
|
||||
@@ -12,6 +13,7 @@ export class ToastComponent implements AfterViewInit {
|
||||
@Input() error: CustomError;
|
||||
@Output() closeToast: EventEmitter<CustomError> = new EventEmitter();
|
||||
|
||||
iconType = IconType;
|
||||
errorSeverity = ErrorSeverity;
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DigiNgIconInfoCircleRegModule } from '@af/digi-ng/_icon/icon-info-circl
|
||||
import { DigiNgIconXModule } from '@af/digi-ng/_icon/icon-x';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { IconModule } from '@dafa-shared/components/icon/icon.module';
|
||||
import { ToastComponent } from './toast.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -15,6 +16,7 @@ import { ToastComponent } from './toast.component';
|
||||
DigiNgIconExclamationCircleModule,
|
||||
DigiNgIconExclamationTriangleModule,
|
||||
DigiNgIconInfoCircleRegModule,
|
||||
IconModule,
|
||||
],
|
||||
exports: [ToastComponent],
|
||||
})
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
export enum AccessGroup {
|
||||
UserManagement = 'UserManagement',
|
||||
Economy = 'Economy',
|
||||
Reports = 'Reports',
|
||||
ParticipantManagement = 'ParticipantManagement',
|
||||
User = 'User',
|
||||
}
|
||||
|
||||
export enum PegaAccessGroup {
|
||||
Users = 'MeetTest:Users',
|
||||
Administrators = 'MeetTest:Administrators',
|
||||
}
|
||||
|
||||
export function mapPegaAccessGroupToAccessGroups(pegaAccessGroup: PegaAccessGroup): AccessGroup[] {
|
||||
const accessGroups: AccessGroup[] = [];
|
||||
switch (pegaAccessGroup) {
|
||||
case PegaAccessGroup.Users:
|
||||
accessGroups.push(AccessGroup.User);
|
||||
break;
|
||||
case PegaAccessGroup.Administrators:
|
||||
accessGroups.push(AccessGroup.UserManagement);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return accessGroups;
|
||||
}
|
||||
28
apps/dafa-web/src/app/data/enums/authorization.enum.ts
Normal file
28
apps/dafa-web/src/app/data/enums/authorization.enum.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
export enum Authorization {
|
||||
UserManagement = 'UserManagement',
|
||||
Economy = 'Economy',
|
||||
Reports = 'Reports',
|
||||
ParticipantManagement = 'ParticipantManagement',
|
||||
User = 'User',
|
||||
}
|
||||
|
||||
export enum PegaAuthorization {
|
||||
Users = 'MeetTest:Users',
|
||||
Administrators = 'MeetTest:Administrators',
|
||||
}
|
||||
|
||||
export function mapPegaAuthorizationToAuthorization(pegaAuthorization: PegaAuthorization): Authorization[] {
|
||||
const authorizations: Authorization[] = [];
|
||||
switch (pegaAuthorization) {
|
||||
case PegaAuthorization.Users:
|
||||
authorizations.push(Authorization.User);
|
||||
break;
|
||||
case PegaAuthorization.Administrators:
|
||||
authorizations.push(Authorization.UserManagement);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return authorizations;
|
||||
}
|
||||
@@ -9,4 +9,8 @@ export enum IconType {
|
||||
ENVELOPE = 'envelope',
|
||||
SOK_KANDIDAT = 'sok-kandidat',
|
||||
EDIT = 'edit',
|
||||
INFO = 'info',
|
||||
WARNING = 'warning',
|
||||
APPROVED = 'approved',
|
||||
X = 'x',
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { mapPegaAccessGroupToAccessGroups, PegaAccessGroup } from '@dafa-enums/access-group.enum';
|
||||
import { Agency } from '@dafa-models/agency.model';
|
||||
import { mapPegaAuthorizationToAuthorization, PegaAuthorization } from '@dafa-enums/authorization.enum';
|
||||
import { Service } from '@dafa-enums/service.enum';
|
||||
import { Participant } from './participant.model';
|
||||
import { User } from './user.model';
|
||||
import { User, UserApiResponse } from './user.model';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface Employee extends User {
|
||||
@@ -10,12 +10,19 @@ export interface Employee extends User {
|
||||
start: Date;
|
||||
end: Date;
|
||||
}[];
|
||||
ssn: string;
|
||||
agencies: Agency[];
|
||||
participants: Participant[];
|
||||
services: Service[];
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
export interface EmployeeApiResponse extends UserApiResponse {
|
||||
active: boolean;
|
||||
services: Service[];
|
||||
languages: string[];
|
||||
participants: Participant[];
|
||||
}
|
||||
|
||||
export interface EmployeesApiResponse {
|
||||
export interface PegaEmployeesApiResponse {
|
||||
pxMore: string;
|
||||
pxObjClass: string;
|
||||
pxPageCount: string;
|
||||
@@ -24,11 +31,11 @@ export interface EmployeesApiResponse {
|
||||
pxTotalResultCount: string;
|
||||
pyMaxRecords: string;
|
||||
pyObjClass: string;
|
||||
pxResults: EmployeeApiResponse[];
|
||||
pxResults: PegaEmployeeApiResponse[];
|
||||
pzPerformanceSettings: string[];
|
||||
}
|
||||
|
||||
export interface EmployeeApiResponse {
|
||||
export interface PegaEmployeeApiResponse {
|
||||
pxInsHandle: string;
|
||||
pxObjClass: string;
|
||||
pyAccessGroup: string;
|
||||
@@ -42,13 +49,13 @@ export interface EmployeeApiResponse {
|
||||
pyUserName: string;
|
||||
}
|
||||
|
||||
export interface EmployeeApiRequestData {
|
||||
export interface PegaEmployeeApiRequestData {
|
||||
pyFirstName: string;
|
||||
pyLastName: string;
|
||||
pyTelephone: string;
|
||||
}
|
||||
|
||||
export interface EmployeeApiPostResponse {
|
||||
export interface PegaEmployeeApiPostResponse {
|
||||
pxObjClass: string;
|
||||
pyErrorMessage: string;
|
||||
pyFirstName: string;
|
||||
@@ -58,7 +65,7 @@ export interface EmployeeApiPostResponse {
|
||||
pyUserIdentifier: string;
|
||||
}
|
||||
|
||||
export function mapEmployeeToEmployeeApiRequestData(data: Employee): EmployeeApiRequestData {
|
||||
export function mapEmployeeToEmployeeApiRequestData(data: Employee): PegaEmployeeApiRequestData {
|
||||
return {
|
||||
pyFirstName: data.firstName,
|
||||
pyLastName: data.lastName,
|
||||
@@ -66,24 +73,65 @@ export function mapEmployeeToEmployeeApiRequestData(data: Employee): EmployeeApi
|
||||
};
|
||||
}
|
||||
|
||||
export function mapEmployeeReponseToEmployee(data: EmployeeApiResponse): Employee {
|
||||
export function mapPegaEmployeeReponseToEmployee(data: PegaEmployeeApiResponse): Employee {
|
||||
return {
|
||||
id: data.pyUserIdentifier,
|
||||
lastName: data.pyLastName,
|
||||
firstName: data.pyFirstName,
|
||||
fullName: `${data.pyFirstName} ${data.pyLastName}`,
|
||||
organization: data.pyOrganization,
|
||||
organizationDivision: data.pyOrgDivision,
|
||||
organizationUnit: data.pyOrgUnit,
|
||||
organization: {
|
||||
id: '',
|
||||
name: data.pyOrganization,
|
||||
kaNumber: null,
|
||||
address: {
|
||||
street: null,
|
||||
houseNumber: null,
|
||||
postalCode: null,
|
||||
city: null,
|
||||
kommun: null,
|
||||
},
|
||||
},
|
||||
phone: data.pyTelephone,
|
||||
email: '',
|
||||
accessGroups: mapPegaAccessGroupToAccessGroups(data.pyAccessGroup as PegaAccessGroup),
|
||||
utforandeverksamhet: '',
|
||||
service: '',
|
||||
authorizations: mapPegaAuthorizationToAuthorization(data.pyAccessGroup as PegaAuthorization),
|
||||
services: [],
|
||||
languages: [],
|
||||
outOfOffice: null,
|
||||
ssn: '',
|
||||
agencies: [],
|
||||
participants: [],
|
||||
active: true,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapEmployeeReponseToEmployee(data: EmployeeApiResponse): Employee {
|
||||
const {
|
||||
id,
|
||||
firstName,
|
||||
lastName,
|
||||
phone,
|
||||
email,
|
||||
ssn,
|
||||
active,
|
||||
services,
|
||||
languages,
|
||||
organization,
|
||||
authorizations,
|
||||
participants,
|
||||
} = data;
|
||||
return {
|
||||
id,
|
||||
firstName,
|
||||
lastName,
|
||||
fullName: `${firstName} ${lastName}`,
|
||||
organization,
|
||||
phone,
|
||||
email,
|
||||
authorizations,
|
||||
services,
|
||||
languages,
|
||||
outOfOffice: null,
|
||||
ssn,
|
||||
participants,
|
||||
active,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export interface Agency {
|
||||
export interface Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
kaNumber: number;
|
||||
kaNumber: string;
|
||||
address: {
|
||||
street: string;
|
||||
houseNumber: number;
|
||||
postalCode: number;
|
||||
houseNumber: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
kommun: string;
|
||||
};
|
||||
@@ -1,21 +1,30 @@
|
||||
import { AccessGroup, mapPegaAccessGroupToAccessGroups, PegaAccessGroup } from '@dafa-enums/access-group.enum';
|
||||
import { Authorization, mapPegaAuthorizationToAuthorization, PegaAuthorization } from '@dafa-enums/authorization.enum';
|
||||
import { Organization } from './organization.model';
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
fullName: string;
|
||||
organization: string;
|
||||
organizationDivision: string;
|
||||
organizationUnit: string;
|
||||
ssn: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
accessGroups: AccessGroup[];
|
||||
utforandeverksamhet: string;
|
||||
service: string;
|
||||
organization: Organization;
|
||||
authorizations: Authorization[];
|
||||
}
|
||||
|
||||
export interface UserApiResponse {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
ssn: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
organization: Organization;
|
||||
authorizations: Authorization[];
|
||||
}
|
||||
|
||||
export interface PegaUserApiResponse {
|
||||
pxInsName: string;
|
||||
pxLimitedAccess: string;
|
||||
pxObjClass: string;
|
||||
@@ -39,19 +48,42 @@ export interface UserApiResponse {
|
||||
};
|
||||
}
|
||||
|
||||
export function mapUserApiReponseToUser(data: UserApiResponse): User {
|
||||
export function mapUserApiResponseToUser(data: UserApiResponse): User {
|
||||
const { id, firstName, lastName, ssn, organization, phone, email, authorizations } = data;
|
||||
return {
|
||||
id,
|
||||
firstName,
|
||||
lastName,
|
||||
fullName: `${firstName} ${lastName}`,
|
||||
ssn,
|
||||
organization,
|
||||
phone,
|
||||
email,
|
||||
authorizations,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapPegaUserApiReponseToUser(data: PegaUserApiResponse): User {
|
||||
return {
|
||||
id: data.pyUserIdentifier,
|
||||
lastName: data.pyLastName,
|
||||
firstName: data.pyFirstName,
|
||||
fullName: `${data.pyFirstName} ${data.pyLastName}`,
|
||||
organization: data.pyOrganization,
|
||||
organizationDivision: data.pyOrgDivision,
|
||||
organizationUnit: data.pyOrgUnit,
|
||||
ssn: null,
|
||||
organization: {
|
||||
id: '',
|
||||
name: data.pyOrganization,
|
||||
kaNumber: null,
|
||||
address: {
|
||||
street: null,
|
||||
houseNumber: null,
|
||||
postalCode: null,
|
||||
city: null,
|
||||
kommun: null,
|
||||
},
|
||||
},
|
||||
phone: data.pyTelephone,
|
||||
email: data.pyAddresses.Email.pyEmailAddress,
|
||||
accessGroups: mapPegaAccessGroupToAccessGroups(data.pyAccessGroup as PegaAccessGroup),
|
||||
utforandeverksamhet: '',
|
||||
service: '',
|
||||
authorizations: mapPegaAuthorizationToAuthorization(data.pyAccessGroup as PegaAuthorization),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,22 +29,14 @@
|
||||
<h2>Uppgifter om arbete</h2>
|
||||
|
||||
<dl>
|
||||
<dt>Organisation</dt>
|
||||
<dd *ngIf="detailedEmployeeData.organization; else emptyDD">{{ detailedEmployeeData.organization }}</dd>
|
||||
<dt>Avdelning</dt>
|
||||
<dd *ngIf="detailedEmployeeData.organizationDivision; else emptyDD">
|
||||
{{ detailedEmployeeData.organizationDivision }}
|
||||
<dt>Utförandeverksamhet</dt>
|
||||
<dd *ngIf="detailedEmployeeData.organization; else emptyDD">
|
||||
{{ detailedEmployeeData.organization.address.city }}
|
||||
</dd>
|
||||
<dt>Behörigheter</dt>
|
||||
<dd *ngIf="detailedEmployeeData.accessGroups?.length; else emptyDD">
|
||||
{{ detailedEmployeeData.accessGroups.join(', ') }}
|
||||
<dd *ngIf="detailedEmployeeData.authorizations?.length; else emptyDD">
|
||||
{{ detailedEmployeeData.authorizations.join(', ') }}
|
||||
</dd>
|
||||
<dt>Behörighet</dt>
|
||||
<ng-container *ngIf="detailedEmployeeData.authorisations?.length; else emptyDD">
|
||||
<dd *ngFor="let item of detailedEmployeeData.authorisations">
|
||||
{{ item }}
|
||||
</dd>
|
||||
</ng-container>
|
||||
<dt>Frånvaroperiod</dt>
|
||||
<ng-container *ngIf="detailedEmployeeData.outOfOffice?.length; else emptyDD">
|
||||
<dd *ngFor="let date of detailedEmployeeData.outOfOffice">
|
||||
@@ -52,7 +44,9 @@
|
||||
</dd>
|
||||
</ng-container>
|
||||
<dt>Tjänst</dt>
|
||||
<dd *ngIf="detailedEmployeeData.service; else emptyDD">{{ detailedEmployeeData.service }}</dd>
|
||||
<dd *ngIf="detailedEmployeeData.services.length; else emptyDD">
|
||||
{{ detailedEmployeeData.services.join(', ') }}
|
||||
</dd>
|
||||
<dt>Språk</dt>
|
||||
<dd>{{ detailedEmployeeData.languages?.join(', ') }}</dd>
|
||||
</dl>
|
||||
|
||||
@@ -13,18 +13,18 @@
|
||||
</button>
|
||||
</th>
|
||||
<th scope="col" class="employees-list__column-head">
|
||||
<button class="employees-list__sort-button" (click)="handleSort('service')">
|
||||
<button class="employees-list__sort-button" (click)="handleSort('services')">
|
||||
Tjänst
|
||||
<ng-container *ngIf="sortBy?.key === 'service'">
|
||||
<ng-container *ngIf="sortBy?.key === 'services'">
|
||||
<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')">
|
||||
<button class="employees-list__sort-button" (click)="handleSort('organization')">
|
||||
Utförandeverksamhet
|
||||
<ng-container *ngIf="sortBy?.key === 'utforandeverksamhet'">
|
||||
<ng-container *ngIf="sortBy?.key === 'organization'">
|
||||
<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>
|
||||
@@ -37,8 +37,8 @@
|
||||
<th scope="row">
|
||||
<a [routerLink]="employees.id" class="employees-list__link">{{ employees.fullName }}</a>
|
||||
</th>
|
||||
<td>{{ employees.service || '-' }}</td>
|
||||
<td>{{ employees.kommun || '-' }}</td>
|
||||
<td>{{ employees.services.length ? employees.services.join(', ') : '-' }}</td>
|
||||
<td>{{ employees.organization.address.city || '-' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -4,10 +4,10 @@ import { ErrorType } from '@dafa-enums/error-type.enum';
|
||||
import { environment } from '@dafa-environment';
|
||||
import {
|
||||
Employee,
|
||||
EmployeeApiPostResponse,
|
||||
EmployeesApiResponse,
|
||||
EmployeeApiResponse,
|
||||
mapEmployeeReponseToEmployee,
|
||||
mapEmployeeToEmployeeApiRequestData,
|
||||
PegaEmployeeApiPostResponse,
|
||||
} from '@dafa-models/employee.model';
|
||||
import { SortBy } from '@dafa-models/sort-by.model';
|
||||
import { sort } from '@dafa-utils/sort.util';
|
||||
@@ -23,14 +23,13 @@ const API_HEADERS = { headers: environment.api.headers };
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EmployeeService {
|
||||
private _employeesApiUrl = `${environment.api.meet}/employees`;
|
||||
private _employeeApiUrl = `${environment.api.meet}/employee`;
|
||||
private _employeesRawData: Observable<EmployeesApiResponse> = this.httpClient.get<EmployeesApiResponse>(
|
||||
this._employeesApiUrl,
|
||||
private _employeeApiUrl = `${environment.api.url}/employee`;
|
||||
private _employeesRawData: Observable<EmployeeApiResponse[]> = this.httpClient.get<EmployeeApiResponse[]>(
|
||||
this._employeeApiUrl,
|
||||
API_HEADERS
|
||||
);
|
||||
private _allEmployees$: Observable<Employee[]> = this._employeesRawData.pipe(
|
||||
map(({ pxResults }) => pxResults.map(result => mapEmployeeReponseToEmployee(result)))
|
||||
map(results => results.map(result => mapEmployeeReponseToEmployee(result)))
|
||||
);
|
||||
|
||||
private _employeesSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'fullName', reverse: false });
|
||||
@@ -42,7 +41,7 @@ export class EmployeeService {
|
||||
map(([employees, searchFilter]) => filterEmployees(employees, searchFilter))
|
||||
);
|
||||
|
||||
public resultCount$: Observable<number> = this._employeesRawData.pipe(map(({ pxResultCount }) => +pxResultCount));
|
||||
public resultCount$: Observable<number> = this._employeesRawData.pipe(map(results => results.length)); // TODO: need META
|
||||
public filteredEmployees$: Observable<Employee[]> = combineLatest([
|
||||
this._filteredEmployees$,
|
||||
this._employeesSortBy$,
|
||||
@@ -56,8 +55,8 @@ export class EmployeeService {
|
||||
|
||||
public getDetailedEmployeeData(id: string): Observable<Employee> {
|
||||
return this.httpClient
|
||||
.get<EmployeesApiResponse>(`${this._employeeApiUrl}`, { ...API_HEADERS, params: { OperatorId: id } })
|
||||
.pipe(map(({ pxResults }) => mapEmployeeReponseToEmployee(pxResults[0])));
|
||||
.get<EmployeeApiResponse>(`${this._employeeApiUrl}/${id}`, { ...API_HEADERS })
|
||||
.pipe(map(result => mapEmployeeReponseToEmployee(result)));
|
||||
}
|
||||
|
||||
public setSearchFilter(value: string) {
|
||||
@@ -72,7 +71,7 @@ export class EmployeeService {
|
||||
|
||||
public postNewEmployee(employeeData: Employee): Observable<string> {
|
||||
return this.httpClient
|
||||
.post<EmployeeApiPostResponse>(
|
||||
.post<PegaEmployeeApiPostResponse>(
|
||||
this._employeeApiUrl,
|
||||
mapEmployeeToEmployeeApiRequestData(employeeData),
|
||||
API_HEADERS
|
||||
|
||||
@@ -22,7 +22,7 @@ function filterParticipants(participants: Participant[], searchFilter: string):
|
||||
})
|
||||
export class ParticipantsService {
|
||||
private _allParticipants$: Observable<Participant[]> = this.httpClient.get<Participant[]>(
|
||||
`${environment.api.meet}/participants`
|
||||
`${environment.api.url}/participants`
|
||||
);
|
||||
private _activeParticipantsSortBy$ = new BehaviorSubject<SortBy | null>({ key: 'handleBefore', reverse: false });
|
||||
public activeParticipantsSortBy$: Observable<SortBy> = this._activeParticipantsSortBy$.asObservable();
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '@dafa-environment';
|
||||
import { mapUserApiReponseToUser, User, UserApiResponse } from '@dafa-models/user.model';
|
||||
import { mapUserApiResponseToUser, User, UserApiResponse } from '@dafa-models/user.model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
const API_HEADERS = { headers: environment.api.headers };
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UserService {
|
||||
private _userApiUrl = `${environment.api.default}/D_OperatorID`;
|
||||
private _userApiUrl = `${environment.api.url}/currentUser`;
|
||||
public currentUser$: Observable<User> = this.httpClient
|
||||
.get<UserApiResponse>(this._userApiUrl, {
|
||||
headers: environment.api.headers,
|
||||
})
|
||||
.pipe(map(response => mapUserApiReponseToUser(response)));
|
||||
.get<UserApiResponse>(this._userApiUrl, API_HEADERS)
|
||||
.pipe(map(response => mapUserApiResponseToUser(response)));
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
}
|
||||
|
||||
@@ -35,5 +35,12 @@
|
||||
<digi-icon-envelope-filled *ngSwitchCase="iconType.ENVELOPE" [ngClass]="iconClass"></digi-icon-envelope-filled>
|
||||
<digi-icon-sokkandidat *ngSwitchCase="iconType.SOK_KANDIDAT" [ngClass]="iconClass"></digi-icon-sokkandidat>
|
||||
<digi-icon-edit *ngSwitchCase="iconType.EDIT" [ngClass]="iconClass"></digi-icon-edit>
|
||||
<digi-icon-exclamation-circle *ngSwitchCase="iconType.INFO" [ngClass]="iconClass"></digi-icon-exclamation-circle>
|
||||
<digi-icon-exclamation-triangle
|
||||
*ngSwitchCase="iconType.WARNING"
|
||||
[ngClass]="iconClass"
|
||||
></digi-icon-exclamation-triangle>
|
||||
<digi-icon-check-circle-reg *ngSwitchCase="iconType.APPROVED" [ngClass]="iconClass"></digi-icon-check-circle-reg>
|
||||
<digi-icon-x *ngSwitchCase="iconType.X" [ngClass]="iconClass"></digi-icon-x>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
@@ -14,7 +14,7 @@ export function mapPathsToBreadcrumbs(
|
||||
];
|
||||
|
||||
if (isEmployeeCardRoute(paths)) {
|
||||
breadcrumbs[breadcrumbs.length - 1].text = 'Personalkort';
|
||||
breadcrumbs[breadcrumbs.length - 1].text = 'Personal information';
|
||||
}
|
||||
|
||||
return breadcrumbs;
|
||||
|
||||
7
apps/dafa-web/src/environments/environment.dotnet.ts
Normal file
7
apps/dafa-web/src/environments/environment.dotnet.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
api: {
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
@@ -1,8 +1,7 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
api: {
|
||||
meet: '/api',
|
||||
default: '/api',
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
api: {
|
||||
meet: '/api',
|
||||
default: '/api',
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
|
||||
6
config/proxy.conf.dotnet.json
Normal file
6
config/proxy.conf.dotnet.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "http://localhost:6001",
|
||||
"secure": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "http://localhost:8000/",
|
||||
"secure": false
|
||||
"target": "http://localhost:8000",
|
||||
"secure": false,
|
||||
"pathRewrite": {
|
||||
"^/api": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"/api/*": "/$1",
|
||||
"/participants": "/participants?_embed=employees",
|
||||
"/participant/:id": "/participants/:id?_embed=employees"
|
||||
"/participant/:id": "/participants/:id?_embed=employees",
|
||||
"/employee": "/employees",
|
||||
"/employee/:id": "/employees/:id"
|
||||
}
|
||||
|
||||
28
mock-api/dafa-web/scripts/current-user.js
Normal file
28
mock-api/dafa-web/scripts/current-user.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import faker from 'faker';
|
||||
import organizations from './organizations.js';
|
||||
import chooseRandom from './utils/choose-random.util.js';
|
||||
|
||||
faker.locale = 'sv';
|
||||
|
||||
const ORGANIZATIONS = organizations.generate();
|
||||
const AUTHORIZATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
|
||||
|
||||
function generateCurrentUser() {
|
||||
return {
|
||||
id: faker.datatype.uuid(),
|
||||
firstName: faker.name.firstName(),
|
||||
lastName: faker.name.lastName(),
|
||||
ssn: `${faker.date.between('1950', '2000').toISOString().split('T')[0].replace(/-/g, '')}-${faker.datatype.number({
|
||||
min: 1000,
|
||||
max: 9999,
|
||||
})}`,
|
||||
phone: `07${faker.datatype.number(9)}-${faker.datatype.number({ min: 1000000, max: 9999999 })}`,
|
||||
email: faker.internet.email(),
|
||||
organization: ORGANIZATIONS[Math.floor(Math.random() * ORGANIZATIONS.length)],
|
||||
authorizations: chooseRandom(AUTHORIZATIONS, faker.datatype.number(3)),
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
generate: generateCurrentUser,
|
||||
};
|
||||
@@ -1,18 +1,17 @@
|
||||
import faker from 'faker';
|
||||
import agencies from './agencies.js';
|
||||
import kommuner from './kommuner.js';
|
||||
import languages from './languages.js';
|
||||
import organizations from './organizations.js';
|
||||
import services from './services.js';
|
||||
import chooseRandom from './utils/choose-random.util.js';
|
||||
|
||||
faker.locale = 'sv';
|
||||
|
||||
const SERVICES = services.generate();
|
||||
const KOMMUN = kommuner.generate();
|
||||
const AGENCIES = agencies.generate();
|
||||
const ORGANIZATIONS = organizations.generate();
|
||||
const STATUSES = [true, false];
|
||||
const LANGUAGES = languages.generate();
|
||||
const AUTHORISATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
|
||||
const AUTHORIZATIONS = ['Hantera användare', 'Hantera origisation', 'Hantera ekonomi'];
|
||||
|
||||
function generateEmployees(amount = 10) {
|
||||
const employees = [];
|
||||
@@ -20,16 +19,8 @@ function generateEmployees(amount = 10) {
|
||||
for (let i = 1; i <= amount; ++i) {
|
||||
const person = {
|
||||
id: faker.datatype.uuid(),
|
||||
employeeId: faker.datatype.number(),
|
||||
firstName: faker.name.firstName(),
|
||||
lastName: faker.name.lastName(),
|
||||
kommun: KOMMUN[Math.floor(Math.random() * KOMMUN.length)].kommun,
|
||||
active: STATUSES[Math.floor(Math.random() * STATUSES.length)],
|
||||
service: SERVICES[Math.floor(Math.random() * SERVICES.length)].name,
|
||||
languages: [
|
||||
LANGUAGES.find(language => language.name === 'Svenska'),
|
||||
...chooseRandom(LANGUAGES, faker.datatype.number(3)),
|
||||
],
|
||||
ssn: `${faker.date.between('1950', '2000').toISOString().split('T')[0].replace(/-/g, '')}-${faker.datatype.number(
|
||||
{
|
||||
min: 1000,
|
||||
@@ -38,19 +29,25 @@ function generateEmployees(amount = 10) {
|
||||
)}`,
|
||||
phone: `07${faker.datatype.number(9)}-${faker.datatype.number({ min: 1000000, max: 9999999 })}`,
|
||||
email: faker.internet.email(),
|
||||
authorisations: chooseRandom(AUTHORISATIONS, faker.datatype.number(3)),
|
||||
outOfOffice: STATUSES[Math.floor(Math.random() * STATUSES.length)]
|
||||
? [
|
||||
{
|
||||
start: new Date('2021-07-12'),
|
||||
end: new Date('2021-07-24'),
|
||||
},
|
||||
]
|
||||
: [],
|
||||
agencies: chooseRandom(AGENCIES, faker.datatype.number(3)),
|
||||
organization: ORGANIZATIONS[Math.floor(Math.random() * ORGANIZATIONS.length)],
|
||||
services: [SERVICES[Math.floor(Math.random() * SERVICES.length)].name],
|
||||
authorizations: AUTHORIZATIONS,
|
||||
// active: STATUSES[Math.floor(Math.random() * STATUSES.length)],
|
||||
// languages: [
|
||||
// LANGUAGES.find(language => language.name === 'Svenska'),
|
||||
// ...chooseRandom(LANGUAGES, faker.datatype.number(3)),
|
||||
// ],
|
||||
// outOfOffice: STATUSES[Math.floor(Math.random() * STATUSES.length)]
|
||||
// ? [
|
||||
// {
|
||||
// start: new Date('2021-07-12'),
|
||||
// end: new Date('2021-07-24'),
|
||||
// },
|
||||
// ]
|
||||
// : [],
|
||||
};
|
||||
|
||||
employees.push({ ...person, fullName: `${person.firstName} ${person.lastName}` });
|
||||
employees.push(person);
|
||||
}
|
||||
|
||||
console.info('Employees generated...');
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
import fs from 'fs';
|
||||
import agencies from './agencies.js';
|
||||
import currentUser from './current-user.js';
|
||||
import employees from './employees.js';
|
||||
import kommuner from './kommuner.js';
|
||||
import languages from './languages.js';
|
||||
import organizations from './organizations.js';
|
||||
import participants from './participants.js';
|
||||
import services from './services.js';
|
||||
|
||||
const generatedEmployees = employees.generate(5);
|
||||
const generatedEmployees = employees.generate(10);
|
||||
|
||||
const apiData = {
|
||||
services: services.generate(),
|
||||
languages: languages.generate(),
|
||||
employees: generatedEmployees,
|
||||
kommuner: kommuner.generate(),
|
||||
agencies: agencies.generate(),
|
||||
organizations: organizations.generate(),
|
||||
participants: participants.generate(50).map(participant => ({
|
||||
...participant,
|
||||
employeeId: generatedEmployees[Math.floor(Math.random() * generatedEmployees.length)].id,
|
||||
})),
|
||||
currentUser: currentUser.generate(),
|
||||
};
|
||||
|
||||
fs.writeFileSync('api.json', JSON.stringify(apiData, null, '\t'));
|
||||
|
||||
@@ -5,11 +5,11 @@ faker.locale = 'sv';
|
||||
|
||||
const KOMMUN = kommuner.generate();
|
||||
|
||||
function generateAgencies(amount = 10) {
|
||||
const agencies = [];
|
||||
function generateOrganizations(amount = 10) {
|
||||
const organizations = [];
|
||||
|
||||
for (let i = 1; i <= amount; ++i) {
|
||||
agencies.push({
|
||||
organizations.push({
|
||||
id: faker.datatype.uuid(),
|
||||
name: faker.company.companyName(),
|
||||
kaNumber: faker.datatype.number({ min: 100000, max: 999999 }),
|
||||
@@ -23,11 +23,11 @@ function generateAgencies(amount = 10) {
|
||||
});
|
||||
}
|
||||
|
||||
console.info('Agencies generated...');
|
||||
console.info('Organizations generated...');
|
||||
|
||||
return agencies;
|
||||
return organizations;
|
||||
}
|
||||
|
||||
export default {
|
||||
generate: generateAgencies,
|
||||
generate: generateOrganizations,
|
||||
};
|
||||
@@ -6,20 +6,20 @@ function generateServices() {
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'STOM',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'KVL',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'YSM',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'AUB',
|
||||
},
|
||||
// {
|
||||
// id: 3,
|
||||
// name: 'STOM',
|
||||
// },
|
||||
// {
|
||||
// id: 4,
|
||||
// name: 'YSM',
|
||||
// },
|
||||
// {
|
||||
// id: 5,
|
||||
// name: 'AUB',
|
||||
// },
|
||||
];
|
||||
|
||||
console.info('Services generated...');
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
"nx": "nx",
|
||||
"start": "ng serve dafa-web",
|
||||
"start:pega": "ng serve dafa-web --configuration pega",
|
||||
"start:dotnet": "ng serve dafa-web --configuration dotnet",
|
||||
"build": "ng build dafa-web",
|
||||
"build:pega": "ng build dafa-web --configuration pega",
|
||||
"build:dotnet": "ng build dafa-web --configuration dotnet",
|
||||
"test": "ng test dafa-web",
|
||||
"release": "bash ./tools/release.sh",
|
||||
"release:dry": "bash ./tools/release.sh dry",
|
||||
|
||||
Reference in New Issue
Block a user