Display ETH balance in overlay account selector (#4588)

* Add account balance display from ParityBar

* Ellipsis with title

* Balance display in Dapp permissions

* Add balance to vault account selector

* Add key prop to accounts in Vault

* Fix failing test (missing redux prop)
This commit is contained in:
Jaco Greeff 2017-02-22 10:42:42 +01:00 committed by Gav Wood
parent fba4bda0ff
commit 0a85fc7a3e
9 changed files with 91 additions and 17 deletions

View File

@ -17,6 +17,7 @@
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { AccountCard, Portal, SectionList } from '~/ui'; import { AccountCard, Portal, SectionList } from '~/ui';
import { CheckIcon, StarIcon, StarOutlineIcon } from '~/ui/Icons'; import { CheckIcon, StarIcon, StarOutlineIcon } from '~/ui/Icons';
@ -24,15 +25,16 @@ import { CheckIcon, StarIcon, StarOutlineIcon } from '~/ui/Icons';
import styles from './dappPermissions.css'; import styles from './dappPermissions.css';
@observer @observer
export default class DappPermissions extends Component { class DappPermissions extends Component {
static propTypes = { static propTypes = {
store: PropTypes.object.isRequired balances: PropTypes.object,
permissionStore: PropTypes.object.isRequired
}; };
render () { render () {
const { store } = this.props; const { permissionStore } = this.props;
if (!store.modalOpen) { if (!permissionStore.modalOpen) {
return null; return null;
} }
@ -50,7 +52,7 @@ export default class DappPermissions extends Component {
/> />
</div> </div>
} }
onClose={ store.closeModal } onClose={ permissionStore.closeModal }
open open
title={ title={
<FormattedMessage <FormattedMessage
@ -61,7 +63,7 @@ export default class DappPermissions extends Component {
> >
<div className={ styles.container }> <div className={ styles.container }>
<SectionList <SectionList
items={ store.accounts } items={ permissionStore.accounts }
noStretch noStretch
renderItem={ this.renderAccount } renderItem={ this.renderAccount }
/> />
@ -71,14 +73,15 @@ export default class DappPermissions extends Component {
} }
renderAccount = (account) => { renderAccount = (account) => {
const { store } = this.props; const { balances, permissionStore } = this.props;
const balance = balances[account.address];
const onMakeDefault = () => { const onMakeDefault = () => {
store.setDefaultAccount(account.address); permissionStore.setDefaultAccount(account.address);
}; };
const onSelect = () => { const onSelect = () => {
store.selectAccount(account.address); permissionStore.selectAccount(account.address);
}; };
let className; let className;
@ -95,6 +98,7 @@ export default class DappPermissions extends Component {
<div className={ styles.item }> <div className={ styles.item }>
<AccountCard <AccountCard
account={ account } account={ account }
balance={ balance }
className={ className } className={ className }
onClick={ onSelect } onClick={ onSelect }
/> />
@ -114,3 +118,16 @@ export default class DappPermissions extends Component {
); );
} }
} }
function mapStateToProps (state) {
const { balances } = state.balances;
return {
balances
};
}
export default connect(
mapStateToProps,
null
)(DappPermissions);

View File

@ -16,13 +16,40 @@
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import React from 'react'; import React from 'react';
import sinon from 'sinon';
import DappPermissions from './'; import DappPermissions from './';
function renderShallow (store = {}) { let component;
return shallow( let store;
<DappPermissions store={ store } />
); function createRedux () {
store = {
dispatch: sinon.stub(),
subscribe: sinon.stub(),
getState: () => {
return {
balances: {
balances: {}
}
};
}
};
return store;
}
function renderShallow (permissionStore = {}) {
component = shallow(
<DappPermissions permissionStore={ permissionStore } />,
{
context: {
store: createRedux()
}
}
).find('DappPermissions').shallow();
return component;
} }
describe('modals/DappPermissions', () => { describe('modals/DappPermissions', () => {

View File

@ -35,6 +35,7 @@ class VaultAccounts extends Component {
static propTypes = { static propTypes = {
accounts: PropTypes.object.isRequired, accounts: PropTypes.object.isRequired,
balances: PropTypes.object.isRequired,
newError: PropTypes.func.isRequired, newError: PropTypes.func.isRequired,
personalAccountsInfo: PropTypes.func.isRequired, personalAccountsInfo: PropTypes.func.isRequired,
vaultStore: PropTypes.object.isRequired vaultStore: PropTypes.object.isRequired
@ -105,7 +106,9 @@ class VaultAccounts extends Component {
// (although that has defaults) and this one. A genrerix multi-select component // (although that has defaults) and this one. A genrerix multi-select component
// would be applicable going forward. (Originals passed in, new selections back) // would be applicable going forward. (Originals passed in, new selections back)
renderAccount = (account) => { renderAccount = (account) => {
const { balances } = this.props;
const { vaultName, selectedAccounts } = this.props.vaultStore; const { vaultName, selectedAccounts } = this.props.vaultStore;
const balance = balances[account.address];
const isInVault = account.meta.vault === vaultName; const isInVault = account.meta.vault === vaultName;
const isSelected = isInVault const isSelected = isInVault
? !selectedAccounts[account.address] ? !selectedAccounts[account.address]
@ -119,6 +122,7 @@ class VaultAccounts extends Component {
<div className={ styles.item }> <div className={ styles.item }>
<AccountCard <AccountCard
account={ account } account={ account }
balance={ balance }
className={ className={
isSelected isSelected
? styles.selected ? styles.selected
@ -177,9 +181,13 @@ class VaultAccounts extends Component {
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { balances } = state.balances;
const { accounts } = state.personal; const { accounts } = state.personal;
return { accounts }; return {
accounts,
balances
};
} }
function mapDispatchToProps (dispatch) { function mapDispatchToProps (dispatch) {

View File

@ -75,6 +75,9 @@ function createReduxStore () {
subscribe: sinon.stub(), subscribe: sinon.stub(),
getState: () => { getState: () => {
return { return {
balances: {
balances: {}
},
personal: { personal: {
accounts: ACCOUNTS accounts: ACCOUNTS
} }

View File

@ -120,6 +120,9 @@
.accountName { .accountName {
font-weight: 700 !important; font-weight: 700 !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
} }

View File

@ -85,7 +85,10 @@ export default class VaultCard extends Component {
{ {
accounts.map((address) => { accounts.map((address) => {
return ( return (
<Link to={ `/accounts/${address}` }> <Link
key={ address }
to={ `/accounts/${address}` }
>
<IdentityIcon <IdentityIcon
address={ address } address={ address }
center center

View File

@ -80,7 +80,7 @@ class Dapps extends Component {
return ( return (
<div> <div>
<DappPermissions store={ this.permissionStore } /> <DappPermissions permissionStore={ this.permissionStore } />
<DappsVisible store={ this.store } /> <DappsVisible store={ this.store } />
<Actionbar <Actionbar
className={ styles.toolbar } className={ styles.toolbar }

View File

@ -48,6 +48,7 @@ class ParityBar extends Component {
}; };
static propTypes = { static propTypes = {
balances: PropTypes.object,
dapp: PropTypes.bool, dapp: PropTypes.bool,
externalLink: PropTypes.string, externalLink: PropTypes.string,
pending: PropTypes.array pending: PropTypes.array
@ -344,6 +345,8 @@ class ParityBar extends Component {
} }
renderAccount = (account) => { renderAccount = (account) => {
const { balances } = this.props;
const balance = balances[account.address];
const makeDefaultAccount = () => { const makeDefaultAccount = () => {
this.toggleAccountsDisplay(); this.toggleAccountsDisplay();
return this.accountStore return this.accountStore
@ -358,6 +361,7 @@ class ParityBar extends Component {
> >
<AccountCard <AccountCard
account={ account } account={ account }
balance={ balance }
className={ className={
account.default account.default
? styles.selected ? styles.selected
@ -653,9 +657,11 @@ class ParityBar extends Component {
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { balances } = state.balances;
const { pending } = state.signer; const { pending } = state.signer;
return { return {
balances,
pending pending
}; };
} }

View File

@ -31,7 +31,14 @@ function createRedux (state = {}) {
store = { store = {
dispatch: sinon.stub(), dispatch: sinon.stub(),
subscribe: sinon.stub(), subscribe: sinon.stub(),
getState: () => Object.assign({ signer: { pending: [] } }, state) getState: () => Object.assign({
balances: {
balances: {}
},
signer: {
pending: []
}
}, state)
}; };
return store; return store;