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:
Erik Tiekstra
2021-05-20 15:20:29 +02:00
parent dc40953aba
commit 4334fd7364
32 changed files with 339 additions and 204 deletions

View File

@@ -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"
}
}
},

View File

@@ -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));
})
);

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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],
})

View File

@@ -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;
}

View 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;
}

View File

@@ -9,4 +9,8 @@ export enum IconType {
ENVELOPE = 'envelope',
SOK_KANDIDAT = 'sok-kandidat',
EDIT = 'edit',
INFO = 'info',
WARNING = 'warning',
APPROVED = 'approved',
X = 'x',
}

View File

@@ -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,
};
}

View File

@@ -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;
};

View File

@@ -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),
};
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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();

View File

@@ -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) {}
}

View File

@@ -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>

View File

@@ -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;

View File

@@ -0,0 +1,7 @@
export const environment = {
production: false,
api: {
url: '/api',
headers: {},
},
};

View File

@@ -1,8 +1,7 @@
export const environment = {
production: true,
api: {
meet: '/api',
default: '/api',
url: '/api',
headers: {},
},
};

View File

@@ -1,8 +1,7 @@
export const environment = {
production: false,
api: {
meet: '/api',
default: '/api',
url: '/api',
headers: {},
},
};

View File

@@ -0,0 +1,6 @@
{
"/api": {
"target": "http://localhost:6001",
"secure": false
}
}

View File

@@ -1,6 +1,9 @@
{
"/api": {
"target": "http://localhost:8000/",
"secure": false
"target": "http://localhost:8000",
"secure": false,
"pathRewrite": {
"^/api": "/"
}
}
}

View File

@@ -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"
}

View 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,
};

View File

@@ -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...');

View File

@@ -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'));

View File

@@ -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,
};

View File

@@ -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...');

View File

@@ -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",