feat(settings): Added feature toggling. (TV-564)
Squashed commit of the following: commit b67cced3bd44d1673173e5fa188d776d2d097fd4 Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se> Date: Fri Sep 10 11:59:37 2021 +0200 Added feature toggling for routes and navigation
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { AuthGuard } from '@msfa-guards/auth.guard';
|
||||
import { OrganizationGuard } from '@msfa-guards/organization.guard';
|
||||
import { RoleGuard } from '@msfa-guards/role.guard';
|
||||
|
||||
const activeFeatures: Feature[] = environment.activeFeatures;
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
@@ -13,24 +16,6 @@ const routes: Routes = [
|
||||
loadChildren: () => import('./pages/start/start.module').then(m => m.StartModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard],
|
||||
},
|
||||
{
|
||||
path: 'administration',
|
||||
data: { title: 'Administration', expectedRole: RoleEnum.MSFA_AuthAdmin },
|
||||
loadChildren: () => import('./pages/administration/administration.module').then(m => m.AdministrationModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
},
|
||||
{
|
||||
path: 'deltagare',
|
||||
data: { title: 'Deltagare', expectedRole: RoleEnum.MSFA_ReportAndPlanning },
|
||||
loadChildren: () => import('./pages/deltagare/deltagare.module').then(m => m.DeltagareModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
},
|
||||
{
|
||||
path: 'nya-deltagare',
|
||||
data: { title: 'Nya deltagare', expectedRole: RoleEnum.MSFA_ReceiveDeltagare },
|
||||
loadChildren: () => import('./pages/avrop/avrop.module').then(m => m.AvropModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
},
|
||||
{
|
||||
path: 'logga-ut',
|
||||
data: { title: 'Logga ut' },
|
||||
@@ -44,12 +29,6 @@ const routes: Routes = [
|
||||
import('./pages/organization-picker/organization-picker.module').then(m => m.OrganizationPickerModule),
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{
|
||||
path: 'mitt-konto',
|
||||
data: { title: 'Mitt konto' },
|
||||
loadChildren: () => import('./pages/my-account/my-account.module').then(m => m.MyAccountModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard],
|
||||
},
|
||||
{
|
||||
path: 'obehorig',
|
||||
data: { title: 'Saknar behörighet' },
|
||||
@@ -58,21 +37,59 @@ const routes: Routes = [
|
||||
},
|
||||
];
|
||||
|
||||
if (!environment.production) {
|
||||
routes.push(
|
||||
{
|
||||
path: 'mock-login',
|
||||
data: { title: 'Mock login' },
|
||||
loadChildren: () => import('./pages/mock-login/mock-login.module').then(m => m.MockLoginModule),
|
||||
},
|
||||
{
|
||||
path: 'releases',
|
||||
data: { title: 'Releaser' },
|
||||
loadChildren: () => import('./pages/releases/releases.module').then(m => m.ReleasesModule),
|
||||
canActivate: [AuthGuard],
|
||||
}
|
||||
);
|
||||
}
|
||||
activeFeatures.forEach(feature => {
|
||||
switch (feature) {
|
||||
case Feature.ADMINISTRATION:
|
||||
routes.push({
|
||||
path: 'administration',
|
||||
data: { title: 'Administration', expectedRole: RoleEnum.MSFA_AuthAdmin },
|
||||
loadChildren: () => import('./pages/administration/administration.module').then(m => m.AdministrationModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
});
|
||||
break;
|
||||
case Feature.AVROP:
|
||||
routes.push({
|
||||
path: 'nya-deltagare',
|
||||
data: { title: 'Nya deltagare', expectedRole: RoleEnum.MSFA_ReceiveDeltagare },
|
||||
loadChildren: () => import('./pages/avrop/avrop.module').then(m => m.AvropModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
});
|
||||
break;
|
||||
case Feature.DELTAGARE:
|
||||
routes.push({
|
||||
path: 'deltagare',
|
||||
data: { title: 'Deltagare', expectedRole: RoleEnum.MSFA_ReportAndPlanning },
|
||||
loadChildren: () => import('./pages/deltagare/deltagare.module').then(m => m.DeltagareModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard, RoleGuard],
|
||||
});
|
||||
break;
|
||||
case Feature.MY_ACCOUNT:
|
||||
routes.push({
|
||||
path: 'mitt-konto',
|
||||
data: { title: 'Mitt konto' },
|
||||
loadChildren: () => import('./pages/my-account/my-account.module').then(m => m.MyAccountModule),
|
||||
canActivate: [AuthGuard, OrganizationGuard],
|
||||
});
|
||||
break;
|
||||
case Feature.RELEASES:
|
||||
routes.push({
|
||||
path: 'releases',
|
||||
data: { title: 'Releaser' },
|
||||
loadChildren: () => import('./pages/releases/releases.module').then(m => m.ReleasesModule),
|
||||
canActivate: [AuthGuard],
|
||||
});
|
||||
break;
|
||||
case Feature.MOCK_LOGIN:
|
||||
routes.push({
|
||||
path: 'mock-login',
|
||||
data: { title: 'Mock login' },
|
||||
loadChildren: () => import('./pages/mock-login/mock-login.module').then(m => m.MockLoginModule),
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
routes.push({
|
||||
path: '**',
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
</a>
|
||||
</div>
|
||||
<ul class="navigation__list msfa__hide-on-print" *ngIf="user">
|
||||
<li class="navigation__item">
|
||||
<li class="navigation__item" *ngIf="myAccountVisible">
|
||||
<a routerLink="/mitt-konto" class="navigation__link">
|
||||
<msfa-icon [icon]="iconType.USER" size="l"></msfa-icon>
|
||||
<span class="navigation__text">{{ user.fullName }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="selectedOrganization" class="navigation__item navigation__item--without-link">
|
||||
<li *ngIf="selectedOrganization && myOrganizationVisible" class="navigation__item navigation__item--without-link">
|
||||
<msfa-icon [icon]="iconType.BUILDING" size="l"></msfa-icon>
|
||||
<span class="navigation__text">{{ selectedOrganization.name }}</span>
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
import { IconType } from '@msfa-enums/icon-type.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { Employee } from '@msfa-models/employee.model';
|
||||
import { Organization } from '@msfa-models/organization.model';
|
||||
|
||||
@@ -13,4 +15,12 @@ export class NavigationComponent {
|
||||
@Input() user: Employee;
|
||||
@Input() selectedOrganization: Organization;
|
||||
iconType = IconType;
|
||||
activeFeatures: Feature[] = environment.activeFeatures;
|
||||
|
||||
get myAccountVisible(): boolean {
|
||||
return this.activeFeatures.includes(Feature.MY_ACCOUNT);
|
||||
}
|
||||
get myOrganizationVisible(): boolean {
|
||||
return this.activeFeatures.includes(Feature.MY_ORGANIZATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,20 +11,20 @@
|
||||
Hem
|
||||
</a>
|
||||
</li>
|
||||
<li class="sidebar__item" *ngIf="isReceiveDeltagare">
|
||||
<li class="sidebar__item" *ngIf="avropVisible">
|
||||
<a [routerLink]="['/nya-deltagare']" [routerLinkActive]="['sidebar__link--active']" class="sidebar__link">
|
||||
<msfa-icon class="sidebar__icon" [icon]="iconType.CLIPBOARD" size="xl"></msfa-icon>
|
||||
Nya deltagare
|
||||
</a>
|
||||
</li>
|
||||
<li class="sidebar__item" *ngIf="isReportAndPlanning">
|
||||
<li class="sidebar__item" *ngIf="deltagareVisible">
|
||||
<a [routerLink]="['/deltagare']" [routerLinkActive]="['sidebar__link--active']" class="sidebar__link">
|
||||
<msfa-icon class="sidebar__icon" [icon]="iconType.SOK_KANDIDAT" size="xl"></msfa-icon>
|
||||
Deltagarlista
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="sidebar__item" *ngIf="isAuthAdmin">
|
||||
<li class="sidebar__item" *ngIf="adminVisible">
|
||||
<a [routerLink]="['/administration']" [routerLinkActive]="['sidebar__link--active']" class="sidebar__link">
|
||||
<msfa-icon class="sidebar__icon" [icon]="iconType.SETTINGS" size="xl"></msfa-icon>
|
||||
Administration
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
import { IconType } from '@msfa-enums/icon-type.enum';
|
||||
import { RoleEnum } from '@msfa-enums/role.enum';
|
||||
import { environment } from '@msfa-environment';
|
||||
import { Role } from '@msfa-models/role.model';
|
||||
|
||||
@Component({
|
||||
@@ -12,14 +14,24 @@ import { Role } from '@msfa-models/role.model';
|
||||
export class SidebarComponent {
|
||||
@Input() userRoles: Role[];
|
||||
iconType = IconType;
|
||||
activeFeatures: Feature[] = environment.activeFeatures;
|
||||
|
||||
get isAuthAdmin(): boolean {
|
||||
return this.userRoles?.some(role => role.type === RoleEnum.MSFA_AuthAdmin);
|
||||
get adminVisible(): boolean {
|
||||
return (
|
||||
this.activeFeatures.includes(Feature.ADMINISTRATION) &&
|
||||
this.userRoles?.some(role => role.type === RoleEnum.MSFA_AuthAdmin)
|
||||
);
|
||||
}
|
||||
get isReceiveDeltagare(): boolean {
|
||||
return this.userRoles?.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare);
|
||||
get avropVisible(): boolean {
|
||||
return (
|
||||
this.activeFeatures.includes(Feature.AVROP) &&
|
||||
this.userRoles?.some(role => role.type === RoleEnum.MSFA_ReceiveDeltagare)
|
||||
);
|
||||
}
|
||||
get isReportAndPlanning(): boolean {
|
||||
return this.userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning);
|
||||
get deltagareVisible(): boolean {
|
||||
return (
|
||||
this.activeFeatures.includes(Feature.DELTAGARE) &&
|
||||
this.userRoles?.some(role => role.type === RoleEnum.MSFA_ReportAndPlanning)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
9
apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts
Normal file
9
apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export enum Feature {
|
||||
AVROP,
|
||||
DELTAGARE,
|
||||
ADMINISTRATION,
|
||||
MY_ACCOUNT,
|
||||
MY_ORGANIZATION,
|
||||
RELEASES,
|
||||
MOCK_LOGIN,
|
||||
}
|
||||
5
apps/mina-sidor-fa/src/app/shared/models/ciam.model.ts
Normal file
5
apps/mina-sidor-fa/src/app/shared/models/ciam.model.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface Ciam {
|
||||
clientId: string;
|
||||
loginUrl: string;
|
||||
logoutUrl: string;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
|
||||
export interface Environment {
|
||||
environment: 'api' | 'local' | 'acc' | 'prod';
|
||||
clientId: string;
|
||||
@@ -8,4 +10,5 @@ export interface Environment {
|
||||
url: string;
|
||||
headers: { [key: string]: string };
|
||||
};
|
||||
activeFeatures: Feature[];
|
||||
}
|
||||
|
||||
12
apps/mina-sidor-fa/src/environments/active-features.ts
Normal file
12
apps/mina-sidor-fa/src/environments/active-features.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
|
||||
export const ACTIVE_FEATURES_PROD: Feature[] = [Feature.ADMINISTRATION, Feature.MY_ACCOUNT, Feature.MY_ORGANIZATION];
|
||||
|
||||
export const ACTIVE_FEATURES_TEST: Feature[] = [
|
||||
Feature.ADMINISTRATION,
|
||||
Feature.MY_ACCOUNT,
|
||||
Feature.DELTAGARE,
|
||||
Feature.AVROP,
|
||||
Feature.MY_ORGANIZATION,
|
||||
Feature.RELEASES,
|
||||
];
|
||||
19
apps/mina-sidor-fa/src/environments/ciam.ts
Normal file
19
apps/mina-sidor-fa/src/environments/ciam.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Ciam } from '@msfa-models/ciam.model';
|
||||
|
||||
export const CIAM_TEST: Ciam = {
|
||||
clientId: '5d08c2e4-763e-42f6-b858-24e4773bb83d',
|
||||
loginUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/oauth2/authorization?response_type=code&scope=openid',
|
||||
logoutUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/logout',
|
||||
};
|
||||
|
||||
export const CIAM_PROD: Ciam = {
|
||||
clientId: '71010833-e445-4bbc-926a-775247b7a6e3',
|
||||
loginUrl: 'https://ciam.arbetsformedlingen.se/uas/oauth2/authorization?response_type=code&scope=openid',
|
||||
logoutUrl: 'https://ciam.arbetsformedlingen.se/uas/logout',
|
||||
};
|
||||
|
||||
export const CIAM_MOCK: Ciam = {
|
||||
clientId: '',
|
||||
loginUrl: '/mock-login',
|
||||
logoutUrl: '/mock-login',
|
||||
};
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Environment } from '@msfa-models/environment.model';
|
||||
import { ACTIVE_FEATURES_PROD } from './active-features';
|
||||
import { CIAM_TEST } from './ciam';
|
||||
|
||||
export const environment: Environment = {
|
||||
environment: 'acc',
|
||||
clientId: '5d08c2e4-763e-42f6-b858-24e4773bb83d',
|
||||
loginUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/oauth2/authorization?response_type=code&scope=openid',
|
||||
logoutUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/logout',
|
||||
production: true,
|
||||
api: {
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
activeFeatures: [...ACTIVE_FEATURES_PROD],
|
||||
...CIAM_TEST,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Environment } from '@msfa-models/environment.model';
|
||||
import { ACTIVE_FEATURES_TEST } from './active-features';
|
||||
import { CIAM_TEST } from './ciam';
|
||||
|
||||
export const environment: Environment = {
|
||||
environment: 'api',
|
||||
clientId: '5d08c2e4-763e-42f6-b858-24e4773bb83d',
|
||||
loginUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/oauth2/authorization?response_type=code&scope=openid',
|
||||
logoutUrl: 'https://ciam-test.arbetsformedlingen.se:8443/uas/logout',
|
||||
production: false,
|
||||
api: {
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
activeFeatures: [...ACTIVE_FEATURES_TEST],
|
||||
...CIAM_TEST,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Environment } from '@msfa-models/environment.model';
|
||||
import { ACTIVE_FEATURES_PROD } from './active-features';
|
||||
import { CIAM_PROD } from './ciam';
|
||||
|
||||
export const environment: Environment = {
|
||||
environment: 'prod',
|
||||
clientId: '71010833-e445-4bbc-926a-775247b7a6e3',
|
||||
loginUrl: 'https://ciam.arbetsformedlingen.se/uas/oauth2/authorization?response_type=code&scope=openid',
|
||||
logoutUrl: 'https://ciam.arbetsformedlingen.se/uas/logout',
|
||||
production: true,
|
||||
api: {
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
activeFeatures: [...ACTIVE_FEATURES_PROD],
|
||||
...CIAM_PROD,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { Feature } from '@msfa-enums/feature.enum';
|
||||
import { Environment } from '@msfa-models/environment.model';
|
||||
import { ACTIVE_FEATURES_TEST } from './active-features';
|
||||
import { CIAM_MOCK } from './ciam';
|
||||
|
||||
export const environment: Environment = {
|
||||
environment: 'local',
|
||||
clientId: '',
|
||||
loginUrl: '/mock-login',
|
||||
logoutUrl: '/mock-login',
|
||||
production: false,
|
||||
api: {
|
||||
url: '/api',
|
||||
headers: {},
|
||||
},
|
||||
activeFeatures: [...ACTIVE_FEATURES_TEST, Feature.MOCK_LOGIN],
|
||||
...CIAM_MOCK,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user