Skip to content
Merged
8 changes: 7 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@
"out": true
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
"typescript.tsc.autoDetect": "off",
"mdb.presetConnections": [
{
"name": "Preset Database",
"connectionString": "mongodb://localhost:27017"
}
]
}
81 changes: 69 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@
"command": "mdb.copyConnectionString",
"title": "Copy Connection String"
},
{
"command": "mdb.editPresetConnections",
"title": "Edit Preset Connections..."
},
{
"command": "mdb.renameConnection",
"title": "Rename Connection..."
Expand Down Expand Up @@ -489,42 +493,49 @@
},
{
"command": "mdb.addConnection",
"when": "view == mongoDBConnectionExplorer"
"when": "view == mongoDBConnectionExplorer",
"group": "1@1"
},
{
"command": "mdb.addConnectionWithURI",
"when": "view == mongoDBConnectionExplorer"
"when": "view == mongoDBConnectionExplorer",
"group": "1@2"
},
{
"command": "mdb.editPresetConnections",
"when": "view == mongoDBConnectionExplorer",
"group": "2@1"
}
],
"view/item/context": [
{
"command": "mdb.addDatabase",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == false",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == false",
"group": "inline"
},
{
"command": "mdb.addDatabase",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == false",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == false",
"group": "1@1"
},
{
"command": "mdb.addStreamProcessor",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == true",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == true",
"group": "inline"
},
{
"command": "mdb.addStreamProcessor",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem && mdb.isAtlasStreams == true",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem) && mdb.isAtlasStreams == true",
"group": "1@1"
},
{
"command": "mdb.refreshConnection",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
"group": "1@2"
},
{
"command": "mdb.treeViewOpenMongoDBShell",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
"group": "2@1"
},
{
Expand All @@ -537,14 +548,19 @@
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"group": "3@2"
},
{
"command": "mdb.editPresetConnections",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedPresetConnectionTreeItem",
"group": "3@2"
},
{
"command": "mdb.copyConnectionString",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
"group": "4@1"
},
{
"command": "mdb.disconnectFromConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && viewItem == connectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == connectedConnectionTreeItem || viewItem == connectedPresetConnectionTreeItem)",
"group": "5@1"
},
{
Expand All @@ -559,7 +575,7 @@
},
{
"command": "mdb.connectToConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == disconnectedConnectionTreeItem || viewItem == disconnectedPresetConnectionTreeItem)",
"group": "1@1"
},
{
Expand All @@ -572,9 +588,14 @@
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
"group": "2@2"
},
{
"command": "mdb.editPresetConnections",
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedPresetConnectionTreeItem",
"group": "2@2"
},
{
"command": "mdb.copyConnectionString",
"when": "view == mongoDBConnectionExplorer && viewItem == disconnectedConnectionTreeItem",
"when": "view == mongoDBConnectionExplorer && (viewItem == disconnectedConnectionTreeItem || viewItem == disconnectedPresetConnectionTreeItem)",
"group": "3@1"
},
{
Expand Down Expand Up @@ -1171,6 +1192,42 @@
"type": "string",
"default": "",
"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."
},
"mdb.presetConnections": {
"scope": "window",
"type": "array",
"description": "Defines preset saved connections. Can be used to share connection configurations in a workspace or global scope. Do not store sensitive credentials here.",
"examples": [
[
{
"name": "Preset Database",
"connectionString": "mongodb://localhost:27017"
}
]
],
"items": {
"type": "object",
"examples": [
{
"name": "Preset Database",
"connectionString": "mongodb://localhost:27017"
}
],
"properties": {
"name": {
"type": "string",
"description": "Name of the connection."
},
"connectionString": {
"type": "string",
"description": "Connection string. Do not store sensitive credentials here."
}
},
"required": [
"name",
"connectionString"
]
}
}
}
},
Expand Down
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum EXTENSION_COMMANDS {
MDB_EDIT_CONNECTION = 'mdb.editConnection',
MDB_REFRESH_CONNECTION = 'mdb.refreshConnection',
MDB_COPY_CONNECTION_STRING = 'mdb.copyConnectionString',
MDB_EDIT_PRESET_CONNECTIONS = 'mdb.editPresetConnections',
MDB_REMOVE_CONNECTION_TREE_VIEW = 'mdb.treeItemRemoveConnection',
MDB_RENAME_CONNECTION = 'mdb.renameConnection',
MDB_ADD_DATABASE = 'mdb.addDatabase',
Expand Down
55 changes: 54 additions & 1 deletion src/connectionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ import type { StorageController } from './storage';
import type { StatusView } from './views';
import type TelemetryService from './telemetry/telemetryService';
import { openLink } from './utils/linkHelper';
import type { LoadedConnection } from './storage/connectionStorage';
import type {
ConnectionSource,
LoadedConnection,
} from './storage/connectionStorage';
import { ConnectionStorage } from './storage/connectionStorage';
import LINKS from './utils/links';
import { isAtlasStream } from 'mongodb-build-info';
import { DocumentSource } from './documentSource';
import type { ConnectionTreeItem } from './explorer';

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

async openPresetConnectionsSettings(
originTreeItem: ConnectionTreeItem | undefined
): Promise<void> {
this._telemetryService.trackPresetConnectionEdited({
source: DocumentSource.DOCUMENT_SOURCE_TREEVIEW,
source_details: originTreeItem ? 'tree_item' : 'header',
});
let source: ConnectionSource | undefined = originTreeItem?.source;
if (!source) {
const mdbConfiguration = vscode.workspace.getConfiguration('mdb');

const presetConnections = mdbConfiguration?.inspect('presetConnections');

if (presetConnections?.workspaceValue) {
source = 'workspaceSettings';
} else if (presetConnections?.globalValue) {
source = 'globalSettings';
} else {
// If no preset settings exist in workspace and global scope,
// set a default one inside the workspace and open it.
source = 'workspaceSettings';
await mdbConfiguration.update('presetConnections', [
{
name: 'Preset Database',
connectionString: 'mongodb://localhost:27017',
},
]);
}
}
switch (source) {
case 'globalSettings':
await vscode.commands.executeCommand(
'workbench.action.openSettingsJson'
);
break;
case 'workspaceSettings':
case 'user':
await vscode.commands.executeCommand(
'workbench.action.openWorkspaceSettingsFile'
);
break;
default:
throw new Error('Unknown preset connection source');
}
}

async loadSavedConnections(): Promise<void> {
this._connections = Object.create(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this fixing a bug where deleted saved connections would show up because they're not overridden in the for loop? Couldn't spot a test that verifies the behavior before was incorrect - am I just blind or should we add one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this hasn't been an issue because we'd only run loadSavedConnections at startup / when this._connections would be not yet defined. Now with the reloading on save this becomes more obvious. I'll add a test.


const loadedConnections = await this._connectionStorage.loadConnections();

for (const connection of loadedConnections) {
Expand Down
33 changes: 21 additions & 12 deletions src/explorer/connectionTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import formatError from '../utils/formatError';
import { getImagesPath } from '../extensionConstants';
import type TreeItemParent from './treeItemParentInterface';
import StreamProcessorTreeItem from './streamProcessorTreeItem';
import type { ConnectionSource } from '../storage/connectionStorage';

export enum ConnectionItemContextValues {
disconnected = 'disconnectedConnectionTreeItem',
connected = 'connectedConnectionTreeItem',
}
export type ConnectionItemContextValue = `${'disconnected' | 'connected'}${
| ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[extreme nit] The leading | makes the formatting really awkard - is it even worse without it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets automatically added by the linter 🤷

| 'Preset'}ConnectionTreeItem`;

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

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

isExpanded: boolean;
source: ConnectionSource;

constructor({
connectionId,
Expand All @@ -58,6 +59,7 @@ export default class ConnectionTreeItem
connectionController,
cacheIsUpToDate,
childrenCache,
source,
}: {
connectionId: string;
collapsibleState: vscode.TreeItemCollapsibleState;
Expand All @@ -67,21 +69,24 @@ export default class ConnectionTreeItem
childrenCache: {
[key: string]: DatabaseTreeItem | StreamProcessorTreeItem;
}; // Existing cache.
source: ConnectionSource;
}) {
super(
connectionController.getSavedConnectionName(connectionId),
collapsibleState
);

if (
const isConnected =
connectionController.getActiveConnectionId() === connectionId &&
!connectionController.isDisconnecting() &&
!connectionController.isConnecting()
) {
this.contextValue = ConnectionItemContextValues.connected;
}
!connectionController.isConnecting();

this.contextValue = `${isConnected ? 'connected' : 'disconnected'}${
source === 'user' ? '' : 'Preset'
}ConnectionTreeItem`;

this.connectionId = connectionId;
this.source = source;
this._connectionController = connectionController;
this.isExpanded = isExpanded;
this._childrenCache = childrenCache;
Expand Down Expand Up @@ -204,7 +209,9 @@ export default class ConnectionTreeItem
return Object.values(this._childrenCache);
}

private async _buildChildrenCacheForDatabases(dataService: DataService) {
private async _buildChildrenCacheForDatabases(
dataService: DataService
): Promise<Record<string, DatabaseTreeItem>> {
const databases = await this.listDatabases();
databases.sort((a: string, b: string) => a.localeCompare(b));

Expand All @@ -226,7 +233,9 @@ export default class ConnectionTreeItem
return newChildrenCache;
}

private async _buildChildrenCacheForStreams(dataService: DataService) {
private async _buildChildrenCacheForStreams(
dataService: DataService
): Promise<Record<string, StreamProcessorTreeItem>> {
const processors = await this.listStreamProcessors();
processors.sort((a, b) => a.name.localeCompare(b.name));

Expand Down
Loading
Loading