Skip to content

Commit 27fc8bd

Browse files
authored
feat: Add DashboardPlugin support to embed-widget (#1950)
Needed for deephaven/deephaven-plugins#215 Doesn't support multiple dashboards being opened in one embed, but some of the groundwork is there and we don't support multiple dashboards from a single widget anyway yet.
1 parent 5770557 commit 27fc8bd

File tree

19 files changed

+339
-66
lines changed

19 files changed

+339
-66
lines changed

Diff for: package-lock.json

+22-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/app-utils/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@deephaven/console": "file:../console",
3636
"@deephaven/dashboard": "file:../dashboard",
3737
"@deephaven/dashboard-core-plugins": "file:../dashboard-core-plugins",
38+
"@deephaven/golden-layout": "file:../golden-layout",
3839
"@deephaven/icons": "file:../icons",
3940
"@deephaven/iris-grid": "file:../iris-grid",
4041
"@deephaven/jsapi-bootstrap": "file:../jsapi-bootstrap",
@@ -48,6 +49,7 @@
4849
"@deephaven/utils": "file:../utils",
4950
"@paciolan/remote-component": "2.13.0",
5051
"@paciolan/remote-module-loader": "^3.0.2",
52+
"classnames": "^2.5.1",
5153
"fira": "mozilla/fira#4.202"
5254
},
5355
"peerDependencies": {

Diff for: packages/code-studio/src/main/AppDashboards.tsx renamed to packages/app-utils/src/components/AppDashboards.tsx

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,40 @@ import React, { useCallback } from 'react';
22
import classNames from 'classnames';
33
import {
44
DashboardUtils,
5-
DEFAULT_DASHBOARD_ID,
65
DehydratedDashboardPanelProps,
76
LazyDashboard,
87
} from '@deephaven/dashboard';
98
import {
109
sanitizeVariableDescriptor,
1110
useObjectFetcher,
1211
} from '@deephaven/jsapi-bootstrap';
13-
import LayoutManager, { ItemConfigType } from '@deephaven/golden-layout';
12+
import LayoutManager, {
13+
ItemConfigType,
14+
Settings as LayoutSettings,
15+
} from '@deephaven/golden-layout';
1416
import { LoadingOverlay } from '@deephaven/components';
15-
import EmptyDashboard from './EmptyDashboard';
1617

1718
interface AppDashboardsProps {
1819
dashboards: {
1920
id: string;
2021
layoutConfig: ItemConfigType[];
22+
layoutSettings?: Partial<LayoutSettings>;
2123
key?: string;
2224
}[];
2325
activeDashboard: string;
26+
onLayoutInitialized?: () => void;
2427
onGoldenLayoutChange: (goldenLayout: LayoutManager) => void;
2528
plugins: JSX.Element[];
26-
onAutoFillClick: (event: React.MouseEvent) => void;
29+
emptyDashboard?: JSX.Element;
2730
}
2831

2932
export function AppDashboards({
3033
dashboards,
3134
activeDashboard,
35+
onLayoutInitialized,
3236
onGoldenLayoutChange,
3337
plugins,
34-
onAutoFillClick,
38+
emptyDashboard = <LoadingOverlay />,
3539
}: AppDashboardsProps): JSX.Element {
3640
const fetchObject = useObjectFetcher();
3741

@@ -68,14 +72,10 @@ export function AppDashboards({
6872
id={d.id}
6973
key={d.key}
7074
isActive={d.id === activeDashboard}
71-
emptyDashboard={
72-
d.id === DEFAULT_DASHBOARD_ID ? (
73-
<EmptyDashboard onAutoFillClick={onAutoFillClick} />
74-
) : (
75-
<LoadingOverlay />
76-
)
77-
}
75+
emptyDashboard={emptyDashboard}
7876
layoutConfig={d.layoutConfig}
77+
layoutSettings={d.layoutSettings}
78+
onLayoutInitialized={onLayoutInitialized}
7979
onGoldenLayoutChange={onGoldenLayoutChange}
8080
hydrate={hydratePanel}
8181
plugins={plugins}

Diff for: packages/app-utils/src/components/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './AppBootstrap';
2+
export * from './AppDashboards';
23
export * from './AuthBootstrap';
34
export * from './ConnectionBootstrap';
45
export * from './ConnectionContext';

Diff for: packages/code-studio/src/main/AppMainContainer.tsx

+14-25
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
NavTabList,
2727
type NavTabItem,
2828
SlideTransition,
29+
LoadingOverlay,
2930
} from '@deephaven/components';
3031
import { SHORTCUTS as IRIS_GRID_SHORTCUTS } from '@deephaven/iris-grid';
3132
import {
@@ -88,13 +89,8 @@ import {
8889
} from '@deephaven/utils';
8990
import GoldenLayout from '@deephaven/golden-layout';
9091
import type { ItemConfigType } from '@deephaven/golden-layout';
91-
import {
92-
type DashboardPlugin,
93-
isDashboardPlugin,
94-
type LegacyDashboardPlugin,
95-
isLegacyDashboardPlugin,
96-
type PluginModuleMap,
97-
} from '@deephaven/plugin';
92+
import { type PluginModuleMap, getDashboardPlugins } from '@deephaven/plugin';
93+
import { AppDashboards } from '@deephaven/app-utils';
9894
import JSZip from 'jszip';
9995
import SettingsMenu from '../settings/SettingsMenu';
10096
import AppControlsMenu from './AppControlsMenu';
@@ -103,8 +99,8 @@ import './AppMainContainer.scss';
10399
import WidgetList, { WindowMouseEvent } from './WidgetList';
104100
import UserLayoutUtils from './UserLayoutUtils';
105101
import LayoutStorage from '../storage/LayoutStorage';
106-
import AppDashboards from './AppDashboards';
107102
import { getFormattedVersionInfo } from '../settings/SettingsUtils';
103+
import EmptyDashboard from './EmptyDashboard';
108104

109105
const log = Log.module('AppMainContainer');
110106

@@ -783,22 +779,9 @@ export class AppMainContainer extends Component<
783779
});
784780
}
785781

786-
getDashboardPlugins = memoize((plugins: PluginModuleMap) => {
787-
const dashboardPlugins = [...plugins.entries()].filter(
788-
([, plugin]) =>
789-
isDashboardPlugin(plugin) || isLegacyDashboardPlugin(plugin)
790-
) as [string, DashboardPlugin | LegacyDashboardPlugin][];
791-
792-
return dashboardPlugins.map(([name, plugin]) => {
793-
if (isLegacyDashboardPlugin(plugin)) {
794-
const { DashboardPlugin: DPlugin } = plugin;
795-
return <DPlugin key={name} />;
796-
}
797-
798-
const { component: DPlugin } = plugin;
799-
return <DPlugin key={name} />;
800-
});
801-
});
782+
getDashboardPlugins = memoize((plugins: PluginModuleMap) =>
783+
getDashboardPlugins(plugins)
784+
);
802785

803786
handleHomeClick(): void {
804787
this.handleTabSelect(DEFAULT_DASHBOARD_ID);
@@ -995,7 +978,13 @@ export class AppMainContainer extends Component<
995978
dashboards={this.getDashboards()}
996979
activeDashboard={activeTabKey}
997980
onGoldenLayoutChange={this.handleGoldenLayoutChange}
998-
onAutoFillClick={this.handleAutoFillClick}
981+
emptyDashboard={
982+
activeTabKey === DEFAULT_DASHBOARD_ID ? (
983+
<EmptyDashboard onAutoFillClick={this.handleAutoFillClick} />
984+
) : (
985+
<LoadingOverlay />
986+
)
987+
}
999988
plugins={[
1000989
<ConsolePlugin
1001990
key="ConsolePlugin"

Diff for: packages/dashboard/src/DashboardEvents.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ export function stopListenForCreateDashboard<T = unknown>(
1212
eventHub: EventHub,
1313
handler: (p: CreateDashboardPayload<T>) => void
1414
): void {
15-
eventHub.off(CREATE_DASHBOARD, handler);
15+
try {
16+
eventHub.off(CREATE_DASHBOARD, handler);
17+
} catch {
18+
// golden-layout throws if the handler is not found. Instead catch it and no-op
19+
}
1620
}
1721

1822
export function listenForCreateDashboard<T = unknown>(

Diff for: packages/dashboard/src/DashboardLayout.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,6 @@ export function DashboardLayout({
101101
layout.getReactChildren()
102102
);
103103

104-
// Fire only once after the layout is mounted
105-
// This should ensure DashboardPlugins have been mounted
106-
// eslint-disable-next-line react-hooks/exhaustive-deps
107-
useEffect(() => onLayoutInitialized(), []);
108-
109104
const hydrateMap = useMemo(() => new Map(), []);
110105
const dehydrateMap = useMemo(() => new Map(), []);
111106
const registerComponent = useCallback(
@@ -320,6 +315,13 @@ export function DashboardLayout({
320315
]
321316
);
322317

318+
// This should be the last hook called in this component
319+
// Ensures it runs after any other effects on mount
320+
// Fire only once after the layout is mounted
321+
// This should ensure DashboardPlugins have been mounted
322+
// eslint-disable-next-line react-hooks/exhaustive-deps
323+
useEffect(() => onLayoutInitialized(), []);
324+
323325
return (
324326
<>
325327
{isDashboardEmpty && emptyDashboard}

Diff for: packages/embed-widget/package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,21 @@
1818
"dependencies": {
1919
"@deephaven/app-utils": "file:../app-utils",
2020
"@deephaven/components": "file:../components",
21+
"@deephaven/dashboard": "file:../dashboard",
2122
"@deephaven/dashboard-core-plugins": "file:../dashboard-core-plugins",
2223
"@deephaven/jsapi-bootstrap": "file:../jsapi-bootstrap",
2324
"@deephaven/jsapi-components": "file:../jsapi-components",
2425
"@deephaven/jsapi-types": "1.0.0-dev0.33.1",
2526
"@deephaven/jsapi-utils": "file:../jsapi-utils",
2627
"@deephaven/log": "file:../log",
2728
"@deephaven/plugin": "file:../plugin",
29+
"@deephaven/redux": "file:../redux",
30+
"@deephaven/utils": "file:../utils",
2831
"fira": "mozilla/fira#4.202",
2932
"react": "^17.0.2",
30-
"react-dom": "^17.0.2"
33+
"react-dom": "^17.0.2",
34+
"react-redux": "^7.2.4",
35+
"shortid": "^2.2.16"
3136
},
3237
"scripts": {
3338
"analyze": "source-map-explorer build/assets/*.js --no-border-checks",

Diff for: packages/embed-widget/src/App.scss

+37
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,43 @@
77
left: 0;
88
right: 0;
99
bottom: 0;
10+
height: 100vh;
11+
width: 100vw;
12+
display: flex;
13+
flex-direction: column;
14+
flex-wrap: nowrap;
15+
overflow: hidden;
16+
}
17+
18+
$tab-height: 32px;
19+
$tab-font-size: 1rem;
20+
21+
$tab-button-side-padding: 9px;
22+
23+
$tab-link-disabled-color: $gray-600;
24+
25+
$nav-space: 4px; // give a gap around some buttons for focus area that are in nav bar
26+
27+
.app-main-top-nav-menus {
28+
display: flex;
29+
width: 100%;
30+
justify-content: space-between;
31+
align-items: center;
32+
}
33+
34+
.tab-content {
35+
flex-grow: 1;
36+
height: 100%;
37+
}
38+
39+
.tab-pane {
1040
height: 100%;
1141
width: 100%;
42+
flex-grow: 1;
43+
}
44+
45+
.app-main-tabs {
46+
&:focus {
47+
outline: none;
48+
}
1249
}

0 commit comments

Comments
 (0)