Merge branch 'devel' of https://github.com/dbeaver/cloudbeaver into devel

This commit is contained in:
Wroud
2022-06-20 17:17:36 +03:00
5 changed files with 96 additions and 9 deletions
@@ -221,7 +221,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
contextDefaults != null && contextDefaults.supportsSchemaChange()
&& (
contextDefaults.getDefaultCatalog().getName().equals(node.getName())
|| catalog.equals(node.getName())
|| node.getName().equals(catalog)
)
) {
try {
@@ -10,16 +10,24 @@ import { ProcessSnackbar } from '@cloudbeaver/core-blocks';
import { injectable } from '@cloudbeaver/core-di';
import { CommonDialogService, ConfirmationDialogDelete, DialogueStateResult } from '@cloudbeaver/core-dialogs';
import { NotificationService } from '@cloudbeaver/core-events';
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { Executor, ExecutorInterrupter, IExecutor } from '@cloudbeaver/core-executor';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
import { AuthenticationService } from '@cloudbeaver/plugin-authentication';
import { ConnectionInfoResource, Connection } from './ConnectionInfoResource';
import { ContainerResource, IStructContainers, ObjectContainer } from './ContainerResource';
import { EConnectionFeature } from './EConnectionFeature';
export interface IConnectionExecutorData {
connections: string[];
state: 'before' | 'after';
}
@injectable()
export class ConnectionsManagerService {
readonly connectionExecutor: IExecutor<string | null>;
readonly onDisconnect: IExecutor<IConnectionExecutorData>;
readonly onDelete: IExecutor<IConnectionExecutorData>;
private disconnecting: boolean;
@@ -27,11 +35,23 @@ export class ConnectionsManagerService {
readonly connectionInfo: ConnectionInfoResource,
readonly containerContainers: ContainerResource,
private readonly notificationService: NotificationService,
private readonly commonDialogService: CommonDialogService
private readonly commonDialogService: CommonDialogService,
private readonly authenticationService: AuthenticationService,
) {
this.disconnecting = false;
this.connectionExecutor = new Executor<string | null>(null, (active, current) => active === current);
this.onDisconnect = new Executor();
this.onDelete = new Executor();
this.connectionExecutor.addHandler(() => connectionInfo.load(CachedMapAllKey));
this.onDelete.before(this.onDisconnect);
this.authenticationService.onLogout.before(this.onDisconnect, state => ({
connections: this.connectionInfo.values
.filter(connection => connection.connected)
.map(connection => connection.id),
state,
}));
}
async requireConnection(connectionId: string | null = null): Promise<Connection | null> {
@@ -93,7 +113,21 @@ export class ConnectionsManagerService {
return;
}
const contexts = await this.onDelete.execute({
connections: [id],
state: 'before',
});
if (ExecutorInterrupter.isInterrupted(contexts)) {
return;
}
await this.connectionInfo.deleteConnection(id);
this.onDelete.execute({
connections: [id],
state: 'after',
});
}
hasAnyConnection(connected?: boolean): boolean {
@@ -140,11 +174,25 @@ export class ConnectionsManagerService {
if (!connection || !connection.connected) {
return;
}
const contexts = await this.onDisconnect.execute({
connections: [connection.id],
state: 'before',
});
if (ExecutorInterrupter.isInterrupted(contexts)) {
return;
}
const { controller, notification } = this.notificationService.processNotification(() => ProcessSnackbar, {}, { title: 'Disconnecting...' });
try {
await this._closeConnectionAsync(connection);
notification.close();
this.onDisconnect.execute({
connections: [connection.id],
state: 'after',
});
} catch (exception: any) {
controller.reject(exception);
}
@@ -11,7 +11,7 @@ import { AppAuthService, AuthInfoService, AuthProviderContext, AuthProviderServi
import { injectable, Bootstrap } from '@cloudbeaver/core-di';
import type { DialogueStateResult } from '@cloudbeaver/core-dialogs';
import { NotificationService } from '@cloudbeaver/core-events';
import type { IExecutorHandler } from '@cloudbeaver/core-executor';
import { Executor, ExecutorInterrupter, IExecutorHandler } from '@cloudbeaver/core-executor';
import { ServerConfigResource, SessionDataResource } from '@cloudbeaver/core-root';
import { ScreenService } from '@cloudbeaver/core-routing';
import type { ObjectOrigin } from '@cloudbeaver/core-sdk';
@@ -19,8 +19,12 @@ import { openCenteredPopup } from '@cloudbeaver/core-utils';
import { AuthDialogService } from './Dialog/AuthDialogService';
export type LogoutEventType = 'before' | 'after';
@injectable()
export class AuthenticationService extends Bootstrap {
readonly onLogout: Executor<LogoutEventType>;
configureAuthProvider: (() => void) | null;
configureIdentityProvider: (() => void) | null;
@@ -40,6 +44,9 @@ export class AuthenticationService extends Bootstrap {
private readonly serverConfigResource: ServerConfigResource,
) {
super();
this.onLogout = new Executor();
this.authPromise = null;
this.configureAuthProvider = null;
this.configureIdentityProvider = null;
@@ -58,6 +65,12 @@ export class AuthenticationService extends Bootstrap {
}
async logout(): Promise<void> {
const contexts = await this.onLogout.execute('before');
if (ExecutorInterrupter.isInterrupted(contexts)) {
return;
}
if (this.authInfoService.userAuthConfigurations.length > 0) {
const userAuthConfiguration = this.authInfoService.userAuthConfigurations[0];
@@ -72,6 +85,8 @@ export class AuthenticationService extends Bootstrap {
if (!this.administrationScreenService.isConfigurationMode) {
this.screenService.navigateToRoot();
}
await this.onLogout.execute('after');
} catch (exception: any) {
this.notificationService.logException(exception, 'Can\'t logout');
}
@@ -12,15 +12,15 @@ import {
ConnectionSchemaManagerService,
isObjectCatalogProvider, isObjectSchemaProvider, DATA_CONTEXT_NAV_NODE, NavigationTabsService
} from '@cloudbeaver/core-app';
import { isConnectionProvider } from '@cloudbeaver/core-connections';
import { ConnectionsManagerService, IConnectionExecutorData, isConnectionProvider } from '@cloudbeaver/core-connections';
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { CommonDialogService, DialogueStateResult, RenameDialog } from '@cloudbeaver/core-dialogs';
import type { IExecutorHandler } from '@cloudbeaver/core-executor';
import { ExecutorInterrupter, IExecutionContextProvider, IExecutorHandler } from '@cloudbeaver/core-executor';
import { ExtensionUtils } from '@cloudbeaver/core-extensions';
import { ISessionAction, sessionActionContext, SessionActionService } from '@cloudbeaver/core-root';
import { ActionService, ACTION_RENAME, DATA_CONTEXT_MENU_NESTED, menuExtractActions, MenuService, ViewService } from '@cloudbeaver/core-view';
import { DATA_CONTEXT_CONNECTION } from '@cloudbeaver/plugin-connections';
import { DATA_CONTEXT_SQL_EDITOR_STATE, LocalStorageSqlDataSource } from '@cloudbeaver/plugin-sql-editor';
import { DATA_CONTEXT_SQL_EDITOR_STATE, LocalStorageSqlDataSource, SqlResultTabsService } from '@cloudbeaver/plugin-sql-editor';
import { ACTION_SQL_EDITOR_OPEN } from './ACTION_SQL_EDITOR_OPEN';
import { DATA_CONTEXT_SQL_EDITOR_TAB } from './DATA_CONTEXT_SQL_EDITOR_TAB';
@@ -41,12 +41,16 @@ export class SqlEditorBootstrap extends Bootstrap {
private readonly menuService: MenuService,
private readonly sessionActionService: SessionActionService,
private readonly commonDialogService: CommonDialogService,
private readonly sqlEditorTabService: SqlEditorTabService
private readonly sqlEditorTabService: SqlEditorTabService,
private readonly sqlResultTabsService: SqlResultTabsService,
private readonly connectionsManagerService: ConnectionsManagerService,
) {
super();
}
register(): void {
this.connectionsManagerService.onDisconnect.addHandler(this.disconnectHandler.bind(this));
this.mainMenuService.registerRootItem(
{
id: 'sql-editor',
@@ -195,4 +199,24 @@ export class SqlEditorBootstrap extends Bootstrap {
}
}
};
private async disconnectHandler(
data: IConnectionExecutorData,
contexts: IExecutionContextProvider<IConnectionExecutorData>
) {
if (data.state === 'before') {
for (const tab of this.sqlEditorTabService.sqlEditorTabs) {
if (!data.connections.includes(tab.handlerState.executionContext?.connectionId ?? '')) {
continue;
}
const canDisconnect = await this.sqlResultTabsService.canCloseResultTabs(tab.handlerState);
if (!canDisconnect) {
ExecutorInterrupter.interrupt(contexts);
return;
}
}
}
}
}
@@ -125,5 +125,5 @@ export class MenuBootstrap extends Bootstrap {
}
}
load(): void { }
load(): void | Promise<void> { }
}