Merge pull request #55 in TEA/dafa-web-monorepo from feature/TV-366 to develop
Squashed commit of the following: commit 41f27ba3701d7b690e941f2038676218facaab84 Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Thu Aug 19 06:40:44 2021 +0200 TV-366 removed redundant import commit f31d3d6545375e2c84254a60b9e072333fddaa80 Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Thu Aug 19 06:38:41 2021 +0200 TV-366 made a bunch of changes in accordance with the feedback from the current pull request. commit 04c0775649390ce36cc3d2c03ae3cd756e8190b5 Merge: 721b58ee712f2fAuthor: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Thu Aug 19 06:10:28 2021 +0200 Co-authored-by: af-aden <af-aden@users.noreply.github.com> commit 721b58e1767c465673cb817414e1410b403f5e60 Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Wed Aug 18 10:16:40 2021 +0200 Merge branch 'develop-remote' into feature/TV-366 # Conflicts: # apps/mina-sidor-fa/src/app/pages/administration/pages/employees/components/employees-list/employees-list.component.spec.ts # apps/mina-sidor-fa/src/app/pages/logout/logout.component.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker-form/organization-picker-form.component.html # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker-form/organization-picker-form.component.scss # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker-form/organization-picker-form.component.spec.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker-form/organization-picker-form.component.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker-routing.module.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.html # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.scss # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.spec.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.component.ts # apps/mina-sidor-fa/src/app/pages/organization-picker/organization-picker.module.ts # apps/mina-sidor-fa/src/app/shared/guards/auth.guard.ts commit f3e6e590fe24f0b3aefb45d3b8bfae9a3ce7af82 Merge: fbda233218e3d6Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Wed Aug 18 09:41:54 2021 +0200 Merge branch 'develop-remote' into feature/TV-366 commit fbda233782a0850edb5e23b50f0030486a15effe Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Tue Aug 17 19:50:08 2021 +0200 TV-366 removing stored selected organization when logging out. commit ed51909892cd92f180f6785635f85c735ec3f129 Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Tue Aug 17 19:05:14 2021 +0200 Merge branch 'develop-remote' into feature/TV-366 # Conflicts: # apps/dafa-web/src/app/shared/services/api/user.service.ts commit 6a77f2497aec71d174c719d27c6d5c644ba53fed Merge: 17f643d6d29baaAuthor: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Tue Aug 17 19:04:22 2021 +0200 Merge branch 'develop-remote' into feature/TV-366 commit 17f643d18abcbdbfe12a91a63179278d559fdba5 Author: arbetsformedlingen_garcn <christian.gardebrink@arbetsformedlingen.se> Date: Tue Aug 17 17:35:59 2021 +0200 TV-366 First version od organization-picker
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { BackLinkComponent } from './back-link.component';
|
||||
|
||||
describe('BackLinkComponent', () => {
|
||||
@@ -11,6 +12,7 @@ describe('BackLinkComponent', () => {
|
||||
void TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
declarations: [BackLinkComponent],
|
||||
imports: [RouterTestingModule],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { IconComponent } from '../icon/icon.component';
|
||||
import { HideTextComponent } from './hide-text.component';
|
||||
|
||||
describe('HideTextComponent', () => {
|
||||
@@ -7,7 +8,7 @@ describe('HideTextComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [HideTextComponent],
|
||||
declarations: [HideTextComponent, IconComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { IconModule } from '@msfa-shared/components/icon/icon.module';
|
||||
@@ -12,6 +13,7 @@ describe('NavigationComponent', () => {
|
||||
void TestBed.configureTestingModule({
|
||||
declarations: [NavigationComponent],
|
||||
imports: [RouterTestingModule, IconModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { UserService } from '@msfa-services/api/user.service';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AuthenticationService } from '@msfa-services/api/authentication.service';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { redirectUriQueryParam } from '../../pages/organization-picker/organization-picker.component';
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(private authenticationService: AuthenticationService, private router: Router) {}
|
||||
constructor(
|
||||
private authenticationService: AuthenticationService,
|
||||
private userService: UserService,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
|
||||
return this.authenticationService.isLoggedIn$.pipe(
|
||||
switchMap(loggedIn => {
|
||||
if (loggedIn) {
|
||||
if (!this.userService.hasSelectedUserOrganization()) {
|
||||
this.router.navigateByUrl(`/organization-picker?${redirectUriQueryParam}=${encodeURI(location.href)}`);
|
||||
}
|
||||
|
||||
return of(true);
|
||||
} else if (route.queryParams.code) {
|
||||
return this.authenticationService.login$(route.queryParams.code).pipe(map(result => !!result));
|
||||
|
||||
@@ -16,6 +16,8 @@ const API_HEADERS = { headers: environment.api.headers };
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UserService extends UnsubscribeDirective {
|
||||
private readonly selectedUserOrganizationNumberKey = 'selectedOrganizationId';
|
||||
|
||||
private _authApiUrl = `${environment.api.url}/auth`;
|
||||
private _user$ = new BehaviorSubject<User>(null);
|
||||
|
||||
@@ -30,6 +32,32 @@ export class UserService extends UnsubscribeDirective {
|
||||
);
|
||||
}
|
||||
|
||||
getSelectedUserOrganization(user: User): Organization {
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user.organizations.find(
|
||||
organization => organization.organizationNumber === localStorage.getItem(this.selectedUserOrganizationNumberKey)
|
||||
);
|
||||
}
|
||||
|
||||
setSelectedUserOrganization(organization: Organization): void {
|
||||
if (!organization) {
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.setItem(this.selectedUserOrganizationNumberKey, organization?.organizationNumber);
|
||||
}
|
||||
|
||||
hasSelectedUserOrganization(): boolean {
|
||||
return !!localStorage.getItem(this.selectedUserOrganizationNumberKey);
|
||||
}
|
||||
|
||||
removeSelectedUserOrganization(): void {
|
||||
localStorage.removeItem(this.selectedUserOrganizationNumberKey);
|
||||
}
|
||||
|
||||
private _fetchOrganizations$(): Observable<Organization[]> {
|
||||
return this.httpClient.get<{ data: OrganizationResponse[] }>(`${this._authApiUrl}/organizations`, API_HEADERS).pipe(
|
||||
filter(response => !!response?.data),
|
||||
|
||||
@@ -17,6 +17,10 @@ export function sort<T>(data: T[], sort: Sort<keyof T>): T[] {
|
||||
}
|
||||
|
||||
export function sortFromToDates(a: FromToDates, b: FromToDates): number {
|
||||
const cleanDateString = (dateString: string): string => {
|
||||
return dateString.substring(0, 10).replace(/-/g, '');
|
||||
};
|
||||
|
||||
if (!a.from || !b.from) {
|
||||
console.error('Some date is not set: ', { a, b });
|
||||
return -1;
|
||||
@@ -36,10 +40,10 @@ export function sortFromToDates(a: FromToDates, b: FromToDates): number {
|
||||
}
|
||||
|
||||
// Remove optional time and '-' characters whenever the ISO date string is given.
|
||||
a.from = a.from.substring(0, 10).replaceAll('-', '');
|
||||
b.from = b.from.substring(0, 10).replaceAll('-', '');
|
||||
a.to = a.to.substring(0, 10).replaceAll('-', '');
|
||||
b.to = b.to.substring(0, 10).replaceAll('-', '');
|
||||
a.from = cleanDateString(a.from);
|
||||
b.from = cleanDateString(b.from);
|
||||
a.to = cleanDateString(a.to);
|
||||
b.to = cleanDateString(b.to);
|
||||
|
||||
// If no complete dates are available we will add as high numbers as possible to make them sort on top.
|
||||
// If no tillValue is available it means it is still ongoing and should sort on top
|
||||
|
||||
Reference in New Issue
Block a user