Skip to content

Commit 70b1351

Browse files
authored
feat(connections): add edit connection context menu action VSCODE-406 (#655)
1 parent 82de91d commit 70b1351

25 files changed

+887
-584
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ If you use Terraform to manage your infrastructure, MongoDB for VS Code helps yo
8383
| `mdb.persistOIDCTokens` | Remain logged in when using the MONGODB-OIDC authentication mechanism for MongoDB server connection. Access tokens are encrypted using the system keychain before being stored. | `true` |
8484
| `mdb.showOIDCDeviceAuthFlow` | Opt-in and opt-out for diagnostic and telemetry collection. | `true` |
8585
| `mdb.excludeFromPlaygroundsSearch` | Exclude files and folders while searching for playground files in the current workspace. | Refer to [`package.json`](https://github.com/mongodb-js/vscode/blob/7b10092db4c8c10c4aa9c45b443c8ed3d5f37d5c/package.json) |
86-
| `mdb.connectionSaving.` `hideOptionToChooseWhereToSaveNewConnections` | When a connection is added, a prompt is shown that let's the user decide where the new connection should be saved. When this setting is checked, the prompt is not shown and the default connection saving location setting is used. | `true` |
8786
| `mdb.connectionSaving.` `defaultConnectionSavingLocation` | When the setting that hides the option to choose where to save new connections is checked, this setting sets if and where new connections are saved. | `Global` |
8887
| `mdb.useDefaultTemplateForPlayground` | Choose whether to use the default template for playground files or to start with an empty playground editor. | `true` |
8988
| `mdb.uniqueObjectIdPerCursor` | The default behavior is to generate a single ObjectId and insert it on all cursors. Set to true to generate a unique ObjectId per cursor instead. | `false` |

package-lock.json

Lines changed: 119 additions & 121 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@
274274
"command": "mdb.treeItemRemoveConnection",
275275
"title": "Remove Connection..."
276276
},
277+
{
278+
"command": "mdb.editConnection",
279+
"title": "Edit Connection..."
280+
},
277281
{
278282
"command": "mdb.addDatabase",
279283
"title": "Add Database...",
@@ -481,6 +485,11 @@
481485
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
482486
"group": "3@1"
483487
},
488+
{
489+
"command": "mdb.editConnection",
490+
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
491+
"group": "3@2"
492+
},
484493
{
485494
"command": "mdb.copyConnectionString",
486495
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
@@ -511,6 +520,11 @@
511520
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
512521
"group": "2@1"
513522
},
523+
{
524+
"command": "mdb.editConnection",
525+
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
526+
"group": "2@2"
527+
},
514528
{
515529
"command": "mdb.copyConnectionString",
516530
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
@@ -746,6 +760,10 @@
746760
"command": "mdb.renameConnection",
747761
"when": "false"
748762
},
763+
{
764+
"command": "mdb.editConnection",
765+
"when": "false"
766+
},
749767
{
750768
"command": "mdb.treeItemRemoveConnection",
751769
"when": "false"
@@ -1008,11 +1026,6 @@
10081026
"default": true,
10091027
"description": "Allow the collection of anonymous diagnostic and usage telemetry data to help improve the product."
10101028
},
1011-
"mdb.connectionSaving.hideOptionToChooseWhereToSaveNewConnections": {
1012-
"type": "boolean",
1013-
"default": true,
1014-
"description": "When a connection is added, a prompt is shown that let's the user decide where the new connection should be saved. When this setting is checked, the prompt is not shown and the default connection saving location setting is used."
1015-
},
10161029
"mdb.connectionSaving.defaultConnectionSavingLocation": {
10171030
"type": "string",
10181031
"enum": [
@@ -1050,7 +1063,7 @@
10501063
"@babel/parser": "^7.22.6",
10511064
"@babel/traverse": "^7.23.2",
10521065
"@mongodb-js/compass-components": "^1.20.0",
1053-
"@mongodb-js/connection-form": "^1.20.4",
1066+
"@mongodb-js/connection-form": "^1.22.2",
10541067
"@mongodb-js/connection-info": "^0.1.1",
10551068
"@mongodb-js/mongodb-constants": "^0.7.1",
10561069
"@mongosh/browser-runtime-electron": "^2.0.2",

src/commands/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum EXTENSION_COMMANDS {
4141
MDB_CONNECT_TO_CONNECTION_TREE_VIEW = 'mdb.connectToConnectionTreeItem',
4242
MDB_CREATE_PLAYGROUND_FROM_TREE_VIEW = 'mdb.createNewPlaygroundFromTreeView',
4343
MDB_DISCONNECT_FROM_CONNECTION_TREE_VIEW = 'mdb.disconnectFromConnectionTreeItem',
44+
MDB_EDIT_CONNECTION = 'mdb.editConnection',
4445
MDB_REFRESH_CONNECTION = 'mdb.refreshConnection',
4546
MDB_COPY_CONNECTION_STRING = 'mdb.copyConnectionString',
4647
MDB_REMOVE_CONNECTION_TREE_VIEW = 'mdb.treeItemRemoveConnection',

src/connectionController.ts

Lines changed: 90 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,13 @@ export default class ConnectionController {
251251
);
252252

253253
try {
254-
const connectResult = await this.saveNewConnectionAndConnect(
255-
{
256-
id: uuidv4(),
257-
connectionOptions: {
258-
connectionString: connectionStringData.toString(),
259-
},
254+
const connectResult = await this.saveNewConnectionAndConnect({
255+
connectionId: uuidv4(),
256+
connectionOptions: {
257+
connectionString: connectionStringData.toString(),
260258
},
261-
ConnectionTypes.CONNECTION_STRING
262-
);
259+
connectionType: ConnectionTypes.CONNECTION_STRING,
260+
});
263261

264262
return connectResult.successfullyConnected;
265263
} catch (error) {
@@ -282,34 +280,37 @@ export default class ConnectionController {
282280
);
283281
}
284282

285-
async saveNewConnectionAndConnect(
286-
connection: {
287-
connectionOptions: ConnectionOptions;
288-
id: string;
289-
},
290-
connectionType: ConnectionTypes
291-
): Promise<ConnectionAttemptResult> {
292-
const savedConnectionWithoutSecrets =
293-
await this._connectionStorage.saveNewConnection(connection);
283+
async saveNewConnectionAndConnect({
284+
connectionOptions,
285+
connectionId,
286+
connectionType,
287+
}: {
288+
connectionOptions: ConnectionOptions;
289+
connectionId: string;
290+
connectionType: ConnectionTypes;
291+
}): Promise<ConnectionAttemptResult> {
292+
const connection = this._connectionStorage.createNewConnection({
293+
connectionId,
294+
connectionOptions,
295+
});
294296

295-
this._connections[savedConnectionWithoutSecrets.id] = {
296-
...savedConnectionWithoutSecrets,
297-
connectionOptions: connection.connectionOptions, // The connection options with secrets.
298-
};
297+
await this._connectionStorage.saveConnection(connection);
299298

300-
log.info(
301-
'Connect called to connect to instance',
302-
savedConnectionWithoutSecrets.name
303-
);
299+
this._connections[connection.id] = cloneDeep(connection);
304300

305-
return this._connect(savedConnectionWithoutSecrets.id, connectionType);
301+
return this._connect(connection.id, connectionType);
306302
}
307303

308304
// eslint-disable-next-line complexity
309305
async _connect(
310306
connectionId: string,
311307
connectionType: ConnectionTypes
312308
): Promise<ConnectionAttemptResult> {
309+
log.info(
310+
'Connect called to connect to instance',
311+
this._connections[connectionId]?.name || 'empty connection name'
312+
);
313+
313314
// Cancel the current connection attempt if we're connecting.
314315
this._connectionAttempt?.cancelConnectionAttempt();
315316

@@ -538,22 +539,30 @@ export default class ConnectionController {
538539
this._connectionAttempt?.cancelConnectionAttempt();
539540
}
540541

541-
async connectWithConnectionId(connectionId: string): Promise<boolean> {
542+
async connectWithConnectionId(
543+
connectionId: string
544+
): Promise<ConnectionAttemptResult> {
542545
if (!this._connections[connectionId]) {
543546
throw new Error('Connection not found.');
544547
}
545548

546549
try {
547550
await this._connect(connectionId, ConnectionTypes.CONNECTION_ID);
548551

549-
return true;
552+
return {
553+
successfullyConnected: true,
554+
connectionErrorMessage: '',
555+
};
550556
} catch (error) {
551557
log.error('Failed to connect by a connection id', error);
552558
const printableError = formatError(error);
553559
void vscode.window.showErrorMessage(
554560
`Unable to connect: ${printableError.message}`
555561
);
556-
return false;
562+
return {
563+
successfullyConnected: false,
564+
connectionErrorMessage: '',
565+
};
557566
}
558567
}
559568

@@ -598,7 +607,7 @@ export default class ConnectionController {
598607
} catch (error) {
599608
// Show an error, however we still reset the active connection to free up the extension.
600609
void vscode.window.showErrorMessage(
601-
'An error occured while disconnecting from the current connection.'
610+
'An error occurred while disconnecting from the current connection.'
602611
);
603612
}
604613

@@ -692,6 +701,41 @@ export default class ConnectionController {
692701
return this.removeMongoDBConnection(connectionIdToRemove);
693702
}
694703

704+
async updateConnection({
705+
connectionId,
706+
connectionOptions,
707+
}: {
708+
connectionId: string;
709+
connectionOptions: ConnectionOptions;
710+
}): Promise<void> {
711+
if (!this._connections[connectionId]) {
712+
throw new Error('Cannot find connection to update.');
713+
}
714+
715+
this._connections[connectionId] = {
716+
...this._connections[connectionId],
717+
connectionOptions,
718+
};
719+
await this._connectionStorage.saveConnection(
720+
this._connections[connectionId]
721+
);
722+
}
723+
724+
async updateConnectionAndConnect({
725+
connectionId,
726+
connectionOptions,
727+
}: {
728+
connectionId: string;
729+
connectionOptions: ConnectionOptions;
730+
}): Promise<ConnectionAttemptResult> {
731+
await this.updateConnection({
732+
connectionId,
733+
connectionOptions,
734+
});
735+
736+
return await this.connectWithConnectionId(connectionId);
737+
}
738+
695739
async renameConnection(connectionId: string): Promise<boolean> {
696740
let inputtedConnectionName: string | undefined;
697741

@@ -789,6 +833,20 @@ export default class ConnectionController {
789833
: '';
790834
}
791835

836+
getConnectionConnectionOptions(
837+
connectionId: string
838+
): ConnectionOptions | undefined {
839+
const connectionStringWithoutAppName = new ConnectionString(
840+
this._connections[connectionId]?.connectionOptions.connectionString
841+
);
842+
connectionStringWithoutAppName.searchParams.delete('appname');
843+
844+
return {
845+
...this._connections[connectionId]?.connectionOptions,
846+
connectionString: connectionStringWithoutAppName.toString(),
847+
};
848+
}
849+
792850
_getConnectionStringWithProxy({
793851
url,
794852
options,
@@ -982,8 +1040,9 @@ export default class ConnectionController {
9821040
return true;
9831041
}
9841042

985-
return this.connectWithConnectionId(
1043+
const { successfullyConnected } = await this.connectWithConnectionId(
9861044
selectedQuickPickItem.data.connectionId
9871045
);
1046+
return successfullyConnected;
9881047
}
9891048
}

src/explorer/collectionTreeItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ export default class CollectionTreeItem
366366
});
367367
} catch (error) {
368368
return Promise.reject(
369-
new Error(`An error occured parsing the collection name: ${error}`)
369+
new Error(`An error occurred parsing the collection name: ${error}`)
370370
);
371371
}
372372

src/explorer/connectionTreeItem.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,11 @@ export default class ConnectionTreeItem
267267

268268
// If we aren't the active connection, we reconnect.
269269
try {
270-
const connectSuccess =
270+
const { successfullyConnected } =
271271
await this._connectionController.connectWithConnectionId(
272272
this.connectionId
273273
);
274-
return connectSuccess;
274+
return successfullyConnected;
275275
} catch (err) {
276276
this.isExpanded = false;
277277
void vscode.window.showErrorMessage(

src/explorer/databaseTreeItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export default class DatabaseTreeItem
214214
});
215215
} catch (e) {
216216
return Promise.reject(
217-
new Error(`An error occured parsing the database name: ${e}`)
217+
new Error(`An error occurred parsing the database name: ${e}`)
218218
);
219219
}
220220

src/explorer/streamProcessorTreeItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export default class StreamProcessorTreeItem
127127
});
128128
} catch (e) {
129129
return Promise.reject(
130-
new Error(`An error occured parsing the stream processor name: ${e}`)
130+
new Error(`An error occurred parsing the stream processor name: ${e}`)
131131
);
132132
}
133133

0 commit comments

Comments
 (0)