;
commandEditor?: monaco.editor.IStandaloneCodeEditor;
@@ -279,6 +280,8 @@ export class ConsoleInput extends PureComponent<
this.commandEditor.focus();
+ this.resizeObserver.observe(element);
+
this.updateDimensions();
this.setState({ model: this.commandEditor.getModel() });
@@ -293,7 +296,7 @@ export class ConsoleInput extends PureComponent<
}
}
- handleWindowResize(): void {
+ handleResize(): void {
this.updateDimensions();
}
diff --git a/packages/dashboard/src/Dashboard.tsx b/packages/dashboard/src/Dashboard.tsx
index 2daea39be2..fd3897d014 100644
--- a/packages/dashboard/src/Dashboard.tsx
+++ b/packages/dashboard/src/Dashboard.tsx
@@ -10,6 +10,7 @@ import React, {
import throttle from 'lodash.throttle';
import GoldenLayout from '@deephaven/golden-layout';
import type { ItemConfigType } from '@deephaven/golden-layout';
+import { useResizeObserver } from '@deephaven/react-hooks';
import './layout/GoldenLayout.scss';
import LayoutUtils from './layout/LayoutUtils';
import PanelPlaceholder from './PanelPlaceholder';
@@ -123,15 +124,7 @@ export function Dashboard({
[layout]
);
- useEffect(
- function initResizeEventListner() {
- window.addEventListener('resize', handleResize);
- return () => {
- window.removeEventListener('resize', handleResize);
- };
- },
- [handleResize]
- );
+ useResizeObserver(layoutElement.current, handleResize);
return (
diff --git a/packages/dashboard/src/DashboardEvents.ts b/packages/dashboard/src/DashboardEvents.ts
new file mode 100644
index 0000000000..22564e867c
--- /dev/null
+++ b/packages/dashboard/src/DashboardEvents.ts
@@ -0,0 +1,23 @@
+import type { EventHub } from '@deephaven/golden-layout';
+
+export const CREATE_DASHBOARD = 'CREATE_DASHBOARD';
+
+export interface CreateDashboardPayload {
+ pluginId: string;
+ title: string;
+ data: unknown;
+}
+
+export function listenForCreateDashboard(
+ eventHub: EventHub,
+ handler: (p: CreateDashboardPayload) => void
+): void {
+ eventHub.on(CREATE_DASHBOARD, handler);
+}
+
+export function emitCreateDashboard(
+ eventHub: EventHub,
+ payload: CreateDashboardPayload
+): void {
+ eventHub.emit(CREATE_DASHBOARD, payload);
+}
diff --git a/packages/dashboard/src/LazyDashboard.tsx b/packages/dashboard/src/LazyDashboard.tsx
new file mode 100644
index 0000000000..219731d9d2
--- /dev/null
+++ b/packages/dashboard/src/LazyDashboard.tsx
@@ -0,0 +1,60 @@
+import React, { useCallback, useState } from 'react';
+import { useDispatch } from 'react-redux';
+import { LoadingOverlay } from '@deephaven/components';
+import { updateWorkspaceData } from '@deephaven/redux';
+import { Dashboard, DashboardProps } from './Dashboard';
+import { updateDashboardData } from './redux';
+import { DashboardLayoutConfig } from './DashboardLayout';
+import { DEFAULT_DASHBOARD_ID } from './DashboardConstants';
+
+export interface LazyDashboardProps extends DashboardProps {
+ id: string;
+ isActive: boolean;
+ plugins: JSX.Element[];
+}
+
+export function LazyDashboard({
+ id,
+ isActive,
+ plugins,
+ ...rest
+}: LazyDashboardProps): JSX.Element {
+ const [isLoaded, setIsLoaded] = useState(isActive);
+ const dispatch = useDispatch();
+
+ const handleLayoutConfigChange = useCallback(
+ (config?: DashboardLayoutConfig) => {
+ // TODO: #1746 Call updateDashboardData for every dashboard
+ // This currently allows the default dashboard to keep its layout since
+ // other dashboards are not persistent yet and we read workspaceData
+ // for the default dashboard layout
+ if (id === DEFAULT_DASHBOARD_ID) {
+ dispatch(updateWorkspaceData({ layoutConfig: config }));
+ } else {
+ dispatch(updateDashboardData(id, { layoutConfig: config }));
+ }
+ },
+ [id, dispatch]
+ );
+
+ if (!isLoaded && isActive) {
+ setIsLoaded(true);
+ }
+
+ if (!isLoaded) {
+ return ;
+ }
+
+ return (
+
+ {plugins}
+
+ );
+}
+
+export default LazyDashboard;
diff --git a/packages/dashboard/src/index.ts b/packages/dashboard/src/index.ts
index 37006159a9..026255f5fc 100644
--- a/packages/dashboard/src/index.ts
+++ b/packages/dashboard/src/index.ts
@@ -4,10 +4,12 @@ export default Dashboard;
export * from './Dashboard';
export * from './DashboardConstants';
+export * from './DashboardEvents';
export * from './DashboardPlugin';
export * from './DashboardLayout';
export * from './DashboardUtils';
export { default as DashboardUtils } from './DashboardUtils';
+export * from './LazyDashboard';
export * from './layout';
export * from './redux';
export * from './PanelManager';
diff --git a/packages/dashboard/src/redux/actions.ts b/packages/dashboard/src/redux/actions.ts
index 7347efebd3..af297b474d 100644
--- a/packages/dashboard/src/redux/actions.ts
+++ b/packages/dashboard/src/redux/actions.ts
@@ -43,11 +43,12 @@ export const updateDashboardData =
);
/**
- * Action to update the dashboard data. Will combine the update with any existing dashboard data.
+ * Action to set the dashboard plugin data.
+ * Will replace any existing plugin data for the plugin in the dashboard with the data provided.
* @param id The id of the dashboard to set the data on
* @param pluginId The id of the plugin to set the data on
* @param data The data to replace the existing plugin data with
- * @returns
+ * @returns Thunk action to dispatch
*/
export const setDashboardPluginData =
(
@@ -59,8 +60,9 @@ export const setDashboardPluginData =
dispatch(
setDashboardData(id, {
...getDashboardData(getState(), id),
- pluginDataMap: new Map(
- getPluginDataMapForDashboard(getState(), id)
- ).set(pluginId, data),
+ pluginDataMap: {
+ ...getPluginDataMapForDashboard(getState(), id),
+ [pluginId]: data,
+ },
})
);
diff --git a/packages/dashboard/src/redux/selectors.ts b/packages/dashboard/src/redux/selectors.ts
index 506013d37d..460c45615f 100644
--- a/packages/dashboard/src/redux/selectors.ts
+++ b/packages/dashboard/src/redux/selectors.ts
@@ -65,7 +65,7 @@ export const getPluginDataMapForDashboard = (
store: RootState,
dashboardId: string
): PluginDataMap =>
- getDashboardData(store, dashboardId).pluginDataMap ?? EMPTY_MAP;
+ getDashboardData(store, dashboardId).pluginDataMap ?? EMPTY_OBJECT;
/**
* @param store The redux store
@@ -77,4 +77,4 @@ export const getPluginDataForDashboard = (
store: RootState,
dashboardId: string,
pluginId: string
-): PluginData => getPluginDataMapForDashboard(store, dashboardId).get(pluginId);
+): PluginData => getPluginDataMapForDashboard(store, dashboardId)[pluginId];
diff --git a/packages/redux/src/store.ts b/packages/redux/src/store.ts
index e8e88d3624..f171163d5f 100644
--- a/packages/redux/src/store.ts
+++ b/packages/redux/src/store.ts
@@ -80,9 +80,12 @@ export interface Workspace {
export type PluginData = unknown;
-export type PluginDataMap = Map;
+export type PluginDataMap = Record;
export type DashboardData = Record & {
+ title?: string;
+ closed?: unknown[];
+ filterSets?: unknown[];
pluginDataMap?: PluginDataMap;
};
@@ -105,7 +108,7 @@ export type RootState = {
user: User;
workspace: CustomizableWorkspace;
defaultWorkspaceSettings: WorkspaceSettings;
- dashboardData: Record;
+ dashboardData: { [id: string]: DashboardData };
layoutStorage: unknown;
serverConfigValues: ServerConfigValues;
};