Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Add peer management to the Status tab (#5566)
Browse files Browse the repository at this point in the history
* Add peer management to the Status tab

* Fix propTypes issue
  • Loading branch information
ngotchac authored and gavofyork committed May 16, 2017
1 parent 945c1a9 commit 0f1a857
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 15 deletions.
8 changes: 4 additions & 4 deletions js/src/api/rpc/parity/parity.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export default class Parity {
.then(outAccountInfo);
}

addReservedPeer (encode) {
addReservedPeer (enode) {
return this._transport
.execute('parity_addReservedPeer', encode);
.execute('parity_addReservedPeer', enode);
}

chainStatus () {
Expand Down Expand Up @@ -429,9 +429,9 @@ export default class Parity {
.execute('parity_releasesInfo');
}

removeReservedPeer (encode) {
removeReservedPeer (enode) {
return this._transport
.execute('parity_removeReservedPeer', encode);
.execute('parity_removeReservedPeer', enode);
}

removeTransaction (hash) {
Expand Down
6 changes: 6 additions & 0 deletions js/src/ui/Container/Title/title.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ $bylineMaxHeight: 2.4rem;
$titleLineHeight: 2rem;
$smallFontSize: 0.75rem;

.container {
display: flex;
flex-direction: row;
justify-content: space-between;
}

.byline,
.description {
color: $bylineColor;
Expand Down
36 changes: 29 additions & 7 deletions js/src/ui/Container/Title/title.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,44 @@ import styles from './title.css';

export default class Title extends Component {
static propTypes = {
actions: PropTypes.array,
byline: nodeOrStringProptype(),
className: PropTypes.string,
description: nodeOrStringProptype(),
title: nodeOrStringProptype()
}
};

static defaultProps = {
actions: []
};

render () {
const { className, title } = this.props;

return (
<div className={ className }>
<h3 className={ styles.title }>
{ title }
</h3>
{ this.renderByline() }
{ this.renderDescription() }
<div className={ [ className, styles.container ].join(' ') }>
<div>
<h3 className={ styles.title }>
{ title }
</h3>
{ this.renderByline() }
{ this.renderDescription() }
</div>
{ this.renderActions() }
</div>
);
}

renderActions () {
const { actions } = this.props;

if (actions.length === 0) {
return null;
}

return (
<div>
{ actions }
</div>
);
}
Expand Down
3 changes: 2 additions & 1 deletion js/src/views/Application/Snackbar/snackbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const bodyStyle = {
backgroundColor: darkBlack,
borderStyle: 'solid',
borderColor: grey800,
borderWidth: '1px 1px 0 1px'
borderWidth: '1px 1px 0 1px',
minWidth: 0
};

class Snackbar extends Component {
Expand Down
13 changes: 13 additions & 0 deletions js/src/views/Status/Peers/peers.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,16 @@
white-space: nowrap;
}
}

.form {
align-items: center;
display: flex;
flex-direction: row;
float: right;
width: 40em;

.input {
flex: 1;
margin-right: 1em;
}
}
207 changes: 204 additions & 3 deletions js/src/views/Status/Peers/peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,92 @@

import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import { Container, ContainerTitle, ScrollableText, ShortenedHash } from '~/ui';
import { Button, Container, ContainerTitle, Input, ScrollableText, ShortenedHash } from '~/ui';
import { showSnackbar } from '~/redux/providers/snackbarActions';
import { newError } from '~/redux/actions';

import styles from './peers.css';

class Peers extends Component {
static contextTypes = {
api: PropTypes.object
};

static propTypes = {
peers: PropTypes.array.isRequired
peers: PropTypes.array.isRequired,
newError: PropTypes.func,
showSnackbar: PropTypes.func
};

state = {
action: '',
formInput: '',
showForm: false
};

getActions () {
return [
<Button
key='btn_acceptNonReserved'
label={
<FormattedMessage
id='peers.acceptNonReserved.label'
defaultMessage='Accept non-reserved'
/>
}
onClick={ this.handleAcceptNonReserved }
/>,
<Button
key='btn_dropNonReserved'
label={
<FormattedMessage
id='peers.dropNonReserved.label'
defaultMessage='Drop non-reserved'
/>
}
onClick={ this.handleDropNonReserved }
/>,
<Button
key='btn_addReserved'
label={
<FormattedMessage
id='peers.addReserved.label'
defaultMessage='Add reserved'
/>
}
onClick={ this.handleAddReserved }
/>,
<Button
key='btn_removeReserved'
label={
<FormattedMessage
id='peers.removeReserved.label'
defaultMessage='Remove reserved'
/>
}
onClick={ this.handleRemoveReserved }
/>
];
}

render () {
const { peers } = this.props;

return (
<Container>
<ContainerTitle
actions={ this.getActions() }
title={
<FormattedMessage
id='status.peers.title'
defaultMessage='network peers'
/>
}
/>
{ this.renderForm() }
<div className={ styles.peers }>
<table>
<thead>
Expand Down Expand Up @@ -92,6 +154,52 @@ class Peers extends Component {
);
}

renderForm () {
const { action, showForm } = this.state;

if (!showForm) {
return null;
}

return (
<div className={ styles.form }>
<div className={ styles.input }>
<Input
label={
<FormattedMessage
id='peers.form.label'
defaultMessage='Peer enode URL'
/>
}
onChange={ this.handleInputChange }
/>
</div>
<Button
label={
<FormattedMessage
id='peers.form.action.label'
defaultMessage='{add, select, true {Add} false {}}{remove, select, true {Remove} false {}}'
values={ {
add: action === 'add',
remove: action === 'remove'
} }
/>
}
onClick={ this.handleConfirmForm }
/>
<Button
label={
<FormattedMessage
id='peers.form.cancel.label'
defaultMessage='Cancel'
/>
}
onClick={ this.handleCancelForm }
/>
</div>
);
}

renderPeers (peers) {
return peers.map((peer, index) => this.renderPeer(peer, index));
}
Expand Down Expand Up @@ -140,6 +248,92 @@ class Peers extends Component {
</tr>
);
}

handleAcceptNonReserved = () => {
return this.context.api.parity.acceptNonReservedPeers()
.then(() => {
const message = (
<FormattedMessage
id='peers.acceptNonReservedPeers.success'
defaultMessage='Accepting non-reserved peers'
/>
);

this.props.showSnackbar(message, 3000);
})
.catch((error) => {
this.props.newError(error);
});
};

handleDropNonReserved = () => {
return this.context.api.parity.dropNonReservedPeers()
.then(() => {
const message = (
<FormattedMessage
id='peers.dropNonReservedPeers.success'
defaultMessage='Dropping non-reserved peers'
/>
);

this.props.showSnackbar(message, 3000);
})
.catch((error) => {
this.props.newError(error);
});
};

handleAddReserved = () => {
this.setState({ showForm: true, action: 'add' });
};

handleRemoveReserved = () => {
this.setState({ showForm: true, action: 'remove' });
};

handleInputChange = (event, value) => {
this.setState({ formInput: value });
};

handleCancelForm = () => {
this.setState({ showForm: false, action: '', formInput: '' });
};

handleConfirmForm = () => {
const { action, formInput } = this.state;
let method;

if (action === 'add') {
method = 'addReservedPeer';
} else if (action === 'remove') {
method = 'removeReservedPeer';
}

this.setState({ showForm: false, action: '', formInput: '' });

if (!method) {
return;
}

this.context.api.parity[method](formInput)
.then(() => {
const message = (
<FormattedMessage
id='peers.form.action.success'
defaultMessage='Successfully {add, select, true {added} false {}}{remove, select, true {removed} false {}} a reserved peer'
values={ {
add: action === 'add',
remove: action === 'remove'
} }
/>
);

this.props.showSnackbar(message, 3000);
})
.catch((error) => {
this.props.newError(error);
});
};
}

function mapStateToProps (state) {
Expand All @@ -160,4 +354,11 @@ function mapStateToProps (state) {
return { peers: realPeers };
}

export default connect(mapStateToProps)(Peers);
function mapDispatchToProps (dispatch) {
return bindActionCreators({
newError,
showSnackbar
}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Peers);

0 comments on commit 0f1a857

Please sign in to comment.