Skip to content

Commit 6b2fc4d

Browse files
authored
feat(compass-welcome): show connection progress on welcome COMPASS-9634 (#7258)
1 parent 58e9647 commit 6b2fc4d

File tree

4 files changed

+368
-31
lines changed

4 files changed

+368
-31
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import React from 'react';
2+
import {
3+
Icon,
4+
SpinLoader,
5+
Description,
6+
spacing,
7+
css,
8+
palette,
9+
keyframes,
10+
} from '@mongodb-js/compass-components';
11+
import {
12+
useConnectionIds,
13+
useConnectionInfoForId,
14+
useConnectionForId,
15+
} from '@mongodb-js/compass-connections/provider';
16+
17+
/**
18+
* Returns a list of connection ids for connections that are in an active state
19+
* (connecting, connected, or failed). This is useful for components that need
20+
* to show activity status without subscribing to the full connection state.
21+
*/
22+
export function useActiveConnectionIds() {
23+
return useConnectionIds(
24+
(connection) =>
25+
connection.status === 'connecting' ||
26+
connection.status === 'connected' ||
27+
connection.status === 'failed'
28+
);
29+
}
30+
31+
const connectionListStyles = css({
32+
marginTop: spacing[400],
33+
listStyle: 'none',
34+
padding: 0,
35+
// Save space to avoid jumping
36+
// items are about: spacing[200] (margin) + ~24px (icon/text height)
37+
minHeight: `${spacing[200] * 3 + 72}px`,
38+
});
39+
40+
const fadeInFromAbove = keyframes({
41+
'0%': {
42+
opacity: 0,
43+
transform: `translateY(-${spacing[100]}px)`,
44+
},
45+
'100%': {
46+
opacity: 1,
47+
transform: 'translateY(0)',
48+
},
49+
});
50+
51+
const connectionItemStyles = css({
52+
marginBottom: spacing[200],
53+
display: 'flex',
54+
alignItems: 'center',
55+
gap: spacing[200],
56+
animation: `${fadeInFromAbove} 300ms ease-out`,
57+
});
58+
59+
interface ConnectionStatusProps {
60+
connectionId: string;
61+
}
62+
63+
function ConnectionStatus({ connectionId }: ConnectionStatusProps) {
64+
const connectionInfo = useConnectionInfoForId(connectionId);
65+
const connection = useConnectionForId(connectionId);
66+
67+
if (!connectionInfo || !connection) {
68+
return null;
69+
}
70+
71+
const connectionName = connectionInfo.title;
72+
const status = connection.status;
73+
74+
const { icon, statusText } =
75+
status === 'connected'
76+
? {
77+
icon: (
78+
<Icon glyph="Checkmark" size="small" color={palette.green.dark2} />
79+
),
80+
statusText: `Connected to ${connectionName}`,
81+
}
82+
: status === 'failed'
83+
? {
84+
icon: <Icon glyph="X" size="small" color={palette.red.base} />,
85+
statusText: `Failed to connect to ${connectionName}`,
86+
}
87+
: {
88+
icon: <SpinLoader size={16} />,
89+
statusText: `Connecting to ${connectionName}`,
90+
};
91+
92+
return (
93+
<li className={connectionItemStyles}>
94+
{icon}
95+
<Description>{statusText}</Description>
96+
</li>
97+
);
98+
}
99+
100+
export default function ConnectionList() {
101+
const activeConnectionIds = useActiveConnectionIds();
102+
103+
if (activeConnectionIds.length === 0) {
104+
return null;
105+
}
106+
107+
return (
108+
<ul className={connectionListStyles}>
109+
{activeConnectionIds.map((connectionId) => (
110+
<ConnectionStatus key={connectionId} connectionId={connectionId} />
111+
))}
112+
</ul>
113+
);
114+
}

packages/compass-welcome/src/components/desktop-welcome-tab.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
1919
import { useConnectionActions } from '@mongodb-js/compass-connections/provider';
2020
import { usePreference } from 'compass-preferences-model/provider';
21-
import { WelcomeTabImage } from './welcome-image';
21+
import { WelcomeTabImage, WelcomePlugImage } from './welcome-image';
22+
import ConnectionList, { useActiveConnectionIds } from './connection-list';
2223

2324
const sectionContainerStyles = css({
2425
margin: 0,
@@ -126,12 +127,14 @@ export default function DesktopWelcomeTab() {
126127
'enableCreatingNewConnections'
127128
);
128129

130+
const activeConnectionIds = useActiveConnectionIds();
131+
129132
return (
130133
<div className={welcomeTabStyles}>
131-
<WelcomeTabImage />
134+
{activeConnectionIds.length ? <WelcomePlugImage /> : <WelcomeTabImage />}
132135
<div>
133136
<H3>Welcome to MongoDB Compass</H3>
134-
{enableCreatingNewConnections && (
137+
{!activeConnectionIds.length && enableCreatingNewConnections ? (
135138
<>
136139
<Body>To get started, connect to an existing server or</Body>
137140
<Button
@@ -145,7 +148,9 @@ export default function DesktopWelcomeTab() {
145148
</Button>
146149
<AtlasHelpSection />
147150
</>
148-
)}
151+
) : activeConnectionIds.length ? (
152+
<ConnectionList />
153+
) : null}
149154
</div>
150155
</div>
151156
);

packages/compass-welcome/src/components/web-welcome-tab.tsx

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
Link,
1010
} from '@mongodb-js/compass-components';
1111
import { useConnectionIds } from '@mongodb-js/compass-connections/provider';
12-
import { WelcomeTabImage } from './welcome-image';
12+
import { WelcomePlugImage, WelcomeTabImage } from './welcome-image';
13+
import ConnectionList, { useActiveConnectionIds } from './connection-list';
1314

1415
const welcomeTabStyles = css({
1516
display: 'flex',
@@ -28,36 +29,41 @@ const contentBodyStyles = css({
2829

2930
export default function WebWelcomeTab() {
3031
const numConnections = useConnectionIds().length;
32+
const activeConnectionIds = useActiveConnectionIds();
33+
3134
return (
3235
<div className={welcomeTabStyles}>
33-
<WelcomeTabImage />
36+
{activeConnectionIds.length ? <WelcomePlugImage /> : <WelcomeTabImage />}
3437
<div>
3538
<H3>Welcome! Explore your data</H3>
36-
<div className={contentBodyStyles}>
37-
<Body>
38-
{numConnections === 0
39-
? 'To get started, create your first MongoDB Cluster.'
40-
: 'To get started, connect to an existing cluster.'}
41-
</Body>
42-
{numConnections === 0 && (
43-
<>
44-
<Button
45-
as={Link}
46-
data-testid="add-new-atlas-cluster-button"
47-
variant={ButtonVariant.Primary}
48-
href={'#/clusters/starterTemplates'}
49-
>
50-
Create a Cluster
51-
</Button>
52-
<Body>
53-
Need more help?{' '}
54-
<Link href="https://www.mongodb.com/docs/atlas/create-connect-deployments/">
55-
View documentation
56-
</Link>
57-
</Body>
58-
</>
59-
)}
60-
</div>
39+
{!activeConnectionIds.length && (
40+
<div className={contentBodyStyles}>
41+
<Body>
42+
{numConnections === 0
43+
? 'To get started, create your first MongoDB Cluster.'
44+
: 'To get started, connect to an existing cluster.'}
45+
</Body>
46+
{numConnections === 0 && (
47+
<>
48+
<Button
49+
as={Link}
50+
data-testid="add-new-atlas-cluster-button"
51+
variant={ButtonVariant.Primary}
52+
href={'#/clusters/starterTemplates'}
53+
>
54+
Create a Cluster
55+
</Button>
56+
<Body>
57+
Need more help?{' '}
58+
<Link href="https://www.mongodb.com/docs/atlas/create-connect-deployments/">
59+
View documentation
60+
</Link>
61+
</Body>
62+
</>
63+
)}
64+
</div>
65+
)}
66+
{activeConnectionIds.length > 0 ? <ConnectionList /> : null}
6167
</div>
6268
</div>
6369
);

0 commit comments

Comments
 (0)