mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
New sidebar in the bottom left
* status bar (fixes #207) * moved topology options to sidebar * render topology option like snackbar * upgrade material-ui to 0.11
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
const React = require('react');
|
||||
const mui = require('material-ui');
|
||||
|
||||
const Logo = require('./logo');
|
||||
const AppStore = require('../stores/app-store');
|
||||
const Sidebar = require('./sidebar.js');
|
||||
const Status = require('./status.js');
|
||||
const Topologies = require('./topologies.js');
|
||||
const TopologyOptions = require('./topology-options.js');
|
||||
@@ -11,6 +13,8 @@ const Details = require('./details');
|
||||
const Nodes = require('./nodes');
|
||||
const RouterUtils = require('../utils/router-utils');
|
||||
|
||||
const ThemeManager = new mui.Styles.ThemeManager();
|
||||
|
||||
const ESC_KEY_CODE = 27;
|
||||
|
||||
function getStateFromStores() {
|
||||
@@ -57,6 +61,12 @@ const App = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
getChildContext: function() {
|
||||
return {
|
||||
muiTheme: ThemeManager.getCurrentTheme()
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const showingDetails = this.state.selectedNodeId;
|
||||
const versionString = this.state.version ? 'Version ' + this.state.version : '';
|
||||
@@ -73,9 +83,6 @@ const App = React.createClass({
|
||||
<div className="header">
|
||||
<Logo />
|
||||
<Topologies topologies={this.state.topologies} currentTopology={this.state.currentTopology} />
|
||||
<TopologyOptions options={this.state.currentTopologyOptions}
|
||||
activeOptions={this.state.activeTopologyOptions} />
|
||||
<Status errorUrl={this.state.errorUrl} websocketClosed={this.state.websocketClosed} />
|
||||
</div>
|
||||
|
||||
<Nodes nodes={this.state.nodes} highlightedNodeIds={this.state.highlightedNodeIds}
|
||||
@@ -83,14 +90,24 @@ const App = React.createClass({
|
||||
selectedNodeId={this.state.selectedNodeId} topMargin={topMargin}
|
||||
topologyId={this.state.currentTopologyId} />
|
||||
|
||||
<Sidebar>
|
||||
<TopologyOptions options={this.state.currentTopologyOptions}
|
||||
activeOptions={this.state.activeTopologyOptions} />
|
||||
<Status errorUrl={this.state.errorUrl} topology={this.state.currentTopology}
|
||||
websocketClosed={this.state.websocketClosed} />
|
||||
</Sidebar>
|
||||
|
||||
<div className="footer">
|
||||
{versionString}
|
||||
<a href="https://gitreports.com/issue/weaveworks/scope" target="_blank">Report an issue</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
muiTheme: React.PropTypes.object
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = App;
|
||||
|
||||
@@ -10,7 +10,7 @@ const Details = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div id="details">
|
||||
<Paper zDepth={3}>
|
||||
<Paper zDepth={3} style={{height: '100%', paddingBottom: 8}}>
|
||||
<div className="details-tools-wrapper">
|
||||
<div className="details-tools">
|
||||
<span className="fa fa-close" onClick={this.handleClickClose} />
|
||||
|
||||
15
client/app/scripts/components/sidebar.js
Normal file
15
client/app/scripts/components/sidebar.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const React = require('react');
|
||||
|
||||
const Sidebar = React.createClass({
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="sidebar">
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = Sidebar;
|
||||
@@ -14,10 +14,17 @@ const Status = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
renderTopologyStats: function(stats) {
|
||||
const statsText = `${stats.node_count} nodes, ${stats.edge_count} connections`;
|
||||
return <div className="status-stats">{statsText}</div>;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const showStats = this.props.topology && !this.props.errorUrl && !this.props.websocketClosed;
|
||||
return (
|
||||
<div className="status">
|
||||
{this.renderConnectionState(this.props.errorUrl, this.props.websocketClosed)}
|
||||
<div className="status sidebar-item">
|
||||
{showStats && this.renderTopologyStats(this.props.topology.stats)}
|
||||
{!showStats && this.renderConnectionState(this.props.errorUrl, this.props.websocketClosed)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
22
client/app/scripts/components/topology-option-action.js
Normal file
22
client/app/scripts/components/topology-option-action.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const React = require('react');
|
||||
|
||||
const AppActions = require('../actions/app-actions');
|
||||
|
||||
const TopologyOptionAction = React.createClass({
|
||||
|
||||
onClick: function(ev) {
|
||||
ev.preventDefault();
|
||||
AppActions.changeTopologyOption(this.props.option, this.props.value);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<span className="sidebar-item-action" onClick={this.onClick}>
|
||||
{this.props.value}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = TopologyOptionAction;
|
||||
@@ -1,40 +1,35 @@
|
||||
const React = require('react');
|
||||
const _ = require('lodash');
|
||||
const mui = require('material-ui');
|
||||
const DropDownMenu = mui.DropDownMenu;
|
||||
|
||||
const AppActions = require('../actions/app-actions');
|
||||
const TopologyOptionAction = require('./topology-option-action');
|
||||
|
||||
const TopologyOptions = React.createClass({
|
||||
|
||||
componentDidMount: function() {
|
||||
this.fixWidth();
|
||||
},
|
||||
|
||||
onChange: function(ev, index, item) {
|
||||
ev.preventDefault();
|
||||
AppActions.changeTopologyOption(item.option, item.payload);
|
||||
renderAction: function(action, option) {
|
||||
return (
|
||||
<TopologyOptionAction option={option} value={action} />
|
||||
);
|
||||
},
|
||||
|
||||
renderOption: function(items) {
|
||||
let selected = 0;
|
||||
let key;
|
||||
let activeText;
|
||||
const actions = [];
|
||||
const activeOptions = this.props.activeOptions;
|
||||
const menuItems = items.map(function(item, index) {
|
||||
items.forEach(function(item) {
|
||||
if (activeOptions[item.option] && activeOptions[item.option] === item.value) {
|
||||
selected = index;
|
||||
activeText = item.display;
|
||||
} else {
|
||||
actions.push(this.renderAction(item.value, item.option));
|
||||
}
|
||||
key = item.option;
|
||||
return {
|
||||
option: item.option,
|
||||
payload: item.value,
|
||||
text: item.display
|
||||
};
|
||||
});
|
||||
}, this);
|
||||
|
||||
return (
|
||||
<DropDownMenu menuItems={menuItems} onChange={this.onChange} key={key}
|
||||
selectedIndex={selected} />
|
||||
<div className="sidebar-item">
|
||||
{activeText}
|
||||
<span className="sidebar-item-actions">
|
||||
{actions}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -51,27 +46,14 @@ const TopologyOptions = React.createClass({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="topology-options" ref="container">
|
||||
<div className="topology-options">
|
||||
{options.map(function(items) {
|
||||
return this.renderOption(items);
|
||||
}, this)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
componentDidUpdate: function() {
|
||||
this.fixWidth();
|
||||
},
|
||||
|
||||
fixWidth: function() {
|
||||
const containerNode = this.refs.container.getDOMNode();
|
||||
_.each(containerNode.childNodes, function(child) {
|
||||
// set drop down width to length of current label
|
||||
const label = child.getElementsByClassName('mui-menu-label')[0];
|
||||
const width = label.getBoundingClientRect().width + 40;
|
||||
child.style.width = width + 'px';
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = TopologyOptions;
|
||||
|
||||
Reference in New Issue
Block a user