1- import React , { useCallback , useEffect , useMemo , useRef } from 'react' ;
2- import { AppRegistryProvider } from 'hadron-app-registry' ;
1+ import React , { useCallback , useMemo } from 'react' ;
32import {
43 ErrorBoundary ,
54 MongoDBLogoMark ,
65 WorkspaceTabs ,
76 css ,
87 palette ,
9- rafraf ,
108 spacing ,
119 useDarkMode ,
1210} from '@mongodb-js/compass-components' ;
@@ -20,7 +18,6 @@ import type {
2018import {
2119 closeTab ,
2220 getActiveTab ,
23- getLocalAppRegistryForTab ,
2421 moveTab ,
2522 openFallbackWorkspace ,
2623 openTabFromCurrent ,
@@ -32,17 +29,9 @@ import { useWorkspacePlugins } from './workspaces-provider';
3229import toNS from 'mongodb-ns' ;
3330import { useLogger } from '@mongodb-js/compass-logging/provider' ;
3431import { connect } from '../stores/context' ;
35- import {
36- WorkspaceTabStateProvider ,
37- useTabState ,
38- } from './workspace-tab-state-provider' ;
39- import { useOnTabReplace } from './workspace-close-handler' ;
40- import { NamespaceProvider } from '@mongodb-js/compass-app-stores/provider' ;
41- import {
42- ConnectionInfoProvider ,
43- useTabConnectionTheme ,
44- } from '@mongodb-js/compass-connections/provider' ;
32+ import { useTabConnectionTheme } from '@mongodb-js/compass-connections/provider' ;
4533import { useConnectionsListRef } from '@mongodb-js/compass-connections/provider' ;
34+ import { WorkspaceTabContextProvider } from './workspace-tab-context-provider' ;
4635
4736type Tooltip = [ string , string ] [ ] ;
4837
@@ -64,51 +53,6 @@ const EmptyWorkspaceContent = () => {
6453 ) ;
6554} ;
6655
67- const ActiveTabCloseHandler : React . FunctionComponent = ( { children } ) => {
68- const mountedRef = useRef ( false ) ;
69- const [ hasInteractedOnce , setHasInteractedOnce ] = useTabState (
70- 'hasInteractedOnce' ,
71- false
72- ) ;
73-
74- useEffect ( ( ) => {
75- mountedRef . current = true ;
76- return ( ) => {
77- mountedRef . current = false ;
78- } ;
79- } ) ;
80-
81- const markAsInteracted = useCallback ( ( ) => {
82- // Make sure we don't count clicking on buttons that actually cause the
83- // workspace to change, like using breadcrumbs or clicking on an item in the
84- // Databases / Collections list. There are certain corner-cases this doesn't
85- // handle, but it's good enough to prevent most cases where users can lose
86- // content by accident
87- rafraf ( ( ) => {
88- if ( mountedRef . current ) {
89- setHasInteractedOnce ( true ) ;
90- }
91- } ) ;
92- } , [ setHasInteractedOnce ] ) ;
93-
94- useOnTabReplace ( ( ) => {
95- return ! hasInteractedOnce ;
96- } ) ;
97-
98- return (
99- // We're not using these for actual user interactions, just to capture the
100- // interacted state
101- // eslint-disable-next-line jsx-a11y/no-static-element-interactions
102- < div
103- style = { { display : 'contents' } }
104- onKeyDown = { markAsInteracted }
105- onClickCapture = { markAsInteracted }
106- >
107- { children }
108- </ div >
109- ) ;
110- } ;
111-
11256const workspacesContainerStyles = css ( {
11357 display : 'grid' ,
11458 width : '100%' ,
@@ -309,71 +253,7 @@ const CompassWorkspaces: React.FunctionComponent<CompassWorkspacesProps> = ({
309253 } , [ tabs , collectionInfo , databaseInfo , getThemeOf , getConnectionById ] ) ;
310254
311255 const activeTabIndex = tabs . findIndex ( ( tab ) => tab === activeTab ) ;
312-
313- const activeWorkspaceElement = useMemo ( ( ) => {
314- switch ( activeTab ?. type ) {
315- case 'Welcome' :
316- case 'My Queries' :
317- case 'Data Modeling' : {
318- const Component = getWorkspacePluginByName ( activeTab . type ) ;
319- return < Component > </ Component > ;
320- }
321- case 'Shell' : {
322- const Component = getWorkspacePluginByName ( activeTab . type ) ;
323- return (
324- < ConnectionInfoProvider connectionInfoId = { activeTab . connectionId } >
325- < Component
326- initialEvaluate = { activeTab . initialEvaluate }
327- initialInput = { activeTab . initialInput }
328- > </ Component >
329- </ ConnectionInfoProvider >
330- ) ;
331- }
332- case 'Performance' :
333- case 'Databases' : {
334- const Component = getWorkspacePluginByName ( activeTab . type ) ;
335- return (
336- < ConnectionInfoProvider connectionInfoId = { activeTab . connectionId } >
337- < Component > </ Component >
338- </ ConnectionInfoProvider >
339- ) ;
340- }
341- case 'Collections' : {
342- const Component = getWorkspacePluginByName ( activeTab . type ) ;
343- return (
344- < ConnectionInfoProvider connectionInfoId = { activeTab . connectionId } >
345- < NamespaceProvider
346- namespace = { activeTab . namespace }
347- onNamespaceFallbackSelect = { ( ns ) => {
348- onNamespaceNotFound ( activeTab , ns ) ;
349- } }
350- >
351- < Component namespace = { activeTab . namespace } > </ Component >
352- </ NamespaceProvider >
353- </ ConnectionInfoProvider >
354- ) ;
355- }
356- case 'Collection' : {
357- const Component = getWorkspacePluginByName ( activeTab . type ) ;
358- // eslint-disable-next-line @typescript-eslint/no-unused-vars
359- const { id, type, connectionId, ...collectionMetadata } = activeTab ;
360- return (
361- < ConnectionInfoProvider connectionInfoId = { activeTab . connectionId } >
362- < NamespaceProvider
363- namespace = { activeTab . namespace }
364- onNamespaceFallbackSelect = { ( ns ) => {
365- onNamespaceNotFound ( activeTab , ns ) ;
366- } }
367- >
368- < Component tabId = { id } { ...collectionMetadata } > </ Component >
369- </ NamespaceProvider >
370- </ ConnectionInfoProvider >
371- ) ;
372- }
373- default :
374- return null ;
375- }
376- } , [ activeTab , getWorkspacePluginByName , onNamespaceNotFound ] ) ;
256+ const WorkspaceComponent = getWorkspacePluginByName ( activeTab ?. type ) ;
377257
378258 const onCreateNewTab = useCallback ( ( ) => {
379259 onCreateTab ( openOnEmptyWorkspace ) ;
@@ -397,31 +277,26 @@ const CompassWorkspaces: React.FunctionComponent<CompassWorkspacesProps> = ({
397277 > </ WorkspaceTabs >
398278
399279 < div className = { workspacesContentStyles } >
400- { activeTab && activeWorkspaceElement ? (
401- < WorkspaceTabStateProvider id = { activeTab . id } >
402- < AppRegistryProvider
403- key = { activeTab . id }
404- scopeName = "Workspace Tab"
405- localAppRegistry = { getLocalAppRegistryForTab ( activeTab . id ) }
406- deactivateOnUnmount = { false }
280+ { activeTab && WorkspaceComponent ? (
281+ < ErrorBoundary
282+ displayName = { activeTab . type }
283+ onError = { ( error , errorInfo ) => {
284+ log . error (
285+ mongoLogId ( 1_001_000_277 ) ,
286+ 'Workspace' ,
287+ 'Rendering workspace tab failed' ,
288+ { name : activeTab . type , error : error . message , errorInfo }
289+ ) ;
290+ } }
291+ >
292+ < WorkspaceTabContextProvider
293+ tab = { activeTab }
294+ sectionType = "tab-content"
295+ onNamespaceNotFound = { onNamespaceNotFound }
407296 >
408- < ActiveTabCloseHandler >
409- < ErrorBoundary
410- displayName = { activeTab . type }
411- onError = { ( error , errorInfo ) => {
412- log . error (
413- mongoLogId ( 1_001_000_277 ) ,
414- 'Workspace' ,
415- 'Rendering workspace tab failed' ,
416- { name : activeTab . type , error : error . message , errorInfo }
417- ) ;
418- } }
419- >
420- { activeWorkspaceElement }
421- </ ErrorBoundary >
422- </ ActiveTabCloseHandler >
423- </ AppRegistryProvider >
424- </ WorkspaceTabStateProvider >
297+ < WorkspaceComponent > </ WorkspaceComponent >
298+ </ WorkspaceTabContextProvider >
299+ </ ErrorBoundary >
425300 ) : (
426301 < EmptyWorkspaceContent > </ EmptyWorkspaceContent >
427302 ) }
0 commit comments