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>
This commit is contained in:
Tatiana Fokina
2023-03-28 13:56:31 +03:00
committed by GitHub
co-authored by dariamarutkina
parent 0430a3df1d
commit bb4d65d341
6 changed files with 79 additions and 154 deletions
@@ -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 <Loader />;
}
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)(
<wrapper>
@@ -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
/>
<MenuBar menu={menu} style={MENU_BAR_DEFAULT_STYLES} />
@@ -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<string, string> {
constructor(
private readonly graphQLService: GraphQLService,
private readonly navNodeInfoResource: NavNodeInfoResource,
) {
super();
this.navNodeInfoResource.outdateResource(this);
this.navNodeInfoResource.deleteInResource(this);
}
protected async loader(key: ResourceKey<string>): Promise<Map<string, string>> {
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';
}
}
@@ -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<void> {
await this.showMetadata(this.nodeId);
}
destruct(): void {
this.ddlViewerService.resetMetadata(this.nodeId);
}
private async showMetadata(nodeId: string): Promise<void> {
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<void> {
const connection = this.connectionInfoResource.getConnectionForNode(nodeId);
if (connection) {
this.dialect = await this.sqlDialectInfoService.loadSqlDialectInfo(createConnectionParam(connection));
}
}
}
@@ -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<string, Promise<string>>();
constructor(private readonly graphQLService: GraphQLService) {
makeObservable<DdlViewerService, 'ddlMetadata'>(this, {
ddlMetadata: observable,
});
}
getMetadata(nodeId: string) {
return this.ddlMetadata.get(nodeId);
}
async loadDdlMetadata(nodeId: string): Promise<string> {
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<string> {
const response = await this.graphQLService.sdk.metadataGetNodeDDL({ nodeId });
return response.metadataGetNodeDDL || '';
}
}
@@ -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)(
<Loader state={[extendedDDLResource, connectionDialectResource]}>
<wrapper>
<SQLCodeEditorLoader
bindings={{
autoCursor: false,
}}
value={extendedDDLResource.data}
dialect={connectionDialectResource.data}
readonly
/>
<MenuBar menu={menu} style={MENU_BAR_DEFAULT_STYLES} />
</wrapper>
</Loader>
<wrapper>
<SQLCodeEditorLoader
bindings={{
autoCursor: false,
}}
value={extendedDDLResource.data}
dialect={connectionDialectResource.data}
readonly
/>
<MenuBar menu={menu} style={MENU_BAR_DEFAULT_STYLES} />
</wrapper>
);
});
@@ -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,
],
};