Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
728fee1
Adding feature flags for connect
imlucas Sep 24, 2015
8ae50c6
:construction: refactoring connect
imlucas Sep 24, 2015
f67c05b
make things work
imlucas Sep 24, 2015
9fff452
implement untitled
imlucas Sep 24, 2015
42099c1
open devtools detached when in dev mode for all new windows
imlucas Sep 25, 2015
eb09506
kernel 2.6.x doesn't support SCRAM so try again w/ CR
imlucas Sep 25, 2015
defdbf9
INT-635: resize connect window with auth settings visibility toggled
imlucas Sep 25, 2015
c967fd2
update connect copy + icon spacing
imlucas Sep 25, 2015
e6f744b
fix duplicate connections being added to sidebar
imlucas Sep 25, 2015
68295bd
:bug: Populate auth fields when using a connection
imlucas Sep 25, 2015
00fd9d4
:arrow_up: mongodb-connection-model@0.0.3 + use DEFAULT `auth_mechanism`
imlucas Sep 25, 2015
91f6c73
:arrow_up: scout-server@0.2.2 scout-client@0.1.2
imlucas Sep 25, 2015
5aa592f
:fire: replace scout-brain with new mongodb-*-*models
imlucas Sep 25, 2015
18489a2
:arrow_up: mongodb-js-precommit@0.2.2
imlucas Sep 25, 2015
9345454
:arrow_right: mongodb-js-fmt@0.0.3
imlucas Sep 25, 2015
ee6dd1f
Show a :lock: next to connections which use auth
imlucas Sep 25, 2015
28d1019
:art: overhaul app initialization
imlucas Sep 25, 2015
104653f
:tshirt: found by latest fmt updates
imlucas Sep 25, 2015
0d07868
:bug: missed a method rename
imlucas Sep 25, 2015
2eaa856
:arrow_up: scout-client@0.1.4
imlucas Sep 25, 2015
eb735cb
:art: Make status bar have an api for fatal's
imlucas Sep 25, 2015
9aff345
:rage: switch back to retry hack as the driver throws an error if DEF…
imlucas Sep 25, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"start": "gulp dev",
"release": "gulp release",
"test": "mocha",
"check": "mongodb-js-precommit"
"check": "mongodb-js-precommit",
"fmt": "mongodb-js-fmt src/{**/*.js,*.js}"
},
"pre-commit": [
"check",
Expand All @@ -67,10 +68,14 @@
"dependencies": {
"ampersand-form-view": "^5.1.1",
"ampersand-input-view": "^5.0.0",
"ampersand-rest-collection": "^5.0.0",
"debug": "^2.2.0",
"electron-squirrel-startup": "^0.1.2",
"mongodb-connection-model": "0.0.2",
"scout-server": "http://bin.mongodb.org/js/scout-server/v0.2.1/scout-server-0.2.1.tar.gz"
"mongodb-collection-model": "^0.1.0",
"mongodb-connection-model": "^0.0.3",
"mongodb-instance-model": "^0.2.0",
"mongodb-ns": "^1.0.0",
"scout-server": "http://bin.mongodb.org/js/scout-server/v0.2.2/scout-server-0.2.2.tar.gz"
},
"devDependencies": {
"ampersand-app": "^1.0.4",
Expand Down Expand Up @@ -114,7 +119,8 @@
"mocha": "^2.2.5",
"moment": "^2.10.3",
"mongodb-extended-json": "^1.3.1",
"mongodb-js-precommit": "^0.1.2",
"mongodb-js-precommit": "^0.2.2",
"mongodb-js-fmt": "^0.0.3",
"mongodb-language-model": "^0.2.1",
"mongodb-schema": "^3.3.0",
"mousetrap": "^1.5.3",
Expand All @@ -130,8 +136,7 @@
"raf": "^3.0.0",
"run-sequence": "^1.1.2",
"run-series": "^1.1.2",
"scout-brain": "http://bin.mongodb.org/js/scout-brain/v0.0.2/scout-brain-0.0.2.tar.gz",
"scout-client": "http://bin.mongodb.org/js/scout-client/v0.1.2/scout-client-0.1.2.tar.gz",
"scout-client": "http://bin.mongodb.org/js/scout-client/v0.1.4/scout-client-0.1.4.tar.gz",
"stream-combiner2": "^1.0.2",
"uuid": "^2.0.1",
"vinyl-buffer": "^1.0.0",
Expand Down
152 changes: 116 additions & 36 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint no-console:0 */

var pkg = require('../package.json');
var app = require('ampersand-app');
app.extend({
Expand All @@ -8,7 +10,9 @@ app.extend({
'App Version': pkg.version
}
});
require('./bugsnag').listen(app);

var bugsnag = require('./bugsnag');
bugsnag.listen(app);

var _ = require('lodash');
var domReady = require('domready');
Expand All @@ -17,6 +21,13 @@ var getOrCreateClient = require('scout-client');
var ViewSwitcher = require('ampersand-view-switcher');
var View = require('ampersand-view');
var localLinks = require('local-links');

var QueryOptions = require('./models/query-options');
var Connection = require('./models/connection');
var MongoDBInstance = require('./models/mongodb-instance');
var Router = require('./router');
var Statusbar = require('./statusbar');

var debug = require('debug')('scout:app');

// Inter-process communication with main process (Electron window)
Expand Down Expand Up @@ -78,24 +89,62 @@ var Application = View.extend({
/**
* Enable/Disable features with one global switch
*/
features: 'object'
features: 'object',
clientStartedAt: 'date',
clientStalledTimeout: 'number'
},
events: {
'click a': 'onLinkClick'
},
/**
* We have what we need, we can now start our router and show the appropriate page!
*/
_onDOMReady: function() {
this.el = document.querySelector('#application');
this.render();
onClientReady: function() {
debug('Client ready! Took %dms to become readable',
new Date() - this.clientStartedAt);

debug('clearing client stall timeout...');
clearTimeout(this.clientStalledTimeout);

debug('initializing singleton models... ');
this.queryOptions = new QueryOptions();
this.volatileQueryOptions = new QueryOptions();
this.instance = new MongoDBInstance();

this.startRouter();
},
startRouter: function() {
this.router = new Router();
debug('Listening for page changes from the router...');
this.listenTo(this.router, 'page', this.onPageChange);

debug('Starting router...');
this.router.history.start({
pushState: false,
root: '/'
});
app.statusbar.hide();
},
onFatalError: function(id, err) {
debug('clearing client stall timeout...');
clearTimeout(this.clientStalledTimeout);

console.error('Fatal Error!: ', id, err);
bugsnag.notifyException(err, 'Fatal Error: ' + id);
app.statusbar.fatal(err);
},
// ms we'll wait for a `scout-client` instance
// to become readable before giving up and showing
// a fatal error message.
CLIENT_STALLED_REDLINE: 5 * 1000,
startClientStalledTimer: function() {
this.clientStartedAt = new Date();

debug('Starting client stalled timer to bail in %dms...',
this.CLIENT_STALLED_REDLINE);

this.clientStalledTimeout = setTimeout(function() {
this.onFatalError('client stalled',
new Error('Error connecting to MongoDB. '
+ 'Please reload the page.'));
}.bind(this), this.CLIENT_STALLED_REDLINE);
},
/**
* When you want to go to a different page in the app or just save
Expand All @@ -117,15 +166,25 @@ var Application = View.extend({
trigger: !options.silent
});
},
/**
* Called a soon as the DOM is ready so we can
* start showing status indicators as
* quickly as possible.
*/
render: function() {
debug('Rendering app container...');

this.el = document.querySelector('#application');
this.renderWithTemplate(this);
this.pageSwitcher = new ViewSwitcher(this.queryByHook('layout-container'), {
show: function() {
document.scrollTop = 0;
}
});

this.statusbar.el = this.queryByHook('statusbar');
debug('rendering statusbar...');
this.statusbar = new Statusbar({
el: this.queryByHook('statusbar')
});
this.statusbar.render();
},
onPageChange: function(view) {
Expand Down Expand Up @@ -153,47 +212,68 @@ var state = new Application({
connection_id: connection_id
});

var QueryOptions = require('./models/query-options');
var Connection = require('./models/connection');
var MongoDBInstance = require('./models/mongodb-instance');
var Router = require('./router');
var Statusbar = require('./statusbar');

function start() {
state.router = new Router();
domReady(state._onDOMReady.bind(state));
}
// @todo (imlucas): Feature flags can be overrideen
// via `window.localStorage`.
var FEATURES = {
querybuilder: true,
'Connect with SSL': false,
'Connect with Kerberos': true,
'Connect with LDAP': false,
'Connect with X.509': false
};

app.extend({
client: null,
// @note (imlucas): Backwards compat for querybuilder
features: FEATURES,
/**
* Check whether a feature flag is currently enabled.
*
* @param {String} id - A key in `FEATURES`.
* @return {Boolean}
*/
isFeatureEnabled: function(id) {
return FEATURES[id] === true;
},
init: function() {
// feature flags
this.features = {
querybuilder: true
};
state.statusbar = new Statusbar();
domReady(function() {
state.render();

if (!connection_id) {
// Not serving a part of the app which uses the client,
// so we can just start everything up now.
state.startRouter();
return;
}

app.statusbar.show('Retrieving connection details...');

if (connection_id) {
state.connection = new Connection({
_id: connection_id
});


debug('looking up connection `%s`...', connection_id);
state.connection.fetch({
success: function() {
debug('got connection `%j`...', state.connection.serialize());
app.client = getOrCreateClient(app.endpoint, state.connection.serialize());
app.statusbar.show('Connection details loaded! Initializing client...');

var endpoint = app.endpoint;
var connection = state.connection.serialize();

app.client = getOrCreateClient(endpoint, connection)
.on('readable', state.onClientReady.bind(state))
.on('error', state.onFatalError.bind(state, 'create client'));

state.queryOptions = new QueryOptions();
state.volatileQueryOptions = new QueryOptions();
state.instance = new MongoDBInstance();
start();
state.startClientStalledTimer();
},
error: function() {
// @todo (imlucas) `ampersand-sync-localforage` currently drops
// the real error so for now just use a generic.
state.onFatalError(state, 'fetch connection',
new Error('Error retrieving connection. Please reload the page.'));
}
});
} else {
start();
}
});
// set up ipc
ipc.on('message', state.onMessageReceived.bind(this));
},
Expand Down
2 changes: 2 additions & 0 deletions src/bugsnag.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ function beforeNotify(d) {
debug('redacted bugsnag report\n', JSON.stringify(d, null, 2));
}

module.exports = bugsnag;

/**
* Configure bugsnag's api client which attaches a handler to
* `window.onerror` so any uncaught exceptions are trapped and logged
Expand Down
7 changes: 0 additions & 7 deletions src/connect/auth-fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ module.exports = {
password,
database_name
],

'MONGODB-CR': [
username,
password,
database_name
],

GSSAPI: [
username,
service_name
Expand Down
32 changes: 4 additions & 28 deletions src/connect/connect-form-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,7 @@ var ConnectFormView = FormView.extend({
*/
submitCallback: function(obj) {
debug('form submitted', obj);

var connection = new Connection(obj);

var existingName = this.parent.checkExistingConnection(connection);
if (existingName) {
this.valid = false;
this.setValue('name', existingName);
return;
}

existingName = this.parent.checkExistingName(connection);
if (existingName) {
this.valid = false;
return;
}

app.statusbar.show();

debug('testing credentials are usable...');
connection.test(function(err) {
app.statusbar.hide();
if (err) {
this.parent.onConnectionError(err, connection);
return;
}
this.parent.onConnectionAccepted(connection);
}.bind(this));
this.parent.onFormSubmitted(new Connection(obj));
},
clean: function(obj) {
// clean up the form values here, e.g. conversion to numbers etc.
Expand Down Expand Up @@ -73,6 +47,8 @@ var ConnectFormView = FormView.extend({
* These are the default form fields that are always present in the connect dialog. Auth and
* SSL fields are added/removed dynamically, depending on whether the options are expanded or
* collapsed.
*
* @return {Array<InputView>}
*/
fields: function() {
return [
Expand Down Expand Up @@ -110,7 +86,7 @@ var ConnectFormView = FormView.extend({
template: require('./input-saveas.jade'),
el: this.parent.queryByHook('saveas-subview'),
name: 'name',
placeholder: 'Connection Name',
placeholder: 'e.g. Shared Dev, Stats Box, PRODUCTION',
required: false
})
];
Expand Down
7 changes: 6 additions & 1 deletion src/connect/connection.jade
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
li.list-group-item
.close-icon(data-hook='close')
i.fa.fa-close
a(data-hook='name')
a()
span(data-hook='name')
span(style='padding-left: 4px;',
data-hook='has-auth',
title='This connection has authentication enabled.')
i.fa.fa-lock
Loading