Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Convert DashboardPlugins to WidgetPlugins #1598

Merged
merged 5 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 38 additions & 40 deletions packages/dashboard-core-plugins/src/ChartPlugin.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import { useCallback } from 'react';
import {
assertIsDashboardPluginProps,
DashboardPluginComponentProps,
DehydratedDashboardPanelProps,
useDashboardPanel,
} from '@deephaven/dashboard';
import { forwardRef, useMemo } from 'react';
import { useApi } from '@deephaven/jsapi-bootstrap';
import { useConnection } from '@deephaven/jsapi-components';
import { ChartModel, ChartModelFactory } from '@deephaven/chart';
import type { dh as DhType, IdeConnection } from '@deephaven/jsapi-types';
import { IrisGridUtils } from '@deephaven/iris-grid';
import { getTimeZone, store } from '@deephaven/redux';
import { type WidgetComponentProps } from '@deephaven/plugin';
import {
ChartPanel,
ChartPanelMetadata,
GLChartPanelState,
isChartPanelDehydratedProps,
isChartPanelTableMetadata,
} from './panels';
import ConnectedChartPanel, {
type ChartPanel,
type ChartPanelProps,
} from './panels/ChartPanel';

async function createChartModel(
dh: DhType,
Expand Down Expand Up @@ -86,41 +84,41 @@ async function createChartModel(
return ChartModelFactory.makeModelFromSettings(dh, settings as any, table);
}

export function ChartPlugin(
props: DashboardPluginComponentProps
): JSX.Element | null {
assertIsDashboardPluginProps(props);
const dh = useApi();
const connection = useConnection();
export const ChartPlugin = forwardRef(
(props: WidgetComponentProps, ref: React.Ref<ChartPanel>) => {
const dh = useApi();
const connection = useConnection();

const hydrate = useCallback(
(hydrateProps: DehydratedDashboardPanelProps, id: string) => ({
...hydrateProps,
localDashboardId: id,
makeModel: () => {
const { metadata } = hydrateProps;
const panelState = isChartPanelDehydratedProps(hydrateProps)
? hydrateProps.panelState
: undefined;
if (metadata == null) {
throw new Error('Metadata is required for chart panel');
}
const hydratedProps = useMemo(
() => ({
...(props as unknown as ChartPanelProps),
metadata: props.metadata as ChartPanelMetadata,
localDashboardId: props.localDashboardId,
makeModel: () => {
const { metadata } = props;
const panelState = isChartPanelDehydratedProps(props)
? (props as unknown as ChartPanelProps).panelState
: undefined;
if (metadata == null) {
throw new Error('Metadata is required for chart panel');
}

return createChartModel(dh, connection, metadata, panelState);
},
}),
[dh, connection]
);
return createChartModel(
dh,
connection,
metadata as ChartPanelMetadata,
panelState
);
},
}),
[dh, connection, props]
);

useDashboardPanel({
dashboardProps: props,
componentName: ChartPanel.COMPONENT,
component: ChartPanel,
supportedTypes: dh.VariableType.FIGURE,
hydrate,
});
// eslint-disable-next-line react/jsx-props-no-spreading
return <ConnectedChartPanel ref={ref} {...hydratedProps} />;
}
);

return null;
}
ChartPlugin.displayName = 'ChartPlugin';

export default ChartPlugin;
13 changes: 9 additions & 4 deletions packages/dashboard-core-plugins/src/ChartPluginConfig.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { PluginType, DashboardPlugin } from '@deephaven/plugin';
import { PluginType, type WidgetPlugin } from '@deephaven/plugin';
import { vsGraph } from '@deephaven/icons';
import ChartPlugin from './ChartPlugin';

const ChartPluginConfig: DashboardPlugin = {
name: 'ChartPlugin',
type: PluginType.DASHBOARD_PLUGIN,
const ChartPluginConfig: WidgetPlugin = {
name: 'ChartPanel',
title: 'Chart',
type: PluginType.WIDGET_PLUGIN,
component: ChartPlugin,
panelComponent: ChartPlugin,
supportedTypes: 'Figure',
icon: vsGraph,
mofojed marked this conversation as resolved.
Show resolved Hide resolved
};

export default ChartPluginConfig;
59 changes: 27 additions & 32 deletions packages/dashboard-core-plugins/src/GridPlugin.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
import { useMemo } from 'react';
import {
assertIsDashboardPluginProps,
DashboardPluginComponentProps,
useDashboardPanel,
} from '@deephaven/dashboard';
import { useApi } from '@deephaven/jsapi-bootstrap';
import { IrisGridPanel } from './panels';
import { forwardRef, useMemo } from 'react';
import { type WidgetComponentProps } from '@deephaven/plugin';
import { type DashboardPanelProps } from '@deephaven/dashboard';
import useHydrateGrid from './useHydrateGrid';
import ConnectedIrisGridPanel, {
IrisGridPanelProps,
type IrisGridPanel,
} from './panels/IrisGridPanel';

export function GridPlugin(
props: DashboardPluginComponentProps
): JSX.Element | null {
assertIsDashboardPluginProps(props);
const dh = useApi();
const hydrate = useHydrateGrid();
export const GridPlugin = forwardRef(
(props: WidgetComponentProps, ref: React.Ref<IrisGridPanel>) => {
const hydrate = useHydrateGrid<
DashboardPanelProps & Pick<IrisGridPanelProps, 'panelState'>
>();
const { localDashboardId } = props;
const hydratedProps = useMemo(
() =>
hydrate(
props as WidgetComponentProps &
Pick<IrisGridPanelProps, 'panelState'>,
localDashboardId
),
[hydrate, props, localDashboardId]
);

const supportedTypes = useMemo(
() => [
dh.VariableType.TABLE,
dh.VariableType.TREETABLE,
dh.VariableType.HIERARCHICALTABLE,
],
[dh]
);
// eslint-disable-next-line react/jsx-props-no-spreading
return <ConnectedIrisGridPanel ref={ref} {...hydratedProps} />;
}
);

useDashboardPanel({
dashboardProps: props,
componentName: IrisGridPanel.COMPONENT,
component: IrisGridPanel,
supportedTypes,
hydrate,
});

return null;
}
GridPlugin.displayName = 'GridPlugin';

export default GridPlugin;
13 changes: 9 additions & 4 deletions packages/dashboard-core-plugins/src/GridPluginConfig.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { PluginType, DashboardPlugin } from '@deephaven/plugin';
import { PluginType, type WidgetPlugin } from '@deephaven/plugin';
import { dhTable } from '@deephaven/icons';
import GridPlugin from './GridPlugin';

const GridPluginConfig: DashboardPlugin = {
name: 'GridPlugin',
type: PluginType.DASHBOARD_PLUGIN,
const GridPluginConfig: WidgetPlugin = {
name: 'IrisGridPanel',
title: 'Table',
type: PluginType.WIDGET_PLUGIN,
component: GridPlugin,
panelComponent: GridPlugin,
supportedTypes: ['Table', 'TreeTable', 'HierarchicalTable'],
icon: dhTable,
};

export default GridPluginConfig;
2 changes: 1 addition & 1 deletion packages/dashboard-core-plugins/src/PandasPluginConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dhPandas } from '@deephaven/icons';
import PandasPlugin from './PandasPlugin';

const PandasPluginConfig: WidgetPlugin = {
name: 'PandasPlugin',
name: 'PandasPanel',
title: 'Pandas',
type: PluginType.WIDGET_PLUGIN,
// TODO: #1573 Replace with actual base component and not just the panel plugin
Expand Down
1 change: 0 additions & 1 deletion packages/dashboard-core-plugins/src/WidgetLoaderPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export function WrapWidgetPlugin(
{...props}
/>
)}
)
mattrunyon marked this conversation as resolved.
Show resolved Hide resolved
</WidgetPanel>
);
}
Expand Down
4 changes: 0 additions & 4 deletions packages/dashboard-core-plugins/src/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import { type IdeConnection } from '@deephaven/jsapi-types';
import { ConnectionContext } from '@deephaven/jsapi-components';
import { PluginsContext } from '@deephaven/plugin';
import {
ChartPlugin,
ConsolePlugin,
FilterPlugin,
GridPlugin,
LinkerPlugin,
MarkdownPlugin,
WidgetLoaderPlugin,
Expand All @@ -36,8 +34,6 @@ it('handles mounting and unmount core plugins properly', () => {
<Provider store={store}>
<Dashboard>
<FilterPlugin />
<GridPlugin hydrate={() => undefined} />
<ChartPlugin hydrate={() => undefined} />
<ConsolePlugin />
<LinkerPlugin />
<MarkdownPlugin />
Expand Down
49 changes: 24 additions & 25 deletions packages/dashboard-core-plugins/src/panels/ChartPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export interface ChartPanelFigureMetadata extends PanelMetadata {
* @deprecated use `name` instead
*/
figure?: string;
sourcePanelId: never;
}

export interface ChartPanelTableMetadata extends PanelMetadata {
Expand Down Expand Up @@ -118,28 +119,34 @@ export interface GLChartPanelState {
table?: string;
figure?: string;
}
export interface ChartPanelProps extends DashboardPanelProps {
interface OwnProps extends DashboardPanelProps {
metadata: ChartPanelMetadata;
/** Function to build the ChartModel used by this ChartPanel. Can return a promise. */
makeModel: () => Promise<ChartModel>;
localDashboardId: string;
Plotly?: typeof PlotlyType;
/** The panel container div */
containerRef?: RefObject<HTMLDivElement>;

panelState: GLChartPanelState;
}

interface StateProps {
inputFilters: InputFilter[];
links: Link[];
localDashboardId: string;
isLinkerActive: boolean;
source?: TableTemplate;
sourcePanel?: PanelComponent;
columnSelectionValidator?: ColumnSelectionValidator;
settings: Partial<WorkspaceSettings>;
}

interface DispatchProps {
setActiveTool: (tool: string) => void;
setDashboardIsolatedLinkerPanelId: (
id: string,
secondParam: undefined
) => void;
Plotly?: typeof PlotlyType;
/** The panel container div */
containerRef?: RefObject<HTMLDivElement>;

panelState: GLChartPanelState;
settings: Partial<WorkspaceSettings>;
}

interface ChartPanelState {
Expand Down Expand Up @@ -178,6 +185,11 @@ function hasPanelState(
return (panel as { panelState: IrisGridPanelState }).panelState != null;
}

export type ChartPanelProps = OwnProps &
StateProps &
DispatchProps &
React.RefAttributes<ChartPanel>;

export class ChartPanel extends Component<ChartPanelProps, ChartPanelState> {
static defaultProps = {
columnSelectionValidator: null,
Expand Down Expand Up @@ -1046,7 +1058,7 @@ export class ChartPanel extends Component<ChartPanelProps, ChartPanelState> {
if (isChartPanelTableMetadata(metadata)) {
name = metadata.table;
} else {
name = metadata.figure;
name = metadata.name ?? metadata.figure;
}
const inputFilterMap = this.getInputFilterColumnMap(
columnMap,
Expand Down Expand Up @@ -1157,23 +1169,10 @@ export class ChartPanel extends Component<ChartPanelProps, ChartPanelState> {
}
}

const mapStateToProps = (
state: RootState,
ownProps: { localDashboardId: string; metadata: { sourcePanelId?: string } }
): Omit<
ChartPanelProps,
| 'glContainer'
| 'glEventHub'
| 'localDashboardId'
| 'makeModel'
| 'metadata'
| 'panelState'
| 'setActiveTool'
| 'setDashboardIsolatedLinkerPanelId'
> => {
const mapStateToProps = (state: RootState, ownProps: OwnProps): StateProps => {
const { localDashboardId, metadata } = ownProps;

let sourcePanelId;
let sourcePanelId: string | undefined;
if (metadata != null) {
sourcePanelId = metadata.sourcePanelId;
}
Expand Down Expand Up @@ -1207,7 +1206,7 @@ const ConnectedChartPanel = connect(
{
setActiveTool: setActiveToolAction,
setDashboardIsolatedLinkerPanelId: setDashboardIsolatedLinkerPanelIdAction,
},
} satisfies DispatchProps,
null,
{ forwardRef: true }
)(ChartPanel);
Expand Down
Loading
Loading