Skip to content

Commit b6e36e8

Browse files
authored
feat(tree-explorer): add ability to set preset connections in settings.json VSCODE-665 (#909)
1 parent c69e314 commit b6e36e8

14 files changed

+456
-76
lines changed

.vscode/settings.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@
1616
"out": true
1717
},
1818
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
19-
"typescript.tsc.autoDetect": "off"
19+
"typescript.tsc.autoDetect": "off",
20+
"mdb.presetConnections": [
21+
{
22+
"name": "Preset Connection",
23+
"connectionString": "mongodb://localhost:27017"
24+
}
25+
]
2026
}

package.json

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@
320320
"command": "mdb.copyConnectionString",
321321
"title": "Copy Connection String"
322322
},
323+
{
324+
"command": "mdb.editPresetConnections",
325+
"title": "Edit Preset Connections..."
326+
},
323327
{
324328
"command": "mdb.renameConnection",
325329
"title": "Rename Connection..."
@@ -489,42 +493,49 @@
489493
},
490494
{
491495
"command": "mdb.addConnection",
492-
"when": "view == mongoDBConnectionExplorer"
496+
"when": "view == mongoDBConnectionExplorer",
497+
"group": "1@1"
493498
},
494499
{
495500
"command": "mdb.addConnectionWithURI",
496-
"when": "view == mongoDBConnectionExplorer"
501+
"when": "view == mongoDBConnectionExplorer",
502+
"group": "1@2"
503+
},
504+
{
505+
"command": "mdb.editPresetConnections",
506+
"when": "view == mongoDBConnectionExplorer",
507+
"group": "2@1"
497508
}
498509
],
499510
"view/item/context": [
500511
{
501512
"command": "mdb.addDatabase",
502-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == false",
513+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == false",
503514
"group": "inline"
504515
},
505516
{
506517
"command": "mdb.addDatabase",
507-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == false",
518+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == false",
508519
"group": "1@1"
509520
},
510521
{
511522
"command": "mdb.addStreamProcessor",
512-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == true",
523+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == true",
513524
"group": "inline"
514525
},
515526
{
516527
"command": "mdb.addStreamProcessor",
517-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == true",
528+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == true",
518529
"group": "1@1"
519530
},
520531
{
521532
"command": "mdb.refreshConnection",
522-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
533+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
523534
"group": "1@2"
524535
},
525536
{
526537
"command": "mdb.treeViewOpenMongoDBShell",
527-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
538+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
528539
"group": "2@1"
529540
},
530541
{
@@ -537,14 +548,19 @@
537548
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
538549
"group": "3@2"
539550
},
551+
{
552+
"command": "mdb.editPresetConnections",
553+
"when": "view == mongoDBConnectionExplorer && viewItem == connectedPresetConnectionTreeItem",
554+
"group": "3@2"
555+
},
540556
{
541557
"command": "mdb.copyConnectionString",
542-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
558+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
543559
"group": "4@1"
544560
},
545561
{
546562
"command": "mdb.disconnectFromConnectionTreeItem",
547-
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
563+
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
548564
"group": "5@1"
549565
},
550566
{
@@ -559,7 +575,7 @@
559575
},
560576
{
561577
"command": "mdb.connectToConnectionTreeItem",
562-
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
578+
"when": "view == mongoDBConnectionExplorer && (viewItem == disconnectedConnectionTreeItem || viewItem == disconnectedPresetConnectionTreeItem)",
563579
"group": "1@1"
564580
},
565581
{
@@ -572,9 +588,14 @@
572588
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
573589
"group": "2@2"
574590
},
591+
{
592+
"command": "mdb.editPresetConnections",
593+
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedPresetConnectionTreeItem",
594+
"group": "2@2"
595+
},
575596
{
576597
"command": "mdb.copyConnectionString",
577-
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
598+
"when": "view == mongoDBConnectionExplorer && (viewItem == disconnectedConnectionTreeItem || viewItem == disconnectedPresetConnectionTreeItem)",
578599
"group": "3@1"
579600
},
580601
{
@@ -1171,6 +1192,42 @@
11711192
"type": "string",
11721193
"default": "",
11731194
"description": "Specify a shell command that is run to start the browser for authenticating with the OIDC identity provider for the server connection. Leave this empty for default browser."
1195+
},
1196+
"mdb.presetConnections": {
1197+
"scope": "window",
1198+
"type": "array",
1199+
"description": "Defines preset connections. Can be used to share connection configurations in a workspace or global scope. Do not store sensitive credentials here.",
1200+
"examples": [
1201+
[
1202+
{
1203+
"name": "Preset Connection",
1204+
"connectionString": "mongodb://localhost:27017"
1205+
}
1206+
]
1207+
],
1208+
"items": {
1209+
"type": "object",
1210+
"examples": [
1211+
{
1212+
"name": "Preset Connection",
1213+
"connectionString": "mongodb://localhost:27017"
1214+
}
1215+
],
1216+
"properties": {
1217+
"name": {
1218+
"type": "string",
1219+
"description": "Name of the connection."
1220+
},
1221+
"connectionString": {
1222+
"type": "string",
1223+
"description": "Connection string. Do not store sensitive credentials here."
1224+
}
1225+
},
1226+
"required": [
1227+
"name",
1228+
"connectionString"
1229+
]
1230+
}
11741231
}
11751232
}
11761233
},

src/commands/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum EXTENSION_COMMANDS {
4444
MDB_EDIT_CONNECTION = 'mdb.editConnection',
4545
MDB_REFRESH_CONNECTION = 'mdb.refreshConnection',
4646
MDB_COPY_CONNECTION_STRING = 'mdb.copyConnectionString',
47+
MDB_EDIT_PRESET_CONNECTIONS = 'mdb.editPresetConnections',
4748
MDB_REMOVE_CONNECTION_TREE_VIEW = 'mdb.treeItemRemoveConnection',
4849
MDB_RENAME_CONNECTION = 'mdb.renameConnection',
4950
MDB_ADD_DATABASE = 'mdb.addDatabase',

src/connectionController.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ import type { StorageController } from './storage';
2121
import type { StatusView } from './views';
2222
import type TelemetryService from './telemetry/telemetryService';
2323
import { openLink } from './utils/linkHelper';
24-
import type { LoadedConnection } from './storage/connectionStorage';
24+
import type {
25+
ConnectionSource,
26+
LoadedConnection,
27+
} from './storage/connectionStorage';
2528
import { ConnectionStorage } from './storage/connectionStorage';
2629
import LINKS from './utils/links';
2730
import { isAtlasStream } from 'mongodb-build-info';
31+
import { DocumentSource } from './documentSource';
32+
import type { ConnectionTreeItem } from './explorer';
2833

2934
// eslint-disable-next-line @typescript-eslint/no-var-requires
3035
const packageJSON = require('../package.json');
@@ -161,7 +166,55 @@ export default class ConnectionController {
161166
});
162167
}
163168

169+
async openPresetConnectionsSettings(
170+
originTreeItem: ConnectionTreeItem | undefined
171+
): Promise<void> {
172+
this._telemetryService.trackPresetConnectionEdited({
173+
source: DocumentSource.DOCUMENT_SOURCE_TREEVIEW,
174+
source_details: originTreeItem ? 'tree_item' : 'header',
175+
});
176+
let source: ConnectionSource | undefined = originTreeItem?.source;
177+
if (!source) {
178+
const mdbConfiguration = vscode.workspace.getConfiguration('mdb');
179+
180+
const presetConnections = mdbConfiguration?.inspect('presetConnections');
181+
182+
if (presetConnections?.workspaceValue) {
183+
source = 'workspaceSettings';
184+
} else if (presetConnections?.globalValue) {
185+
source = 'globalSettings';
186+
} else {
187+
// If no preset settings exist in workspace and global scope,
188+
// set a default one inside the workspace and open it.
189+
source = 'workspaceSettings';
190+
await mdbConfiguration.update('presetConnections', [
191+
{
192+
name: 'Preset Connection',
193+
connectionString: 'mongodb://localhost:27017',
194+
},
195+
]);
196+
}
197+
}
198+
switch (source) {
199+
case 'globalSettings':
200+
await vscode.commands.executeCommand(
201+
'workbench.action.openSettingsJson'
202+
);
203+
break;
204+
case 'workspaceSettings':
205+
case 'user':
206+
await vscode.commands.executeCommand(
207+
'workbench.action.openWorkspaceSettingsFile'
208+
);
209+
break;
210+
default:
211+
throw new Error('Unknown preset connection source');
212+
}
213+
}
214+
164215
async loadSavedConnections(): Promise<void> {
216+
this._connections = Object.create(null);
217+
165218
const loadedConnections = await this._connectionStorage.loadConnections();
166219

167220
for (const connection of loadedConnections) {

src/explorer/connectionTreeItem.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import formatError from '../utils/formatError';
1111
import { getImagesPath } from '../extensionConstants';
1212
import type TreeItemParent from './treeItemParentInterface';
1313
import StreamProcessorTreeItem from './streamProcessorTreeItem';
14+
import type { ConnectionSource } from '../storage/connectionStorage';
1415

15-
export enum ConnectionItemContextValues {
16-
disconnected = 'disconnectedConnectionTreeItem',
17-
connected = 'connectedConnectionTreeItem',
18-
}
16+
export type ConnectionItemContextValue = `${'disconnected' | 'connected'}${
17+
| ''
18+
| 'Preset'}ConnectionTreeItem`;
1919

2020
function getIconPath(isActiveConnection: boolean): {
2121
light: string;
@@ -39,7 +39,7 @@ export default class ConnectionTreeItem
3939
extends vscode.TreeItem
4040
implements TreeItemParent, vscode.TreeDataProvider<ConnectionTreeItem>
4141
{
42-
contextValue = ConnectionItemContextValues.disconnected;
42+
contextValue: ConnectionItemContextValue = 'disconnectedConnectionTreeItem';
4343

4444
private _childrenCache: {
4545
[key: string]: DatabaseTreeItem | StreamProcessorTreeItem;
@@ -50,6 +50,7 @@ export default class ConnectionTreeItem
5050
connectionId: string;
5151

5252
isExpanded: boolean;
53+
source: ConnectionSource;
5354

5455
constructor({
5556
connectionId,
@@ -58,6 +59,7 @@ export default class ConnectionTreeItem
5859
connectionController,
5960
cacheIsUpToDate,
6061
childrenCache,
62+
source,
6163
}: {
6264
connectionId: string;
6365
collapsibleState: vscode.TreeItemCollapsibleState;
@@ -67,21 +69,24 @@ export default class ConnectionTreeItem
6769
childrenCache: {
6870
[key: string]: DatabaseTreeItem | StreamProcessorTreeItem;
6971
}; // Existing cache.
72+
source: ConnectionSource;
7073
}) {
7174
super(
7275
connectionController.getSavedConnectionName(connectionId),
7376
collapsibleState
7477
);
7578

76-
if (
79+
const isConnected =
7780
connectionController.getActiveConnectionId() === connectionId &&
7881
!connectionController.isDisconnecting() &&
79-
!connectionController.isConnecting()
80-
) {
81-
this.contextValue = ConnectionItemContextValues.connected;
82-
}
82+
!connectionController.isConnecting();
83+
84+
this.contextValue = `${isConnected ? 'connected' : 'disconnected'}${
85+
source === 'user' ? '' : 'Preset'
86+
}ConnectionTreeItem`;
8387

8488
this.connectionId = connectionId;
89+
this.source = source;
8590
this._connectionController = connectionController;
8691
this.isExpanded = isExpanded;
8792
this._childrenCache = childrenCache;
@@ -204,7 +209,9 @@ export default class ConnectionTreeItem
204209
return Object.values(this._childrenCache);
205210
}
206211

207-
private async _buildChildrenCacheForDatabases(dataService: DataService) {
212+
private async _buildChildrenCacheForDatabases(
213+
dataService: DataService
214+
): Promise<Record<string, DatabaseTreeItem>> {
208215
const databases = await this.listDatabases();
209216
databases.sort((a: string, b: string) => a.localeCompare(b));
210217

@@ -226,7 +233,9 @@ export default class ConnectionTreeItem
226233
return newChildrenCache;
227234
}
228235

229-
private async _buildChildrenCacheForStreams(dataService: DataService) {
236+
private async _buildChildrenCacheForStreams(
237+
dataService: DataService
238+
): Promise<Record<string, StreamProcessorTreeItem>> {
230239
const processors = await this.listStreamProcessors();
231240
processors.sort((a, b) => a.name.localeCompare(b.name));
232241

0 commit comments

Comments
 (0)