Add read-only inputs to UI plus Copy to Clipboard buttons (#3095)
* Adds readOnly prop to Input, convert disabled props to it (#3066) * WIP * Adds copy icon to readOnly Input (#3009) * Added Copy to Clipboard buttons on the UI (#3009) * copiable to allowCopy props #3095 * Padded copy icons (#3095) * Fixed password width in account creation * Copyable value in MethodDecoding
This commit is contained in:
parent
f3d4aa43f3
commit
e4c75bde4c
@ -31,7 +31,8 @@ export default class AccountDetails extends Component {
|
|||||||
return (
|
return (
|
||||||
<Form>
|
<Form>
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
|
allowCopy
|
||||||
hint='a descriptive name for the account'
|
hint='a descriptive name for the account'
|
||||||
label='account name'
|
label='account name'
|
||||||
value={ name } />
|
value={ name } />
|
||||||
@ -54,7 +55,8 @@ export default class AccountDetails extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
|
allowCopy
|
||||||
hint='the account recovery phrase'
|
hint='the account recovery phrase'
|
||||||
label='account recovery phrase (keep safe)'
|
label='account recovery phrase (keep safe)'
|
||||||
value={ phrase } />
|
value={ phrase } />
|
||||||
|
@ -84,7 +84,6 @@ export default class CreateAccount extends Component {
|
|||||||
<div className={ styles.passwords }>
|
<div className={ styles.passwords }>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password'
|
label='password'
|
||||||
hint='a strong, unique password'
|
hint='a strong, unique password'
|
||||||
type='password'
|
type='password'
|
||||||
@ -94,7 +93,6 @@ export default class CreateAccount extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password (repeat)'
|
label='password (repeat)'
|
||||||
hint='verify your password'
|
hint='verify your password'
|
||||||
type='password'
|
type='password'
|
||||||
|
@ -72,7 +72,6 @@ export default class NewImport extends Component {
|
|||||||
<div className={ styles.passwords }>
|
<div className={ styles.passwords }>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password'
|
label='password'
|
||||||
hint='the password to unlock the wallet'
|
hint='the password to unlock the wallet'
|
||||||
type='password'
|
type='password'
|
||||||
|
@ -75,7 +75,6 @@ export default class RawKey extends Component {
|
|||||||
<div className={ styles.passwords }>
|
<div className={ styles.passwords }>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password'
|
label='password'
|
||||||
hint='a strong, unique password'
|
hint='a strong, unique password'
|
||||||
type='password'
|
type='password'
|
||||||
@ -85,7 +84,6 @@ export default class RawKey extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password (repeat)'
|
label='password (repeat)'
|
||||||
hint='verify your password'
|
hint='verify your password'
|
||||||
type='password'
|
type='password'
|
||||||
|
@ -72,7 +72,6 @@ export default class RecoveryPhrase extends Component {
|
|||||||
<div className={ styles.passwords }>
|
<div className={ styles.passwords }>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password'
|
label='password'
|
||||||
hint='a strong, unique password'
|
hint='a strong, unique password'
|
||||||
type='password'
|
type='password'
|
||||||
@ -82,7 +81,6 @@ export default class RecoveryPhrase extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={ styles.password }>
|
<div className={ styles.password }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.password }
|
|
||||||
label='password (repeat)'
|
label='password (repeat)'
|
||||||
hint='verify your password'
|
hint='verify your password'
|
||||||
type='password'
|
type='password'
|
||||||
|
@ -21,6 +21,15 @@
|
|||||||
.password {
|
.password {
|
||||||
flex: 0 1 50%;
|
flex: 0 1 50%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&:nth-child(odd) {
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
padding-left: 0.25rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.passwords {
|
.passwords {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
.byline {
|
.byline {
|
||||||
color: #aaa;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
line-height: 1.2em;
|
line-height: 1.2em;
|
||||||
@ -24,6 +23,12 @@
|
|||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
|
|
||||||
|
color: #aaa;
|
||||||
|
|
||||||
|
* {
|
||||||
|
color: #aaa !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -24,7 +24,9 @@ export default class Title extends Component {
|
|||||||
title: PropTypes.oneOfType([
|
title: PropTypes.oneOfType([
|
||||||
PropTypes.string, PropTypes.node
|
PropTypes.string, PropTypes.node
|
||||||
]),
|
]),
|
||||||
byline: PropTypes.string
|
byline: PropTypes.oneOfType([
|
||||||
|
PropTypes.string, PropTypes.node
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -34,15 +36,21 @@ export default class Title extends Component {
|
|||||||
render () {
|
render () {
|
||||||
const { className, title, byline } = this.props;
|
const { className, title, byline } = this.props;
|
||||||
|
|
||||||
|
const byLine = typeof byline === 'string'
|
||||||
|
? (
|
||||||
|
<span title={ byline }>
|
||||||
|
{ byline }
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
: byline;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ className }>
|
<div className={ className }>
|
||||||
<h3 className={ styles.title }>
|
<h3 className={ styles.title }>
|
||||||
{ title }
|
{ title }
|
||||||
</h3>
|
</h3>
|
||||||
<div className={ styles.byline }>
|
<div className={ styles.byline }>
|
||||||
<span title={ byline }>
|
{ byLine }
|
||||||
{ byline }
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
31
js/src/ui/Form/Input/input.css
Normal file
31
js/src/ui/Form/Input/input.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity 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 General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-end;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
transition: all .5s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
@ -16,11 +16,22 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import { TextField } from 'material-ui';
|
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||||
|
import CopyIcon from 'material-ui/svg-icons/content/content-copy';
|
||||||
|
import { TextField, IconButton } from 'material-ui';
|
||||||
|
import { lightWhite, fullWhite } from 'material-ui/styles/colors';
|
||||||
|
|
||||||
|
import styles from './input.css';
|
||||||
|
|
||||||
// TODO: duplicated in Select
|
// TODO: duplicated in Select
|
||||||
const UNDERLINE_DISABLED = {
|
const UNDERLINE_DISABLED = {
|
||||||
borderColor: 'rgba(255, 255, 255, 0.298039)' // 'transparent' // 'rgba(255, 255, 255, 0.298039)'
|
borderBottom: 'dotted 2px',
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.125)' // 'transparent' // 'rgba(255, 255, 255, 0.298039)'
|
||||||
|
};
|
||||||
|
|
||||||
|
const UNDERLINE_READONLY = {
|
||||||
|
...UNDERLINE_DISABLED,
|
||||||
|
cursor: 'text'
|
||||||
};
|
};
|
||||||
|
|
||||||
const UNDERLINE_NORMAL = {
|
const UNDERLINE_NORMAL = {
|
||||||
@ -34,6 +45,12 @@ export default class Input extends Component {
|
|||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
|
allowCopy: PropTypes.oneOfType([
|
||||||
|
PropTypes.string,
|
||||||
|
PropTypes.bool
|
||||||
|
]),
|
||||||
|
floatCopy: PropTypes.bool,
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
hint: PropTypes.string,
|
hint: PropTypes.string,
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
@ -45,17 +62,24 @@ export default class Input extends Component {
|
|||||||
rows: PropTypes.number,
|
rows: PropTypes.number,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
submitOnBlur: PropTypes.bool,
|
submitOnBlur: PropTypes.bool,
|
||||||
|
hideUnderline: PropTypes.bool,
|
||||||
value: PropTypes.oneOfType([
|
value: PropTypes.oneOfType([
|
||||||
PropTypes.number, PropTypes.string
|
PropTypes.number, PropTypes.string
|
||||||
])
|
])
|
||||||
}
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
submitOnBlur: true
|
submitOnBlur: true,
|
||||||
|
readOnly: false,
|
||||||
|
allowCopy: false,
|
||||||
|
hideUnderline: false,
|
||||||
|
floatCopy: false
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
value: this.props.value || ''
|
value: this.props.value || '',
|
||||||
|
timeoutId: null,
|
||||||
|
copied: false
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (newProps) {
|
componentWillReceiveProps (newProps) {
|
||||||
@ -64,36 +88,145 @@ export default class Input extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
const { timeoutId } = this.state;
|
||||||
|
|
||||||
|
if (timeoutId) {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value } = this.state;
|
const { value } = this.state;
|
||||||
const { children, className, disabled, error, label, hint, multiLine, rows, type } = this.props;
|
const { children, className, hideUnderline, disabled, error, label, hint, multiLine, rows, type } = this.props;
|
||||||
|
|
||||||
|
const readOnly = this.props.readOnly || disabled;
|
||||||
|
|
||||||
|
const inputStyle = { overflow: 'hidden' };
|
||||||
|
const textFieldStyle = {};
|
||||||
|
|
||||||
|
if (readOnly) {
|
||||||
|
inputStyle.cursor = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hideUnderline && !hint) {
|
||||||
|
textFieldStyle.height = 'initial';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextField
|
<div className={ styles.container }>
|
||||||
autoComplete='off'
|
{ this.renderCopyButton() }
|
||||||
className={ className }
|
<TextField
|
||||||
disabled={ disabled }
|
autoComplete='off'
|
||||||
errorText={ error }
|
className={ className }
|
||||||
floatingLabelFixed
|
style={ textFieldStyle }
|
||||||
floatingLabelText={ label }
|
|
||||||
fullWidth
|
readOnly={ readOnly }
|
||||||
hintText={ hint }
|
|
||||||
multiLine={ multiLine }
|
errorText={ error }
|
||||||
name={ NAME_ID }
|
floatingLabelFixed
|
||||||
id={ NAME_ID }
|
floatingLabelText={ label }
|
||||||
rows={ rows }
|
fullWidth
|
||||||
type={ type || 'text' }
|
hintText={ hint }
|
||||||
underlineDisabledStyle={ UNDERLINE_DISABLED }
|
multiLine={ multiLine }
|
||||||
underlineStyle={ UNDERLINE_NORMAL }
|
name={ NAME_ID }
|
||||||
value={ value }
|
id={ NAME_ID }
|
||||||
onBlur={ this.onBlur }
|
rows={ rows }
|
||||||
onChange={ this.onChange }
|
type={ type || 'text' }
|
||||||
onKeyDown={ this.onKeyDown }>
|
underlineDisabledStyle={ UNDERLINE_DISABLED }
|
||||||
{ children }
|
underlineStyle={ readOnly ? UNDERLINE_READONLY : UNDERLINE_NORMAL }
|
||||||
</TextField>
|
underlineFocusStyle={ readOnly ? { display: 'none' } : null }
|
||||||
|
underlineShow={ !hideUnderline }
|
||||||
|
value={ value }
|
||||||
|
onBlur={ this.onBlur }
|
||||||
|
onChange={ this.onChange }
|
||||||
|
onKeyDown={ this.onKeyDown }
|
||||||
|
inputStyle={ inputStyle }
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
|
</TextField>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderCopyButton () {
|
||||||
|
const { allowCopy, hideUnderline, label, hint, floatCopy } = this.props;
|
||||||
|
const { copied, value } = this.state;
|
||||||
|
|
||||||
|
if (!allowCopy) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
marginBottom: 13
|
||||||
|
};
|
||||||
|
|
||||||
|
const text = typeof allowCopy === 'string'
|
||||||
|
? allowCopy
|
||||||
|
: value;
|
||||||
|
|
||||||
|
const scale = copied ? 'scale(1.15)' : 'scale(1)';
|
||||||
|
|
||||||
|
if (hideUnderline && !label) {
|
||||||
|
style.marginBottom = 2;
|
||||||
|
} else if (label && !hint) {
|
||||||
|
style.marginBottom = 4;
|
||||||
|
} else if (label && hint) {
|
||||||
|
style.marginBottom = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (floatCopy) {
|
||||||
|
style.position = 'absolute';
|
||||||
|
style.left = -24;
|
||||||
|
style.bottom = style.marginBottom;
|
||||||
|
style.marginBottom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.copy } style={ style }>
|
||||||
|
<CopyToClipboard
|
||||||
|
onCopy={ this.handleCopy }
|
||||||
|
text={ text } >
|
||||||
|
<IconButton
|
||||||
|
tooltip={ `${copied ? 'Copied' : 'Copy'} to clipboard` }
|
||||||
|
tooltipPosition='bottom-right'
|
||||||
|
style={ {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
padding: 0
|
||||||
|
} }
|
||||||
|
iconStyle={ {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
transform: scale
|
||||||
|
} }
|
||||||
|
tooltipStyles={ {
|
||||||
|
top: 16
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<CopyIcon
|
||||||
|
color={ copied ? lightWhite : fullWhite }
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
|
</CopyToClipboard>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCopy = () => {
|
||||||
|
if (this.state.timeoutId) {
|
||||||
|
window.clearTimeout(this.state.timeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ copied: true }, () => {
|
||||||
|
const timeoutId = window.setTimeout(() => {
|
||||||
|
this.setState({ copied: false });
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
this.setState({ timeoutId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onChange = (event, value) => {
|
onChange = (event, value) => {
|
||||||
this.setValue(value);
|
this.setValue(value);
|
||||||
|
|
||||||
@ -130,8 +263,6 @@ export default class Input extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setValue (value) {
|
setValue (value) {
|
||||||
this.setState({
|
this.setState({ value });
|
||||||
value
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,4 +29,5 @@
|
|||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 35px;
|
top: 35px;
|
||||||
|
left: 24px;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,9 @@ class InputAddress extends Component {
|
|||||||
error={ error }
|
error={ error }
|
||||||
value={ text && hasAccount ? account.name : value }
|
value={ text && hasAccount ? account.name : value }
|
||||||
onChange={ this.handleInputChange }
|
onChange={ this.handleInputChange }
|
||||||
onSubmit={ onSubmit } />
|
onSubmit={ onSubmit }
|
||||||
|
allowCopy={ disabled ? value : false }
|
||||||
|
/>
|
||||||
{ icon }
|
{ icon }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -268,7 +268,8 @@ class MethodDecoding extends Component {
|
|||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
|
allowCopy
|
||||||
key={ index }
|
key={ index }
|
||||||
className={ styles.input }
|
className={ styles.input }
|
||||||
value={ this.renderValue(input.value) }
|
value={ this.renderValue(input.value) }
|
||||||
|
@ -49,7 +49,6 @@ class Tooltips extends Component {
|
|||||||
redirect (props = this.props) {
|
redirect (props = this.props) {
|
||||||
const { currentId } = props;
|
const { currentId } = props;
|
||||||
|
|
||||||
console.log('c', { currentId });
|
|
||||||
if (currentId !== undefined && currentId !== -1) {
|
if (currentId !== undefined && currentId !== -1) {
|
||||||
const viewLink = '/accounts/';
|
const viewLink = '/accounts/';
|
||||||
this.context.router.push(viewLink);
|
this.context.router.push(viewLink);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags } from '../../../ui';
|
import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags, Input } from '../../../ui';
|
||||||
|
|
||||||
export default class Summary extends Component {
|
export default class Summary extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -47,6 +47,15 @@ export default class Summary extends Component {
|
|||||||
const { address } = account;
|
const { address } = account;
|
||||||
const viewLink = `/${link || 'account'}/${address}`;
|
const viewLink = `/${link || 'account'}/${address}`;
|
||||||
|
|
||||||
|
const addressComponent = (
|
||||||
|
<Input
|
||||||
|
readOnly
|
||||||
|
hideUnderline
|
||||||
|
value={ address }
|
||||||
|
allowCopy={ address }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Tags tags={ tags } handleAddSearchToken={ handleAddSearchToken } />
|
<Tags tags={ tags } handleAddSearchToken={ handleAddSearchToken } />
|
||||||
@ -54,7 +63,7 @@ export default class Summary extends Component {
|
|||||||
address={ address } />
|
address={ address } />
|
||||||
<ContainerTitle
|
<ContainerTitle
|
||||||
title={ <Link to={ viewLink }>{ <IdentityName address={ address } unknown /> }</Link> }
|
title={ <Link to={ viewLink }>{ <IdentityName address={ address } unknown /> }</Link> }
|
||||||
byline={ address } />
|
byline={ addressComponent } />
|
||||||
<Balance
|
<Balance
|
||||||
balance={ balance } />
|
balance={ balance } />
|
||||||
{ children }
|
{ children }
|
||||||
|
@ -42,7 +42,8 @@ class Application extends Component {
|
|||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
netChain: PropTypes.string,
|
netChain: PropTypes.string,
|
||||||
isTest: PropTypes.bool,
|
isTest: PropTypes.bool,
|
||||||
pending: PropTypes.array
|
pending: PropTypes.array,
|
||||||
|
blockNumber: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -73,7 +74,7 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderApp () {
|
renderApp () {
|
||||||
const { children, pending, netChain, isTest } = this.props;
|
const { children, pending, netChain, isTest, blockNumber } = this.props;
|
||||||
const { showFirstRun } = this.state;
|
const { showFirstRun } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -85,7 +86,7 @@ class Application extends Component {
|
|||||||
isTest={ isTest }
|
isTest={ isTest }
|
||||||
pending={ pending } />
|
pending={ pending } />
|
||||||
{ children }
|
{ children }
|
||||||
<Status />
|
{ blockNumber ? (<Status />) : null }
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -124,7 +125,7 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const { netChain, isTest } = state.nodeStatus;
|
const { netChain, isTest, blockNumber } = state.nodeStatus;
|
||||||
const { hasAccounts } = state.personal;
|
const { hasAccounts } = state.personal;
|
||||||
const { pending } = state.signer;
|
const { pending } = state.signer;
|
||||||
|
|
||||||
@ -132,7 +133,8 @@ function mapStateToProps (state) {
|
|||||||
hasAccounts,
|
hasAccounts,
|
||||||
netChain,
|
netChain,
|
||||||
isTest,
|
isTest,
|
||||||
pending
|
pending,
|
||||||
|
blockNumber
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,10 +129,12 @@ class Event extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
|
allowCopy
|
||||||
className={ styles.input }
|
className={ styles.input }
|
||||||
value={ value }
|
value={ value }
|
||||||
label={ name } />
|
label={ name }
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import Chip from 'material-ui/Chip';
|
|
||||||
import LinearProgress from 'material-ui/LinearProgress';
|
import LinearProgress from 'material-ui/LinearProgress';
|
||||||
import { Card, CardActions, CardTitle, CardText } from 'material-ui/Card';
|
import { Card, CardActions, CardTitle, CardText } from 'material-ui/Card';
|
||||||
|
|
||||||
@ -104,13 +103,21 @@ export default class InputQuery extends Component {
|
|||||||
display: this.renderValue(results[index])
|
display: this.renderValue(results[index])
|
||||||
}))
|
}))
|
||||||
.sort((outA, outB) => outA.display.length - outB.display.length)
|
.sort((outA, outB) => outA.display.length - outB.display.length)
|
||||||
.map((out, index) => (<div key={ index }>
|
.map((out, index) => (
|
||||||
<div className={ styles.queryResultName }>{ out.name }</div>
|
<div key={ index }>
|
||||||
<Chip className={ styles.queryValue }>
|
<div className={ styles.queryResultName }>
|
||||||
{ out.display }
|
{ out.name }
|
||||||
</Chip>
|
</div>
|
||||||
<br />
|
|
||||||
</div>));
|
<Input
|
||||||
|
className={ styles.queryValue }
|
||||||
|
readOnly
|
||||||
|
allowCopy
|
||||||
|
value={ out.display }
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInput (input) {
|
renderInput (input) {
|
||||||
|
@ -63,25 +63,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.methodResults > div {
|
.methodResults > div {
|
||||||
margin: 0.5rem;
|
padding: 0.25rem 0.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: 100%;
|
flex: 1 1 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryValue {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queryValue, .queryValue * {
|
.queryValue, .queryValue * {
|
||||||
user-select: text !important;
|
|
||||||
max-width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
white-space: normal !important;
|
white-space: normal !important;
|
||||||
overflow-wrap: break-word !important;
|
overflow-wrap: break-word !important;
|
||||||
}
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
.queryValue:hover {
|
|
||||||
cursor: text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.queryResultName {
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import Chip from 'material-ui/Chip';
|
|
||||||
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
import { Card, CardTitle, CardText } from 'material-ui/Card';
|
||||||
|
|
||||||
import InputQuery from './inputQuery';
|
import InputQuery from './inputQuery';
|
||||||
import { Container, ContainerTitle } from '../../../ui';
|
import { Container, ContainerTitle, Input } from '../../../ui';
|
||||||
|
|
||||||
import styles from './queries.css';
|
import styles from './queries.css';
|
||||||
|
|
||||||
@ -126,9 +125,12 @@ export default class Queries extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chip className={ styles.queryValue }>
|
<Input
|
||||||
{ valueToDisplay }
|
className={ styles.queryValue }
|
||||||
</Chip>
|
value={ valueToDisplay }
|
||||||
|
readOnly
|
||||||
|
allowCopy
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,9 +82,9 @@ class Background extends Component {
|
|||||||
const { settings } = this.props;
|
const { settings } = this.props;
|
||||||
const { seeds } = this.state;
|
const { seeds } = this.state;
|
||||||
|
|
||||||
return seeds.map((seed) => {
|
return seeds.map((seed, index) => {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.bgflex } key={ seed }>
|
<div className={ styles.bgflex } key={ index }>
|
||||||
<div className={ styles.bgseed }>
|
<div className={ styles.bgseed }>
|
||||||
<ParityBackground
|
<ParityBackground
|
||||||
className={ settings.backgroundSeed === seed ? styles.seedactive : styles.seed }
|
className={ settings.backgroundSeed === seed ? styles.seedactive : styles.seed }
|
||||||
|
@ -45,26 +45,41 @@ export default class MiningSettings extends Component {
|
|||||||
hint='the mining author'
|
hint='the mining author'
|
||||||
value={ coinbase }
|
value={ coinbase }
|
||||||
onSubmit={ this.onAuthorChange }
|
onSubmit={ this.onAuthorChange }
|
||||||
{ ...this._test('author') } />
|
allowCopy
|
||||||
|
floatCopy
|
||||||
|
{ ...this._test('author') }
|
||||||
|
/>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
label='extradata'
|
label='extradata'
|
||||||
hint='extra data for mined blocks'
|
hint='extra data for mined blocks'
|
||||||
value={ decodeExtraData(extraData) }
|
value={ decodeExtraData(extraData) }
|
||||||
onSubmit={ this.onExtraDataChange }
|
onSubmit={ this.onExtraDataChange }
|
||||||
defaultValue={ decodeExtraData(defaultExtraData) }
|
defaultValue={ decodeExtraData(defaultExtraData) }
|
||||||
{ ...this._test('extra-data') } />
|
allowCopy
|
||||||
|
floatCopy
|
||||||
|
{ ...this._test('extra-data') }
|
||||||
|
/>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
label='minimal gas price'
|
label='minimal gas price'
|
||||||
hint='the minimum gas price for mining'
|
hint='the minimum gas price for mining'
|
||||||
value={ toNiceNumber(minGasPrice) }
|
value={ toNiceNumber(minGasPrice) }
|
||||||
onSubmit={ this.onMinGasPriceChange }
|
onSubmit={ this.onMinGasPriceChange }
|
||||||
{ ...this._test('min-gas-price') } />
|
allowCopy={ minGasPrice.toString() }
|
||||||
|
floatCopy
|
||||||
|
{ ...this._test('min-gas-price') }
|
||||||
|
/>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
label='gas floor target'
|
label='gas floor target'
|
||||||
hint='the gas floor target for mining'
|
hint='the gas floor target for mining'
|
||||||
value={ toNiceNumber(gasFloorTarget) }
|
value={ toNiceNumber(gasFloorTarget) }
|
||||||
onSubmit={ this.onGasFloorTargetChange }
|
onSubmit={ this.onGasFloorTargetChange }
|
||||||
{ ...this._test('gas-floor-target') } />
|
allowCopy={ gasFloorTarget.toString() }
|
||||||
|
floatCopy
|
||||||
|
{ ...this._test('gas-floor-target') }
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -97,21 +97,21 @@ export default class Status extends Component {
|
|||||||
<div { ...this._test('settings') }>
|
<div { ...this._test('settings') }>
|
||||||
<ContainerTitle title='network settings' />
|
<ContainerTitle title='network settings' />
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='chain'
|
label='chain'
|
||||||
value={ nodeStatus.netChain }
|
value={ nodeStatus.netChain }
|
||||||
{ ...this._test('chain') } />
|
{ ...this._test('chain') } />
|
||||||
<div className={ styles.row }>
|
<div className={ styles.row }>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='peers'
|
label='peers'
|
||||||
value={ peers }
|
value={ peers }
|
||||||
{ ...this._test('peers') } />
|
{ ...this._test('peers') } />
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='network port'
|
label='network port'
|
||||||
value={ nodeStatus.netPort.toString() }
|
value={ nodeStatus.netPort.toString() }
|
||||||
{ ...this._test('network-port') } />
|
{ ...this._test('network-port') } />
|
||||||
@ -119,21 +119,21 @@ export default class Status extends Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='rpc enabled'
|
label='rpc enabled'
|
||||||
value={ rpcSettings.enabled ? 'yes' : 'no' }
|
value={ rpcSettings.enabled ? 'yes' : 'no' }
|
||||||
{ ...this._test('rpc-enabled') } />
|
{ ...this._test('rpc-enabled') } />
|
||||||
<div className={ styles.row }>
|
<div className={ styles.row }>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='rpc interface'
|
label='rpc interface'
|
||||||
value={ rpcSettings.interface }
|
value={ rpcSettings.interface }
|
||||||
{ ...this._test('rpc-interface') } />
|
{ ...this._test('rpc-interface') } />
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.col6 }>
|
<div className={ styles.col6 }>
|
||||||
<Input
|
<Input
|
||||||
disabled
|
readOnly
|
||||||
label='rpc port'
|
label='rpc port'
|
||||||
value={ rpcSettings.port.toString() }
|
value={ rpcSettings.port.toString() }
|
||||||
{ ...this._test('rpc-port') } />
|
{ ...this._test('rpc-port') } />
|
||||||
|
Loading…
Reference in New Issue
Block a user