Skip to content

Commit 84c3d62

Browse files
rueckstiessdurran
authored andcommitted
COMPASS-80 add databases view + collections table (#550)
* [wip] handle all main routing internally in ./src/app/home. * COMPASS-80 add database level view, collections table * use dataService.database(), add columns, styling * 👕 fix linter errors. * COMPASS-80: Fix app registry loading * COMPASS-80: Fix zero state * COMPASS-80: Bring collection tab back
1 parent 37be329 commit 84c3d62

File tree

24 files changed

+524
-114
lines changed

24 files changed

+524
-114
lines changed

src/app/home/collection.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var MongoDBCollection = require('../models/mongodb-collection');
55
var React = require('react');
66
var ReactDOM = require('react-dom');
77
var NamespaceStore = require('hadron-reflux-store').NamespaceStore;
8+
var toNS = require('mongodb-ns');
89
var _ = require('lodash');
910

1011
var app = require('ampersand-app');
@@ -194,9 +195,12 @@ var MongoDBCollectionView = View.extend({
194195
this.schemaActions.resizeMiniCharts();
195196
}
196197
},
197-
onCollectionChanged: function() {
198-
this.ns = NamespaceStore.ns;
199-
if (!this.ns) {
198+
onCollectionChanged: function(ns) {
199+
if (ns === this.ns) {
200+
return;
201+
}
202+
this.ns = ns;
203+
if (!ns || !toNS(ns || '').collection) {
200204
this.visible = false;
201205
debug('No active collection namespace so no schema has been requested yet.');
202206
return;

src/app/home/index.js

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
var View = require('ampersand-view');
2-
var format = require('util').format;
2+
// var format = require('util').format;
33
// var IdentifyView = require('../identify');
44
var CollectionView = require('./collection');
55
var { NamespaceStore } = require('hadron-reflux-store');
@@ -55,9 +55,10 @@ var HomeView = View.extend({
5555
* TODO (imlucas) Handle state when rtss permissions not available.
5656
*/
5757
this.serverStatsView = app.appRegistry.getComponent('RTSS.ServerStats');
58+
this.collectionsTable = app.appRegistry.getComponent('Database.CollectionsTable');
5859
this.listenTo(app.instance, 'sync', this.onInstanceFetched);
5960
this.listenTo(app.connection, 'change:name', this.updateTitle);
60-
NamespaceStore.listen(this.onNamespaceChange.bind(this));
61+
NamespaceStore.listen(this.switchMainContent.bind(this));
6162
ipc.on('window:show-compass-tour', this.showTour.bind(this, true));
6263
ipc.on('window:show-network-optin', this.showOptIn.bind(this));
6364

@@ -68,15 +69,6 @@ var HomeView = View.extend({
6869
},
6970
render: function() {
7071
this.renderWithTemplate(this);
71-
var containerNode = this.queryByHook('report-zero-state');
72-
ReactDOM.render(
73-
React.createElement(this.serverStatsView, { interval: 1000 }),
74-
containerNode
75-
);
76-
NamespaceStore.listen(() => {
77-
ReactDOM.unmountComponentAtNode(containerNode);
78-
});
79-
8072
const SideBarComponent = app.appRegistry.getComponent('Sidebar.Component');
8173
ReactDOM.render(
8274
React.createElement(SideBarComponent),
@@ -88,6 +80,34 @@ var HomeView = View.extend({
8880
} else {
8981
this.tourClosed();
9082
}
83+
this.switchMainContent('');
84+
},
85+
switchMainContent: function(namespace) {
86+
if (namespace === this.ns) {
87+
debug('already selected namespace', namespace);
88+
return;
89+
}
90+
this.ns = namespace;
91+
const ns = toNS(namespace);
92+
var containerNode = this.queryByHook('report-zero-state');
93+
94+
if (ns.database === '') {
95+
// neither database nor collection are present, top level instance view
96+
ReactDOM.render(
97+
React.createElement(this.serverStatsView, {interval: 1000}),
98+
containerNode
99+
);
100+
} else if (ns.collection === '') {
101+
// a database was clicked, render collections table
102+
ReactDOM.render(
103+
React.createElement(this.collectionsTable),
104+
containerNode
105+
);
106+
} else {
107+
// unmount instance/databases view and switch to collection view
108+
ReactDOM.unmountComponentAtNode(containerNode);
109+
}
110+
this.updateTitle(namespace);
91111
},
92112
showTour: function(force) {
93113
var tourView = new TourView({force: force});
@@ -146,10 +166,10 @@ var HomeView = View.extend({
146166
}
147167
}
148168
},
149-
updateTitle: function(model) {
169+
updateTitle: function(ns) {
150170
var title = 'MongoDB Compass - ' + app.connection.instance_id;
151-
if (model) {
152-
title += '/' + model.getId();
171+
if (ns) {
172+
title += '/' + ns;
153173
}
154174
document.title = title;
155175
},
@@ -170,26 +190,27 @@ var HomeView = View.extend({
170190

171191
return database.collections.get(ns.ns);
172192
},
173-
onNamespaceChange: function() {
174-
const model = this._getCollection();
175-
176-
if (!model) {
177-
app.navigate('/');
178-
return;
179-
}
180-
181-
const collection = app.instance.collections;
182-
if (!collection.select(model)) {
183-
return debug('already selected %s', model);
184-
}
185-
186-
this.updateTitle(model);
187-
this.showNoCollectionsZeroState = false;
188-
this.showDefaultZeroState = false;
189-
app.navigate(format('schema/%s', model.getId()), {
190-
silent: true
191-
});
192-
},
193+
// onNamespaceChange: function(ns) {
194+
// const model = this._getCollection();
195+
//
196+
// // if (!model) {
197+
// // app.navigate('/');
198+
// // return;
199+
// // }
200+
//
201+
// const collection = app.instance.collections;
202+
// if (!collection.select(model)) {
203+
// return debug('already selected %s', model);
204+
// }
205+
//
206+
// this.updateTitle(model);
207+
// this.showNoCollectionsZeroState = false;
208+
// this.showDefaultZeroState = false;
209+
//
210+
// // app.navigate(format('schema/%s', model.getId()), {
211+
// // silent: true
212+
// // });
213+
// },
193214
onClickShowConnectWindow: function() {
194215
// code to close current connection window and open connect dialog
195216
ipc.call('app:show-connect-window');

src/app/index.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
@import "../internal-packages/explain/styles/index.less";
2727
@import "../internal-packages/sidebar/styles/index.less";
2828
@import "../internal-packages/validation/styles/index.less";
29+
@import "../internal-packages/database/styles/index.less";

src/internal-packages/app/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const app = require('ampersand-app');
22
const StoreConnector = require('./lib/components/store-connector');
33
const SortableTable = require('./lib/components/sortable-table');
4+
const TabNavBar = require('./lib/components/tab-nav-bar');
45
const InstanceActions = require('./lib/actions/instance-actions');
56
const InstanceStore = require('./lib/stores/instance-store');
67
const ModalStatusMessage = require('./lib/components/modal-status-message');
@@ -12,6 +13,7 @@ function activate() {
1213
app.appRegistry.registerComponent('App.StoreConnector', StoreConnector);
1314
app.appRegistry.registerComponent('App.SortableTable', SortableTable);
1415
app.appRegistry.registerComponent('App.ModalStatusMessage', ModalStatusMessage);
16+
app.appRegistry.registerComponent('App.TabNavBar', TabNavBar);
1517
app.appRegistry.registerAction('App.InstanceActions', InstanceActions);
1618
app.appRegistry.registerStore('App.InstanceStore', InstanceStore);
1719
}
@@ -23,6 +25,7 @@ function deactivate() {
2325
app.appRegistry.deregisterComponent('App.StoreConnector');
2426
app.appRegistry.deregisterComponent('App.SortableTable');
2527
app.appRegistry.deregisterComponent('App.ModalStatusMessage');
28+
app.appRegistry.deregisterComponent('App.TabNavBar');
2629
app.appRegistry.deregisterAction('App.InstanceActions');
2730
app.appRegistry.deregisterStore('App.InstanceStore');
2831
}

src/internal-packages/server-stats/lib/component/navbar-component.jsx renamed to src/internal-packages/app/lib/components/tab-nav-bar.jsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ class NavBarComponent extends React.Component {
3030

3131
renderTabs() {
3232
const listItems = _.map(this.props.tabs, (tab, idx) => (
33-
<li key={`tab-${idx}`} className={`rt-nav__tab ${idx === this.state.activeTabIndex ? 'rt-nav--selected' : ''}`}>
34-
<a onClick={this.onTabClicked.bind(this, idx)} className="rt-nav__link" href="#">{tab}</a>
33+
<li onClick={this.onTabClicked.bind(this, idx)} key={`tab-${idx}`} className={`tab-nav-bar tab-nav-bar-tab ${idx === this.state.activeTabIndex ? 'tab-nav-bar-is-selected' : ''}`}>
34+
<span className="tab-nav-bar tab-nav-bar-link" href="#">{tab}</span>
3535
</li>
3636
));
37-
return <ul className="rt-nav__tabs">{listItems}</ul>;
37+
return <ul className="tab-nav-bar tab-nav-bar-tabs">{listItems}</ul>;
3838
}
3939

4040
renderActiveView() {
@@ -44,8 +44,8 @@ class NavBarComponent extends React.Component {
4444

4545
render() {
4646
return (
47-
<div>
48-
<header className="rt-nav">
47+
<div className={`tab-nav-bar tab-nav-bar-is-${this.props.theme}-theme`}>
48+
<header className="tab-nav-bar tab-nav-bar-header">
4949
{this.renderTabs()}
5050
</header>
5151
{this.renderActiveView()}
@@ -55,13 +55,15 @@ class NavBarComponent extends React.Component {
5555
}
5656

5757
NavBarComponent.propTypes = {
58+
theme: React.PropTypes.oneOf(['dark', 'light']),
5859
activeTabIndex: React.PropTypes.number,
5960
tabs: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
6061
views: React.PropTypes.arrayOf(React.PropTypes.element).isRequired,
6162
onTabClicked: React.PropTypes.func
6263
};
6364

6465
NavBarComponent.defaultProps = {
66+
theme: 'light',
6567
activeTabIndex: 0
6668
};
6769

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
@import './sortable-table.less';
22
@import './modal-status-message.less';
3+
@import './tab-nav-bar.less';

src/internal-packages/app/styles/sortable-table.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
user-select: none;
1515
-webkit-user-select: none;
1616
padding-left: 24px;
17-
background-color: #f5f6f7;
17+
background-color: @gray8;
1818

1919
&-is-active {
2020
.sortable-table-sort-icon {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
.tab-nav-bar {
2+
3+
&-header {
4+
height: 45px;
5+
background-color: @pw;
6+
display: flex;
7+
justify-content: flex-start;
8+
align-items: flex-end;
9+
position: relative;
10+
}
11+
12+
&-tabs {
13+
display: flex;
14+
justify-content: flex-end;
15+
align-self: flex-end;
16+
margin-bottom: 0;
17+
position: absolute;
18+
top: 16px;
19+
margin-left: 10px;
20+
}
21+
22+
&-tab {
23+
height: 30px;
24+
width: 130px;
25+
margin-right: 5px;
26+
font-size: 13px;
27+
text-transform: uppercase;
28+
border-radius: 3px 3px 0 0;
29+
display: flex;
30+
justify-content: center;
31+
cursor: pointer;
32+
margin-bottom: 0;
33+
color: #43B1E5;
34+
}
35+
36+
&-tab:hover {
37+
background-color: @pw;
38+
color: @gray0;
39+
border: 1px solid @gray7;
40+
41+
.tab-nav-bar-link {
42+
color: @gray0;
43+
}
44+
}
45+
46+
&-link {
47+
margin: auto;
48+
text-transform: uppercase;
49+
font-size: 11px;
50+
font-weight: bold;
51+
color: #43B1E5;
52+
}
53+
54+
&-link:hover, &-link:active, &-link:focus {
55+
text-decoration: none;
56+
color: @gray0;
57+
}
58+
59+
&-is-selected {
60+
.tab-nav-bar-link {
61+
color: @gray0;
62+
}
63+
64+
&.tab-nav-bar-tab:hover {
65+
background-color: @gray8;
66+
border-bottom: none;
67+
}
68+
background-color: @gray8;
69+
cursor: default;
70+
border: #ebebed 1px solid;
71+
border-bottom: none;
72+
}
73+
74+
&-is-dark-theme {
75+
.tab-nav-bar-header {
76+
background-color: #2B3033;
77+
}
78+
79+
.tab-nav-bar-tab {
80+
color: #8B8D8F;
81+
}
82+
83+
.tab-nav-bar-link {
84+
color: @pw;
85+
}
86+
87+
.tab-nav-bar-is-selected {
88+
color: @pw;
89+
background-color: #3D4247;
90+
border-color: #545454;
91+
92+
&.tab-nav-bar-tab:hover {
93+
background-color: #3D4247;
94+
}
95+
}
96+
97+
.tab-nav-bar-tab:hover {
98+
background-color: #2B3033;
99+
border-color: #545454;
100+
border-bottom: none;
101+
102+
color: @pw;
103+
104+
.tab-nav-bar-link {
105+
color: @pw;
106+
}
107+
}
108+
}
109+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const app = require('ampersand-app');
2+
const CollectionsTable = require('./lib/components');
3+
4+
/**
5+
* Activate all the components in the Schema package.
6+
*/
7+
function activate() {
8+
app.appRegistry.registerComponent('Database.CollectionsTable', CollectionsTable);
9+
}
10+
11+
/**
12+
* Deactivate all the components in the Schema package.
13+
*/
14+
function deactivate() {
15+
app.appRegistry.deregisterComponent('Database.CollectionsTable');
16+
}
17+
18+
module.exports.activate = activate;
19+
module.exports.deactivate = deactivate;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const Reflux = require('reflux');
2+
3+
/**
4+
* The actions used by the server stats components.
5+
*/
6+
const Actions = Reflux.createActions([
7+
'sortCollections',
8+
'deleteCollection',
9+
'createCollection'
10+
]);
11+
12+
module.exports = Actions;

0 commit comments

Comments
 (0)