From 2d2a84b0e811044064e04ad25c121baeaccd082d Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Wed, 22 Dec 2021 17:14:57 +0100 Subject: [PATCH 01/10] adds connection menu to duplicate and remove --- .../connection-list/connection-list.tsx | 8 ++ .../connection-list/connection-menu.spec.tsx | 104 +++++++++++++++++- .../connection-list/connection-menu.tsx | 25 ++++- .../components/connection-list/connection.tsx | 9 +- .../src/components/connections.tsx | 4 + .../src/components/resizeable-sidebar.tsx | 6 + .../src/stores/connections-store.ts | 36 +++++- 7 files changed, 183 insertions(+), 9 deletions(-) diff --git a/packages/connections/src/components/connection-list/connection-list.tsx b/packages/connections/src/components/connection-list/connection-list.tsx index 4b04ef7b5e1..e3a8eaa5b0d 100644 --- a/packages/connections/src/components/connection-list/connection-list.tsx +++ b/packages/connections/src/components/connection-list/connection-list.tsx @@ -142,6 +142,8 @@ function ConnectionList({ setActiveConnectionId, onDoubleClick, removeAllRecentsConnections, + duplicateConnection, + removeConnection }: { activeConnectionId?: string; connections: ConnectionInfo[]; @@ -149,6 +151,8 @@ function ConnectionList({ setActiveConnectionId: (connectionId?: string) => void; onDoubleClick: (connectionInfo: ConnectionInfo) => void; removeAllRecentsConnections: () => void; + duplicateConnection: (connectionInfo: ConnectionInfo) => void; + removeConnection: (connectionInfo: ConnectionInfo) => void; }): React.ReactElement { const [recentHeaderHover, setRecentHover] = useState(false); const favoriteConnections = connections @@ -208,6 +212,8 @@ function ConnectionList({ connectionInfo={connectionInfo} onClick={() => setActiveConnectionId(connectionInfo.id)} onDoubleClick={onDoubleClick} + removeConnection={removeConnection} + duplicateConnection={duplicateConnection} /> ))} @@ -243,6 +249,8 @@ function ConnectionList({ connectionInfo={connectionInfo} onClick={() => setActiveConnectionId(connectionInfo.id)} onDoubleClick={onDoubleClick} + removeConnection={removeConnection} + duplicateConnection={duplicateConnection} /> ))} diff --git a/packages/connections/src/components/connection-list/connection-menu.spec.tsx b/packages/connections/src/components/connection-list/connection-menu.spec.tsx index 13748a62668..5958a21199b 100644 --- a/packages/connections/src/components/connection-list/connection-menu.spec.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.spec.tsx @@ -4,11 +4,18 @@ import { expect } from 'chai'; import sinon from 'sinon'; import ConnectionMenu from './connection-menu'; +import { ConnectionInfo } from 'mongodb-data-service' describe('ConnectionMenu Component', function () { - describe('when rendered', function () { + describe('on non-favorite item', function() { beforeEach(function () { - render(); + const connectionInfo: ConnectionInfo = { + id: 'test-id', + connectionOptions: { + connectionString: 'mongodb://kaleesi', + } + } + render( true} removeConnection={() => true} connectionInfo={connectionInfo} iconColor='#EAEAEA'/>); }); it('shows a button', function () { @@ -17,6 +24,55 @@ describe('ConnectionMenu Component', function () { it('does not show the menu items', function () { expect(screen.queryByText('Copy Connection String')).to.not.exist; + expect(screen.queryByText('Duplicate')).to.not.exist; + expect(screen.queryByText('Remove')).to.not.exist; + }); + + describe('when clicked', function () { + beforeEach(function () { + const button = screen.getByRole('button'); + + fireEvent( + button, + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + }); + + it('shows the menu items without the "Duplicate" option', function () { + expect(screen.getByText('Copy Connection String')).to.be.visible; + expect(screen.queryByText('Duplicate')).to.throw; + expect(screen.getByText('Remove')).to.be.visible; + }); + }); + }) + describe('on favorite item', function () { + beforeEach(function () { + const connectionInfo: ConnectionInfo = { + id: 'test-id', + favorite: { + name: 'First Server' + }, + connectionOptions: { + connectionString: 'mongodb://kaleesi', + } + + } + render( true} removeConnection={() => true} connectionInfo={connectionInfo} iconColor='#EAEAEA'/>); + + + }); + + it('shows a button', function () { + expect(screen.getByRole('button')).to.be.visible; + }); + + it('does not show the menu items', function () { + expect(screen.queryByText('Copy Connection String')).to.not.exist; + expect(screen.queryByText('Duplicate')).to.not.exist; + expect(screen.queryByText('Remove')).to.not.exist; }); describe('when clicked', function () { @@ -34,6 +90,8 @@ describe('ConnectionMenu Component', function () { it('shows the menu items', function () { expect(screen.getByText('Copy Connection String')).to.be.visible; + expect(screen.getByText('Duplicate')).to.be.visible; + expect(screen.getByText('Remove')).to.be.visible; }); describe('when copy connection is clicked', function () { @@ -174,4 +232,46 @@ describe('ConnectionMenu Component', function () { }); }); }); + describe('function calls', function() { + it('should call the removeConnection function', function() { + const connectionInfo: ConnectionInfo = { + id: 'test-id', + favorite: { + name: 'First Server' + }, + connectionOptions: { + connectionString: 'mongodb://kaleesi', + } + } + const mockDuplicateConnection = sinon.fake.resolves(null); + const mockRemoveConnection = sinon.fake.resolves(null); + render(); + + fireEvent( + screen.getByRole('button'), + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + const duplicateConnectionButton = screen.getByText('Duplicate'); + fireEvent( + duplicateConnectionButton, + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + const removeConnectionButton = screen.getByText('Remove'); + fireEvent( + removeConnectionButton, + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + expect(mockDuplicateConnection.called).to.equal(true); + expect(mockRemoveConnection.called).to.equal(true); + }) + }) }); diff --git a/packages/connections/src/components/connection-list/connection-menu.tsx b/packages/connections/src/components/connection-list/connection-menu.tsx index f4580eafed5..c868629ce1a 100644 --- a/packages/connections/src/components/connection-list/connection-menu.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useReducer } from 'react'; +import React, { useEffect, useRef, useReducer, useState } from 'react'; import { IconButton, Icon, @@ -10,7 +10,7 @@ import { css, cx, } from '@mongodb-js/compass-components'; - +import { ConnectionInfo } from 'mongodb-data-service'; const dropdownButtonStyles = css({ position: 'absolute', right: spacing[1], @@ -74,15 +74,22 @@ function reducer(state: State, action: Action): State { function ConnectionMenu({ connectionString, iconColor, + connectionInfo, + duplicateConnection, + removeConnection }: { connectionString: string; iconColor: string; + connectionInfo: ConnectionInfo; + duplicateConnection: (connectionInfo: ConnectionInfo) => void; + removeConnection: (connectionInfo: ConnectionInfo) => void; + }): React.ReactElement { const [{ error, toastOpen, toastVariant }, dispatch] = useReducer(reducer, { ...defaultToastState, }); const toastHideTimeout = useRef | null>(null); - + const [menuIsOpen, setMenuIsOpen] = useState(false); function startToastHideTimeout() { if (toastHideTimeout.current) { // If we're currently showing a toast, cancel that previous timeout. @@ -164,10 +171,20 @@ function ConnectionMenu({ } + open={menuIsOpen} + setOpen={setMenuIsOpen} > - copyConnectionString(connectionString)}> + { await copyConnectionString(connectionString); setMenuIsOpen(false)} }> Copy Connection String + { connectionInfo.favorite && + { duplicateConnection(connectionInfo); setMenuIsOpen(false )} }> + Duplicate + + } + removeConnection(connectionInfo)}> + Remove + ); diff --git a/packages/connections/src/components/connection-list/connection.tsx b/packages/connections/src/components/connection-list/connection.tsx index 2c7bddde418..a800a0ba0f7 100644 --- a/packages/connections/src/components/connection-list/connection.tsx +++ b/packages/connections/src/components/connection-list/connection.tsx @@ -126,11 +126,15 @@ function Connection({ connectionInfo, onClick, onDoubleClick, + duplicateConnection, + removeConnection }: { isActive: boolean; connectionInfo: ConnectionInfo; onClick: () => void; onDoubleClick: (connectionInfo: ConnectionInfo) => void; + duplicateConnection: (connectionInfo: ConnectionInfo) => void; + removeConnection: (connectionInfo: ConnectionInfo) => void; }): React.ReactElement { const connectionTitle = getConnectionTitle(connectionInfo); const { @@ -189,7 +193,10 @@ function Connection({ ? uiColors.gray.dark3 : uiColors.white } - connectionString={connectionString} + connectionString={connectionInfo.connectionOptions.connectionString} + connectionInfo={connectionInfo} + duplicateConnection={duplicateConnection} + removeConnection={removeConnection} /> diff --git a/packages/connections/src/components/connections.tsx b/packages/connections/src/components/connections.tsx index 8f4ab0f1f19..1630b4858c1 100644 --- a/packages/connections/src/components/connections.tsx +++ b/packages/connections/src/components/connections.tsx @@ -77,6 +77,8 @@ function Connections({ hideStoreConnectionError, setActiveConnectionById, removeAllRecentsConnections, + removeConnection, + duplicateConnection }, ] = useConnections(onConnected, connectionStorage, connectFn); @@ -94,6 +96,8 @@ function Connections({ setActiveConnectionId={setActiveConnectionById} onConnectionDoubleClicked={connect} removeAllRecentsConnections={removeAllRecentsConnections} + removeConnection={removeConnection} + duplicateConnection={duplicateConnection} />
{storeConnectionError && ( diff --git a/packages/connections/src/components/resizeable-sidebar.tsx b/packages/connections/src/components/resizeable-sidebar.tsx index 7dafab5e3bd..32bc73ceb9c 100644 --- a/packages/connections/src/components/resizeable-sidebar.tsx +++ b/packages/connections/src/components/resizeable-sidebar.tsx @@ -36,6 +36,8 @@ function ResizableSidebar({ setActiveConnectionId, onConnectionDoubleClicked, removeAllRecentsConnections, + duplicateConnection, + removeConnection }: { activeConnectionId?: string; connections: ConnectionInfo[]; @@ -43,6 +45,8 @@ function ResizableSidebar({ setActiveConnectionId: (newConnectionId?: string) => void; onConnectionDoubleClicked: (connectionInfo: ConnectionInfo) => void; removeAllRecentsConnections: () => void; + duplicateConnection: (connectionInfo: ConnectionInfo) => void; + removeConnection: (connectionInfo: ConnectionInfo) => void; }): React.ReactElement { const [width, setWidth] = useState(initialSidebarWidth); @@ -61,6 +65,8 @@ function ResizableSidebar({ setActiveConnectionId={setActiveConnectionId} onDoubleClick={onConnectionDoubleClicked} removeAllRecentsConnections={removeAllRecentsConnections} + removeConnection={removeConnection} + duplicateConnection={duplicateConnection} /> setWidth(newWidth)} diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index 95634a3c4c8..26f2c1a1fcd 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -1,4 +1,3 @@ -import { v4 as uuidv4 } from 'uuid'; import { ConnectionInfo, ConnectionOptions, @@ -17,6 +16,8 @@ import { trackNewConnectionEvent, trackConnectionFailedEvent, } from '../modules/telemetry'; +import { v4 as uuidv4 } from 'uuid'; +import { util } from 'chai'; const debug = debugModule('mongodb-compass:connections:connections-store'); @@ -94,6 +95,9 @@ type Action = | { type: 'set-connections'; connections: ConnectionInfo[]; + } + | { + type: 'refresh-connections'; }; export function connectionsReducer(state: State, action: Action): State { @@ -151,6 +155,10 @@ export function connectionsReducer(state: State, action: Action): State { ...state, connections: action.connections, }; + case 'refresh-connections': + return { + ...state, + }; default: return state; } @@ -191,6 +199,8 @@ export function useConnections( hideStoreConnectionError(): void; setActiveConnectionById(newConnectionId?: string | undefined): void; removeAllRecentsConnections(): void; + duplicateConnection(connectioInfo: ConnectionInfo): void; + removeConnection(connectionInfo: ConnectionInfo): void; } ] { const [state, dispatch]: [State, React.Dispatch] = useReducer( @@ -206,7 +216,6 @@ export function useConnections( async function saveConnectionInfo(connectionInfo: ConnectionInfo) { try { await connectionStorage.save(connectionInfo); - debug(`saved connection with id ${connectionInfo.id || ''}`); } catch (err) { debug( @@ -379,6 +388,29 @@ export function useConnections( }), }); }, + async removeConnection(connectionInfo: ConnectionInfo) { + await connectionStorage.delete(connectionInfo); + dispatch({ + type: 'set-connections', + connections: connections.filter( + (conn) => conn.id !== connectionInfo.id + ), + }); + }, + async duplicateConnection(connectionInfo: ConnectionInfo) { + if (!connectionInfo.favorite) return; + const duplicate: ConnectionInfo = { + ...JSON.parse(JSON.stringify(connectionInfo)), + id: uuidv4(), + }; + duplicate.favorite!.name += ' (copy)'; + + await saveConnectionInfo(duplicate); + dispatch({ + type: 'set-connections', + connections: [...connections, duplicate], + }); + }, }, ]; } From a58f185a927ee3ad6ca3ebe7e5d7dc78d2cb3a4f Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Mon, 10 Jan 2022 09:11:01 +0100 Subject: [PATCH 02/10] linting --- .../connection-list/connection-list.tsx | 2 +- .../connection-list/connection-menu.spec.tsx | 67 ++++++++++++------- .../connection-list/connection-menu.tsx | 21 ++++-- .../components/connection-list/connection.tsx | 2 +- .../src/components/connections.tsx | 2 +- .../src/components/resizeable-sidebar.tsx | 2 +- 6 files changed, 63 insertions(+), 33 deletions(-) diff --git a/packages/connections/src/components/connection-list/connection-list.tsx b/packages/connections/src/components/connection-list/connection-list.tsx index e3a8eaa5b0d..77b03605ffe 100644 --- a/packages/connections/src/components/connection-list/connection-list.tsx +++ b/packages/connections/src/components/connection-list/connection-list.tsx @@ -143,7 +143,7 @@ function ConnectionList({ onDoubleClick, removeAllRecentsConnections, duplicateConnection, - removeConnection + removeConnection, }: { activeConnectionId?: string; connections: ConnectionInfo[]; diff --git a/packages/connections/src/components/connection-list/connection-menu.spec.tsx b/packages/connections/src/components/connection-list/connection-menu.spec.tsx index 5958a21199b..c0b21967dfc 100644 --- a/packages/connections/src/components/connection-list/connection-menu.spec.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.spec.tsx @@ -4,18 +4,26 @@ import { expect } from 'chai'; import sinon from 'sinon'; import ConnectionMenu from './connection-menu'; -import { ConnectionInfo } from 'mongodb-data-service' +import { ConnectionInfo } from 'mongodb-data-service'; describe('ConnectionMenu Component', function () { - describe('on non-favorite item', function() { + describe('on non-favorite item', function () { beforeEach(function () { const connectionInfo: ConnectionInfo = { id: 'test-id', connectionOptions: { connectionString: 'mongodb://kaleesi', - } - } - render( true} removeConnection={() => true} connectionInfo={connectionInfo} iconColor='#EAEAEA'/>); + }, + }; + render( + true} + removeConnection={() => true} + connectionInfo={connectionInfo} + iconColor="#EAEAEA" + /> + ); }); it('shows a button', function () { @@ -47,22 +55,27 @@ describe('ConnectionMenu Component', function () { expect(screen.getByText('Remove')).to.be.visible; }); }); - }) + }); describe('on favorite item', function () { beforeEach(function () { const connectionInfo: ConnectionInfo = { id: 'test-id', favorite: { - name: 'First Server' + name: 'First Server', }, connectionOptions: { connectionString: 'mongodb://kaleesi', - } - - } - render( true} removeConnection={() => true} connectionInfo={connectionInfo} iconColor='#EAEAEA'/>); - - + }, + }; + render( + true} + removeConnection={() => true} + connectionInfo={connectionInfo} + iconColor="#EAEAEA" + /> + ); }); it('shows a button', function () { @@ -232,21 +245,29 @@ describe('ConnectionMenu Component', function () { }); }); }); - describe('function calls', function() { - it('should call the removeConnection function', function() { + describe('function calls', function () { + it('should call the removeConnection function', function () { const connectionInfo: ConnectionInfo = { id: 'test-id', favorite: { - name: 'First Server' + name: 'First Server', }, connectionOptions: { connectionString: 'mongodb://kaleesi', - } - } + }, + }; const mockDuplicateConnection = sinon.fake.resolves(null); const mockRemoveConnection = sinon.fake.resolves(null); - render(); - + render( + + ); + fireEvent( screen.getByRole('button'), new MouseEvent('click', { @@ -270,8 +291,8 @@ describe('ConnectionMenu Component', function () { cancelable: true, }) ); - expect(mockDuplicateConnection.called).to.equal(true); + expect(mockDuplicateConnection.called).to.equal(true); expect(mockRemoveConnection.called).to.equal(true); - }) - }) + }); + }); }); diff --git a/packages/connections/src/components/connection-list/connection-menu.tsx b/packages/connections/src/components/connection-list/connection-menu.tsx index c868629ce1a..654190b81fd 100644 --- a/packages/connections/src/components/connection-list/connection-menu.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.tsx @@ -76,14 +76,13 @@ function ConnectionMenu({ iconColor, connectionInfo, duplicateConnection, - removeConnection + removeConnection, }: { connectionString: string; iconColor: string; connectionInfo: ConnectionInfo; duplicateConnection: (connectionInfo: ConnectionInfo) => void; removeConnection: (connectionInfo: ConnectionInfo) => void; - }): React.ReactElement { const [{ error, toastOpen, toastVariant }, dispatch] = useReducer(reducer, { ...defaultToastState, @@ -174,14 +173,24 @@ function ConnectionMenu({ open={menuIsOpen} setOpen={setMenuIsOpen} > - { await copyConnectionString(connectionString); setMenuIsOpen(false)} }> + { + await copyConnectionString(connectionString); + setMenuIsOpen(false); + }} + > Copy Connection String - { connectionInfo.favorite && - { duplicateConnection(connectionInfo); setMenuIsOpen(false )} }> + {connectionInfo.favorite && ( + { + duplicateConnection(connectionInfo); + setMenuIsOpen(false); + }} + > Duplicate - } + )} removeConnection(connectionInfo)}> Remove diff --git a/packages/connections/src/components/connection-list/connection.tsx b/packages/connections/src/components/connection-list/connection.tsx index a800a0ba0f7..806b49c11ae 100644 --- a/packages/connections/src/components/connection-list/connection.tsx +++ b/packages/connections/src/components/connection-list/connection.tsx @@ -127,7 +127,7 @@ function Connection({ onClick, onDoubleClick, duplicateConnection, - removeConnection + removeConnection, }: { isActive: boolean; connectionInfo: ConnectionInfo; diff --git a/packages/connections/src/components/connections.tsx b/packages/connections/src/components/connections.tsx index 1630b4858c1..327a2127dbc 100644 --- a/packages/connections/src/components/connections.tsx +++ b/packages/connections/src/components/connections.tsx @@ -78,7 +78,7 @@ function Connections({ setActiveConnectionById, removeAllRecentsConnections, removeConnection, - duplicateConnection + duplicateConnection, }, ] = useConnections(onConnected, connectionStorage, connectFn); diff --git a/packages/connections/src/components/resizeable-sidebar.tsx b/packages/connections/src/components/resizeable-sidebar.tsx index 32bc73ceb9c..6589e92c457 100644 --- a/packages/connections/src/components/resizeable-sidebar.tsx +++ b/packages/connections/src/components/resizeable-sidebar.tsx @@ -37,7 +37,7 @@ function ResizableSidebar({ onConnectionDoubleClicked, removeAllRecentsConnections, duplicateConnection, - removeConnection + removeConnection, }: { activeConnectionId?: string; connections: ConnectionInfo[]; From 81b266f3e9210e1435d7f22e9e22ad736e33bbf1 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Wed, 12 Jan 2022 11:47:35 +0100 Subject: [PATCH 03/10] removes refresh-connections action --- packages/connections/src/stores/connections-store.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index 26f2c1a1fcd..9be2f77ae47 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -95,9 +95,6 @@ type Action = | { type: 'set-connections'; connections: ConnectionInfo[]; - } - | { - type: 'refresh-connections'; }; export function connectionsReducer(state: State, action: Action): State { @@ -155,10 +152,6 @@ export function connectionsReducer(state: State, action: Action): State { ...state, connections: action.connections, }; - case 'refresh-connections': - return { - ...state, - }; default: return state; } From 2ec787f46b5ee8a6449c7b2b6fa21a6a48569d36 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Wed, 12 Jan 2022 11:49:43 +0100 Subject: [PATCH 04/10] separates function call tests --- .../connection-list/connection-menu.spec.tsx | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/packages/connections/src/components/connection-list/connection-menu.spec.tsx b/packages/connections/src/components/connection-list/connection-menu.spec.tsx index c0b21967dfc..88331792744 100644 --- a/packages/connections/src/components/connection-list/connection-menu.spec.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.spec.tsx @@ -256,12 +256,11 @@ describe('ConnectionMenu Component', function () { connectionString: 'mongodb://kaleesi', }, }; - const mockDuplicateConnection = sinon.fake.resolves(null); const mockRemoveConnection = sinon.fake.resolves(null); render( true} removeConnection={mockRemoveConnection} connectionInfo={connectionInfo} iconColor="#EAEAEA" @@ -275,24 +274,54 @@ describe('ConnectionMenu Component', function () { cancelable: true, }) ); - const duplicateConnectionButton = screen.getByText('Duplicate'); + + const removeConnectionButton = screen.getByText('Remove'); fireEvent( - duplicateConnectionButton, + removeConnectionButton, new MouseEvent('click', { bubbles: true, cancelable: true, }) ); - const removeConnectionButton = screen.getByText('Remove'); + expect(mockRemoveConnection.called).to.equal(true); + }); + it('should call the duplicateConnection function', function () { + const connectionInfo: ConnectionInfo = { + id: 'test-id', + favorite: { + name: 'First Server', + }, + connectionOptions: { + connectionString: 'mongodb://kaleesi', + }, + }; + const mockDuplicateConnection = sinon.fake.resolves(null); + render( + true} + connectionInfo={connectionInfo} + iconColor="#EAEAEA" + /> + ); + fireEvent( - removeConnectionButton, + screen.getByRole('button'), + new MouseEvent('click', { + bubbles: true, + cancelable: true, + }) + ); + const duplicateConnectionButton = screen.getByText('Duplicate'); + fireEvent( + duplicateConnectionButton, new MouseEvent('click', { bubbles: true, cancelable: true, }) ); expect(mockDuplicateConnection.called).to.equal(true); - expect(mockRemoveConnection.called).to.equal(true); }); }); }); From a98f4f607c4a738e135271a4ebc661ed91fc309f Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Fri, 14 Jan 2022 11:56:13 +0100 Subject: [PATCH 05/10] selects current duplicated connection --- .../connection-list/connection-menu.spec.tsx | 2 +- packages/connections/src/stores/connections-store.ts | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/connections/src/components/connection-list/connection-menu.spec.tsx b/packages/connections/src/components/connection-list/connection-menu.spec.tsx index 88331792744..c1500cc700e 100644 --- a/packages/connections/src/components/connection-list/connection-menu.spec.tsx +++ b/packages/connections/src/components/connection-list/connection-menu.spec.tsx @@ -274,7 +274,7 @@ describe('ConnectionMenu Component', function () { cancelable: true, }) ); - + const removeConnectionButton = screen.getByText('Remove'); fireEvent( removeConnectionButton, diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index 9be2f77ae47..06a46c42dff 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -389,9 +389,14 @@ export function useConnections( (conn) => conn.id !== connectionInfo.id ), }); + const nextActiveConnection = createNewConnectionInfo(); + dispatch({ + type: 'set-active-connection', + connectionId: nextActiveConnection.id, + connectionInfo: nextActiveConnection, + }); }, async duplicateConnection(connectionInfo: ConnectionInfo) { - if (!connectionInfo.favorite) return; const duplicate: ConnectionInfo = { ...JSON.parse(JSON.stringify(connectionInfo)), id: uuidv4(), @@ -403,6 +408,11 @@ export function useConnections( type: 'set-connections', connections: [...connections, duplicate], }); + dispatch({ + type: 'set-active-connection', + connectionId: duplicate.id, + connectionInfo: duplicate, + }); }, }, ]; From 679807e6aaa6f212b69bc97ad85ee9a450d2e2a1 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Mon, 17 Jan 2022 16:53:29 +0100 Subject: [PATCH 06/10] removes unused vars --- packages/connections/src/stores/connections-store.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index 06a46c42dff..6d1382db3cd 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -17,7 +17,6 @@ import { trackConnectionFailedEvent, } from '../modules/telemetry'; import { v4 as uuidv4 } from 'uuid'; -import { util } from 'chai'; const debug = debugModule('mongodb-compass:connections:connections-store'); From 3147e702070473c7c88cec0648c45bf128ed5347 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Tue, 18 Jan 2022 08:35:16 +0100 Subject: [PATCH 07/10] adds action to set connections and select --- .../src/stores/connections-store.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index 6d1382db3cd..ef8fa59702e 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -94,6 +94,11 @@ type Action = | { type: 'set-connections'; connections: ConnectionInfo[]; + } + | { + type: 'set-connections-and-select'; + connections: ConnectionInfo[]; + activeConnectionInfo: ConnectionInfo; }; export function connectionsReducer(state: State, action: Action): State { @@ -151,6 +156,13 @@ export function connectionsReducer(state: State, action: Action): State { ...state, connections: action.connections, }; + case 'set-connections-and-select': + return { + ...state, + connections: action.connections, + activeConnectionId: action.activeConnectionInfo.id, + activeConnectionInfo: action.activeConnectionInfo, + }; default: return state; } @@ -404,13 +416,9 @@ export function useConnections( await saveConnectionInfo(duplicate); dispatch({ - type: 'set-connections', + type: 'set-connections-and-select', connections: [...connections, duplicate], - }); - dispatch({ - type: 'set-active-connection', - connectionId: duplicate.id, - connectionInfo: duplicate, + activeConnectionInfo: duplicate, }); }, }, From b2464299cc5e73c6222c4ddaf51f4c1bf7ee3f27 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Tue, 18 Jan 2022 08:38:27 +0100 Subject: [PATCH 08/10] selects new connection only if removing current active connection --- .../connections/src/stores/connections-store.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index ef8fa59702e..cdb943e4feb 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -211,7 +211,8 @@ export function useConnections( connectionsReducer, defaultConnectionsState() ); - const { isConnected, connectionAttempt, connections } = state; + const { isConnected, connectionAttempt, connections, activeConnectionId } = + state; const connectingConnectionAttempt = useRef(); const connectedConnectionInfo = useRef(); @@ -400,12 +401,14 @@ export function useConnections( (conn) => conn.id !== connectionInfo.id ), }); - const nextActiveConnection = createNewConnectionInfo(); - dispatch({ - type: 'set-active-connection', - connectionId: nextActiveConnection.id, - connectionInfo: nextActiveConnection, - }); + if (activeConnectionId === connectionInfo.id) { + const nextActiveConnection = createNewConnectionInfo(); + dispatch({ + type: 'set-active-connection', + connectionId: nextActiveConnection.id, + connectionInfo: nextActiveConnection, + }); + } }, async duplicateConnection(connectionInfo: ConnectionInfo) { const duplicate: ConnectionInfo = { From 92509d3e3d2e38bc626c0a2e27ab32a4137bf530 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Tue, 18 Jan 2022 16:15:51 +0100 Subject: [PATCH 09/10] uses cloneDeep to duplicate connectionInfo --- packages/connections/src/stores/connections-store.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/connections/src/stores/connections-store.ts b/packages/connections/src/stores/connections-store.ts index cdb943e4feb..0b2aacde24c 100644 --- a/packages/connections/src/stores/connections-store.ts +++ b/packages/connections/src/stores/connections-store.ts @@ -17,7 +17,7 @@ import { trackConnectionFailedEvent, } from '../modules/telemetry'; import { v4 as uuidv4 } from 'uuid'; - +import { cloneDeep } from 'lodash'; const debug = debugModule('mongodb-compass:connections:connections-store'); export function createNewConnectionInfo(): ConnectionInfo { @@ -412,7 +412,7 @@ export function useConnections( }, async duplicateConnection(connectionInfo: ConnectionInfo) { const duplicate: ConnectionInfo = { - ...JSON.parse(JSON.stringify(connectionInfo)), + ...cloneDeep(connectionInfo), id: uuidv4(), }; duplicate.favorite!.name += ' (copy)'; From c302bbc26793cea7d66f4a036d3be415c71e1797 Mon Sep 17 00:00:00 2001 From: Leonardo Rossi Date: Wed, 19 Jan 2022 15:36:31 +0100 Subject: [PATCH 10/10] adds lodash as dependency --- package-lock.json | 2 ++ packages/connections/package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/package-lock.json b/package-lock.json index b878ce29b19..0d46ca0d3ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95286,6 +95286,7 @@ "@mongodb-js/compass-logging": "^0.6.1", "@mongodb-js/connect-form": "^0.4.1", "debug": "^4.2.0", + "lodash": "^4.17.21", "mongodb": "^4.3.0", "react": "^16.14.0", "react-dom": "^16.14.0", @@ -115145,6 +115146,7 @@ "debug": "^4.2.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", + "lodash": "*", "mocha": "^8.4.0", "mongodb": "^4.3.0", "mongodb-build-info": "^1.3.0", diff --git a/packages/connections/package.json b/packages/connections/package.json index d605c106743..57bd4ad9031 100644 --- a/packages/connections/package.json +++ b/packages/connections/package.json @@ -57,6 +57,7 @@ "@mongodb-js/compass-logging": "^0.6.1", "@mongodb-js/connect-form": "^0.4.1", "debug": "^4.2.0", + "lodash": "^4.17.21", "mongodb": "^4.3.0", "react": "^16.14.0", "react-dom": "^16.14.0",