Skip to content

Commit

Permalink
feat(connections): add edit connection context menu action VSCODE-406 (
Browse files Browse the repository at this point in the history
  • Loading branch information
Anemy authored Jan 16, 2024
1 parent 82de91d commit 70b1351
Show file tree
Hide file tree
Showing 25 changed files with 887 additions and 584 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ If you use Terraform to manage your infrastructure, MongoDB for VS Code helps yo
| `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` |
| `mdb.showOIDCDeviceAuthFlow` | Opt-in and opt-out for diagnostic and telemetry collection. | `true` |
| `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) |
| `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` |
| `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` |
| `mdb.useDefaultTemplateForPlayground` | Choose whether to use the default template for playground files or to start with an empty playground editor. | `true` |
| `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` |
Expand Down
240 changes: 119 additions & 121 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 19 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@
"command": "mdb.treeItemRemoveConnection",
"title": "Remove Connection..."
},
{
"command": "mdb.editConnection",
"title": "Edit Connection..."
},
{
"command": "mdb.addDatabase",
"title": "Add Database...",
Expand Down Expand Up @@ -481,6 +485,11 @@
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"group": "3@1"
},
{
"command": "mdb.editConnection",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"group": "3@2"
},
{
"command": "mdb.copyConnectionString",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
Expand Down Expand Up @@ -511,6 +520,11 @@
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
"group": "2@1"
},
{
"command": "mdb.editConnection",
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
"group": "2@2"
},
{
"command": "mdb.copyConnectionString",
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
Expand Down Expand Up @@ -746,6 +760,10 @@
"command": "mdb.renameConnection",
"when": "false"
},
{
"command": "mdb.editConnection",
"when": "false"
},
{
"command": "mdb.treeItemRemoveConnection",
"when": "false"
Expand Down Expand Up @@ -1008,11 +1026,6 @@
"default": true,
"description": "Allow the collection of anonymous diagnostic and usage telemetry data to help improve the product."
},
"mdb.connectionSaving.hideOptionToChooseWhereToSaveNewConnections": {
"type": "boolean",
"default": true,
"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."
},
"mdb.connectionSaving.defaultConnectionSavingLocation": {
"type": "string",
"enum": [
Expand Down Expand Up @@ -1050,7 +1063,7 @@
"@babel/parser": "^7.22.6",
"@babel/traverse": "^7.23.2",
"@mongodb-js/compass-components": "^1.20.0",
"@mongodb-js/connection-form": "^1.20.4",
"@mongodb-js/connection-form": "^1.22.2",
"@mongodb-js/connection-info": "^0.1.1",
"@mongodb-js/mongodb-constants": "^0.7.1",
"@mongosh/browser-runtime-electron": "^2.0.2",
Expand Down
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum EXTENSION_COMMANDS {
MDB_CONNECT_TO_CONNECTION_TREE_VIEW = 'mdb.connectToConnectionTreeItem',
MDB_CREATE_PLAYGROUND_FROM_TREE_VIEW = 'mdb.createNewPlaygroundFromTreeView',
MDB_DISCONNECT_FROM_CONNECTION_TREE_VIEW = 'mdb.disconnectFromConnectionTreeItem',
MDB_EDIT_CONNECTION = 'mdb.editConnection',
MDB_REFRESH_CONNECTION = 'mdb.refreshConnection',
MDB_COPY_CONNECTION_STRING = 'mdb.copyConnectionString',
MDB_REMOVE_CONNECTION_TREE_VIEW = 'mdb.treeItemRemoveConnection',
Expand Down
121 changes: 90 additions & 31 deletions src/connectionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,13 @@ export default class ConnectionController {
);

try {
const connectResult = await this.saveNewConnectionAndConnect(
{
id: uuidv4(),
connectionOptions: {
connectionString: connectionStringData.toString(),
},
const connectResult = await this.saveNewConnectionAndConnect({
connectionId: uuidv4(),
connectionOptions: {
connectionString: connectionStringData.toString(),
},
ConnectionTypes.CONNECTION_STRING
);
connectionType: ConnectionTypes.CONNECTION_STRING,
});

return connectResult.successfullyConnected;
} catch (error) {
Expand All @@ -282,34 +280,37 @@ export default class ConnectionController {
);
}

async saveNewConnectionAndConnect(
connection: {
connectionOptions: ConnectionOptions;
id: string;
},
connectionType: ConnectionTypes
): Promise<ConnectionAttemptResult> {
const savedConnectionWithoutSecrets =
await this._connectionStorage.saveNewConnection(connection);
async saveNewConnectionAndConnect({
connectionOptions,
connectionId,
connectionType,
}: {
connectionOptions: ConnectionOptions;
connectionId: string;
connectionType: ConnectionTypes;
}): Promise<ConnectionAttemptResult> {
const connection = this._connectionStorage.createNewConnection({
connectionId,
connectionOptions,
});

this._connections[savedConnectionWithoutSecrets.id] = {
...savedConnectionWithoutSecrets,
connectionOptions: connection.connectionOptions, // The connection options with secrets.
};
await this._connectionStorage.saveConnection(connection);

log.info(
'Connect called to connect to instance',
savedConnectionWithoutSecrets.name
);
this._connections[connection.id] = cloneDeep(connection);

return this._connect(savedConnectionWithoutSecrets.id, connectionType);
return this._connect(connection.id, connectionType);
}

// eslint-disable-next-line complexity
async _connect(
connectionId: string,
connectionType: ConnectionTypes
): Promise<ConnectionAttemptResult> {
log.info(
'Connect called to connect to instance',
this._connections[connectionId]?.name || 'empty connection name'
);

// Cancel the current connection attempt if we're connecting.
this._connectionAttempt?.cancelConnectionAttempt();

Expand Down Expand Up @@ -538,22 +539,30 @@ export default class ConnectionController {
this._connectionAttempt?.cancelConnectionAttempt();
}

async connectWithConnectionId(connectionId: string): Promise<boolean> {
async connectWithConnectionId(
connectionId: string
): Promise<ConnectionAttemptResult> {
if (!this._connections[connectionId]) {
throw new Error('Connection not found.');
}

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

return true;
return {
successfullyConnected: true,
connectionErrorMessage: '',
};
} catch (error) {
log.error('Failed to connect by a connection id', error);
const printableError = formatError(error);
void vscode.window.showErrorMessage(
`Unable to connect: ${printableError.message}`
);
return false;
return {
successfullyConnected: false,
connectionErrorMessage: '',
};
}
}

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

Expand Down Expand Up @@ -692,6 +701,41 @@ export default class ConnectionController {
return this.removeMongoDBConnection(connectionIdToRemove);
}

async updateConnection({
connectionId,
connectionOptions,
}: {
connectionId: string;
connectionOptions: ConnectionOptions;
}): Promise<void> {
if (!this._connections[connectionId]) {
throw new Error('Cannot find connection to update.');
}

this._connections[connectionId] = {
...this._connections[connectionId],
connectionOptions,
};
await this._connectionStorage.saveConnection(
this._connections[connectionId]
);
}

async updateConnectionAndConnect({
connectionId,
connectionOptions,
}: {
connectionId: string;
connectionOptions: ConnectionOptions;
}): Promise<ConnectionAttemptResult> {
await this.updateConnection({
connectionId,
connectionOptions,
});

return await this.connectWithConnectionId(connectionId);
}

async renameConnection(connectionId: string): Promise<boolean> {
let inputtedConnectionName: string | undefined;

Expand Down Expand Up @@ -789,6 +833,20 @@ export default class ConnectionController {
: '';
}

getConnectionConnectionOptions(
connectionId: string
): ConnectionOptions | undefined {
const connectionStringWithoutAppName = new ConnectionString(
this._connections[connectionId]?.connectionOptions.connectionString
);
connectionStringWithoutAppName.searchParams.delete('appname');

return {
...this._connections[connectionId]?.connectionOptions,
connectionString: connectionStringWithoutAppName.toString(),
};
}

_getConnectionStringWithProxy({
url,
options,
Expand Down Expand Up @@ -982,8 +1040,9 @@ export default class ConnectionController {
return true;
}

return this.connectWithConnectionId(
const { successfullyConnected } = await this.connectWithConnectionId(
selectedQuickPickItem.data.connectionId
);
return successfullyConnected;
}
}
2 changes: 1 addition & 1 deletion src/explorer/collectionTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export default class CollectionTreeItem
});
} catch (error) {
return Promise.reject(
new Error(`An error occured parsing the collection name: ${error}`)
new Error(`An error occurred parsing the collection name: ${error}`)
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/explorer/connectionTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,11 @@ export default class ConnectionTreeItem

// If we aren't the active connection, we reconnect.
try {
const connectSuccess =
const { successfullyConnected } =
await this._connectionController.connectWithConnectionId(
this.connectionId
);
return connectSuccess;
return successfullyConnected;
} catch (err) {
this.isExpanded = false;
void vscode.window.showErrorMessage(
Expand Down
2 changes: 1 addition & 1 deletion src/explorer/databaseTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export default class DatabaseTreeItem
});
} catch (e) {
return Promise.reject(
new Error(`An error occured parsing the database name: ${e}`)
new Error(`An error occurred parsing the database name: ${e}`)
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/explorer/streamProcessorTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default class StreamProcessorTreeItem
});
} catch (e) {
return Promise.reject(
new Error(`An error occured parsing the stream processor name: ${e}`)
new Error(`An error occurred parsing the stream processor name: ${e}`)
);
}

Expand Down
Loading

0 comments on commit 70b1351

Please sign in to comment.