From bb4d65d3412c8f345a23b459c81808dfbb955029 Mon Sep 17 00:00:00 2001 From: Tatiana Fokina <123386439+tfokina@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:56:31 +0400 Subject: [PATCH] CB-3073 add ddl resource, remove ddl controller (#1563) * CB-3073 add ddl resource, remove ddl controller * CB-3073 Remove loader, load active project connections --------- Co-authored-by: dariamarutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../src/DdlViewer/DDLViewerTabPanel.tsx | 27 +++---- .../src/DdlViewer/DdlResource.ts | 47 +++++++++++++ .../src/DdlViewer/DdlViewerController.ts | 70 ------------------- .../src/DdlViewer/DdlViewerService.ts | 46 ------------ .../ExtendedDDLViewerTabPanel.tsx | 39 +++++------ .../plugin-ddl-viewer/src/manifest.ts | 4 +- 6 files changed, 79 insertions(+), 154 deletions(-) create mode 100644 webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlResource.ts delete mode 100644 webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts delete mode 100644 webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerService.ts diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx index ce6eb9011d..65950b53c4 100644 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx @@ -7,11 +7,10 @@ */ import { observer } from 'mobx-react-lite'; -import { useEffect } from 'react'; import styled from 'reshadow'; -import { Loader, useStyles } from '@cloudbeaver/core-blocks'; -import { useController } from '@cloudbeaver/core-di'; +import { useResource, useStyles } from '@cloudbeaver/core-blocks'; +import { ConnectionDialectResource, ConnectionInfoActiveProjectKey, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { MenuBar, MENU_BAR_DEFAULT_STYLES } from '@cloudbeaver/core-ui'; import { useMenu } from '@cloudbeaver/core-view'; import type { NavNodeTransformViewComponent } from '@cloudbeaver/plugin-navigation-tree'; @@ -20,26 +19,22 @@ import { SQLCodeEditorLoader } from '@cloudbeaver/plugin-sql-editor'; import { TAB_PANEL_STYLES } from '../TAB_PANEL_STYLES'; import { DATA_CONTEXT_DDL_VIEWER_NODE } from './DATA_CONTEXT_DDL_VIEWER_NODE'; import { DATA_CONTEXT_DDL_VIEWER_VALUE } from './DATA_CONTEXT_DDL_VIEWER_VALUE'; -import { DdlViewerController } from './DdlViewerController'; +import { DdlResource } from './DdlResource'; import { MENU_DDL_VIEWER_FOOTER } from './MENU_DDL_VIEWER_FOOTER'; export const DDLViewerTabPanel: NavNodeTransformViewComponent = observer(function DDLViewerTabPanel({ nodeId, folderId }) { const style = useStyles(TAB_PANEL_STYLES); - const controller = useController(DdlViewerController, nodeId); const menu = useMenu({ menu: MENU_DDL_VIEWER_FOOTER }); - useEffect(() => { - controller.load(); - }); - // TODO: not triggered in switch case with lazy - // useTab(folderId, () => controller.load()); + const ddlResource = useResource(DDLViewerTabPanel, DdlResource, nodeId); - if (controller.isLoading) { - return ; - } + const connectionInfoResource = useResource(DDLViewerTabPanel, ConnectionInfoResource, ConnectionInfoActiveProjectKey); + const connection = connectionInfoResource.resource.getConnectionForNode(nodeId); + const connectionParam = connection ? createConnectionParam(connection) : null; + const connectionDialectResource = useResource(DDLViewerTabPanel, ConnectionDialectResource, connectionParam); menu.context.set(DATA_CONTEXT_DDL_VIEWER_NODE, nodeId); - menu.context.set(DATA_CONTEXT_DDL_VIEWER_VALUE, controller.metadata); + menu.context.set(DATA_CONTEXT_DDL_VIEWER_VALUE, ddlResource.data); return styled(style)( @@ -47,8 +42,8 @@ export const DDLViewerTabPanel: NavNodeTransformViewComponent = observer(functio bindings={{ autoCursor: false, }} - value={controller.metadata} - dialect={controller.dialect} + value={ddlResource.data} + dialect={connectionDialectResource.data} readonly /> diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlResource.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlResource.ts new file mode 100644 index 0000000000..d9f5a08ff9 --- /dev/null +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlResource.ts @@ -0,0 +1,47 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 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 { injectable } from '@cloudbeaver/core-di'; +import { NavNodeInfoResource } from '@cloudbeaver/core-navigation-tree'; +import { CachedMapResource, ResourceKey, ResourceKeyUtils, isResourceAlias, GraphQLService } from '@cloudbeaver/core-sdk'; + +@injectable() +export class DdlResource extends CachedMapResource { + constructor( + private readonly graphQLService: GraphQLService, + private readonly navNodeInfoResource: NavNodeInfoResource, + ) { + super(); + + this.navNodeInfoResource.outdateResource(this); + this.navNodeInfoResource.deleteInResource(this); + } + + protected async loader(key: ResourceKey): Promise> { + if (isResourceAlias(key)) { + throw new Error('Aliases not supported by this resource.'); + } + + const values: string[] = []; + + await ResourceKeyUtils.forEachAsync(key, async nodeId => { + const { metadataGetNodeDDL } = await this.graphQLService.sdk.metadataGetNodeDDL({ nodeId }); + if (metadataGetNodeDDL) { + values.push(metadataGetNodeDDL); + } + }); + + this.set(ResourceKeyUtils.toList(key), values); + + return this.data; + } + + protected validateKey(key: string): boolean { + return typeof key === 'string'; + } +} diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts deleted file mode 100644 index 9b827fdfd4..0000000000 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ - -import { observable, makeObservable } from 'mobx'; - -import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; -import { IDestructibleController, IInitializableController, injectable } from '@cloudbeaver/core-di'; -import { NotificationService } from '@cloudbeaver/core-events'; -import type { SqlDialectInfo } from '@cloudbeaver/core-sdk'; -import { SqlDialectInfoService } from '@cloudbeaver/plugin-sql-editor'; - -import { DdlViewerService } from './DdlViewerService'; - -@injectable() -export class DdlViewerController implements IInitializableController, IDestructibleController { - isLoading = true; - metadata = ''; - dialect?: SqlDialectInfo; - - private nodeId!: string; - - constructor( - private readonly ddlViewerService: DdlViewerService, - private readonly connectionInfoResource: ConnectionInfoResource, - private readonly sqlDialectInfoService: SqlDialectInfoService, - private readonly notificationService: NotificationService - ) { - makeObservable(this, { - isLoading: observable, - metadata: observable, - dialect: observable, - }); - } - - init(nodeId: string): void { - this.nodeId = nodeId; - } - - async load(): Promise { - await this.showMetadata(this.nodeId); - } - - destruct(): void { - this.ddlViewerService.resetMetadata(this.nodeId); - } - - private async showMetadata(nodeId: string): Promise { - try { - this.metadata = await this.ddlViewerService.loadDdlMetadata(nodeId)!; - await this.loadDialect(nodeId); - } catch (error: any) { - this.notificationService.logException(error, 'Failed to load DDL'); - } finally { - this.isLoading = false; - } - } - - private async loadDialect(nodeId: string): Promise { - const connection = this.connectionInfoResource.getConnectionForNode(nodeId); - - if (connection) { - this.dialect = await this.sqlDialectInfoService.loadSqlDialectInfo(createConnectionParam(connection)); - } - } -} diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerService.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerService.ts deleted file mode 100644 index 43375952da..0000000000 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerService.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -import { observable, makeObservable } from 'mobx'; - -import { injectable } from '@cloudbeaver/core-di'; -import { GraphQLService } from '@cloudbeaver/core-sdk'; - -@injectable() -export class DdlViewerService { - private ddlMetadata = new Map>(); - - constructor(private readonly graphQLService: GraphQLService) { - makeObservable(this, { - ddlMetadata: observable, - }); - } - - getMetadata(nodeId: string) { - return this.ddlMetadata.get(nodeId); - } - - async loadDdlMetadata(nodeId: string): Promise { - const cached = this.ddlMetadata.get(nodeId); - if (cached) { - return cached; - } - const metadata = this.fetchDdlMetadata(nodeId); - this.ddlMetadata.set(nodeId, metadata); - return metadata; - } - - resetMetadata(nodeId: string): void { - this.ddlMetadata.delete(nodeId); - } - - private async fetchDdlMetadata(nodeId: string): Promise { - const response = await this.graphQLService.sdk.metadataGetNodeDDL({ nodeId }); - return response.metadataGetNodeDDL || ''; - } -} diff --git a/webapp/packages/plugin-ddl-viewer/src/ExtendedDDLViewer/ExtendedDDLViewerTabPanel.tsx b/webapp/packages/plugin-ddl-viewer/src/ExtendedDDLViewer/ExtendedDDLViewerTabPanel.tsx index 574bb9d116..a9e8247c7b 100644 --- a/webapp/packages/plugin-ddl-viewer/src/ExtendedDDLViewer/ExtendedDDLViewerTabPanel.tsx +++ b/webapp/packages/plugin-ddl-viewer/src/ExtendedDDLViewer/ExtendedDDLViewerTabPanel.tsx @@ -9,9 +9,8 @@ import { observer } from 'mobx-react-lite'; import styled from 'reshadow'; -import { Loader, useResource, useStyles } from '@cloudbeaver/core-blocks'; -import { ConnectionDialectResource, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; -import { useService } from '@cloudbeaver/core-di'; +import { useResource, useStyles } from '@cloudbeaver/core-blocks'; +import { ConnectionDialectResource, ConnectionInfoActiveProjectKey, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { MenuBar, MENU_BAR_DEFAULT_STYLES } from '@cloudbeaver/core-ui'; import { useMenu } from '@cloudbeaver/core-view'; import type { NavNodeTransformViewComponent } from '@cloudbeaver/plugin-navigation-tree'; @@ -29,31 +28,31 @@ export const ExtendedDDLViewerTabPanel: NavNodeTransformViewComponent = observer const style = useStyles(TAB_PANEL_STYLES); const menu = useMenu({ menu: MENU_DDL_VIEWER_FOOTER }); - const connectionInfoResource = useService(ConnectionInfoResource); - const extendedDDLResource = useResource(ExtendedDDLViewerTabPanel, ExtendedDDLResource, nodeId); - const connection = connectionInfoResource.getConnectionForNode(nodeId); + const connectionInfoResource = useResource( + ExtendedDDLViewerTabPanel, + ConnectionInfoResource, + ConnectionInfoActiveProjectKey + ); + const connection = connectionInfoResource.resource.getConnectionForNode(nodeId); const connectionParam = connection ? createConnectionParam(connection) : null; - const connectionDialectResource = useResource(ExtendedDDLViewerTabPanel, ConnectionDialectResource, connectionParam); menu.context.set(DATA_CONTEXT_DDL_VIEWER_NODE, nodeId); menu.context.set(DATA_CONTEXT_DDL_VIEWER_VALUE, extendedDDLResource.data); return styled(style)( - - - - - - + + + + ); }); diff --git a/webapp/packages/plugin-ddl-viewer/src/manifest.ts b/webapp/packages/plugin-ddl-viewer/src/manifest.ts index c365a42356..11f3f473d1 100644 --- a/webapp/packages/plugin-ddl-viewer/src/manifest.ts +++ b/webapp/packages/plugin-ddl-viewer/src/manifest.ts @@ -8,8 +8,8 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; +import { DdlResource } from './DdlViewer/DdlResource'; import { DDLViewerFooterService } from './DdlViewer/DDLViewerFooterService'; -import { DdlViewerService } from './DdlViewer/DdlViewerService'; import { DdlViewerBootstrap } from './DdlViewerBootstrap'; import { ExtendedDDLResource } from './ExtendedDDLViewer/ExtendedDDLResource'; @@ -20,8 +20,8 @@ export const manifest: PluginManifest = { providers: [ DdlViewerBootstrap, - DdlViewerService, DDLViewerFooterService, ExtendedDDLResource, + DdlResource, ], };