From 46c6eb8593f93fd69596035d32899b5ca8e6ea4f Mon Sep 17 00:00:00 2001 From: Wroud Date: Wed, 9 Feb 2022 13:16:02 +0300 Subject: [PATCH] feat(plugin-sql-editor): CB-1631 select existing sql console --- .../NavigationTabs/NavigationTabsService.ts | 4 +- .../src/SQL_EDITOR_SOURCE_ACTION.ts | 9 ++++ .../src/SqlEditorBootstrap.ts | 11 ++-- .../src/SqlEditorNavigatorService.ts | 50 ++++++++++++------- .../src/SqlEditorTabService.ts | 6 +-- .../src/ISqlEditorTabState.ts | 2 +- .../plugin-sql-editor/src/SqlEditor.tsx | 22 +++++++- .../plugin-sql-editor/src/SqlEditorService.ts | 4 +- 8 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 webapp/packages/plugin-sql-editor-navigation-tab/src/SQL_EDITOR_SOURCE_ACTION.ts diff --git a/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsService.ts b/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsService.ts index aa6ebf13fb..6f4e9ba753 100644 --- a/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsService.ts +++ b/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsService.ts @@ -290,8 +290,6 @@ export class NavigationTabsService extends View { if (!this.appAuthService.authenticated) { return; } - - this.onInit.execute(true); for (const handler of this.handlers.values()) { await handler.onNavInit?.(); @@ -323,6 +321,8 @@ export class NavigationTabsService extends View { this.selectTab(this.userTabsState.currentId); this.onTabSelect.execute(tab); } + + this.onInit.execute(true); } private async callHandlerCallback(tab: ITab, selector: (handler: TabHandler) => TabHandlerEvent | undefined) { diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SQL_EDITOR_SOURCE_ACTION.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SQL_EDITOR_SOURCE_ACTION.ts new file mode 100644 index 0000000000..6c2a0f1c3b --- /dev/null +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SQL_EDITOR_SOURCE_ACTION.ts @@ -0,0 +1,9 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export const SQL_EDITOR_SOURCE_ACTION = 'action'; \ No newline at end of file diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorBootstrap.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorBootstrap.ts index 8d8777b75c..adeec6d6e3 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorBootstrap.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorBootstrap.ts @@ -25,6 +25,7 @@ import { DATA_CONTEXT_SQL_EDITOR_STATE } 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'; import { isSessionActionOpenSQLEditor } from './sessionActionOpenSQLEditor'; +import { SQL_EDITOR_SOURCE_ACTION } from './SQL_EDITOR_SOURCE_ACTION'; import { SqlEditorNavigatorService } from './SqlEditorNavigatorService'; import { SqlEditorTabService } from './SqlEditorTabService'; @@ -132,7 +133,7 @@ export class SqlEditorBootstrap extends Bootstrap { case ACTION_SQL_EDITOR_OPEN: { const connection = context.get(DATA_CONTEXT_CONNECTION); - this.sqlEditorNavigatorService.openNewEditor(undefined, connection.id); + this.sqlEditorNavigatorService.openNewEditor({ connectionId: connection.id }); break; } } @@ -178,7 +179,7 @@ export class SqlEditorBootstrap extends Bootstrap { schemaId = this.connectionSchemaManagerService.currentObjectSchemaId; } - this.sqlEditorNavigatorService.openNewEditor(undefined, connectionId, catalogId, schemaId); + this.sqlEditorNavigatorService.openNewEditor({ connectionId, catalogId, schemaId }); } private readonly handleAction: IExecutorHandler = (data, contexts) => { @@ -186,7 +187,11 @@ export class SqlEditorBootstrap extends Bootstrap { if (isSessionActionOpenSQLEditor(data)) { try { - this.sqlEditorNavigatorService.openNewEditor(data['editor-name'], data['connection-id']); + this.sqlEditorNavigatorService.openNewEditor({ + name: data['editor-name'], + connectionId: data['connection-id'], + source: SQL_EDITOR_SOURCE_ACTION, + }); } finally { processInfo.process(); } diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts index 053691893c..b470dd6ffc 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts @@ -13,6 +13,7 @@ import { IExecutor, Executor, IExecutionContextProvider } from '@cloudbeaver/cor import { NavigationService } from '@cloudbeaver/core-ui'; import { ISqlEditorTabState, SqlResultTabsService } from '@cloudbeaver/plugin-sql-editor'; +import { SQL_EDITOR_SOURCE_ACTION } from './SQL_EDITOR_SOURCE_ACTION'; import { SqlEditorTabService, isSQLEditorTab } from './SqlEditorTabService'; enum SQLEditorNavigationAction { @@ -25,13 +26,16 @@ export interface SQLEditorActionContext { type: SQLEditorNavigationAction; } -export interface SQLCreateAction extends SQLEditorActionContext { - type: SQLEditorNavigationAction.create; - +export interface ISQLEditorOptions { name?: string; connectionId?: string; catalogId?: string; schemaId?: string; + source?: string; +} + +export interface SQLCreateAction extends SQLEditorActionContext, ISQLEditorOptions { + type: SQLEditorNavigationAction.create; } export interface SQLEditorAction extends SQLEditorActionContext { @@ -60,13 +64,10 @@ export class SqlEditorNavigatorService { .addHandler(this.navigateHandler.bind(this)); } - async openNewEditor(name?: string, connectionId?: string, catalogId?: string, schemaId?: string): Promise { + async openNewEditor(options: ISQLEditorOptions): Promise { await this.navigator.execute({ type: SQLEditorNavigationAction.create, - name, - connectionId, - catalogId, - schemaId, + ...options, }); } @@ -96,22 +97,33 @@ export class SqlEditorNavigatorService { let tab: ITab | null = null; if (data.type === SQLEditorNavigationAction.create) { - const tabOptions = this.sqlEditorTabService.createNewEditor( - data.name, - data.connectionId - ); + if (data.source === SQL_EDITOR_SOURCE_ACTION) { + tab = this.navigationTabsService.findTab(isSQLEditorTab(tab => ( + tab.handlerState.source === SQL_EDITOR_SOURCE_ACTION + && tab.handlerState.executionContext?.connectionId === data.connectionId + ))); + } + + if (!tab) { + const tabOptions = this.sqlEditorTabService.createNewEditor( + data.name, + data.source + ); - if (tabOptions) { - tab = tabInfo.openNewTab(tabOptions); - } + if (tabOptions) { + tab = tabInfo.openNewTab(tabOptions); + } - if (tab && data.connectionId) { - await this.sqlEditorTabService.setConnectionId(tab, data.connectionId, data.catalogId, data.schemaId); + if (tab && data.connectionId) { + await this.sqlEditorTabService.setConnectionId(tab, data.connectionId, data.catalogId, data.schemaId); + } + return; } - return; } - tab = this.navigationTabsService.findTab(isSQLEditorTab(tab => tab.id === data.editorId)); + if (!tab && 'editorId' in data) { + tab = this.navigationTabsService.findTab(isSQLEditorTab(tab => tab.id === data.editorId)); + } if (!tab) { return; diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts index ddbade01a6..0f8aa6cff4 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts @@ -91,14 +91,14 @@ export class SqlEditorTabService extends Bootstrap { createNewEditor( name?: string, - connectionId?: string, + source?: string, ): ITabOptions | null { const order = this.getFreeEditorId(); return { handlerId: sqlEditorTabHandlerKey, - handlerState: this.sqlEditorService.getState(order, name, connectionId), + handlerState: this.sqlEditorService.getState(order, name, source), }; } @@ -154,7 +154,7 @@ export class SqlEditorTabService extends Bootstrap { || !['string', 'undefined', 'object'].includes(typeof tab.handlerState.executionContext?.defaultSchema) || !['string', 'undefined', 'object'].includes(typeof tab.handlerState.currentTabId) || !['string', 'undefined', 'object'].includes(typeof tab.handlerState.name) - || !['string', 'undefined', 'object'].includes(typeof tab.handlerState.connectionId) + || !['string', 'undefined', 'object'].includes(typeof tab.handlerState.source) || !Array.isArray(tab.handlerState.tabs) || !Array.isArray(tab.handlerState.executionPlanTabs) || !Array.isArray(tab.handlerState.resultGroups) diff --git a/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts b/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts index c55404c8a4..f9c69733c0 100644 --- a/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts +++ b/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts @@ -45,9 +45,9 @@ export interface IExecutionPlanTab { export interface ISqlEditorTabState { name?: string; + source?: string; order: number; query: string; - connectionId?: string; executionContext?: IConnectionExecutionContextInfo; currentTabId?: string; tabs: ISqlEditorResultTab[]; diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditor.tsx b/webapp/packages/plugin-sql-editor/src/SqlEditor.tsx index 465df7195c..9f2ee7f0fa 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditor.tsx +++ b/webapp/packages/plugin-sql-editor/src/SqlEditor.tsx @@ -7,10 +7,11 @@ */ import { observer } from 'mobx-react-lite'; +import { useEffect } from 'react'; import styled, { css } from 'reshadow'; import { splitStyles, Split, ResizerControls, Pane, splitHorizontalStyles, Overlay, OverlayMessage, OverlayActions, Button, useMapResource, getComputed } from '@cloudbeaver/core-blocks'; -import { ConnectionExecutionContextResource } from '@cloudbeaver/core-connections'; +import { ConnectionExecutionContextResource, ConnectionInfoResource } from '@cloudbeaver/core-connections'; import { useService } from '@cloudbeaver/core-di'; import { useTranslate } from '@cloudbeaver/core-localization'; import { useStyles } from '@cloudbeaver/core-theming'; @@ -38,8 +39,17 @@ export const SqlEditor = observer(function SqlEditor({ state }) { const translate = useTranslate(); const sqlEditorService = useService(SqlEditorService); const styles = useStyles(splitStyles, splitHorizontalStyles, viewerStyles); - const context = useMapResource(SqlEditor, ConnectionExecutionContextResource, state.executionContext?.id ?? null); + const connection = useMapResource(SqlEditor, ConnectionInfoResource, state.executionContext?.connectionId ?? null); + const connected = getComputed(() => connection.data?.connected ?? false); + + const context = useMapResource( + SqlEditor, + ConnectionExecutionContextResource, + connected ? (state.executionContext?.id ?? null) : null + ); + + const initializingContext = getComputed(() => connection.isLoading() || context.isLoading()); const initExecutionContext = getComputed(() => context.data === undefined && state.executionContext !== undefined); async function cancelConnection() { @@ -50,6 +60,13 @@ export const SqlEditor = observer(function SqlEditor({ state }) { await sqlEditorService.initEditorConnection(state); } + useEffect(() => { + if (initExecutionContext && connected) { + init(); + } + + }, [connected, initExecutionContext]); + return styled(styles)( <> @@ -75,6 +92,7 @@ export const SqlEditor = observer(function SqlEditor({ state }) {