diff --git a/webapp/packages/core-app/src/index.ts b/webapp/packages/core-app/src/index.ts index d6742cee8b..d8b6099614 100644 --- a/webapp/packages/core-app/src/index.ts +++ b/webapp/packages/core-app/src/index.ts @@ -21,7 +21,7 @@ export * from './shared/NavigationTabs/NavigationTabsService'; export * from './shared/NavigationTabs/TabNavigationContext'; export * from './shared/ToolsPanel/LogViewTab/LogViewerMenuService'; export * from './shared/ToolsPanel/LogViewTab/LogViewerService'; -export * from './shared/SessionExpire/SessionExpireService'; +export * from './shared/SessionExpireDialog/SessionExpiredDialogService'; export * from './NavigationTree/NavigationTreeService'; export * from './NavigationTree/NavigationTreeContextMenuService'; export * from './AppLocaleService'; diff --git a/webapp/packages/core-app/src/shared/SessionExpire/SessionExpiredDialog.tsx b/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx similarity index 100% rename from webapp/packages/core-app/src/shared/SessionExpire/SessionExpiredDialog.tsx rename to webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx diff --git a/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialogService.ts b/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialogService.ts new file mode 100644 index 0000000000..15e1c50779 --- /dev/null +++ b/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialogService.ts @@ -0,0 +1,42 @@ +/* + * cloudbeaver - Cloud Database Manager + * Copyright (C) 2020 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + + +import { ActionSnackbar } from '@cloudbeaver/core-blocks'; +import { injectable } from '@cloudbeaver/core-di'; +import { CommonDialogService } from '@cloudbeaver/core-dialogs'; +import { ENotificationType, NotificationService } from '@cloudbeaver/core-events'; +import { SessionExpireService } from '@cloudbeaver/core-root'; + +import { SessionExpiredDialog } from './SessionExpiredDialog'; + +@injectable() +export class SessionExpiredDialogService { + constructor( + private notificationService: NotificationService, + private commonDialogService: CommonDialogService, + private sessionExpireService: SessionExpireService + ) { + } + + subscribe(): void { + this.sessionExpireService.onSessionExpire.subscribe(this.sessionExpiredInterceptor.bind(this)); + } + + private async sessionExpiredInterceptor(): Promise { + try { + await this.commonDialogService.open(SessionExpiredDialog, null); + } finally { + this.notificationService.customNotification(() => ActionSnackbar, { + actionText: 'app_root_session_expired_reload', + onAction: () => location.reload(), + }, { title: 'app_root_session_expired_title', persistent: true, type: ENotificationType.Error }); + } + + } +} diff --git a/webapp/packages/core-bootstrap/src/AppBootstrap.ts b/webapp/packages/core-bootstrap/src/AppBootstrap.ts index c32fe07f54..0504be6882 100644 --- a/webapp/packages/core-bootstrap/src/AppBootstrap.ts +++ b/webapp/packages/core-bootstrap/src/AppBootstrap.ts @@ -11,10 +11,11 @@ import { NavigationTabsService, NavigationTreeContextMenuService, LogViewerMenuService, - ConnectionSchemaManagerService, SessionExpireService + ConnectionSchemaManagerService, SessionExpiredDialogService } from '@cloudbeaver/core-app'; import { injectable } from '@cloudbeaver/core-di'; import { ExceptionsCatcherService } from '@cloudbeaver/core-events'; +import { SessionExpireService } from '@cloudbeaver/core-root'; import { ThemeService } from '@cloudbeaver/core-theming'; /** @@ -31,6 +32,7 @@ export class AppBootstrap { private connectionDialogService: ConnectionDialogsService, private logViewerMenuService: LogViewerMenuService, private sessionExpireService: SessionExpireService, + private sessionExpireDialogService: SessionExpiredDialogService, private navigationTreeContextMenuService: NavigationTreeContextMenuService, private navigationTabsService: NavigationTabsService, private connectionSchemaManagerService: ConnectionSchemaManagerService, @@ -39,7 +41,7 @@ export class AppBootstrap { register(): void | Promise { this.exceptionsCatcherService.subscribe(); this.sessionExpireService.subscribe(); - + this.sessionExpireDialogService.subscribe(); this.connectionSchemaManagerService.registerCallbacks(); this.navigationTreeContextMenuService.registerMenuItems(); this.connectionDialogService.registerMenuItems(); diff --git a/webapp/packages/core-bootstrap/src/manifest.ts b/webapp/packages/core-bootstrap/src/manifest.ts index d357a37ec7..52ed990d13 100644 --- a/webapp/packages/core-bootstrap/src/manifest.ts +++ b/webapp/packages/core-bootstrap/src/manifest.ts @@ -37,7 +37,7 @@ import { CoreSettingsService, AdministrationTopAppBarBootstrapService, AppLocaleService, - SessionExpireService + SessionExpiredDialogService } from '@cloudbeaver/core-app'; import { AuthInfoService, @@ -75,7 +75,7 @@ import { ServerSettingsService, ServerConfigResource, PermissionsResource, - SessionResource, + SessionResource, SessionExpireService } from '@cloudbeaver/core-root'; import { RouterService, ScreenService } from '@cloudbeaver/core-routing'; import { EnvironmentService, GraphQLService } from '@cloudbeaver/core-sdk'; @@ -120,6 +120,7 @@ export const coreManifest: PluginManifest = { CoreSettingsService, CommonDialogService, SessionExpireService, + SessionExpiredDialogService, ConnectionsLocaleService, ConnectionDialogsService, ConnectionSchemaManagerService, diff --git a/webapp/packages/core-events/src/NotificationService.ts b/webapp/packages/core-events/src/NotificationService.ts index e408d8a104..e5bf2cc72c 100644 --- a/webapp/packages/core-events/src/NotificationService.ts +++ b/webapp/packages/core-events/src/NotificationService.ts @@ -14,7 +14,6 @@ import { EventsSettingsService } from './EventsSettingsService'; import { ENotificationType, INotification, INotificationExtraProps, INotificationOptions, NotificationComponent } from './INotification'; -import { SessionError } from './SessionError'; @injectable() @@ -95,11 +94,7 @@ export class NotificationService { logException(exception: Error | GQLError, message?: string, silent?: boolean): void { const exceptionMessage = hasDetails(exception) ? exception.errorText : exception.message || exception.name; - const isSessionExpired = exception instanceof SessionError; - if(isSessionExpired && message) { - message = exception.message - } if (!silent) { this.logError({ title: message || exceptionMessage, diff --git a/webapp/packages/core-events/src/index.ts b/webapp/packages/core-events/src/index.ts index 81cc9edb4c..368c849337 100644 --- a/webapp/packages/core-events/src/index.ts +++ b/webapp/packages/core-events/src/index.ts @@ -1,6 +1,5 @@ export * from './NotificationService'; export * from './INotification'; export * from './DbeaverError'; -export * from './SessionError' export * from './ExceptionsCatcherService'; export * from './EventsSettingsService'; diff --git a/webapp/packages/core-events/src/SessionError.ts b/webapp/packages/core-root/src/SessionError.ts similarity index 100% rename from webapp/packages/core-events/src/SessionError.ts rename to webapp/packages/core-root/src/SessionError.ts diff --git a/webapp/packages/core-app/src/shared/SessionExpire/SessionExpireService.ts b/webapp/packages/core-root/src/SessionExpireService.ts similarity index 54% rename from webapp/packages/core-app/src/shared/SessionExpire/SessionExpireService.ts rename to webapp/packages/core-root/src/SessionExpireService.ts index 0d8c1a6b16..aeb1f725c6 100644 --- a/webapp/packages/core-app/src/shared/SessionExpire/SessionExpireService.ts +++ b/webapp/packages/core-root/src/SessionExpireService.ts @@ -8,16 +8,13 @@ import { Subject } from 'rxjs'; -import { ActionSnackbar } from '@cloudbeaver/core-blocks'; import { injectable } from '@cloudbeaver/core-di'; -import { CommonDialogService } from '@cloudbeaver/core-dialogs'; -import { ENotificationType, NotificationService } from '@cloudbeaver/core-events'; -import { SessionError } from '@cloudbeaver/core-events'; import { GQLError, GraphQLService, EServerErrorCode } from '@cloudbeaver/core-sdk'; -import { SessionExpiredDialog } from './SessionExpiredDialog'; +import { SessionError } from './SessionError'; + @injectable() export class SessionExpireService { @@ -26,8 +23,6 @@ export class SessionExpireService { onSessionExpire = new Subject(); constructor( private graphQLService: GraphQLService, - private notificationService: NotificationService, - private commonDialogService: CommonDialogService ) { } @@ -42,18 +37,10 @@ export class SessionExpireService { if (exception instanceof GQLError && exception.errorCode === EServerErrorCode.sessionExpired && !this.isNotifiedAboutExpiredSession) { + const e = new SessionError('Session expired'); + this.graphQLService.blockRequests(e); this.isNotifiedAboutExpiredSession = true; this.onSessionExpire.next(); - try { - await this.commonDialogService.open(SessionExpiredDialog, null); - } finally { - const e = new SessionError('Session expired'); - this.graphQLService.blockRequests(e); - this.notificationService.customNotification(() => ActionSnackbar, { - actionText: 'app_root_session_expired_reload', - onAction: () => location.reload(), - }, { title: 'app_root_session_expired_title', persistent: true, type: ENotificationType.Error }); - } } throw exception; } diff --git a/webapp/packages/core-root/src/index.ts b/webapp/packages/core-root/src/index.ts index 62a7479682..3948e481d7 100644 --- a/webapp/packages/core-root/src/index.ts +++ b/webapp/packages/core-root/src/index.ts @@ -7,3 +7,4 @@ export * from './ServerService'; export * from './usePermission'; export * from './ServerSettingsService'; export * from './SessionSettingsService'; +export * from './SessionExpireService'; diff --git a/webapp/packages/core-sdk/src/CustomGraphQLClient.ts b/webapp/packages/core-sdk/src/CustomGraphQLClient.ts index 0bea990e03..15f131129c 100644 --- a/webapp/packages/core-sdk/src/CustomGraphQLClient.ts +++ b/webapp/packages/core-sdk/src/CustomGraphQLClient.ts @@ -14,7 +14,8 @@ import { IResponseInterceptor } from './IResponseInterceptor'; export class CustomGraphQLClient extends GraphQLClient { private interceptors: IResponseInterceptor[] = []; - private isRequestsBlockedData: { status: boolean; reason: Error | string } = { status: false, reason: '' }; + private isRequestsBlocked = false; + private requestsBlockedReason?: Error | string; constructor(endpoint: string) { super(endpoint); @@ -32,23 +33,24 @@ export class CustomGraphQLClient extends GraphQLClient { } blockRequests(reason: Error | string): void { - this.isRequestsBlockedData.status = true; - this.isRequestsBlockedData.reason = reason; + this.isRequestsBlocked = true; + this.requestsBlockedReason = reason; } - blockRequestsReasonHandler(): void { - if(this.isRequestsBlockedData.reason instanceof Error) { - throw this.isRequestsBlockedData.reason; - } else { - throw new Error(this.isRequestsBlockedData.reason) + private blockRequestsReasonHandler(): void { + if(!this.isRequestsBlocked) { + return; + } else { + if(this.requestsBlockedReason instanceof Error) { + throw this.requestsBlockedReason; + } else { + throw new Error(this.requestsBlockedReason) + } } } private async overrideRequest(query: string, variables?: Variables): Promise { - if(this.isRequestsBlockedData.status) { - this.blockRequestsReasonHandler(); - } - + this.blockRequestsReasonHandler(); try { const response = await this.rawRequest(query, variables);