Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 1 addition & 2 deletions dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ $ (cd dashboard/assets && ./node_modules/.bin/webpack --watch)
$ geth --dashboard --dashboard.assets=dashboard/assets/public --vmodule=dashboard=5
```

To bundle up the final UI into Geth, run `webpack` and `go generate`:
To bundle up the final UI into Geth, run `go generate`:

```
$ (cd dashboard/assets && ./node_modules/.bin/webpack)
$ go generate ./dashboard
```

Expand Down
38,404 changes: 38,365 additions & 39 deletions dashboard/assets.go

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions dashboard/assets/components/Body.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import withStyles from 'material-ui/styles/withStyles';

import SideBar from './SideBar.jsx';
import Content from "./Content.jsx";

// Styles for the Body component.
const styles = theme => ({
body: {
display: 'flex',
width: '100%',
height: '100%',
},
});

// Body renders the body of the dashboard.
@withStyles(styles)
class Body extends Component {
render() {
const {classes} = this.props; // The classes property is injected by withStyles().

return (
<div className={classes.body}>
<SideBar
opened={this.props.opened}
changeContent={this.props.changeContent}
/>
<Content
active={this.props.active}
memory={this.props.memory}
traffic={this.props.traffic}
logs={this.props.logs}
shouldUpdate={this.props.shouldUpdate}
/>
</div>
);
}
}

Body.propTypes = {
opened: PropTypes.bool.isRequired,
changeContent: PropTypes.func.isRequired,
active: PropTypes.string.isRequired,
memory: PropTypes.array.isRequired,
traffic: PropTypes.array.isRequired,
logs: PropTypes.array.isRequired,
shouldUpdate: PropTypes.object.isRequired,
};

export default Body;
48 changes: 48 additions & 0 deletions dashboard/assets/components/ChartGrid.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Grid from 'material-ui/Grid';
import {ResponsiveContainer} from 'recharts';


// ChartGrid renders a grid container for responsive charts.
// The children are Recharts components extended with the Material-UI's xs property.
class ChartGrid extends Component {
render() {
return (
<Grid container spacing={this.props.spacing}>
{
React.Children.map(this.props.children, child => (
<Grid item xs={child.props.xs}>
<ResponsiveContainer width="100%" height={child.props.height}>
{React.cloneElement(child, {data: child.props.values.map(value => ({value: value}))})}
</ResponsiveContainer>
</Grid>
))
}
</Grid>
);
}
}

ChartGrid.propTypes = {
spacing: PropTypes.number.isRequired,
};

export default ChartGrid;
16 changes: 8 additions & 8 deletions dashboard/assets/components/Common.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ export const LIMIT = {
traffic: 200, // Maximum number of traffic data samples.
log: 200, // Maximum number of logs.
};

// The sidebar menu and the main content are rendered based on these elements.
export const TAGS = (() => {
const T = {
home: { title: "Home", },
chain: { title: "Chain", },
transactions: { title: "Transactions", },
network: { title: "Network", },
system: { title: "System", },
logs: { title: "Logs", },
home: { title: "Home", icon: "home", },
chain: { title: "Chain", icon: "link", },
transactions: { title: "Transactions", icon: "credit-card", },
network: { title: "Network", icon: "globe", },
system: { title: "System", icon: "tachometer", },
logs: { title: "Logs", icon: "list", },
};
// Using the key is circumstantial in some cases, so it is better to insert it also as a value.
// This way the mistyping is prevented.
Expand All @@ -48,5 +49,4 @@ export const DATA_KEYS = (() => {
return DK;
})();

// Temporary - taken from Material-UI
export const DRAWER_WIDTH = 240;
export const DURATION = 200;
71 changes: 71 additions & 0 deletions dashboard/assets/components/Content.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import withStyles from 'material-ui/styles/withStyles';

import Home from './Home.jsx';
import {TAGS} from './Common.jsx';

// Styles for the Content component.
const styles = theme => ({
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
padding: theme.spacing.unit * 3,
overflow: 'auto',
},
});

// Content renders the chosen content.
@withStyles(styles)
class Content extends Component {
render() {
const {classes, active, memory, traffic, logs, shouldUpdate} = this.props;

let content = null;
switch(active) {
case TAGS.home.id:
content = <Home memory={memory} traffic={traffic} shouldUpdate={shouldUpdate} />;
break;
case TAGS.chain.id:
content = <div>Chain is under construction.</div>;
break;
case TAGS.transactions.id:
content = <div>Transactions is under construction.</div>;
break;
case TAGS.network.id:
content = <div>Network is under construction.</div>;
break;
case TAGS.system.id:
content = <div>System is under construction.</div>;
break;
case TAGS.logs.id:
content = <div>{logs.map((log, index) => <div key={index}>{log}</div>)}</div>;
}

return <div className={classes.content}>{content}</div>;
}
}

Content.propTypes = {
active: PropTypes.string.isRequired,
shouldUpdate: PropTypes.object.isRequired,
};

export default Content;
45 changes: 19 additions & 26 deletions dashboard/assets/components/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,29 @@
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {withStyles} from 'material-ui/styles';

import SideBar from './SideBar.jsx';
import withStyles from 'material-ui/styles/withStyles';

import Header from './Header.jsx';
import Main from "./Main.jsx";
import {isNullOrUndefined, LIMIT, TAGS, DATA_KEYS,} from "./Common.jsx";
import Body from './Body.jsx';
import {isNullOrUndefined, LIMIT, TAGS, DATA_KEYS} from "./Common.jsx";

// Styles for the Dashboard component.
const styles = theme => ({
appFrame: {
position: 'relative',
dashboard: {
display: 'flex',
flexFlow: 'column',
width: '100%',
height: '100%',
background: theme.palette.background.default,
zIndex: 1,
overflow: 'hidden',
},
});

// Dashboard is the main component, which renders the whole page, makes connection with the server and listens for messages.
// When there is an incoming message, updates the page's content correspondingly.
@withStyles(styles)
class Dashboard extends Component {
constructor(props) {
super(props);
Expand All @@ -45,7 +47,7 @@ class Dashboard extends Component {
memory: [],
traffic: [],
logs: [],
shouldUpdate: {},
shouldUpdate: {}, // contains the labels of the incoming sample types
};
}

Expand Down Expand Up @@ -74,7 +76,6 @@ class Dashboard extends Component {

// update analyzes the incoming message, and updates the charts' content correspondingly.
update = msg => {
console.log(msg);
this.setState(prevState => {
let newState = [];
newState.shouldUpdate = {};
Expand Down Expand Up @@ -121,9 +122,9 @@ class Dashboard extends Component {
});
};

// The change of the active label on the SideBar component will trigger a new render in the Main component.
changeContent = active => {
this.setState(prevState => prevState.active !== active ? {active: active} : {});
// changeContent sets the active label, which is used at the content rendering.
changeContent = newActive => {
this.setState(prevState => prevState.active !== newActive ? {active: newActive} : {});
};

openSideBar = () => {
Expand All @@ -135,22 +136,18 @@ class Dashboard extends Component {
};

render() {
// The classes property is injected by withStyles().
const {classes} = this.props;
const {classes} = this.props; // The classes property is injected by withStyles().

return (
<div className={classes.appFrame}>
<div className={classes.dashboard}>
<Header
opened={this.state.sideBar}
open={this.openSideBar}
openSideBar={this.openSideBar}
closeSideBar={this.closeSideBar}
/>
<SideBar
<Body
opened={this.state.sideBar}
close={this.closeSideBar}
changeContent={this.changeContent}
/>
<Main
opened={this.state.sideBar}
active={this.state.active}
memory={this.state.memory}
traffic={this.state.traffic}
Expand All @@ -162,8 +159,4 @@ class Dashboard extends Component {
}
}

Dashboard.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(Dashboard);
export default Dashboard;
Loading