Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -146,6 +146,15 @@ const drawerLayoutFixesStyles = css({
'& > div:nth-child(2)': {
marginTop: -1, // hiding the top border as we already have one in the place where the Anchor is currently rendered
},

// Doing our best to target the section title here, leafygreen really doesn't
// give us anything else to try. We're stretching the title container to all
// available width so that we can layout the controls there better
'& > div:nth-child(2) div:has(> strong)': {
flex: 1,
maxWidth: 'calc(100% - 28px)', // disallow going over the title size (100 - close button width)
overflow: 'hidden',
},
});

const emptyDrawerLayoutFixesStyles = css({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ export const DrawerToolbarLayoutContainer = forwardRef<
) => {
const { openDrawer, closeDrawer, getActiveDrawerContent, isDrawerOpen } =
useDrawerToolbarContext();
const { id, title, content } = getActiveDrawerContent() || {};
const { id } = getActiveDrawerContent() || {};
const lgIds = getLgIds(dataLgId);
const hasData = toolbarData && toolbarData.length > 0;
const { title, content } =
toolbarData.find((data) => {
return data.id === id;
}) ?? {};
Comment on lines +42 to +48
Copy link
Collaborator Author

@gribnoysup gribnoysup Aug 8, 2025

Choose a reason for hiding this comment

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

This is like a super minimal version of the fix that LG team did in this patch, mapping their changes on top of our vendored package was tricky due to naming (and seems like code was generally shifted around more there), but we can be sure that when this is not vendored anymore, this will continue working

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, I promised a test for this, let me add that

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added in 1538798


const handleOnClose = (event: React.MouseEvent<HTMLButtonElement>) => {
onClose?.(event);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,161 @@
import React from 'react';
import React, { useMemo } from 'react';
import { connect } from 'react-redux';
import type { DataModelingState } from '../../store/reducer';
import { DrawerSection } from '@mongodb-js/compass-components';
import {
css,
DrawerSection,
ItemActionControls,
} from '@mongodb-js/compass-components';
import CollectionDrawerContent from './collection-drawer-content';
import RelationshipDrawerContent from './relationship-drawer-content';
import {
deleteRelationship,
selectCurrentModelFromState,
} from '../../store/diagram';
import { getDefaultRelationshipName } from '../../utils';

export const DATA_MODELING_DRAWER_ID = 'data-modeling-drawer';

const drawerTitleStyles = css({
display: 'flex',
width: '100%',
});

const drawerTitleTextStyles = css({
flex: 1,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
});

const drawerTitleActionGroupStyles = css({});

type DiagramEditorSidePanelProps = {
selectedItems: { type: 'relationship' | 'collection'; id: string } | null;
selectedItems: {
id: string;
type: 'relationship' | 'collection';
label: string;
} | null;
onDeleteRelationship: (rId: string) => void;
};

function DiagramEditorSidePanel({
selectedItems,
onDeleteRelationship,
}: DiagramEditorSidePanelProps) {
if (!selectedItems) {
return null;
}
const { content, label, actions, handleAction } = useMemo(() => {
if (selectedItems?.type === 'collection') {
return {
label: selectedItems.label,
content: (
<CollectionDrawerContent
key={selectedItems.id}
namespace={selectedItems.id}
></CollectionDrawerContent>
),
actions: [],
handleAction: () => {},
};
}

if (selectedItems?.type === 'relationship') {
return {
label: selectedItems.label,
content: (
<RelationshipDrawerContent
key={selectedItems.id}
relationshipId={selectedItems.id}
></RelationshipDrawerContent>
),
actions: [
{ action: 'delete', label: 'Delete', icon: 'Trash' as const },
],
handleAction: (actionName: string) => {
if (actionName === 'delete') {
onDeleteRelationship(selectedItems.id);
}
},
};
}

return { content: null };
}, [selectedItems, onDeleteRelationship]);

let content;

if (selectedItems.type === 'collection') {
content = (
<CollectionDrawerContent
key={selectedItems.id}
namespace={selectedItems.id}
></CollectionDrawerContent>
);
} else if (selectedItems.type === 'relationship') {
content = (
<RelationshipDrawerContent
key={selectedItems.id}
relationshipId={selectedItems.id}
></RelationshipDrawerContent>
);
if (!content) {
return null;
}

return (
<DrawerSection
id={DATA_MODELING_DRAWER_ID}
title="Details"
label="Details"
glyph="InfoWithCircle"
title={
<div className={drawerTitleStyles}>
<span className={drawerTitleTextStyles} title={label}>
{label}
</span>

<ItemActionControls
actions={actions}
iconSize="small"
onAction={handleAction}
className={drawerTitleActionGroupStyles}
// Because the close button here is out of our control, we have do
// adjust the actions rendering in a bit of an unconventional way:
// if there's more than one action available, collapse it to "...",
// if it's just one, render the button
collapseAfter={actions.length > 1 ? 0 : 1}
></ItemActionControls>
</div>
}
label={label}
glyph="Wrench"
autoOpen
// TODO: Leafygreen doesn't allow us to tie close event to a particular
// action. We can add this functionality ourselves, but I'm not sure that
// adding even more logic on top of the drawer is a good idea. Maybe we're
// okay with the drawer close button click just staying there until you
// explicitly click something else?
// onClose={onClose}
>
{content}
</DrawerSection>
);
}

export default connect((state: DataModelingState) => {
return {
selectedItems: state.diagram?.selectedItems ?? null,
};
})(DiagramEditorSidePanel);
export default connect(
(state: DataModelingState) => {
const selected = state.diagram?.selectedItems;

if (!selected) {
return {
selectedItems: null,
};
}

if (selected.type === 'collection') {
return {
selectedItems: {
...selected,
label: selected.id,
},
};
}

if (selected.type === 'relationship') {
const model = selectCurrentModelFromState(state);
const relationship = model.relationships.find((relationship) => {
return relationship.id === selected.id;
});

if (!relationship) {
throw new Error(
'Can not find corresponding relationship when rendering DiagramEditorSidePanel'
);
}

return {
selectedItems: {
...selected,
label: getDefaultRelationshipName(relationship.relationship),
},
};
}
},
{
onDeleteRelationship: deleteRelationship,
}
)(DiagramEditorSidePanel);
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import {
spacing,
css,
palette,
Button,
Icon,
TextArea,
} from '@mongodb-js/compass-components';
import {
Expand All @@ -34,7 +32,6 @@ type RelationshipDrawerContentProps = {
relationship: Relationship;
fields: Record<string, string[][]>;
onRelationshipUpdate: (relationship: Relationship) => void;
onDeleteRelationshipClick: (rId: string) => void;
};

type RelationshipFormFields = {
Expand All @@ -47,11 +44,6 @@ type RelationshipFormFields = {
note: string;
};

const titleBtnStyles = css({
marginLeft: 'auto',
maxHeight: 20, // to make sure we're matching accordion line height
});

const FIELD_DIVIDER = '~~##$$##~~';

function useRelationshipFormFields(
Expand Down Expand Up @@ -156,13 +148,7 @@ const configurationForeignFieldStyles = css({

const RelationshipDrawerContent: React.FunctionComponent<
RelationshipDrawerContentProps
> = ({
relationshipId,
relationship,
fields,
onRelationshipUpdate,
onDeleteRelationshipClick,
}) => {
> = ({ relationshipId, relationship, fields, onRelationshipUpdate }) => {
const collections = useMemo(() => {
return Object.keys(fields);
}, [fields]);
Expand Down Expand Up @@ -192,25 +178,7 @@ const RelationshipDrawerContent: React.FunctionComponent<

return (
<div data-relationship-id={relationshipId}>
<DMDrawerSection
label={
<>
<span>Relationship properties</span>

<Button
variant="dangerOutline"
leftGlyph={<Icon glyph="Trash" />}
className={titleBtnStyles}
size="xsmall"
onClick={() => {
onDeleteRelationshipClick(relationshipId);
}}
>
Delete
</Button>
</>
}
>
<DMDrawerSection label="Relationship properties">
<div className={configurationContainerStyles}>
<div className={configurationLocalFieldStyles}>
<DMFormFieldContainer>
Expand Down
Loading