Skip to content

Commit d1a53af

Browse files
authored
chore(compass-connections): Move connection modal UI from compass-sidebar to compass-connections COMPASS-8471 (#6508)
* wip * wip * compass-connections plugin component * help * broken * tweak * put the code in the new component * move back * more minimal changes to Home * undo unnecessary change * undo unnecessary change * remove unused dep * test fix * looks like the connection form has to be inside FileInputBackendProvider * better types
1 parent 670c799 commit d1a53af

File tree

9 files changed

+269
-171
lines changed

9 files changed

+269
-171
lines changed

package-lock.json

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import React from 'react';
2+
import { connect as reduxConnect } from '../stores/store-context';
3+
import { ConnectionFormModal } from '@mongodb-js/connection-form';
4+
import type { ConnectionInfo } from '@mongodb-js/connection-storage/provider';
5+
import {
6+
connect,
7+
disconnect,
8+
cancelEditConnection,
9+
saveEditedConnectionInfo,
10+
saveAndConnect,
11+
openSettingsModal,
12+
} from '../stores/connections-store-redux';
13+
14+
import { useConnectionFormPreferences } from '../hooks/use-connection-form-preferences';
15+
16+
import type {
17+
ConnectionId,
18+
ConnectionState,
19+
} from '../stores/connections-store-redux';
20+
21+
function shouldDisableConnectionEditing(connection: ConnectionState): boolean {
22+
return connection.status === 'connected';
23+
}
24+
25+
function mapState({
26+
isEditingNewConnection,
27+
isEditingConnectionInfoModalOpen,
28+
editingConnectionInfoId,
29+
connections,
30+
}: {
31+
isEditingNewConnection: boolean;
32+
isEditingConnectionInfoModalOpen: boolean;
33+
editingConnectionInfoId?: ConnectionId;
34+
connections: {
35+
byId: Record<ConnectionId, ConnectionState>;
36+
};
37+
}) {
38+
const editingConnection = editingConnectionInfoId
39+
? connections.byId[editingConnectionInfoId]
40+
: undefined;
41+
const editingConnectionInfo = editingConnection?.info;
42+
43+
const disableEditingConnectedConnection = editingConnection
44+
? shouldDisableConnectionEditing(editingConnection)
45+
: false;
46+
47+
return {
48+
isOpen: isEditingConnectionInfoModalOpen,
49+
initialConnectionInfo: editingConnectionInfo,
50+
connectionErrorMessage: editingConnection?.error?.message,
51+
disableEditingConnectedConnection,
52+
editingConnectionInfoId,
53+
isEditingNewConnection,
54+
};
55+
}
56+
57+
const mapDispatch = {
58+
connect,
59+
disconnect,
60+
cancelEditConnection,
61+
saveEditedConnectionInfo,
62+
saveAndConnect,
63+
openSettingsModal,
64+
};
65+
66+
type ConnectionModalProps = {
67+
isOpen: boolean;
68+
initialConnectionInfo?: ConnectionInfo;
69+
connectionErrorMessage?: string;
70+
disableEditingConnectedConnection: boolean;
71+
editingConnectionInfoId?: ConnectionId;
72+
isEditingNewConnection: boolean;
73+
connect: (connectionInfo: ConnectionInfo) => Promise<void>;
74+
disconnect: (id: string) => void;
75+
cancelEditConnection: (id: string) => void;
76+
saveEditedConnectionInfo: (connectionInfo: ConnectionInfo) => Promise<void>;
77+
saveAndConnect: (connectionInfo: ConnectionInfo) => Promise<void>;
78+
openSettingsModal: (tab?: string) => void;
79+
};
80+
81+
const ConnectionModal: React.FunctionComponent<ConnectionModalProps> = ({
82+
// pulling initialConnectionInfo out of props to help TypeScript know that it
83+
// is not undefined by the time we render ConnectionFormModal
84+
initialConnectionInfo,
85+
// pulling editingConnectionInfoId and isEditingNewConnection out of props
86+
// because they aren't known to ConnectionFormModal and only get used here.
87+
editingConnectionInfoId,
88+
isEditingNewConnection,
89+
...props
90+
}) => {
91+
const formPreferences = useConnectionFormPreferences();
92+
93+
const {
94+
disableEditingConnectedConnection,
95+
connect,
96+
disconnect,
97+
cancelEditConnection,
98+
saveEditedConnectionInfo,
99+
saveAndConnect,
100+
} = props;
101+
102+
if (!(editingConnectionInfoId && initialConnectionInfo)) {
103+
return null;
104+
}
105+
106+
return (
107+
<ConnectionFormModal
108+
initialConnectionInfo={initialConnectionInfo}
109+
{...props}
110+
{...formPreferences}
111+
onDisconnectClicked={() => disconnect(editingConnectionInfoId)}
112+
setOpen={(newOpen) => {
113+
// This is how leafygreen propagates `X` button click
114+
if (newOpen === false) {
115+
cancelEditConnection(editingConnectionInfoId);
116+
}
117+
}}
118+
onCancel={() => {
119+
cancelEditConnection(editingConnectionInfoId);
120+
}}
121+
onSaveClicked={(connectionInfo) => {
122+
return saveEditedConnectionInfo(connectionInfo);
123+
}}
124+
onConnectClicked={
125+
isEditingNewConnection || disableEditingConnectedConnection
126+
? undefined
127+
: (connectionInfo) => {
128+
void connect(connectionInfo);
129+
}
130+
}
131+
onSaveAndConnectClicked={
132+
disableEditingConnectedConnection
133+
? undefined
134+
: (connectionInfo) => {
135+
void saveAndConnect(connectionInfo);
136+
}
137+
}
138+
/>
139+
);
140+
};
141+
142+
export const ConnectedConnectionModal = reduxConnect(
143+
mapState,
144+
mapDispatch
145+
)(ConnectionModal);
146+
147+
export default ConnectedConnectionModal;

packages/compass-connections/src/index.tsx

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1+
import { preferencesLocator } from 'compass-preferences-model/provider';
12
import { registerHadronPlugin } from 'hadron-app-registry';
2-
import {
3-
autoconnectCheck,
4-
configureStore,
5-
disconnect,
6-
loadConnections,
7-
} from './stores/connections-store-redux';
3+
import type { connect as devtoolsConnect } from 'mongodb-data-service';
84
import React, { useContext, useRef } from 'react';
95
import { createLoggerLocator } from '@mongodb-js/compass-logging/provider';
10-
import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider';
11-
import { preferencesLocator } from 'compass-preferences-model/provider';
6+
import { connectionStorageLocator } from '@mongodb-js/connection-storage/provider';
127
import type {
138
ConnectionInfo,
149
ConnectionStorage,
1510
} from '@mongodb-js/connection-storage/provider';
16-
import { connectionStorageLocator } from '@mongodb-js/connection-storage/provider';
11+
import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider';
12+
import type { ExtraConnectionData as ExtraConnectionDataForTelemetry } from '@mongodb-js/compass-telemetry';
13+
import { ConnectedConnectionModal } from './components/connection-modal';
14+
export { default as SingleConnectionForm } from './components/legacy-connections';
15+
export { LegacyConnectionsModal } from './components/legacy-connections-modal';
16+
import {
17+
autoconnectCheck,
18+
configureStore,
19+
disconnect,
20+
loadConnections,
21+
} from './stores/connections-store-redux';
1722
import {
18-
ConnectionActionsProvider,
1923
ConnectionsStoreContext,
24+
ConnectionActionsProvider,
2025
} from './stores/store-context';
21-
export { default as SingleConnectionForm } from './components/legacy-connections';
22-
export { LegacyConnectionsModal } from './components/legacy-connections-modal';
23-
export { useConnectionFormPreferences } from './hooks/use-connection-form-preferences';
24-
import type { connect as devtoolsConnect } from 'mongodb-data-service';
25-
import type { ExtraConnectionData as ExtraConnectionDataForTelemetry } from '@mongodb-js/compass-telemetry';
2626
export type { ConnectionFeature } from './utils/connection-supports';
2727
export { connectionSupports } from './utils/connection-supports';
2828

@@ -37,7 +37,12 @@ const ConnectionsComponent: React.FunctionComponent<{
3737
connectFn?: typeof devtoolsConnect | undefined;
3838
preloadStorageConnectionInfos?: ConnectionInfo[];
3939
}> = ({ children }) => {
40-
return <ConnectionActionsProvider>{children}</ConnectionActionsProvider>;
40+
return (
41+
<ConnectionActionsProvider>
42+
{children}
43+
<ConnectedConnectionModal />
44+
</ConnectionActionsProvider>
45+
);
4146
};
4247

4348
const CompassConnectionsPlugin = registerHadronPlugin(
@@ -46,7 +51,7 @@ const CompassConnectionsPlugin = registerHadronPlugin(
4651
component: ConnectionsComponent,
4752
activate(
4853
initialProps,
49-
{ logger, preferences, connectionStorage, track },
54+
{ logger, preferences, connectionStorage, track, globalAppRegistry },
5055
{ addCleanup, cleanup }
5156
) {
5257
const store = configureStore(initialProps.preloadStorageConnectionInfos, {
@@ -57,6 +62,7 @@ const CompassConnectionsPlugin = registerHadronPlugin(
5762
getExtraConnectionData: initialProps.onExtraConnectionDataRequest,
5863
appName: initialProps.appName,
5964
connectFn: initialProps.connectFn,
65+
globalAppRegistry,
6066
});
6167

6268
setTimeout(() => {
@@ -106,7 +112,10 @@ export const ConnectFnProvider: React.FunctionComponent<{
106112
};
107113

108114
export default function CompassConnections(
109-
props: Omit<React.ComponentProps<typeof ConnectionsComponent>, 'connectFn'>
115+
props: Omit<
116+
React.ComponentProps<typeof CompassConnectionsPlugin>,
117+
'connectFn'
118+
>
110119
) {
111120
const connectFn = useContext(ConnectFnContext);
112121
return (

packages/compass-connections/src/stores/connections-store-redux.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type AppRegistry from 'hadron-app-registry';
12
import type { Reducer, AnyAction, Action } from 'redux';
23
import { createStore, applyMiddleware } from 'redux';
34
import type { ThunkAction } from 'redux-thunk';
@@ -185,6 +186,7 @@ type ThunkExtraArg = {
185186
connectionInfo: ConnectionInfo
186187
) => Promise<[ExtraConnectionDataForTelemetry, string | null]>;
187188
connectFn?: typeof devtoolsConnect;
189+
globalAppRegistry: Pick<AppRegistry, 'on' | 'emit' | 'removeListener'>;
188190
};
189191

190192
export type ConnectionsThunkAction<
@@ -2167,6 +2169,14 @@ export const importConnections = (
21672169
};
21682170
};
21692171

2172+
export const openSettingsModal = (
2173+
tab?: string
2174+
): ConnectionsThunkAction<void> => {
2175+
return (_dispatch, _getState, { globalAppRegistry }) => {
2176+
globalAppRegistry.emit('open-compass-settings', tab);
2177+
};
2178+
};
2179+
21702180
export function configureStore(
21712181
preloadConnectionInfos: ConnectionInfo[] = [],
21722182
thunkArg: ThunkExtraArg

packages/compass-sidebar/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
"@mongodb-js/compass-maybe-protect-connection-string": "^0.28.0",
5858
"@mongodb-js/compass-telemetry": "^1.2.3",
5959
"@mongodb-js/compass-workspaces": "^0.28.0",
60-
"@mongodb-js/connection-form": "^1.44.0",
6160
"@mongodb-js/connection-info": "^0.9.3",
6261
"compass-preferences-model": "^2.30.0",
6362
"hadron-app-registry": "^9.2.7",

0 commit comments

Comments
 (0)