Skip to content

Commit eab7899

Browse files
authored
feat(compass-global-writes): sharding in progress state COMPASS-8277 (#6347)
1 parent 11209f0 commit eab7899

File tree

8 files changed

+604
-86
lines changed

8 files changed

+604
-86
lines changed

packages/compass-global-writes/src/components/index.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
spacing,
66
WorkspaceContainer,
77
SpinLoaderWithLabel,
8+
ConfirmationModalArea,
89
} from '@mongodb-js/compass-components';
910
import type { RootState, ShardingStatus } from '../store/reducer';
1011
import { ShardingStatuses } from '../store/reducer';
@@ -55,7 +56,10 @@ function ShardingStateView({
5556
return <UnshardedState />;
5657
}
5758

58-
if (shardingStatus === ShardingStatuses.SHARDING) {
59+
if (
60+
shardingStatus === ShardingStatuses.SHARDING ||
61+
shardingStatus === ShardingStatuses.CANCELLING_SHARDING
62+
) {
5963
return <ShardingState />;
6064
}
6165

@@ -73,7 +77,9 @@ export function GlobalWrites({ shardingStatus }: GlobalWritesProps) {
7377
return (
7478
<div className={containerStyles}>
7579
<WorkspaceContainer className={workspaceContentStyles}>
76-
<ShardingStateView shardingStatus={shardingStatus} />
80+
<ConfirmationModalArea>
81+
<ShardingStateView shardingStatus={shardingStatus} />
82+
</ConfirmationModalArea>
7783
</WorkspaceContainer>
7884
</div>
7985
);
Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,52 @@
11
import React from 'react';
22
import { expect } from 'chai';
3-
import { screen } from '@mongodb-js/testing-library-compass';
3+
import { screen, userEvent } from '@mongodb-js/testing-library-compass';
44
import { ShardingState } from './sharding';
55
import { renderWithStore } from '../../../tests/create-store';
6+
import Sinon from 'sinon';
67

78
function renderWithProps(
89
props?: Partial<React.ComponentProps<typeof ShardingState>>
910
) {
10-
return renderWithStore(<ShardingState {...props} />);
11+
return renderWithStore(
12+
<ShardingState
13+
onCancelSharding={() => {}}
14+
isCancellingSharding={false}
15+
{...props}
16+
/>
17+
);
1118
}
1219

1320
describe('Sharding', function () {
1421
it('renders the info banner', async function () {
1522
await renderWithProps();
1623
expect(screen.getByRole('alert')).to.exist;
1724
});
25+
26+
it('sharding request can be cancelled', async function () {
27+
const onCancelSharding = Sinon.spy();
28+
await renderWithProps({
29+
onCancelSharding,
30+
});
31+
const btn = screen.getByRole('button', { name: 'Cancel Request' });
32+
expect(btn).to.be.visible;
33+
34+
userEvent.click(btn);
35+
36+
expect(onCancelSharding).to.have.been.calledOnce;
37+
});
38+
39+
it('when cancelling is in progress, it cannot be triggered again', async function () {
40+
const onCancelSharding = Sinon.spy();
41+
await renderWithProps({
42+
isCancellingSharding: true,
43+
onCancelSharding,
44+
});
45+
const btn = screen.getByTestId('cancel-sharding-btn');
46+
expect(btn.getAttribute('aria-disabled')).to.equal('true');
47+
48+
userEvent.click(btn);
49+
50+
expect(onCancelSharding).not.to.have.been.calledOnce;
51+
});
1852
});

packages/compass-global-writes/src/components/states/sharding.tsx

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import {
33
Banner,
44
BannerVariant,
55
Body,
6+
Button,
67
css,
78
Link,
89
spacing,
910
} from '@mongodb-js/compass-components';
1011
import { connect } from 'react-redux';
12+
import {
13+
cancelSharding,
14+
type RootState,
15+
ShardingStatuses,
16+
} from '../../store/reducer';
1117

1218
const nbsp = '\u00a0';
1319

@@ -17,12 +23,33 @@ const containerStyles = css({
1723
gap: spacing[400],
1824
});
1925

20-
export function ShardingState() {
26+
const btnStyles = css({
27+
float: 'right',
28+
height: spacing[600],
29+
});
30+
31+
interface ShardingStateProps {
32+
isCancellingSharding: boolean;
33+
onCancelSharding: () => void;
34+
}
35+
36+
export function ShardingState({
37+
isCancellingSharding,
38+
onCancelSharding,
39+
}: ShardingStateProps) {
2140
return (
2241
<div className={containerStyles}>
2342
<Banner variant={BannerVariant.Info}>
2443
<strong>Sharding your collection …</strong>
2544
{nbsp}this should not take too long.
45+
<Button
46+
className={btnStyles}
47+
data-testid="cancel-sharding-btn"
48+
onClick={onCancelSharding}
49+
isLoading={isCancellingSharding}
50+
>
51+
Cancel Request
52+
</Button>
2653
</Banner>
2754
<Body>
2855
Once your collection is sharded, this tab will show instructions on
@@ -39,4 +66,11 @@ export function ShardingState() {
3966
);
4067
}
4168

42-
export default connect()(ShardingState);
69+
export default connect(
70+
(state: RootState) => ({
71+
isCancellingSharding: state.status === ShardingStatuses.CANCELLING_SHARDING,
72+
}),
73+
{
74+
onCancelSharding: cancelSharding,
75+
}
76+
)(ShardingState);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { expect } from 'chai';
3+
import { PluginTitle } from './plugin-title';
4+
import { render, screen } from '@mongodb-js/testing-library-compass';
5+
6+
describe('PluginTitle', function () {
7+
it('Renders a warning', function () {
8+
render(<PluginTitle showWarning={true} />);
9+
expect(screen.getByLabelText('warning')).to.be.visible;
10+
});
11+
12+
it('Does not render a warning', function () {
13+
render(<PluginTitle showWarning={false} />);
14+
expect(screen.queryByLabelText('warning')).not.to.exist;
15+
});
16+
});

packages/compass-global-writes/src/plugin-title.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const iconStylesDark = css({
3030
color: palette.yellow.base,
3131
});
3232

33-
const PluginTitle = ({ showWarning }: { showWarning: boolean }) => {
33+
export const PluginTitle = ({ showWarning }: { showWarning: boolean }) => {
3434
const darkMode = useDarkMode();
3535
return (
3636
<div data-testid="global-writes-tab-title" className={containerStyles}>
@@ -50,6 +50,7 @@ const PluginTitle = ({ showWarning }: { showWarning: boolean }) => {
5050
>
5151
<Icon
5252
glyph="ImportantWithCircle"
53+
aria-label="warning"
5354
className={cx(
5455
warningIconStyles,
5556
iconStylesLight,

packages/compass-global-writes/src/services/atlas-global-writes-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export type ClusterDetailsApiResponse = {
4242
replicationSpecList: ReplicationItem[];
4343
};
4444

45-
type AutomationAgentProcess = {
45+
export type AutomationAgentProcess = {
4646
statusType: string;
4747
workingOnShort: string;
4848
errorText: string;

0 commit comments

Comments
 (0)