diff --git a/js/src/ui/TxList/TxRow/txRow.js b/js/src/ui/TxList/TxRow/txRow.js
index 10f78307c..e42f64159 100644
--- a/js/src/ui/TxList/TxRow/txRow.js
+++ b/js/src/ui/TxList/TxRow/txRow.js
@@ -16,8 +16,10 @@
import moment from 'moment';
import React, { Component, PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { Link } from 'react-router';
-import { txLink, addressLink } from '~/3rdparty/etherscan/links';
+import { txLink } from '~/3rdparty/etherscan/links';
import IdentityIcon from '../../IdentityIcon';
import IdentityName from '../../IdentityName';
@@ -25,19 +27,20 @@ import MethodDecoding from '../../MethodDecoding';
import styles from '../txList.css';
-export default class TxRow extends Component {
+class TxRow extends Component {
static contextTypes = {
api: PropTypes.object.isRequired
};
static propTypes = {
- tx: PropTypes.object.isRequired,
+ accountAddresses: PropTypes.array.isRequired,
address: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
+ tx: PropTypes.object.isRequired,
block: PropTypes.object,
- historic: PropTypes.bool,
- className: PropTypes.string
+ className: PropTypes.string,
+ historic: PropTypes.bool
};
static defaultProps = {
@@ -77,22 +80,20 @@ export default class TxRow extends Component {
}
renderAddress (address) {
- const { isTest } = this.props;
-
let esLink = null;
if (address) {
esLink = (
-
-
+
);
}
@@ -138,4 +139,30 @@ export default class TxRow extends Component {
);
}
+
+ addressLink (address) {
+ const { accountAddresses } = this.props;
+ const isAccount = accountAddresses.includes(address);
+
+ if (isAccount) {
+ return `/accounts/${address}`;
+ }
+
+ return `/addresses/${address}`;
+ }
}
+
+function mapStateToProps (initState) {
+ const { accounts } = initState.personal;
+ const accountAddresses = Object.keys(accounts);
+
+ return () => {
+ return { accountAddresses };
+ };
+}
+
+export default connect(
+ mapStateToProps,
+ null
+)(TxRow);
+
diff --git a/js/src/ui/TxList/TxRow/txRow.spec.js b/js/src/ui/TxList/TxRow/txRow.spec.js
index f46f2e7fa..dc9f4d3cc 100644
--- a/js/src/ui/TxList/TxRow/txRow.spec.js
+++ b/js/src/ui/TxList/TxRow/txRow.spec.js
@@ -25,13 +25,28 @@ import TxRow from './txRow';
const api = new Api({ execute: sinon.stub() });
+const STORE = {
+ dispatch: sinon.stub(),
+ subscribe: sinon.stub(),
+ getState: () => {
+ return {
+ personal: {
+ accounts: {
+ '0x123': {}
+ }
+ }
+ };
+ }
+};
+
function render (props) {
return shallow(
,
{ context: { api } }
- );
+ ).find('TxRow').shallow({ context: { api } });
}
describe('ui/TxList/TxRow', () => {
@@ -48,5 +63,37 @@ describe('ui/TxList/TxRow', () => {
expect(render({ address: '0x123', block, isTest: true, tx })).to.be.ok;
});
+
+ it('renders an account link', () => {
+ const block = {
+ timestamp: new Date()
+ };
+ const tx = {
+ blockNumber: new BigNumber(123),
+ hash: '0x123456789abcdef0123456789abcdef0123456789abcdef',
+ to: '0x123',
+ value: new BigNumber(1)
+ };
+
+ const element = render({ address: '0x123', block, isTest: true, tx });
+
+ expect(element.find('Link').prop('to')).to.equal('/accounts/0x123');
+ });
+
+ it('renders an address link', () => {
+ const block = {
+ timestamp: new Date()
+ };
+ const tx = {
+ blockNumber: new BigNumber(123),
+ hash: '0x123456789abcdef0123456789abcdef0123456789abcdef',
+ to: '0x456',
+ value: new BigNumber(1)
+ };
+
+ const element = render({ address: '0x123', block, isTest: true, tx });
+
+ expect(element.find('Link').prop('to')).to.equal('/addresses/0x456');
+ });
});
});
diff --git a/js/src/ui/TxList/txList.css b/js/src/ui/TxList/txList.css
index 3913fea33..a38ba14fd 100644
--- a/js/src/ui/TxList/txList.css
+++ b/js/src/ui/TxList/txList.css
@@ -65,6 +65,11 @@
.link {
vertical-align: top;
+
+ &.currentLink {
+ color: white;
+ cursor: text;
+ }
}
.right {
diff --git a/js/src/views/ParityBar/parityBar.js b/js/src/views/ParityBar/parityBar.js
index 63036b9e4..ac251d0a3 100644
--- a/js/src/views/ParityBar/parityBar.js
+++ b/js/src/views/ParityBar/parityBar.js
@@ -285,6 +285,7 @@ class ParityBar extends Component {
}
renderExpanded () {
+ const { externalLink } = this.props;
const { displayType } = this.state;
return (
@@ -333,7 +334,7 @@ class ParityBar extends Component {
/>
)
: (
-
+
)
}
diff --git a/js/src/views/Signer/components/Account/AccountLink/accountLink.js b/js/src/views/Signer/components/Account/AccountLink/accountLink.js
index 265642246..81f25f4e1 100644
--- a/js/src/views/Signer/components/Account/AccountLink/accountLink.js
+++ b/js/src/views/Signer/components/Account/AccountLink/accountLink.js
@@ -15,16 +15,19 @@
// along with Parity. If not, see .
import React, { Component, PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { Link } from 'react-router';
-import { addressLink } from '~/3rdparty/etherscan/links';
import styles from './accountLink.css';
-export default class AccountLink extends Component {
+class AccountLink extends Component {
static propTypes = {
- isTest: PropTypes.bool.isRequired,
+ accountAddresses: PropTypes.array.isRequired,
address: PropTypes.string.isRequired,
className: PropTypes.string,
- children: PropTypes.node
+ children: PropTypes.node,
+ externalLink: PropTypes.string.isRequired,
+ isTest: PropTypes.bool.isRequired
}
state = {
@@ -32,36 +35,72 @@ export default class AccountLink extends Component {
};
componentWillMount () {
- const { address, isTest } = this.props;
+ const { address, externalLink, isTest } = this.props;
- this.updateLink(address, isTest);
+ this.updateLink(address, externalLink, isTest);
}
componentWillReceiveProps (nextProps) {
- const { address, isTest } = nextProps;
+ const { address, externalLink, isTest } = nextProps;
- this.updateLink(address, isTest);
+ this.updateLink(address, externalLink, isTest);
}
render () {
- const { children, address, className } = this.props;
+ const { children, address, className, externalLink } = this.props;
+
+ if (externalLink) {
+ return (
+
+ { children || address }
+
+ );
+ }
return (
-
{ children || address }
-
+
);
}
- updateLink (address, isTest) {
- const link = addressLink(address, isTest);
+ updateLink (address, externalLink, isTest) {
+ const { accountAddresses } = this.props;
+ const isAccount = accountAddresses.includes(address);
+
+ let link = isAccount
+ ? `/accounts/${address}`
+ : `/addresses/${address}`;
+
+ if (externalLink) {
+ const path = externalLink.replace(/\/+$/, '');
+
+ link = `${path}/#${link}`;
+ }
this.setState({
link
});
}
}
+
+function mapStateToProps (initState) {
+ const { accounts } = initState.personal;
+ const accountAddresses = Object.keys(accounts);
+
+ return () => {
+ return { accountAddresses };
+ };
+}
+
+export default connect(
+ mapStateToProps,
+ null
+)(AccountLink);
diff --git a/js/src/views/Signer/components/Account/account.js b/js/src/views/Signer/components/Account/account.js
index b2b109634..1a7197d1a 100644
--- a/js/src/views/Signer/components/Account/account.js
+++ b/js/src/views/Signer/components/Account/account.js
@@ -25,6 +25,7 @@ export default class Account extends Component {
static propTypes = {
className: PropTypes.string,
address: PropTypes.string.isRequired,
+ externalLink: PropTypes.string.isRequired,
isTest: PropTypes.bool.isRequired,
balance: PropTypes.object // eth BigNumber, not required since it mght take time to fetch
};
@@ -51,12 +52,13 @@ export default class Account extends Component {
}
render () {
- const { address, isTest, className } = this.props;
+ const { address, externalLink, isTest, className } = this.props;
return (
;
if (!name) {
return (
[{ this.shortAddress(address) }]
@@ -96,6 +99,7 @@ export default class Account extends Component {
return (
diff --git a/js/src/views/Signer/components/SignRequest/signRequest.js b/js/src/views/Signer/components/SignRequest/signRequest.js
index c76769763..21f5211e6 100644
--- a/js/src/views/Signer/components/SignRequest/signRequest.js
+++ b/js/src/views/Signer/components/SignRequest/signRequest.js
@@ -93,7 +93,9 @@ export default class SignRequest extends Component {
renderDetails () {
const { api } = this.context;
const { address, isTest, store, data } = this.props;
- const balance = store.balances[address];
+ const { balances, externalLink } = store;
+
+ const balance = balances[address];
if (!balance) {
return ;
@@ -105,6 +107,7 @@ export default class SignRequest extends Component {
diff --git a/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.js b/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.js
index 812d1fb35..e73fee922 100644
--- a/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.js
+++ b/js/src/views/Signer/components/TransactionMainDetails/transactionMainDetails.js
@@ -27,6 +27,7 @@ import styles from './transactionMainDetails.css';
export default class TransactionMainDetails extends Component {
static propTypes = {
children: PropTypes.node,
+ externalLink: PropTypes.string.isRequired,
from: PropTypes.string.isRequired,
fromBalance: PropTypes.object,
gasStore: PropTypes.object,
@@ -50,7 +51,7 @@ export default class TransactionMainDetails extends Component {
}
render () {
- const { children, from, fromBalance, gasStore, isTest, transaction } = this.props;
+ const { children, externalLink, from, fromBalance, gasStore, isTest, transaction } = this.props;
return (
@@ -59,6 +60,7 @@ export default class TransactionMainDetails extends Component {
diff --git a/js/src/views/Signer/components/TransactionPending/transactionPending.js b/js/src/views/Signer/components/TransactionPending/transactionPending.js
index a49f5c2e0..1a96d0144 100644
--- a/js/src/views/Signer/components/TransactionPending/transactionPending.js
+++ b/js/src/views/Signer/components/TransactionPending/transactionPending.js
@@ -89,14 +89,16 @@ export default class TransactionPending extends Component {
renderTransaction () {
const { className, focus, id, isSending, isTest, store, transaction } = this.props;
const { totalValue } = this.state;
+ const { balances, externalLink } = store;
const { from, value } = transaction;
- const fromBalance = store.balances[from];
+ const fromBalance = balances[from];
return (