From 9d96f0d972a75bfc361074419c22ee64644efa24 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Fri, 10 Dec 2021 08:07:06 +0100 Subject: [PATCH] Pull request #291: Feature/TV-945 felhantering 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge in TEA/mina-sidor-fa-web from feature/TV-945-felhantering-2 to develop Squashed commit of the following: commit 9e581d36dfecb901fbd4c04eb5b8a80e77a51216 Author: Erik Tiekstra Date: Tue Dec 7 15:29:20 2021 +0100 Fixed last few error-handling issues commit eb35f23d05d8584673ea3f8f28a67206bb21a3cf Author: Erik Tiekstra Date: Tue Dec 7 15:17:45 2021 +0100 Renamed api-services commit e2764cb623701afadfb6455e77b8f6e718c1523a Author: Erik Tiekstra Date: Tue Dec 7 15:13:54 2021 +0100 Improved error-handling for user and refactored user(api)service commit 78cbdc6695653646eee73f1583ef6e272158d50a Author: Erik Tiekstra Date: Tue Dec 7 13:53:52 2021 +0100 Improved error-handling for tjanst commit 9b4ae985f9a92ed1eb7a9d823b37ce7cc069c417 Author: Erik Tiekstra Date: Tue Dec 7 13:35:41 2021 +0100 Improved error-handling for slutredovisning commit 37bb43bde8151075450cd988715d6b9cb2ab8b1b Author: Erik Tiekstra Date: Tue Dec 7 13:32:18 2021 +0100 Improved error-handling for signal commit a8e3bfb4a222d05abfdcb5b415dc93682731c14d Author: Erik Tiekstra Date: Tue Dec 7 13:23:22 2021 +0100 Improved error-handling for periodisk redovisning commit f1eb5cb768fb662412ef73026586a88982ea56c7 Author: Erik Tiekstra Date: Tue Dec 7 13:19:24 2021 +0100 Improved error-handling for news commit cd81cade46bc28d70a67f3a54dc571c3e348606a Author: Erik Tiekstra Date: Tue Dec 7 13:19:15 2021 +0100 Improved error-handling for informativ rapport commit bff13ae4e54b40546266d46f0595aa3594cf32ca Author: Erik Tiekstra Date: Tue Dec 7 13:16:29 2021 +0100 Improved error-handling for handlingar commit 9264f0aa63fdb6e260cf3221cee838795bd095dc Merge: 174264e4 8f0b7016 Author: Erik Tiekstra Date: Tue Dec 7 13:05:30 2021 +0100 Merge branch 'develop' into feature/TV-945-felhantering-2 commit 174264e495296c87f6d60b5e017a95b8f0efe76e Author: Erik Tiekstra Date: Mon Dec 6 12:59:41 2021 +0100 Improved error-handling for handledare commit c1430f375f3baf604ec153405f40eb51c84b5eb9 Author: Erik Tiekstra Date: Mon Dec 6 12:48:18 2021 +0100 Improved error-handling for export, frånvaroreport, gemensam planering --- .../accessibility/accessibility.component.ts | 2 +- .../employee-form/employee-form.component.ts | 6 +- .../services/employee-form.service.ts | 13 +- .../employee-invite.component.ts | 4 +- .../deltagare-card.component.html | 10 +- .../deltagare-card.component.ts | 58 +++++---- .../avvikelse-report-form.service.ts | 2 +- .../gemensam-planering-form.service.ts | 10 +- .../periodisk-redovisning-form.service.ts | 4 +- .../slutredovisning-form.service.ts | 4 +- .../avvikelse-report-view.service.ts | 2 +- .../gemensam-planering-view.service.ts | 2 +- .../periodisk-redovisning-view.service.ts | 8 +- .../pages/my-account/my-account.component.ts | 2 +- .../organization-picker.component.ts | 2 +- .../src/app/pages/start/start.component.ts | 2 +- .../src/app/pages/start/start.service.ts | 3 +- .../components/layout/layout.component.html | 2 +- .../components/layout/layout.component.ts | 11 +- .../app/shared/guards/organization.guard.ts | 2 +- .../src/app/shared/guards/role.guard.ts | 2 +- ...op-api.service.ts => avrop.api.service.ts} | 0 ...pi.service.ts => avvikelse.api.service.ts} | 0 ....ts => deltagare-handelser.api.service.ts} | 0 .../shared/services/api/export.api.service.ts | 8 +- .../api/franvaro-report.api.service.ts | 48 +++---- .../api/gemensam-planering-api.service.ts | 57 --------- .../api/gemensam-planering.api.service.ts | 65 ++++++++++ .../services/api/handledare.api.service.ts | 26 +++- .../services/api/handlingar.api.service.ts | 105 ++++++++++++++-- .../api/informativ-rapport.api.service.ts | 13 +- .../shared/services/api/news.api.service.ts | 11 +- .../api/periodisk-redovisning.api.service.ts | 18 +-- .../shared/services/api/signal.api.service.ts | 9 +- .../api/slutredovisning.api.service.ts | 38 +++--- .../shared/services/api/tjanst.api.service.ts | 30 +++++ .../app/shared/services/api/tjanst.service.ts | 36 ------ .../shared/services/api/user.api.service.ts | 45 +++++++ .../app/shared/services/api/user.service.ts | 118 ------------------ .../src/app/shared/services/avrop.service.ts | 2 +- .../services/deltagare-handelser.service.ts | 2 +- .../app/shared/services/handledare.service.ts | 6 - .../src/app/shared/services/role.service.ts | 2 - .../src/app/shared/services/user.service.ts | 74 +++++++++++ 44 files changed, 483 insertions(+), 381 deletions(-) rename apps/mina-sidor-fa/src/app/shared/services/api/{avrop-api.service.ts => avrop.api.service.ts} (100%) rename apps/mina-sidor-fa/src/app/shared/services/api/{avvikelse-api.service.ts => avvikelse.api.service.ts} (100%) rename apps/mina-sidor-fa/src/app/shared/services/api/{deltagare-handelser-api.service.ts => deltagare-handelser.api.service.ts} (100%) delete mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering-api.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering.api.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/tjanst.api.service.ts delete mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/tjanst.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/user.api.service.ts delete mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/user.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/services/user.service.ts diff --git a/apps/mina-sidor-fa/src/app/pages/accessibility/accessibility.component.ts b/apps/mina-sidor-fa/src/app/pages/accessibility/accessibility.component.ts index 1f101cb..31943f9 100644 --- a/apps/mina-sidor-fa/src/app/pages/accessibility/accessibility.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/accessibility/accessibility.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { Role } from '@msfa-models/role.model'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/employee-form.component.ts b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/employee-form.component.ts index 861e02b..964abd9 100644 --- a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/employee-form.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/employee-form.component.ts @@ -7,11 +7,11 @@ import { Role } from '@msfa-models/role.model'; import { Tjanst } from '@msfa-models/tjanst.model'; import { UtforandeVerksamhet } from '@msfa-models/utforande-verksamhet.model'; import { EmployeeService } from '@msfa-services/api/employee.service'; -import { TjanstService } from '@msfa-services/api/tjanst.service'; import { RoleService } from '@msfa-services/role.service'; import { UtforandeVerksamheterService } from '@msfa-services/utforande-verksamheter/utforande-verksamheter.service'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { catchError, mapTo, startWith, switchMap } from 'rxjs/operators'; +import { EmployeeFormService } from './services/employee-form.service'; @Component({ selector: 'msfa-employee-form', @@ -30,7 +30,7 @@ export class EmployeeFormComponent implements OnInit { errorWhileUpdating$: Observable = this._errorWhileUpdating$.asObservable(); employee$ = this.employeeService.employee$; - tjanster$: Observable = this.tjanstService.tjanster$; + tjanster$: Observable = this.employeeFormService.fetchTjanster$(); availableRoles: Role[] = this.roleService.allRoles; isLoadingUtforandeVerksamheter$: Observable; @@ -38,7 +38,7 @@ export class EmployeeFormComponent implements OnInit { constructor( private employeeService: EmployeeService, private roleService: RoleService, - private tjanstService: TjanstService, + private employeeFormService: EmployeeFormService, private utforandeVerksamheterService: UtforandeVerksamheterService, private activatedRoute: ActivatedRoute, private router: Router diff --git a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/services/employee-form.service.ts b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/services/employee-form.service.ts index 3c479a3..213cfa7 100644 --- a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/services/employee-form.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-form/services/employee-form.service.ts @@ -2,12 +2,23 @@ import { Injectable } from '@angular/core'; 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'; +import { mapResponseToTjanst, Tjanst } from '@msfa-models/tjanst.model'; +import { TjanstApiService } from '@msfa-services/api/tjanst.api.service'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root', }) export class EmployeeFormService { + constructor(private tjanstApiService: TjanstApiService) {} + + fetchTjanster$(): Observable { + return this.tjanstApiService + .fetchTjanster$() + .pipe(map(({ data }) => data.map(tjanst => mapResponseToTjanst(tjanst)))); + } + isSelectedRole(role: Role, selectedRoles: RoleEnum[]): boolean { if (!selectedRoles || !role) { return false; diff --git a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-invite/employee-invite.component.ts b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-invite/employee-invite.component.ts index a87d959..174652a 100644 --- a/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-invite/employee-invite.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/administration/pages/employee-invite/employee-invite.component.ts @@ -99,9 +99,9 @@ export class EmployeeInviteComponent { this._lastInvites$.next(data); this.formGroup.reset(); }, - error: error => { + error: (error: CustomError) => { this.submitIsLoading$.next(false); - throw new CustomError(error); + throw error; }, complete: () => { post.unsubscribe(); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/deltagare-card.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/deltagare-card.component.html index c560886..1c73d85 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/deltagare-card.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/deltagare-card.component.html @@ -14,12 +14,12 @@ (afOnToggle)="setActiveTab('0')" af-aria-label="Deltagare & tjänst" af-id="deltagare-card-personal-information" - *ngIf="deltagareTjanstVisible" + *ngIf="deltagareTjanstVisible$ | async" > @@ -27,7 +27,7 @@ (afOnToggle)="setActiveTab('1')" af-aria-label="Rapportering" af-id="deltagare-card-reports" - *ngIf="reportingTabVisible" + *ngIf="reportingTabVisible$ | async" > = this.userService.userRoles$; + + deltagareTjanstVisible$: Observable = this._userRoles$.pipe( + map(roles => + roles.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning || role.type === RoleEnum.MSFA_ReceiveDeltagare) + ) + ); + handledarePickerVisible$: Observable = this._userRoles$.pipe( + map(roles => roles.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare)) + ); + reportingTabVisible$: Observable = this._userRoles$.pipe( + map( + roles => + roles.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning) && + this._activeFeatures.includes(Feature.REPORTING) + ) + ); + experiencesVisible$: Observable = this._userRoles$.pipe( + map(roles => roles.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)) + ); + sensitiveDataVisible$: Observable = this._userRoles$.pipe( + map( + roles => + roles.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning) && + this._activeFeatures.includes(Feature.DELTAGARE_SENSITIVE_INFORMATION) + ) + ); contactInformation$: Observable = this.deltagareCardService.contactInformation$; @@ -41,34 +67,6 @@ export class DeltagareCardComponent extends UnsubscribeDirective implements OnDe ); } - get deltagareTjanstVisible(): boolean { - return this._userRoles?.some( - role => role.type === RoleEnum.MSFA_ReportAndPlanning || role.type === RoleEnum.MSFA_ReceiveDeltagare - ); - } - - get handledarePickerVisible(): boolean { - return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare); - } - - get reportingTabVisible(): boolean { - return ( - this._activeFeatures.includes(Feature.REPORTING) && - this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning) - ); - } - - get experiencesVisible(): boolean { - return this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning); - } - - get sensitiveDataVisible(): boolean { - return ( - this._activeFeatures.includes(Feature.DELTAGARE_SENSITIVE_INFORMATION) && - this._userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning) - ); - } - setActiveTab(tabId: string): void { this.deltagareCardService.setActiveTab(tabId); } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/avvikelse-report-form/avvikelse-report-form.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/avvikelse-report-form/avvikelse-report-form.service.ts index 12e37d7..677078d 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/avvikelse-report-form/avvikelse-report-form.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/avvikelse-report-form/avvikelse-report-form.service.ts @@ -3,7 +3,7 @@ import { AvvikelseReportRequest } from '@msfa-models/api/avvikelse-request.model import { DeltagareAvrop } from '@msfa-models/avrop.model'; import { AvvikelseQuestion } from '@msfa-models/avvikelse-question.model'; import { AvvikelseReason, sortAvvikelseReasons } from '@msfa-models/avvikelse-reason.model'; -import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service'; +import { AvvikelseApiService } from '@msfa-services/api/avvikelse.api.service'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/gemensam-planering-form/gemensam-planering-form.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/gemensam-planering-form/gemensam-planering-form.service.ts index 364a581..809df39 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/gemensam-planering-form/gemensam-planering-form.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/gemensam-planering-form/gemensam-planering-form.service.ts @@ -2,17 +2,21 @@ import { Injectable } from '@angular/core'; import { Activity } from '@msfa-models/activity.model'; import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model'; import { DeltagareAvrop } from '@msfa-models/avrop.model'; -import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering.api.service'; import { Observable } from 'rxjs'; @Injectable() export class GemensamPlaneringFormService { public activities$: Observable = this.gemensamPlaneringApiService.fetchActivities$(); - constructor(private gemensamPlaneringApiService: GemensamPlaneringApiService) {} + constructor( + private gemensamPlaneringApiService: GemensamPlaneringApiService, + private deltagareApiService: DeltagareApiService + ) {} public fetchAvropInformation$(genomforandeReferens: number): Observable { - return this.gemensamPlaneringApiService.fetchAvropInformation$(genomforandeReferens); + return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); } public postGemensamPlanering$(requestData: GemensamPlaneringPostRequest): Observable { diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/periodisk-redovisning-form/periodisk-redovisning-form.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/periodisk-redovisning-form/periodisk-redovisning-form.service.ts index 6bcf5ab..d85922c 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/periodisk-redovisning-form/periodisk-redovisning-form.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/periodisk-redovisning-form/periodisk-redovisning-form.service.ts @@ -3,7 +3,7 @@ import { Activity, mapResponseToActivity } from '@msfa-models/activity.model'; import { PeriodiskRedovisningRequest } from '@msfa-models/api/periodisk-redovisning.request.model'; import { DeltagareAvrop } from '@msfa-models/avrop.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering.api.service'; import { PeriodiskRedovisningApiService } from '@msfa-services/api/periodisk-redovisning.api.service'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -26,7 +26,7 @@ export class PeriodiskRedovisningFormService { getAllChosenActivities(genomforandeReferens: number): Observable { return this.gemensamPlaneringApiService - .fetchAllChosenActivities(genomforandeReferens) + .fetchAllChosenActivities$(genomforandeReferens) .pipe(map(({ data }) => data.map(activity => mapResponseToActivity(activity)))); } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts index 2b33b6a..bfde201 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts @@ -4,7 +4,7 @@ import { SlutredovisningRequest } from '@msfa-models/api/slutredovisning.request import { DeltagareAvrop } from '@msfa-models/avrop.model'; import { mapResponseToYrkesomrade, Yrkesomrade, yrkeToTextMap } from '@msfa-models/yrkesomrade.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering.api.service'; import { SlutredovisningApiService } from '@msfa-services/api/slutredovisning.api.service'; import { BehaviorSubject, Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; @@ -70,7 +70,7 @@ export class SlutredovisningFormService { getAllChosenActivities(genomforandeReferens: number): Observable { return this.gemensamPlaneringApiService - .fetchAllChosenActivities(genomforandeReferens) + .fetchAllChosenActivities$(genomforandeReferens) .pipe(map(({ data }) => data.map(activity => mapResponseToActivity(activity)))); } } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/avvikelse-report-view/avvikelse-report-view.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/avvikelse-report-view/avvikelse-report-view.service.ts index 56134db..dbb7d1e 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/avvikelse-report-view/avvikelse-report-view.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/avvikelse-report-view/avvikelse-report-view.service.ts @@ -3,7 +3,7 @@ import { DeltagareAvrop } from '@msfa-models/avrop.model'; import { AvvikelseQuestion } from '@msfa-models/avvikelse-question.model'; import { AvvikelseReason } from '@msfa-models/avvikelse-reason.model'; import { AvvikelseReport, mapResponseToAvvikelse } from '@msfa-models/avvikelse.model'; -import { AvvikelseApiService } from '@msfa-services/api/avvikelse-api.service'; +import { AvvikelseApiService } from '@msfa-services/api/avvikelse.api.service'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { HandlingarApiService } from '@msfa-services/api/handlingar.api.service'; import { combineLatest, Observable } from 'rxjs'; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/gemensam-planering-view/gemensam-planering-view.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/gemensam-planering-view/gemensam-planering-view.service.ts index c69b86e..d36cf27 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/gemensam-planering-view/gemensam-planering-view.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/gemensam-planering-view/gemensam-planering-view.service.ts @@ -6,7 +6,7 @@ import { mapResponseToGemensamPlaneringDetailed, } from '@msfa-models/gemensam-planering.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering.api.service'; import { HandlingarApiService } from '@msfa-services/api/handlingar.api.service'; import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/periodisk-redovisning-view/periodisk-redovisning-view.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/periodisk-redovisning-view/periodisk-redovisning-view.service.ts index 53c06ab..44a5785 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/periodisk-redovisning-view/periodisk-redovisning-view.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/periodisk-redovisning-view/periodisk-redovisning-view.service.ts @@ -3,8 +3,8 @@ import { Activity } from '@msfa-models/activity.model'; import { DeltagareAvrop } from '@msfa-models/avrop.model'; import { mapResponseToPeriodiskRedovisning, PeriodiskRedovisning } from '@msfa-models/periodisk-redovisning.model'; import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; -import { PeriodiskRedovisningApiService } from '@msfa-services/api/periodisk-redovisning.api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering.api.service'; +import { HandlingarApiService } from '@msfa-services/api/handlingar.api.service'; import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; @@ -13,7 +13,7 @@ export class PeriodiskRedovisningViewService { private _activities$: Observable = this.gemensamPlaneringApiService.fetchActivities$(); constructor( - private periodiskRedovisningApiService: PeriodiskRedovisningApiService, + private handlingarApiService: HandlingarApiService, private gemensamPlaneringApiService: GemensamPlaneringApiService, private deltagareApiService: DeltagareApiService ) {} @@ -25,7 +25,7 @@ export class PeriodiskRedovisningViewService { public fetchPeriodiskRedovisning$(handlingId: string): Observable { return this._activities$.pipe( switchMap(activities => - this.periodiskRedovisningApiService + this.handlingarApiService .fetchPeriodiskRedovisning$(handlingId) .pipe(map(({ data }) => mapResponseToPeriodiskRedovisning(data, activities))) ) diff --git a/apps/mina-sidor-fa/src/app/pages/my-account/my-account.component.ts b/apps/mina-sidor-fa/src/app/pages/my-account/my-account.component.ts index 2f7881d..ca4c6f2 100644 --- a/apps/mina-sidor-fa/src/app/pages/my-account/my-account.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/my-account/my-account.component.ts @@ -4,8 +4,8 @@ import { environment } from '@msfa-environment'; import { Employee } from '@msfa-models/employee.model'; import { Organization } from '@msfa-models/organization.model'; import { Role } from '@msfa-models/role.model'; -import { UserService } from '@msfa-services/api/user.service'; import { RoleService } from '@msfa-services/role.service'; +import { UserService } from '@msfa-services/user.service'; import { UiIconType } from '@ui/icon/icon-type.enum'; import { combineLatest, Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.ts b/apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.ts index 1710a17..91c46ad 100644 --- a/apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.ts @@ -3,7 +3,7 @@ import { Title } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive'; import { Organization } from '@msfa-models/organization.model'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { Observable } from 'rxjs'; import { filter } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/pages/start/start.component.ts b/apps/mina-sidor-fa/src/app/pages/start/start.component.ts index 1a9efd3..3e22fe6 100644 --- a/apps/mina-sidor-fa/src/app/pages/start/start.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/start/start.component.ts @@ -3,7 +3,7 @@ import { Feature } from '@msfa-enums/feature.enum'; import { environment } from '@msfa-environment'; import { News } from '@msfa-models/news.model'; import { Role } from '@msfa-models/role.model'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; import { StartService } from './start.service'; diff --git a/apps/mina-sidor-fa/src/app/pages/start/start.service.ts b/apps/mina-sidor-fa/src/app/pages/start/start.service.ts index 4768355..a6126ed 100644 --- a/apps/mina-sidor-fa/src/app/pages/start/start.service.ts +++ b/apps/mina-sidor-fa/src/app/pages/start/start.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { CustomError } from '@msfa-models/error/custom-error'; import { mapNewsResponseToNews, News } from '@msfa-models/news.model'; import { NewsApiService } from '@msfa-services/api/news.api.service'; import { BehaviorSubject, Observable } from 'rxjs'; @@ -19,7 +20,7 @@ export class StartService { this._newsLoading$.next(false); return mapNewsResponseToNews(response); }), - catchError(error => { + catchError((error: CustomError) => { this._newsLoading$.next(false); throw error; }) diff --git a/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.html b/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.html index 39cac2d..4589323 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.html +++ b/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.html @@ -14,4 +14,4 @@ - + diff --git a/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.ts b/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.ts index 3527e14..245ebc5 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.ts +++ b/apps/mina-sidor-fa/src/app/shared/components/layout/layout.component.ts @@ -6,10 +6,10 @@ import { Employee } from '@msfa-models/employee.model'; import { Organization } from '@msfa-models/organization.model'; import { Role } from '@msfa-models/role.model'; import { AuthenticationService } from '@msfa-services/api/authentication.service'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { mapPathsToBreadcrumbs } from '@msfa-utils/map-paths-to-breadcrumbs.util'; import { BehaviorSubject, Observable } from 'rxjs'; -import { filter } from 'rxjs/operators'; +import { filter, switchMap } from 'rxjs/operators'; @Component({ selector: 'msfa-layout', @@ -22,8 +22,11 @@ export class LayoutComponent extends UnsubscribeDirective { selectedOrganization$: Observable = this.userService.selectedOrganization$; user$: Observable = this.userService.user$.pipe(filter(user => !!user)); roles$: Observable = this.userService.userRoles$.pipe(filter(roles => !!roles)); - userLoading$: Observable = this.userService.userLoading$; - rolesLoading$: Observable = this.userService.userRolesLoading$; + isLoggedIn$: Observable = this.authenticationService.isLoggedIn$; + userLoading$: Observable = this.isLoggedIn$.pipe( + filter(isLoggedIn => !!isLoggedIn), + switchMap(() => this.userService.userLoading$) + ); private readonly _startBreadcrumb: NavigationBreadcrumbsItem = { text: 'Start', routerLink: '/', diff --git a/apps/mina-sidor-fa/src/app/shared/guards/organization.guard.ts b/apps/mina-sidor-fa/src/app/shared/guards/organization.guard.ts index 94fd76f..0ef2d56 100644 --- a/apps/mina-sidor-fa/src/app/shared/guards/organization.guard.ts +++ b/apps/mina-sidor-fa/src/app/shared/guards/organization.guard.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { CanActivate, Router } from '@angular/router'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/shared/guards/role.guard.ts b/apps/mina-sidor-fa/src/app/shared/guards/role.guard.ts index cd69dc3..72ba687 100644 --- a/apps/mina-sidor-fa/src/app/shared/guards/role.guard.ts +++ b/apps/mina-sidor-fa/src/app/shared/guards/role.guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; import { RoleEnum } from '@msfa-enums/role.enum'; -import { UserService } from '@msfa-services/api/user.service'; +import { UserService } from '@msfa-services/user.service'; import { Observable } from 'rxjs'; import { filter, map } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/avrop-api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/avrop.api.service.ts similarity index 100% rename from apps/mina-sidor-fa/src/app/shared/services/api/avrop-api.service.ts rename to apps/mina-sidor-fa/src/app/shared/services/api/avrop.api.service.ts diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/avvikelse.api.service.ts similarity index 100% rename from apps/mina-sidor-fa/src/app/shared/services/api/avvikelse-api.service.ts rename to apps/mina-sidor-fa/src/app/shared/services/api/avvikelse.api.service.ts diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/deltagare-handelser-api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/deltagare-handelser.api.service.ts similarity index 100% rename from apps/mina-sidor-fa/src/app/shared/services/api/deltagare-handelser-api.service.ts rename to apps/mina-sidor-fa/src/app/shared/services/api/deltagare-handelser.api.service.ts diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/export.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/export.api.service.ts index f9b9b87..4064a7b 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/export.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/export.api.service.ts @@ -1,7 +1,6 @@ import { HttpClient, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Params } from '@angular/router'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { DeltagareExportRequest } from '@msfa-models/api/deltagare-export.request.model'; import { CustomError } from '@msfa-models/error/custom-error'; @@ -22,9 +21,10 @@ export class ExportApiService { ...requestData, includeExportedDeltagare: requestData.includeExportedDeltagare.toString(), }; + const apiUrl = `${this._apiBaseUrl}/deltagare`; return this.httpClient - .get(`${this._apiBaseUrl}/deltagare`, { + .get(apiUrl, { params, observe: 'response', responseType: 'blob' as 'json', @@ -37,7 +37,9 @@ export class ExportApiService { throw new CustomError({ error, message: `Kunde inte hämta exportfilen för deltagare.\n\n${error.message}`, - type: ErrorType.API, + name: `GET ${apiUrl}`, + data: params, + method: 'ExportApiService.fetchDeltagareExportFile$', }); }) ); diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts index 9da22d8..89f2851 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/franvaro-report.api.service.ts @@ -1,13 +1,10 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { FranvaroReasonResponse } from '@msfa-models/api/franvaro-reason.response.model'; import { FranvaroReportRequest } from '@msfa-models/api/franvaro-request.model'; -import { DeltagareAvrop } from '@msfa-models/avrop.model'; -import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; +import { CustomError } from '@msfa-models/error/custom-error'; import { FranvaroReason, mapResponseToFranvaroReason } from '@msfa-models/franvaro-reason.model'; -import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; import { Observable } from 'rxjs'; import { catchError, filter, map, shareReplay } from 'rxjs/operators'; @@ -17,44 +14,51 @@ import { catchError, filter, map, shareReplay } from 'rxjs/operators'; export class FranvaroReportApiService { private _apiBaseUrl = `${environment.api.url}/rapporter`; - constructor(private httpClient: HttpClient, private deltagareApiService: DeltagareApiService) {} + constructor(private httpClient: HttpClient) {} public fetchReasons$(): Observable { - return this.httpClient.get<{ data: FranvaroReasonResponse[] }>(`${this._apiBaseUrl}/orsakskoderfranvaro`).pipe( + const apiUrl = `${this._apiBaseUrl}/orsakskoderfranvaro`; + return this.httpClient.get<{ data: FranvaroReasonResponse[] }>(apiUrl).pipe( filter(response => !!response?.data), map(({ data }) => data.map(reason => mapResponseToFranvaroReason(reason))), - catchError((error: Error & { status: number }) => { - throw new CustomError( - errorToCustomError({ ...error, message: `Kunde inte hämta orsaker till frånvaro.\n\n${error.message}` }) - ); + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta orsaker till frånvaro.\n\n${error.message}`, + name: `GET ${apiUrl}`, + method: 'FranvaroReportApiService.fetchReasons$', + }); }), shareReplay(1) ); } public fetchOtherKnownReasons$(): Observable { - return this.httpClient.get<{ data: FranvaroReasonResponse[] }>(`${this._apiBaseUrl}/kandaavvikelsekoder`).pipe( + const apiUrl = `${this._apiBaseUrl}/kandaavvikelsekoder`; + return this.httpClient.get<{ data: FranvaroReasonResponse[] }>(apiUrl).pipe( filter(response => !!response?.data), map(({ data }) => data.map(reason => mapResponseToFranvaroReason(reason))), - catchError((error: Error & { status: number }) => { - throw new CustomError( - errorToCustomError({ ...error, message: `Kunde inte hämta kända orsaker till frånvaro.\n\n${error.message}` }) - ); + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta kända orsaker till frånvaro.\n\n${error.message}`, + name: `GET ${apiUrl}`, + method: 'FranvaroReportApiService.fetchOtherKnownReasons$', + }); }), shareReplay(1) ); } - public fetchAvropInformation$(genomforandeReferens: number): Observable { - return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); - } - - public postFranvaroReport$(requestData: FranvaroReportRequest): Observable { - return this.httpClient.post(`${this._apiBaseUrl}/franvaro`, requestData).pipe( + public postFranvaroReport$(data: FranvaroReportRequest): Observable { + const apiUrl = `${this._apiBaseUrl}/franvaro`; + return this.httpClient.post(apiUrl, data).pipe( catchError((error: Error) => { throw new CustomError({ error, message: `Kunde inte spara Avvikelserapport (frånvaro).\n\n${error.message}`, - type: ErrorType.API, + name: `POST ${apiUrl}`, + data, + method: 'FranvaroReportApiService.postFranvaroReport$', }); }) ); diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering-api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering-api.service.ts deleted file mode 100644 index 547ea2c..0000000 --- a/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering-api.service.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; -import { environment } from '@msfa-environment'; -import { Activity, mapResponseToActivity } from '@msfa-models/activity.model'; -import { ActivityResponse } from '@msfa-models/api/activity.response.model'; -import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model'; -import { DeltagareAvrop } from '@msfa-models/avrop.model'; -import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; -import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; -import { Observable } from 'rxjs'; -import { catchError, filter, map, shareReplay } from 'rxjs/operators'; - -@Injectable({ - providedIn: 'root', -}) -export class GemensamPlaneringApiService { - private _apiBaseUrl = `${environment.api.url}/rapporter/gemensam-planering`; - private _apiHandlingarUrl = `${environment.api.url}/handlingar`; - - public fetchActivities$(): Observable { - return this.httpClient.get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/aktiviteter`).pipe( - filter(response => !!response?.data), - map(({ data }) => data.map(activity => mapResponseToActivity(activity))), - catchError((error: Error & { status: number }) => { - throw new CustomError( - errorToCustomError({ ...error, message: `Kunde inte hämta aktiviteter.\n\n${error.message}` }) - ); - }), - shareReplay(1) - ); - } - - public fetchAvropInformation$(genomforandeReferens: number): Observable { - return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); - } - - public fetchAllChosenActivities(genomforandereferens: number): Observable<{ data: ActivityResponse[] }> { - return this.httpClient.get<{ data: ActivityResponse[] }>( - `${this._apiBaseUrl}/alla-valda-aktiviteter/${genomforandereferens}` - ); - } - - public postGemensamPlanering$(requestData: GemensamPlaneringPostRequest): Observable { - return this.httpClient.post(`${this._apiBaseUrl}`, requestData).pipe( - catchError((error: Error) => { - throw new CustomError({ - error, - message: `Kunde inte spara Gemensam planering.\n\n${error.message}`, - type: ErrorType.API, - }); - }) - ); - } - - constructor(private httpClient: HttpClient, private deltagareApiService: DeltagareApiService) {} -} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering.api.service.ts new file mode 100644 index 0000000..318008c --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/api/gemensam-planering.api.service.ts @@ -0,0 +1,65 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from '@msfa-environment'; +import { Activity, mapResponseToActivity } from '@msfa-models/activity.model'; +import { ActivityResponse } from '@msfa-models/api/activity.response.model'; +import { GemensamPlaneringPostRequest } from '@msfa-models/api/gemensam-planering.request.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Observable } from 'rxjs'; +import { catchError, filter, map, shareReplay } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root', +}) +export class GemensamPlaneringApiService { + private _apiBaseUrl = `${environment.api.url}/rapporter/gemensam-planering`; + + public fetchActivities$(): Observable { + const apiUrl = `${this._apiBaseUrl}/aktiviteter`; + return this.httpClient.get<{ data: ActivityResponse[] }>(apiUrl).pipe( + filter(response => !!response?.data), + map(({ data }) => data.map(activity => mapResponseToActivity(activity))), + catchError((error: Error & { status: number }) => { + throw new CustomError({ + error, + message: `Kunde inte hämta aktiviteter.\n\n${error.message}`, + name: `GET ${apiUrl}`, + method: 'GemensamPlaneringApiService.fetchActivities$', + }); + }), + shareReplay(1) + ); + } + + public fetchAllChosenActivities$(genomforandereferens: number): Observable<{ data: ActivityResponse[] }> { + return this.httpClient + .get<{ data: ActivityResponse[] }>(`${this._apiBaseUrl}/alla-valda-aktiviteter/${genomforandereferens}`) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta valda aktiviteter.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/alla-valda-aktiviteter/{genomforandereferens}`, + data: { genomforandereferens }, + method: 'GemensamPlaneringApiService.fetchAllChosenActivities$', + }); + }) + ); + } + + public postGemensamPlanering$(data: GemensamPlaneringPostRequest): Observable { + return this.httpClient.post(`${this._apiBaseUrl}`, data).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte spara Gemensam planering.\n\n${error.message}`, + name: `POST ${this._apiBaseUrl}`, + data, + method: 'GemensamPlaneringApiService.postGemensamPlanering$', + }); + }) + ); + } + + constructor(private httpClient: HttpClient) {} +} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/handledare.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/handledare.api.service.ts index a11fa97..ae5fc72 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/handledare.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/handledare.api.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; import { environment } from '@msfa-environment'; import { HandledareResponse } from '@msfa-models/api/handledare.response.model'; import { Params } from '@msfa-models/api/params.model'; -import { CustomError, errorToCustomError } from '@msfa-models/error/custom-error'; +import { CustomError } from '@msfa-models/error/custom-error'; import { Handledare, mapHandledareResponseToHandledare } from '@msfa-models/handledare.model'; import { Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; @@ -24,9 +24,13 @@ export class HandledareApiService { .pipe( map(({ data }) => data.map(handledare => mapHandledareResponseToHandledare(handledare))), catchError((error: Error) => { - throw new CustomError( - errorToCustomError({ ...error, message: `Kunde inte hämta handledare.\n\n${error.message}` }) - ); + throw new CustomError({ + error, + message: `Kunde inte hämta handledare.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}`, + data: { avropIds }, + method: 'HandledareApiService.fetchAvailableHandledare$', + }); }) ); } @@ -36,8 +40,20 @@ export class HandledareApiService { avropIds, ciamUserId: handledare.ciamUserId, }; + const apiUrl = `${this._apiBaseUrl}/assign`; return this.httpClient - .patch(`${this._apiBaseUrl}/assign`, null, { params }) + .patch(apiUrl, null, { params }) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte tilldela handledare.\n\n${error.message}`, + name: `PATCH ${apiUrl}`, + data: params, + method: 'HandledareApiService.assignHandledare', + }); + }) + ) .toPromise(); } } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts index 15e141d..8fbd21f 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts @@ -5,9 +5,12 @@ import { AvvikelseReportResponse } from '@msfa-models/api/avvikelse-response.mod import { FranvaroReportResponse } from '@msfa-models/api/franvaro-response.model'; import { GemensamPlaneringResponse } from '@msfa-models/api/gemensam-planering.response.model'; import { InformativRapportResponse } from '@msfa-models/api/informativ-rapport.response.model'; -import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; -import { Observable } from 'rxjs'; +import { PeriodiskRedovisningResponse } from '@msfa-models/api/periodisk-redovisning.response.model'; import { SignalResponse } from '@msfa-models/api/signal.response.model'; +import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Observable } from 'rxjs'; +import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root', @@ -18,29 +21,107 @@ export class HandlingarApiService { constructor(private httpClient: HttpClient) {} public fetchGemensamPlanering$(handlingId: string): Observable<{ data: GemensamPlaneringResponse }> { - return this.httpClient.get<{ data: GemensamPlaneringResponse }>( - `${this._apiBaseUrl}/gemensam-planering/${handlingId}` - ); + return this.httpClient + .get<{ data: GemensamPlaneringResponse }>(`${this._apiBaseUrl}/gemensam-planering/${handlingId}`) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Gemensam planering.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/gemensam-planering/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchGemensamPlanering$', + }); + }) + ); + } + + public fetchPeriodiskRedovisning$(handlingId: string): Observable<{ data: PeriodiskRedovisningResponse }> { + return this.httpClient + .get<{ data: PeriodiskRedovisningResponse }>(`${this._apiBaseUrl}/periodisk-redovisning/${handlingId}`) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Periodisk redovisning.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/periodisk-redovisning/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchPeriodiskRedovisning$', + }); + }) + ); } public fetchInformativRapport$(handlingId: string): Observable<{ data: InformativRapportResponse }> { - return this.httpClient.get<{ data: InformativRapportResponse }>( - `${this._apiBaseUrl}/informativ-rapport/${handlingId}` - ); + return this.httpClient + .get<{ data: InformativRapportResponse }>(`${this._apiBaseUrl}/informativ-rapport/${handlingId}`) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Informativ rapport.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/informativ-rapport/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchInformativRapport$', + }); + }) + ); } public fetchSignal$(handlingId: string): Observable<{ data: SignalResponse }> { - return this.httpClient.get<{ data: SignalResponse }>(`${this._apiBaseUrl}/signal/${handlingId}`); + return this.httpClient.get<{ data: SignalResponse }>(`${this._apiBaseUrl}/signal/${handlingId}`).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Signal om arbete eller studier.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/signal/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchSignal$', + }); + }) + ); } public fetchFranvaroReport$(handlingId: string): Observable<{ data: FranvaroReportResponse }> { - return this.httpClient.get<{ data: FranvaroReportResponse }>(`${this._apiBaseUrl}/franvaro/${handlingId}`); + return this.httpClient.get<{ data: FranvaroReportResponse }>(`${this._apiBaseUrl}/franvaro/${handlingId}`).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Avvikelserapport (frånvaro).\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/franvaro/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchFranvaroReport$', + }); + }) + ); } public fetchAvvikelseReport$(handlingId: string): Observable<{ data: AvvikelseReportResponse }> { - return this.httpClient.get<{ data: AvvikelseReportResponse }>(`${this._apiBaseUrl}/avvikelse/${handlingId}`); + return this.httpClient.get<{ data: AvvikelseReportResponse }>(`${this._apiBaseUrl}/avvikelse/${handlingId}`).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Avvikelserapport (avvikelse).\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/avvikelse/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchAvvikelseReport$', + }); + }) + ); } public fetchSlutredovisning$(handlingId: string): Observable<{ data: SlutredovisningResponse }> { - return this.httpClient.get<{ data: SlutredovisningResponse }>(`${this._apiBaseUrl}/slutredovisning/${handlingId}`); + return this.httpClient + .get<{ data: SlutredovisningResponse }>(`${this._apiBaseUrl}/slutredovisning/${handlingId}`) + .pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta Slutredovisning.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}/slutredovisning/{handlingId}`, + data: { handlingId }, + method: 'HandlingarApiService.fetchSlutredovisning$', + }); + }) + ); } } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/informativ-rapport.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/informativ-rapport.api.service.ts index 95b8dda..5fd7515 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/informativ-rapport.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/informativ-rapport.api.service.ts @@ -1,6 +1,5 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { InformativRapportRequest } from '@msfa-models/api/informativ-rapport.request.model'; import { CustomError } from '@msfa-models/error/custom-error'; @@ -13,17 +12,19 @@ import { catchError } from 'rxjs/operators'; export class InformativRapportApiService { private _apiBaseUrl = `${environment.api.url}/rapporter/informativ-rapport`; - public postInformativRapport$(requestData: InformativRapportRequest): Observable { - return this.httpClient.post(this._apiBaseUrl, requestData).pipe( + constructor(private httpClient: HttpClient) {} + + public postInformativRapport$(data: InformativRapportRequest): Observable { + return this.httpClient.post(this._apiBaseUrl, data).pipe( catchError((error: Error) => { throw new CustomError({ error, message: `Kunde inte spara Informativ rapport.\n\n${error.message}`, - type: ErrorType.API, + name: `POST ${this._apiBaseUrl}`, + data, + method: 'InformativRapportApiService.postInformativRapport$', }); }) ); } - - constructor(private httpClient: HttpClient) {} } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/news.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/news.api.service.ts index 68f0771..4de04a3 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/news.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/news.api.service.ts @@ -1,10 +1,8 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { NewsResponse } from '@msfa-models/api/news.response.model'; import { CustomError } from '@msfa-models/error/custom-error'; -import { ErrorService } from '@msfa-services/error.service'; import { Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; @@ -14,19 +12,18 @@ import { catchError, map } from 'rxjs/operators'; export class NewsApiService { private _apiBaseUrl = `${environment.api.url}/confluence/nyheter`; - constructor(private http: HttpClient, private errorService: ErrorService) {} + constructor(private http: HttpClient) {} public fetchNews$(): Observable { return this.http.get<{ data: NewsResponse }>(this._apiBaseUrl).pipe( map(({ data }) => data), catchError((error: Error) => { - const customError = new CustomError({ + throw new CustomError({ error, message: `Kunde inte hämta nyheter.\n\n${error.message}`, - type: ErrorType.API, + name: `GET ${this._apiBaseUrl}`, + method: 'NewsApiService.fetchNews$', }); - this.errorService.add(customError); - throw customError; }) ); } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/periodisk-redovisning.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/periodisk-redovisning.api.service.ts index 2682314..98b1b7b 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/periodisk-redovisning.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/periodisk-redovisning.api.service.ts @@ -1,9 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { PeriodiskRedovisningRequest } from '@msfa-models/api/periodisk-redovisning.request.model'; -import { PeriodiskRedovisningResponse } from '@msfa-models/api/periodisk-redovisning.response.model'; import { CustomError } from '@msfa-models/error/custom-error'; import { Observable } from 'rxjs'; import { catchError } from 'rxjs/operators'; @@ -14,23 +12,17 @@ import { catchError } from 'rxjs/operators'; export class PeriodiskRedovisningApiService { private _apiBaseUrl = `${environment.api.url}/rapporter/periodisk-redovisning`; - private _handlingarBaseUrl = `${environment.api.url}/handlingar`; - constructor(private httpClient: HttpClient) {} - public fetchPeriodiskRedovisning$(handlingId: string): Observable<{ data: PeriodiskRedovisningResponse }> { - return this.httpClient.get<{ data: PeriodiskRedovisningResponse }>( - `${this._handlingarBaseUrl}/periodisk-redovisning/${handlingId}` - ); - } - - public postPeriodiskRedovisning$(requestData: PeriodiskRedovisningRequest): Observable { - return this.httpClient.post(`${this._apiBaseUrl}`, requestData).pipe( + public postPeriodiskRedovisning$(data: PeriodiskRedovisningRequest): Observable { + return this.httpClient.post(this._apiBaseUrl, data).pipe( catchError((error: Error) => { throw new CustomError({ error, message: `Kunde inte spara Periodisk redovisning.\n\n${error.message}`, - type: ErrorType.API, + name: `POST ${this._apiBaseUrl}`, + data, + method: 'PeriodiskRedovisningApiService.postPeriodiskRedovisning$', }); }) ); diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/signal.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/signal.api.service.ts index 4ee6bb5..9ee39b9 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/signal.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/signal.api.service.ts @@ -1,6 +1,5 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { SignalRequest } from '@msfa-models/api/signal.request.model'; import { CustomError } from '@msfa-models/error/custom-error'; @@ -13,13 +12,15 @@ import { catchError } from 'rxjs/operators'; export class SignalApiService { private _apiBaseUrl = `${environment.api.url}/rapporter/signal`; - public postSignal$(requestData: SignalRequest): Observable { - return this.httpClient.post(this._apiBaseUrl, requestData).pipe( + public postSignal$(data: SignalRequest): Observable { + return this.httpClient.post(this._apiBaseUrl, data).pipe( catchError((error: Error) => { throw new CustomError({ error, message: `Kunde inte spara Signal om arbete eller studier.\n\n${error.message}`, - type: ErrorType.API, + name: `POST ${this._apiBaseUrl}`, + data, + method: 'SignalApiService.postSignal$', }); }) ); diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts index e892df9..a510ee6 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts @@ -1,10 +1,8 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { YRKEN } from '@msfa-constants/yrken'; -import { ErrorType } from '@msfa-enums/error-type.enum'; import { environment } from '@msfa-environment'; import { SlutredovisningRequest } from '@msfa-models/api/slutredovisning.request.model'; -import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; import { YrkesomradeResponse } from '@msfa-models/api/yrkesomrade.response.model'; import { CustomError } from '@msfa-models/error/custom-error'; import { Observable, of } from 'rxjs'; @@ -15,37 +13,35 @@ import { catchError } from 'rxjs/operators'; }) export class SlutredovisningApiService { private _apiBaseUrl = `${environment.api.url}/rapporter`; - private _handlingarBaseUrl = `${environment.api.url}/handlingar`; constructor(private httpClient: HttpClient) {} public fetchYrken$(): Observable<{ data: YrkesomradeResponse[] }> { return of({ data: YRKEN }); // TODO: Whenever the taxonomy endpoint is implemented correctly in IPF then this should be implemented instead. - // return this.httpClient.get<{ data: YrkesomradeResponse[] }>(`${this._apiBaseUrl}/yrkesomraden`).pipe( - // catchError((error: Error) => { - // throw new CustomError({ - // error, - // message: `Kunde inte hämta yrkesområden och yrkesgrupper.\n\n${error.message}`, - // type: ErrorType.API, - // }); - // }) - // ); + // const apiUrl = `${this._apiBaseUrl}/yrkesomraden`; + // return this.httpClient.get<{ data: YrkesomradeResponse[] }>(apiUrl).pipe( + // catchError((error: Error) => { + // throw new CustomError({ + // error, + // message: `Kunde inte hämta yrkesområden och yrkesgrupper.\n\n${error.message}`, + // name: `GET ${apiUrl}`, + // method: 'SlutredovisningApiService.fetchYrken$', + // }); + // }) + // ); } - public fetchSlutredovisning$(handlingId: string): Observable<{ data: SlutredovisningResponse }> { - return this.httpClient.get<{ data: SlutredovisningResponse }>( - `${this._handlingarBaseUrl}/slutredovisning/${handlingId}` - ); - } - - public submitSlutredovisning$(requestData: SlutredovisningRequest): Observable { - return this.httpClient.post(`${this._apiBaseUrl}/slutredovisning`, requestData).pipe( + public submitSlutredovisning$(data: SlutredovisningRequest): Observable { + const apiUrl = `${this._apiBaseUrl}/slutredovisning`; + return this.httpClient.post(apiUrl, data).pipe( catchError((error: Error) => { throw new CustomError({ error, message: `Kunde inte spara Periodisk redovisning.\n\n${error.message}`, - type: ErrorType.API, + name: `POST ${apiUrl}`, + data, + method: 'SlutredovisningApiService.submitSlutredovisning$', }); }) ); diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.api.service.ts new file mode 100644 index 0000000..b443da1 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.api.service.ts @@ -0,0 +1,30 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from '@msfa-environment'; +import { TjanstResponse } from '@msfa-models/api/tjanst.response.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Observable } from 'rxjs'; +import { catchError, shareReplay } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root', +}) +export class TjanstApiService { + private _apiBaseUrl = `${environment.api.url}/tjanster`; + + constructor(private httpClient: HttpClient) {} + + public fetchTjanster$(): Observable<{ data: TjanstResponse[] }> { + return this.httpClient.get<{ data: TjanstResponse[] }>(this._apiBaseUrl).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta tjänster.\n\n${error.message}`, + name: `GET ${this._apiBaseUrl}`, + method: 'TjanstApiService.fetchTjanster$', + }); + }), + shareReplay(1) + ); + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.service.ts deleted file mode 100644 index afdeb15..0000000 --- a/apps/mina-sidor-fa/src/app/shared/services/api/tjanst.service.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive'; -import { environment } from '@msfa-environment'; -import { TjanstResponse } from '@msfa-models/api/tjanst.response.model'; -import { mapResponseToTjanst, Tjanst } from '@msfa-models/tjanst.model'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { filter, map, switchMap } from 'rxjs/operators'; - -@Injectable({ - providedIn: 'root', -}) -export class TjanstService extends UnsubscribeDirective { - private _apiBaseUrl = `${environment.api.url}/tjanster`; - private _tjanster$ = new BehaviorSubject(null); - - public tjanster$: Observable = this._tjanster$.asObservable(); - - private _fetchTjanster$: Observable = this.tjanster$.pipe( - filter(tjanster => !tjanster?.length), - switchMap(() => - this.httpClient - .get<{ data: TjanstResponse[] }>(this._apiBaseUrl) - .pipe(map(({ data }) => data.map(tjanst => mapResponseToTjanst(tjanst)))) - ) - ); - - constructor(private httpClient: HttpClient) { - super(); - super.unsubscribeOnDestroy( - this._fetchTjanster$.subscribe(tjanster => { - this._tjanster$.next(tjanster); - }) - ); - } -} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/user.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/user.api.service.ts new file mode 100644 index 0000000..2c1efb2 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/api/user.api.service.ts @@ -0,0 +1,45 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from '@msfa-environment'; +import { EmployeeResponse } from '@msfa-models/api/employee.response.model'; +import { OrganizationResponse } from '@msfa-models/api/organization.response.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Observable } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root', +}) +export class UserApiService { + private _apiAuthUrl = `${environment.api.url}/auth`; + private _apiUserUrl = `${environment.api.url}/users/currentUser`; + + constructor(private httpClient: HttpClient) {} + + public fetchOrganizations$(): Observable<{ data: OrganizationResponse[] }> { + const apiUrl = `${this._apiAuthUrl}/organizations`; + return this.httpClient.get<{ data: OrganizationResponse[] }>(apiUrl).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta organisationer.\n\n${error.message}`, + name: `GET ${apiUrl}`, + method: 'UserApiService.fetchOrganizations$', + }); + }) + ); + } + + public fetchCurrentUser$(): Observable<{ data: EmployeeResponse }> { + return this.httpClient.get<{ data: EmployeeResponse }>(this._apiUserUrl).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte hämta användarinformation.\n\n${error.message}`, + name: `GET ${this._apiUserUrl}`, + method: 'UserApiService.fetchCurrentUser$', + }); + }) + ); + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/user.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/user.service.ts deleted file mode 100644 index f292774..0000000 --- a/apps/mina-sidor-fa/src/app/shared/services/api/user.service.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { ApmService } from '@elastic/apm-rum-angular'; -import { SELECTED_ORGANIZATION_NUMBER_KEY } from '@msfa-constants/local-storage-keys'; -import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive'; -import { environment } from '@msfa-environment'; -import { EmployeeResponse } from '@msfa-models/api/employee.response.model'; -import { OrganizationResponse } from '@msfa-models/api/organization.response.model'; -import { UserInfoResponse } from '@msfa-models/api/user-info.response.model'; -import { Employee, mapResponseToEmployee } from '@msfa-models/employee.model'; -import { mapResponseToOrganization, Organization } from '@msfa-models/organization.model'; -import { Role } from '@msfa-models/role.model'; -import { mapResponseToUserInfo, UserInfo } from '@msfa-models/user-info.model'; -import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; -import { filter, map, switchMap, tap } from 'rxjs/operators'; -import { AuthenticationService } from './authentication.service'; - -@Injectable({ - providedIn: 'root', -}) -export class UserService extends UnsubscribeDirective { - private _apiAuthUrl = `${environment.api.url}/auth`; - private _apiUserUrl = `${environment.api.url}/users/currentUser`; - - private _isLoggedIn$: Observable = this.authenticationService.isLoggedIn$; - private _organizations$ = new BehaviorSubject(null); - public organizations$: Observable = this._organizations$.asObservable(); - private _user$ = new BehaviorSubject(null); - public user$: Observable = this._user$.asObservable(); - private _userRolesLoading$ = new BehaviorSubject(false); - public userRolesLoading$: Observable = this._userRolesLoading$.asObservable(); - private _userLoading$ = new BehaviorSubject(false); - public userLoading$: Observable = this._userLoading$.asObservable(); - private _userRoles$ = new BehaviorSubject(null); - public userRoles$: Observable = this._userRoles$.asObservable(); - private _selectedOrganizationNumber$ = new BehaviorSubject(null); - - public get userRolesSnapshot(): Role[] { - return this._userRoles$.getValue(); - } - - constructor( - private httpClient: HttpClient, - private authenticationService: AuthenticationService, - private apmService: ApmService - ) { - super(); - this._selectedOrganizationNumber$.next(this._selectedOrganizationNumber); - super.unsubscribeOnDestroy( - this._isLoggedIn$ - .pipe( - filter(loggedIn => !!loggedIn), - switchMap(() => this._fetchOrganizations$()) - ) - .subscribe(organizations => { - this._organizations$.next(organizations); - }), - combineLatest([this._isLoggedIn$, this.selectedOrganization$]) - .pipe( - filter(([loggedIn, selectedOrganization]) => !!(loggedIn && selectedOrganization)), - tap(() => { - this._userLoading$.next(true); - this._userRolesLoading$.next(true); - }), - switchMap(() => combineLatest([this._fetchUserInfo$(), this._fetchCurrentUser$()])) - ) - .subscribe(([userInfo, currentUser]) => { - this._userRoles$.next(userInfo.roles); - this._user$.next(currentUser); - this._userLoading$.next(false); - this._userRolesLoading$.next(false); - - this.apmService.apm.setUserContext({ id: currentUser.id }); - }) - ); - } - - private _fetchOrganizations$(): Observable { - return this.httpClient.get<{ data: OrganizationResponse[] }>(`${this._apiAuthUrl}/organizations`).pipe( - filter(response => !!response?.data), - map(({ data }) => data.map(organization => mapResponseToOrganization(organization))) - ); - } - - private _fetchUserInfo$(): Observable { - return this.httpClient.get<{ data: UserInfoResponse }>(`${this._apiAuthUrl}/userinfo`).pipe( - filter(response => !!response?.data), - map(({ data }) => mapResponseToUserInfo(data)) - ); - } - - private _fetchCurrentUser$(): Observable { - return this.httpClient.get<{ data: EmployeeResponse }>(`${this._apiUserUrl}`).pipe( - filter(response => !!response?.data), - map(({ data }) => mapResponseToEmployee(data)) - ); - } - - private get _selectedOrganizationNumber(): string | null { - return localStorage.getItem(SELECTED_ORGANIZATION_NUMBER_KEY); - } - - public get selectedOrganization$(): Observable { - return combineLatest([this._selectedOrganizationNumber$, this._organizations$]).pipe( - filter(([, organizations]) => !!organizations?.length), - map(([organizationNumber, organizations]) => { - return organizationNumber - ? organizations.find(organization => organization.organizationNumber === organizationNumber) - : null; - }) - ); - } - - public setSelectedOrganization(organization: Organization): void { - localStorage.setItem(SELECTED_ORGANIZATION_NUMBER_KEY, organization.organizationNumber); - this._selectedOrganizationNumber$.next(organization.organizationNumber); - } -} diff --git a/apps/mina-sidor-fa/src/app/shared/services/avrop.service.ts b/apps/mina-sidor-fa/src/app/shared/services/avrop.service.ts index 930cd87..d0f9c1e 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/avrop.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/avrop.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { AvropParams, Params } from '@msfa-models/api/params.model'; import { Avrop, AvropAndMeta } from '@msfa-models/avrop.model'; import { Handledare } from '@msfa-models/handledare.model'; -import { AvropApiService } from '@msfa-services/api/avrop-api.service'; +import { AvropApiService } from '@msfa-services/api/avrop.api.service'; import { MultiselectFilterOption } from '@ui/multiselect/multiselect-filter-option'; import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs'; import { distinctUntilChanged, filter, map, shareReplay, switchMap, tap } from 'rxjs/operators'; diff --git a/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts b/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts index f27aa58..dd8ae87 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/deltagare-handelser.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { PaginationParams } from '@msfa-models/api/params.model'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { DeltagareHandelserApiService } from './api/deltagare-handelser-api.service'; +import { DeltagareHandelserApiService } from './api/deltagare-handelser.api.service'; const DEFAULT_PARAMS: PaginationParams = { page: 1, diff --git a/apps/mina-sidor-fa/src/app/shared/services/handledare.service.ts b/apps/mina-sidor-fa/src/app/shared/services/handledare.service.ts index 0dfbf73..e2d4af5 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/handledare.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/handledare.service.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; -import { errorToCustomError } from '@msfa-models/error/custom-error'; import { Handledare } from '@msfa-models/handledare.model'; import { BehaviorSubject, Observable } from 'rxjs'; import { HandledareApiService } from './api/handledare.api.service'; @@ -31,11 +30,6 @@ export class HandledareService { .then(() => { this._lastSavedHandledare$.next(handledare); }) - .catch((error: Error) => { - this.errorService.add( - errorToCustomError({ ...error, message: `Kunde inte tilldela handledare.\n\n${error.message}` }) - ); - }) .finally(() => { this._submitHandledareLoading$.next(false); }); diff --git a/apps/mina-sidor-fa/src/app/shared/services/role.service.ts b/apps/mina-sidor-fa/src/app/shared/services/role.service.ts index f0ad6a7..6ed77a3 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/role.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/role.service.ts @@ -1,13 +1,11 @@ import { Injectable } from '@angular/core'; import { RoleEnum } from '@msfa-enums/role.enum'; -import { environment } from '@msfa-environment'; import { mapResponseToRoles, Role } from '@msfa-models/role.model'; @Injectable({ providedIn: 'root', }) export class RoleService { - private readonly _apiBaseUrl = `${environment.api.url}/auth/userinfo`; public get allRoles(): Role[] { return mapResponseToRoles(Object.keys(RoleEnum) as RoleEnum[]); } diff --git a/apps/mina-sidor-fa/src/app/shared/services/user.service.ts b/apps/mina-sidor-fa/src/app/shared/services/user.service.ts new file mode 100644 index 0000000..eddd186 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/user.service.ts @@ -0,0 +1,74 @@ +import { Injectable } from '@angular/core'; +import { ApmService } from '@elastic/apm-rum-angular'; +import { SELECTED_ORGANIZATION_NUMBER_KEY } from '@msfa-constants/local-storage-keys'; +import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive'; +import { Employee, mapResponseToEmployee } from '@msfa-models/employee.model'; +import { mapResponseToOrganization, Organization } from '@msfa-models/organization.model'; +import { mapResponseToRoles, Role } from '@msfa-models/role.model'; +import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; +import { filter, map, mapTo, shareReplay, startWith, switchMap } from 'rxjs/operators'; +import { AuthenticationService } from './api/authentication.service'; +import { UserApiService } from './api/user.api.service'; + +@Injectable({ + providedIn: 'root', +}) +export class UserService extends UnsubscribeDirective { + private _isLoggedIn$: Observable = this.authenticationService.isLoggedIn$; + private _selectedOrganizationNumber$ = new BehaviorSubject(null); + + public organizations$: Observable = this._isLoggedIn$.pipe( + filter(loggedIn => !!loggedIn), + switchMap(() => + this.userApiService + .fetchOrganizations$() + .pipe(map(({ data }) => data.map(organization => mapResponseToOrganization(organization)))) + ), + shareReplay(1) + ); + public selectedOrganization$: Observable = combineLatest([ + this.organizations$, + this._selectedOrganizationNumber$, + ]).pipe( + filter(([organizations]) => !!organizations?.length), + map(([organizations, organizationNumber]) => { + return organizationNumber + ? organizations.find(organization => organization.organizationNumber === organizationNumber) + : null; + }) + ); + public user$: Observable = combineLatest([this._isLoggedIn$, this.selectedOrganization$]).pipe( + filter(([loggedIn, selectedOrganization]) => !!(loggedIn && selectedOrganization)), + switchMap(() => this.userApiService.fetchCurrentUser$().pipe(map(({ data }) => mapResponseToEmployee(data)))), + shareReplay(1) + ); + public userRoles$: Observable = this.user$.pipe(map(({ roles }) => mapResponseToRoles(roles))); + public userLoading$: Observable = combineLatest([this._isLoggedIn$, this.selectedOrganization$]).pipe( + filter(([isLoggedIn, selectedOrganization]) => !!(isLoggedIn && selectedOrganization)), + switchMap(() => this.user$.pipe(mapTo(false), startWith(true))), + startWith(false) + ); + + constructor( + private authenticationService: AuthenticationService, + private userApiService: UserApiService, + private apmService: ApmService + ) { + super(); + this._setSelectedOrganizationNumberFromLocalStorage(); + super.unsubscribeOnDestroy( + this.user$.subscribe(user => { + this.apmService.apm.setUserContext({ id: user.id }); + }) + ); + } + + private _setSelectedOrganizationNumberFromLocalStorage(): void { + this._selectedOrganizationNumber$.next(localStorage.getItem(SELECTED_ORGANIZATION_NUMBER_KEY)); + } + + public setSelectedOrganization(organization: Organization): void { + localStorage.setItem(SELECTED_ORGANIZATION_NUMBER_KEY, organization.organizationNumber); + this._selectedOrganizationNumber$.next(organization.organizationNumber); + } +}