diff --git a/src/internal-packages/database/lib/stores/collections-store.js b/src/internal-packages/database/lib/stores/collections-store.js index 25961732f76..23f26f48de5 100644 --- a/src/internal-packages/database/lib/stores/collections-store.js +++ b/src/internal-packages/database/lib/stores/collections-store.js @@ -1,6 +1,7 @@ const Reflux = require('reflux'); const StateMixin = require('reflux-state-mixin'); const CollectionsActions = require('../actions/collections-actions'); +const { NamespaceStore } = require('hadron-reflux-store'); const toNS = require('mongodb-ns'); const app = require('ampersand-app'); const _ = require('lodash'); @@ -38,7 +39,8 @@ const CollectionsStore = Reflux.createStore({ * Initialize everything that is not part of the store's state. */ init() { - this.listenToExternalStore('Sidebar.Store', this.onSidebarChange.bind(this)); + this.listenToExternalStore('App.InstanceStore', this.onInstanceChange.bind(this)); + NamespaceStore.listen(this.onNamespaceChanged.bind(this)); this.indexes = []; }, @@ -60,16 +62,20 @@ const CollectionsStore = Reflux.createStore({ column || this.state.sortColumn, order || this.state.sortOrder); }, - onSidebarChange(state) { - // continue only when a database is the activeNamespace - if (!state.activeNamespace || state.activeNamespace.includes('.')) { - return; - } + setDatabaseCollections(databases, namespace) { + const database = _.first(_.filter(databases.models, '_id', namespace)); - // retrieve the collections from sidebar object - const database = _.first(_.filter(state.databases, '_id', state.activeNamespace)); + const collections = database.collections.models.map(c => { + return { + _id: c._id, + database: c.database, + capped: c.capped, + power_of_two: c.power_of_two, + readonly: c.readonly + }; + }); - app.dataService.database(state.activeNamespace, {}, (err, res) => { + app.dataService.database(namespace, {}, (err, res) => { if (err) { this.setState({ collections: [], @@ -80,31 +86,49 @@ const CollectionsStore = Reflux.createStore({ return; } const unsorted = _(res.collections) - .filter((coll) => { - // skip system collections - const ns = toNS(coll.ns); - return !ns.system; - }) - .map((coll) => { - // re-format for table view - return _.zipObject(COLL_COLUMNS, [ - coll.name, // Collection Name - coll.document_count, // Num. Documents - coll.size / coll.document_count, // Avg. Document Size - coll.size, // Total Document Size - coll.index_count, // Num Indexes - coll.index_size // Total Index Size - ]); - }) - .value(); + .filter((coll) => { + // skip system collections + const ns = toNS(coll.ns); + return !ns.system; + }) + .map((coll) => { + // re-format for table view + return _.zipObject(COLL_COLUMNS, [ + coll.name, // Collection Name + coll.document_count, // Num. Documents + coll.size / coll.document_count, // Avg. Document Size + coll.size, // Total Document Size + coll.index_count, // Num Indexes + coll.index_size // Total Index Size + ]); + }) + .value(); this.setState({ - collections: database.collections, + collections: collections, renderedCollections: this._sort(unsorted), - database: state.activeNamespace + database: namespace }); }); }, + onNamespaceChanged(namespace) { + if (!namespace || namespace.includes('.') || namespace === this.state.database) { + return; + } + + this.setDatabaseCollections(app.instance.databases, namespace); + }, + + onInstanceChange(state) { + // continue only when a database is the activeNamespace + const namespace = NamespaceStore.ns; + if (!namespace || namespace.includes('.')) { + return; + } + + this.setDatabaseCollections(state.instance.databases, namespace); + }, + sortCollections(column, order) { this.setState({ renderedCollections: this._sort(this.state.renderedCollections, column, order), diff --git a/src/internal-packages/sidebar/lib/components/sidebar-database.jsx b/src/internal-packages/sidebar/lib/components/sidebar-database.jsx index 6ef8aa9556e..e05cb1419ae 100644 --- a/src/internal-packages/sidebar/lib/components/sidebar-database.jsx +++ b/src/internal-packages/sidebar/lib/components/sidebar-database.jsx @@ -3,14 +3,21 @@ const ipc = require('hadron-ipc'); const React = require('react'); const SidebarCollection = require('./sidebar-collection'); const { NamespaceStore } = require('hadron-reflux-store'); +const toNS = require('mongodb-ns'); class SidebarDatabase extends React.Component { - constructor() { - super(); - this.state = { expanded: true }; + constructor(props) { + super(props); + this.state = { expanded: props.expanded }; this.CollectionStore = app.appRegistry.getStore('App.CollectionStore'); } + componentWillReceiveProps(nextProps) { + this.setState({ + expanded: nextProps.expanded || toNS(nextProps.activeNamespace).database === this.props._id} + ); + } + getCollectionComponents() { if (this.state.expanded) { return this.props.collections.map(c => { @@ -75,7 +82,8 @@ class SidebarDatabase extends React.Component { SidebarDatabase.propTypes = { _id: React.PropTypes.string, activeNamespace: React.PropTypes.string.isRequired, - collections: React.PropTypes.array + collections: React.PropTypes.array, + expanded: React.PropTypes.bool }; module.exports = SidebarDatabase; diff --git a/src/internal-packages/sidebar/lib/components/sidebar.jsx b/src/internal-packages/sidebar/lib/components/sidebar.jsx index ebb080e8ecb..51fe0aff68f 100644 --- a/src/internal-packages/sidebar/lib/components/sidebar.jsx +++ b/src/internal-packages/sidebar/lib/components/sidebar.jsx @@ -19,7 +19,7 @@ class Sidebar extends React.Component { try { re = new RegExp(searchString, 'i'); } catch (e) { - re = /.*/; + re = /(?:)/; } SidebarActions.filterDatabases(re); @@ -36,7 +36,7 @@ class Sidebar extends React.Component {
- +
{ @@ -44,6 +44,7 @@ class Sidebar extends React.Component { const props = { _id: db._id, collections: db.collections, + expanded: this.props.expanded, activeNamespace: this.props.activeNamespace }; return ( @@ -60,7 +61,8 @@ class Sidebar extends React.Component { Sidebar.propTypes = { instance: React.PropTypes.object, databases: React.PropTypes.array, - activeNamespace: React.PropTypes.string + activeNamespace: React.PropTypes.string, + expanded: React.PropTypes.bool }; module.exports = Sidebar; diff --git a/src/internal-packages/sidebar/lib/stores/index.js b/src/internal-packages/sidebar/lib/stores/index.js index f424d38e697..15aa266e3e2 100644 --- a/src/internal-packages/sidebar/lib/stores/index.js +++ b/src/internal-packages/sidebar/lib/stores/index.js @@ -6,6 +6,8 @@ const { NamespaceStore } = require('hadron-reflux-store'); const debug = require('debug')('mongodb-compass:stores:sidebar'); +const BLANK = '(?:)'; + /** * Compass Sidebar store. */ @@ -37,9 +39,10 @@ const SidebarStore = Reflux.createStore({ */ getInitialState() { return { + expanded: false, instance: {}, databases: [], - filterRegex: /.*/, + filterRegex: /(?:)/, activeNamespace: '' }; }, @@ -53,12 +56,14 @@ const SidebarStore = Reflux.createStore({ onInstanceChange(state) { this.setState({ instance: state.instance, + expanded: this.state.filterRegex.source !== BLANK, databases: this._filterDatabases(this.state.filterRegex, state.instance.databases) }); }, filterDatabases(re) { this.setState({ + expanded: re.source !== BLANK, databases: this._filterDatabases(re, this.state.instance.databases), filterRegex: re }); diff --git a/test/compass-functional.test.js b/test/compass-functional.test.js index 7c062175aec..0780244a4d4 100644 --- a/test/compass-functional.test.js +++ b/test/compass-functional.test.js @@ -90,15 +90,6 @@ describe('Compass Functional Test Suite #spectron', function() { }); }); - context('when entering a filter in the sidebar', function() { - context('when entering a plain string', function() { - it('filters the list'); - }); - - context('when entering a regex', function() { - it('filters the list'); - }); - }); context('when viewing the performance view', function() { it('renders the operations graph inserts', function() { @@ -262,6 +253,44 @@ describe('Compass Functional Test Suite #spectron', function() { }); }); + context('when entering a filter in the sidebar', function() { + let dbCount; + + before(function(done) { + client.getSidebarDatabaseNames().then(function(names) { + dbCount = names.length; + done(); + }); + }); + + context('when entering a plain string', function() { + it('filters the list', function() { + return client + .inputSidebarFilter('mus') + .getSidebarDatabaseNames() + .should.eventually.include('music'); + }); + }); + + context('when entering a regex', function() { + it('filters the list', function() { + return client + .inputSidebarFilter('ad|al') + .getSidebarDatabaseNames() + .should.eventually.include('local'); + }); + }); + + context('when entering default blank regex', function() { + it('restores the sidebar', function() { + return client + .inputSidebarFilter('(?:)') + .getSidebarDatabaseNames() + .should.eventually.have.length(dbCount); + }); + }); + }); + context('when deleting a database', function() { let dbCount; diff --git a/test/support/spectron-support.js b/test/support/spectron-support.js index 98cff79fec6..e05b2e1f2ec 100644 --- a/test/support/spectron-support.js +++ b/test/support/spectron-support.js @@ -207,6 +207,9 @@ function addWaitCommands(client) { return this.waitForVisibleInCompass(selector('create-index-modal')); }); + client.addCommand('waitForSidebar', function(type) { + return this.waitForVisibleInCompass(selector('sidebar-' + type)); + }); /** * Waits for the create database modal to open. */ @@ -985,9 +988,13 @@ function addGetCommands(client) { * Get a list of database names from the sidebar. */ client.addCommand('getSidebarDatabaseNames', function() { - return this.getText(selector('sidebar-database')); + return this.waitForSidebar('database').getText(selector('sidebar-database')); }); + client.addCommand('inputSidebarFilter', function(filter) { + const base = selector('sidebar-filter-input'); + return this.setValue(base, filter); + }); /** * Get a list of database names from the home view. */