diff --git a/packages/compass-database/package.json b/packages/compass-database/package.json index f219ba01255..2d648f80677 100644 --- a/packages/compass-database/package.json +++ b/packages/compass-database/package.json @@ -58,6 +58,7 @@ "peerDependencies": { "@mongodb-js/compass-components": "^1.19.0", "@mongodb-js/compass-logging": "^1.2.6", + "hadron-app-registry": "^9.0.14", "react": "^17.0.2" }, "devDependencies": { @@ -74,7 +75,6 @@ "chai": "^4.1.2", "depcheck": "^1.4.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.0.14", "mocha": "^10.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -82,6 +82,7 @@ }, "dependencies": { "@mongodb-js/compass-components": "^1.19.0", - "@mongodb-js/compass-logging": "^1.2.6" + "@mongodb-js/compass-logging": "^1.2.6", + "hadron-app-registry": "^9.0.14" } } diff --git a/packages/compass-database/src/components/database-tabs-provider.tsx b/packages/compass-database/src/components/database-tabs-provider.tsx new file mode 100644 index 00000000000..211c4becbed --- /dev/null +++ b/packages/compass-database/src/components/database-tabs-provider.tsx @@ -0,0 +1,29 @@ +import React, { useContext, useMemo, useRef } from 'react'; + +export type DatabaseTab = { + name: string; + component: React.ComponentType; +}; + +const DatabaseTabsContext = React.createContext([]); + +export const DatabaseTabsProvider: React.FunctionComponent<{ + tabs: DatabaseTab[]; +}> = ({ tabs, children }) => { + const tabsRef = useRef(tabs); + return ( + + {children} + + ); +}; + +export function useDatabaseTabs( + filterFn: (tab: DatabaseTab) => boolean = () => true +): DatabaseTab[] { + const tabs = useContext(DatabaseTabsContext); + const filteredTabs = useMemo(() => { + return tabs.filter(filterFn); + }, [tabs, filterFn]); + return filteredTabs; +} diff --git a/packages/compass-database/src/components/database.spec.tsx b/packages/compass-database/src/components/database.spec.tsx index a3ac19d2a28..1130e0dc32e 100644 --- a/packages/compass-database/src/components/database.spec.tsx +++ b/packages/compass-database/src/components/database.spec.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { expect } from 'chai'; -import AppRegistry from 'hadron-app-registry'; import { Database } from './database'; +import { DatabaseTabsProvider } from './database-tabs-provider'; class Collections extends React.Component { render() { @@ -19,18 +19,11 @@ const ROLE = { describe('Database [Component]', function () { let globalBefore: any; beforeEach(function () { - const registry = new AppRegistry(); - - globalBefore = (global as any).hadronApp; - (global as any).hadronApp = { - appRegistry: registry, - }; - - ((global as any).hadronApp.appRegistry as AppRegistry).registerRole( - 'Database.Tab', - ROLE + render( + + + ); - render(); }); afterEach(function () { diff --git a/packages/compass-database/src/components/database.tsx b/packages/compass-database/src/components/database.tsx index 5036785bc42..9bbcc02cfd8 100644 --- a/packages/compass-database/src/components/database.tsx +++ b/packages/compass-database/src/components/database.tsx @@ -1,9 +1,7 @@ -import React, { useState, useRef, useCallback } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { ErrorBoundary, TabNavBar, css } from '@mongodb-js/compass-components'; -import { createLoggerAndTelemetry } from '@mongodb-js/compass-logging'; -import type AppRegistry from 'hadron-app-registry'; - -const { log, mongoLogId } = createLoggerAndTelemetry('COMPASS-DATABASES'); +import { useLoggerAndTelemetry } from '@mongodb-js/compass-logging/provider'; +import { useDatabaseTabs } from './database-tabs-provider'; const databaseStyles = css({ display: 'flex', @@ -12,7 +10,8 @@ const databaseStyles = css({ height: '100%', }); -function Database() { +export function Database() { + const { log, mongoLogId } = useLoggerAndTelemetry('COMPASS-DATABASES'); const [activeTab, setActiveTab] = useState(0); const onTabClicked = useCallback( @@ -25,29 +24,28 @@ function Database() { [activeTab] ); - const roles = useRef( - ((global as any).hadronApp?.appRegistry as AppRegistry).getRole( - 'Database.Tab' - ) || [] - ); - const tabs = useRef(roles.current.map((role) => role.name)); - const views = useRef( - roles.current.map((role, i) => ( - { - log.error( - mongoLogId(1001000109), - 'Database Workspace', - 'Rendering database tab failed', - { name: role.name, error: error.message, errorInfo } - ); - }} - > - - - )) + const tabs = useDatabaseTabs(); + + const tabNames = useMemo(() => tabs.map((tab) => tab.name), [tabs]); + const views = useMemo( + () => + tabs.map((tab, i) => ( + { + log.error( + mongoLogId(1001000109), + 'Database Workspace', + 'Rendering database tab failed', + { name: tab.name, error: error.message, errorInfo } + ); + }} + > + + + )), + [tabs, log, mongoLogId] ); return ( @@ -55,13 +53,11 @@ function Database() { ); } - -export { Database }; diff --git a/packages/compass-database/src/index.ts b/packages/compass-database/src/index.ts index ecf05477799..2d49abc3bf3 100644 --- a/packages/compass-database/src/index.ts +++ b/packages/compass-database/src/index.ts @@ -1,22 +1,24 @@ -import type AppRegistry from 'hadron-app-registry'; -import DatabasePlugin from './plugin'; +import type { LoggerAndTelemetry } from '@mongodb-js/compass-logging/provider'; +import { registerHadronPlugin } from 'hadron-app-registry'; +import { DatabasePlugin, onActivated } from './plugin'; -/** - * Activate all the components in the Database package. - * @param {Object} appRegistry - The Hadron appRegisrty to activate this plugin with. - **/ -function activate(appRegistry: AppRegistry): void { - appRegistry.registerComponent('Database.Workspace', DatabasePlugin); +function activate(): void { + // noop } -/** - * Deactivate all the components in the Database package. - * @param {Object} appRegistry - The Hadron appRegisrty to deactivate this plugin with. - **/ -function deactivate(appRegistry: AppRegistry): void { - appRegistry.deregisterComponent('Database.Workspace'); +function deactivate(): void { + // noop } -export default DatabasePlugin; +export const CompassDatabasePlugin = registerHadronPlugin< + object, + { logger: () => LoggerAndTelemetry } +>({ + name: 'CompassDatabase', + component: DatabasePlugin as React.FunctionComponent, + activate: onActivated, +}); + +export { DatabaseTabsProvider } from './components/database-tabs-provider'; export { activate, deactivate }; export { default as metadata } from '../package.json'; diff --git a/packages/compass-database/src/plugin.tsx b/packages/compass-database/src/plugin.tsx index 9cd06a7e62f..f508d07b65b 100644 --- a/packages/compass-database/src/plugin.tsx +++ b/packages/compass-database/src/plugin.tsx @@ -1,8 +1,17 @@ import React from 'react'; import { Database } from './components/database'; -function Plugin() { +export function DatabasePlugin() { return ; } -export default Plugin; +export function onActivated() { + return { + store: { + state: {}, + }, + deactivate() { + /* nothing to do */ + }, + }; +} diff --git a/packages/compass-home/package.json b/packages/compass-home/package.json index 25b66b42a90..d2a95369b47 100644 --- a/packages/compass-home/package.json +++ b/packages/compass-home/package.json @@ -39,6 +39,7 @@ "@mongodb-js/compass-app-stores": "^7.6.1", "@mongodb-js/compass-components": "^1.19.0", "@mongodb-js/compass-connections": "^1.20.1", + "@mongodb-js/compass-database": "^3.19.1", "@mongodb-js/compass-databases-collections": "^1.19.1", "@mongodb-js/compass-find-in-page": "^4.19.1", "@mongodb-js/compass-import-export": "^7.19.1", @@ -61,6 +62,7 @@ "@mongodb-js/compass-app-stores": "^7.6.1", "@mongodb-js/compass-components": "^1.19.0", "@mongodb-js/compass-connections": "^1.20.1", + "@mongodb-js/compass-database": "^3.19.1", "@mongodb-js/compass-databases-collections": "^1.19.1", "@mongodb-js/compass-find-in-page": "^4.19.1", "@mongodb-js/compass-import-export": "^7.19.1", diff --git a/packages/compass-home/src/components/home.spec.tsx b/packages/compass-home/src/components/home.spec.tsx index cd5c3c29bde..043d6939b03 100644 --- a/packages/compass-home/src/components/home.spec.tsx +++ b/packages/compass-home/src/components/home.spec.tsx @@ -57,7 +57,7 @@ describe('Home [Component]', function () { const testAppRegistry = globalAppRegistry; beforeEach(function () { - ['Collection.Workspace', 'Database.Workspace'].forEach((name) => + ['Collection.Workspace'].forEach((name) => testAppRegistry.registerComponent(name, getComponent(name)) ); diff --git a/packages/compass-home/src/components/workspace-content.spec.tsx b/packages/compass-home/src/components/workspace-content.spec.tsx index 78776b0df14..836bba2f63f 100644 --- a/packages/compass-home/src/components/workspace-content.spec.tsx +++ b/packages/compass-home/src/components/workspace-content.spec.tsx @@ -36,7 +36,7 @@ function renderWorkspaceContent( describe('WorkspaceContent [Component]', function () { before(function () { - ['Collection.Workspace', 'Database.Workspace'].map((name) => + ['Collection.Workspace'].map((name) => globalAppRegistry.registerComponent(name, getComponent(name)) ); globalAppRegistry.onActivated(); @@ -50,7 +50,6 @@ describe('WorkspaceContent [Component]', function () { }); it('renders content correctly', function () { - expect(screen.queryByTestId('test-Database.Workspace')).to.not.exist; expect(screen.queryByTestId('test-Collection.Workspace')).to.not.exist; }); }); @@ -61,7 +60,6 @@ describe('WorkspaceContent [Component]', function () { }); it('renders content correctly', function () { - expect(screen.getByTestId('test-Database.Workspace')).to.be.visible; expect(screen.queryByTestId('test-Collection.Workspace')).to.not.exist; }); }); @@ -74,7 +72,6 @@ describe('WorkspaceContent [Component]', function () { }); it('renders content correctly', function () { - expect(screen.queryByTestId('test-Database.Workspace')).to.not.exist; expect(screen.getByTestId('test-Collection.Workspace')).to.be.visible; }); }); diff --git a/packages/compass-home/src/components/workspace-content.tsx b/packages/compass-home/src/components/workspace-content.tsx index f937618f7f8..ef60ca5f357 100644 --- a/packages/compass-home/src/components/workspace-content.tsx +++ b/packages/compass-home/src/components/workspace-content.tsx @@ -7,6 +7,10 @@ import { import InstanceWorkspacePlugin, { InstanceTabsProvider, } from '@mongodb-js/compass-instance'; +import { + CompassDatabasePlugin, + DatabaseTabsProvider, +} from '@mongodb-js/compass-database'; import CompassSavedAggregationsQueriesPlugin from '@mongodb-js/compass-saved-aggregations-queries'; import { InstanceTab as DatabasesPlugin } from '@mongodb-js/compass-databases-collections'; import type Namespace from '../types/namespace'; @@ -17,18 +21,21 @@ const WorkspaceContent: React.FunctionComponent<{ namespace: Namespace }> = ({ namespace, }) => { const instanceTabs = useAppRegistryRole('Instance.Tab'); + const databaseTabs = useAppRegistryRole('Database.Tab'); const Collection = useAppRegistryComponent('Collection.Workspace') ?? EmptyComponent; - const Database = - useAppRegistryComponent('Database.Workspace') ?? EmptyComponent; if (namespace.collection) { return ; } if (namespace.database) { - return ; + return ( + + + + ); } return (