From d58367b9c3edf488ba02eb159d6b6033120b83dd Mon Sep 17 00:00:00 2001 From: Wroud Date: Fri, 3 Sep 2021 10:16:05 +0300 Subject: [PATCH] refactor: CB-1094 metadata editor --- .../NavigationNodeElement.tsx | 6 +- webapp/packages/core-app/src/index.ts | 4 +- .../NavigationTabsBar/NavigationTabsBar.tsx | 2 +- .../NavNodeView/IFolderTransform.ts | 25 +++++ .../NavNodeView/NavNodeViewService.ts | 48 ++++++++++ .../core-blocks/src/Tabs/TabsState.tsx | 7 +- .../packages/core-bootstrap/src/manifest.ts | 2 + .../ConnectionExecutionContextService.ts | 2 +- .../src/DdlViewer/DDLViewerTab.tsx | 26 ++++++ .../{DdlViewer.tsx => DDLViewerTabPanel.tsx} | 33 +++---- .../src/DdlViewer/DdlViewerController.ts | 14 +-- .../src/DdlViewerBootstrap.ts | 37 ++++++-- .../src/DdlViewerTabService.ts | 65 ------------- .../plugin-ddl-viewer/src/manifest.ts | 2 - .../FolderPanelRenderer.tsx | 54 +++++++++++ .../FolderTabRenderer.tsx | 55 +++++++++++ .../NavNodeMetadata/NavNodeMetadataPanel.tsx | 17 ++++ .../NavNodeMetadata/NavNodeMetadataTab.tsx | 38 ++++++++ .../NavNodeMetadataViewBootstrap.ts | 57 ++++++++++++ .../NavNodeMetadata}/ObjectProperties.tsx | 0 .../NavNodeMetadata}/ObjectProperty.tsx | 4 +- .../VirtualFolder/VirtualFolderPanel.tsx | 44 +++++++++ .../VirtualFolder/VirtualFolderTab.tsx | 31 +++++++ .../VirtualFolder/VirtualFolderUtils.ts | 23 +++++ .../VirtualFolderViewBootstrap.ts | 69 ++++++++++++++ .../ObjectPropertiesPage/ObjectFolders.tsx | 63 +++++++++---- .../ObjectFoldersController.ts | 64 ------------- .../ObjectFoldersService.ts | 91 ------------------- .../ObjectFoldersTab/ObjectFolderTabModel.ts | 34 ------- .../ObjectFoldersTabService.ts | 45 --------- .../NodePropertiesMixin.ts | 13 --- .../ObjectFoldersTabContainer.ts | 19 ---- .../ObjectInfoTab/ObjectInfoTab.tsx | 21 ----- .../ObjectInfoTab/ObjectInfoTabModel.ts | 23 ----- .../ObjectInfoTab/ObjectInfoTabService.ts | 37 -------- .../ObjectPropertiesPageService.ts | 5 - .../VirtualFolderTab/VirtualFolderTab.tsx | 38 -------- .../VirtualFolderTab/VirtualFolderTabData.tsx | 15 --- .../VirtualFolderTabMixin.tsx | 48 ---------- .../VirtualFolderTabModel.tsx | 30 ------ .../VirtualFolderTabService.tsx | 64 ------------- .../plugin-object-viewer/src/index.ts | 1 - .../plugin-object-viewer/src/locales/en.ts | 1 + .../plugin-object-viewer/src/locales/it.ts | 1 + .../plugin-object-viewer/src/locales/ru.ts | 1 + .../plugin-object-viewer/src/manifest.ts | 12 +-- 46 files changed, 603 insertions(+), 688 deletions(-) create mode 100644 webapp/packages/core-app/src/shared/NodesManager/NavNodeView/IFolderTransform.ts create mode 100644 webapp/packages/core-app/src/shared/NodesManager/NavNodeView/NavNodeViewService.ts create mode 100644 webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTab.tsx rename webapp/packages/plugin-ddl-viewer/src/DdlViewer/{DdlViewer.tsx => DDLViewerTabPanel.tsx} (60%) delete mode 100644 webapp/packages/plugin-ddl-viewer/src/DdlViewerTabService.ts create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderPanelRenderer.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderTabRenderer.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataPanel.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataTab.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataViewBootstrap.ts rename webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/{ObjectInfoTab => NavNodeView/NavNodeMetadata}/ObjectProperties.tsx (100%) rename webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/{ObjectInfoTab => NavNodeView/NavNodeMetadata}/ObjectProperty.tsx (94%) create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderPanel.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderTab.tsx create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderUtils.ts create mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderViewBootstrap.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersController.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersService.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFolderTabModel.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFoldersTabService.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/NodePropertiesMixin.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/ObjectFoldersTabContainer.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTab.tsx delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabModel.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabService.ts delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTab.tsx delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabData.tsx delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabMixin.tsx delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabModel.tsx delete mode 100644 webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabService.tsx diff --git a/webapp/packages/core-app/src/NavigationTree/NavigationTreeNode/NavigationNodeElement.tsx b/webapp/packages/core-app/src/NavigationTree/NavigationTreeNode/NavigationNodeElement.tsx index c3261aa84c..898c4a0037 100644 --- a/webapp/packages/core-app/src/NavigationTree/NavigationTreeNode/NavigationNodeElement.tsx +++ b/webapp/packages/core-app/src/NavigationTree/NavigationTreeNode/NavigationNodeElement.tsx @@ -29,11 +29,9 @@ export const NavigationNodeElement = observer(function NavigationNodeElem for (const renderer of context.tree.renderers) { const CustomRenderer = renderer(nodeId); - if (CustomRenderer === undefined) { - continue; + if (CustomRenderer) { + return ; } - - return ; } } diff --git a/webapp/packages/core-app/src/index.ts b/webapp/packages/core-app/src/index.ts index 314602273b..b8fdd5f4e3 100644 --- a/webapp/packages/core-app/src/index.ts +++ b/webapp/packages/core-app/src/index.ts @@ -7,11 +7,13 @@ export * from './TopNavBar/ConnectionSchemaManager/ConnectionSchemaManagerServic export * from './TopNavBar/TopNavBarService'; export * from './TopNavBar/AdministrationTopAppBarBootstrapService'; export * from './TopNavBar/shared/topMenuStyles'; -export * from './shared/NodesManager/ConnectionDialogsService'; export * from './shared/NodesManager/extensions/IObjectCatalogProvider'; export * from './shared/NodesManager/extensions/IObjectCatalogSetter'; export * from './shared/NodesManager/extensions/IObjectSchemaProvider'; export * from './shared/NodesManager/extensions/IObjectSchemaSetter'; +export * from './shared/NodesManager/NavNodeView/IFolderTransform'; +export * from './shared/NodesManager/NavNodeView/NavNodeViewService'; +export * from './shared/NodesManager/ConnectionDialogsService'; export * from './shared/NodesManager/DBObjectService'; export * from './shared/NodesManager/NavNodeInfoResource'; export * from './shared/NodesManager/NavNodeManagerService'; diff --git a/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsBar/NavigationTabsBar.tsx b/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsBar/NavigationTabsBar.tsx index 5271c799e0..6937ce994b 100644 --- a/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsBar/NavigationTabsBar.tsx +++ b/webapp/packages/core-app/src/shared/NavigationTabs/NavigationTabsBar/NavigationTabsBar.tsx @@ -80,7 +80,7 @@ export const NavigationTabsBar = observer(function NavigationTabsBar() { tabIndex={0} > {navigation.tabIdList.map(tabId => ( - + ))} diff --git a/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/IFolderTransform.ts b/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/IFolderTransform.ts new file mode 100644 index 0000000000..f7739d07fe --- /dev/null +++ b/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/IFolderTransform.ts @@ -0,0 +1,25 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 type { ComponentStyle } from '@cloudbeaver/core-theming'; + +export type NavNodeTransformViewComponent = React.FC<{ + nodeId: string; + folderId: string; + style?: ComponentStyle; +}>; + +export type NavNodeTransformView = (nodeId: string, folderId: string) => NavNodeTransformViewComponent | undefined; + +export type NavNodeFolderTransformFn = (nodeId: string, children: string[] | undefined) => string[] | undefined; + +export interface INavNodeFolderTransform { + tab: NavNodeTransformView; + panel: NavNodeTransformView; + transformer: NavNodeFolderTransformFn; +} diff --git a/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/NavNodeViewService.ts b/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/NavNodeViewService.ts new file mode 100644 index 0000000000..1cc79027f1 --- /dev/null +++ b/webapp/packages/core-app/src/shared/NodesManager/NavNodeView/NavNodeViewService.ts @@ -0,0 +1,48 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { NavTreeResource } from '../NavTreeResource'; +import type { NavNodeTransformView, INavNodeFolderTransform, NavNodeFolderTransformFn } from './IFolderTransform'; + +@injectable() +export class NavNodeViewService { + get tabs(): NavNodeTransformView[] { + return this.transformers.map(transform => transform.tab); + } + + get panels(): NavNodeTransformView[] { + return this.transformers.map(transform => transform.panel); + } + + get transformations(): NavNodeFolderTransformFn[] { + return this.transformers.map(transform => transform.transformer); + } + + private transformers: INavNodeFolderTransform[]; + + constructor( + private navTreeResource: NavTreeResource + ) { + this.transformers = []; + } + + getFolders(nodeId: string): string[] | undefined { + const children = this.navTreeResource.get(nodeId); + + return this.transformations.reduce( + (children, transform) => transform(nodeId, children), + children + ); + } + + addTransform(transform: INavNodeFolderTransform): void { + this.transformers.push(transform); + } +} diff --git a/webapp/packages/core-blocks/src/Tabs/TabsState.tsx b/webapp/packages/core-blocks/src/Tabs/TabsState.tsx index 607f8a5825..386e9ed8ff 100644 --- a/webapp/packages/core-blocks/src/Tabs/TabsState.tsx +++ b/webapp/packages/core-blocks/src/Tabs/TabsState.tsx @@ -107,9 +107,10 @@ export const TabsState = observer(function TabsState>({ }, []); useEffect(() => { - if (currentTabId !== undefined) { - return; - } + // prevent from initial render handlers execution + // if (currentTabId !== undefined) { + // return; + // } openExecutor.execute({ tabId: state.selectedId!, diff --git a/webapp/packages/core-bootstrap/src/manifest.ts b/webapp/packages/core-bootstrap/src/manifest.ts index 08823f5e0e..8c85ec9573 100644 --- a/webapp/packages/core-bootstrap/src/manifest.ts +++ b/webapp/packages/core-bootstrap/src/manifest.ts @@ -21,6 +21,7 @@ import { NavigationTreeService, NavNodeManagerService, DBObjectService, + NavNodeViewService, NavNodeExtensionsService, NavNodeInfoResource, NavTreeResource, @@ -193,6 +194,7 @@ export const coreManifest: PluginManifest = { NavigationTreeContextMenuService, NavigationTreeService, NavNodeManagerService, + NavNodeViewService, NavNodeExtensionsService, NavNodeInfoResource, NavTreeResource, diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts index 6dd302094b..dce3626ed5 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts @@ -8,9 +8,9 @@ import { injectable } from '@cloudbeaver/core-di'; import { TaskScheduler } from '@cloudbeaver/core-executor'; +import { ResourceKeyUtils } from '@cloudbeaver/core-sdk'; import { MetadataMap } from '@cloudbeaver/core-utils'; -import { ResourceKeyUtils } from '../../../core-sdk/src'; import { ConnectionExecutionContext } from './ConnectionExecutionContext'; import { ConnectionExecutionContextResource } from './ConnectionExecutionContextResource'; diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTab.tsx b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTab.tsx new file mode 100644 index 0000000000..9972d28b97 --- /dev/null +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTab.tsx @@ -0,0 +1,26 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; +import styled from 'reshadow'; + +import type { NavNodeTransformViewComponent } from '@cloudbeaver/core-app'; +import { Tab, TabIcon, TabTitle } from '@cloudbeaver/core-blocks'; +import { useStyles } from '@cloudbeaver/core-theming'; + +export const DDLViewerTab: NavNodeTransformViewComponent = observer(function DDLViewerTab({ + folderId, + style, +}) { + return styled(useStyles(style))( + + + DDL + + ); +}); diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewer.tsx b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx similarity index 60% rename from webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewer.tsx rename to webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx index 4b77c9ebd7..4e275b07e8 100644 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewer.tsx +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DDLViewerTabPanel.tsx @@ -9,7 +9,8 @@ import { observer } from 'mobx-react-lite'; import styled, { css } from 'reshadow'; -import { Loader } from '@cloudbeaver/core-blocks'; +import type { NavNodeTransformViewComponent } from '@cloudbeaver/core-app'; +import { Loader, useTab } from '@cloudbeaver/core-blocks'; import { useController } from '@cloudbeaver/core-di'; import { SQLCodeEditorLoader } from '@cloudbeaver/plugin-sql-editor'; @@ -18,22 +19,20 @@ import { DdlViewerController } from './DdlViewerController'; const styles = css` wrapper { flex: 1; + display: flex; overflow: auto; composes: theme-typography--body1 from global; } SQLCodeEditorLoader { height: 100%; + flex: 1; + overflow: auto; } `; -export interface DdlViewerTabPanelProps { - nodeId: string; -} - -export const ddlViewer = (nodeId: string) => (); - -const DdlViewerTabPanel = observer(function DdlViewerTabPanel({ nodeId }) { +export const DDLViewerTabPanel: NavNodeTransformViewComponent = observer(function DDLViewerTabPanel({ nodeId, folderId }) { const controller = useController(DdlViewerController, nodeId); + useTab(folderId, () => controller.load()); if (controller.isLoading) { return ; @@ -41,16 +40,14 @@ const DdlViewerTabPanel = observer(function DdlViewerTab return styled(styles)( - {controller.metadata && ( - - )} + ); }); diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts index dd85e061cb..f4e759cde5 100644 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewer/DdlViewerController.ts @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ -import { observable, when, makeObservable } from 'mobx'; +import { observable, makeObservable } from 'mobx'; import { NodeManagerUtils, NavNodeManagerService } from '@cloudbeaver/core-app'; import { IDestructibleController, IInitializableController, injectable } from '@cloudbeaver/core-di'; @@ -37,12 +37,12 @@ export class DdlViewerController implements IInitializableController, IDestructi }); } - init(nodeId: string) { + init(nodeId: string): void { this.nodeId = nodeId; - when( - () => !!this.ddlViewerService.getMetadata(nodeId), - () => this.showMetadata(nodeId) - ); + } + + async load(): Promise { + await this.showMetadata(this.nodeId); } destruct(): void { @@ -51,7 +51,7 @@ export class DdlViewerController implements IInitializableController, IDestructi private async showMetadata(nodeId: string): Promise { try { - this.metadata = await this.ddlViewerService.getMetadata(nodeId)!; + this.metadata = await this.ddlViewerService.loadDdlMetadata(nodeId)!; await this.loadDialect(nodeId); } catch (error) { this.notificationService.logException(error, 'Failed to load DDL'); diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts index df357133db..bef3aba636 100644 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts +++ b/webapp/packages/plugin-ddl-viewer/src/DdlViewerBootstrap.ts @@ -6,26 +6,47 @@ * you may not use this file except in compliance with the License. */ +import { EObjectFeature, NavNodeInfoResource, NavNodeViewService } from '@cloudbeaver/core-app'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; -import { ITabBuilder, ObjectFoldersService } from '@cloudbeaver/plugin-object-viewer'; -import { DdlViewerTabService } from './DdlViewerTabService'; +import { DDLViewerTab } from './DdlViewer/DDLViewerTab'; +import { DDLViewerTabPanel } from './DdlViewer/DDLViewerTabPanel'; + +const navNodeDDLId = 'object-viewer://ddl'; @injectable() export class DdlViewerBootstrap extends Bootstrap { constructor( - private objectFoldersService: ObjectFoldersService, - private ddlViewerTabService: DdlViewerTabService + private readonly navNodeViewService: NavNodeViewService, + private readonly navNodeInfoResource: NavNodeInfoResource ) { super(); } register(): void { - const tabBuilder: ITabBuilder = { - build: nodeId => this.ddlViewerTabService.buildTab(nodeId), - }; + this.navNodeViewService.addTransform({ + tab: (nodeId, folderId) => { + if (folderId.startsWith(navNodeDDLId)) { + return DDLViewerTab; + } + return undefined; + }, + panel: (nodeId, folderId) => { + if (folderId.startsWith(navNodeDDLId)) { + return DDLViewerTabPanel; + } + return undefined; + }, + transformer: (nodeId, children) => { + const node = this.navNodeInfoResource.get(nodeId); - this.objectFoldersService.registerTabConstructor(tabBuilder); + if (!node?.objectFeatures?.includes(EObjectFeature.script)) { + return children; + } + + return [...children || [], navNodeDDLId]; + }, + }); } load(): void {} diff --git a/webapp/packages/plugin-ddl-viewer/src/DdlViewerTabService.ts b/webapp/packages/plugin-ddl-viewer/src/DdlViewerTabService.ts deleted file mode 100644 index 38e9025931..0000000000 --- a/webapp/packages/plugin-ddl-viewer/src/DdlViewerTabService.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { - EObjectFeature, NavNodeManagerService, INodeNavigationData -} from '@cloudbeaver/core-app'; -import type { ITab } from '@cloudbeaver/core-blocks'; -import { injectable } from '@cloudbeaver/core-di'; -import { NotificationService } from '@cloudbeaver/core-events'; -import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; -import { ObjectViewerTabService } from '@cloudbeaver/plugin-object-viewer'; - -import { ddlViewer } from './DdlViewer/DdlViewer'; -import { DdlViewerService } from './DdlViewerService'; - -const ddlViewerTabId = 'ddl-viewer'; - -@injectable() -export class DdlViewerTabService { - constructor( - private navNodeManagerService: NavNodeManagerService, - private objectViewerTabService: ObjectViewerTabService, - private notificationService: NotificationService, - private ddlViewerService: DdlViewerService - ) { - this.navNodeManagerService.navigator.addHandler(this.navigationHandler.bind(this)); - } - - buildTab(nodeId: string): ITab | null { - const node = this.navNodeManagerService.getNode(nodeId); - const isDdlRequired = node?.objectFeatures.includes(EObjectFeature.script); - if (!isDdlRequired) { - return null; - } - const ddlTab: ITab = { - tabId: ddlViewerTabId, - title: 'DDL', - icon: '/icons/DDL.svg', - onActivate: () => this.activateDDLTab(nodeId, node?.parentId as string), - panel: () => ddlViewer(nodeId), - }; - return ddlTab; - } - - private async navigationHandler(data: INodeNavigationData, contexts: IExecutionContextProvider) { - try { - const tabContext = await contexts.getContext(this.objectViewerTabService.objectViewerTabContext); - - if (tabContext.nodeInfo.folderId === ddlViewerTabId) { - this.ddlViewerService.loadDdlMetadata(tabContext.nodeInfo.nodeId); - } - } catch (exception) { - this.notificationService.logException(exception, 'Object Viewer Error', 'Error in Object Viewer while processing action with ddl-viewer'); - } - } - - private activateDDLTab(nodeId: string, parentId: string) { - this.navNodeManagerService.navToNode(nodeId, parentId, ddlViewerTabId); - } -} diff --git a/webapp/packages/plugin-ddl-viewer/src/manifest.ts b/webapp/packages/plugin-ddl-viewer/src/manifest.ts index 8c024f01e5..3335f6369c 100644 --- a/webapp/packages/plugin-ddl-viewer/src/manifest.ts +++ b/webapp/packages/plugin-ddl-viewer/src/manifest.ts @@ -10,7 +10,6 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; import { DdlViewerBootstrap } from './DdlViewerBootstrap'; import { DdlViewerService } from './DdlViewerService'; -import { DdlViewerTabService } from './DdlViewerTabService'; export const manifest: PluginManifest = { info: { @@ -19,7 +18,6 @@ export const manifest: PluginManifest = { providers: [ DdlViewerBootstrap, - DdlViewerTabService, DdlViewerService, ], }; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderPanelRenderer.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderPanelRenderer.tsx new file mode 100644 index 0000000000..e8d5d33f31 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderPanelRenderer.tsx @@ -0,0 +1,54 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; + +import { NavNodeViewService, useNode } from '@cloudbeaver/core-app'; +import { useService } from '@cloudbeaver/core-di'; +import type { ComponentStyle } from '@cloudbeaver/core-theming'; + +import { ObjectPropertyTable } from './ObjectPropertyTable/ObjectPropertyTable'; + +interface IFolderPanelRendererProps { + nodeId: string; + folderId: string; + style?: ComponentStyle; +} + +export const FolderPanelRenderer = observer(function FolderPanelRenderer({ + nodeId, + folderId, + style, +}) { + const navNodeViewService = useService(NavNodeViewService); + + for (const panel of navNodeViewService.panels) { + const Panel = panel(nodeId, folderId); + + if (Panel) { + return ; + } + } + + return ; +}); + +interface INavNodePanelProps { + nodeId: string; + style?: ComponentStyle; +} + +const NavNodePanel = observer(function NavNodeTab({ nodeId }) { + const nodeInfo = useNode(nodeId); + + if (!nodeInfo.node) { + return null; + } + + return ; +}); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderTabRenderer.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderTabRenderer.tsx new file mode 100644 index 0000000000..84d7cd05b9 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderTabRenderer.tsx @@ -0,0 +1,55 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; +import styled from 'reshadow'; + +import { NavNodeViewService, useNode } from '@cloudbeaver/core-app'; +import { Tab, TabIcon, TabTitle } from '@cloudbeaver/core-blocks'; +import { useService } from '@cloudbeaver/core-di'; +import { ComponentStyle, useStyles } from '@cloudbeaver/core-theming'; + +interface IFolderTabRendererProps { + nodeId: string; + folderId: string; + style?: ComponentStyle; +} + +export const FolderTabRenderer = observer(function FolderTabRenderer({ + nodeId, + folderId, + style, +}) { + const navNodeViewService = useService(NavNodeViewService); + + for (const tab of navNodeViewService.tabs) { + const Tab = tab(nodeId, folderId); + + if (Tab) { + return ; + } + } + + return ; +}); + +interface INavNodeTabProps { + nodeId: string; + style?: ComponentStyle; +} + +const NavNodeTab = observer(function NavNodeTab({ nodeId, style }) { + const nodeInfo = useNode(nodeId); + + return styled(useStyles(style))( + + {nodeInfo.node?.icon && } + {nodeInfo.node?.name} + + ); +}); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataPanel.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataPanel.tsx new file mode 100644 index 0000000000..05519ea6d1 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataPanel.tsx @@ -0,0 +1,17 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 type { NavNodeTransformViewComponent } from '@cloudbeaver/core-app'; + +import { ObjectProperties } from './ObjectProperties'; + +export const NavNodeMetadataPanel: NavNodeTransformViewComponent = function NavNodeMetadataPanel({ + nodeId, +}) { + return ; +}; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataTab.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataTab.tsx new file mode 100644 index 0000000000..1a22f4caa2 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataTab.tsx @@ -0,0 +1,38 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; +import styled from 'reshadow'; + +import { NavNodeTransformViewComponent, useNode } from '@cloudbeaver/core-app'; +import { Tab, TabIcon, TabTitle } from '@cloudbeaver/core-blocks'; +import { useTranslate } from '@cloudbeaver/core-localization'; +import { useStyles } from '@cloudbeaver/core-theming'; + +export const NavNodeMetadataTab: NavNodeTransformViewComponent = observer(function NavNodeMetadataTab({ + folderId, + nodeId, + style, +}) { + const translate = useTranslate(); + const styles = useStyles(style); + const nodeInfo = useNode(nodeId); + + if (!nodeInfo.node) { + return null; + } + + const icon = 'platform:/plugin/org.jkiss.dbeaver.model/icons/tree/info.png'; + + return styled(styles)( + + + {translate('plugin_object_viewer_object_info_tab')} + + ); +}); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataViewBootstrap.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataViewBootstrap.ts new file mode 100644 index 0000000000..23068f1ae7 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataViewBootstrap.ts @@ -0,0 +1,57 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { ENodeFeature, NavNodeInfoResource, NavNodeViewService } from '@cloudbeaver/core-app'; +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; + +import { NavNodeMetadataPanel } from './NavNodeMetadataPanel'; +import { NavNodeMetadataTab } from './NavNodeMetadataTab'; + +const navNodeMetadataId = 'object-viewer://metadata'; + +@injectable() +export class NavNodeMetadataViewBootstrap extends Bootstrap { + constructor( + private readonly navNodeViewService: NavNodeViewService, + private readonly navNodeInfoResource: NavNodeInfoResource + ) { + super(); + } + + register(): void { + this.navNodeViewService.addTransform({ + tab: (nodeId, folderId) => { + if (folderId.startsWith(navNodeMetadataId)) { + return NavNodeMetadataTab; + } + return undefined; + }, + panel: (nodeId, folderId) => { + if (folderId.startsWith(navNodeMetadataId)) { + return NavNodeMetadataPanel; + } + return undefined; + }, + transformer: (nodeId, children) => { + const node = this.navNodeInfoResource.get(nodeId); + const isDatabaseObject = ( + node?.features?.includes(ENodeFeature.item) + || node?.features?.includes(ENodeFeature.container) + ); + + if (!isDatabaseObject) { + return children; + } + + return [navNodeMetadataId, ...children || []]; + }, + }); + } + + load(): void { } +} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectProperties.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/ObjectProperties.tsx similarity index 100% rename from webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectProperties.tsx rename to webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/ObjectProperties.tsx diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectProperty.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/ObjectProperty.tsx similarity index 94% rename from webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectProperty.tsx rename to webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/ObjectProperty.tsx index f1c455e991..da52e80ad6 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectProperty.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/NavNodeMetadata/ObjectProperty.tsx @@ -10,8 +10,8 @@ import { observer } from 'mobx-react-lite'; import { FieldCheckboxNew, InputFieldNew } from '@cloudbeaver/core-blocks'; -import type { ObjectPropertyProps } from '../formControls'; -import { additionalProps, filterProperty, getValue, matchType } from '../helpers'; +import type { ObjectPropertyProps } from '../../formControls'; +import { additionalProps, filterProperty, getValue, matchType } from '../../helpers'; export const ObjectProperty = observer(function ObjectProperty({ objectProperty, diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderPanel.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderPanel.tsx new file mode 100644 index 0000000000..7d16bdfd3d --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderPanel.tsx @@ -0,0 +1,44 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 styled, { css } from 'reshadow'; + +import { NavNodeInfoResource, NavNodeTransformViewComponent, useChildren } from '@cloudbeaver/core-app'; +import { useService } from '@cloudbeaver/core-di'; +import { resourceKeyList } from '@cloudbeaver/core-sdk'; + +import { ObjectChildrenPropertyTable } from '../../ObjectPropertyTable/ObjectChildrenPropertyTable'; +import { VirtualFolderUtils } from './VirtualFolderUtils'; + +const style = css` + tab-wrapper { + position: relative; + width: 100%; + flex: 1 0 auto; + } +`; + +export const VirtualFolderPanel: NavNodeTransformViewComponent = function VirtualFolderPanel({ + folderId, + nodeId, +}) { + const nodeType = VirtualFolderUtils.getNodeType(folderId); + const navNodeInfoResource = useService(NavNodeInfoResource); + const children = useChildren(nodeId); + + const nodeIds = navNodeInfoResource + .get(resourceKeyList(children.children || [])) + .filter(node => node?.nodeType === nodeType) + .map(node => node!.id); + + return styled(style)( + + + + ); +}; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderTab.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderTab.tsx new file mode 100644 index 0000000000..81ea9cee15 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderTab.tsx @@ -0,0 +1,31 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 styled from 'reshadow'; + +import type { NavNodeTransformViewComponent } from '@cloudbeaver/core-app'; +import { Tab, TabIcon, TabTitle } from '@cloudbeaver/core-blocks'; +import { useStyles } from '@cloudbeaver/core-theming'; + +import { VirtualFolderUtils } from './VirtualFolderUtils'; + +export const VirtualFolderTab: NavNodeTransformViewComponent = function VirtualFolderTab({ + folderId, + style, +}) { + const nodeType = VirtualFolderUtils.getNodeType(folderId); + const styles = useStyles(style); + const icon = 'platform:/plugin/org.jkiss.dbeaver.model/icons/tree/folder.png'; + + return styled(styles)( + + + {nodeType} + + ); +}; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderUtils.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderUtils.ts new file mode 100644 index 0000000000..3ec6140c17 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderUtils.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 VirtualFolderUtils = { + prefix: 'object-viewer://virtual-folder/', + + getFolderId(nodeType: string): string { + return this.prefix + nodeType; + }, + + getNodeType(folderId: string): string { + return folderId.replace(this.prefix, ''); + }, + + isVirtualFolder(folderId: string): boolean { + return folderId.startsWith(this.prefix); + }, +}; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderViewBootstrap.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderViewBootstrap.ts new file mode 100644 index 0000000000..97bd5ce62b --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderViewBootstrap.ts @@ -0,0 +1,69 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2021 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 { NavNodeInfoResource, NavNodeViewService } from '@cloudbeaver/core-app'; +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; + +import { VirtualFolderPanel } from './VirtualFolderPanel'; +import { VirtualFolderTab } from './VirtualFolderTab'; +import { VirtualFolderUtils } from './VirtualFolderUtils'; + +@injectable() +export class VirtualFolderViewBootstrap extends Bootstrap { + constructor( + private readonly navNodeViewService: NavNodeViewService, + private readonly navNodeInfoResource: NavNodeInfoResource + ) { + super(); + } + + register(): void { + this.navNodeViewService.addTransform({ + tab: (nodeId, folderId) => { + if (VirtualFolderUtils.isVirtualFolder(folderId)) { + return VirtualFolderTab; + } + return undefined; + }, + panel: (nodeId, folderId) => { + if (VirtualFolderUtils.isVirtualFolder(folderId)) { + return VirtualFolderPanel; + } + return undefined; + }, + transformer: (nodeId, children) => { + if (!children) { + return children; + } + + const virtualFolders: string[] = []; + const nextChildren = []; + + for (const child of children) { + const node = this.navNodeInfoResource.get(child); + + if (!node || node?.folder) { + nextChildren.push(child); + } else if (node?.nodeType) { + const virtualId = VirtualFolderUtils.getFolderId(node.nodeType); + + if (!virtualFolders.includes(virtualId)) { + virtualFolders.push(virtualId); + } + } + } + + nextChildren.push(...virtualFolders); + + return nextChildren; + }, + }); + } + + load(): void { } +} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx index a0dcc9f6ec..b12d7a4501 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFolders.tsx @@ -7,15 +7,17 @@ */ import { observer } from 'mobx-react-lite'; +import { useEffect } from 'react'; import styled, { css } from 'reshadow'; -import type { ITab } from '@cloudbeaver/core-app'; -import { Tab, TabIcon, TabList, TabPanel, TabsState, TabTitle, verticalTabStyles } from '@cloudbeaver/core-blocks'; -import { useController } from '@cloudbeaver/core-di'; +import { ITab, NavNodeManagerService, NavNodeViewService, NavTreeResource } from '@cloudbeaver/core-app'; +import { ITabData, TabList, TabPanel, TabsState, useMapResource, verticalTabStyles } from '@cloudbeaver/core-blocks'; +import { useService } from '@cloudbeaver/core-di'; import { useStyles, composes } from '@cloudbeaver/core-theming'; import type { IObjectViewerTabState } from '../IObjectViewerTabState'; -import { ObjectFoldersController } from './ObjectFoldersController'; +import { FolderPanelRenderer } from './FolderPanelRenderer'; +import { FolderTabRenderer } from './FolderTabRenderer'; const styles = composes( css` @@ -46,34 +48,55 @@ const styles = composes( ` ); +const tabStyles = [verticalTabStyles, styles]; + interface IProps { tab: ITab; } export const ObjectFolders = observer(function ObjectFolders({ tab }) { - const controller = useController(ObjectFoldersController, tab); + const navNodeManagerService = useService(NavNodeManagerService); + const navNodeViewService = useService(NavNodeViewService); - const tabContainer = controller.getTabContainer(); + const nodeId = tab.handlerState.objectId; + const parentId = tab.handlerState.parentId; + let folderId = tab.handlerState.folderId; + + useMapResource(NavTreeResource, nodeId, { + onLoad: async resource => { + for (const nodeId of tab.handlerState.parents) { + await resource.load(nodeId); + } + }, + }); + + const folders = navNodeViewService.getFolders(nodeId) || []; + + function openFolder(tabData: ITabData) { + navNodeManagerService.navToNode(nodeId, parentId, tabData.tabId); + } + + useEffect(() => { + if (!folders.includes(folderId) && folders.length > 0) { + navNodeManagerService.navToNode(nodeId, parentId, folders[0]); + } + }); + + if (!folders.includes(folderId) && folders.length > 0) { + folderId = folders[0]; + } return styled(useStyles(verticalTabStyles, styles))( - + - {tabContainer.tabs.map(tab => ( - - {tab.icon && } - {tab.title} - + {folders.map(folderId => ( + ))} - {tabContainer.tabs.map(tab => ( - - + {folders.map(folderId => ( + + ))} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersController.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersController.ts deleted file mode 100644 index 77944e083b..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersController.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { autorun } from 'mobx'; - -import { ITab, NavigationTabsService } from '@cloudbeaver/core-app'; -import { IDestructibleController, IInitializableController, injectable } from '@cloudbeaver/core-di'; - -import type { IObjectViewerTabState } from '../IObjectViewerTabState'; -import { ObjectFoldersService } from './ObjectFoldersService'; -import type { ObjectFoldersTabContainer } from './ObjectFoldersTabsContainer/ObjectFoldersTabContainer'; - -@injectable() -export class ObjectFoldersController implements IInitializableController, IDestructibleController { - private tabContainer!: ObjectFoldersTabContainer; - private navigationTab!: ITab; - private disposer!: ReturnType; - - constructor( - private objectFoldersService: ObjectFoldersService, - private navigationTabsService: NavigationTabsService - ) { } - - getTabContainer(): ObjectFoldersTabContainer { - return this.tabContainer; - } - - init(tab: ITab): void { - this.navigationTab = tab; - - this.tabContainer = this.objectFoldersService.createTabsContainer(tab.handlerState.objectId); - - this.disposer = autorun(() => { - const currentFolderId = tab.handlerState.folderId || null; - if (this.navigationTabsService.currentTabId === tab.id) { - this.activateTab(currentFolderId); - } - }); - } - - private activateTab(folderId: string | null): void { - try { - this.tabContainer.activateTab(folderId); - } catch { - // no tab with tabId - this.activateFirstTab(); - } - } - - private activateFirstTab() { - const firstTab = this.tabContainer.tabs[0]; - this.tabContainer.activateTab(firstTab?.tabId || null); - } - - destruct(): void { - this.disposer(); - this.objectFoldersService.destroyTabContainer(this.navigationTab.handlerState.objectId); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersService.ts deleted file mode 100644 index 212103c7f7..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersService.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { action, makeObservable } from 'mobx'; - -import { TabEntity } from '@cloudbeaver/core-app'; -import type { ITab } from '@cloudbeaver/core-blocks'; -import { Entity, injectable, RootContainerService } from '@cloudbeaver/core-di'; - -import { ObjectFoldersTabService } from './ObjectFoldersTab/ObjectFoldersTabService'; -import { ObjectFoldersTabContainer } from './ObjectFoldersTabsContainer/ObjectFoldersTabContainer'; -import { ObjectInfoTabService } from './ObjectInfoTab/ObjectInfoTabService'; -import { VirtualFolderTabService } from './VirtualFolderTab/VirtualFolderTabService'; - -export interface ITabBuilder { - build: (objectId: string) => ITab | ITab[] | null; -} - -@injectable() -export class ObjectFoldersService { - private tabBuilders: ITabBuilder[] = []; - - // todo temporary solution while only ObjectFolders supports entities - // later it will be integrated in common lifecycle of nested entities - private tabContainersStorage = new Entity(); - - constructor( - private objectInfoTabService: ObjectInfoTabService, - private virtualFolderTabService: VirtualFolderTabService, - private objectFoldersTabService: ObjectFoldersTabService, - private rootContainerService: RootContainerService - ) { - makeObservable(this, { - createTabsContainer: action, - }); - - this.rootContainerService.registerEntityInRootContainer(this.tabContainersStorage); - } - - createTabsContainer(nodeId: string): ObjectFoldersTabContainer { - const tabContainer = new ObjectFoldersTabContainer(nodeId); - this.tabContainersStorage.addChild(tabContainer); - - const infoTab = this.objectInfoTabService.createTabEntity(nodeId); - if (infoTab) { - tabContainer.addTabEntity(infoTab); - } - - this.objectFoldersTabService.createTabEntities(nodeId) - .forEach(tabEntity => tabContainer.addTabEntity(tabEntity)); - - this.virtualFolderTabService.createTabEntities(nodeId) - .forEach(tabEntity => tabContainer.addTabEntity(tabEntity)); - - const tabs = this.getTabs(nodeId); - tabs.forEach(tab => { - const tabEntity = new TabEntity(tab); - tabContainer.addTabEntity(tabEntity); - }); - return tabContainer; - } - - destroyTabContainer(nodeId: string) { - this.tabContainersStorage.removeChild(nodeId); - } - - /** - * return tabs that should be created once for node id - * @param nodeId - */ - getTabs(nodeId: string): ITab[] { - const tabList: ITab[] = []; - this.tabBuilders.forEach(builder => { - const tab = builder.build(nodeId); - if (tab) { - const tabs = Array.isArray(tab) ? tab : [tab]; - tabList.push(...tabs); - } - }); - return tabList; - } - - registerTabConstructor(tabBuilder: ITabBuilder) { - this.tabBuilders.push(tabBuilder); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFolderTabModel.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFolderTabModel.ts deleted file mode 100644 index 6bbe0cf96f..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFolderTabModel.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 type { ReactElement } from 'react'; - -import type { NavNode } from '@cloudbeaver/core-app'; -import type { ITab } from '@cloudbeaver/core-blocks'; - -import { objectPropertyTablePanel } from '../ObjectPropertyTable/ObjectPropertyTable'; - -export class ObjectFolderTabModel implements ITab { - readonly tabId: string; - - get title(): string { - return this.node.name || ''; - } - - get icon(): string | undefined { - return this.node.icon; - } - - panel: () => ReactElement | null; - - constructor(private node: NavNode, - public onActivate: () => void) { - this.tabId = node.id; - this.panel = () => objectPropertyTablePanel(node.parentId, node.id); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFoldersTabService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFoldersTabService.ts deleted file mode 100644 index d6cb8519ea..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTab/ObjectFoldersTabService.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { NavNodeManagerService, TabEntity } from '@cloudbeaver/core-app'; -import type { ITab } from '@cloudbeaver/core-blocks'; -import { injectable } from '@cloudbeaver/core-di'; - -import { ObjectFolderTabModel } from './ObjectFolderTabModel'; - -@injectable() -export class ObjectFoldersTabService { - constructor(private navNodeManagerService: NavNodeManagerService) { - } - - createTabEntities(nodeId: string): TabEntity[] { - return this.tabBuilder(nodeId).map(tab => new TabEntity(tab)); - } - - private tabBuilder(nodeId: string): ITab[] { - const children = this.navNodeManagerService.getTree(nodeId) || []; - - const folderTabs = children.filter(nodeId => { - const node = this.navNodeManagerService.getNode(nodeId); - return node ? node.folder : false; - }); - - const tabList: ITab[] = folderTabs.map(nodeId => { - const node = this.navNodeManagerService.getNode(nodeId); - if (!node) { - throw Error(`node not found: ${nodeId}`); - } - - return new ObjectFolderTabModel( - node, - () => this.navNodeManagerService.navToNode(node.id, node.parentId) - ); - }); - return tabList; - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/NodePropertiesMixin.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/NodePropertiesMixin.ts deleted file mode 100644 index 829e3d7b69..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/NodePropertiesMixin.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 class NodePropertiesMixin { - constructor( - public readonly nodeId: string - ) {} -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/ObjectFoldersTabContainer.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/ObjectFoldersTabContainer.ts deleted file mode 100644 index 17c96aeabb..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectFoldersTabsContainer/ObjectFoldersTabContainer.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { TabContainerEntity } from '@cloudbeaver/core-app'; - -import { NodePropertiesMixin } from './NodePropertiesMixin'; - -export class ObjectFoldersTabContainer extends TabContainerEntity { - constructor(nodeId: string) { - super([], nodeId); - const nodePropertiesMixin = new NodePropertiesMixin(nodeId); - this.addMixin(NodePropertiesMixin, nodePropertiesMixin); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTab.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTab.tsx deleted file mode 100644 index 330f8d93fc..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTab.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; - -import { useService } from '@cloudbeaver/core-di'; - -import { NodePropertiesMixin } from '../ObjectFoldersTabsContainer/NodePropertiesMixin'; -import { ObjectProperties } from './ObjectProperties'; - -export const ObjectInfoTab = observer(function ObjectInfoTab() { - const nodePropertiesMixin = useService(NodePropertiesMixin); - return ( - - ); -}); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabModel.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabModel.ts deleted file mode 100644 index 800fa3fd82..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabModel.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 type { ITab } from '@cloudbeaver/core-blocks'; -import { injectable } from '@cloudbeaver/core-di'; - -import { ObjectInfoTab } from './ObjectInfoTab'; - -@injectable() -export class ObjectInfoTabModel implements ITab { - readonly tabId = 'infoTab'; - title = 'Info'; - icon = 'platform:/plugin/org.jkiss.dbeaver.model/icons/tree/info.png'; - - panel = ObjectInfoTab; - - constructor(public onActivate: () => void) { } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabService.ts deleted file mode 100644 index fb622106ed..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabService.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { TabEntity, NavNodeManagerService, ENodeFeature } from '@cloudbeaver/core-app'; -import { injectable } from '@cloudbeaver/core-di'; - -import { ObjectInfoTabModel } from './ObjectInfoTabModel'; - -@injectable() -export class ObjectInfoTabService { - constructor( - private navNodeManagerService: NavNodeManagerService - ) {} - - createTabEntity(navNodeId: string): TabEntity | null { - const node = this.navNodeManagerService.getNode(navNodeId); - const isDatabaseObject = node?.features?.includes(ENodeFeature.item) - || node?.features?.includes(ENodeFeature.container); - if (!isDatabaseObject) { - return null; - } - - return new TabEntity(new ObjectInfoTabModel( - () => { - const node = this.navNodeManagerService.getNode(navNodeId); - if (node) { - this.navNodeManagerService.navToNode(node.id, node.parentId, 'infoTab'); - } - } - )); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertiesPageService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertiesPageService.ts index 2c59cd96e0..2b04655dfa 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertiesPageService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertiesPageService.ts @@ -57,11 +57,6 @@ export class ObjectPropertiesPageService { try { const tabContext = await contexts.getContext(this.objectViewerTabService.objectViewerTabContext); - - if (tabContext.tab && !tabContext.tab.handlerState.folderId) { - tabContext.tab.handlerState.folderId = 'infoTab'; - } - tabContext.trySwitchPage(this.page); } catch (exception) { this.notificationService.logException(exception, 'Object Viewer Error', 'Error in Object Viewer while processing action with database node'); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTab.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTab.tsx deleted file mode 100644 index f5605e074b..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTab.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { observer } from 'mobx-react-lite'; -import styled, { css } from 'reshadow'; - -import { Loader } from '@cloudbeaver/core-blocks'; -import { useService } from '@cloudbeaver/core-di'; - -import { ObjectChildrenPropertyTable } from '../ObjectPropertyTable/ObjectChildrenPropertyTable'; -import { VirtualFolderTabMixin } from './VirtualFolderTabMixin'; - -const style = css` - tab-wrapper { - position: relative; - width: 100%; - flex: 1 0 auto; - } -`; - -export const VirtualFolderTab = observer(function VirtualFolderTab() { - const folderMixin = useService(VirtualFolderTabMixin); - - if (!folderMixin.isActivated) { - return ; - } - - return styled(style)( - - - - ); -}); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabData.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabData.tsx deleted file mode 100644 index 3b54fcccbd..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabData.tsx +++ /dev/null @@ -1,15 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 class VirtualFolderTabData { - constructor( - public readonly nodeId: string, - public readonly folderName: string, - public readonly childrenIds: string[] - ) {} -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabMixin.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabMixin.tsx deleted file mode 100644 index b3cf5546d2..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabMixin.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { VirtualFolderTabData } from './VirtualFolderTabData'; - -@injectable() -export class VirtualFolderTabMixin { - isActivated = false; - - constructor( - private virtualFolderTabData: VirtualFolderTabData, - ) { - makeObservable(this, { - isActivated: observable, - }); - } - - getChildrenId() { - return this.virtualFolderTabData.childrenIds; - } - - getTitle(): string { - return this.virtualFolderTabData.folderName; - } - - async onActivate() { - if (this.isActivated) { - return; - } - - try { - // for (const nodeId of this.getChildrenId()) { - // await this.dbObjectService.load(nodeId); - // } - } finally { - this.isActivated = true; - } - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabModel.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabModel.tsx deleted file mode 100644 index c1cce653b2..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabModel.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 type { ITab } from '@cloudbeaver/core-blocks'; -import { Entity, injectable } from '@cloudbeaver/core-di'; - -import { VirtualFolderTab } from './VirtualFolderTab'; -import { VirtualFolderTabMixin } from './VirtualFolderTabMixin'; - -@injectable() -export class VirtualFolderTabModel implements ITab { - readonly tabId: string; - title: string; - icon = 'platform:/plugin/org.jkiss.dbeaver.model/icons/tree/folder.png'; - - panel = VirtualFolderTab; - - onActivate = () => this.virtualFolderTabMixin.onActivate(); - - constructor(private tabEntity: Entity, - private virtualFolderTabMixin: VirtualFolderTabMixin) { - this.tabId = this.tabEntity.id; - this.title = this.virtualFolderTabMixin.getTitle(); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabService.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabService.tsx deleted file mode 100644 index 1d854902fa..0000000000 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabService.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2021 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 { NavNodeManagerService, NavNode, TabEntity } from '@cloudbeaver/core-app'; -import { injectable, MixinProvider } from '@cloudbeaver/core-di'; - -import { VirtualFolderTabData } from './VirtualFolderTabData'; -import { VirtualFolderTabMixin } from './VirtualFolderTabMixin'; -import { VirtualFolderTabModel } from './VirtualFolderTabModel'; - -@injectable() -export class VirtualFolderTabService { - constructor(private navNodeManagerService: NavNodeManagerService) { } - - createTabEntities(nodeId: string): TabEntity[] { - const children = this.navNodeManagerService.getTree(nodeId) || []; - - const notFolderNodes = children.reduce( - (nodes, nodeId) => { - const node = this.navNodeManagerService.getNode(nodeId); - if (node && !node.folder) { - nodes.push(node); - } - return nodes; - }, - [] - ); - - const virtualFolders = notFolderNodes.reduce>( - (map, node) => { - const folderName = node?.nodeType || 'unknown'; - - let tabData = map.get(folderName); - if (!tabData) { - tabData = new VirtualFolderTabData(nodeId, folderName, []); - map.set(folderName, tabData); - } - - tabData.childrenIds.push(node.id); - return map; - }, - new Map() - ); - - return Array.from(virtualFolders.values()) - .map(tabData => this.createEntity(tabData)); - } - - private createEntity(tabData: VirtualFolderTabData): TabEntity { - const mixins: Array> = [ - { - token: VirtualFolderTabData, - value: tabData, - }, - VirtualFolderTabMixin, - ]; - return new TabEntity(VirtualFolderTabModel, mixins); - } -} diff --git a/webapp/packages/plugin-object-viewer/src/index.ts b/webapp/packages/plugin-object-viewer/src/index.ts index d230141875..4543e9a376 100644 --- a/webapp/packages/plugin-object-viewer/src/index.ts +++ b/webapp/packages/plugin-object-viewer/src/index.ts @@ -5,6 +5,5 @@ export default manifest; // All Services and Components that is provided by this plugin should be exported here export * from './ObjectPage/DBObjectPageService'; export * from './ObjectPage/ObjectPage'; -export * from './ObjectPropertiesPage/ObjectFoldersService'; export * from './ObjectViewerTabService'; export * from './IObjectViewerTabState'; diff --git a/webapp/packages/plugin-object-viewer/src/locales/en.ts b/webapp/packages/plugin-object-viewer/src/locales/en.ts index 11c56dc59e..8fb5326248 100644 --- a/webapp/packages/plugin-object-viewer/src/locales/en.ts +++ b/webapp/packages/plugin-object-viewer/src/locales/en.ts @@ -1,5 +1,6 @@ export default [ ['plugin_object_viewer_properties_tab', 'Properties'], + ['plugin_object_viewer_object_info_tab', 'Info'], ['plugin_object_viewer_table_name', 'Name'], ['plugin_object_viewer_table_no_items', 'There are no items to show'], ['plugin_object_viewer_error', 'Error occurred while tab loading'], diff --git a/webapp/packages/plugin-object-viewer/src/locales/it.ts b/webapp/packages/plugin-object-viewer/src/locales/it.ts index 00bd246899..5649eb5fd4 100644 --- a/webapp/packages/plugin-object-viewer/src/locales/it.ts +++ b/webapp/packages/plugin-object-viewer/src/locales/it.ts @@ -1,5 +1,6 @@ export default [ ['plugin_object_viewer_properties_tab', 'Proprietà'], + ['plugin_object_viewer_object_info_tab', 'Informazioni'], ['plugin_object_viewer_table_name', 'Nome'], ['plugin_object_viewer_table_no_items', 'Non ci sono elementi da mostrare'], ['plugin_object_viewer_error', 'Errore durante il caricamento della tab'], diff --git a/webapp/packages/plugin-object-viewer/src/locales/ru.ts b/webapp/packages/plugin-object-viewer/src/locales/ru.ts index 09d6a77ecd..4974003b9c 100644 --- a/webapp/packages/plugin-object-viewer/src/locales/ru.ts +++ b/webapp/packages/plugin-object-viewer/src/locales/ru.ts @@ -1,5 +1,6 @@ export default [ ['plugin_object_viewer_properties_tab', 'Свойства'], + ['plugin_object_viewer_object_info_tab', 'Информация'], ['plugin_object_viewer_table_name', 'Название'], ['plugin_object_viewer_table_no_items', 'Нет объектов для показа'], ['plugin_object_viewer_error', 'Произошла ошибка при загрузке вкладки'], diff --git a/webapp/packages/plugin-object-viewer/src/manifest.ts b/webapp/packages/plugin-object-viewer/src/manifest.ts index 907d290f16..6cb56a799d 100644 --- a/webapp/packages/plugin-object-viewer/src/manifest.ts +++ b/webapp/packages/plugin-object-viewer/src/manifest.ts @@ -10,11 +10,9 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; import { LocaleService } from './LocaleService'; import { DBObjectPageService } from './ObjectPage/DBObjectPageService'; -import { ObjectFoldersService } from './ObjectPropertiesPage/ObjectFoldersService'; -import { ObjectFoldersTabService } from './ObjectPropertiesPage/ObjectFoldersTab/ObjectFoldersTabService'; -import { ObjectInfoTabService } from './ObjectPropertiesPage/ObjectInfoTab/ObjectInfoTabService'; +import { NavNodeMetadataViewBootstrap } from './ObjectPropertiesPage/NavNodeView/NavNodeMetadata/NavNodeMetadataViewBootstrap'; +import { VirtualFolderViewBootstrap } from './ObjectPropertiesPage/NavNodeView/VirtualFolder/VirtualFolderViewBootstrap'; import { ObjectPropertiesPageService } from './ObjectPropertiesPage/ObjectPropertiesPageService'; -import { VirtualFolderTabService } from './ObjectPropertiesPage/VirtualFolderTab/VirtualFolderTabService'; import { ObjectViewerBootstrap } from './ObjectViewerBootstrap'; import { ObjectViewerTabService } from './ObjectViewerTabService'; @@ -23,12 +21,10 @@ export const manifest: PluginManifest = { providers: [ ObjectViewerBootstrap, + NavNodeMetadataViewBootstrap, + VirtualFolderViewBootstrap, ObjectPropertiesPageService, - ObjectFoldersService, ObjectViewerTabService, - ObjectInfoTabService, - ObjectFoldersTabService, - VirtualFolderTabService, DBObjectPageService, LocaleService, ],