mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
dashboard: update npm packages, improve UI, rebase
This commit is contained in:
parent
6d6c0e69a8
commit
0f74ca792f
5 changed files with 11008 additions and 12534 deletions
21830
dashboard/assets.go
21830
dashboard/assets.go
File diff suppressed because one or more lines are too long
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
import React, {Component} from 'react';
|
||||
|
||||
import withStyles from '@material-ui/core/styles/withStyles';
|
||||
import Table from '@material-ui/core/Table';
|
||||
import TableHead from '@material-ui/core/TableHead';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
|
|
@ -27,10 +28,11 @@ import Grid from '@material-ui/core/Grid/Grid';
|
|||
import Typography from '@material-ui/core/Typography';
|
||||
import {AreaChart, Area, Tooltip, YAxis} from 'recharts';
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faCircle as fasCircle} from '@fortawesome/free-solid-svg-icons';
|
||||
import {faCircle as fasCircle} from '@fortawesome/free-solid-svg-icons'; // More icons at fontawesome.com/icons
|
||||
import {faCircle as farCircle} from '@fortawesome/free-regular-svg-icons';
|
||||
import {faClipboard as farClipboard} from '@fortawesome/free-regular-svg-icons';
|
||||
import convert from 'color-convert';
|
||||
import ScrollArea from 'react-scrollbar';
|
||||
import {Scrollbars} from 'react-custom-scrollbars';
|
||||
|
||||
import CustomTooltip, {bytePlotter, multiplier} from 'CustomTooltip';
|
||||
import type {Network as NetworkType, PeerEvent} from '../types/content';
|
||||
|
|
@ -386,7 +388,6 @@ const styles = {
|
|||
marginLeft: 5,
|
||||
},
|
||||
table: {
|
||||
background: '#212121',
|
||||
borderCollapse: 'unset',
|
||||
padding: 5,
|
||||
},
|
||||
|
|
@ -410,6 +411,16 @@ const styles = {
|
|||
},
|
||||
};
|
||||
|
||||
// themeStyles returns the styles generated from the theme for the component.
|
||||
const themeStyles = theme => ({
|
||||
title: {
|
||||
color: theme.palette.common.white,
|
||||
},
|
||||
table: {
|
||||
background: theme.palette.grey[900],
|
||||
},
|
||||
});
|
||||
|
||||
// limitedWidthStyle returns a style object which cuts the long text with three dots.
|
||||
const limitedWidthStyle = (width) => {
|
||||
return {
|
||||
|
|
@ -421,6 +432,7 @@ const limitedWidthStyle = (width) => {
|
|||
};
|
||||
|
||||
export type Props = {
|
||||
classes: Object, // injected by withStyles()
|
||||
container: Object,
|
||||
content: NetworkType,
|
||||
shouldUpdate: Object,
|
||||
|
|
@ -458,6 +470,49 @@ class Network extends Component<Props, State> {
|
|||
});
|
||||
};
|
||||
|
||||
lesList = () => {
|
||||
const list = [];
|
||||
Object.values(this.props.content.peers.bundles).forEach((bundle) => {
|
||||
if (!bundle.knownPeers || Object.keys(bundle.knownPeers).length < 1) {
|
||||
return;
|
||||
}
|
||||
Object.entries(bundle.knownPeers).forEach(([enode, peer]) => {
|
||||
if (peer.les === '' || peer.eth !== '') {
|
||||
return;
|
||||
}
|
||||
list.push({enode, name: peer.name, location: bundle.location, protocols: peer.protocols});
|
||||
});
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
ethList = () => {
|
||||
const list = [];
|
||||
Object.values(this.props.content.peers.bundles).forEach((bundle) => {
|
||||
if (!bundle.knownPeers || Object.keys(bundle.knownPeers).length < 1) {
|
||||
return;
|
||||
}
|
||||
Object.entries(bundle.knownPeers).forEach(([enode, peer]) => {
|
||||
if (peer.eth === '' && peer.les !== '') {
|
||||
return;
|
||||
}
|
||||
list.push({enode, name: peer.name, location: bundle.location, protocols: peer.protocols});
|
||||
});
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
attemptList = () => {
|
||||
const list = [];
|
||||
Object.entries(this.props.content.peers.bundles).forEach(([addr, bundle]) => {
|
||||
if (!bundle.attempts) {
|
||||
return;
|
||||
}
|
||||
list.push({addr, location: bundle.location, attempts: bundle.attempts});
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
knownPeerTableRow = (addr, enode, bundle, peer, showTraffic, proto) => {
|
||||
const ingressValues = peer.ingress.map(({value}) => ({ingress: value || 0.001}));
|
||||
const egressValues = peer.egress.map(({value}) => ({egress: -value || -0.001}));
|
||||
|
|
@ -500,95 +555,103 @@ class Network extends Component<Props, State> {
|
|||
{bundle.shortLocation}
|
||||
</TableCell>
|
||||
<TableCell style={styles.tableCell}>
|
||||
<AreaChart
|
||||
width={trafficChartWidth}
|
||||
height={trafficChartHeight}
|
||||
data={ingressValues}
|
||||
margin={{top: 5, right: 5, bottom: 0, left: 5}}
|
||||
syncId={`peerIngress_${addr}_${enode}`}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={`ingressGradient_${addr}_${enode}`} x1='0' y1='1' x2='0' y2='0'>
|
||||
{peer.ingressGradient
|
||||
&& peer.ingressGradient.map(({offset, color}, i) => (
|
||||
<stop
|
||||
key={`ingressStop_${addr}_${enode}_${i}`}
|
||||
offset={`${offset}%`}
|
||||
stopColor={color}
|
||||
/>
|
||||
))}
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Tooltip cursor={false} content={<CustomTooltip tooltip={bytePlotter('Download')} />} />
|
||||
<YAxis hide scale='sqrt' domain={[0.001, dataMax => Math.max(dataMax, 0)]} />
|
||||
<Area
|
||||
dataKey='ingress'
|
||||
isAnimationActive={false}
|
||||
type='monotone'
|
||||
fill={`url(#ingressGradient_${addr}_${enode})`}
|
||||
stroke={peer.ingressGradient[peer.ingressGradient.length - 1].color}
|
||||
strokeWidth={chartStrokeWidth}
|
||||
/>
|
||||
</AreaChart>
|
||||
<AreaChart
|
||||
width={trafficChartWidth}
|
||||
height={trafficChartHeight}
|
||||
data={egressValues}
|
||||
margin={{top: 0, right: 5, bottom: 5, left: 5}}
|
||||
syncId={`peerIngress_${addr}_${enode}`}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={`egressGradient_${addr}_${enode}`} x1='0' y1='1' x2='0' y2='0'>
|
||||
{peer.egressGradient
|
||||
&& peer.egressGradient.map(({offset, color}, i) => (
|
||||
<stop
|
||||
key={`egressStop_${addr}_${enode}_${i}`}
|
||||
offset={`${offset}%`}
|
||||
stopColor={color}
|
||||
/>
|
||||
))}
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Tooltip cursor={false} content={<CustomTooltip tooltip={bytePlotter('Upload', multiplier(-1))} />} />
|
||||
<YAxis hide scale='sqrt' domain={[dataMin => Math.min(dataMin, 0), -0.001]} />
|
||||
<Area
|
||||
dataKey='egress'
|
||||
isAnimationActive={false}
|
||||
type='monotone'
|
||||
fill={`url(#egressGradient_${addr}_${enode})`}
|
||||
stroke={peer.egressGradient[0].color}
|
||||
strokeWidth={chartStrokeWidth}
|
||||
/>
|
||||
</AreaChart>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
...limitedWidthStyle(80),
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.head))}
|
||||
>
|
||||
{proto.head}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.difficulty))}
|
||||
>
|
||||
{proto.difficulty}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.version))}
|
||||
>
|
||||
{proto.version}
|
||||
{showTraffic ? (
|
||||
<>
|
||||
<AreaChart
|
||||
width={trafficChartWidth}
|
||||
height={trafficChartHeight}
|
||||
data={ingressValues}
|
||||
margin={{top: 5, right: 5, bottom: 0, left: 5}}
|
||||
syncId={`peerIngress_${addr}_${enode}`}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={`ingressGradient_${addr}_${enode}`} x1='0' y1='1' x2='0' y2='0'>
|
||||
{peer.ingressGradient
|
||||
&& peer.ingressGradient.map(({offset, color}, i) => (
|
||||
<stop
|
||||
key={`ingressStop_${addr}_${enode}_${i}`}
|
||||
offset={`${offset}%`}
|
||||
stopColor={color}
|
||||
/>
|
||||
))}
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Tooltip cursor={false} content={<CustomTooltip tooltip={bytePlotter('Download')} />} />
|
||||
<YAxis hide scale='sqrt' domain={[0.001, dataMax => Math.max(dataMax, 0)]} />
|
||||
<Area
|
||||
dataKey='ingress'
|
||||
isAnimationActive={false}
|
||||
type='monotone'
|
||||
fill={`url(#ingressGradient_${addr}_${enode})`}
|
||||
stroke={peer.ingressGradient[peer.ingressGradient.length - 1].color}
|
||||
strokeWidth={chartStrokeWidth}
|
||||
/>
|
||||
</AreaChart>
|
||||
<AreaChart
|
||||
width={trafficChartWidth}
|
||||
height={trafficChartHeight}
|
||||
data={egressValues}
|
||||
margin={{top: 0, right: 5, bottom: 5, left: 5}}
|
||||
syncId={`peerIngress_${addr}_${enode}`}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={`egressGradient_${addr}_${enode}`} x1='0' y1='1' x2='0' y2='0'>
|
||||
{peer.egressGradient
|
||||
&& peer.egressGradient.map(({offset, color}, i) => (
|
||||
<stop
|
||||
key={`egressStop_${addr}_${enode}_${i}`}
|
||||
offset={`${offset}%`}
|
||||
stopColor={color}
|
||||
/>
|
||||
))}
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Tooltip cursor={false} content={<CustomTooltip tooltip={bytePlotter('Upload', multiplier(-1))} />} />
|
||||
<YAxis hide scale='sqrt' domain={[dataMin => Math.min(dataMin, 0), -0.001]} />
|
||||
<Area
|
||||
dataKey='egress'
|
||||
isAnimationActive={false}
|
||||
type='monotone'
|
||||
fill={`url(#egressGradient_${addr}_${enode})`}
|
||||
stroke={peer.egressGradient[0].color}
|
||||
strokeWidth={chartStrokeWidth}
|
||||
/>
|
||||
</AreaChart>
|
||||
</>
|
||||
) : null}
|
||||
</TableCell>
|
||||
{typeof proto === 'object' ? (
|
||||
<>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
...limitedWidthStyle(80),
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.head))}
|
||||
>
|
||||
{proto.head}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.difficulty))}
|
||||
>
|
||||
{proto.difficulty}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
style={{
|
||||
cursor: 'copy',
|
||||
...styles.tableCell,
|
||||
}}
|
||||
onClick={this.copyToClipboard(JSON.stringify(proto.version))}
|
||||
>
|
||||
{proto.version}
|
||||
</TableCell>
|
||||
</>
|
||||
) : null }
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
|
|
@ -614,15 +677,21 @@ class Network extends Component<Props, State> {
|
|||
);
|
||||
|
||||
render() {
|
||||
const {classes} = this.props;
|
||||
return (
|
||||
<Grid container direction='row' spacing={24}>
|
||||
<Grid item xs style={{width: '40%'}}>
|
||||
<div style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom style={styles.title}>
|
||||
<Grid container direction='row' spacing={3}>
|
||||
<Grid item style={{width: '40%'}}>
|
||||
<div className={classes.table} style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom className={classes.title} style={styles.title}>
|
||||
ETH peers
|
||||
<FontAwesomeIcon
|
||||
icon={farClipboard}
|
||||
onClick={this.copyToClipboard(JSON.stringify(this.ethList()))}
|
||||
style={{float: 'right'}}
|
||||
/>
|
||||
</Typography>
|
||||
<ScrollArea speed={0.8} style={styles.content}>
|
||||
<Table style={styles.table}>
|
||||
<Scrollbars style={styles.content}>
|
||||
<Table>
|
||||
<TableHead style={styles.tableHead}>
|
||||
<TableRow style={styles.tableRow}>
|
||||
<TableCell style={styles.tableCell} />
|
||||
|
|
@ -668,16 +737,21 @@ class Network extends Component<Props, State> {
|
|||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</Scrollbars>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs style={{width: '40%'}}>
|
||||
<div style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom style={styles.title}>
|
||||
<Grid item style={{width: '40%'}}>
|
||||
<div className={classes.table} style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom className={classes.title} style={styles.title}>
|
||||
LES peers
|
||||
<FontAwesomeIcon
|
||||
icon={farClipboard}
|
||||
onClick={this.copyToClipboard(JSON.stringify(this.lesList()))}
|
||||
style={{float: 'right'}}
|
||||
/>
|
||||
</Typography>
|
||||
<ScrollArea speed={0.8} style={styles.content}>
|
||||
<Table style={styles.table}>
|
||||
<Scrollbars style={styles.content}>
|
||||
<Table>
|
||||
<TableHead style={styles.tableHead}>
|
||||
<TableRow style={styles.tableRow}>
|
||||
<TableCell style={styles.tableCell} />
|
||||
|
|
@ -723,15 +797,20 @@ class Network extends Component<Props, State> {
|
|||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</Scrollbars>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<div style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom style={styles.title}>
|
||||
<div className={classes.table} style={styles.table}>
|
||||
<Typography variant='subtitle1' gutterBottom className={classes.title} style={styles.title}>
|
||||
Connection attempts
|
||||
<FontAwesomeIcon
|
||||
icon={farClipboard}
|
||||
onClick={this.copyToClipboard(JSON.stringify(this.attemptList()))}
|
||||
style={{float: 'right'}}
|
||||
/>
|
||||
</Typography>
|
||||
<ScrollArea speed={0.8} style={styles.content}>
|
||||
<Scrollbars style={styles.content}>
|
||||
<Table>
|
||||
<TableHead style={styles.tableHead}>
|
||||
<TableRow style={styles.tableRow}>
|
||||
|
|
@ -757,7 +836,7 @@ class Network extends Component<Props, State> {
|
|||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</Scrollbars>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
@ -765,4 +844,4 @@ class Network extends Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default Network;
|
||||
export default withStyles(themeStyles)(Network);
|
||||
|
|
|
|||
|
|
@ -47,10 +47,11 @@ const themeStyles = theme => ({
|
|||
background: theme.palette.grey[900],
|
||||
},
|
||||
listItem: {
|
||||
minWidth: theme.spacing.unit * 7,
|
||||
minWidth: theme.spacing(7),
|
||||
color: theme.palette.common.white,
|
||||
},
|
||||
icon: {
|
||||
fontSize: theme.spacing.unit * 3,
|
||||
fontSize: theme.spacing(3),
|
||||
overflow: 'unset',
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,55 +1,56 @@
|
|||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "7.3.4",
|
||||
"@babel/plugin-proposal-class-properties": "7.3.4",
|
||||
"@babel/core": "7.4.5",
|
||||
"@babel/plugin-proposal-class-properties": "7.4.4",
|
||||
"@babel/plugin-proposal-function-bind": "7.2.0",
|
||||
"@babel/plugin-transform-flow-strip-types": "7.3.4",
|
||||
"@babel/preset-env": "7.3.4",
|
||||
"@babel/plugin-transform-flow-strip-types": "7.4.4",
|
||||
"@babel/preset-env": "7.4.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/preset-stage-0": "^7.0.0",
|
||||
"@fortawesome/fontawesome-free-regular": "^5.0.13",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.15",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.2",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.18",
|
||||
"@fortawesome/free-regular-svg-icons": "5.8.2",
|
||||
"@fortawesome/free-solid-svg-icons": "5.8.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.4",
|
||||
"@material-ui/core": "3.9.2",
|
||||
"@material-ui/icons": "3.0.2",
|
||||
"@material-ui/core": "4.0.1",
|
||||
"@material-ui/icons": "4.0.1",
|
||||
"babel-eslint": "10.0.1",
|
||||
"babel-loader": "8.0.5",
|
||||
"babel-loader": "8.0.6",
|
||||
"classnames": "^2.2.6",
|
||||
"color-convert": "^2.0.0",
|
||||
"css-loader": "2.1.1",
|
||||
"escape-html": "^1.0.3",
|
||||
"eslint": "5.15.1",
|
||||
"eslint": "5.16.0",
|
||||
"eslint-config-airbnb": "^17.0.0",
|
||||
"eslint-loader": "2.1.2",
|
||||
"eslint-plugin-flowtype": "3.4.2",
|
||||
"eslint-plugin-import": "2.16.0",
|
||||
"eslint-plugin-flowtype": "3.9.1",
|
||||
"eslint-plugin-import": "2.17.3",
|
||||
"eslint-plugin-jsx-a11y": "6.2.1",
|
||||
"eslint-plugin-node": "8.0.1",
|
||||
"eslint-plugin-promise": "4.0.1",
|
||||
"eslint-plugin-react": "7.12.4",
|
||||
"eslint-plugin-node": "9.1.0",
|
||||
"eslint-plugin-promise": "4.1.1",
|
||||
"eslint-plugin-react": "7.13.0",
|
||||
"file-loader": "3.0.1",
|
||||
"flow-bin": "0.94.0",
|
||||
"flow-bin": "0.98.1",
|
||||
"flow-bin-loader": "^1.0.3",
|
||||
"flow-typed": "^2.5.1",
|
||||
"js-beautify": "1.9.0",
|
||||
"flow-typed": "2.5.2",
|
||||
"js-beautify": "1.10.0",
|
||||
"path": "^0.12.7",
|
||||
"react": "16.8.4",
|
||||
"react-dom": "16.8.4",
|
||||
"react-hot-loader": "4.8.0",
|
||||
"react-scrollbar": "^0.5.6",
|
||||
"react-transition-group": "2.6.1",
|
||||
"recharts": "1.5.0",
|
||||
"react": "16.8.6",
|
||||
"react-custom-scrollbars": "^4.2.1",
|
||||
"react-dom": "16.8.6",
|
||||
"react-hot-loader": "4.8.8",
|
||||
"react-scrollbar": "0.5.6",
|
||||
"react-transition-group": "4.0.1",
|
||||
"recharts": "1.6.2",
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "^1.2.3",
|
||||
"terser-webpack-plugin": "1.3.0",
|
||||
"url": "^0.11.0",
|
||||
"url-loader": "1.1.2",
|
||||
"webpack": "4.29.6",
|
||||
"webpack-cli": "3.2.3",
|
||||
"webpack-dashboard": "3.0.0",
|
||||
"webpack-dev-server": "3.2.1",
|
||||
"webpack": "4.32.2",
|
||||
"webpack-cli": "3.3.2",
|
||||
"webpack-dashboard": "3.0.7",
|
||||
"webpack-dev-server": "3.4.1",
|
||||
"webpack-merge": "4.2.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue