Skip to content

Commit

Permalink
fix: Load default dashboard data from workspace data (#1810)
Browse files Browse the repository at this point in the history
- Until we have support for #1746 , load the default dashboard data from
workspace
  - Needed for testing the widget hydration PR
- Tested with my changes for widget hydration
  - Ensured deephaven.ui widgets re-opened upon refresh
  - Ensured links remained between existing tables
  • Loading branch information
mofojed authored Feb 28, 2024
1 parent 67de0e0 commit 6dd9814
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 28 deletions.
62 changes: 52 additions & 10 deletions packages/code-studio/src/main/AppMainContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
PanelEvent,
setDashboardData as setDashboardDataAction,
setDashboardPluginData as setDashboardPluginDataAction,
stopListenForCreateDashboard,
updateDashboardData as updateDashboardDataAction,
} from '@deephaven/dashboard';
import {
Expand Down Expand Up @@ -203,6 +204,8 @@ export class AppMainContainer extends Component<

const { allDashboardData } = this.props;

this.dashboardLayouts = new Map();

this.state = {
contextActions: [
{
Expand Down Expand Up @@ -261,6 +264,7 @@ export class AppMainContainer extends Component<

componentDidMount(): void {
this.initWidgets();
this.initDashboardData();
this.startListeningForDisconnect();

window.addEventListener(
Expand All @@ -283,13 +287,18 @@ export class AppMainContainer extends Component<
this.deinitWidgets();
this.stopListeningForDisconnect();

this.dashboardLayouts.forEach(layout => {
stopListenForCreateDashboard(layout.eventHub, this.handleCreateDashboard);
});

window.removeEventListener(
'beforeunload',
AppMainContainer.handleWindowBeforeUnload
);
}

goldenLayout?: GoldenLayout;
/** Map from the dashboard ID to the GoldenLayout instance for that dashboard */
dashboardLayouts: Map<string, GoldenLayout>;

importElement: RefObject<HTMLInputElement>;

Expand Down Expand Up @@ -337,6 +346,28 @@ export class AppMainContainer extends Component<
this.widgetListenerRemover?.();
}

initDashboardData(): void {
// TODO: #1746 We should be loading data from a dashboard storage store
// For now only the default dashboard data is stored with the workspace and set on the default dashboard
const { setDashboardPluginData, updateDashboardData, workspace } =
this.props;
const { data: workspaceData } = workspace;
const { filterSets, links, pluginDataMap } = workspaceData;
updateDashboardData(DEFAULT_DASHBOARD_ID, {
filterSets,
links,
});
if (pluginDataMap != null) {
const pluginKeys = Object.keys(pluginDataMap);
for (let i = 0; i < pluginKeys.length; i += 1) {
const pluginId = pluginKeys[i];
const pluginData = pluginDataMap[pluginId];
log.debug('initDashboardData plugin data', pluginId, pluginData);
setDashboardPluginData(DEFAULT_DASHBOARD_ID, pluginId, pluginData);
}
}
}

openNotebookFromURL(): void {
const { match } = this.props;
const { notebookPath } = match.params;
Expand Down Expand Up @@ -374,7 +405,9 @@ export class AppMainContainer extends Component<
}

emitLayoutEvent(event: string, ...args: unknown[]): void {
this.goldenLayout?.eventHub.emit(event, ...args);
const { activeTabKey } = this.state;
const layout = this.dashboardLayouts.get(activeTabKey);
layout?.eventHub.emit(event, ...args);
}

handleCancelResetLayoutPrompt(): void {
Expand Down Expand Up @@ -465,16 +498,25 @@ export class AppMainContainer extends Component<
const { updateWorkspaceData } = this.props;

// Only save the data that is serializable/we want to persist to the workspace
const { closed, filterSets, links } = data;
updateWorkspaceData({ closed, filterSets, links });
const { closed, filterSets, links, pluginDataMap } = data;
updateWorkspaceData({ closed, filterSets, links, pluginDataMap });
}

handleGoldenLayoutChange(goldenLayout: GoldenLayout): void {
this.goldenLayout = goldenLayout;
listenForCreateDashboard(
this.goldenLayout.eventHub,
this.handleCreateDashboard
);
handleGoldenLayoutChange(newLayout: GoldenLayout): void {
const { activeTabKey } = this.state;
const oldLayout = this.dashboardLayouts.get(activeTabKey);
if (oldLayout === newLayout) return;

if (oldLayout != null) {
stopListenForCreateDashboard(
oldLayout.eventHub,
this.handleCreateDashboard
);
}

this.dashboardLayouts.set(activeTabKey, newLayout);

listenForCreateDashboard(newLayout.eventHub, this.handleCreateDashboard);
}

handleCreateDashboard({
Expand Down
1 change: 1 addition & 0 deletions packages/code-studio/src/storage/LocalWorkspaceStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export class LocalWorkspaceStorage implements WorkspaceStorage {
closed: [{}],
links,
filterSets,
pluginDataMap: {},
};
}

Expand Down
20 changes: 14 additions & 6 deletions packages/dashboard/src/DashboardEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@ import type { EventHub } from '@deephaven/golden-layout';

export const CREATE_DASHBOARD = 'CREATE_DASHBOARD';

export interface CreateDashboardPayload {
export interface CreateDashboardPayload<T = unknown> {
pluginId: string;
title: string;
data: unknown;
data: T;
}

export function listenForCreateDashboard(
export function stopListenForCreateDashboard<T = unknown>(
eventHub: EventHub,
handler: (p: CreateDashboardPayload) => void
handler: (p: CreateDashboardPayload<T>) => void
): void {
eventHub.off(CREATE_DASHBOARD, handler);
}

export function listenForCreateDashboard<T = unknown>(
eventHub: EventHub,
handler: (p: CreateDashboardPayload<T>) => void
): () => void {
eventHub.on(CREATE_DASHBOARD, handler);
return () => stopListenForCreateDashboard(eventHub, handler);
}

export function emitCreateDashboard(
export function emitCreateDashboard<T = unknown>(
eventHub: EventHub,
payload: CreateDashboardPayload
payload: CreateDashboardPayload<T>
): void {
eventHub.emit(CREATE_DASHBOARD, payload);
}
9 changes: 5 additions & 4 deletions packages/dashboard/src/redux/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import { setDashboardPluginData } from './actions';
* @param pluginId - The ID of the plugin.
* @returns A tuple containing the plugin data and a function to update the plugin data.
*/
export function useDashboardPluginData(
export function useDashboardPluginData<T = PluginData>(
dashboardId: string,
pluginId: string
): [PluginData, (data: PluginData) => void] {
): [T, (data: T) => void] {
const dispatch = useDispatch();
const data = useSelector((store: RootState) =>
getPluginDataForDashboard(store, dashboardId, pluginId)
getPluginDataForDashboard<T>(store, dashboardId, pluginId)
);
const setData = useCallback(
newData => dispatch(setDashboardPluginData(dashboardId, pluginId, newData)),
(newData: T) =>
dispatch(setDashboardPluginData(dashboardId, pluginId, newData)),
[dashboardId, pluginId, dispatch]
);
return [data, setData];
Expand Down
8 changes: 4 additions & 4 deletions packages/dashboard/src/redux/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export const getOpenedPanelMapForDashboard = (
* @param dashboardId The dashboard ID to get data for
* @returns The map of plugin IDs to data for all plugins on the dashboard
*/
export const getPluginDataMapForDashboard = (
export const getPluginDataMapForDashboard = <T = PluginData>(
store: RootState,
dashboardId: string
): PluginDataMap =>
): PluginDataMap<T> =>
getDashboardData(store, dashboardId).pluginDataMap ?? EMPTY_OBJECT;

/**
Expand All @@ -73,8 +73,8 @@ export const getPluginDataMapForDashboard = (
* @param pluginId The plugin ID to get data for
* @returns The plugin data
*/
export const getPluginDataForDashboard = (
export const getPluginDataForDashboard = <T = PluginData>(
store: RootState,
dashboardId: string,
pluginId: string
): PluginData => getPluginDataMapForDashboard(store, dashboardId)[pluginId];
): T => getPluginDataMapForDashboard<T>(store, dashboardId)[pluginId];
14 changes: 10 additions & 4 deletions packages/redux/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ export interface WorkspaceSettings {
}

export interface WorkspaceData {
settings: WorkspaceSettings;

// TODO: #1746 The rest of these options should not be stored with workspace data, we should have a separate DashboardStorage
closed: unknown[];
filterSets: unknown[];
layoutConfig: unknown[];
links: unknown;
settings: WorkspaceSettings;
pluginDataMap: PluginDataMap;
}

export interface CustomizableWorkspaceData
Expand All @@ -82,13 +85,16 @@ export interface Workspace {

export type PluginData = unknown;

export type PluginDataMap = Record<string, PluginData>;
export type PluginDataMap<TData = PluginData> = Record<string, TData>;

export type DashboardData = Record<string, unknown> & {
export type DashboardData<TPluginData = PluginData> = Record<
string,
unknown
> & {
title?: string;
closed?: unknown[];
filterSets?: unknown[];
pluginDataMap?: PluginDataMap;
pluginDataMap?: PluginDataMap<TPluginData>;
};

export type WorkspaceStorageLoadOptions = {
Expand Down

0 comments on commit 6dd9814

Please sign in to comment.