Skip to content

Commit 369ef5e

Browse files
authored
feat(data-modeling): add side panel COMPASS-9476 (#7111)
add diagram editor side panel
1 parent 01e92b0 commit 369ef5e

File tree

5 files changed

+131
-0
lines changed

5 files changed

+131
-0
lines changed

packages/compass-data-modeling/src/components/data-modeling.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import SavedDiagramsList from './saved-diagrams-list';
55
import NewDiagramFormModal from './new-diagram-form';
66
import type { DataModelingState } from '../store/reducer';
77
import { DiagramProvider } from '@mongodb-js/diagramming';
8+
import DiagramEditorSidePanel from './diagram-editor-side-panel';
89
type DataModelingPluginInitialProps = {
910
showList: boolean;
1011
};
@@ -19,6 +20,7 @@ const DataModeling: React.FunctionComponent<DataModelingPluginInitialProps> = ({
1920
) : (
2021
<DiagramProvider fitView>
2122
<DiagramEditor />
23+
<DiagramEditorSidePanel />
2224
</DiagramProvider>
2325
)}
2426
<NewDiagramFormModal></NewDiagramFormModal>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react';
2+
import { connect } from 'react-redux';
3+
import type { DataModelingState } from '../store/reducer';
4+
import { closeSidePanel } from '../store/side-panel';
5+
import {
6+
Button,
7+
css,
8+
cx,
9+
Body,
10+
spacing,
11+
palette,
12+
useDarkMode,
13+
} from '@mongodb-js/compass-components';
14+
15+
const containerStyles = css({
16+
width: '400px',
17+
height: '100%',
18+
19+
display: 'flex',
20+
flexDirection: 'column',
21+
alignItems: 'center',
22+
justifyContent: 'center',
23+
gap: spacing[400],
24+
borderLeft: `1px solid ${palette.gray.light2}`,
25+
});
26+
27+
const darkModeContainerStyles = css({
28+
borderLeftColor: palette.gray.dark2,
29+
});
30+
31+
type DiagramEditorSidePanelProps = {
32+
isOpen: boolean;
33+
onClose: () => void;
34+
};
35+
36+
function DiagmramEditorSidePanel({
37+
isOpen,
38+
onClose,
39+
}: DiagramEditorSidePanelProps) {
40+
const isDarkMode = useDarkMode();
41+
if (!isOpen) {
42+
return null;
43+
}
44+
return (
45+
<div className={cx(containerStyles, isDarkMode && darkModeContainerStyles)}>
46+
<Body>This feature is under development.</Body>
47+
<Button onClick={onClose} variant="primary" size="small">
48+
Close Side Panel
49+
</Button>
50+
</div>
51+
);
52+
}
53+
54+
export default connect(
55+
(state: DataModelingState) => {
56+
const { sidePanel } = state;
57+
return {
58+
isOpen: sidePanel.isOpen,
59+
};
60+
},
61+
{
62+
onClose: closeSidePanel,
63+
}
64+
)(DiagmramEditorSidePanel);

packages/compass-data-modeling/src/components/diagram-editor.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import type { StaticModel } from '../services/data-model-storage';
3838
import DiagramEditorToolbar from './diagram-editor-toolbar';
3939
import ExportDiagramModal from './export-diagram-modal';
4040
import { useLogger } from '@mongodb-js/compass-logging/provider';
41+
import { openSidePanel } from '../store/side-panel';
4142

4243
const loadingContainerStyles = css({
4344
width: '100%',
@@ -188,6 +189,7 @@ const DiagramEditor: React.FunctionComponent<{
188189
onCancelClick: () => void;
189190
onApplyInitialLayout: (positions: Record<string, [number, number]>) => void;
190191
onMoveCollection: (ns: string, newPosition: [number, number]) => void;
192+
onOpenSidePanel: () => void;
191193
}> = ({
192194
diagramLabel,
193195
step,
@@ -196,6 +198,7 @@ const DiagramEditor: React.FunctionComponent<{
196198
onCancelClick,
197199
onApplyInitialLayout,
198200
onMoveCollection,
201+
onOpenSidePanel,
199202
}) => {
200203
const { log, mongoLogId } = useLogger('COMPASS-DATA-MODELING-DIAGRAM-EDITOR');
201204
const isDarkMode = useDarkMode();
@@ -332,6 +335,10 @@ const DiagramEditor: React.FunctionComponent<{
332335
title={diagramLabel}
333336
edges={edges}
334337
nodes={areNodesReady ? nodes : []}
338+
onEdgeClick={() => {
339+
// TODO: we have to open a side panel with edge details
340+
onOpenSidePanel();
341+
}}
335342
fitViewOptions={{
336343
maxZoom: 1,
337344
minZoom: 0.25,
@@ -370,5 +377,6 @@ export default connect(
370377
onCancelClick: cancelAnalysis,
371378
onApplyInitialLayout: applyInitialLayout,
372379
onMoveCollection: moveCollection,
380+
onOpenSidePanel: openSidePanel,
373381
}
374382
)(DiagramEditor);

packages/compass-data-modeling/src/store/reducer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,30 @@ import type {
2020
ExportDiagramActions,
2121
} from './export-diagram';
2222
import { exportDiagramReducer } from './export-diagram';
23+
import type { SidePanelActions, SidePanelActionTypes } from './side-panel';
24+
import { sidePanelReducer } from './side-panel';
2325

2426
const reducer = combineReducers({
2527
step: stepReducer,
2628
generateDiagramWizard: generateDiagramWizardReducer,
2729
analysisProgress: analysisProcessReducer,
2830
diagram: diagramReducer,
2931
exportDiagram: exportDiagramReducer,
32+
sidePanel: sidePanelReducer,
3033
});
3134

3235
export type DataModelingActions =
3336
| GenerateDiagramWizardActions
3437
| AnalysisProgressActions
3538
| DiagramActions
39+
| SidePanelActions
3640
| ExportDiagramActions;
3741

3842
export type DataModelingActionTypes =
3943
| GenerateDiagramWizardActionTypes
4044
| AnalysisProcessActionTypes
4145
| DiagramActionTypes
46+
| SidePanelActionTypes
4247
| ExportDiagramActionTypes;
4348

4449
export type DataModelingState = ReturnType<typeof reducer>;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { Reducer } from 'redux';
2+
import { isAction } from './util';
3+
4+
export type SidePanelState = {
5+
isOpen: boolean;
6+
};
7+
8+
export enum SidePanelActionTypes {
9+
SIDE_PANEL_OPENED = 'data-modeling/side-panel/SIDE_PANEL_OPENED',
10+
SIDE_PANEL_CLOSED = 'data-modeling/side-panel/SIDE_PANEL_CLOSED',
11+
}
12+
13+
export type SidePanelOpenedAction = {
14+
type: SidePanelActionTypes.SIDE_PANEL_OPENED;
15+
};
16+
17+
export type SidePanelClosedAction = {
18+
type: SidePanelActionTypes.SIDE_PANEL_CLOSED;
19+
};
20+
21+
export type SidePanelActions = SidePanelOpenedAction | SidePanelClosedAction;
22+
23+
const INITIAL_STATE: SidePanelState = {
24+
isOpen: false,
25+
};
26+
27+
export const sidePanelReducer: Reducer<SidePanelState> = (
28+
state = INITIAL_STATE,
29+
action
30+
) => {
31+
if (isAction(action, SidePanelActionTypes.SIDE_PANEL_OPENED)) {
32+
return {
33+
...state,
34+
isOpen: true,
35+
};
36+
}
37+
if (isAction(action, SidePanelActionTypes.SIDE_PANEL_CLOSED)) {
38+
return {
39+
...state,
40+
isOpen: false,
41+
};
42+
}
43+
return state;
44+
};
45+
46+
export const openSidePanel = (): SidePanelOpenedAction => ({
47+
type: SidePanelActionTypes.SIDE_PANEL_OPENED,
48+
});
49+
50+
export const closeSidePanel = (): SidePanelClosedAction => ({
51+
type: SidePanelActionTypes.SIDE_PANEL_CLOSED,
52+
});

0 commit comments

Comments
 (0)