diff --git a/packages/compass-components/src/components/breadcrumb.spec.tsx b/packages/compass-components/src/components/breadcrumb.spec.tsx index 16ae6ee470b..17df9ec5131 100644 --- a/packages/compass-components/src/components/breadcrumb.spec.tsx +++ b/packages/compass-components/src/components/breadcrumb.spec.tsx @@ -12,7 +12,7 @@ import sinon from 'sinon'; describe('Breadcrumbs Component', function () { afterEach(cleanup); - it('renders nothing when list is empty', function () { + it('renders empty when list is empty', function () { render(); expect(screen.getByTestId('breadcrumbs').children.length).to.equal(0); }); diff --git a/packages/compass-components/src/components/breadcrumb.tsx b/packages/compass-components/src/components/breadcrumb.tsx index 3edff348990..6bc11ef3d10 100644 --- a/packages/compass-components/src/components/breadcrumb.tsx +++ b/packages/compass-components/src/components/breadcrumb.tsx @@ -55,29 +55,27 @@ export const Breadcrumbs = ({ items, className, }: { - items: Array; + items: + | BreadcrumbItem[] + | [...BreadcrumbItem[], Omit]; className?: string; }) => { const darkMode = useDarkMode(); + if (items.length === 0) { + return ( +
+ ); + } + const lastItem = items[items.length - 1]; + const clickableItems = items.slice(0, -1) as BreadcrumbItem[]; return (
- {items.map((item, index) => { - const isLast = index === items.length - 1; - if (isLast) { - return ( - - {item.name} - - ); - } + {clickableItems.map((item, index) => { return ( - + ); })} + + {lastItem.name} +
); }; diff --git a/packages/compass-data-modeling/src/components/diagram-editor-toolbar.spec.tsx b/packages/compass-data-modeling/src/components/diagram-editor-toolbar.spec.tsx index 03b1fa42633..0f47508c00b 100644 --- a/packages/compass-data-modeling/src/components/diagram-editor-toolbar.spec.tsx +++ b/packages/compass-data-modeling/src/components/diagram-editor-toolbar.spec.tsx @@ -3,27 +3,45 @@ import { expect } from 'chai'; import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; import { DiagramEditorToolbar } from './diagram-editor-toolbar'; import sinon from 'sinon'; +import { + type WorkspacesService, + WorkspacesServiceProvider, +} from '@mongodb-js/compass-workspaces/provider'; + +const workspacesService = { + openDataModelingWorkspace: () => {}, +} as WorkspacesService; function renderDiagramEditorToolbar( props: Partial> = {} ) { render( - {}} - onRedoClick={() => {}} - onExportClick={() => {}} - onRelationshipDrawingToggle={() => {}} - onAddCollectionClick={() => {}} - {...props} - /> + + {}} + onRedoClick={() => {}} + onExportClick={() => {}} + onRelationshipDrawingToggle={() => {}} + onAddCollectionClick={() => {}} + {...props} + /> + ); } describe('DiagramEditorToolbar', function () { + beforeEach(function () { + workspacesService.openDataModelingWorkspace = sinon.spy(); + }); + + afterEach(function () { + sinon.reset(); + }); + it('renders nothing if step is NO_DIAGRAM_SELECTED', function () { renderDiagramEditorToolbar({ step: 'NO_DIAGRAM_SELECTED' }); expect(() => screen.getByTestId('diagram-editor-toolbar')).to.throw(); @@ -34,6 +52,23 @@ describe('DiagramEditorToolbar', function () { expect(() => screen.getByTestId('diagram-editor-toolbar')).to.throw(); }); + context('breadcrumbs', function () { + it('includes "diagrams" breadcrumb', function () { + renderDiagramEditorToolbar(); + const diagrams = screen.getByRole('button', { name: 'diagrams' }); + expect(diagrams).to.be.visible; + userEvent.click(diagrams); + expect( + workspacesService.openDataModelingWorkspace + ).to.have.been.calledOnce; + }); + + it('includes diagram name breadcrumb', function () { + renderDiagramEditorToolbar({ diagramName: 'My Diagram' }); + expect(screen.getByText('My Diagram')).to.be.visible; + }); + }); + context('undo button', function () { it('renders it disabled if hasUndo is false', function () { renderDiagramEditorToolbar({ hasUndo: false }); diff --git a/packages/compass-data-modeling/src/components/diagram-editor-toolbar.tsx b/packages/compass-data-modeling/src/components/diagram-editor-toolbar.tsx index 0a0d5cfef2f..a38f4fecfb5 100644 --- a/packages/compass-data-modeling/src/components/diagram-editor-toolbar.tsx +++ b/packages/compass-data-modeling/src/components/diagram-editor-toolbar.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { connect } from 'react-redux'; import type { DataModelingState } from '../store/reducer'; import { redoEdit, undoEdit } from '../store/diagram'; @@ -14,13 +14,21 @@ import { useDarkMode, transparentize, Tooltip, + Breadcrumbs, + type BreadcrumbItem, } from '@mongodb-js/compass-components'; import AddCollection from './icons/add-collection'; -const containerStyles = css({ +import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider'; + +const breadcrumbsStyles = css({ + padding: `${spacing[300]}px ${spacing[400]}px`, +}); + +const editorToolbarStyles = css({ display: 'flex', justifyContent: 'space-between', alignItems: 'center', - padding: `${spacing[150]}px ${spacing[200]}px`, + padding: `${spacing[150]}px ${spacing[300]}px`, backgroundColor: palette.gray.light3, borderBottom: `1px solid ${palette.gray.light2}`, marginBottom: spacing[50], @@ -29,7 +37,7 @@ const containerStyles = css({ }px ${transparentize(0.85, palette.black)}`, }); -const containerDarkStyles = css({ +const editorToolbarDarkStyles = css({ backgroundColor: palette.gray.dark3, borderBottom: `1px solid ${palette.gray.dark2}`, boxShadow: `0px ${spacing[50]}px ${spacing[100]}px -${ @@ -43,6 +51,7 @@ const toolbarGroupStyles = css({ export const DiagramEditorToolbar: React.FunctionComponent<{ step: DataModelingState['step']; + diagramName?: string; hasUndo: boolean; hasRedo: boolean; isInRelationshipDrawingMode: boolean; @@ -53,6 +62,7 @@ export const DiagramEditorToolbar: React.FunctionComponent<{ onAddCollectionClick: () => void; }> = ({ step, + diagramName, hasUndo, onUndoClick, hasRedo, @@ -63,47 +73,75 @@ export const DiagramEditorToolbar: React.FunctionComponent<{ isInRelationshipDrawingMode, }) => { const darkmode = useDarkMode(); + const { openDataModelingWorkspace } = useOpenWorkspace(); + + const breadcrumbItems: [ + ...BreadcrumbItem[], + Omit + ] = useMemo( + () => [ + { name: 'diagrams', onClick: () => openDataModelingWorkspace() }, + { name: diagramName || 'untitled' }, + ], + [diagramName, openDataModelingWorkspace] + ); + if (step !== 'EDITING') { return null; } + return ( -
-
- - - - - - - - - - - - - } - > - Drag from one collection to another to create a relationship. - -
-
- +
+ +
+
+ + + + + + + + + + + + + } + > + Drag from one collection to another to create a relationship. + +
+
+ +
); @@ -116,6 +154,7 @@ export default connect( step: step, hasUndo: (diagram?.edits.prev.length ?? 0) > 0, hasRedo: (diagram?.edits.next.length ?? 0) > 0, + diagramName: diagram?.name, }; }, {