Extract i18n strings in views/* (#4695)

* i18n for writecontract

* i18n for writecontract store

* wallet i18n

* wallet confirmations i18n

* wallet details i18n

* wallet transactions i18n

* status i18n

* status calls i18n

* status callstoolbar i18n

* status debug i18n

* status editableValue i18n

* status miningSettings i18n

* status rpcCalls i18n

* status rpcDocs i18n

* status status i18n

* signer i18n

* signer origin i18n

* signer signRequest i18n

* signer transactionMainDetails i18n

* sign transactionPending i18n

* signer transactionPending i18n

* Fix duplicate ids

* Typo

* Adapt tests for i18n

* Actionbar i18n

* contracts i18n

* contract i18n

* contract/queries i18n

* contract/events i18n

* application/frameError i18n

* Actionbar key naming

* addresses i18n

* address i18n

* accounts i18n (tooltip)

* Plural strings for owner numbers

* IdentityIcon placement

* Re-apply s/actiobar/actionbar/ after merge
This commit is contained in:
Jaco Greeff 2017-03-02 12:24:54 +01:00 committed by Gav Wood
parent 36468f3fc7
commit 5dd406a19a
38 changed files with 1251 additions and 294 deletions

View File

@ -65,7 +65,7 @@ export default class ActionbarImport extends Component {
icon={ <FileUploadIcon /> } icon={ <FileUploadIcon /> }
label={ label={
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.button.import' id='ui.actionbar.import.button.import'
defaultMessage='import' defaultMessage='import'
/> />
} }
@ -87,19 +87,19 @@ export default class ActionbarImport extends Component {
const steps = typeof renderValidation === 'function' const steps = typeof renderValidation === 'function'
? [ ? [
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.step.select' id='ui.actionbar.import.step.select'
defaultMessage='select a file' defaultMessage='select a file'
/>, />,
error error
? ( ? (
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.step.error' id='ui.actionbar.import.step.error'
defaultMessage='error' defaultMessage='error'
/> />
) )
: ( : (
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.step.validate' id='ui.actionbar.import.step.validate'
defaultMessage='validate' defaultMessage='validate'
/>) />)
] ]
@ -128,7 +128,7 @@ export default class ActionbarImport extends Component {
key='cancel' key='cancel'
label={ label={
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.button.cancel' id='ui.actionbar.import.button.cancel'
defaultMessage='Cancel' defaultMessage='Cancel'
/> />
} }
@ -147,7 +147,7 @@ export default class ActionbarImport extends Component {
key='confirm' key='confirm'
label={ label={
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.button.confirm' id='ui.actionbar.import.button.confirm'
defaultMessage='Confirm' defaultMessage='Confirm'
/> />
} }
@ -169,7 +169,7 @@ export default class ActionbarImport extends Component {
<div> <div>
<p> <p>
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.error' id='ui.actionbar.import.error'
defaultMessage='An error occured: {errorText}' defaultMessage='An error occured: {errorText}'
values={ { values={ {
errorText errorText
@ -196,7 +196,7 @@ export default class ActionbarImport extends Component {
<div> <div>
<p className={ styles.desc }> <p className={ styles.desc }>
<FormattedMessage <FormattedMessage
id='ui.actiobar.import.confirm' id='ui.actionbar.import.confirm'
defaultMessage='Confirm that this is what was intended to import.' defaultMessage='Confirm that this is what was intended to import.'
/> />
</p> </p>

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import IconMenu from 'material-ui/IconMenu'; import IconMenu from 'material-ui/IconMenu';
@ -71,12 +72,38 @@ export default class ActionbarSort extends Component {
> >
{ {
showDefault showDefault
? this.renderMenuItem('', 'Default') ? this.renderMenuItem('', (
<FormattedMessage
id='ui.actionbar.sort.typeDefault'
defaultMessage='Default'
/>
))
: null : null
} }
{ this.renderMenuItem('tags', 'Sort by tags') } {
{ this.renderMenuItem('name', 'Sort by name') } this.renderMenuItem('tags', (
{ this.renderMenuItem('eth', 'Sort by ETH') } <FormattedMessage
id='ui.actionbar.sort.typeTags'
defaultMessage='Sort by tags'
/>
))
}
{
this.renderMenuItem('name', (
<FormattedMessage
id='ui.actionbar.sort.typeName'
defaultMessage='Sort by name'
/>
))
}
{
this.renderMenuItem('eth', (
<FormattedMessage
id='ui.actionbar.sort.typeEth'
defaultMessage='Sort by ETH'
/>
))
}
{ this.renderSortByMetas() } { this.renderSortByMetas() }
</IconMenu> </IconMenu>
@ -88,8 +115,17 @@ export default class ActionbarSort extends Component {
return metas return metas
.map((meta, index) => { .map((meta, index) => {
return this const label = (
.renderMenuItem(meta.key, `Sort by ${meta.label}`, index); <FormattedMessage
id='ui.actionbar.sort.sortBy'
defaultMessage='Sort by {label}'
values={ {
label: meta.label
} }
/>
);
return this.renderMenuItem(meta.key, label, index);
}); });
} }

View File

@ -29,22 +29,29 @@ export ContractIcon from 'material-ui/svg-icons/action/code';
export CopyIcon from 'material-ui/svg-icons/content/content-copy'; export CopyIcon from 'material-ui/svg-icons/content/content-copy';
export DashboardIcon from 'material-ui/svg-icons/action/dashboard'; export DashboardIcon from 'material-ui/svg-icons/action/dashboard';
export DeleteIcon from 'material-ui/svg-icons/action/delete'; export DeleteIcon from 'material-ui/svg-icons/action/delete';
export DevelopIcon from 'material-ui/svg-icons/action/description';
export DoneIcon from 'material-ui/svg-icons/action/done-all'; export DoneIcon from 'material-ui/svg-icons/action/done-all';
export EditIcon from 'material-ui/svg-icons/content/create'; export EditIcon from 'material-ui/svg-icons/content/create';
export ErrorIcon from 'material-ui/svg-icons/alert/error'; export ErrorIcon from 'material-ui/svg-icons/alert/error';
export FileUploadIcon from 'material-ui/svg-icons/file/file-upload'; export FileUploadIcon from 'material-ui/svg-icons/file/file-upload';
export FileIcon from 'material-ui/svg-icons/editor/insert-drive-file'; export FileIcon from 'material-ui/svg-icons/editor/insert-drive-file';
export FingerprintIcon from 'material-ui/svg-icons/action/fingerprint'; export FingerprintIcon from 'material-ui/svg-icons/action/fingerprint';
export GasIcon from 'material-ui/svg-icons/maps/local-gas-station';
export KeyIcon from 'material-ui/svg-icons/communication/vpn-key'; export KeyIcon from 'material-ui/svg-icons/communication/vpn-key';
export KeyboardIcon from 'material-ui/svg-icons/hardware/keyboard'; export KeyboardIcon from 'material-ui/svg-icons/hardware/keyboard';
export LinkIcon from 'material-ui/svg-icons/content/link'; export LinkIcon from 'material-ui/svg-icons/content/link';
export ListIcon from 'material-ui/svg-icons/action/view-list';
export LockedIcon from 'material-ui/svg-icons/action/lock'; export LockedIcon from 'material-ui/svg-icons/action/lock';
export MembershipIcon from 'material-ui/svg-icons/action/card-membership'; export MembershipIcon from 'material-ui/svg-icons/action/card-membership';
export MoveIcon from 'material-ui/svg-icons/action/open-with'; export MoveIcon from 'material-ui/svg-icons/action/open-with';
export NextIcon from 'material-ui/svg-icons/navigation/arrow-forward'; export NextIcon from 'material-ui/svg-icons/navigation/arrow-forward';
export PauseIcon from 'material-ui/svg-icons/av/pause';
export PlayIcon from 'material-ui/svg-icons/av/play-arrow';
export PrevIcon from 'material-ui/svg-icons/navigation/arrow-back'; export PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
export PrintIcon from 'material-ui/svg-icons/action/print'; export PrintIcon from 'material-ui/svg-icons/action/print';
export RefreshIcon from 'material-ui/svg-icons/action/autorenew'; export RefreshIcon from 'material-ui/svg-icons/action/autorenew';
export ReorderIcon from 'material-ui/svg-icons/action/reorder';
export ReplayIcon from 'material-ui/svg-icons/av/replay';
export SaveIcon from 'material-ui/svg-icons/content/save'; export SaveIcon from 'material-ui/svg-icons/content/save';
export SendIcon from 'material-ui/svg-icons/content/send'; export SendIcon from 'material-ui/svg-icons/content/send';
export SettingsIcon from 'material-ui/svg-icons/action/settings'; export SettingsIcon from 'material-ui/svg-icons/action/settings';

View File

@ -214,7 +214,13 @@ class Summary extends Component {
/> />
</div> </div>
<ReactTooltip id={ `owner_${owner.address}` }> <ReactTooltip id={ `owner_${owner.address}` }>
<strong>{ owner.name } </strong><small> (owner)</small> <FormattedMessage
id='accounts.tooltips.owner'
defaultMessage='{name} (owner)'
values={ {
name: owner.name
} }
/>
</ReactTooltip> </ReactTooltip>
</Link> </Link>
); );

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -49,13 +50,21 @@ class Delete extends Component {
return ( return (
<ConfirmDialog <ConfirmDialog
className={ styles.delete } className={ styles.delete }
title='confirm removal' title={
<FormattedMessage
id='address.delete.title'
defaultMessage='confirm removal'
/>
}
visible visible
onDeny={ this.closeDeleteDialog } onDeny={ this.closeDeleteDialog }
onConfirm={ this.onDeleteConfirmed } onConfirm={ this.onDeleteConfirmed }
> >
<div className={ styles.hero }> <div className={ styles.hero }>
Are you sure you want to remove the following address from your addressbook? <FormattedMessage
id='address.delete.confirmInfo'
defaultMessage='Are you sure you want to remove the following address from your addressbook?'
/>
</div> </div>
<div className={ styles.info }> <div className={ styles.info }>
<IdentityIcon <IdentityIcon
@ -64,7 +73,10 @@ class Delete extends Component {
/> />
<div className={ styles.nameinfo }> <div className={ styles.nameinfo }>
<div className={ styles.header }> <div className={ styles.header }>
<IdentityName address={ account.address } unknown /> <IdentityName
address={ account.address }
unknown
/>
</div> </div>
<div className={ styles.address }> <div className={ styles.address }>
{ account.address } { account.address }

View File

@ -15,14 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import ContentCreate from 'material-ui/svg-icons/content/create';
import ContentAdd from 'material-ui/svg-icons/content/add';
import { EditMeta, AddAddress } from '~/modals'; import { EditMeta, AddAddress } from '~/modals';
import { Actionbar, Button, Page } from '~/ui'; import { Actionbar, Button, Page } from '~/ui';
import { AddIcon, DeleteIcon, EditIcon } from '~/ui/Icons';
import Header from '../Account/Header'; import Header from '../Account/Header';
import Transactions from '../Account/Transactions'; import Transactions from '../Account/Transactions';
@ -146,14 +145,24 @@ class Address extends Component {
const buttons = [ const buttons = [
<Button <Button
key='editmeta' key='editmeta'
icon={ <ContentCreate /> } icon={ <EditIcon /> }
label='edit' label={
<FormattedMessage
id='address.buttons.edit'
defaultMessage='edit'
/>
}
onClick={ this.onEditClick } onClick={ this.onEditClick }
/>, />,
<Button <Button
key='delete' key='delete'
icon={ <ActionDelete /> } icon={ <DeleteIcon /> }
label='forget' label={
<FormattedMessage
id='address.buttons.forget'
defaultMessage='forget'
/>
}
onClick={ this.showDeleteDialog } onClick={ this.showDeleteDialog }
/> />
]; ];
@ -161,16 +170,30 @@ class Address extends Component {
const addToBook = ( const addToBook = (
<Button <Button
key='newAddress' key='newAddress'
icon={ <ContentAdd /> } icon={ <AddIcon /> }
label='save' label={
<FormattedMessage
id='address.buttons.save'
defaultMessage='save'
/>
}
onClick={ this.onOpenAdd } onClick={ this.onOpenAdd }
/> />
); );
return ( return (
<Actionbar <Actionbar
title='Address Information' title={
buttons={ !contact ? [ addToBook ] : buttons } <FormattedMessage
id='address.title'
defaultMessage='Address Information'
/>
}
buttons={
!contact
? [ addToBook ]
: buttons
}
/> />
); );
} }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import ContentAdd from 'material-ui/svg-icons/content/add'; import ContentAdd from 'material-ui/svg-icons/content/add';
@ -143,7 +144,12 @@ class Addresses extends Component {
<Button <Button
key='newAddress' key='newAddress'
icon={ <ContentAdd /> } icon={ <ContentAdd /> }
label='address' label={
<FormattedMessage
id='addresses.buttons.add'
defaultMessage='address'
/>
}
onClick={ this.onOpenAdd } onClick={ this.onOpenAdd }
/>, />,
<ActionbarExport <ActionbarExport
@ -163,7 +169,12 @@ class Addresses extends Component {
return ( return (
<Actionbar <Actionbar
className={ styles.toolbar } className={ styles.toolbar }
title='Saved Addresses' title={
<FormattedMessage
id='addresses.title'
defaultMessage='Saved Addresses'
/>
}
buttons={ buttons } buttons={ buttons }
/> />
); );
@ -187,7 +198,12 @@ class Addresses extends Component {
renderValidation = (content) => { renderValidation = (content) => {
const error = { const error = {
error: 'The provided file is invalid...' error: (
<FormattedMessage
id='addresses.errors.invalidFile'
defaultMessage='The provided file is invalid...'
/>
)
}; };
try { try {
@ -214,7 +230,9 @@ class Addresses extends Component {
{ body } { body }
</div> </div>
); );
} catch (e) { return error; } } catch (e) {
return error;
}
} }
onImport = (content) => { onImport = (content) => {

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component } from 'react'; import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import styles from './frameError.css'; import styles from './frameError.css';
@ -22,7 +23,10 @@ export default class FrameError extends Component {
render () { render () {
return ( return (
<div className={ styles.error }> <div className={ styles.error }>
ERROR: This application cannot and should not be loaded in an embedded iFrame <FormattedMessage
id='application.frame.error'
defaultMessage='ERROR: This application cannot and should not be loaded in an embedded iFrame'
/>
</div> </div>
); );
} }

View File

@ -17,6 +17,7 @@
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import moment from 'moment'; import moment from 'moment';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { IdentityIcon, IdentityName, Input, InputAddress } from '~/ui'; import { IdentityIcon, IdentityName, Input, InputAddress } from '~/ui';
import ShortenedHash from '~/ui/ShortenedHash'; import ShortenedHash from '~/ui/ShortenedHash';
@ -64,7 +65,12 @@ export default class Event extends Component {
<td className={ styles.timestamp }> <td className={ styles.timestamp }>
<div>{ <div>{
event.state === 'pending' event.state === 'pending'
? 'pending' ? (
<FormattedMessage
id='contract.events.eventPending'
defaultMessage='pending'
/>
)
: this.formatBlockTimestamp(block) : this.formatBlockTimestamp(block)
}</div> }</div>
<div>{ this.formatNumber(transaction.blockNumber) }</div> <div>{ this.formatNumber(transaction.blockNumber) }</div>
@ -96,7 +102,11 @@ export default class Event extends Component {
center center
inline inline
/> />
{ withName ? <IdentityName address={ address } /> : address } {
withName
? <IdentityName address={ address } />
: address
}
</span> </span>
); );
} }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { Container, Loading } from '~/ui'; import { Container, Loading } from '~/ui';
@ -22,6 +23,13 @@ import { Container, Loading } from '~/ui';
import Event from './Event'; import Event from './Event';
import styles from '../contract.css'; import styles from '../contract.css';
const TITLE = (
<FormattedMessage
id='contract.events.title'
defaultMessage='events'
/>
);
export default class Events extends Component { export default class Events extends Component {
static contextTypes = { static contextTypes = {
api: PropTypes.object api: PropTypes.object
@ -43,7 +51,7 @@ export default class Events extends Component {
if (isLoading) { if (isLoading) {
return ( return (
<Container title='events'> <Container title={ TITLE }>
<div> <div>
<Loading size={ 2 } /> <Loading size={ 2 } />
</div> </div>
@ -53,8 +61,13 @@ export default class Events extends Component {
if (!events || !events.length) { if (!events || !events.length) {
return ( return (
<Container title='events'> <Container title={ TITLE }>
<p>No events has been sent from this contract.</p> <p>
<FormattedMessage
id='contract.events.noEvents'
defaultMessage='No events has been sent from this contract.'
/>
</p>
</Container> </Container>
); );
} }
@ -73,7 +86,7 @@ export default class Events extends Component {
}); });
return ( return (
<Container title='events'> <Container title={ TITLE }>
<table className={ styles.events }> <table className={ styles.events }>
<thead> <thead>
<tr> <tr>

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
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';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -80,7 +81,12 @@ class InputQuery extends Component {
</CardText> </CardText>
<CardActions> <CardActions>
<Button <Button
label='Query' label={
<FormattedMessage
id='contract.queries.buttons.query'
defaultMessage='Query'
/>
}
disabled={ !isValid } disabled={ !isValid }
onClick={ this.onClick } onClick={ this.onClick }
/> />
@ -94,7 +100,9 @@ class InputQuery extends Component {
const { accountsInfo, outputs } = this.props; const { accountsInfo, outputs } = this.props;
if (isLoading) { if (isLoading) {
return (<LinearProgress mode='indeterminate' />); return (
<LinearProgress mode='indeterminate' />
);
} }
if (!results || results.length < 1) { if (!results || results.length < 1) {

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Card, CardTitle, CardText } from 'material-ui/Card'; import { Card, CardTitle, CardText } from 'material-ui/Card';
import InputQuery from './inputQuery'; import InputQuery from './inputQuery';
@ -59,7 +60,14 @@ export default class Queries extends Component {
} }
return ( return (
<Container title='queries'> <Container
title={
<FormattedMessage
id='contract.queries.title'
defaultMessage='queries'
/>
}
>
<div className={ styles.methods }> <div className={ styles.methods }>
{ {
noInputQueries.length > 0 noInputQueries.length > 0

View File

@ -15,22 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { FormattedMessage } from 'react-intl';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import ActionDelete from 'material-ui/svg-icons/action/delete'; import { EditMeta, ExecuteContract } from '~/modals';
import AvPlayArrow from 'material-ui/svg-icons/av/play-arrow';
import ContentCreate from 'material-ui/svg-icons/content/create';
import EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
import ContentClear from 'material-ui/svg-icons/content/clear';
import { newError } from '~/redux/actions'; import { newError } from '~/redux/actions';
import { setVisibleAccounts } from '~/redux/providers/personalActions'; import { setVisibleAccounts } from '~/redux/providers/personalActions';
import { EditMeta, ExecuteContract } from '~/modals';
import { Actionbar, Button, Page, Portal } from '~/ui'; import { Actionbar, Button, Page, Portal } from '~/ui';
import { CancelIcon, DeleteIcon, EditIcon, PlayIcon, VisibleIcon } from '~/ui/Icons';
import Editor from '~/ui/Editor'; import Editor from '~/ui/Editor';
import Header from '../Account/Header'; import Header from '../Account/Header';
@ -191,8 +185,13 @@ class Contract extends Component {
const cancelBtn = ( const cancelBtn = (
<Button <Button
icon={ <ContentClear /> } icon={ <CancelIcon /> }
label='Close' label={
<FormattedMessage
id='contract.buttons.close'
defaultMessage='Close'
/>
}
onClick={ this.closeDetailsDialog } onClick={ this.closeDetailsDialog }
/> />
); );
@ -202,7 +201,12 @@ class Contract extends Component {
buttons={ [ cancelBtn ] } buttons={ [ cancelBtn ] }
onClose={ this.closeDetailsDialog } onClose={ this.closeDetailsDialog }
open open
title={ 'contract details' } title={
<FormattedMessage
id='contract.details.title'
defaultMessage='contract details'
/>
}
> >
<div className={ styles.details }> <div className={ styles.details }>
{ this.renderSource(contract) } { this.renderSource(contract) }
@ -243,33 +247,58 @@ class Contract extends Component {
const buttons = [ const buttons = [
<Button <Button
key='execute' key='execute'
icon={ <AvPlayArrow /> } icon={ <PlayIcon /> }
label='execute' label={
<FormattedMessage
id='contract.buttons.execute'
defaultMessage='execute'
/>
}
onClick={ this.showExecuteDialog } onClick={ this.showExecuteDialog }
/>, />,
<Button <Button
key='editmeta' key='editmeta'
icon={ <ContentCreate /> } icon={ <EditIcon /> }
label='edit' label={
<FormattedMessage
id='contract.buttons.edit'
defaultMessage='edit'
/>
}
onClick={ this.showEditDialog } onClick={ this.showEditDialog }
/>, />,
<Button <Button
key='delete' key='delete'
icon={ <ActionDelete /> } icon={ <DeleteIcon /> }
label='forget' label={
<FormattedMessage
id='contract.buttons.forget'
defaultMessage='forget'
/>
}
onClick={ this.showDeleteDialog } onClick={ this.showDeleteDialog }
/>, />,
<Button <Button
key='viewDetails' key='viewDetails'
icon={ <EyeIcon /> } icon={ <VisibleIcon /> }
label='details' label={
<FormattedMessage
id='contract.buttons.details'
defaultMessage='details'
/>
}
onClick={ this.showDetailsDialog } onClick={ this.showDetailsDialog }
/> />
]; ];
return ( return (
<Actionbar <Actionbar
title='Contract Information' title={
<FormattedMessage
id='contract.title'
defaultMessage='Contract Information'
/>
}
buttons={ !account ? [] : buttons } buttons={ !account ? [] : buttons }
/> />
); );

View File

@ -15,19 +15,40 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router'; import { Link } from 'react-router';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import ContentAdd from 'material-ui/svg-icons/content/add';
import FileIcon from 'material-ui/svg-icons/action/description';
import { uniq, isEqual } from 'lodash'; import { uniq, isEqual } from 'lodash';
import { Actionbar, ActionbarSearch, ActionbarSort, Button, Page } from '~/ui';
import { AddContract, DeployContract } from '~/modals'; import { AddContract, DeployContract } from '~/modals';
import { setVisibleAccounts } from '~/redux/providers/personalActions'; import { setVisibleAccounts } from '~/redux/providers/personalActions';
import { Actionbar, ActionbarSearch, ActionbarSort, Button, Page } from '~/ui';
import { AddIcon, DevelopIcon } from '~/ui/Icons';
import List from '../Accounts/List'; import List from '../Accounts/List';
const META_SORT = [
{
key: 'timestamp',
label: (
<FormattedMessage
id='contracts.sortOrder.date'
defaultMessage='date'
/>
)
},
{
key: 'blockNumber:-1',
label: (
<FormattedMessage
id='contracts.sortOrder.minedBlock'
defaultMessage='mined block'
/>
)
}
];
class Contracts extends Component { class Contracts extends Component {
static contextTypes = { static contextTypes = {
api: PropTypes.object.isRequired api: PropTypes.object.isRequired
@ -109,10 +130,7 @@ class Contracts extends Component {
key='sortAccounts' key='sortAccounts'
id='sortContracts' id='sortContracts'
order={ this.state.sortOrder } order={ this.state.sortOrder }
metas={ [ metas={ META_SORT }
{ key: 'timestamp', label: 'date' },
{ key: 'blockNumber:-1', label: 'mined block' }
] }
showDefault={ false } showDefault={ false }
onChange={ onChange } onChange={ onChange }
/> />
@ -137,14 +155,24 @@ class Contracts extends Component {
const buttons = [ const buttons = [
<Button <Button
key='addContract' key='addContract'
icon={ <ContentAdd /> } icon={ <AddIcon /> }
label='watch' label={
<FormattedMessage
id='contracts.buttons.watch'
defaultMessage='watch'
/>
}
onClick={ this.onAddContract } onClick={ this.onAddContract }
/>, />,
<Button <Button
key='deployContract' key='deployContract'
icon={ <ContentAdd /> } icon={ <AddIcon /> }
label='deploy' label={
<FormattedMessage
id='contracts.buttons.deploy'
defaultMessage='deploy'
/>
}
onClick={ this.onDeployContract } onClick={ this.onDeployContract }
/>, />,
<Link <Link
@ -152,8 +180,13 @@ class Contracts extends Component {
key='writeContract' key='writeContract'
> >
<Button <Button
icon={ <FileIcon /> } icon={ <DevelopIcon /> }
label='develop' label={
<FormattedMessage
id='contracts.buttons.develop'
defaultMessage='develop'
/>
}
/> />
</Link>, </Link>,
@ -163,7 +196,12 @@ class Contracts extends Component {
return ( return (
<Actionbar <Actionbar
title='Contracts' title={
<FormattedMessage
id='contracts.title'
defaultMessage='Contracts'
/>
}
buttons={ buttons } buttons={ buttons }
/> />
); );

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import IdentityIcon from '~/ui/IdentityIcon'; import IdentityIcon from '~/ui/IdentityIcon';
@ -45,16 +46,36 @@ export default class RequestOrigin extends Component {
renderOrigin (origin) { renderOrigin (origin) {
if (origin.type === 'unknown') { if (origin.type === 'unknown') {
return ( return (
<span className={ styles.unknown }>via unknown interface</span> <span className={ styles.unknown }>
<FormattedMessage
id='signer.requestOrigin.unknownInterface'
defaultMessage='via unknown interface'
/>
</span>
); );
} }
if (origin.type === 'dapp') { if (origin.type === 'dapp') {
return ( return (
<span> <span>
by a dapp at <span className={ styles.url }> <FormattedMessage
{ origin.details || 'unknown URL' } id='signer.requestOrigin.dapp'
defaultMessage='by a dapp at {url}'
values={ {
url: (
<span className={ styles.url }>
{
origin.details || (
<FormattedMessage
id='signer.requestOrigin.unknownUrl'
defaultMessage='unknown URL'
/>
)
}
</span> </span>
)
} }
/>
</span> </span>
); );
} }
@ -62,9 +83,24 @@ export default class RequestOrigin extends Component {
if (origin.type === 'rpc') { if (origin.type === 'rpc') {
return ( return (
<span> <span>
via RPC <span className={ styles.url }> <FormattedMessage
({ origin.details || 'unidentified' }) id='signer.requestOrigin.rpc'
defaultMessage='via RPC {rpc}'
values={ {
url: (
<span className={ styles.url }>
({
origin.details || (
<FormattedMessage
id='signer.requestOrigin.unknownRpc'
defaultMessage='unidentified'
/>
)
})
</span> </span>
)
} }
/>
</span> </span>
); );
} }
@ -72,7 +108,10 @@ export default class RequestOrigin extends Component {
if (origin.type === 'ipc') { if (origin.type === 'ipc') {
return ( return (
<span> <span>
via IPC session <FormattedMessage
id='signer.requestOrigin.ipc'
defaultMessage='via IPC session'
/>
<span <span
className={ styles.hash } className={ styles.hash }
title={ origin.details } title={ origin.details }
@ -94,13 +133,21 @@ export default class RequestOrigin extends Component {
renderSigner (session) { renderSigner (session) {
if (session.substr(2) === this.context.api.transport.sessionHash) { if (session.substr(2) === this.context.api.transport.sessionHash) {
return ( return (
<span title={ session }>via current tab</span> <span title={ session }>
<FormattedMessage
id='signer.requestOrigin.signerCurrent'
defaultMessage='via current tab'
/>
</span>
); );
} }
return ( return (
<span> <span>
via UI session <FormattedMessage
id='signer.requestOrigin.signerUI'
defaultMessage='via UI session'
/>
<span <span
className={ styles.hash } className={ styles.hash }
title={ `UI Session id: ${session}` } title={ `UI Session id: ${session}` }

View File

@ -34,39 +34,39 @@ describe('views/Signer/components/RequestOrigin', () => {
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'unknown', details: '' } } />, <RequestOrigin origin={ { type: 'unknown', details: '' } } />,
context context
).text()).to.equal('Requested via unknown interface'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.unknownInterface');
}); });
it('renders dapps', () => { it('renders dapps', () => {
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'dapp', details: 'http://parity.io' } } />, <RequestOrigin origin={ { type: 'dapp', details: 'http://parity.io' } } />,
context context
).text()).to.equal('Requested by a dapp at http://parity.io'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.dapp');
}); });
it('renders rpc', () => { it('renders rpc', () => {
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'rpc', details: '' } } />, <RequestOrigin origin={ { type: 'rpc', details: '' } } />,
context context
).text()).to.equal('Requested via RPC (unidentified)'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.rpc');
}); });
it('renders ipc', () => { it('renders ipc', () => {
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'ipc', details: '0x1234' } } />, <RequestOrigin origin={ { type: 'ipc', details: '0x1234' } } />,
context context
).text()).to.equal('Requested via IPC session<Connect(IdentityIcon) />'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.ipc');
}); });
it('renders signer', () => { it('renders signer', () => {
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'signer', details: '0x12345' } } />, <RequestOrigin origin={ { type: 'signer', details: '0x12345' } } />,
context context
).text()).to.equal('Requested via UI session<Connect(IdentityIcon) />'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.signerUI');
expect(shallow( expect(shallow(
<RequestOrigin origin={ { type: 'signer', details: '0x1234' } } />, <RequestOrigin origin={ { type: 'signer', details: '0x1234' } } />,
context context
).text()).to.equal('Requested via current tab'); ).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.signerCurrent');
}); });
}); });

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import Account from '../Account'; import Account from '../Account';
@ -91,9 +92,16 @@ export default class SignRequest extends Component {
} }
renderBinaryDetails (data) { renderBinaryDetails (data) {
return (<div className={ styles.signData }> return (
<p>(Unknown binary data)</p> <div className={ styles.signData }>
</div>); <p>
<FormattedMessage
id='signer.signRequest.unknownBinary'
defaultMessage='(Unknown binary data)'
/>
</p>
</div>
);
} }
renderDetails () { renderDetails () {
@ -119,13 +127,25 @@ export default class SignRequest extends Component {
<RequestOrigin origin={ origin } /> <RequestOrigin origin={ origin } />
</div> </div>
<div className={ styles.info } title={ api.util.sha3(data) }> <div className={ styles.info } title={ api.util.sha3(data) }>
<p>A request to sign data using your account:</p> <p>
<FormattedMessage
id='signer.signRequest.request'
defaultMessage='A request to sign data using your account:'
/>
</p>
{ {
isAscii(data) isAscii(data)
? this.renderAsciiDetails(api.util.hexToAscii(data)) ? this.renderAsciiDetails(api.util.hexToAscii(data))
: this.renderBinaryDetails(data) : this.renderBinaryDetails(data)
} }
<p><strong>WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.</strong></p> <p>
<strong>
<FormattedMessage
id='signer.signRequest.warning'
defaultMessage='WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.'
/>
</strong>
</p>
</div> </div>
</div> </div>
); );
@ -138,14 +158,24 @@ export default class SignRequest extends Component {
if (status === 'confirmed') { if (status === 'confirmed') {
return ( return (
<div className={ styles.actions }> <div className={ styles.actions }>
<span className={ styles.isConfirmed }>Confirmed</span> <span className={ styles.isConfirmed }>
<FormattedMessage
id='signer.signRequest.state.confirmed'
defaultMessage='Confirmed'
/>
</span>
</div> </div>
); );
} }
return ( return (
<div className={ styles.actions }> <div className={ styles.actions }>
<span className={ styles.isRejected }>Rejected</span> <span className={ styles.isRejected }>
<FormattedMessage
id='signer.signRequest.state.rejected'
defaultMessage='Rejected'
/>
</span>
</div> </div>
); );
} }

View File

@ -14,11 +14,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import MapsLocalGasStation from 'material-ui/svg-icons/maps/local-gas-station';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
import { Button, MethodDecoding } from '~/ui'; import { Button, MethodDecoding } from '~/ui';
import { GasIcon } from '~/ui/Icons';
import * as tUtil from '../util/transaction'; import * as tUtil from '../util/transaction';
import Account from '../Account'; import Account from '../Account';
@ -103,8 +104,13 @@ export default class TransactionMainDetails extends Component {
return ( return (
<div className={ styles.editButtonRow }> <div className={ styles.editButtonRow }>
<Button <Button
icon={ <MapsLocalGasStation /> } icon={ <GasIcon /> }
label='Edit conditions/gas/gasPrice' label={
<FormattedMessage
id='signer.mainDetails.editTx'
defaultMessage='Edit conditions/gas/gasPrice'
/>
}
onClick={ this.toggleGasEditor } onClick={ this.toggleGasEditor }
/> />
</div> </div>
@ -128,8 +134,23 @@ export default class TransactionMainDetails extends Component {
{ totalValueDisplay } <small>ETH</small> { totalValueDisplay } <small>ETH</small>
</div> </div>
<ReactTooltip id={ labelId }> <ReactTooltip id={ labelId }>
The value of the transaction including the mining fee is <strong>{ totalValueDisplayWei }</strong> <small>WEI</small>. <br /> <FormattedMessage
(This includes a mining fee of <strong>{ feeEth }</strong> <small>ETH</small>) id='signer.mainDetails.tooltips.total1'
defaultMessage='The value of the transaction including the mining fee is {total} {type}.'
values={ {
total: <strong>{ totalValueDisplayWei }</strong>,
type: <small>WEI</small>
} }
/>
<br />
<FormattedMessage
id='signer.mainDetails.tooltips.total2'
defaultMessage='(This includes a mining fee of {fee} {token})'
values={ {
fee: <strong>{ feeEth }</strong>,
token: <small>ETH</small>
} }
/>
</ReactTooltip> </ReactTooltip>
</div> </div>
); );
@ -151,7 +172,11 @@ export default class TransactionMainDetails extends Component {
<small>ETH</small> <small>ETH</small>
</div> </div>
<ReactTooltip id={ labelId }> <ReactTooltip id={ labelId }>
The value of the transaction.<br /> <FormattedMessage
id='signer.mainDetails.tooltips.value1'
defaultMessage='The value of the transaction.'
/>
<br />
<strong>{ valueDisplayWei }</strong> <small>WEI</small> <strong>{ valueDisplayWei }</strong> <small>WEI</small>
</ReactTooltip> </ReactTooltip>
</div> </div>

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Button, GasPriceEditor } from '~/ui'; import { Button, GasPriceEditor } from '~/ui';
@ -132,7 +133,12 @@ export default class TransactionPending extends Component {
<div className={ `${styles.container} ${className}` }> <div className={ `${styles.container} ${className}` }>
<GasPriceEditor store={ this.gasStore }> <GasPriceEditor store={ this.gasStore }>
<Button <Button
label='view transaction' label={
<FormattedMessage
id='signer.txPending.buttons.viewToggle'
defaultMessage='view transaction'
/>
}
onClick={ this.toggleGasEditor } onClick={ this.toggleGasEditor }
/> />
</GasPriceEditor> </GasPriceEditor>

View File

@ -18,6 +18,7 @@ import keycode from 'keycode';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
@ -98,7 +99,17 @@ class TransactionPendingFormConfirm extends Component {
const passwordHintText = this.getPasswordHint(); const passwordHintText = this.getPasswordHint();
const passwordHint = passwordHintText const passwordHint = passwordHintText
? (<div><span>(hint) </span>{ passwordHintText }</div>) ? (
<div>
<FormattedMessage
id='signer.txPendingConfirm.passwordHint'
defaultMessage='(hint) {hint}'
values={ {
hint: passwordHintText
} }
/>
</div>
)
: null; : null;
const isWalletOk = !isExternal || (walletError === null && wallet !== null); const isWalletOk = !isExternal || (walletError === null && wallet !== null);
@ -113,13 +124,33 @@ class TransactionPendingFormConfirm extends Component {
<Input <Input
hint={ hint={
isExternal isExternal
? 'decrypt the key' ? (
: 'unlock the account' <FormattedMessage
id='signer.txPendingConfirm.decryptKey.hint'
defaultMessage='decrypt the key'
/>
)
: (
<FormattedMessage
id='signer.txPendingConfirm.unlockAccount.hint'
defaultMessage='unlock the account'
/>
)
} }
label={ label={
isExternal isExternal
? 'Key Password' ? (
: 'Account Password' <FormattedMessage
id='signer.txPendingConfirm.decryptKey.label'
defaultMessage='Key Password'
/>
)
: (
<FormattedMessage
id='signer.txPendingConfirm.unlockAccount.label'
defaultMessage='Account Password'
/>
)
} }
onChange={ this.onModifyPassword } onChange={ this.onModifyPassword }
onKeyDown={ this.onKeyDown } onKeyDown={ this.onKeyDown }
@ -149,8 +180,18 @@ class TransactionPendingFormConfirm extends Component {
} }
label={ label={
isSending isSending
? 'Confirming...' ? (
: 'Confirm Request' <FormattedMessage
id='signer.txPendingConfirm.buttons.confirmBusy'
defaultMessage='Confirming...'
/>
)
: (
<FormattedMessage
id='signer.txPendingConfirm.buttons.confirmRequest'
defaultMessage='Confirm Request'
/>
)
} }
onTouchTap={ this.onConfirm } onTouchTap={ this.onConfirm }
primary primary
@ -169,7 +210,12 @@ class TransactionPendingFormConfirm extends Component {
<Input <Input
className={ styles.fileInput } className={ styles.fileInput }
error={ walletError } error={ walletError }
label='Select Local Key' label={
<FormattedMessage
id='signer.txPendingConfirm.keySelect.label'
defaultMessage='Select Local Key'
/>
}
onChange={ this.onKeySelect } onChange={ this.onKeySelect }
type='file' type='file'
/> />
@ -183,7 +229,10 @@ class TransactionPendingFormConfirm extends Component {
return ( return (
<ReactTooltip id={ `transactionConfirmForm${this.id}` }> <ReactTooltip id={ `transactionConfirmForm${this.id}` }>
Please provide a password for this account <FormattedMessage
id='signer.txPendingConfirm.tooltips.password'
defaultMessage='Please provide a password for this account'
/>
</ReactTooltip> </ReactTooltip>
); );
} }
@ -216,7 +265,12 @@ class TransactionPendingFormConfirm extends Component {
} catch (error) { } catch (error) {
this.setState({ this.setState({
wallet: null, wallet: null,
walletError: 'Given wallet file is invalid.' walletError: (
<FormattedMessage
id='signer.txPendingConfirm.errors.invalidWallet'
defaultMessage='Given wallet file is invalid.'
/>
)
}); });
} }
}; };

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
@ -32,14 +33,28 @@ export default class TransactionPendingFormReject extends Component {
return ( return (
<div> <div>
<div className={ styles.rejectText }> <div className={ styles.rejectText }>
Are you sure you want to reject request? <br /> <FormattedMessage
<strong>This cannot be undone</strong> id='signer.txPendingReject.info'
defaultMessage='Are you sure you want to reject request?'
/>
<br />
<strong>
<FormattedMessage
id='signer.txPendingReject.undone'
defaultMessage='This cannot be undone'
/>
</strong>
</div> </div>
<RaisedButton <RaisedButton
onTouchTap={ onReject } onTouchTap={ onReject }
className={ styles.rejectButton } className={ styles.rejectButton }
fullWidth fullWidth
label={ 'Reject Request' } label={
<FormattedMessage
id='signer.txPendingReject.buttons.reject'
defaultMessage='Reject Request'
/>
}
/> />
</div> </div>
); );

View File

@ -15,8 +15,9 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import BackIcon from 'material-ui/svg-icons/navigation/arrow-back'; import { PrevIcon } from '~/ui/Icons';
import TransactionPendingFormConfirm from './TransactionPendingFormConfirm'; import TransactionPendingFormConfirm from './TransactionPendingFormConfirm';
import TransactionPendingFormReject from './TransactionPendingFormReject'; import TransactionPendingFormReject from './TransactionPendingFormReject';
@ -75,9 +76,24 @@ export default class TransactionPendingForm extends Component {
let html; let html;
if (!isRejectOpen) { if (!isRejectOpen) {
html = <span>reject request</span>; html = (
<span>
<FormattedMessage
id='signer.txPendingForm.reject'
defaultMessage='reject request'
/>
</span>
);
} else { } else {
html = <span><BackIcon />{ "I've changed my mind" }</span>; html = (
<span>
<PrevIcon />
<FormattedMessage
id='signer.txPendingForm.changedMind'
defaultMessage="I've changed my mind"
/>
</span>
);
} }
return ( return (

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component } from 'react'; import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { Actionbar } from '~/ui'; import { Actionbar } from '~/ui';
import RequestsPage from './containers/RequestsPage'; import RequestsPage from './containers/RequestsPage';
@ -23,7 +24,14 @@ export default class Signer extends Component {
render () { render () {
return ( return (
<div> <div>
<Actionbar title='Trusted Signer' /> <Actionbar
title={
<FormattedMessage
id='signer.title'
defaultMessage='Trusted Signer'
/>
}
/>
<RequestsPage /> <RequestsPage />
</div> </div>
); );

View File

@ -15,6 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import Call from '../Call'; import Call from '../Call';
import CallsToolbar from '../CallsToolbar'; import CallsToolbar from '../CallsToolbar';
import styles from './Calls.css'; import styles from './Calls.css';
@ -33,7 +35,12 @@ export default class Calls extends Component {
{ ...this._test('container') } { ...this._test('container') }
> >
{ this.renderClear() } { this.renderClear() }
<h2 className={ styles.header }>History</h2> <h2 className={ styles.header }>
<FormattedMessage
id='status.calls.title'
defaultMessage='History'
/>
</h2>
<div className={ `${styles.history} row` } ref={ this.setCallsHistory }> <div className={ `${styles.history} row` } ref={ this.setCallsHistory }>
{ this.renderNoCallsMsg() } { this.renderNoCallsMsg() }
{ this.renderCalls() } { this.renderCalls() }
@ -56,7 +63,12 @@ export default class Calls extends Component {
return ( return (
<a <a
{ ...this._test('remove') } { ...this._test('remove') }
title='Clear RPC calls history' title={
<FormattedMessage
id='status.calls.clearHistory'
defaultMessage='Clear RPC calls history'
/>
}
onClick={ this.clearHistory } onClick={ this.clearHistory }
className={ styles.removeIcon } className={ styles.removeIcon }
> >
@ -73,7 +85,10 @@ export default class Calls extends Component {
return ( return (
<div { ...this._test('empty-wrapper') }> <div { ...this._test('empty-wrapper') }>
<h3 className={ styles.historyInfo } { ...this._test('empty') }> <h3 className={ styles.historyInfo } { ...this._test('empty') }>
Fire up some calls and the results will be here. <FormattedMessage
id='status.calls.rpcResults'
defaultMessage='Fire up some calls and the results will be here.'
/>
</h3> </h3>
</div> </div>
); );

View File

@ -16,6 +16,7 @@
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import CopyToClipboard from 'react-copy-to-clipboard'; import CopyToClipboard from 'react-copy-to-clipboard';
import { FormattedMessage } from 'react-intl';
import { sortBy, find, extend } from 'lodash'; import { sortBy, find, extend } from 'lodash';
import IconButton from 'material-ui/IconButton'; import IconButton from 'material-ui/IconButton';
@ -58,7 +59,12 @@ export default class CallsToolbar extends Component {
<IconButton <IconButton
className={ styles.callAction } className={ styles.callAction }
onTouchTap={ this.setCall } onTouchTap={ this.setCall }
tooltip='Set' tooltip={
<FormattedMessage
id='status.callsToolbar.tooltip.set'
defaultMessage='Set'
/>
}
tooltipPosition='top-left' tooltipPosition='top-left'
{ ...this._test('button-setCall') } { ...this._test('button-setCall') }
> >
@ -67,7 +73,12 @@ export default class CallsToolbar extends Component {
<IconButton <IconButton
className={ styles.callAction } className={ styles.callAction }
onTouchTap={ this.makeCall } onTouchTap={ this.makeCall }
tooltip='Fire again' tooltip={
<FormattedMessage
id='status.callsToolbar.tooltip.fireAgain'
defaultMessage='Fire again'
/>
}
tooltipPosition='top-left' tooltipPosition='top-left'
{ ...this._test('button-makeCall') } { ...this._test('button-makeCall') }
> >
@ -79,7 +90,12 @@ export default class CallsToolbar extends Component {
> >
<IconButton <IconButton
className={ styles.callAction } className={ styles.callAction }
tooltip='Copy to clipboard' tooltip={
<FormattedMessage
id='status.callsToolbar.tooltip.copy'
defaultMessage='Copy to clipboard'
/>
}
tooltipPosition='top-left' tooltipPosition='top-left'
{ ...this._test('copyCallToClipboard') } { ...this._test('copyCallToClipboard') }
> >
@ -112,7 +128,12 @@ export default class CallsToolbar extends Component {
} }
copyToClipboard = () => { copyToClipboard = () => {
this.props.actions.copyToClipboard('method copied to clipboard'); this.props.actions.copyToClipboard(
<FormattedMessage
id='status.callsToolbar.copied'
defaultMessage='method copied to clipboard'
/>
);
} }
hasScrollbar (el) { hasScrollbar (el) {

View File

@ -15,12 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import AvPause from 'material-ui/svg-icons/av/pause'; import { FormattedMessage } from 'react-intl';
import AvPlay from 'material-ui/svg-icons/av/play-arrow';
import AvReplay from 'material-ui/svg-icons/av/replay';
import ReorderIcon from 'material-ui/svg-icons/action/reorder';
import { Container } from '~/ui'; import { Container } from '~/ui';
import { PauseIcon, PlayIcon, ReorderIcon, ReplayIcon } from '~/ui/Icons';
import styles from './debug.css'; import styles from './debug.css';
@ -42,7 +40,14 @@ export default class Debug extends Component {
const { devLogsLevels } = nodeStatus; const { devLogsLevels } = nodeStatus;
return ( return (
<Container title='Node Logs'> <Container
title={
<FormattedMessage
id='status.debug.title'
defaultMessage='Node Logs'
/>
}
>
{ this.renderActions() } { this.renderActions() }
<h2 className={ styles.subheader }> <h2 className={ styles.subheader }>
{ devLogsLevels || '-' } { devLogsLevels || '-' }
@ -62,7 +67,10 @@ export default class Debug extends Component {
return ( return (
<div className={ styles.stopped }> <div className={ styles.stopped }>
Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates. <FormattedMessage
id='status.debug.stopped'
defaultMessage='Refresh and display of logs from Parity is currently stopped via the UI, start it to see the latest updates.'
/>
</div> </div>
); );
} }
@ -112,14 +120,24 @@ export default class Debug extends Component {
renderActions () { renderActions () {
const { devLogsEnabled } = this.props.nodeStatus; const { devLogsEnabled } = this.props.nodeStatus;
const toggleButton = devLogsEnabled const toggleButton = devLogsEnabled
? <AvPause /> ? <PauseIcon />
: <AvPlay />; : <PlayIcon />;
return ( return (
<div className={ styles.actions }> <div className={ styles.actions }>
<a onClick={ this.toggle }>{ toggleButton }</a> <a onClick={ this.toggle }>{ toggleButton }</a>
<a onClick={ this.clear }><AvReplay /></a> <a onClick={ this.clear }><ReplayIcon /></a>
<a onClick={ this.reverse } title='Reverse Order'><ReorderIcon /></a> <a
onClick={ this.reverse }
title={
<FormattedMessage
id='status.debug.reverse'
defaultMessage='Reverse Order'
/>
}
>
<ReorderIcon />
</a>
</div> </div>
); );
} }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import AutoComplete from 'material-ui/AutoComplete'; import AutoComplete from 'material-ui/AutoComplete';
import styles from './EditableValue.css'; import styles from './EditableValue.css';
@ -133,10 +134,18 @@ export default class EditableValue extends Component {
return ( return (
<a <a
key={ 'reset' } key='reset'
className={ `${styles.icon} ${styles.firstIcon}` } className={ `${styles.icon} ${styles.firstIcon}` }
onClick={ this.onResetToDefault } onClick={ this.onResetToDefault }
title={ `Reset to ${this.props.defaultValue}` } title={
<FormattedMessage
id='status.editableValue.reset'
defaultMessage='Reset to {defaultVaule}'
values={ {
defaultVaule: this.props.defaultValue
} }
/>
}
{ ...this._testInherit('reset') } { ...this._testInherit('reset') }
> >
<i className='icon-anchor' /> <i className='icon-anchor' />
@ -148,7 +157,7 @@ export default class EditableValue extends Component {
if (this.state.inEditMode) { if (this.state.inEditMode) {
return [ return [
<a <a
key={ 'submit' } key='submit'
className={ styles.iconSuccess } className={ styles.iconSuccess }
onClick={ this.onSubmit } onClick={ this.onSubmit }
{ ...this._testInherit('submit') } { ...this._testInherit('submit') }
@ -156,7 +165,7 @@ export default class EditableValue extends Component {
<i className='icon-check' /> <i className='icon-check' />
</a>, </a>,
<a <a
key={ 'cancel' } key='cancel'
className={ styles.icon } className={ styles.icon }
onClick={ this.onCancel } onClick={ this.onCancel }
{ ...this._testInherit('cancel') } { ...this._testInherit('cancel') }
@ -168,10 +177,15 @@ export default class EditableValue extends Component {
return ( return (
<a <a
key={ 'edit' } key='edit'
className={ styles.icon } className={ styles.icon }
onClick={ this.onOpenEdit } onClick={ this.onOpenEdit }
title='Edit' title={
<FormattedMessage
id='status.editableValue.edit'
defaultMessage='Edit'
/>
}
{ ...this._testInherit('edit') } { ...this._testInherit('edit') }
> >
<i className='icon-pencil' /> <i className='icon-pencil' />

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import formatNumber from 'format-number'; import formatNumber from 'format-number';
import { ContainerTitle, Input } from '~/ui'; import { ContainerTitle, Input } from '~/ui';
@ -47,10 +48,27 @@ export default class MiningSettings extends Component {
return ( return (
<div { ...this._testInherit() }> <div { ...this._testInherit() }>
<ContainerTitle title='mining settings' /> <ContainerTitle
title={
<FormattedMessage
id='status.miningSettings.title'
defaultMessage='mining settings'
/>
}
/>
<Input <Input
label='author' label={
hint='the mining author' <FormattedMessage
id='status.miningSettings.input.author.label'
defaultMessage='author'
/>
}
hint={
<FormattedMessage
id='status.miningSettings.input.author.hint'
defaultMessage='the mining author'
/>
}
value={ coinbase } value={ coinbase }
onSubmit={ this.onAuthorChange } onSubmit={ this.onAuthorChange }
allowCopy allowCopy
@ -59,8 +77,18 @@ export default class MiningSettings extends Component {
/> />
<Input <Input
label='extradata' label={
hint='extra data for mined blocks' <FormattedMessage
id='status.miningSettings.input.extradata.label'
defaultMessage='extradata'
/>
}
hint={
<FormattedMessage
id='status.miningSettings.input.extradata.hint'
defaultMessage='extra data for mined blocks'
/>
}
value={ extradata } value={ extradata }
onSubmit={ this.onExtraDataChange } onSubmit={ this.onExtraDataChange }
defaultValue={ defaultExtradata } defaultValue={ defaultExtradata }
@ -70,8 +98,18 @@ export default class MiningSettings extends Component {
/> />
<Input <Input
label='minimal gas price' label={
hint='the minimum gas price for mining' <FormattedMessage
id='status.miningSettings.input.gasPrice.label'
defaultMessage='minimal gas price'
/>
}
hint={
<FormattedMessage
id='status.miningSettings.input.gasPrice.hint'
defaultMessage='the minimum gas price for mining'
/>
}
value={ toNiceNumber(minGasPrice) } value={ toNiceNumber(minGasPrice) }
onSubmit={ this.onMinGasPriceChange } onSubmit={ this.onMinGasPriceChange }
allowCopy={ minGasPrice.toString() } allowCopy={ minGasPrice.toString() }
@ -80,8 +118,18 @@ export default class MiningSettings extends Component {
/> />
<Input <Input
label='gas floor target' label={
hint='the gas floor target for mining' <FormattedMessage
id='status.miningSettings.input.gasFloor.label'
defaultMessage='gas floor target'
/>
}
hint={
<FormattedMessage
id='status.miningSettings.input.gasFloor.hint'
defaultMessage='the gas floor target for mining'
/>
}
value={ toNiceNumber(gasFloorTarget) } value={ toNiceNumber(gasFloorTarget) }
onSubmit={ this.onGasFloorTargetChange } onSubmit={ this.onGasFloorTargetChange }
allowCopy={ gasFloorTarget.toString() } allowCopy={ gasFloorTarget.toString() }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import _ from 'lodash'; import _ from 'lodash';
import Toggle from 'material-ui/Toggle/Toggle'; import Toggle from 'material-ui/Toggle/Toggle';
@ -38,11 +39,11 @@ export default class RpcCalls extends Component {
const { paramsValues, params } = nextProps.rpc.selectedMethod; const { paramsValues, params } = nextProps.rpc.selectedMethod;
if (paramsValues) { if (paramsValues) {
params.map((p, idx) => { params.map((p, index) => {
// todo [adgo] 01.05.2016 - make sure this works // todo [adgo] 01.05.2016 - make sure this works
// not sure idx is the same for paramsValues and params // not sure idx is the same for paramsValues and params
this.setState({ this.setState({
[this.paramKey(p)]: paramsValues[idx] [this.paramKey(p)]: paramsValues[index]
}); });
}); });
@ -59,7 +60,12 @@ export default class RpcCalls extends Component {
<div className='dapp-container'> <div className='dapp-container'>
<div className='row'> <div className='row'>
<div className='col col-6'> <div className='col col-6'>
<h1><span>RPC</span> Requests</h1> <h1>
<FormattedMessage
id='status.rpcCalls.requests'
defaultMessage='RPC Requests'
/>
</h1>
</div> </div>
<div className='col col-6'> <div className='col col-6'>
<RpcNav /> <RpcNav />
@ -92,11 +98,19 @@ export default class RpcCalls extends Component {
<Toggle <Toggle
className={ styles.jsonToggle } className={ styles.jsonToggle }
onToggle={ this.onJsonToggle } onToggle={ this.onJsonToggle }
label='JSON' label={
<FormattedMessage
id='status.rpcCalls.json'
defaultMessage='JSON'
/>
}
/> />
<h2 className={ styles.header }> <h2 className={ styles.header }>
<label htmlFor='selectedMethod'> <label htmlFor='selectedMethod'>
Call Method <FormattedMessage
id='status.rpcCalls.callMethod'
defaultMessage='Call Method'
/>
</label> </label>
</h2> </h2>
<AnimateChildren absolute> <AnimateChildren absolute>
@ -117,9 +131,19 @@ export default class RpcCalls extends Component {
return ( return (
<div className='row'> <div className='row'>
{ this.renderMethodList() } { this.renderMethodList() }
<h3>Parameters</h3> <h3>
<FormattedMessage
id='status.rpcCalls.parameters'
defaultMessage='Parameters'
/>
</h3>
{ this.renderInputs() } { this.renderInputs() }
<h3>Returns</h3> <h3>
<FormattedMessage
id='status.rpcCalls.returns'
defaultMessage='Returns'
/>
</h3>
<Markdown val={ formatRpcMd(returns) } /> <Markdown val={ formatRpcMd(returns) } />
{ this.renderFormButton() } { this.renderFormButton() }
</div> </div>
@ -177,7 +201,10 @@ export default class RpcCalls extends Component {
if (!params || !params.length) { if (!params || !params.length) {
return ( return (
<span>none</span> <FormattedMessage
id='status.rpcCalls.none'
defaultMessage='none'
/>
); );
} }
@ -284,7 +311,10 @@ export default class RpcCalls extends Component {
disabled={ this.state.jsonEditorError } disabled={ this.state.jsonEditorError }
onClick={ this.onRpcFire } onClick={ this.onRpcFire }
> >
Fire! <FormattedMessage
id='status.rpcCalls.fireButton'
defaultMessage='Fire'
/>
</button> </button>
); );
} }

View File

@ -16,6 +16,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { FormattedMessage } from 'react-intl';
import { sortBy } from 'lodash'; import { sortBy } from 'lodash';
import List from 'material-ui/List/List'; import List from 'material-ui/List/List';
import ListItem from 'material-ui/List/ListItem'; import ListItem from 'material-ui/List/ListItem';
@ -38,7 +39,12 @@ class RpcDocs extends Component {
<div className='dapp-container'> <div className='dapp-container'>
<div className='row'> <div className='row'>
<div className='col col-6'> <div className='col col-6'>
<h1><span>RPC</span> Docs</h1> <h1>
<FormattedMessage
id='status.rpcDocs.title'
defaultMessage='RPC Docs'
/>
</h1>
</div> </div>
<div className='col col-6'> <div className='col col-6'>
<RpcNav /> <RpcNav />
@ -50,7 +56,12 @@ class RpcDocs extends Component {
<div className='row'> <div className='row'>
<div className='col col-12'> <div className='col col-12'>
<AutoComplete <AutoComplete
floatingLabelText='Method name' floatingLabelText={
<FormattedMessage
id='status.rpcDocs.methodName'
defaultMessage='Method name'
/>
}
className={ styles.autocomplete } className={ styles.autocomplete }
dataSource={ rpcMethods.map(m => m.name) } dataSource={ rpcMethods.map(m => m.name) }
onNewRequest={ this.handleMethodChange } onNewRequest={ this.handleMethodChange }
@ -78,9 +89,38 @@ class RpcDocs extends Component {
> >
<h3 className={ styles.headline }>{ m.name }</h3> <h3 className={ styles.headline }>{ m.name }</h3>
<Markdown val={ m.desc } /> <Markdown val={ m.desc } />
<p><strong>Params</strong>{ !m.params.length ? ' - none' : '' }</p> <p>
{ m.params.map((p, idx) => <Markdown key={ `${m.name}-${idx}` } val={ formatRpcMd(p) } />) } <FormattedMessage
<p className={ styles.returnsTitle }><strong>Returns</strong> - </p> id='status.rpcDocs.params'
defaultMessage='Params {params}'
vaules={ {
params: !m.params.length
? (
<FormattedMessage
id='status.rpcDocs.paramsNone'
defaultMessage=' - none'
/>
)
: ''
} }
/>
</p>
{
m.params.map((p, idx) => {
return (
<Markdown
key={ `${m.name}-${idx}` }
val={ formatRpcMd(p) }
/>
);
})
}
<p className={ styles.returnsTitle }>
<FormattedMessage
id='status.rpcDocs.returns'
defaultMessage='Returns - '
/>
</p>
<Markdown className={ styles.returnsDesc } val={ formatRpcMd(m.returns) } /> <Markdown className={ styles.returnsDesc } val={ formatRpcMd(m.returns) } />
{ idx !== rpcMethods.length - 1 ? <hr /> : '' } { idx !== rpcMethods.length - 1 ? <hr /> : '' }
</ListItem> </ListItem>

View File

@ -17,6 +17,7 @@
import bytes from 'bytes'; import bytes from 'bytes';
import moment from 'moment'; import moment from 'moment';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Container, ContainerTitle, Input } from '~/ui'; import { Container, ContainerTitle, Input } from '~/ui';
@ -47,7 +48,14 @@ export default class Status extends Component {
<div className={ styles.row }> <div className={ styles.row }>
<div className={ styles.col3 }> <div className={ styles.col3 }>
<div className={ `${styles.col12} ${styles.padBottom}` }> <div className={ `${styles.col12} ${styles.padBottom}` }>
<ContainerTitle title='best block' /> <ContainerTitle
title={
<FormattedMessage
id='status.status.title.bestBlock'
defaultMessage='best block'
/>
}
/>
<div { ...this._test('best-block') } className={ styles.blockInfo }> <div { ...this._test('best-block') } className={ styles.blockInfo }>
#{ nodeStatus.blockNumber.toFormat() } #{ nodeStatus.blockNumber.toFormat() }
</div> </div>
@ -56,15 +64,35 @@ export default class Status extends Component {
</div> </div>
</div> </div>
<div className={ `${styles.col12} ${styles.padBottom}` }> <div className={ `${styles.col12} ${styles.padBottom}` }>
<ContainerTitle title='peers' /> <ContainerTitle
title={
<FormattedMessage
id='status.status.title.peers'
defaultMessage='peers'
/>
}
/>
<div { ...this._test('peers') } className={ styles.blockInfo }> <div { ...this._test('peers') } className={ styles.blockInfo }>
{ peers } { peers }
</div> </div>
</div> </div>
<div className={ `${styles.col12} ${styles.padBottom}` }> <div className={ `${styles.col12} ${styles.padBottom}` }>
<ContainerTitle title='hash rate' /> <ContainerTitle
title={
<FormattedMessage
id='status.status.title.hashRate'
defaultMessage='hash rate'
/>
}
/>
<div { ...this._test('hashrate') } className={ styles.blockInfo }> <div { ...this._test('hashrate') } className={ styles.blockInfo }>
{ `${hashrate} H/s` } <FormattedMessage
id='status.status.hashrate'
defaultMessage='{hashrate} H/s'
values={ {
hashrate
} }
/>
</div> </div>
</div> </div>
</div> </div>
@ -89,7 +117,12 @@ export default class Status extends Component {
return ( return (
<span> <span>
{ nodeStatus.nodeName || 'Node' } { nodeStatus.nodeName || (
<FormattedMessage
id='status.status.title.node'
defaultMessage='Node'
/>)
}
</span> </span>
); );
} }
@ -107,11 +140,23 @@ export default class Status extends Component {
return ( return (
<div { ...this._test('settings') }> <div { ...this._test('settings') }>
<ContainerTitle title='network settings' /> <ContainerTitle
title={
<FormattedMessage
id='status.status.title.network'
defaultMessage='network settings'
/>
}
/>
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='chain' label={
<FormattedMessage
id='status.status.input.chain'
defaultMessage='chain'
/>
}
value={ nodeStatus.netChain } value={ nodeStatus.netChain }
{ ...this._test('chain') } { ...this._test('chain') }
/> />
@ -120,7 +165,12 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='peers' label={
<FormattedMessage
id='status.status.input.peers'
defaultMessage='peers'
/>
}
value={ peers } value={ peers }
{ ...this._test('peers') } { ...this._test('peers') }
/> />
@ -129,7 +179,12 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='network port' label={
<FormattedMessage
id='status.status.input.port'
defaultMessage='network port'
/>
}
value={ netPort.toString() } value={ netPort.toString() }
{ ...this._test('network-port') } { ...this._test('network-port') }
/> />
@ -139,11 +194,26 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='rpc enabled' label={
<FormattedMessage
id='status.status.input.rpcEnabled'
defaultMessage='rpc enabled'
/>
}
value={ value={
rpcSettings.enabled rpcSettings.enabled
? 'yes' ? (
: 'no' <FormattedMessage
id='status.status.input.yes'
defaultMessage='yes'
/>
)
: (
<FormattedMessage
id='status.status.input.no'
defaultMessage='no'
/>
)
} }
{ ...this._test('rpc-enabled') } { ...this._test('rpc-enabled') }
/> />
@ -152,7 +222,12 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='rpc interface' label={
<FormattedMessage
id='status.status.input.rpcInterface'
defaultMessage='rpc interface'
/>
}
value={ rpcSettings.interface } value={ rpcSettings.interface }
{ ...this._test('rpc-interface') } { ...this._test('rpc-interface') }
/> />
@ -161,7 +236,12 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='rpc port' label={
<FormattedMessage
id='status.status.input.rpcPort'
defaultMessage='rpc port'
/>
}
value={ rpcPort.toString() } value={ rpcPort.toString() }
{ ...this._test('rpc-port') } { ...this._test('rpc-port') }
/> />
@ -173,7 +253,12 @@ export default class Status extends Component {
<Input <Input
allowCopy allowCopy
readOnly readOnly
label='enode' label={
<FormattedMessage
id='status.status.input.enode'
defaultMessage='enode'
/>
}
value={ nodeStatus.enode } value={ nodeStatus.enode }
{ ...this._test('node-enode') } { ...this._test('node-enode') }
/> />

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component } from 'react'; import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { Page } from '~/ui'; import { Page } from '~/ui';
@ -23,7 +24,14 @@ import StatusPage from './containers/StatusPage';
export default class Status extends Component { export default class Status extends Component {
render () { render () {
return ( return (
<Page title='status'> <Page
title={
<FormattedMessage
id='status.title'
defaultMessage='Status'
/>
}
>
<StatusPage /> <StatusPage />
</Page> </Page>
); );

View File

@ -14,8 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { LinearProgress, MenuItem, IconMenu } from 'material-ui'; import { LinearProgress, MenuItem, IconMenu } from 'material-ui';
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import ReactTooltip from 'react-tooltip'; import ReactTooltip from 'react-tooltip';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -70,7 +71,12 @@ class WalletConfirmations extends Component {
if (realConfirmations.length === 0) { if (realConfirmations.length === 0) {
return ( return (
<div> <div>
<p>No transactions needs confirmation right now.</p> <p>
<FormattedMessage
id='wallet.confirmations.none'
defaultMessage='No transactions needs confirmation right now.'
/>
</p>
</div> </div>
); );
} }
@ -217,7 +223,12 @@ class WalletConfirmation extends Component {
const confirmButton = ( const confirmButton = (
<Button <Button
onClick={ this.handleOpenConfirm } onClick={ this.handleOpenConfirm }
label='Confirm As...' label={
<FormattedMessage
id='wallet.confirmations.buttons.confirmAs'
defaultMessage='Confirm As...'
/>
}
disabled={ pending || possibleConfirm.length === 0 } disabled={ pending || possibleConfirm.length === 0 }
/> />
); );
@ -225,13 +236,21 @@ class WalletConfirmation extends Component {
const revokeButton = ( const revokeButton = (
<Button <Button
onClick={ this.handleOpenRevoke } onClick={ this.handleOpenRevoke }
label='Revoke As...' label={
<FormattedMessage
id='wallet.confirmations.buttons.revokeAs'
defaultMessage='Revoke As...'
/>
}
disabled={ pending || possibleRevoke.length === 0 } disabled={ pending || possibleRevoke.length === 0 }
/> />
); );
return ( return (
<tr key={ `actions_${operation}` } className={ className }> <tr
className={ className }
key={ `actions_${operation}` }
>
<td /> <td />
<td colSpan={ 3 }> <td colSpan={ 3 }>
<div className={ styles.actions }> <div className={ styles.actions }>
@ -263,11 +282,15 @@ class WalletConfirmation extends Component {
const account = this.props.accounts[address]; const account = this.props.accounts[address];
return ( return (
<MenuItem value={ address } key={ address }> <MenuItem
key={ address }
value={ address }
>
<div className={ styles.accountItem }> <div className={ styles.accountItem }>
<IdentityIcon <IdentityIcon
inline center
address={ address } address={ address }
center
inline
/> />
<span>{ account.name.toUpperCase() || account.address }</span> <span>{ account.name.toUpperCase() || account.address }</span>
</div> </div>
@ -283,7 +306,10 @@ class WalletConfirmation extends Component {
return ( return (
<tr key={ `prog_${operation}` }> <tr key={ `prog_${operation}` }>
<td colSpan={ 5 } style={ { padding: 0, paddingTop: '1em' } }> <td
colSpan={ 5 }
style={ { padding: 0, paddingTop: '1em' } }
>
<div <div
data-tip data-tip
data-for={ `tooltip_${operation}` } data-for={ `tooltip_${operation}` }
@ -312,7 +338,14 @@ class WalletConfirmation extends Component {
</div> </div>
<ReactTooltip id={ `tooltip_${operation}` }> <ReactTooltip id={ `tooltip_${operation}` }>
Confirmed by { confirmedBy.length }/{ require.toNumber() } owners <FormattedMessage
id='wallet.confirmations.tooltip.confirmed'
defaultMessage='Confirmed by {number}/{required} owners'
values={ {
required: require.toNumber(),
number: confirmedBy.length
} }
/>
</ReactTooltip> </ReactTooltip>
</td> </td>
</tr> </tr>
@ -326,27 +359,27 @@ class WalletConfirmation extends Component {
if (value && to && data) { if (value && to && data) {
return ( return (
<TxRow <TxRow
address={ address }
className={ className } className={ className }
historic={ false }
isTest={ isTest }
key={ operation } key={ operation }
tx={ { tx={ {
hash: transactionHash, hash: transactionHash,
blockNumber: blockNumber, blockNumber,
from: address, from: address,
to: to, to,
value: value, value,
input: bytesToHex(data) input: bytesToHex(data)
} } } }
address={ address }
isTest={ isTest }
historic={ false }
/> />
); );
} }
return ( return (
<tr <tr
key={ operation }
className={ className } className={ className }
key={ operation }
> >
<td colSpan={ 5 }> <td colSpan={ 5 }>
<code>{ operation }</code> <code>{ operation }</code>

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Container, InputAddress } from '~/ui'; import { Container, InputAddress } from '~/ui';
@ -40,7 +41,14 @@ export default class WalletDetails extends Component {
return ( return (
<div className={ [ styles.details, className ].join(' ') }> <div className={ [ styles.details, className ].join(' ') }>
<Container title='Details'> <Container
title={
<FormattedMessage
id='wallet.details.title'
defaultMessage='Details'
/>
}
>
{ this.renderDetails() } { this.renderDetails() }
{ this.renderOwners() } { this.renderOwners() }
</Container> </Container>
@ -62,10 +70,10 @@ export default class WalletDetails extends Component {
return ( return (
<InputAddress <InputAddress
key={ `${idx}_${address}` }
value={ address }
disabled disabled
key={ `${idx}_${address}` }
text text
value={ address }
/> />
); );
}); });
@ -87,9 +95,24 @@ export default class WalletDetails extends Component {
return ( return (
<div> <div>
<p> <p>
<span>This wallet requires at least</span> <FormattedMessage
<span className={ styles.detail }>{ require.toFormat() } owners</span> id='wallet.details.requiredOwners'
<span>to validate any action (transactions, modifications).</span> defaultMessage='This wallet requires at least {owners} to validate any action (transactions, modifications).'
values={ {
owners: (
<span className={ styles.detail }>
<FormattedMessage
id='wallet.details.requiredOwnersNumber'
defaultMessage='{number} {numberValue, plural, one {owner} other {owners}}'
values={ {
number: require.toFormat(),
numberValue: require.toNumber()
} }
/>
</span>
)
} }
/>
</p> </p>
</div> </div>
); );

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { bytesToHex } from '~/api/util/format'; import { bytesToHex } from '~/api/util/format';
import { Container } from '~/ui'; import { Container } from '~/ui';
@ -36,7 +37,14 @@ export default class WalletTransactions extends Component {
render () { render () {
return ( return (
<div> <div>
<Container title='Transactions'> <Container
title={
<FormattedMessage
id='wallet.transactions.title'
defaultMessage='Transactions'
/>
}
>
{ this.renderTransactions() } { this.renderTransactions() }
</Container> </Container>
</div> </div>
@ -52,7 +60,12 @@ export default class WalletTransactions extends Component {
if (transactions.length === 0) { if (transactions.length === 0) {
return ( return (
<div> <div>
<p>No transactions has been sent.</p> <p>
<FormattedMessage
id='wallet.transactions.none'
defaultMessage='No transactions has been sent.'
/>
</p>
</div> </div>
); );
} }
@ -62,14 +75,17 @@ export default class WalletTransactions extends Component {
return ( return (
<TxRow <TxRow
key={ `${transactionHash}_${index}` }
tx={ {
hash: transactionHash,
input: data && bytesToHex(data) || '',
blockNumber, from, to, value
} }
address={ address } address={ address }
isTest={ isTest } isTest={ isTest }
key={ `${transactionHash}_${index}` }
tx={ {
blockNumber,
from,
hash: transactionHash,
input: data && bytesToHex(data) || '',
to,
value
} }
/> />
); );
}); });

View File

@ -15,18 +15,15 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import moment from 'moment'; import moment from 'moment';
import ContentCreate from 'material-ui/svg-icons/content/create';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import ContentSend from 'material-ui/svg-icons/content/send';
import SettingsIcon from 'material-ui/svg-icons/action/settings';
import { nullableProptype } from '~/util/proptypes';
import { EditMeta, Transfer, WalletSettings } from '~/modals'; import { EditMeta, Transfer, WalletSettings } from '~/modals';
import { Actionbar, Button, Page, Loading } from '~/ui'; import { Actionbar, Button, Page, Loading } from '~/ui';
import { DeleteIcon, EditIcon, SendIcon, SettingsIcon } from '~/ui/Icons';
import { nullableProptype } from '~/util/proptypes';
import Delete from '../Address/Delete'; import Delete from '../Address/Delete';
import Header from '../Account/Header'; import Header from '../Account/Header';
@ -53,7 +50,10 @@ class WalletContainer extends Component {
} }
return ( return (
<Wallet isTest={ isTest } { ...others } /> <Wallet
isTest={ isTest }
{ ...others }
/>
); );
} }
} }
@ -166,11 +166,15 @@ class Wallet extends Component {
<div> <div>
<br /> <br />
<p> <p>
<span className={ styles.detail }>{ spent }<span className={ styles.eth } /></span> <FormattedMessage
<span>has been spent today, out of</span> id='wallet.details.spent'
<span className={ styles.detail }>{ limit }<span className={ styles.eth } /></span> defaultMessage='{spent} has been spent today, out of {limit} set as the daily limit, which has been reset on {date}'
<span>set as the daily limit, which has been reset on</span> values={ {
<span className={ styles.detail }>{ date.format('LL') }</span> date: <span className={ styles.detail }>{ date.format('LL') }</span>,
limit: <span className={ styles.detail }>{ limit }<span className={ styles.eth } /></span>,
spent: <span className={ styles.detail }>{ spent }<span className={ styles.eth } /></span>
} }
/>
</p> </p>
</div> </div>
); );
@ -190,19 +194,19 @@ class Wallet extends Component {
return [ return [
<WalletConfirmations <WalletConfirmations
address={ address }
confirmations={ confirmations }
isTest={ isTest }
key='confirmations' key='confirmations'
owners={ owners } owners={ owners }
require={ require } require={ require }
confirmations={ confirmations }
isTest={ isTest }
address={ address }
/>, />,
<WalletTransactions <WalletTransactions
key='transactions'
transactions={ transactions }
address={ address } address={ address }
isTest={ isTest } isTest={ isTest }
key='transactions'
transactions={ transactions }
/> />
]; ];
} }
@ -216,10 +220,15 @@ class Wallet extends Component {
if (owned) { if (owned) {
buttons.push( buttons.push(
<Button <Button
key='transferFunds'
icon={ <ContentSend /> }
label='transfer'
disabled={ !showTransferButton } disabled={ !showTransferButton }
icon={ <SendIcon /> }
key='transferFunds'
label={
<FormattedMessage
id='wallet.buttons.transfer'
defaultMessage='transfer'
/>
}
onClick={ this.onTransferClick } onClick={ this.onTransferClick }
/> />
); );
@ -227,18 +236,28 @@ class Wallet extends Component {
buttons.push( buttons.push(
<Button <Button
icon={ <DeleteIcon /> }
key='delete' key='delete'
icon={ <ActionDelete /> } label={
label='delete' <FormattedMessage
id='wallet.buttons.delete'
defaultMessage='delete'
/>
}
onClick={ this.showDeleteDialog } onClick={ this.showDeleteDialog }
/> />
); );
buttons.push( buttons.push(
<Button <Button
icon={ <EditIcon /> }
key='editmeta' key='editmeta'
icon={ <ContentCreate /> } label={
label='edit' <FormattedMessage
id='wallet.buttons.edit'
defaultMessage='edit'
/>
}
onClick={ this.onEditClick } onClick={ this.onEditClick }
/> />
); );
@ -246,9 +265,14 @@ class Wallet extends Component {
if (owned) { if (owned) {
buttons.push( buttons.push(
<Button <Button
key='settings'
icon={ <SettingsIcon /> } icon={ <SettingsIcon /> }
label='settings' key='settings'
label={
<FormattedMessage
id='wallet.buttons.settings'
defaultMessage='settings'
/>
}
onClick={ this.onSettingsClick } onClick={ this.onSettingsClick }
/> />
); );
@ -256,8 +280,13 @@ class Wallet extends Component {
return ( return (
<Actionbar <Actionbar
title='Wallet Management'
buttons={ buttons } buttons={ buttons }
title={
<FormattedMessage
id='wallet.title'
defaultMessage='Wallet Management'
/>
}
/> />
); );
} }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { PropTypes, Component } from 'react'; import React, { PropTypes, Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { MenuItem, Toggle } from 'material-ui'; import { MenuItem, Toggle } from 'material-ui';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -22,13 +23,8 @@ import CircularProgress from 'material-ui/CircularProgress';
import moment from 'moment'; import moment from 'moment';
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import ContentClear from 'material-ui/svg-icons/content/clear';
import SaveIcon from 'material-ui/svg-icons/content/save';
import ListIcon from 'material-ui/svg-icons/action/view-list';
import SettingsIcon from 'material-ui/svg-icons/action/settings';
import SendIcon from 'material-ui/svg-icons/content/send';
import { Actionbar, ActionbarExport, ActionbarImport, Button, Page, Select, Input } from '~/ui'; import { Actionbar, ActionbarExport, ActionbarImport, Button, Page, Select, Input } from '~/ui';
import { CancelIcon, ListIcon, SaveIcon, SendIcon, SettingsIcon } from '~/ui/Icons';
import Editor from '~/ui/Editor'; import Editor from '~/ui/Editor';
import { DeployContract, SaveContract, LoadContract } from '~/modals'; import { DeployContract, SaveContract, LoadContract } from '~/modals';
@ -97,7 +93,6 @@ class WriteContract extends Component {
{ this.renderDeployModal() } { this.renderDeployModal() }
{ this.renderSaveModal() } { this.renderSaveModal() }
{ this.renderLoadModal() } { this.renderLoadModal() }
{ this.renderActionBar() } { this.renderActionBar() }
<Page className={ styles.page }> <Page className={ styles.page }>
<div <div
@ -133,7 +128,12 @@ class WriteContract extends Component {
className={ styles.parameters } className={ styles.parameters }
style={ { flex: `${100 - size}%` } } style={ { flex: `${100 - size}%` } }
> >
<h2>Parameters</h2> <h2>
<FormattedMessage
id='writeContract.title.parameters'
defaultMessage='Parameters'
/>
</h2>
{ this.renderParameters() } { this.renderParameters() }
</div> </div>
</div> </div>
@ -146,7 +146,12 @@ class WriteContract extends Component {
const { selectedContract } = this.store; const { selectedContract } = this.store;
if (!selectedContract || !selectedContract.name) { if (!selectedContract || !selectedContract.name) {
return 'New Solidity Contract'; return (
<FormattedMessage
id='writeContract.title.new'
defaultMessage='New Solidity Contract'
/>
);
} }
return ( return (
@ -154,9 +159,23 @@ class WriteContract extends Component {
{ selectedContract.name } { selectedContract.name }
<span <span
className={ styles.timestamp } className={ styles.timestamp }
title={ `saved @ ${(new Date(selectedContract.timestamp)).toISOString()}` } title={
<FormattedMessage
id='writeContract.title.saved'
defaultMessage='saved @ {timestamp}'
vaules={ {
timestamp: (new Date(selectedContract.timestamp)).toISOString()
} }
/>
}
> >
(saved { moment(selectedContract.timestamp).fromNow() }) <FormattedMessage
id='writeContract.details.saved'
defaultMessage='(saved {timestamp})'
values={ {
timestamp: moment(selectedContract.timestamp).fromNow()
} }
/>
</span> </span>
</span> </span>
); );
@ -176,20 +195,35 @@ class WriteContract extends Component {
const buttons = [ const buttons = [
<Button <Button
icon={ <ContentClear /> } icon={ <CancelIcon /> }
label='New' label={
<FormattedMessage
id='writeContract.buttons.new'
defaultMessage='New'
/>
}
key='newContract' key='newContract'
onClick={ this.store.handleNewContract } onClick={ this.store.handleNewContract }
/>, />,
<Button <Button
icon={ <ListIcon /> } icon={ <ListIcon /> }
label='Load' label={
<FormattedMessage
id='writeContract.buttons.load'
defaultMessage='Load'
/>
}
key='loadContract' key='loadContract'
onClick={ this.store.handleOpenLoadModal } onClick={ this.store.handleOpenLoadModal }
/>, />,
<Button <Button
icon={ <SaveIcon /> } icon={ <SaveIcon /> }
label='Save' label={
<FormattedMessage
id='writeContract.buttons.save'
defaultMessage='Save'
/>
}
key='saveContract' key='saveContract'
onClick={ this.store.handleSaveContract } onClick={ this.store.handleSaveContract }
/>, />,
@ -200,7 +234,12 @@ class WriteContract extends Component {
/>, />,
<ActionbarImport <ActionbarImport
key='importSourcecode' key='importSourcecode'
title='Import Solidity code' title={
<FormattedMessage
id='writeContract.buttons.import'
defaultMessage='Import Solidity'
/>
}
onConfirm={ this.store.handleImport } onConfirm={ this.store.handleImport }
renderValidation={ this.renderImportValidation } renderValidation={ this.renderImportValidation }
/> />
@ -208,7 +247,12 @@ class WriteContract extends Component {
return ( return (
<Actionbar <Actionbar
title='Write a Contract' title={
<FormattedMessage
id='writeContract.title.main'
defaultMessage='Write a Contract'
/>
}
buttons={ buttons } buttons={ buttons }
/> />
); );
@ -231,8 +275,15 @@ class WriteContract extends Component {
return ( return (
<div className={ styles.panel }> <div className={ styles.panel }>
<div className={ styles.centeredMessage }> <div className={ styles.centeredMessage }>
<p>Unfortuantely, an error occurred...</p> <p>
<div className={ styles.error }>{ workerError.toString() }</div> <FormattedMessage
id='writeContract.error.params'
defaultMessage='An error occurred with the following description'
/>
</p>
<div className={ styles.error }>
{ workerError.toString() }
</div>
</div> </div>
</div> </div>
); );
@ -245,7 +296,12 @@ class WriteContract extends Component {
size={ 80 } size={ 80 }
thickness={ 5 } thickness={ 5 }
/> />
<p>Loading...</p> <p>
<FormattedMessage
id='writeContract.title.loading'
defaultMessage='Loading...'
/>
</p>
</div> </div>
); );
} }
@ -260,7 +316,15 @@ class WriteContract extends Component {
size={ 80 } size={ 80 }
thickness={ 5 } thickness={ 5 }
/> />
<p>Loading Solidity { longVersion }</p> <p>
<FormattedMessage
id='writeContract.title.solidity'
defaultMessage='Loading Solidity {version}'
values={ {
version: longVersion
} }
/>
</p>
</div> </div>
</div> </div>
); );
@ -271,7 +335,12 @@ class WriteContract extends Component {
<div> <div>
<Button <Button
icon={ <SettingsIcon /> } icon={ <SettingsIcon /> }
label='Compile' label={
<FormattedMessage
id='writeContract.buttons.compile'
defaultMessage='Compile'
/>
}
onClick={ this.store.handleCompile } onClick={ this.store.handleCompile }
primary={ false } primary={ false }
disabled={ compiling } disabled={ compiling }
@ -281,7 +350,12 @@ class WriteContract extends Component {
? ( ? (
<Button <Button
icon={ <SendIcon /> } icon={ <SendIcon /> }
label='Deploy' label={
<FormattedMessage
id='writeContract.buttons.deploy'
defaultMessage='Deploy'
/>
}
onClick={ this.store.handleOpenDeployModal } onClick={ this.store.handleOpenDeployModal }
primary={ false } primary={ false }
/> />
@ -292,7 +366,12 @@ class WriteContract extends Component {
<div className={ styles.toggles }> <div className={ styles.toggles }>
<div> <div>
<Toggle <Toggle
label='Optimize' label={
<FormattedMessage
id='writeContract.buttons.optimise'
defaultMessage='Optimise'
/>
}
labelPosition='right' labelPosition='right'
onToggle={ this.store.handleOptimizeToggle } onToggle={ this.store.handleOptimizeToggle }
toggled={ this.store.optimize } toggled={ this.store.optimize }
@ -300,7 +379,12 @@ class WriteContract extends Component {
</div> </div>
<div> <div>
<Toggle <Toggle
label='Auto-Compile' label={
<FormattedMessage
id='writeContract.buttons.autoCompile'
defaultMessage='Auto-Compile'
/>
}
labelPosition='right' labelPosition='right'
onToggle={ this.store.handleAutocompileToggle } onToggle={ this.store.handleAutocompileToggle }
toggled={ this.store.autocompile } toggled={ this.store.autocompile }
@ -324,7 +408,11 @@ class WriteContract extends Component {
> >
{ {
build.release build.release
? (<span className={ styles.big }>{ build.version }</span>) ? (
<span className={ styles.big }>
{ build.version }
</span>
)
: build.longVersion : build.longVersion
} }
</MenuItem> </MenuItem>
@ -333,7 +421,12 @@ class WriteContract extends Component {
return ( return (
<div> <div>
<Select <Select
label='Select a Solidity version' label={
<FormattedMessage
id='writeContract.title.selectSolidity'
defaultMessage='Select a Solidity version'
/>
}
value={ selectedBuild } value={ selectedBuild }
onChange={ this.store.handleSelectBuild } onChange={ this.store.handleSelectBuild }
> >
@ -406,7 +499,12 @@ class WriteContract extends Component {
size={ 80 } size={ 80 }
thickness={ 5 } thickness={ 5 }
/> />
<p>Compiling...</p> <p>
<FormattedMessage
id='writeContract.compiling.busy'
defaultMessage='Compiling...'
/>
</p>
</div> </div>
); );
} }
@ -414,7 +512,12 @@ class WriteContract extends Component {
if (!compiled) { if (!compiled) {
return ( return (
<div className={ styles.centeredMessage }> <div className={ styles.centeredMessage }>
<p>Please compile the source code.</p> <p>
<FormattedMessage
id='writeContract.compiling.action'
defaultMessage='Please compile the source code.'
/>
</p>
</div> </div>
); );
} }
@ -428,7 +531,12 @@ class WriteContract extends Component {
if (contractKeys.length === 0) { if (contractKeys.length === 0) {
return ( return (
<div className={ styles.centeredMessage }> <div className={ styles.centeredMessage }>
<p>No contract has been found.</p> <p>
<FormattedMessage
id='writeContract.error.noContract'
defaultMessage='No contract has been found.'
/>
</p>
</div> </div>
); );
} }
@ -446,15 +554,24 @@ class WriteContract extends Component {
return ( return (
<div className={ styles.compilation }> <div className={ styles.compilation }>
<Select <Select
label='Select a contract' label={
<FormattedMessage
id='writeContract.title.contract'
defaultMessage='Select a contract'
/>
}
value={ contractIndex } value={ contractIndex }
onChange={ this.store.handleSelectContract } onChange={ this.store.handleSelectContract }
> >
{ contractsList } { contractsList }
</Select> </Select>
{ this.renderContract(contract) } { this.renderContract(contract) }
<h4 className={ styles.messagesHeader }>
<h4 className={ styles.messagesHeader }>Compiler messages</h4> <FormattedMessage
id='writeContract.title.messages'
defaultMessage='Compiler messages'
/>
</h4>
{ this.renderErrors() } { this.renderErrors() }
</div> </div>
); );
@ -468,7 +585,12 @@ class WriteContract extends Component {
? ( ? (
<Input <Input
allowCopy allowCopy
label='Metadata' label={
<FormattedMessage
id='writeContract.input.metadata'
defaultMessage='Metadata'
/>
}
readOnly readOnly
value={ contract.metadata } value={ contract.metadata }
/> />
@ -479,14 +601,24 @@ class WriteContract extends Component {
<div> <div>
<Input <Input
allowCopy allowCopy
label='ABI Interface' label={
<FormattedMessage
id='writeContract.input.abi'
defaultMessage='ABI Interface'
/>
}
readOnly readOnly
value={ abi } value={ abi }
/> />
<Input <Input
allowCopy allowCopy
label='Bytecode' label={
<FormattedMessage
id='writeContract.input.code'
defaultMessage='Bytecode'
/>
}
readOnly readOnly
value={ `0x${bytecode}` } value={ `0x${bytecode}` }
/> />
@ -516,7 +648,12 @@ class WriteContract extends Component {
return ( return (
<Input <Input
allowCopy allowCopy
label='Swarm Metadata Hash' label={
<FormattedMessage
id='writeContract.input.swarm'
defaultMessage='Swarm Metadata Hash'
/>
}
readOnly readOnly
value={ `${hash}` } value={ `${hash}` }
/> />

View File

@ -14,35 +14,62 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { action, observable, transaction } from 'mobx';
import store from 'store';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { action, observable, transaction } from 'mobx';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import store from 'store';
import { sha3 } from '~/api/util/sha3'; import { sha3 } from '~/api/util/sha3';
import SolidityUtils from '~/util/solidity'; import SolidityUtils from '~/util/solidity';
const SOLIDITY_LIST_URL = 'https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.json';
const WRITE_CONTRACT_STORE_KEY = '_parity::writeContractStore'; const WRITE_CONTRACT_STORE_KEY = '_parity::writeContractStore';
const SNIPPETS = { const SNIPPETS = {
snippet0: { snippet0: {
name: 'Token.sol', name: 'Token.sol',
description: 'Standard ERP20 Token Contract', description: (
id: 'snippet0', sourcecode: require('raw-loader!../../contracts/snippets/token.sol') <FormattedMessage
id='writeContract.type.standardErc20'
defaultMessage='Standard ERC20 Token Contract'
/>
),
id: 'snippet0',
sourcecode: require('raw-loader!../../contracts/snippets/token.sol')
}, },
snippet1: { snippet1: {
name: 'StandardToken.sol', name: 'StandardToken.sol',
description: 'Implementation of ERP20 Token Contract', description: (
id: 'snippet1', sourcecode: require('raw-loader!../../contracts/snippets/standard-token.sol') <FormattedMessage
id='writeContract.type.implementErc20'
defaultMessage='Implementation of ERC20 Token Contract'
/>
),
id: 'snippet1',
sourcecode: require('raw-loader!../../contracts/snippets/standard-token.sol')
}, },
snippet2: { snippet2: {
name: 'HumanStandardToken.sol', name: 'HumanStandardToken.sol',
description: 'Implementation of the Human Token Contract', description: (
id: 'snippet2', sourcecode: require('raw-loader!../../contracts/snippets/human-standard-token.sol') <FormattedMessage
id='writeContract.type.humanErc20'
defaultMessage='Implementation of the Human Token Contract'
/>
),
id: 'snippet2',
sourcecode: require('raw-loader!../../contracts/snippets/human-standard-token.sol')
}, },
snippet3: { snippet3: {
name: 'Wallet.sol', name: 'Wallet.sol',
description: 'Implementation of a multisig Wallet', description: (
id: 'snippet3', sourcecode: require('raw-loader!../../contracts/snippets/wallet.sol') <FormattedMessage
id='writeContract.type.multisig'
defaultMessage='Implementation of a multisig Wallet'
/>
),
id: 'snippet3',
sourcecode: require('raw-loader!../../contracts/snippets/wallet.sol')
} }
}; };
@ -118,8 +145,8 @@ export default class WriteContractStore {
} }
fetchSolidityVersions () { fetchSolidityVersions () {
return fetch('https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.json') return fetch(SOLIDITY_LIST_URL)
.then((r) => r.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
const { builds, releases, latestRelease } = data; const { builds, releases, latestRelease } = data;
let latestIndex = -1; let latestIndex = -1;