Skip to content

Conversation

@gagik
Copy link
Contributor

@gagik gagik commented Jan 12, 2025

Adds option to specify mdb.presetConfigurations inside settings.json (likely for a workspace) which will load a preset list of connections based on that. This setting defines preset connections. It can be used to share connection configurations in a workspace or global scope.

It is important that users do not store sensitive credentials here as it is just saved as a plaintext file and is easily accessible. The common usecase where this setting is useful is if for example some project has a local mongodb instance associated with it for tests and the repository owner wants to share different preset connection settings for when one loads this.

The setting format is an array of preset connections defined with this kind of schema: 

{
 "name": {
    "type": "string",
    "description": "Name of the connection."
  },
  "connectionString": {
    "type": "string",
    "description": "Connection string. Do not store sensitive credentials here."
  }
}

Users can discover this by clicking the ... in the Tree View next to the Plus icon and selecting Edit Preset Connections... which will open the relevant file as it is detected (or create a preset connection in the workspace to modify if one doesn't exist already).

Preset connections can only be edited through the settings.json file they originate from which can also be accessed when right clicking the a preset connection and choosing "Edit Preset Connections..."

Screenshot 2025-01-13 at 8 44 44 AM

Motivation and Context

Addresses #368.

package.json Outdated
"group": "3@2"
},
{
"command": "mdb.openWorkspaceSettingsFile",
Copy link
Contributor Author

@gagik gagik Jan 13, 2025

Choose a reason for hiding this comment

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

I think it'd be nice to include ability to quickly open workspace settings here when the item is preset (piggybacking on an existing VSCode action).

We can't easily detect where this preset comes from (i.e. it could also come from user settings) so we could also include a shortcut to open user settings, but maybe we don't want to encourage that and assume they know what they're doing by that point?

If someone that defined this in their user settings (as opposed to workspace) and clicks the Open Workspace Settings, it'd open or create a .vscode/settings.json file in the workspace, and setting things there would override user settings, which seems reasonable.

!connectionController.isConnecting();

this.contextValue = `${isConnected ? 'connected' : 'disconnected'}${
isMutable ? '' : 'Immutable'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

naming here I'm not so sure about. Immutable could also be "Preset", I just thought of making this more generic. The idea is that it's not a connection that can be removed/edited/etc.

@gagik gagik marked this pull request as ready for review January 13, 2025 09:31
@alenakhineika
Copy link
Contributor

alenakhineika commented Jan 13, 2025

It looks like we use 2 different setting.json files (see the flow described below). Also, have some thoughts about UX for this feature. Let me know what you think!

  • I opened the MongoDB settings in vscode. This file has the ~/Library/Application Support/Code - Insiders/User/settings.json path
  • Clicked "Edit in settings.json" for the mdb.presetSavedConnections setting
  • It gave me the possibility to add a connection to the mdb.presetSavedConnections array
  • It would be nice to have a placeholder in case of the empty array, so people know about the expected format
  • Can we also refresh the sidebar on save, so new connections immediately appear there? Additionally, we could add a refresh icon to the Connections level to force a manual refresh.
  • I also have noticed that we can not collapse a connected connection item in the sidebar (this issue comes from the main)
  • Then when I click "Open Workspace settings" it actually opens the /Users/alena.khineika/www/app-template/.vscode/settings.json that doesn't have any saved connections
  • Should we move the "Open Workspace Settings" CTA to the "Connections" header so we can edit the current connection and also add new ones from the sidebar?
  • The "(From Configuration)" postfix takes a lot of space. Maybe we could chat with the design team and request some kind of special icon for such connections, or add a lock emoji, so a similar approach to save the space, but still indicate that this is a special kind of connection.

void this._connectionController.loadSavedConnections();
}
});
this._context.subscriptions.push(subscription);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I understand correctly, if I add this subscription to the context, it'll auto-dispose right so no further manual handling needed? @alenakhineika

Copy link
Contributor

Choose a reason for hiding this comment

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

This is how I understand this as well.

Now when one clicks edit preset connections, we'll automatically redirect to the correct settings.json (workspace or global).
@gagik gagik force-pushed the gagik/add-save-settings branch from 915a69d to 181f801 Compare January 16, 2025 11:29
@gagik
Copy link
Contributor Author

gagik commented Jan 16, 2025

@alenakhineika the new changes with reactivity of settings and automatically deriving where the settings.json. I also made it so one can edit connections from the header, allowing for better discoverability. I think that addresses nearly all of your comments..

…eader

Running from header will automatically determine which scope to open and create a preset to edit if none are defined
@gagik gagik force-pushed the gagik/add-save-settings branch from 181f801 to 0128835 Compare January 16, 2025 11:36
@gagik gagik force-pushed the gagik/add-save-settings branch from 0850375 to ef9fa97 Compare January 17, 2025 10:14
Copy link
Contributor

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

Looks good - I mostly have style comments and a few minor suggestions.

// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
"typescript.tsc.autoDetect": "off",
"mdb.presetSavedConnections": [
Copy link
Contributor

Choose a reason for hiding this comment

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

I think preset and saved are a bit redundant here. Probably best to shorten it to presetConnections.

// 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('presetSavedConnections', [
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we extract this string literal to a constant somewhere?

Copy link
Contributor Author

@gagik gagik Jan 20, 2025

Choose a reason for hiding this comment

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

I wanted to but we don't have much precedent of this the way with do with EXTENSION_COMMANDS where we also keep the mdb. suffix which is a bit awkward

Copy link
Contributor Author

@gagik gagik Jan 20, 2025

Choose a reason for hiding this comment

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

I could create a follow-up PR to migrate all our settings into EXTENSION_SETTINGS constants for example. or introduce it here and move them later

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can introduce it here for this particular case and create a follow-up PR to move others in there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was meant to follow up on this but ended up losing this discussion; didn't seem to have a quick obvious location to introduce it here so will create a follow-up PR with everything instead

}

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.

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 🤷

];

return combinedPresetSavedConnections.map((presetConnection) => ({
id: uuidv4(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we generate different ids here as opposed to using the name? Is it because we want to allow multiple connections with the same name as presets?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That may be a good enough reason, It is also because storage saved connections use UUIDs and we end up combining the two, so was kind of thinking of it as a stricter way to stick to a "type" where IDs are arbitrary and not tied to the connection's contents.

const connection = loadedConnections[i];
const expected = expectedConnectionValues[i];
expect(connection.name).equals(expected.name);
expect(connection.connectionOptions.connectionString).contains(
Copy link
Contributor

Choose a reason for hiding this comment

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

q: why are we checking for contains here rather than equals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah actually it was because the connectionString ends up losing the trailing /, will still adjust it to be stricter and more defined

@gagik gagik force-pushed the gagik/add-save-settings branch from ef9fa97 to bf39230 Compare January 20, 2025 10:53
Copy link
Contributor

@alenakhineika alenakhineika left a comment

Choose a reason for hiding this comment

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

Looks good! I created a ticket to address a remaining issue with collapsing an active connection VSCODE-671.

@gagik
Copy link
Contributor Author

gagik commented Jan 20, 2025

@alenakhineika I see the issue now, 63c719d fixes it. Going to merge and we can verify again during release.

@gagik gagik merged commit b6e36e8 into main Jan 20, 2025
6 checks passed
@gagik gagik deleted the gagik/add-save-settings branch January 20, 2025 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants