added tenant code to url
This commit is contained in:
parent
db25687dd5
commit
a4df13a051
|
@ -3,12 +3,11 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
import { AppPermission } from './core/common/enum/permission.enum';
|
import { AppPermission } from './core/common/enum/permission.enum';
|
||||||
import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service';
|
import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service';
|
||||||
import { ReloadHelperComponent } from './ui/misc/reload-helper/reload-helper.component';
|
import { ReloadHelperComponent } from './ui/misc/reload-helper/reload-helper.component';
|
||||||
import { DepositOauth2DialogComponent } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.component';
|
|
||||||
|
|
||||||
const appRoutes: Routes = [
|
const appRoutes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
redirectTo:'home',
|
redirectTo: 'home',
|
||||||
pathMatch: 'full'
|
pathMatch: 'full'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -35,7 +34,7 @@ const appRoutes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'explore-descriptions',
|
path: 'explore-descriptions',
|
||||||
loadChildren: () => import('./ui/description/description.module').then(m => m.DescriptionModule),
|
loadChildren: () => import('./ui/description/description.module').then(m => m.PublicDescriptionModule),
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -60,7 +59,7 @@ const appRoutes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'explore-plans',
|
path: 'explore-plans',
|
||||||
loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule),
|
loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.PublicDmpModule),
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -183,14 +182,6 @@ const appRoutes: Routes = [
|
||||||
title: 'GENERAL.TITLES.COOKIES-POLICY'
|
title: 'GENERAL.TITLES.COOKIES-POLICY'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// path: 'splash',
|
|
||||||
// loadChildren: () => import('./ui/splash/splash.module').then(m => m.SplashModule),
|
|
||||||
// data: {
|
|
||||||
// breadcrumb: true
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
path: 'unauthorized',
|
path: 'unauthorized',
|
||||||
loadChildren: () => import('./ui/misc/unauthorized/unauthorized.module').then(m => m.UnauthorizedModule),
|
loadChildren: () => import('./ui/misc/unauthorized/unauthorized.module').then(m => m.UnauthorizedModule),
|
||||||
|
@ -387,8 +378,18 @@ const appRoutes: Routes = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const tenantEnrichedRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: 't/:tenant_code',
|
||||||
|
children: [
|
||||||
|
...appRoutes
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...appRoutes
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(appRoutes, {})],
|
imports: [RouterModule.forRoot(tenantEnrichedRoutes, {})],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class AppRoutingModule { }
|
export class AppRoutingModule { }
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { of as observableOf, Subscription } from 'rxjs';
|
||||||
|
|
||||||
import { switchMap, filter, map, takeUntil } from 'rxjs/operators';
|
import { switchMap, filter, map, takeUntil } from 'rxjs/operators';
|
||||||
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
import { ActivatedRoute, NavigationEnd, NavigationStart, Router } from '@angular/router';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { AuthService, LoginStatus } from './core/services/auth/auth.service';
|
import { AuthService, LoginStatus } from './core/services/auth/auth.service';
|
||||||
import { CultureService } from './core/services/culture/culture-service';
|
import { CultureService } from './core/services/culture/culture-service';
|
||||||
|
@ -23,6 +23,7 @@ import { TenantConfigurationService } from './core/services/tenant-configuration
|
||||||
import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type';
|
import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type';
|
||||||
import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration';
|
import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
|
import { TenantHandlingService } from './core/services/tenant/tenant-handling.service';
|
||||||
|
|
||||||
|
|
||||||
declare const gapi: any;
|
declare const gapi: any;
|
||||||
|
@ -43,7 +44,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
onlySplash = true;
|
onlySplash = true;
|
||||||
showOnlyRouterOutlet = false;
|
showOnlyRouterOutlet = false;
|
||||||
|
|
||||||
@ViewChild('sidenav') sidenav:MatSidenav;
|
@ViewChild('sidenav') sidenav: MatSidenav;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
@ -61,7 +62,8 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
private location: Location,
|
private location: Location,
|
||||||
private matomoService: MatomoService,
|
private matomoService: MatomoService,
|
||||||
private tenantConfigurationService: TenantConfigurationService,
|
private tenantConfigurationService: TenantConfigurationService,
|
||||||
private sidenavService: SideNavService
|
private sidenavService: SideNavService,
|
||||||
|
private tenantHandlingService: TenantHandlingService
|
||||||
) {
|
) {
|
||||||
this.initializeServices();
|
this.initializeServices();
|
||||||
this.matomoService.init();
|
this.matomoService.init();
|
||||||
|
@ -69,30 +71,30 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
}
|
}
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.sideNavSubscription = this.sidenavService.status().subscribe(isopen=>{
|
this.sideNavSubscription = this.sidenavService.status().subscribe(isopen => {
|
||||||
const hamburger = document.getElementById('hamburger');
|
const hamburger = document.getElementById('hamburger');
|
||||||
if(isopen){
|
if (isopen) {
|
||||||
//update value of hamburfer
|
//update value of hamburfer
|
||||||
if(!hamburger){//try later
|
if (!hamburger) {//try later
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const hamburger = document.getElementById('hamburger');
|
const hamburger = document.getElementById('hamburger');
|
||||||
if(hamburger){
|
if (hamburger) {
|
||||||
hamburger.classList.add('change');
|
hamburger.classList.add('change');
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
}else{
|
} else {
|
||||||
hamburger.classList.add('change');
|
hamburger.classList.add('change');
|
||||||
}
|
}
|
||||||
this.sidenav.open()
|
this.sidenav.open()
|
||||||
}else{//closed
|
} else {//closed
|
||||||
if(!hamburger){//try later
|
if (!hamburger) {//try later
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const hamburger = document.getElementById('hamburger');
|
const hamburger = document.getElementById('hamburger');
|
||||||
if(hamburger){
|
if (hamburger) {
|
||||||
hamburger.classList.remove('change');
|
hamburger.classList.remove('change');
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
}else{
|
} else {
|
||||||
hamburger.classList.remove('change');
|
hamburger.classList.remove('change');
|
||||||
}
|
}
|
||||||
this.sidenav.close();
|
this.sidenav.close();
|
||||||
|
@ -114,7 +116,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
if (this.location.path() === '') {
|
if (this.location.path() === '') {
|
||||||
if (!this.configurationService.useSplash) {
|
if (!this.configurationService.useSplash) {
|
||||||
this.onlySplash = false;
|
this.onlySplash = false;
|
||||||
this.router.navigate(['/reload']).then(() => this.router.navigate(['/home']));
|
this.router.navigate(['/home']);
|
||||||
} else {
|
} else {
|
||||||
this.onlySplash = true;
|
this.onlySplash = true;
|
||||||
this.router.navigate(['/reload']).then(() => this.router.navigate(['/splash']));
|
this.router.navigate(['/reload']).then(() => this.router.navigate(['/splash']));
|
||||||
|
@ -126,7 +128,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
}
|
}
|
||||||
if (!this.cookieService.check("cookiesConsent")) {
|
if (!this.cookieService.check("cookiesConsent")) {
|
||||||
// this.cookieService.set("cookiesConsent", "false", 356);
|
// this.cookieService.set("cookiesConsent", "false", 356);
|
||||||
this.cookieService.set("cookiesConsent", "false", 356,null,null,false, 'Lax');
|
this.cookieService.set("cookiesConsent", "false", 356, null, null, false, 'Lax');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,17 +173,32 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
return { title: child.snapshot.data['title'], usePrefix: usePrefix };
|
return { title: child.snapshot.data['title'], usePrefix: usePrefix };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { title: appTitle, usePrefix: true};
|
return { title: appTitle, usePrefix: true };
|
||||||
})
|
})
|
||||||
).subscribe((titleOptions: { title: string, usePrefix: boolean}) => {
|
).subscribe((titleOptions: { title: string, usePrefix: boolean }) => {
|
||||||
this.translateTitle(titleOptions.title, titleOptions.usePrefix);
|
this.translateTitle(titleOptions.title, titleOptions.usePrefix);
|
||||||
this.translate.onLangChange.subscribe(() => this.translateTitle(titleOptions.title, titleOptions.usePrefix));
|
this.translate.onLangChange.subscribe(() => this.translateTitle(titleOptions.title, titleOptions.usePrefix));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.router
|
||||||
|
.events.pipe(
|
||||||
|
filter(event => event instanceof NavigationEnd)
|
||||||
|
)
|
||||||
|
.subscribe((event: NavigationStart) => {
|
||||||
|
const enrichedUrl = this.tenantHandlingService.getUrlEnrichedWithTenantCode(event.url, this.authentication.selectedTenant() ?? 'default');
|
||||||
|
if (event.url != enrichedUrl) {
|
||||||
|
this.router.navigate([enrichedUrl]);
|
||||||
|
console.log('enriched')
|
||||||
|
console.log(event.url)
|
||||||
|
console.log(enrichedUrl)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => {
|
this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => {
|
||||||
if (event.status == "dismiss") {
|
if (event.status == "dismiss") {
|
||||||
// this.cookieService.set("cookiesConsent", "true", 365);
|
// this.cookieService.set("cookiesConsent", "true", 365);
|
||||||
this.cookieService.set("cookiesConsent", "true", 356,null,null,false, 'Lax');
|
this.cookieService.set("cookiesConsent", "true", 356, null, null, false, 'Lax');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -203,7 +220,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
}
|
}
|
||||||
this.ccService.destroy();
|
this.ccService.destroy();
|
||||||
this.ccService.init(this.ccService.getConfig());
|
this.ccService.init(this.ccService.getConfig());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
translateTitle(ttl: string, usePrefix: boolean) {
|
translateTitle(ttl: string, usePrefix: boolean) {
|
||||||
|
@ -226,7 +243,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.statusChangeSubscription.unsubscribe();
|
this.statusChangeSubscription.unsubscribe();
|
||||||
if(this.sideNavSubscription){
|
if (this.sideNavSubscription) {
|
||||||
this.sideNavSubscription.unsubscribe();
|
this.sideNavSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,24 +286,24 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
private loadCssColors() {
|
private loadCssColors() {
|
||||||
if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) {
|
if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) {
|
||||||
this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.CssColors, [
|
this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.CssColors, [
|
||||||
nameof<TenantConfiguration>(x => x.type),
|
nameof<TenantConfiguration>(x => x.type),
|
||||||
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor)].join('.'),
|
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor)].join('.'),
|
||||||
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor2)].join('.'),
|
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor2)].join('.'),
|
||||||
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor3)].join('.'),
|
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor3)].join('.'),
|
||||||
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.secondaryColor)].join('.'),
|
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.secondaryColor)].join('.'),
|
||||||
])
|
])
|
||||||
.pipe(map(data => data as TenantConfiguration))
|
.pipe(map(data => data as TenantConfiguration))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
data => {
|
data => {
|
||||||
if (data?.cssColors) {
|
if (data?.cssColors) {
|
||||||
if (data.cssColors.primaryColor) document.documentElement.style.setProperty(`--primary-color`, data.cssColors.primaryColor);
|
if (data.cssColors.primaryColor) document.documentElement.style.setProperty(`--primary-color`, data.cssColors.primaryColor);
|
||||||
if (data.cssColors.primaryColor2) document.documentElement.style.setProperty(`--primary-color-2`, data.cssColors.primaryColor2);
|
if (data.cssColors.primaryColor2) document.documentElement.style.setProperty(`--primary-color-2`, data.cssColors.primaryColor2);
|
||||||
if (data.cssColors.primaryColor3) document.documentElement.style.setProperty(`--primary-color-3`, data.cssColors.primaryColor3);
|
if (data.cssColors.primaryColor3) document.documentElement.style.setProperty(`--primary-color-3`, data.cssColors.primaryColor3);
|
||||||
if (data.cssColors.secondaryColor) document.documentElement.style.setProperty(`--secondary-color`, data.cssColors.secondaryColor);
|
if (data.cssColors.secondaryColor) document.documentElement.style.setProperty(`--secondary-color`, data.cssColors.secondaryColor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import { CoreAnnotationServiceModule } from 'annotation-service/services/core-se
|
||||||
import { CoreNotificationServiceModule } from '@notification-service/services/core-service.module';
|
import { CoreNotificationServiceModule } from '@notification-service/services/core-service.module';
|
||||||
import { DepositOauth2DialogModule } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.module';
|
import { DepositOauth2DialogModule } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.module';
|
||||||
import { AnalyticsService } from './core/services/matomo/analytics-service';
|
import { AnalyticsService } from './core/services/matomo/analytics-service';
|
||||||
|
import { TenantHandlingService } from './core/services/tenant/tenant-handling.service';
|
||||||
|
|
||||||
// AoT requires an exported function for factories
|
// AoT requires an exported function for factories
|
||||||
export function HttpLoaderFactory(languageHttpService: LanguageHttpService) {
|
export function HttpLoaderFactory(languageHttpService: LanguageHttpService) {
|
||||||
|
@ -82,7 +83,7 @@ const appearance: MatFormFieldDefaultOptions = {
|
||||||
// appearance: 'standard'
|
// appearance: 'standard'
|
||||||
};
|
};
|
||||||
|
|
||||||
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService) {
|
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService:TenantHandlingService) {
|
||||||
return () => appConfig.loadConfiguration().then(() => {
|
return () => appConfig.loadConfiguration().then(() => {
|
||||||
return languageService.loadAvailableLanguages().toPromise();
|
return languageService.loadAvailableLanguages().toPromise();
|
||||||
}).then(x => keycloak.init({
|
}).then(x => keycloak.init({
|
||||||
|
@ -109,8 +110,10 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
||||||
InterceptorType.UnauthorizedResponse,
|
InterceptorType.UnauthorizedResponse,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tenantCode = tenantHandlingService.extractTenantCodeFromUrlPath(window.location.pathname) ?? authService.selectedTenant() ?? 'default';
|
||||||
const tokenPromise = keycloak.getToken();
|
const tokenPromise = keycloak.getToken();
|
||||||
return authService.prepareAuthRequest(from(tokenPromise), { params }).toPromise().catch(error => authService.onAuthenticateError(error));
|
return authService.prepareAuthRequest(from(tokenPromise), tenantCode, { params }).toPromise().catch(error => authService.onAuthenticateError(error));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import { VisibilityRulesService } from '@app/ui/description/editor/description-f
|
||||||
import { StorageFileService } from './services/storage-file/storage-file.service';
|
import { StorageFileService } from './services/storage-file/storage-file.service';
|
||||||
import { TenantConfigurationService } from './services/tenant-configuration/tenant-configuration.service';
|
import { TenantConfigurationService } from './services/tenant-configuration/tenant-configuration.service';
|
||||||
import { DefaultUserLocaleService } from './services/default-user-locale/default-user-locale.service';
|
import { DefaultUserLocaleService } from './services/default-user-locale/default-user-locale.service';
|
||||||
|
import { TenantHandlingService } from './services/tenant/tenant-handling.service';
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||||
|
@ -109,7 +110,8 @@ export class CoreServiceModule {
|
||||||
PrefillingSourceService,
|
PrefillingSourceService,
|
||||||
VisibilityRulesService,
|
VisibilityRulesService,
|
||||||
TenantConfigurationService,
|
TenantConfigurationService,
|
||||||
StorageFileService
|
StorageFileService,
|
||||||
|
TenantHandlingService
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,11 +154,11 @@ export class AuthService extends BaseService {
|
||||||
public isLoggedIn(): boolean {
|
public isLoggedIn(): boolean {
|
||||||
return this.authState();
|
return this.authState();
|
||||||
}
|
}
|
||||||
public prepareAuthRequest(observable: Observable<string>, httpParams?: Object): Observable<boolean> {
|
public prepareAuthRequest(observable: Observable<string>, tenantCode: string, httpParams?: Object): Observable<boolean> {
|
||||||
return observable.pipe(
|
return observable.pipe(
|
||||||
map((x) => this.currentAuthenticationToken(x)),
|
map((x) => this.currentAuthenticationToken(x)),
|
||||||
exhaustMap(() => forkJoin([
|
exhaustMap(() => forkJoin([
|
||||||
this.accessToken ? this.ensureTenant() : of(false),
|
this.accessToken ? this.ensureTenant(tenantCode ?? this.selectedTenant() ?? 'default') : of(false),
|
||||||
this.accessToken ? this.principalService.me(httpParams) : of(null),
|
this.accessToken ? this.principalService.me(httpParams) : of(null),
|
||||||
])),
|
])),
|
||||||
map((item) => {
|
map((item) => {
|
||||||
|
@ -176,10 +176,10 @@ export class AuthService extends BaseService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ensureTenant(): Observable<string> {
|
private ensureTenant(tenantCode: string): Observable<string> {
|
||||||
if (!this.selectedTenant()) {
|
// if (!this.selectedTenant()) {
|
||||||
this.selectedTenant('default');
|
// this.selectedTenant('default');
|
||||||
}
|
// }
|
||||||
const params = new BaseHttpParams();
|
const params = new BaseHttpParams();
|
||||||
params.interceptorContext = {
|
params.interceptorContext = {
|
||||||
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
||||||
|
@ -188,16 +188,21 @@ export class AuthService extends BaseService {
|
||||||
map(
|
map(
|
||||||
(myTenants) => {
|
(myTenants) => {
|
||||||
if (myTenants) {
|
if (myTenants) {
|
||||||
if (this.selectedTenant()) {
|
if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) {
|
||||||
if (myTenants.findIndex(x => x.code.toLocaleLowerCase() == this.selectedTenant().toLocaleLowerCase()) < 0) {
|
this.selectedTenant(tenantCode);
|
||||||
this.selectedTenant(null);
|
} else {
|
||||||
}
|
this.selectedTenant(null);
|
||||||
}
|
|
||||||
if (!this.selectedTenant()) {
|
|
||||||
if (myTenants.length > 0) {
|
|
||||||
this.selectedTenant(myTenants[0]?.code);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// if (this.selectedTenant()) {
|
||||||
|
// if (myTenants.findIndex(x => x.code.toLocaleLowerCase() == this.selectedTenant().toLocaleLowerCase()) < 0) {
|
||||||
|
// this.selectedTenant(null);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (!this.selectedTenant()) {
|
||||||
|
// if (myTenants.length > 0) {
|
||||||
|
// this.selectedTenant(myTenants[0]?.code);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
this.selectedTenant(null);
|
this.selectedTenant(null);
|
||||||
}
|
}
|
||||||
|
@ -326,6 +331,7 @@ export class AuthService extends BaseService {
|
||||||
|
|
||||||
return this.prepareAuthRequest(
|
return this.prepareAuthRequest(
|
||||||
from(this.keycloakService.getToken()),
|
from(this.keycloakService.getToken()),
|
||||||
|
this.selectedTenant(),
|
||||||
httpParams
|
httpParams
|
||||||
)
|
)
|
||||||
.pipe(takeUntil(this._destroyed))
|
.pipe(takeUntil(this._destroyed))
|
||||||
|
|
|
@ -57,21 +57,34 @@ export class CultureService {
|
||||||
// Set angular locale based on user selection.
|
// Set angular locale based on user selection.
|
||||||
// This is a very hacky way to map cultures with angular cultures, since there is no mapping. We first try to
|
// This is a very hacky way to map cultures with angular cultures, since there is no mapping. We first try to
|
||||||
// use the culture with the specialization (ex en-US), and if not exists we import the base culture (first part).
|
// use the culture with the specialization (ex en-US), and if not exists we import the base culture (first part).
|
||||||
let locale = newCulture.name;
|
// let locale = newCulture.name;
|
||||||
import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => {
|
// const base = import(
|
||||||
this.logger.error('Could not load locale: ' + locale);
|
// /* webpackExclude: /\.d\.ts$/ */
|
||||||
}).then(selectedLocale => {
|
// /* webpackMode: "lazy-once" */
|
||||||
if (selectedLocale) {
|
// /* webpackChunkName: "i18n-base" */
|
||||||
registerLocaleData(selectedLocale.default);
|
// `@angular/common/locales/${locale}.mjs`)//.then(m => m[basePkg]);
|
||||||
} else {
|
|
||||||
locale = newCulture.name.split('-')[0];
|
// const extra = import(
|
||||||
import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => {
|
// /* webpackExclude: /\.d\.ts$/ */
|
||||||
this.logger.error('Could not load locale: ' + locale);
|
// /* webpackMode: "lazy-once" */
|
||||||
}).then(selectedDefaultLocale => {
|
// /* webpackChunkName: "i18n-extra" */
|
||||||
registerLocaleData(selectedDefaultLocale.default);
|
// `@angular/common/locales/extra/${locale.split('-')[0]}.mjs`)//.then(m => m[extraPkg]);
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
// import(`/node_modules/ @angular/common/locales/${locale}.mjs`).catch(reason => {
|
||||||
|
// this.logger.error('Could not load locale: ' + locale);
|
||||||
|
// }).then(selectedLocale => {
|
||||||
|
// if (selectedLocale) {
|
||||||
|
// registerLocaleData(selectedLocale.default);
|
||||||
|
// } else {
|
||||||
|
// locale = newCulture.name.split('-')[0];
|
||||||
|
// import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => {
|
||||||
|
// this.logger.error('Could not load locale: ' + locale);
|
||||||
|
// }).then(selectedDefaultLocale => {
|
||||||
|
// registerLocaleData(selectedDefaultLocale.default);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
getCultureChangeObservable(): Observable<CultureInfo> {
|
getCultureChangeObservable(): Observable<CultureInfo> {
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { DOCUMENT, LocationStrategy } from '@angular/common';
|
||||||
|
import { Inject, Injectable } from '@angular/core';
|
||||||
|
import { PRIMARY_OUTLET, Router, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TenantHandlingService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(DOCUMENT) private readonly document: Document,
|
||||||
|
private readonly locationStrategy: LocationStrategy,
|
||||||
|
private readonly router: Router,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
extractTenantCodeFromUrlPath(path: string): string {
|
||||||
|
//Searches for "/t/<tenant_code>/" in a url;
|
||||||
|
const tenantRegex = new RegExp("\/t\/([^\/]+)");
|
||||||
|
const regexResult = tenantRegex.exec(path);
|
||||||
|
let tenantCode = null;
|
||||||
|
if (Array.isArray(regexResult) && regexResult.length > 0) {
|
||||||
|
tenantCode = regexResult[1];
|
||||||
|
}
|
||||||
|
return tenantCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentUrlEnrichedWithTenantCode(tenantCode: string, withOrigin: boolean) {
|
||||||
|
const path = this.getUrlEnrichedWithTenantCode(this.router.routerState.snapshot.url, tenantCode)
|
||||||
|
return withOrigin ? this.getBaseUrl() + path.substring(1) : path;
|
||||||
|
}
|
||||||
|
|
||||||
|
getUrlEnrichedWithTenantCode(url: string, tenantCode: string) {
|
||||||
|
|
||||||
|
const urlTree: UrlTree = this.router.parseUrl(url);
|
||||||
|
const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
|
||||||
|
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
|
||||||
|
|
||||||
|
const tenantParamIndex = urlSegments.findIndex(x => x.path == 't');
|
||||||
|
if (tenantParamIndex >= 0) {
|
||||||
|
|
||||||
|
if (tenantCode == 'default') {
|
||||||
|
urlSegments.splice(tenantParamIndex, 2);
|
||||||
|
} else {
|
||||||
|
const tenantCodeSegment = urlSegments.at(tenantParamIndex + 1);
|
||||||
|
tenantCodeSegment.path = tenantCode;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tenantCode != 'default') {
|
||||||
|
urlTree.root.children[PRIMARY_OUTLET].segments = [new UrlSegment('t', {}), new UrlSegment(tenantCode, {}), ...urlSegments];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlTree.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
getBaseUrl(): string {
|
||||||
|
return this.document.location.origin + this.locationStrategy.getBaseHref();
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,13 +31,13 @@
|
||||||
<div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]>
|
<div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]>
|
||||||
<div *ngIf="showDescription" class="mb-4">
|
<div *ngIf="showDescription" class="mb-4">
|
||||||
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</h5>
|
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</h5>
|
||||||
<rich-text-editor-component [form]="form.get('description')" [id]="'editor1'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
|
<rich-text-editor-component [form]="form.get('description')" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
|
||||||
</rich-text-editor-component>
|
</rich-text-editor-component>
|
||||||
<mat-error *ngIf="this.form.get('description').hasError('backendError')">{{form.get('description').getError('backendError').message}}</mat-error>
|
<mat-error *ngIf="this.form.get('description').hasError('backendError')">{{form.get('description').getError('backendError').message}}</mat-error>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="showExtendedDescription" class="mb-4">
|
<div *ngIf="showExtendedDescription" class="mb-4">
|
||||||
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</h5>
|
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</h5>
|
||||||
<rich-text-editor-component [form]="form.get('extendedDescription')" [id]="'editor2'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
|
<rich-text-editor-component [form]="form.get('extendedDescription')" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
|
||||||
</rich-text-editor-component>
|
</rich-text-editor-component>
|
||||||
<mat-error *ngIf="this.form.get('extendedDescription').hasError('backendError')">{{form.get('extendedDescription').getError('backendError').message}}</mat-error>
|
<mat-error *ngIf="this.form.get('extendedDescription').hasError('backendError')">{{form.get('extendedDescription').getError('backendError').message}}</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import { Component, Input, NgZone, OnInit } from '@angular/core';
|
import { Component, Input, NgZone, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
import { PrincipalService } from '@app/core/services/http/principal.service';
|
import { TenantHandlingService } from '@app/core/services/tenant/tenant-handling.service';
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
|
||||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
|
||||||
import { KeycloakService } from 'keycloak-angular';
|
import { KeycloakService } from 'keycloak-angular';
|
||||||
import { from } from 'rxjs';
|
import { from } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
@ -27,7 +25,7 @@ export class LoginComponent extends BaseComponent implements OnInit {
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private principalService: PrincipalService,
|
private tenantHandlingService: TenantHandlingService,
|
||||||
private keycloakService: KeycloakService
|
private keycloakService: KeycloakService
|
||||||
) { super(); }
|
) { super(); }
|
||||||
|
|
||||||
|
@ -36,7 +34,8 @@ export class LoginComponent extends BaseComponent implements OnInit {
|
||||||
if (!this.keycloakService.isLoggedIn()) {
|
if (!this.keycloakService.isLoggedIn()) {
|
||||||
this.authService.authenticate(this.returnUrl);
|
this.authService.authenticate(this.returnUrl);
|
||||||
} else {
|
} else {
|
||||||
this.authService.prepareAuthRequest(from(this.keycloakService.getToken())).pipe(takeUntil(this._destroyed)).subscribe(
|
const tenantCode = this.tenantHandlingService.extractTenantCodeFromUrlPath(this.returnUrl) ?? this.authService.selectedTenant() ?? 'default';
|
||||||
|
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), tenantCode).pipe(takeUntil(this._destroyed)).subscribe(
|
||||||
() => {
|
() => {
|
||||||
let returnUrL = this.returnUrl;
|
let returnUrL = this.returnUrl;
|
||||||
this.zone.run(() => this.router.navigateByUrl(returnUrL));
|
this.zone.run(() => this.router.navigateByUrl(returnUrL));
|
||||||
|
|
|
@ -15,13 +15,10 @@ export class LogoutComponent implements OnInit {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.authService.clear();
|
this.authService.clear();
|
||||||
|
debugger;
|
||||||
this.keycloak.logout(location.origin).then(() => {
|
this.keycloak.logout(location.origin).then(() => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
// this.router.navigate(['./'], { replaceUrl: true });
|
// this.router.navigate(['./'], { replaceUrl: true });
|
||||||
});
|
});
|
||||||
// this.tokenService.logout(() => {
|
|
||||||
// localStorage.clear();
|
|
||||||
// this.router.navigate(["./"], { replaceUrl: true });
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormattingModule } from '@app/core/formatting.module';
|
import { FormattingModule } from '@app/core/formatting.module';
|
||||||
import { DescriptionRoutingModule } from '@app/ui/description/description.routing';
|
import { DescriptionRoutingModule, PublicDescriptionRoutingModule } from '@app/ui/description/description.routing';
|
||||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||||
|
|
||||||
|
@ -17,3 +17,17 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class DescriptionModule { }
|
export class DescriptionModule { }
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonUiModule,
|
||||||
|
CommonFormsModule,
|
||||||
|
FormattingModule,
|
||||||
|
PublicDescriptionRoutingModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class PublicDescriptionModule { }
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||||
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
|
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
|
||||||
// import { DescriptionWizardComponent } from './description-wizard/description-wizard.component';
|
|
||||||
// import { DescriptionOverviewComponent } from './overview/description-overview.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'overview',
|
path: 'overview',
|
||||||
loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule),
|
loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule),
|
||||||
|
canActivate: [AuthGuard],
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -18,6 +18,28 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'edit',
|
path: 'edit',
|
||||||
loadChildren: () => import('./editor/description-editor.module').then(m => m.DescriptionEditorModule),
|
loadChildren: () => import('./editor/description-editor.module').then(m => m.DescriptionEditorModule),
|
||||||
|
canActivate: [AuthGuard],
|
||||||
|
data: {
|
||||||
|
breadcrumb: true,
|
||||||
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
hideNavigationItem: true
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
canActivate: [AuthGuard],
|
||||||
|
loadChildren: () => import('./listing/description-listing.module').then(m => m.DescriptionListingModule),
|
||||||
|
data: {
|
||||||
|
breadcrumb: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const publicRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'overview',
|
||||||
|
loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule),
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -40,3 +62,10 @@ const routes: Routes = [
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
export class DescriptionRoutingModule { }
|
export class DescriptionRoutingModule { }
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(publicRoutes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
providers: []
|
||||||
|
})
|
||||||
|
export class PublicDescriptionRoutingModule { }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormattingModule } from '@app/core/formatting.module';
|
import { FormattingModule } from '@app/core/formatting.module';
|
||||||
import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing';
|
import { DmpRoutingModule, PublicDmpRoutingModule } from '@app/ui/dmp/dmp.routing';
|
||||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||||
|
|
||||||
|
@ -17,3 +17,17 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class DmpModule { }
|
export class DmpModule { }
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonUiModule,
|
||||||
|
CommonFormsModule,
|
||||||
|
FormattingModule,
|
||||||
|
PublicDmpRoutingModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class PublicDmpModule { }
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
|
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
|
||||||
|
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'overview',
|
path: 'overview',
|
||||||
loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule),
|
loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule),
|
||||||
|
canActivate:[AuthGuard],
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -16,6 +18,7 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
|
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
|
||||||
|
canActivate:[AuthGuard],
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -27,6 +30,7 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'edit',
|
path: 'edit',
|
||||||
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
|
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
|
||||||
|
canActivate:[AuthGuard],
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true,
|
breadcrumb: true,
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
|
@ -37,80 +41,32 @@ const routes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
|
canActivate:[AuthGuard],
|
||||||
loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule),
|
loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule),
|
||||||
data: {
|
data: {
|
||||||
breadcrumb: true
|
breadcrumb: true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const publicRoutes: Routes = [
|
||||||
|
{
|
||||||
// {
|
path: 'overview',
|
||||||
// path: 'publicEdit/:publicId',
|
loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule),
|
||||||
// component: DmpEditorComponent,
|
data: {
|
||||||
// data: {
|
breadcrumb: true,
|
||||||
// breadcrumb: true,
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
// title: 'GENERAL.TITLES.DMP-PUBLIC-EDIT'
|
hideNavigationItem: true
|
||||||
// },
|
}),
|
||||||
// canDeactivate: [CanDeactivateGuard]
|
}
|
||||||
// },
|
},
|
||||||
|
{
|
||||||
// {
|
path: '',
|
||||||
// path: 'publicOverview/:publicId',
|
loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule),
|
||||||
// component: DmpOverviewComponent,
|
data: {
|
||||||
// data: {
|
breadcrumb: true
|
||||||
// breadcrumb: true,
|
},
|
||||||
// title: 'GENERAL.TITLES.DMP-OVERVIEW'
|
},
|
||||||
// },
|
|
||||||
// },
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// {
|
|
||||||
// path: 'new/dataset',
|
|
||||||
// component: DmpEditorComponent,
|
|
||||||
// canActivate: [AuthGuard],
|
|
||||||
// data: {
|
|
||||||
// breadcrumbs: 'new/dataset',
|
|
||||||
// title: 'GENERAL.TITLES.DATASET-NEW'
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'new/dataset/:dmpId',
|
|
||||||
// component: DmpEditorComponent,
|
|
||||||
// canActivate: [AuthGuard],
|
|
||||||
// data: {
|
|
||||||
// breadcrumbs: 'new/dataset',
|
|
||||||
// title: 'GENERAL.TITLES.DATASET-NEW'
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'new_version/:id',
|
|
||||||
// // component: DmpWizardComponent,
|
|
||||||
// component: DmpCloneComponent,
|
|
||||||
// data: {
|
|
||||||
// clone: false,
|
|
||||||
// breadcrumb: true,
|
|
||||||
// title: 'GENERAL.TITLES.DMP-NEW-VERSION'
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'clone/:id',
|
|
||||||
// component: DmpCloneComponent,
|
|
||||||
// data: {
|
|
||||||
// clone: false,
|
|
||||||
// breadcrumb: true,
|
|
||||||
// title: 'GENERAL.TITLES.DMP-CLONE'
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'invitation/:id',
|
|
||||||
// component: InvitationAcceptedComponent,
|
|
||||||
// data: {
|
|
||||||
// breadcrumb: true
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -118,3 +74,9 @@ const routes: Routes = [
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class DmpRoutingModule { }
|
export class DmpRoutingModule { }
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(publicRoutes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class PublicDmpRoutingModule { }
|
||||||
|
|
|
@ -90,14 +90,20 @@ export class NavbarComponent extends BaseComponent implements OnInit {
|
||||||
this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => {
|
this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => {
|
||||||
if (authenticationState.loginStatus === LoginStatus.LoggedIn) {
|
if (authenticationState.loginStatus === LoginStatus.LoggedIn) {
|
||||||
this.loadLogo();
|
this.loadLogo();
|
||||||
|
this.loadUser();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.loadLogo();
|
this.loadLogo();
|
||||||
|
this.loadUser();
|
||||||
|
}
|
||||||
|
|
||||||
this.userService.getSingle(this.authentication.userId(), [
|
private loadUser() {
|
||||||
nameof<User>(x => x.id),
|
if (this.authentication.currentAccountIsAuthenticated() && this.authentication.userId()) {
|
||||||
nameof<User>(x => x.name)
|
this.userService.getSingle(this.authentication.userId(), [
|
||||||
]).subscribe(u => this.userName = u.name); //TODO HANDLE-ERRORS
|
nameof<User>(x => x.id),
|
||||||
|
nameof<User>(x => x.name)
|
||||||
|
]).subscribe(u => this.userName = u.name); //TODO HANDLE-ERRORS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadLogo() {
|
private loadLogo() {
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { MatButtonToggleChange } from "@angular/material/button-toggle";
|
import { MatButtonToggleChange } from "@angular/material/button-toggle";
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { Tenant } from "@app/core/model/tenant/tenant";
|
import { Tenant } from "@app/core/model/tenant/tenant";
|
||||||
import { AuthService } from "@app/core/services/auth/auth.service";
|
import { AuthService } from "@app/core/services/auth/auth.service";
|
||||||
import { PrincipalService } from "@app/core/services/http/principal.service";
|
import { PrincipalService } from "@app/core/services/http/principal.service";
|
||||||
|
import { TenantHandlingService } from "@app/core/services/tenant/tenant-handling.service";
|
||||||
import { BaseComponent } from "@common/base/base.component";
|
import { BaseComponent } from "@common/base/base.component";
|
||||||
import { BaseHttpParams } from "@common/http/base-http-params";
|
import { BaseHttpParams } from "@common/http/base-http-params";
|
||||||
import { InterceptorType } from "@common/http/interceptors/interceptor-type";
|
import { InterceptorType } from "@common/http/interceptors/interceptor-type";
|
||||||
import { KeycloakService } from "keycloak-angular";
|
import { Observable } from "rxjs";
|
||||||
import { Observable, from } from "rxjs";
|
|
||||||
import { takeUntil } from "rxjs/operators";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-tenant-switch',
|
selector: 'app-tenant-switch',
|
||||||
|
@ -20,10 +18,9 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
|
||||||
tenants: Observable<Array<Tenant>>;
|
tenants: Observable<Array<Tenant>>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
|
||||||
private keycloakService: KeycloakService,
|
|
||||||
private principalService: PrincipalService,
|
private principalService: PrincipalService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
|
private tenantHandlingService: TenantHandlingService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -34,7 +31,6 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.tenants = this.loadUserTenants(); //TODO
|
this.tenants = this.loadUserTenants(); //TODO
|
||||||
//this.tenantChange.emit(this.getCurrentLanguage())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUserTenants(): Observable<Array<Tenant>> {
|
loadUserTenants(): Observable<Array<Tenant>> {
|
||||||
|
@ -48,22 +44,7 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
|
||||||
onTenantSelected(selectedTenant: MatButtonToggleChange) {
|
onTenantSelected(selectedTenant: MatButtonToggleChange) {
|
||||||
if (selectedTenant.value === undefined || selectedTenant.value === '') return;
|
if (selectedTenant.value === undefined || selectedTenant.value === '') return;
|
||||||
|
|
||||||
this.formSubmit(selectedTenant.value);
|
this.authService.selectedTenant(selectedTenant.value);
|
||||||
this.loadUser();
|
window.location.href = this.tenantHandlingService.getCurrentUrlEnrichedWithTenantCode(selectedTenant.value, true);
|
||||||
}
|
|
||||||
|
|
||||||
formSubmit(selectedTenant: string): void {
|
|
||||||
this.authService.selectedTenant(selectedTenant);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadUser(): void {
|
|
||||||
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), {})
|
|
||||||
.pipe(takeUntil(this._destroyed))
|
|
||||||
.subscribe(
|
|
||||||
() => {
|
|
||||||
this.authService.onAuthenticateSuccessReload();
|
|
||||||
},
|
|
||||||
(error) => this.authService.onAuthenticateError(error)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
@ -18,6 +17,7 @@ import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
||||||
import { ReferenceService } from '@app/core/services/reference/reference.service';
|
import { ReferenceService } from '@app/core/services/reference/reference.service';
|
||||||
|
import { TenantHandlingService } from '@app/core/services/tenant/tenant-handling.service';
|
||||||
import { UserService } from '@app/core/services/user/user.service';
|
import { UserService } from '@app/core/services/user/user.service';
|
||||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||||
|
@ -28,16 +28,15 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati
|
||||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||||
import { Guid } from '@common/types/guid';
|
import { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { KeycloakService } from 'keycloak-angular';
|
|
||||||
import * as moment from 'moment-timezone';
|
import * as moment from 'moment-timezone';
|
||||||
import { Observable, from, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
import { AddAccountDialogComponent } from './add-account/add-account-dialog.component';
|
import { AddAccountDialogComponent } from './add-account/add-account-dialog.component';
|
||||||
import { UserProfileEditorModel } from './user-profile-editor.model';
|
import { UserProfileEditorModel } from './user-profile-editor.model';
|
||||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-profile',
|
selector: 'app-user-profile',
|
||||||
|
@ -81,7 +80,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
public enumUtils: EnumUtils,
|
public enumUtils: EnumUtils,
|
||||||
private formBuilder: UntypedFormBuilder,
|
private formBuilder: UntypedFormBuilder,
|
||||||
private keycloakService: KeycloakService,
|
private tenantHandlingService: TenantHandlingService,
|
||||||
private principalService: PrincipalService,
|
private principalService: PrincipalService,
|
||||||
private formService: FormService,
|
private formService: FormService,
|
||||||
private referenceService: ReferenceService,
|
private referenceService: ReferenceService,
|
||||||
|
@ -281,7 +280,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
||||||
}, maxWidth: '30em'
|
}, maxWidth: '30em'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -309,7 +308,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error)); //TODO how to handle this
|
error => this.httpErrorHandlingService.handleBackedRequestError(error)); //TODO how to handle this
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -367,17 +366,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
||||||
if (this.tenantFormGroup.valid === false) return;
|
if (this.tenantFormGroup.valid === false) return;
|
||||||
|
|
||||||
const selectedTenant = this.tenantFormGroup.get('tenantCode').value;
|
const selectedTenant = this.tenantFormGroup.get('tenantCode').value;
|
||||||
this.formSubmit(selectedTenant);
|
|
||||||
this.loadUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
formSubmit(selectedTenant: string): void {
|
this.authService.selectedTenant(selectedTenant.value);
|
||||||
this.authService.selectedTenant(selectedTenant);
|
window.location.href = this.tenantHandlingService.getCurrentUrlEnrichedWithTenantCode(selectedTenant.value, true);
|
||||||
}
|
|
||||||
|
|
||||||
loadUser(): void {
|
|
||||||
const returnUrl = '/profile';
|
|
||||||
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), {}).pipe(takeUntil(this._destroyed)).subscribe(() => this.authService.onAuthenticateSuccess(returnUrl), (error) => this.authService.onAuthenticateError(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Preferences
|
//Preferences
|
||||||
|
|
|
@ -43,13 +43,13 @@ export class UnauthorizedResponseInterceptor extends BaseInterceptor {
|
||||||
this.authService.refreshToken().then((isRefreshed) => {
|
this.authService.refreshToken().then((isRefreshed) => {
|
||||||
this.accountRefresh$ = null;
|
this.accountRefresh$ = null;
|
||||||
if (!isRefreshed) {
|
if (!isRefreshed) {
|
||||||
this.logoutUser();
|
this.handleUnauthorized();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}).catch(x => {
|
}).catch(x => {
|
||||||
this.logoutUser();
|
this.handleUnauthorized();
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
).pipe(filter((x) => x));
|
).pipe(filter((x) => x));
|
||||||
|
@ -67,10 +67,10 @@ export class UnauthorizedResponseInterceptor extends BaseInterceptor {
|
||||||
return next.handle(newRequest);
|
return next.handle(newRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private logoutUser() {
|
private handleUnauthorized() {
|
||||||
if (!this.isLoginRoute() && !this.isSignupRoute()) {
|
if (!this.isLoginRoute() && !this.isSignupRoute()) {
|
||||||
this.authService.clear();
|
this.authService.clear();
|
||||||
this.router.navigate(['/unauthorized']);
|
this.router.navigate(['/unauthorized', { queryParams: { returnUrl: this.router.url } }]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue