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

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react';
import IconMenu from 'material-ui/IconMenu';
@ -71,12 +72,38 @@ export default class ActionbarSort extends Component {
>
{
showDefault
? this.renderMenuItem('', 'Default')
? this.renderMenuItem('', (
<FormattedMessage
id='ui.actionbar.sort.typeDefault'
defaultMessage='Default'
/>
))
: null
}
{ this.renderMenuItem('tags', 'Sort by tags') }
{ this.renderMenuItem('name', 'Sort by name') }
{ this.renderMenuItem('eth', 'Sort by ETH') }
{
this.renderMenuItem('tags', (
<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() }
</IconMenu>
@ -88,8 +115,17 @@ export default class ActionbarSort extends Component {
return metas
.map((meta, index) => {
return this
.renderMenuItem(meta.key, `Sort by ${meta.label}`, index);
const label = (
<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 DashboardIcon from 'material-ui/svg-icons/action/dashboard';
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 EditIcon from 'material-ui/svg-icons/content/create';
export ErrorIcon from 'material-ui/svg-icons/alert/error';
export FileUploadIcon from 'material-ui/svg-icons/file/file-upload';
export FileIcon from 'material-ui/svg-icons/editor/insert-drive-file';
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 KeyboardIcon from 'material-ui/svg-icons/hardware/keyboard';
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 MembershipIcon from 'material-ui/svg-icons/action/card-membership';
export MoveIcon from 'material-ui/svg-icons/action/open-with';
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 PrintIcon from 'material-ui/svg-icons/action/print';
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 SendIcon from 'material-ui/svg-icons/content/send';
export SettingsIcon from 'material-ui/svg-icons/action/settings';

View File

@ -214,7 +214,13 @@ class Summary extends Component {
/>
</div>
<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>
</Link>
);

View File

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

View File

@ -15,14 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-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 { Actionbar, Button, Page } from '~/ui';
import { AddIcon, DeleteIcon, EditIcon } from '~/ui/Icons';
import Header from '../Account/Header';
import Transactions from '../Account/Transactions';
@ -146,14 +145,24 @@ class Address extends Component {
const buttons = [
<Button
key='editmeta'
icon={ <ContentCreate /> }
label='edit'
icon={ <EditIcon /> }
label={
<FormattedMessage
id='address.buttons.edit'
defaultMessage='edit'
/>
}
onClick={ this.onEditClick }
/>,
<Button
key='delete'
icon={ <ActionDelete /> }
label='forget'
icon={ <DeleteIcon /> }
label={
<FormattedMessage
id='address.buttons.forget'
defaultMessage='forget'
/>
}
onClick={ this.showDeleteDialog }
/>
];
@ -161,16 +170,30 @@ class Address extends Component {
const addToBook = (
<Button
key='newAddress'
icon={ <ContentAdd /> }
label='save'
icon={ <AddIcon /> }
label={
<FormattedMessage
id='address.buttons.save'
defaultMessage='save'
/>
}
onClick={ this.onOpenAdd }
/>
);
return (
<Actionbar
title='Address Information'
buttons={ !contact ? [ addToBook ] : buttons }
title={
<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/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ContentAdd from 'material-ui/svg-icons/content/add';
@ -143,7 +144,12 @@ class Addresses extends Component {
<Button
key='newAddress'
icon={ <ContentAdd /> }
label='address'
label={
<FormattedMessage
id='addresses.buttons.add'
defaultMessage='address'
/>
}
onClick={ this.onOpenAdd }
/>,
<ActionbarExport
@ -163,7 +169,12 @@ class Addresses extends Component {
return (
<Actionbar
className={ styles.toolbar }
title='Saved Addresses'
title={
<FormattedMessage
id='addresses.title'
defaultMessage='Saved Addresses'
/>
}
buttons={ buttons }
/>
);
@ -187,7 +198,12 @@ class Addresses extends Component {
renderValidation = (content) => {
const error = {
error: 'The provided file is invalid...'
error: (
<FormattedMessage
id='addresses.errors.invalidFile'
defaultMessage='The provided file is invalid...'
/>
)
};
try {
@ -214,7 +230,9 @@ class Addresses extends Component {
{ body }
</div>
);
} catch (e) { return error; }
} catch (e) {
return error;
}
}
onImport = (content) => {

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import styles from './frameError.css';
@ -22,7 +23,10 @@ export default class FrameError extends Component {
render () {
return (
<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>
);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,39 +34,39 @@ describe('views/Signer/components/RequestOrigin', () => {
expect(shallow(
<RequestOrigin origin={ { type: 'unknown', details: '' } } />,
context
).text()).to.equal('Requested via unknown interface');
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.unknownInterface');
});
it('renders dapps', () => {
expect(shallow(
<RequestOrigin origin={ { type: 'dapp', details: 'http://parity.io' } } />,
context
).text()).to.equal('Requested by a dapp at http://parity.io');
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.dapp');
});
it('renders rpc', () => {
expect(shallow(
<RequestOrigin origin={ { type: 'rpc', details: '' } } />,
context
).text()).to.equal('Requested via RPC (unidentified)');
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.rpc');
});
it('renders ipc', () => {
expect(shallow(
<RequestOrigin origin={ { type: 'ipc', details: '0x1234' } } />,
context
).text()).to.equal('Requested via IPC session<Connect(IdentityIcon) />');
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.ipc');
});
it('renders signer', () => {
expect(shallow(
<RequestOrigin origin={ { type: 'signer', details: '0x12345' } } />,
context
).text()).to.equal('Requested via UI session<Connect(IdentityIcon) />');
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.signerUI');
expect(shallow(
<RequestOrigin origin={ { type: 'signer', details: '0x1234' } } />,
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/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react';
import Account from '../Account';
@ -91,9 +92,16 @@ export default class SignRequest extends Component {
}
renderBinaryDetails (data) {
return (<div className={ styles.signData }>
<p>(Unknown binary data)</p>
</div>);
return (
<div className={ styles.signData }>
<p>
<FormattedMessage
id='signer.signRequest.unknownBinary'
defaultMessage='(Unknown binary data)'
/>
</p>
</div>
);
}
renderDetails () {
@ -119,13 +127,25 @@ export default class SignRequest extends Component {
<RequestOrigin origin={ origin } />
</div>
<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)
? this.renderAsciiDetails(api.util.hexToAscii(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>
);
@ -138,14 +158,24 @@ export default class SignRequest extends Component {
if (status === 'confirmed') {
return (
<div className={ styles.actions }>
<span className={ styles.isConfirmed }>Confirmed</span>
<span className={ styles.isConfirmed }>
<FormattedMessage
id='signer.signRequest.state.confirmed'
defaultMessage='Confirmed'
/>
</span>
</div>
);
}
return (
<div className={ styles.actions }>
<span className={ styles.isRejected }>Rejected</span>
<span className={ styles.isRejected }>
<FormattedMessage
id='signer.signRequest.state.rejected'
defaultMessage='Rejected'
/>
</span>
</div>
);
}

View File

@ -14,11 +14,12 @@
// You should have received a copy of the GNU General Public License
// 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 { FormattedMessage } from 'react-intl';
import ReactTooltip from 'react-tooltip';
import { Button, MethodDecoding } from '~/ui';
import { GasIcon } from '~/ui/Icons';
import * as tUtil from '../util/transaction';
import Account from '../Account';
@ -103,8 +104,13 @@ export default class TransactionMainDetails extends Component {
return (
<div className={ styles.editButtonRow }>
<Button
icon={ <MapsLocalGasStation /> }
label='Edit conditions/gas/gasPrice'
icon={ <GasIcon /> }
label={
<FormattedMessage
id='signer.mainDetails.editTx'
defaultMessage='Edit conditions/gas/gasPrice'
/>
}
onClick={ this.toggleGasEditor }
/>
</div>
@ -128,8 +134,23 @@ export default class TransactionMainDetails extends Component {
{ totalValueDisplay } <small>ETH</small>
</div>
<ReactTooltip id={ labelId }>
The value of the transaction including the mining fee is <strong>{ totalValueDisplayWei }</strong> <small>WEI</small>. <br />
(This includes a mining fee of <strong>{ feeEth }</strong> <small>ETH</small>)
<FormattedMessage
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>
</div>
);
@ -151,7 +172,11 @@ export default class TransactionMainDetails extends Component {
<small>ETH</small>
</div>
<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>
</ReactTooltip>
</div>

View File

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

View File

@ -18,6 +18,7 @@ import keycode from 'keycode';
import RaisedButton from 'material-ui/RaisedButton';
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import ReactTooltip from 'react-tooltip';
@ -98,7 +99,17 @@ class TransactionPendingFormConfirm extends Component {
const passwordHintText = this.getPasswordHint();
const passwordHint = passwordHintText
? (<div><span>(hint) </span>{ passwordHintText }</div>)
? (
<div>
<FormattedMessage
id='signer.txPendingConfirm.passwordHint'
defaultMessage='(hint) {hint}'
values={ {
hint: passwordHintText
} }
/>
</div>
)
: null;
const isWalletOk = !isExternal || (walletError === null && wallet !== null);
@ -113,13 +124,33 @@ class TransactionPendingFormConfirm extends Component {
<Input
hint={
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={
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 }
onKeyDown={ this.onKeyDown }
@ -149,8 +180,18 @@ class TransactionPendingFormConfirm extends Component {
}
label={
isSending
? 'Confirming...'
: 'Confirm Request'
? (
<FormattedMessage
id='signer.txPendingConfirm.buttons.confirmBusy'
defaultMessage='Confirming...'
/>
)
: (
<FormattedMessage
id='signer.txPendingConfirm.buttons.confirmRequest'
defaultMessage='Confirm Request'
/>
)
}
onTouchTap={ this.onConfirm }
primary
@ -169,7 +210,12 @@ class TransactionPendingFormConfirm extends Component {
<Input
className={ styles.fileInput }
error={ walletError }
label='Select Local Key'
label={
<FormattedMessage
id='signer.txPendingConfirm.keySelect.label'
defaultMessage='Select Local Key'
/>
}
onChange={ this.onKeySelect }
type='file'
/>
@ -183,7 +229,10 @@ class TransactionPendingFormConfirm extends Component {
return (
<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>
);
}
@ -216,7 +265,12 @@ class TransactionPendingFormConfirm extends Component {
} catch (error) {
this.setState({
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/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import RaisedButton from 'material-ui/RaisedButton';
@ -32,14 +33,28 @@ export default class TransactionPendingFormReject extends Component {
return (
<div>
<div className={ styles.rejectText }>
Are you sure you want to reject request? <br />
<strong>This cannot be undone</strong>
<FormattedMessage
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>
<RaisedButton
onTouchTap={ onReject }
className={ styles.rejectButton }
fullWidth
label={ 'Reject Request' }
label={
<FormattedMessage
id='signer.txPendingReject.buttons.reject'
defaultMessage='Reject Request'
/>
}
/>
</div>
);

View File

@ -15,8 +15,9 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
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 TransactionPendingFormReject from './TransactionPendingFormReject';
@ -75,9 +76,24 @@ export default class TransactionPendingForm extends Component {
let html;
if (!isRejectOpen) {
html = <span>reject request</span>;
html = (
<span>
<FormattedMessage
id='signer.txPendingForm.reject'
defaultMessage='reject request'
/>
</span>
);
} 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 (

View File

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

View File

@ -15,6 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import Call from '../Call';
import CallsToolbar from '../CallsToolbar';
import styles from './Calls.css';
@ -33,7 +35,12 @@ export default class Calls extends Component {
{ ...this._test('container') }
>
{ 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 }>
{ this.renderNoCallsMsg() }
{ this.renderCalls() }
@ -56,7 +63,12 @@ export default class Calls extends Component {
return (
<a
{ ...this._test('remove') }
title='Clear RPC calls history'
title={
<FormattedMessage
id='status.calls.clearHistory'
defaultMessage='Clear RPC calls history'
/>
}
onClick={ this.clearHistory }
className={ styles.removeIcon }
>
@ -73,7 +85,10 @@ export default class Calls extends Component {
return (
<div { ...this._test('empty-wrapper') }>
<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>
</div>
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { bytesToHex } from '~/api/util/format';
import { Container } from '~/ui';
@ -36,7 +37,14 @@ export default class WalletTransactions extends Component {
render () {
return (
<div>
<Container title='Transactions'>
<Container
title={
<FormattedMessage
id='wallet.transactions.title'
defaultMessage='Transactions'
/>
}
>
{ this.renderTransactions() }
</Container>
</div>
@ -52,7 +60,12 @@ export default class WalletTransactions extends Component {
if (transactions.length === 0) {
return (
<div>
<p>No transactions has been sent.</p>
<p>
<FormattedMessage
id='wallet.transactions.none'
defaultMessage='No transactions has been sent.'
/>
</p>
</div>
);
}
@ -62,14 +75,17 @@ export default class WalletTransactions extends Component {
return (
<TxRow
key={ `${transactionHash}_${index}` }
tx={ {
hash: transactionHash,
input: data && bytesToHex(data) || '',
blockNumber, from, to, value
} }
address={ address }
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/>.
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
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 { 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 Header from '../Account/Header';
@ -53,7 +50,10 @@ class WalletContainer extends Component {
}
return (
<Wallet isTest={ isTest } { ...others } />
<Wallet
isTest={ isTest }
{ ...others }
/>
);
}
}
@ -166,11 +166,15 @@ class Wallet extends Component {
<div>
<br />
<p>
<span className={ styles.detail }>{ spent }<span className={ styles.eth } /></span>
<span>has been spent today, out of</span>
<span className={ styles.detail }>{ limit }<span className={ styles.eth } /></span>
<span>set as the daily limit, which has been reset on</span>
<span className={ styles.detail }>{ date.format('LL') }</span>
<FormattedMessage
id='wallet.details.spent'
defaultMessage='{spent} has been spent today, out of {limit} set as the daily limit, which has been reset on {date}'
values={ {
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>
</div>
);
@ -190,19 +194,19 @@ class Wallet extends Component {
return [
<WalletConfirmations
address={ address }
confirmations={ confirmations }
isTest={ isTest }
key='confirmations'
owners={ owners }
require={ require }
confirmations={ confirmations }
isTest={ isTest }
address={ address }
/>,
<WalletTransactions
key='transactions'
transactions={ transactions }
address={ address }
isTest={ isTest }
key='transactions'
transactions={ transactions }
/>
];
}
@ -216,10 +220,15 @@ class Wallet extends Component {
if (owned) {
buttons.push(
<Button
key='transferFunds'
icon={ <ContentSend /> }
label='transfer'
disabled={ !showTransferButton }
icon={ <SendIcon /> }
key='transferFunds'
label={
<FormattedMessage
id='wallet.buttons.transfer'
defaultMessage='transfer'
/>
}
onClick={ this.onTransferClick }
/>
);
@ -227,18 +236,28 @@ class Wallet extends Component {
buttons.push(
<Button
icon={ <DeleteIcon /> }
key='delete'
icon={ <ActionDelete /> }
label='delete'
label={
<FormattedMessage
id='wallet.buttons.delete'
defaultMessage='delete'
/>
}
onClick={ this.showDeleteDialog }
/>
);
buttons.push(
<Button
icon={ <EditIcon /> }
key='editmeta'
icon={ <ContentCreate /> }
label='edit'
label={
<FormattedMessage
id='wallet.buttons.edit'
defaultMessage='edit'
/>
}
onClick={ this.onEditClick }
/>
);
@ -246,9 +265,14 @@ class Wallet extends Component {
if (owned) {
buttons.push(
<Button
key='settings'
icon={ <SettingsIcon /> }
label='settings'
key='settings'
label={
<FormattedMessage
id='wallet.buttons.settings'
defaultMessage='settings'
/>
}
onClick={ this.onSettingsClick }
/>
);
@ -256,8 +280,13 @@ class Wallet extends Component {
return (
<Actionbar
title='Wallet Management'
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/>.
import React, { PropTypes, Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react';
import { MenuItem, Toggle } from 'material-ui';
import { connect } from 'react-redux';
@ -22,13 +23,8 @@ import CircularProgress from 'material-ui/CircularProgress';
import moment from 'moment';
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 { CancelIcon, ListIcon, SaveIcon, SendIcon, SettingsIcon } from '~/ui/Icons';
import Editor from '~/ui/Editor';
import { DeployContract, SaveContract, LoadContract } from '~/modals';
@ -97,7 +93,6 @@ class WriteContract extends Component {
{ this.renderDeployModal() }
{ this.renderSaveModal() }
{ this.renderLoadModal() }
{ this.renderActionBar() }
<Page className={ styles.page }>
<div
@ -133,7 +128,12 @@ class WriteContract extends Component {
className={ styles.parameters }
style={ { flex: `${100 - size}%` } }
>
<h2>Parameters</h2>
<h2>
<FormattedMessage
id='writeContract.title.parameters'
defaultMessage='Parameters'
/>
</h2>
{ this.renderParameters() }
</div>
</div>
@ -146,7 +146,12 @@ class WriteContract extends Component {
const { selectedContract } = this.store;
if (!selectedContract || !selectedContract.name) {
return 'New Solidity Contract';
return (
<FormattedMessage
id='writeContract.title.new'
defaultMessage='New Solidity Contract'
/>
);
}
return (
@ -154,9 +159,23 @@ class WriteContract extends Component {
{ selectedContract.name }
<span
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>
);
@ -176,20 +195,35 @@ class WriteContract extends Component {
const buttons = [
<Button
icon={ <ContentClear /> }
label='New'
icon={ <CancelIcon /> }
label={
<FormattedMessage
id='writeContract.buttons.new'
defaultMessage='New'
/>
}
key='newContract'
onClick={ this.store.handleNewContract }
/>,
<Button
icon={ <ListIcon /> }
label='Load'
label={
<FormattedMessage
id='writeContract.buttons.load'
defaultMessage='Load'
/>
}
key='loadContract'
onClick={ this.store.handleOpenLoadModal }
/>,
<Button
icon={ <SaveIcon /> }
label='Save'
label={
<FormattedMessage
id='writeContract.buttons.save'
defaultMessage='Save'
/>
}
key='saveContract'
onClick={ this.store.handleSaveContract }
/>,
@ -200,7 +234,12 @@ class WriteContract extends Component {
/>,
<ActionbarImport
key='importSourcecode'
title='Import Solidity code'
title={
<FormattedMessage
id='writeContract.buttons.import'
defaultMessage='Import Solidity'
/>
}
onConfirm={ this.store.handleImport }
renderValidation={ this.renderImportValidation }
/>
@ -208,7 +247,12 @@ class WriteContract extends Component {
return (
<Actionbar
title='Write a Contract'
title={
<FormattedMessage
id='writeContract.title.main'
defaultMessage='Write a Contract'
/>
}
buttons={ buttons }
/>
);
@ -231,8 +275,15 @@ class WriteContract extends Component {
return (
<div className={ styles.panel }>
<div className={ styles.centeredMessage }>
<p>Unfortuantely, an error occurred...</p>
<div className={ styles.error }>{ workerError.toString() }</div>
<p>
<FormattedMessage
id='writeContract.error.params'
defaultMessage='An error occurred with the following description'
/>
</p>
<div className={ styles.error }>
{ workerError.toString() }
</div>
</div>
</div>
);
@ -245,7 +296,12 @@ class WriteContract extends Component {
size={ 80 }
thickness={ 5 }
/>
<p>Loading...</p>
<p>
<FormattedMessage
id='writeContract.title.loading'
defaultMessage='Loading...'
/>
</p>
</div>
);
}
@ -260,7 +316,15 @@ class WriteContract extends Component {
size={ 80 }
thickness={ 5 }
/>
<p>Loading Solidity { longVersion }</p>
<p>
<FormattedMessage
id='writeContract.title.solidity'
defaultMessage='Loading Solidity {version}'
values={ {
version: longVersion
} }
/>
</p>
</div>
</div>
);
@ -271,7 +335,12 @@ class WriteContract extends Component {
<div>
<Button
icon={ <SettingsIcon /> }
label='Compile'
label={
<FormattedMessage
id='writeContract.buttons.compile'
defaultMessage='Compile'
/>
}
onClick={ this.store.handleCompile }
primary={ false }
disabled={ compiling }
@ -281,7 +350,12 @@ class WriteContract extends Component {
? (
<Button
icon={ <SendIcon /> }
label='Deploy'
label={
<FormattedMessage
id='writeContract.buttons.deploy'
defaultMessage='Deploy'
/>
}
onClick={ this.store.handleOpenDeployModal }
primary={ false }
/>
@ -292,7 +366,12 @@ class WriteContract extends Component {
<div className={ styles.toggles }>
<div>
<Toggle
label='Optimize'
label={
<FormattedMessage
id='writeContract.buttons.optimise'
defaultMessage='Optimise'
/>
}
labelPosition='right'
onToggle={ this.store.handleOptimizeToggle }
toggled={ this.store.optimize }
@ -300,7 +379,12 @@ class WriteContract extends Component {
</div>
<div>
<Toggle
label='Auto-Compile'
label={
<FormattedMessage
id='writeContract.buttons.autoCompile'
defaultMessage='Auto-Compile'
/>
}
labelPosition='right'
onToggle={ this.store.handleAutocompileToggle }
toggled={ this.store.autocompile }
@ -324,7 +408,11 @@ class WriteContract extends Component {
>
{
build.release
? (<span className={ styles.big }>{ build.version }</span>)
? (
<span className={ styles.big }>
{ build.version }
</span>
)
: build.longVersion
}
</MenuItem>
@ -333,7 +421,12 @@ class WriteContract extends Component {
return (
<div>
<Select
label='Select a Solidity version'
label={
<FormattedMessage
id='writeContract.title.selectSolidity'
defaultMessage='Select a Solidity version'
/>
}
value={ selectedBuild }
onChange={ this.store.handleSelectBuild }
>
@ -406,7 +499,12 @@ class WriteContract extends Component {
size={ 80 }
thickness={ 5 }
/>
<p>Compiling...</p>
<p>
<FormattedMessage
id='writeContract.compiling.busy'
defaultMessage='Compiling...'
/>
</p>
</div>
);
}
@ -414,7 +512,12 @@ class WriteContract extends Component {
if (!compiled) {
return (
<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>
);
}
@ -428,7 +531,12 @@ class WriteContract extends Component {
if (contractKeys.length === 0) {
return (
<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>
);
}
@ -446,15 +554,24 @@ class WriteContract extends Component {
return (
<div className={ styles.compilation }>
<Select
label='Select a contract'
label={
<FormattedMessage
id='writeContract.title.contract'
defaultMessage='Select a contract'
/>
}
value={ contractIndex }
onChange={ this.store.handleSelectContract }
>
{ contractsList }
</Select>
{ this.renderContract(contract) }
<h4 className={ styles.messagesHeader }>Compiler messages</h4>
<h4 className={ styles.messagesHeader }>
<FormattedMessage
id='writeContract.title.messages'
defaultMessage='Compiler messages'
/>
</h4>
{ this.renderErrors() }
</div>
);
@ -468,7 +585,12 @@ class WriteContract extends Component {
? (
<Input
allowCopy
label='Metadata'
label={
<FormattedMessage
id='writeContract.input.metadata'
defaultMessage='Metadata'
/>
}
readOnly
value={ contract.metadata }
/>
@ -479,14 +601,24 @@ class WriteContract extends Component {
<div>
<Input
allowCopy
label='ABI Interface'
label={
<FormattedMessage
id='writeContract.input.abi'
defaultMessage='ABI Interface'
/>
}
readOnly
value={ abi }
/>
<Input
allowCopy
label='Bytecode'
label={
<FormattedMessage
id='writeContract.input.code'
defaultMessage='Bytecode'
/>
}
readOnly
value={ `0x${bytecode}` }
/>
@ -516,7 +648,12 @@ class WriteContract extends Component {
return (
<Input
allowCopy
label='Swarm Metadata Hash'
label={
<FormattedMessage
id='writeContract.input.swarm'
defaultMessage='Swarm Metadata Hash'
/>
}
readOnly
value={ `${hash}` }
/>

View File

@ -14,35 +14,62 @@
// You should have received a copy of the GNU General Public License
// 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 { 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 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 SNIPPETS = {
snippet0: {
name: 'Token.sol',
description: 'Standard ERP20 Token Contract',
id: 'snippet0', sourcecode: require('raw-loader!../../contracts/snippets/token.sol')
description: (
<FormattedMessage
id='writeContract.type.standardErc20'
defaultMessage='Standard ERC20 Token Contract'
/>
),
id: 'snippet0',
sourcecode: require('raw-loader!../../contracts/snippets/token.sol')
},
snippet1: {
name: 'StandardToken.sol',
description: 'Implementation of ERP20 Token Contract',
id: 'snippet1', sourcecode: require('raw-loader!../../contracts/snippets/standard-token.sol')
description: (
<FormattedMessage
id='writeContract.type.implementErc20'
defaultMessage='Implementation of ERC20 Token Contract'
/>
),
id: 'snippet1',
sourcecode: require('raw-loader!../../contracts/snippets/standard-token.sol')
},
snippet2: {
name: 'HumanStandardToken.sol',
description: 'Implementation of the Human Token Contract',
id: 'snippet2', sourcecode: require('raw-loader!../../contracts/snippets/human-standard-token.sol')
description: (
<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: {
name: 'Wallet.sol',
description: 'Implementation of a multisig Wallet',
id: 'snippet3', sourcecode: require('raw-loader!../../contracts/snippets/wallet.sol')
description: (
<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 () {
return fetch('https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/bin/list.json')
.then((r) => r.json())
return fetch(SOLIDITY_LIST_URL)
.then((response) => response.json())
.then((data) => {
const { builds, releases, latestRelease } = data;
let latestIndex = -1;