Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SavedDiagramsList from './saved-diagrams-list';
import NewDiagramFormModal from './new-diagram-form';
import type { DataModelingState } from '../store/reducer';
import { DiagramProvider } from '@mongodb-js/diagramming';
import DiagramEditorSidePanel from './diagram-editor-side-panel';
type DataModelingPluginInitialProps = {
showList: boolean;
};
Expand All @@ -19,6 +20,7 @@ const DataModeling: React.FunctionComponent<DataModelingPluginInitialProps> = ({
) : (
<DiagramProvider fitView>
<DiagramEditor />
<DiagramEditorSidePanel />
</DiagramProvider>
)}
<NewDiagramFormModal></NewDiagramFormModal>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import { connect } from 'react-redux';
import type { DataModelingState } from '../store/reducer';
import { closeSidePanel } from '../store/side-panel';
import {
Button,
css,
cx,
Body,
spacing,
palette,
useDarkMode,
} from '@mongodb-js/compass-components';

const containerStyles = css({
width: '400px',
height: '100%',

display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: spacing[400],
borderLeft: `1px solid ${palette.gray.light2}`,
});

const darkModeContainerStyles = css({
borderLeftColor: palette.gray.dark2,
});

type DiagramEditorSidePanelProps = {
isOpen: boolean;
onClose: () => void;
};

function DiagmramEditorSidePanel({
isOpen,
onClose,
}: DiagramEditorSidePanelProps) {
const isDarkMode = useDarkMode();
if (!isOpen) {
return null;
}
return (
<div className={cx(containerStyles, isDarkMode && darkModeContainerStyles)}>
Copy link

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding appropriate ARIA attributes (e.g., role="dialog", aria-label) to the panel container so screen readers can properly announce this element.

Suggested change
<div className={cx(containerStyles, isDarkMode && darkModeContainerStyles)}>
<div
className={cx(containerStyles, isDarkMode && darkModeContainerStyles)}
role="dialog"
aria-label="Diagram Editor Side Panel"
>

Copilot uses AI. Check for mistakes.
<Body>This feature is under development.</Body>
<Button onClick={onClose} variant="primary" size="small">
Close Side Panel
</Button>
</div>
);
}

export default connect(
(state: DataModelingState) => {
const { sidePanel } = state;
return {
isOpen: sidePanel.isOpen,
};
},
{
onClose: closeSidePanel,
}
)(DiagmramEditorSidePanel);
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import type { StaticModel } from '../services/data-model-storage';
import DiagramEditorToolbar from './diagram-editor-toolbar';
import ExportDiagramModal from './export-diagram-modal';
import { useLogger } from '@mongodb-js/compass-logging/provider';
import { openSidePanel } from '../store/side-panel';

const loadingContainerStyles = css({
width: '100%',
Expand Down Expand Up @@ -188,6 +189,7 @@ const DiagramEditor: React.FunctionComponent<{
onCancelClick: () => void;
onApplyInitialLayout: (positions: Record<string, [number, number]>) => void;
onMoveCollection: (ns: string, newPosition: [number, number]) => void;
onOpenSidePanel: () => void;
}> = ({
diagramLabel,
step,
Expand All @@ -196,6 +198,7 @@ const DiagramEditor: React.FunctionComponent<{
onCancelClick,
onApplyInitialLayout,
onMoveCollection,
onOpenSidePanel,
}) => {
const { log, mongoLogId } = useLogger('COMPASS-DATA-MODELING-DIAGRAM-EDITOR');
const isDarkMode = useDarkMode();
Expand Down Expand Up @@ -332,6 +335,10 @@ const DiagramEditor: React.FunctionComponent<{
title={diagramLabel}
edges={edges}
nodes={areNodesReady ? nodes : []}
onEdgeClick={() => {
// TODO: we have to open a side panel with edge details
Copy link

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The TODO comment is now outdated since onOpenSidePanel is implemented. Please update or remove this comment to keep the code clean.

Suggested change
// TODO: we have to open a side panel with edge details

Copilot uses AI. Check for mistakes.
onOpenSidePanel();
}}
fitViewOptions={{
maxZoom: 1,
minZoom: 0.25,
Expand Down Expand Up @@ -370,5 +377,6 @@ export default connect(
onCancelClick: cancelAnalysis,
onApplyInitialLayout: applyInitialLayout,
onMoveCollection: moveCollection,
onOpenSidePanel: openSidePanel,
}
)(DiagramEditor);
5 changes: 5 additions & 0 deletions packages/compass-data-modeling/src/store/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,30 @@ import type {
ExportDiagramActions,
} from './export-diagram';
import { exportDiagramReducer } from './export-diagram';
import type { SidePanelActions, SidePanelActionTypes } from './side-panel';
import { sidePanelReducer } from './side-panel';

const reducer = combineReducers({
step: stepReducer,
generateDiagramWizard: generateDiagramWizardReducer,
analysisProgress: analysisProcessReducer,
diagram: diagramReducer,
exportDiagram: exportDiagramReducer,
sidePanel: sidePanelReducer,
});

export type DataModelingActions =
| GenerateDiagramWizardActions
| AnalysisProgressActions
| DiagramActions
| SidePanelActions
| ExportDiagramActions;

export type DataModelingActionTypes =
| GenerateDiagramWizardActionTypes
| AnalysisProcessActionTypes
| DiagramActionTypes
| SidePanelActionTypes
| ExportDiagramActionTypes;

export type DataModelingState = ReturnType<typeof reducer>;
Expand Down
52 changes: 52 additions & 0 deletions packages/compass-data-modeling/src/store/side-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Reducer } from 'redux';
import { isAction } from './util';

export type SidePanelState = {
isOpen: boolean;
};

export enum SidePanelActionTypes {
SIDE_PANEL_OPENED = 'data-modeling/side-panel/SIDE_PANEL_OPENED',
SIDE_PANEL_CLOSED = 'data-modeling/side-panel/SIDE_PANEL_CLOSED',
}

export type SidePanelOpenedAction = {
type: SidePanelActionTypes.SIDE_PANEL_OPENED;
};

export type SidePanelClosedAction = {
type: SidePanelActionTypes.SIDE_PANEL_CLOSED;
};

export type SidePanelActions = SidePanelOpenedAction | SidePanelClosedAction;

const INITIAL_STATE: SidePanelState = {
isOpen: false,
};

export const sidePanelReducer: Reducer<SidePanelState> = (
state = INITIAL_STATE,
action
) => {
if (isAction(action, SidePanelActionTypes.SIDE_PANEL_OPENED)) {
return {
...state,
isOpen: true,
};
}
if (isAction(action, SidePanelActionTypes.SIDE_PANEL_CLOSED)) {
return {
...state,
isOpen: false,
};
}
return state;
};

export const openSidePanel = (): SidePanelOpenedAction => ({
type: SidePanelActionTypes.SIDE_PANEL_OPENED,
});

export const closeSidePanel = (): SidePanelClosedAction => ({
type: SidePanelActionTypes.SIDE_PANEL_CLOSED,
});
Loading