diff --git a/webapp/packages/core-connections/src/ConnectionInfoResource.ts b/webapp/packages/core-connections/src/ConnectionInfoResource.ts index befdb6ef5e..5b0f5e920f 100644 --- a/webapp/packages/core-connections/src/ConnectionInfoResource.ts +++ b/webapp/packages/core-connections/src/ConnectionInfoResource.ts @@ -81,7 +81,7 @@ export const DEFAULT_NAVIGATOR_VIEW_SETTINGS: NavigatorSettingsInput = { @injectable() export class ConnectionInfoResource extends CachedMapResource { readonly onConnectionCreate: ISyncExecutor; - readonly onConnectionClose: ISyncExecutor; + readonly onConnectionClose: ISyncExecutor; private sessionUpdate: boolean; private readonly nodeIdMap: Map; @@ -445,7 +445,7 @@ export class ConnectionInfoResource extends CachedMapResource>(function ConnectionShield({ connectionKey, children }) { + const translate = useTranslate(); + const connectionsManagerService = useService(ConnectionsManagerService); + const notificationService = useService(NotificationService); + + const connection = useResource(ConnectionShield, ConnectionInfoResource, connectionKey); + + const [connecting, setConnecting] = useState(false); + + async function handleConnect() { + if (connecting || !connection.data || !connectionKey) { + return; + } + + setConnecting(true); + + try { + await connectionsManagerService.requireConnection(connectionKey); + } catch (exception: any) { + notificationService.logException(exception); + } finally { + setConnecting(false); + } + } + + if (connection.data && !connection.data.connected) { + if (connecting || connection.isLoading()) { + return ; + } + + return ( + + + + ); + } + + return children; +}); diff --git a/webapp/packages/plugin-connections/src/ConnectionShieldLazy.ts b/webapp/packages/plugin-connections/src/ConnectionShieldLazy.ts new file mode 100644 index 0000000000..7ee2d65b0d --- /dev/null +++ b/webapp/packages/plugin-connections/src/ConnectionShieldLazy.ts @@ -0,0 +1,10 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 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 { importLazyComponent } from '@cloudbeaver/core-blocks'; + +export const ConnectionShieldLazy = importLazyComponent(() => import('./ConnectionShield').then(m => m.ConnectionShield)); diff --git a/webapp/packages/plugin-connections/src/index.ts b/webapp/packages/plugin-connections/src/index.ts index 9d5de586c7..c725ec1cca 100644 --- a/webapp/packages/plugin-connections/src/index.ts +++ b/webapp/packages/plugin-connections/src/index.ts @@ -22,5 +22,6 @@ export * from './ContextMenu/MENU_CONNECTIONS'; export * from './PublicConnectionForm/PublicConnectionFormService'; export * from './ConnectionAuthService'; export * from './PluginConnectionsSettingsService'; +export * from './ConnectionShieldLazy'; export default connectionPlugin; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectViewerPanel/ObjectViewerPanel.tsx b/webapp/packages/plugin-object-viewer/src/ObjectViewerPanel/ObjectViewerPanel.tsx index e9d6f04bea..0edb72e9da 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectViewerPanel/ObjectViewerPanel.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectViewerPanel/ObjectViewerPanel.tsx @@ -5,28 +5,16 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -import { observable, runInAction } from 'mobx'; +import { runInAction } from 'mobx'; import { observer } from 'mobx-react-lite'; -import { useCallback } from 'react'; -import { - Button, - Loader, - s, - SContext, - StyleRegistry, - TextPlaceholder, - useObservableRef, - useResource, - useS, - useTranslate, -} from '@cloudbeaver/core-blocks'; -import { ConnectionInfoResource, ConnectionsManagerService } from '@cloudbeaver/core-connections'; +import { s, SContext, StyleRegistry, TextPlaceholder, useResource, useS, useTranslate } from '@cloudbeaver/core-blocks'; +import { ConnectionInfoResource } from '@cloudbeaver/core-connections'; import { useService } from '@cloudbeaver/core-di'; -import { NotificationService } from '@cloudbeaver/core-events'; import { NavNodeInfoResource } from '@cloudbeaver/core-navigation-tree'; import { TabPanel, TabsBox, TabStyles, useTabLocalState } from '@cloudbeaver/core-ui'; import { MetadataMap } from '@cloudbeaver/core-utils'; +import { ConnectionShieldLazy } from '@cloudbeaver/plugin-connections'; import type { TabHandlerPanelComponent } from '@cloudbeaver/plugin-navigation-tabs'; import type { IObjectViewerTabState } from '../IObjectViewerTabState'; @@ -49,27 +37,13 @@ const tabsRegistry: StyleRegistry = [ export const ObjectViewerPanel: TabHandlerPanelComponent = observer(function ObjectViewerPanel({ tab }) { const translate = useTranslate(); const dbObjectPagesService = useService(DBObjectPageService); - const connectionsManagerService = useService(ConnectionsManagerService); const navNodeInfoResource = useService(NavNodeInfoResource); - const notificationService = useService(NotificationService); const innerTabState = useTabLocalState(() => new MetadataMap()); const style = useS(styles); const objectId = tab.handlerState.objectId; const connectionKey = tab.handlerState.connectionKey || null; - const state = useObservableRef( - () => ({ - connecting: false, - notFound: false, - }), - { - connecting: observable.ref, - notFound: observable.ref, - }, - false, - ); - const connection = useResource(ObjectViewerPanel, ConnectionInfoResource, connectionKey); const node = useResource(ObjectViewerPanel, navNodeInfoResource, objectId, { @@ -79,65 +53,39 @@ export const ObjectViewerPanel: TabHandlerPanelComponent tab.handlerState.tabTitle = data.name; }); }, - active: !state.notFound && connection.data?.connected, + active: connection.data?.connected, }); const pages = dbObjectPagesService.orderedPages; - const handleConnect = useCallback(async () => { - if (state.connecting || !connection.data || !connectionKey) { - return; - } - - state.connecting = true; - - try { - await connectionsManagerService.requireConnection(connectionKey); - } catch (exception: any) { - notificationService.logException(exception); - } finally { - state.connecting = false; - } - }, [connectionKey]); - - if (connection.data && !connection.data.connected) { - if (state.connecting || connection.isLoading()) { - return ; - } - - return ( - - - - ); - } - - if (tab.handlerState.error || state.notFound) { + if (tab.handlerState.error) { return {translate('plugin_object_viewer_error')}; } - return node.data ? ( - + return ( + + {node.data ? ( + + {pages.map(page => ( + + ))} + + } + localState={innerTabState} + > {pages.map(page => ( - + + + ))} - - } - localState={innerTabState} - > - {pages.map(page => ( - - - - ))} - - ) : ( - {translate('plugin_object_viewer_table_no_items')} + + ) : ( + {translate('plugin_object_viewer_table_no_items')} + )} + ); }); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts index 17612a25a6..22de75a46f 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts @@ -89,8 +89,8 @@ export class ObjectViewerTabService { this.navNodeManagerService.onCanOpen.addHandler(this.canOpenHandler.bind(this)); this.navNodeManagerService.navigator.addHandler(this.navigationHandler.bind(this)); this.navNodeManagerService.navigator.addPostHandler(this.navigationPostHandler.bind(this)); - this.connectionInfoResource.onConnectionClose.addHandler(this.closeConnectionInfoTabs.bind(this)); this.connectionInfoResource.onItemUpdate.addHandler(this.updateConnectionTabs.bind(this)); + this.connectionInfoResource.onConnectionClose.addHandler(this.closeConnectionTabs.bind(this)); this.connectionInfoResource.onItemDelete.addHandler(this.closeConnectionTabs.bind(this)); this.navNodeManagerService.navTree.onItemDelete.addHandler(this.removeTabs.bind(this)); this.navTreeResource.onNodeRename.addHandler(this.handleNodeRename.bind(this)); @@ -254,21 +254,6 @@ export class ObjectViewerTabService { }); } - private closeConnectionInfoTabs(connection: Connection) { - if (!connection.connected) { - const tabs = Array.from( - this.navigationTabsService.findTabs( - isObjectViewerTab( - tab => - tab.handlerState.connectionKey?.projectId === connection.projectId && tab.handlerState.connectionKey.connectionId === connection.id, - ), - ), - ).map(tab => tab.id); - - this.navigationTabsService.closeTabSilent(resourceKeyList(tabs), true); - } - } - private async removeTabs(key: ResourceKey) { const tabs: string[] = [];