Skip to content

Commit

Permalink
chore(collection-header): collection action buttons (mongodb-js#5515)
Browse files Browse the repository at this point in the history
* breadcrumbs ui

* refactor

* undo unwanted change

* depcheck

* fix workspace tab tests

* unit test

* fix e2e tests

* todo

* pr feedback

* remove due to connection title

* make text bold

* better if

* collection actions ux

* fix css

* remove irrelevant tests

* reduce padding
  • Loading branch information
mabaasit authored Mar 2, 2024
1 parent e975995 commit c0832c6
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 191 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,43 @@
import { expect } from 'chai';
import React from 'react';
import React, { type ComponentProps } from 'react';
import { render, screen, cleanup } from '@testing-library/react';

import sinon from 'sinon';
import {
WorkspacesServiceProvider,
type WorkspacesService,
} from '@mongodb-js/compass-workspaces/provider';
import CollectionHeaderActions from '../collection-header-actions';

function renderCollectionHeaderActions(
props: Partial<ComponentProps<typeof CollectionHeaderActions>> = {},
workspaceService: Partial<WorkspacesService> = {}
) {
return render(
<WorkspacesServiceProvider value={workspaceService as WorkspacesService}>
<CollectionHeaderActions
namespace="test.test"
isReadonly={false}
{...props}
/>
</WorkspacesServiceProvider>
);
}

describe('CollectionHeaderActions [Component]', function () {
let sandbox: sinon.SinonSandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
this.afterEach(function () {
sandbox.restore();
});
context('when the collection is not readonly', function () {
beforeEach(function () {
render(
<CollectionHeaderActions
isReadonly={false}
onEditViewClicked={() => {}}
onReturnToViewClicked={() => {}}
sourceName="db.coll"
/>
);
renderCollectionHeaderActions({
isReadonly: false,
namespace: 'db.coll2',
sourceName: 'db.coll',
});
});

afterEach(cleanup);
Expand All @@ -29,54 +52,20 @@ describe('CollectionHeaderActions [Component]', function () {
});
});

context('when the collection is readonly', function () {
beforeEach(function () {
render(
<CollectionHeaderActions
isReadonly={true}
onEditViewClicked={() => {}}
onReturnToViewClicked={() => {}}
sourceName="orig.coll"
/>
);
});

afterEach(cleanup);

it('renders the source collection', function () {
const label = screen.getByTestId('collection-view-on');
expect(label).to.have.text('view on: orig.coll');
expect(label).to.be.visible;
});
});

context('when the collection is readonly but not a view', function () {
beforeEach(function () {
render(
<CollectionHeaderActions
isReadonly={true}
onEditViewClicked={() => {}}
onReturnToViewClicked={() => {}}
/>
);
});

afterEach(cleanup);

it('does not render view information', function () {
expect(screen.queryByTestId('collection-badge-view')).to.not.exist;
});
});

context('when the collection is a view', function () {
let openEditViewWorkspaceStub: sinon.SinonStub;
beforeEach(function () {
render(
<CollectionHeaderActions
isReadonly={true}
onEditViewClicked={() => {}}
onReturnToViewClicked={() => {}}
sourceName="db.someSource"
/>
openEditViewWorkspaceStub = sandbox.stub();
renderCollectionHeaderActions(
{
isReadonly: true,
namespace: 'db.coll2',
sourceName: 'db.someSource',
sourcePipeline: [{ $match: { a: 1 } }],
},
{
openEditViewWorkspace: openEditViewWorkspaceStub,
}
);
});

Expand All @@ -87,17 +76,35 @@ describe('CollectionHeaderActions [Component]', function () {
screen.getByTestId('collection-header-actions-edit-button')
).to.exist;
});
it('calls openEditViewWorkspace when the edit button is clicked', function () {
expect(openEditViewWorkspaceStub).to.not.have.been.called;
const button = screen.getByTestId(
'collection-header-actions-edit-button'
);
button.click();
expect(openEditViewWorkspaceStub).to.have.been.calledOnceWith(
'db.coll2',
{
sourceName: 'db.someSource',
sourcePipeline: [{ $match: { a: 1 } }],
}
);
});
});

context('when the collection is editing a view', function () {
let openCollectionWorkspaceStub: sinon.SinonStub;
beforeEach(function () {
render(
<CollectionHeaderActions
isReadonly={false}
onEditViewClicked={() => {}}
onReturnToViewClicked={() => {}}
editViewName="db.editing"
/>
openCollectionWorkspaceStub = sandbox.stub();
renderCollectionHeaderActions(
{
isReadonly: false,
namespace: 'db.coll2',
editViewName: 'db.editing',
},
{
openCollectionWorkspace: openCollectionWorkspaceStub,
}
);
});

Expand All @@ -108,5 +115,15 @@ describe('CollectionHeaderActions [Component]', function () {
screen.getByTestId('collection-header-actions-return-to-view-button')
).to.exist;
});
it('calls openCollectionWorkspace when the return to view button is clicked', function () {
expect(openCollectionWorkspaceStub).to.not.have.been.called;
const button = screen.getByTestId(
'collection-header-actions-return-to-view-button'
);
button.click();
expect(openCollectionWorkspaceStub).to.have.been.calledOnceWith(
'db.editing'
);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,71 +1,72 @@
import {
Button,
ButtonSize,
Icon,
css,
spacing,
} from '@mongodb-js/compass-components';
import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider';
import React from 'react';

import ViewInformation from './view-information';

const editViewButtonStyles = css({
flex: 'none',
});

const collectionHeaderActionsStyles = css({
display: 'flex',
marginLeft: 'auto',
alignItems: 'center',
overflow: 'hidden',
gap: spacing[2],
});

const collectionHeaderActionsReadonlyStyles = css({
alignItems: 'center',
flex: 'none',
});

type CollectionHeaderActionsProps = {
editViewName?: string;
namespace: string;
isReadonly: boolean;
onEditViewClicked: () => void;
onReturnToViewClicked: () => void;
editViewName?: string;
sourceName?: string;
sourcePipeline?: unknown[];
};

const CollectionHeaderActions: React.FunctionComponent<
CollectionHeaderActionsProps
> = ({
editViewName,
namespace,
isReadonly,
onEditViewClicked,
onReturnToViewClicked,
editViewName,
sourceName,
sourcePipeline,
}: CollectionHeaderActionsProps) => {
const { openCollectionWorkspace, openEditViewWorkspace } = useOpenWorkspace();
return (
<div
className={collectionHeaderActionsStyles}
data-testid="collection-header-actions"
>
{isReadonly && sourceName && <ViewInformation sourceName={sourceName} />}
{isReadonly && sourceName && !editViewName && (
<Button
data-testid="collection-header-actions-edit-button"
className={editViewButtonStyles}
size={ButtonSize.XSmall}
onClick={onEditViewClicked}
size={ButtonSize.Small}
onClick={() => {
if (sourceName && sourcePipeline) {
openEditViewWorkspace(namespace, {
sourceName,
sourcePipeline,
});
}
}}
>
EDIT VIEW
<Icon glyph="Edit" />
Edit Pipeline
</Button>
)}
{editViewName && (
<Button
data-testid="collection-header-actions-return-to-view-button"
className={collectionHeaderActionsReadonlyStyles}
size={ButtonSize.XSmall}
onClick={onReturnToViewClicked}
size={ButtonSize.Small}
onClick={() => {
if (editViewName) {
openCollectionWorkspace(editViewName);
}
}}
>
&lt; Return to View
<Icon glyph="ArrowLeft" />
Return to View
</Button>
)}
</div>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ describe('CollectionHeader [Component]', function () {
expect(screen.getByTestId('breadcrumbs')).to.exist;
});

it('renders the source collection', function () {
const label = screen.getByTestId('collection-view-on');
expect(label).to.have.text('view on: orig.coll');
expect(label).to.be.visible;
});

it('renders the readonly badge', function () {
expect(screen.getByTestId('collection-badge-readonly')).to.exist;
});
Expand All @@ -97,10 +91,6 @@ describe('CollectionHeader [Component]', function () {
renderCollectionHeader({ isReadonly: true, sourceName: undefined });
});

it('does not render the source collection', function () {
expect(screen.queryByTestId('collection-view-on')).to.not.exist;
});

it('renders the readonly badge', function () {
expect(screen.getByTestId('collection-badge-readonly')).to.exist;
});
Expand All @@ -115,10 +105,6 @@ describe('CollectionHeader [Component]', function () {
renderCollectionHeader({ isTimeSeries: true });
});

it('does not render the source collection', function () {
expect(screen.queryByTestId('collection-view-on')).to.not.exist;
});

it('does not render the readonly badge', function () {
expect(screen.queryByTestId('collection-badge-readonly')).to.not.exist;
});
Expand All @@ -133,10 +119,6 @@ describe('CollectionHeader [Component]', function () {
renderCollectionHeader({ isClustered: true });
});

it('does not render the source collection', function () {
expect(screen.queryByTestId('collection-view-on')).to.not.exist;
});

it('does not render the readonly badge', function () {
expect(screen.queryByTestId('collection-badge-readonly')).to.not.exist;
});
Expand Down
Loading

0 comments on commit c0832c6

Please sign in to comment.