Skip to content

Commit d3a1275

Browse files
authored
feat(connections): show list of legacy connections COMPASS-7081 (#4714)
1 parent 0ae421d commit d3a1275

File tree

6 files changed

+68
-35
lines changed

6 files changed

+68
-35
lines changed

packages/compass-connections/src/components/connections.spec.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function getMockConnectionStorage(mockConnections: ConnectionInfo[]) {
2424
loadAll: () => {
2525
return Promise.resolve(mockConnections);
2626
},
27-
hasLegacyConnections: () => Promise.resolve(false),
27+
getLegacyConnections: () => Promise.resolve([]),
2828
save: () => Promise.resolve(),
2929
delete: () => Promise.resolve(),
3030
load: (id: string) =>
@@ -448,7 +448,9 @@ describe('Connections Component', function () {
448448
context('when user has any legacy connection', function () {
449449
it('shows modal', async function () {
450450
const mockStorage = getMockConnectionStorage([]);
451-
sinon.stub(mockStorage, 'hasLegacyConnections').resolves(true);
451+
sinon
452+
.stub(mockStorage, 'getLegacyConnections')
453+
.resolves([{ name: 'Connection1' }]);
452454
render(
453455
<ToastArea>
454456
<Connections
@@ -458,14 +460,20 @@ describe('Connections Component', function () {
458460
/>
459461
</ToastArea>
460462
);
463+
461464
await waitFor(
462465
() => expect(screen.getByTestId('legacy-connections-modal')).to.exist
463466
);
467+
468+
const modal = screen.getByTestId('legacy-connections-modal');
469+
expect(within(modal).getByText('Connection1')).to.exist;
464470
});
465471

466472
it('does not show modal when user hides it', async function () {
467473
const mockStorage = getMockConnectionStorage([]);
468-
sinon.stub(mockStorage, 'hasLegacyConnections').resolves(true);
474+
sinon
475+
.stub(mockStorage, 'getLegacyConnections')
476+
.resolves([{ name: 'Connection2' }]);
469477
const { rerender } = render(
470478
<ToastArea>
471479
<Connections

packages/compass-connections/src/components/legacy-connections-modal.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ModalFooter,
1212
Checkbox,
1313
Body,
14+
Banner,
1415
} from '@mongodb-js/compass-components';
1516

1617
import type { ConnectionStorage } from '@mongodb-js/connection-storage/renderer';
@@ -20,11 +21,21 @@ const LEGACY_MODAL_STORAGE_KEY = 'hide_legacy_connections_modal';
2021
const listStyle = css({
2122
listStyle: 'decimal',
2223
paddingLeft: spacing[5],
24+
li: {
25+
marginTop: spacing[1],
26+
marginBottom: spacing[1],
27+
},
2328
});
2429

2530
const bodyStyles = css({
26-
paddingTop: spacing[3],
27-
paddingBottom: 0,
31+
display: 'flex',
32+
flexDirection: 'column',
33+
gap: spacing[3],
34+
});
35+
36+
const bannerContentStyles = css({
37+
maxHeight: spacing[6] * 2,
38+
overflowY: 'scroll',
2839
});
2940

3041
const footerStyles = css({
@@ -33,7 +44,7 @@ const footerStyles = css({
3344
});
3445

3546
const useLegacyModel = (connectionStorage: typeof ConnectionStorage) => {
36-
const [isModalOpen, setIsModalOpen] = useState(false);
47+
const [connections, setConnections] = useState<{ name: string }[]>([]);
3748

3849
const [isModalHiddenByUser, setIsModalHiddenByUser] = usePersistedState(
3950
LEGACY_MODAL_STORAGE_KEY,
@@ -42,16 +53,17 @@ const useLegacyModel = (connectionStorage: typeof ConnectionStorage) => {
4253

4354
useEffect(() => {
4455
void connectionStorage
45-
.hasLegacyConnections()
46-
.then((hasLegacyConnections) => setIsModalOpen(hasLegacyConnections));
56+
.getLegacyConnections()
57+
.then((connections) => setConnections(connections));
4758
}, []);
4859

4960
return {
50-
isOpen: isModalOpen && !isModalHiddenByUser,
51-
hideModal: () => setIsModalOpen(false),
61+
isOpen: connections.length > 0 && !isModalHiddenByUser,
62+
connections,
63+
hideModal: () => setConnections([]),
5264
hideModalPermanently: () => {
5365
setIsModalHiddenByUser(true);
54-
setIsModalOpen(false);
66+
setConnections([]);
5567
},
5668
};
5769
};
@@ -62,7 +74,7 @@ export const LegacyConnectionsModal = ({
6274
connectionStorage: typeof ConnectionStorage;
6375
}) => {
6476
const [isHideModalChecked, setIsHideModalChecked] = useState(false);
65-
const { hideModal, hideModalPermanently, isOpen } =
77+
const { hideModal, hideModalPermanently, isOpen, connections } =
6678
useLegacyModel(connectionStorage);
6779

6880
const onCloseModal = useCallback(() => {
@@ -83,8 +95,18 @@ export const LegacyConnectionsModal = ({
8395
<ModalBody className={bodyStyles}>
8496
<Body>
8597
Compass has identified legacy connections that are no longer supported
86-
beyond v1.39.0. To migrate these connections:
98+
beyond v1.39.0.
8799
</Body>
100+
<Banner>
101+
<div className={bannerContentStyles}>
102+
<ul>
103+
{connections.map(({ name }, index) => (
104+
<li key={index}>{name}</li>
105+
))}
106+
</ul>
107+
</div>
108+
</Banner>
109+
<strong>To migrate these connections:</strong>
88110
<ol className={listStyle}>
89111
<li>
90112
<Body>

packages/compass/src/main/application.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ class CompassApplication {
142142
track('Application Launched', async () => {
143143
let hasLegacyConnections: boolean;
144144
try {
145-
hasLegacyConnections = await ConnectionStorage.hasLegacyConnections();
145+
hasLegacyConnections =
146+
(await ConnectionStorage.getLegacyConnections()).length > 0;
146147
} catch (e) {
147148
debug('Failed to check legacy connections', e);
148149
hasLegacyConnections = false;

packages/connection-storage/src/connection-storage.spec.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,15 +350,15 @@ describe('ConnectionStorage', function () {
350350
});
351351
});
352352

353-
describe('hasLegacyConnections', function () {
353+
describe('getLegacyConnections', function () {
354354
it('returns false if there are no legacy connections', async function () {
355355
const connectionInfo = getConnectionInfo();
356356
writeFakeConnection(tmpDir, {
357357
connectionInfo,
358358
});
359-
const hasLegacyConnections =
360-
await ConnectionStorage.hasLegacyConnections();
361-
expect(hasLegacyConnections).to.be.false;
359+
const getLegacyConnections =
360+
await ConnectionStorage.getLegacyConnections();
361+
expect(getLegacyConnections).to.have.lengthOf(0);
362362
});
363363

364364
it('returns false if there are no favorite legacy connections', async function () {
@@ -377,9 +377,9 @@ describe('ConnectionStorage', function () {
377377
})
378378
);
379379

380-
const hasLegacyConnections =
381-
await ConnectionStorage.hasLegacyConnections();
382-
expect(hasLegacyConnections).to.be.false;
380+
const getLegacyConnections =
381+
await ConnectionStorage.getLegacyConnections();
382+
expect(getLegacyConnections).to.have.lengthOf(0);
383383
});
384384

385385
it('returns true if there are favorite legacy connections', async function () {
@@ -392,16 +392,17 @@ describe('ConnectionStorage', function () {
392392
JSON.stringify({
393393
_id,
394394
isFavorite: true,
395+
name: 'Local 1',
395396
hosts: [{ host: 'localhost', port: 27017 }],
396397
readPreference: 'primary',
397398
port: 27017,
398399
hostname: 'localhost',
399400
})
400401
);
401402

402-
const hasLegacyConnections =
403-
await ConnectionStorage.hasLegacyConnections();
404-
expect(hasLegacyConnections).to.be.true;
403+
const getLegacyConnections =
404+
await ConnectionStorage.getLegacyConnections();
405+
expect(getLegacyConnections).to.deep.equal([{ name: 'Local 1' }]);
405406
});
406407
});
407408

packages/connection-storage/src/connection-storage.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class ConnectionStorage {
5050
ipcExpose('ConnectionStorage', this, [
5151
'loadAll',
5252
'load',
53-
'hasLegacyConnections',
53+
'getLegacyConnections',
5454
'save',
5555
'delete',
5656
'deserializeConnections',
@@ -132,20 +132,21 @@ export class ConnectionStorage {
132132
* connection.connectionInfo -> new connection
133133
* connection.isFavorite -> legacy favorite connection
134134
*/
135-
static async hasLegacyConnections({
135+
static async getLegacyConnections({
136136
signal,
137137
}: {
138138
signal?: AbortSignal;
139-
} = {}): Promise<boolean> {
139+
} = {}): Promise<{ name: string }[]> {
140140
throwIfAborted(signal);
141141
try {
142-
return (
143-
(await this.getConnections()).filter(
144-
(x) => !x.connectionInfo && x.isFavorite
145-
).length > 0
142+
const legacyConnections = (await this.getConnections()).filter(
143+
(x) => !x.connectionInfo && x.isFavorite
146144
);
145+
return legacyConnections.map((x) => ({
146+
name: x.name,
147+
}));
147148
} catch (e) {
148-
return false;
149+
return [];
149150
}
150151
}
151152

packages/connection-storage/src/renderer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class ConnectionStorage {
99
typeof ConnectionStorageMain,
1010
| 'loadAll'
1111
| 'load'
12-
| 'hasLegacyConnections'
12+
| 'getLegacyConnections'
1313
| 'save'
1414
| 'delete'
1515
| 'deserializeConnections'
@@ -18,7 +18,7 @@ export class ConnectionStorage {
1818
>('ConnectionStorage', [
1919
'loadAll',
2020
'load',
21-
'hasLegacyConnections',
21+
'getLegacyConnections',
2222
'save',
2323
'delete',
2424
'deserializeConnections',
@@ -28,7 +28,7 @@ export class ConnectionStorage {
2828

2929
static loadAll = this.ipc.loadAll;
3030
static load = this.ipc.load;
31-
static hasLegacyConnections = this.ipc.hasLegacyConnections;
31+
static getLegacyConnections = this.ipc.getLegacyConnections;
3232
static save = this.ipc.save;
3333
static delete = this.ipc.delete;
3434
static deserializeConnections = this.ipc.deserializeConnections;

0 commit comments

Comments
 (0)