Skip to content

Commit 08de584

Browse files
author
Waley Chen
committed
Merge pull request #213 from 10gen/INT-677-import-connection-URL
INT-677 autofill connection dialog from mongodb URI in clipboard
2 parents 679622a + 9d693bd commit 08de584

File tree

3 files changed

+133
-52
lines changed

3 files changed

+133
-52
lines changed

package.json

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@
1818
"./src/index.js"
1919
],
2020
"ignore": [
21-
"bootstrap",
22-
"font-awesome",
23-
"octicons",
24-
"app",
25-
"auto-updater",
26-
"crash-reporter",
27-
"dialog",
28-
"browser-window",
29-
"menu",
30-
"jade",
31-
"scout-server",
32-
"glob",
33-
"electron-squirrel-startup",
34-
"ipc",
35-
"keytar"
21+
"app",
22+
"auto-updater",
23+
"bootstrap",
24+
"browser-window",
25+
"clipboard",
26+
"crash-reporter",
27+
"dialog",
28+
"electron-squirrel-startup",
29+
"font-awesome",
30+
"glob",
31+
"ipc",
32+
"jade",
33+
"keytar",
34+
"menu",
35+
"octicons",
36+
"scout-server"
3637
]
3738
},
3839
"fonts": [
@@ -74,7 +75,7 @@
7475
"keytar": "^3.0.0",
7576
"localforage": "^1.3.0",
7677
"mongodb-collection-model": "^0.1.1",
77-
"mongodb-connection-model": "^3.0.6",
78+
"mongodb-connection-model": "^3.0.7",
7879
"mongodb-instance-model": "^1.0.2",
7980
"mongodb-ns": "^1.0.1",
8081
"mongodb-js-metrics": "^0.2.2",

src/connect/index.js

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
var View = require('ampersand-view');
2-
var SidebarView = require('./sidebar');
31
var BehaviorStateMachine = require('./behavior');
4-
var ConnectionCollection = require('../models/connection-collection');
52
var ConnectFormView = require('./connect-form-view');
63
var Connection = require('../models/connection');
7-
var debug = require('debug')('scout:connect:index');
4+
var ConnectionCollection = require('../models/connection-collection');
5+
var MongoDBConnection = require('mongodb-connection-model');
6+
var SidebarView = require('./sidebar');
7+
var View = require('ampersand-view');
8+
89
var _ = require('lodash');
910
var app = require('ampersand-app');
1011
var format = require('util').format;
1112
var metrics = require('mongodb-js-metrics');
1213

14+
var remote = window.require('remote');
15+
var dialog = remote.require('dialog');
16+
var Clipboard = remote.require('clipboard');
17+
var BrowserWindow = remote.require('browser-window');
18+
19+
var debug = require('debug')('scout:connect:index');
20+
1321
/**
1422
* AuthenticationOptionCollection
1523
*/
@@ -61,6 +69,10 @@ var ConnectView = View.extend({
6169
previousSslMethod: {
6270
type: 'string',
6371
default: null
72+
},
73+
clipboardText: {
74+
type: 'string',
75+
default: ''
6476
}
6577
},
6678
derived: {
@@ -223,15 +235,60 @@ var ConnectView = View.extend({
223235
});
224236

225237
this.registerSubview(this.form);
238+
226239
this.listenToAndRun(this, 'change:authMethod',
227240
this.replaceAuthMethodFields.bind(this));
241+
228242
this.listenToAndRun(this, 'change:sslMethod',
229243
this.replaceSslMethodFields.bind(this));
230244

245+
this.listenToAndRun(app, 'connect-window-focused',
246+
this.onConnectWindowFocused.bind(this));
247+
231248
// always start in NEW_EMPTY state
232249
this.dispatch('new connection clicked');
233250
},
234251

252+
// === MongoDB URI clipboard Handling
253+
254+
/**
255+
* Called when the user clicked "YES" in the message dialog after
256+
* a MongoDB URI was detected.
257+
*/
258+
autofillFromClipboard: function() {
259+
this.connection = MongoDBConnection.from(this.clipboardText);
260+
this.updateForm();
261+
},
262+
263+
/**
264+
* Called when the Connect Window receives focus.
265+
*/
266+
onConnectWindowFocused: function() {
267+
var clipboardText = Clipboard.readText();
268+
if (clipboardText === this.clipboardText) {
269+
// we have seen this value already, don't ask user again
270+
return;
271+
}
272+
this.clipboardText = clipboardText;
273+
274+
if (MongoDBConnection.isURI(clipboardText)) {
275+
debug('MongoDB URI detected.', clipboardText);
276+
// ask user if Compass should use it to fill out form
277+
dialog.showMessageBox(BrowserWindow.getFocusedWindow(), {
278+
type: 'info',
279+
message: 'MongoDB connection string detected',
280+
detail: 'Compass detected a MongoDB connection string in your '
281+
+ 'clipboard. Do you want to use the connection string to '
282+
+ 'fill out this form?',
283+
buttons: ['Yes', 'No']
284+
}, function(response) {
285+
if (response === 0) {
286+
this.autofillFromClipboard();
287+
}
288+
}.bind(this));
289+
}
290+
},
291+
235292
connectionNameEmptyChanged: function() {
236293
if (this.connectionNameEmpty) {
237294
this.dispatch('name removed');
@@ -240,7 +297,6 @@ var ConnectView = View.extend({
240297
}
241298
},
242299

243-
244300
// === External hooks
245301

246302
/**

src/electron/window-manager.js

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,29 @@
33
* [BrowserWindow](https://github.com/atom/electron/blob/master/docs/api/browser-window.md)
44
* class
55
*/
6-
var path = require('path');
7-
var _ = require('lodash');
8-
var app = require('app');
6+
97
var AppMenu = require('./menu');
108
var BrowserWindow = require('browser-window');
9+
var Notifier = require('node-notifier');
10+
var Path = require('path');
11+
12+
var _ = require('lodash');
13+
var app = require('app');
1114
var config = require('./config');
1215
var debug = require('debug')('scout-electron:window-manager');
1316
var dialog = require('dialog');
14-
var Notifier = require('node-notifier');
1517

1618
/**
1719
* When running in electron, we're in `RESOURCES/src/electron`.
1820
*/
19-
var RESOURCES = path.resolve(__dirname, '../../');
21+
var RESOURCES = Path.resolve(__dirname, '../../');
22+
var SCOUT_ICON_PATH = RESOURCES + '/images/scout.png';
2023

2124
/**
2225
* The app's HTML shell which is the output of `./src/index.jade`
2326
* created by the `build:pages` gulp task.
2427
*/
25-
var DEFAULT_URL = 'file://' + path.join(RESOURCES, 'index.html#connect');
28+
var DEFAULT_URL = 'file://' + Path.join(RESOURCES, 'index.html#connect');
2629

2730
/**
2831
* We want the Connect dialog window to be special
@@ -36,6 +39,38 @@ var connectWindow;
3639
// since this code was laid down.
3740
var windowsOpenCount = 0;
3841

42+
function isConnectDialog(url) {
43+
return url === DEFAULT_URL;
44+
}
45+
46+
// returns true if the application is a single instance application otherwise
47+
// focus the second window (which we'll quit from) and return false
48+
// see "app.makeSingleInstance" in https://github.com/atom/electron/blob/master/docs/api/app.md
49+
function isSingleInstance(_window) {
50+
var isNotSingle = app.makeSingleInstance(function(commandLine, workingDirectory) {
51+
debug('Someone tried to run a second instance! We should focus our window', {
52+
commandLine: commandLine,
53+
workingDirectory: workingDirectory
54+
});
55+
if (_window) {
56+
if (_window.isMinimized()) {
57+
_window.restore();
58+
}
59+
_window.focus();
60+
}
61+
return true;
62+
});
63+
64+
return !isNotSingle;
65+
}
66+
67+
function openDevTools() {
68+
debug('openDevTools()');
69+
AppMenu.lastFocusedWindow.openDevTools({
70+
detach: true
71+
});
72+
}
73+
3974
/**
4075
* Call me instead of using `new BrowserWindow()` directly because i'll:
4176
*
@@ -66,23 +101,7 @@ module.exports.create = function(opts) {
66101
});
67102
AppMenu.load(_window);
68103

69-
// makes the application a single instance application
70-
// see "app.makeSingleInstance" in https://github.com/atom/electron/blob/master/docs/api/app.md
71-
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
72-
debug('Someone tried to run a second instance! We should focus our window', {
73-
commandLine: commandLine,
74-
workingDirectory: workingDirectory
75-
});
76-
if (_window) {
77-
if (_window.isMinimized()) {
78-
_window.restore();
79-
}
80-
_window.focus();
81-
}
82-
return true;
83-
});
84-
85-
if (shouldQuit) {
104+
if (!isSingleInstance(_window)) {
86105
app.quit();
87106
return null;
88107
}
@@ -99,9 +118,13 @@ module.exports.create = function(opts) {
99118
});
100119
});
101120

102-
if (opts.url === DEFAULT_URL) { // if it's the connect dialog
121+
if (isConnectDialog(opts.url)) {
103122
AppMenu.hideConnect(_window);
104123
connectWindow = _window;
124+
connectWindow.on('focus', function() {
125+
debug('connect window focused.');
126+
connectWindow.webContents.send('message', 'connect-window-focused');
127+
});
105128
connectWindow.on('closed', function() {
106129
debug('connect window closed.');
107130
connectWindow = null;
@@ -167,10 +190,17 @@ app.on('show share submenu', function() {
167190
app.on('show bugsnag OS notification', function(errorMsg) {
168191
if (_.contains(['development', 'testing'], process.env.NODE_ENV)) {
169192
Notifier.notify({
170-
'icon': RESOURCES + '/images/scout.png',
193+
'icon': SCOUT_ICON_PATH,
171194
'message': errorMsg,
172195
'title': 'MongoDB Compass Exception',
173196
'wait': true
197+
}, function(err, resp) {
198+
if (err) {
199+
debug(err);
200+
}
201+
if (resp === 'Activate\n') {
202+
openDevTools();
203+
}
174204
});
175205
}
176206
});
@@ -183,12 +213,6 @@ app.on('show bugsnag OS notification', function(errorMsg) {
183213
*/
184214
app.on('ready', function() {
185215
app.emit('show connect dialog');
186-
187-
Notifier.on('click', function() {
188-
AppMenu.lastFocusedWindow.openDevTools({
189-
detach: true
190-
});
191-
});
192216
});
193217

194218
var ipc = require('ipc');

0 commit comments

Comments
 (0)