Merge remote-tracking branch 'origin/ui-2' into ui-2

This commit is contained in:
Jaco Greeff 2017-04-28 11:26:34 +02:00
commit 278dfcdcc5
292 changed files with 734 additions and 805 deletions

View File

@ -1,43 +0,0 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export AddAddress from './AddAddress';
export AddContract from './AddContract';
export CreateAccount from './CreateAccount';
export CreateWallet from './CreateWallet';
export DappPermissions from './DappPermissions';
export DappsVisible from './AddDapps';
export DeleteAccount from './DeleteAccount';
export DeployContract from './DeployContract';
export EditMeta from './EditMeta';
export ExecuteContract from './ExecuteContract';
export ExportAccount from './ExportAccount';
export Faucet from './Faucet';
export FirstRun from './FirstRun';
export LoadContract from './LoadContract';
export PasswordManager from './PasswordManager';
export SaveContract from './SaveContract';
export Shapeshift from './Shapeshift';
export Transfer from './Transfer';
export UpgradeParity from './UpgradeParity';
export VaultAccounts from './VaultAccounts';
export VaultCreate from './VaultCreate';
export VaultLock from './VaultLock';
export VaultMeta from './VaultMeta';
export VaultSelector from './VaultSelector';
export VaultUnlock from './VaultUnlock';
export Verification from './Verification';
export WalletSettings from './WalletSettings';

View File

@ -17,7 +17,7 @@
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { LOG_KEYS, getLogger } from '~/config'; import { LOG_KEYS, getLogger } from '~/config';
import UpgradeStore from '~/modals/UpgradeParity/store'; import UpgradeStore from '~/shell/UpgradeParity/store';
import BalancesProvider from './balances'; import BalancesProvider from './balances';
import { statusBlockNumber, statusCollection } from './statusActions'; import { statusBlockNumber, statusCollection } from './statusActions';

View File

@ -16,9 +16,11 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FirstRun, UpgradeParity } from '~/modals';
import { Errors, Tooltips } from '~/ui'; import { Errors, Tooltips } from '~/ui';
import FirstRun from '../../FirstRun';
import UpgradeParity from '../../UpgradeParity';
import styles from '../application.css'; import styles from '../application.css';
export default function Container ({ children, onCloseFirstRun, showFirstRun, upgradeStore }) { export default function Container ({ children, onCloseFirstRun, showFirstRun, upgradeStore }) {

View File

@ -37,10 +37,12 @@ export default class Extension extends Component {
return ( return (
<div className={ styles.body }> <div className={ styles.body }>
<CloseIcon <div
className={ styles.close } className={ styles.close }
onClick={ this.onClose } onClick={ this.onClose }
/> >
<CloseIcon />
</div>
<p> <p>
<FormattedMessage <FormattedMessage
id='extension.intro' id='extension.intro'

View File

@ -18,19 +18,18 @@ import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import UpgradeStore from '~/modals/UpgradeParity/store';
import Connection from '../Connection'; import Connection from '../Connection';
import ParityBar from '../ParityBar'; import ParityBar from '../ParityBar';
import UpgradeStore from '../UpgradeParity/store';
import Snackbar from './Snackbar'; import Snackbar from './Snackbar';
import Container from './Container'; import Container from './Container';
import DappContainer from './DappContainer'; import DappContainer from './DappContainer';
import Extension from './Extension'; import Extension from './Extension';
import FrameError from './FrameError'; import FrameError from './FrameError';
import Requests from './Requests';
import Status from './Status'; import Status from './Status';
import Store from './store'; import Store from './store';
import Requests from './Requests';
import styles from './application.css'; import styles from './application.css';

View File

@ -65,6 +65,7 @@
} }
.icons { .icons {
padding-top: 1.5em;
} }
.icon, .icon,

View File

@ -29,7 +29,7 @@ function renderShallow (permissionStore = {}) {
return component; return component;
} }
describe('modals/DappPermissions', () => { describe('shell/DappPermissions', () => {
describe('rendering', () => { describe('rendering', () => {
it('renders defaults', () => { it('renders defaults', () => {
expect(renderShallow()).to.be.ok; expect(renderShallow()).to.be.ok;

View File

@ -41,7 +41,7 @@ function create () {
store = new Store(api); store = new Store(api);
} }
describe('modals/DappPermissions/store', () => { describe('shell/DappPermissions/store', () => {
beforeEach(() => { beforeEach(() => {
create(); create();
}); });

View File

@ -21,11 +21,13 @@ import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { DappPermissions, DappsVisible } from '~/modals';
import PermissionStore from '~/modals/DappPermissions/store';
import { Actionbar, Button, DappCard, Page, SectionList } from '~/ui'; import { Actionbar, Button, DappCard, Page, SectionList } from '~/ui';
import { LockedIcon, VisibleIcon } from '~/ui/Icons'; import { LockedIcon, VisibleIcon } from '~/ui/Icons';
import DappsVisible from '../DappsVisible';
import DappPermissions from '../DappPermissions';
import PermissionStore from '../DappPermissions/store';
import DappsStore from './dappsStore'; import DappsStore from './dappsStore';
import styles from './dapps.css'; import styles from './dapps.css';

View File

@ -20,10 +20,10 @@ import { FormattedMessage } from 'react-intl';
import { DappCard, Portal, SelectionList } from '~/ui'; import { DappCard, Portal, SelectionList } from '~/ui';
import styles from './addDapps.css'; import styles from './dappsVisible.css';
@observer @observer
export default class AddDapps extends Component { export default class DappsVisible extends Component {
static propTypes = { static propTypes = {
store: PropTypes.object.isRequired store: PropTypes.object.isRequired
}; };

View File

@ -17,15 +17,15 @@
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import React from 'react'; import React from 'react';
import AddDapps from './'; import DappsVisible from './';
function renderShallow (store = {}) { function renderShallow (store = {}) {
return shallow( return shallow(
<AddDapps store={ store } /> <DappsVisible store={ store } />
); );
} }
describe('modals/AddDapps', () => { describe('shell/DappsVisible', () => {
describe('rendering', () => { describe('rendering', () => {
it('renders defaults', () => { it('renders defaults', () => {
expect(renderShallow()).to.be.ok; expect(renderShallow()).to.be.ok;

View File

@ -0,0 +1,17 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './dappsVisible';

View File

@ -27,10 +27,11 @@ import { newError } from '~/redux/actions';
import { Button, Portal } from '~/ui'; import { Button, Portal } from '~/ui';
import { CheckIcon, DoneIcon, NextIcon, PrintIcon } from '~/ui/Icons'; import { CheckIcon, DoneIcon, NextIcon, PrintIcon } from '~/ui/Icons';
import { NewAccount, AccountDetails } from '../CreateAccount'; // FIXME: These imports, while nice for re-using, breaks since the shell import
import print from '../CreateAccount/print'; import { NewAccount, AccountDetails } from '~/views/Accounts/CreateAccount';
import recoveryPage from '../CreateAccount/recoveryPage.ejs'; import print from '~/views/Accounts/CreateAccount/print';
import CreateStore from '../CreateAccount/store'; import recoveryPage from '~/views/Accounts/CreateAccount/recoveryPage.ejs';
import CreateStore from '~/views/Accounts/CreateAccount/store';
import Completed from './Completed'; import Completed from './Completed';
import TnC from './TnC'; import TnC from './TnC';

View File

@ -16,9 +16,7 @@
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
font-family: 'Roboto', sans-serif; font-family: Sans-Serif;
font-size: 16px;
font-weight: 300;
} }
.loading { .loading {

View File

@ -41,9 +41,6 @@ import Dapps from './Dapps';
import '~/environment'; import '~/environment';
import '~/../assets/fonts/Roboto/font.css';
import '~/../assets/fonts/RobotoMono/font.css';
injectTapEventPlugin(); injectTapEventPlugin();
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {

View File

@ -14,9 +14,8 @@
/* 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/>.
*/ */
.searchcontainer { .searchcontainer {
display: flex;
overflow: hidden;
} }
.searchButton { .searchButton {

View File

@ -16,17 +16,23 @@
*/ */
.actionbar { .actionbar {
padding: 0 24px !important; background: transparent;
margin-bottom: 0; display: flex;
height: auto !important; flex-direction: row;
background: transparent !important; justify-content: space-between;
} padding: 0.5em 1.5em;
margin: 0;
.tooltitle { .title {
text-transform: uppercase; text-transform: uppercase;
} }
.toolbuttons { .children {
padding: 0.5em 0; }
overflow: hidden;
.buttons {
div {
display: inline-block;
}
}
} }

View File

@ -14,55 +14,31 @@
// 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 React, { PropTypes } from 'react';
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
import styles from './actionbar.css'; import styles from './actionbar.css';
export default class Actionbar extends Component { export default function Actionbar ({ buttons, children, className, title }) {
static propTypes = { return (
title: nodeOrStringProptype(), <div className={ `${styles.actionbar} ${className}` }>
buttons: PropTypes.array, <h3 className={ styles.title }>
children: PropTypes.node,
className: PropTypes.string
};
render () {
const { children, className } = this.props;
const classes = `${styles.actionbar} ${className}`;
return (
<Toolbar className={ classes }>
{ this.renderTitle() }
{ this.renderButtons() }
{ children }
</Toolbar>
);
}
renderButtons () {
const { buttons } = this.props;
if (!buttons || !buttons.length) {
return null;
}
return (
<ToolbarGroup className={ styles.toolbuttons }>
{ buttons }
</ToolbarGroup>
);
}
renderTitle () {
const { title } = this.props;
return (
<h3 className={ styles.tooltitle }>
{ title } { title }
</h3> </h3>
); <div className={ styles.children }>
} { children }
</div>
<div className={ styles.buttons }>
{ buttons }
</div>
</div>
);
} }
Actionbar.propTypes = {
title: nodeOrStringProptype(),
buttons: PropTypes.array,
children: PropTypes.node,
className: PropTypes.string
};

View File

@ -14,25 +14,20 @@
// 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 React, { PropTypes } from 'react';
import styles from './badge.css'; import styles from './badge.css';
export default class Badge extends Component { export default function Badge ({ className, color, value }) {
static propTypes = { return (
className: PropTypes.string, <div className={ `${styles.bubble} ${styles[color || 'default']} ${className}` }>
color: PropTypes.string, { value }
value: PropTypes.any </div>
}; );
render () {
const { className, color, value } = this.props;
const classes = `${styles.bubble} ${styles[color || 'default']} ${className}`;
return (
<div className={ classes }>
{ value }
</div>
);
}
} }
Badge.propTypes = {
className: PropTypes.string,
color: PropTypes.string,
value: PropTypes.any
};

View File

@ -15,7 +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 BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -23,122 +23,118 @@ import TokenImage from '~/ui/TokenImage';
import styles from './balance.css'; import styles from './balance.css';
export class Balance extends Component { function Balance ({ balance, className, showOnlyEth, tokens }) {
static contextTypes = { if (Object.keys(balance).length === 0) {
api: PropTypes.object return null;
}; }
static propTypes = { let body = Object.keys(balance)
balance: PropTypes.object.isRequired, .map((tokenId) => {
tokens: PropTypes.object.isRequired, const token = tokens[tokenId];
address: PropTypes.string, const balanceValue = balance[tokenId];
className: PropTypes.string,
showOnlyEth: PropTypes.bool,
showZeroValues: PropTypes.bool
};
static defaultProps = { const isEthToken = token.native;
showOnlyEth: false, const isFullToken = !showOnlyEth || isEthToken;
showZeroValues: false const hasBalance = balanceValue.gt(0);
};
render () { if (!hasBalance && !isEthToken) {
const { balance, className, showOnlyEth, tokens } = this.props; return null;
}
if (Object.keys(balance).length === 0) { const bnf = new BigNumber(token.format || 1);
return null; let decimals = 0;
}
let body = Object.keys(balance) if (bnf.gte(1000)) {
.map((tokenId) => { decimals = 3;
const token = tokens[tokenId]; } else if (bnf.gte(100)) {
const balanceValue = balance[tokenId]; decimals = 2;
} else if (bnf.gte(10)) {
decimals = 1;
}
const isEthToken = token.native; const value = new BigNumber(balanceValue).div(bnf).toFormat(decimals);
const isFullToken = !showOnlyEth || isEthToken;
const hasBalance = balanceValue.gt(0);
if (!hasBalance && !isEthToken) { const classNames = [styles.balance];
return null; let details = null;
}
const bnf = new BigNumber(token.format || 1); if (isFullToken) {
let decimals = 0; classNames.push(styles.full);
details = [
if (bnf.gte(1000)) {
decimals = 3;
} else if (bnf.gte(100)) {
decimals = 2;
} else if (bnf.gte(10)) {
decimals = 1;
}
const value = new BigNumber(balanceValue).div(bnf).toFormat(decimals);
const classNames = [styles.balance];
let details = null;
if (isFullToken) {
classNames.push(styles.full);
details = [
<div
className={ styles.value }
key='value'
>
<span title={ value }>
{ value }
</span>
</div>,
<div
className={ styles.tag }
key='tag'
>
{ token.tag }
</div>
];
}
return (
<div <div
className={ classNames.join(' ') } className={ styles.value }
key={ tokenId } key='value'
> >
<TokenImage token={ token } /> <span title={ value }>
{ details } { value }
</span>
</div>,
<div
className={ styles.tag }
key='tag'
>
{ token.tag }
</div> </div>
); ];
}) }
.filter((node) => node);
if (!body.length) { return (
body = ( <div
<div className={ styles.empty }> className={ classNames.join(' ') }
<FormattedMessage key={ tokenId }
id='ui.balance.none' >
defaultMessage='No balances associated with this account' <TokenImage token={ token } />
/> { details }
</div> </div>
); );
} })
.filter((node) => node);
return ( if (!body.length) {
<div body = (
className={ <div className={ styles.empty }>
[ <FormattedMessage
styles.balances, id='ui.balance.none'
showOnlyEth defaultMessage='No balances associated with this account'
? '' />
: styles.full,
className
].join(' ')
}
>
{ body }
</div> </div>
); );
} }
return (
<div
className={
[
styles.balances,
showOnlyEth
? ''
: styles.full,
className
].join(' ')
}
>
{ body }
</div>
);
} }
Balance.contextTypes = {
api: PropTypes.object.isRequired
};
Balance.propTypes = {
balance: PropTypes.object.isRequired,
tokens: PropTypes.object.isRequired,
address: PropTypes.string,
className: PropTypes.string,
showOnlyEth: PropTypes.bool,
showZeroValues: PropTypes.bool
};
Balance.defaultProps = {
showOnlyEth: false,
showZeroValues: false
};
function mapStateToProps (state, props) { function mapStateToProps (state, props) {
const { balances, tokens } = state; const { balances, tokens } = state;
const { address } = props; const { address } = props;
@ -149,4 +145,7 @@ function mapStateToProps (state, props) {
}; };
} }
export default connect(mapStateToProps)(Balance); export default connect(
mapStateToProps,
null
)(Balance);

View File

@ -14,99 +14,95 @@
// 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 React, { PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import styles from './blockStatus.css'; import styles from './blockStatus.css';
class BlockStatus extends Component { function BlockStatus ({ blockNumber, syncing }) {
static propTypes = { if (!blockNumber) {
blockNumber: PropTypes.object, return null;
syncing: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.object
])
} }
render () { if (!syncing) {
const { blockNumber, syncing } = this.props;
if (!blockNumber) {
return null;
}
if (!syncing) {
return (
<div className={ styles.blockNumber }>
<FormattedMessage
id='ui.blockStatus.bestBlock'
defaultMessage='{blockNumber} best block'
values={ {
blockNumber: blockNumber.toFormat()
} }
/>
</div>
);
}
if (syncing.warpChunksAmount && syncing.warpChunksProcessed && !syncing.warpChunksAmount.eq(syncing.warpChunksProcessed)) {
return (
<div className={ styles.syncStatus }>
<FormattedMessage
id='ui.blockStatus.warpRestore'
defaultMessage='{percentage}% warp restore'
values={ {
percentage: syncing.warpChunksProcessed.mul(100).div(syncing.warpChunksAmount).toFormat(2)
} }
/>
</div>
);
}
let syncStatus = null;
let warpStatus = null;
if (syncing.currentBlock && syncing.highestBlock) {
syncStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.syncStatus'
defaultMessage='{currentBlock}/{highestBlock} syncing'
values={ {
currentBlock: syncing.currentBlock.toFormat(),
highestBlock: syncing.highestBlock.toFormat()
} }
/>
</span>
);
}
if (syncing.blockGap) {
const [first, last] = syncing.blockGap;
warpStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.warpStatus'
defaultMessage=', {percentage}% historic'
values={ {
percentage: first.mul(100).div(last).toFormat(2)
} }
/>
</span>
);
}
return ( return (
<div className={ styles.syncStatus }> <div className={ styles.blockNumber }>
{ syncStatus } <FormattedMessage
{ warpStatus } id='ui.blockStatus.bestBlock'
defaultMessage='{blockNumber} best block'
values={ {
blockNumber: blockNumber.toFormat()
} }
/>
</div> </div>
); );
} }
if (syncing.warpChunksAmount && syncing.warpChunksProcessed && !syncing.warpChunksAmount.eq(syncing.warpChunksProcessed)) {
return (
<div className={ styles.syncStatus }>
<FormattedMessage
id='ui.blockStatus.warpRestore'
defaultMessage='{percentage}% warp restore'
values={ {
percentage: syncing.warpChunksProcessed.mul(100).div(syncing.warpChunksAmount).toFormat(2)
} }
/>
</div>
);
}
let syncStatus = null;
let warpStatus = null;
if (syncing.currentBlock && syncing.highestBlock) {
syncStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.syncStatus'
defaultMessage='{currentBlock}/{highestBlock} syncing'
values={ {
currentBlock: syncing.currentBlock.toFormat(),
highestBlock: syncing.highestBlock.toFormat()
} }
/>
</span>
);
}
if (syncing.blockGap) {
const [first, last] = syncing.blockGap;
warpStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.warpStatus'
defaultMessage=', {percentage}% historic'
values={ {
percentage: first.mul(100).div(last).toFormat(2)
} }
/>
</span>
);
}
return (
<div className={ styles.syncStatus }>
{ syncStatus }
{ warpStatus }
</div>
);
} }
BlockStatus.propTypes = {
blockNumber: PropTypes.object,
syncing: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.object
])
};
function mapStateToProps (state) { function mapStateToProps (state) {
const { blockNumber, syncing } = state.nodeStatus; const { blockNumber, syncing } = state.nodeStatus;

View File

@ -14,63 +14,46 @@
// 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 React, { PropTypes } from 'react';
import { Button as SemButton } from 'semantic-ui-react'; import { Button as SemButton } from 'semantic-ui-react';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
export default class Button extends Component { export default function Button ({ active, animated, basic, className, color, disabled, icon, label, onClick, primary, size, toggle }) {
static propTypes = { return (
active: PropTypes.bool, <SemButton
animated: PropTypes.bool, active={ active }
basic: PropTypes.bool, animated={ animated }
backgroundColor: PropTypes.string, basic={ basic }
className: PropTypes.string, className={ className }
color: PropTypes.string, color={ color }
disabled: PropTypes.bool, disabled={ disabled }
icon: PropTypes.node, icon={ icon }
label: nodeOrStringProptype(), content={ label }
onClick: PropTypes.func, onClick={ onClick }
primary: PropTypes.bool, primary={ primary }
size: PropTypes.string, size={ size }
toggle: PropTypes.bool toggle={ toggle }
} />
);
static defaultProps = {
primary: true
}
render () {
const {
active,
animated,
basic,
className,
color,
disabled,
icon,
label,
onClick,
primary,
size,
toggle
} = this.props;
return (
<SemButton
active={ active }
animated={ animated }
basic={ basic }
className={ className }
color={ color }
disabled={ disabled }
icon={ icon }
content={ label }
onClick={ onClick }
primary={ primary }
size={ size }
toggle={ toggle }
/>
);
}
} }
Button.propTypes = {
active: PropTypes.bool,
animated: PropTypes.bool,
basic: PropTypes.bool,
backgroundColor: PropTypes.string,
className: PropTypes.string,
color: PropTypes.string,
disabled: PropTypes.bool,
icon: PropTypes.node,
label: nodeOrStringProptype(),
onClick: PropTypes.func,
primary: PropTypes.bool,
size: PropTypes.string,
toggle: PropTypes.bool
};
Button.defaultProps = {
primary: true
};

View File

@ -14,7 +14,7 @@
// 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 React, { PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
@ -38,62 +38,56 @@ const DEFAULT_YES = (
/> />
); );
export default class ConfirmDialog extends Component { export default function ConfirmDialog ({ busy, children, className, disabledConfirm, disabledDeny, iconConfirm, iconDeny, labelConfirm, labelDeny, onConfirm, onDeny, open, title, visible }) {
static propTypes = { if (!visible && !open) {
children: PropTypes.node.isRequired, return null;
className: PropTypes.string,
disabledConfirm: PropTypes.bool,
disabledDeny: PropTypes.bool,
busy: PropTypes.bool,
iconConfirm: PropTypes.node,
iconDeny: PropTypes.node,
labelConfirm: PropTypes.string,
labelDeny: PropTypes.string,
onConfirm: PropTypes.func.isRequired,
onDeny: PropTypes.func.isRequired,
open: PropTypes.bool,
title: nodeOrStringProptype().isRequired,
visible: PropTypes.bool
} }
render () { return (
const { busy, children, className, disabledConfirm, disabledDeny, iconConfirm, iconDeny, labelConfirm, labelDeny, onConfirm, onDeny, open, title, visible } = this.props; <Portal
buttons={ [
// TODO: visible is for compatibility with existing, open aligns with Portal. <Button
// (Cleanup once all uses of ConfirmDialog has been migrated) disabled={ disabledDeny }
if (!visible && !open) { icon={ iconDeny || <CancelIcon /> }
return null; key='deny'
} label={ labelDeny || DEFAULT_NO }
onClick={ onDeny }
return ( />,
<Portal <Button
buttons={ [ disabled={ disabledConfirm }
<Button icon={ iconConfirm || <CheckIcon /> }
disabled={ disabledDeny } key='confirm'
icon={ iconDeny || <CancelIcon /> } label={ labelConfirm || DEFAULT_YES }
key='deny' onClick={ onConfirm }
label={ labelDeny || DEFAULT_NO } />
onClick={ onDeny } ] }
/>, busy={ busy }
<Button className={ className }
disabled={ disabledConfirm } isSmallModal
icon={ iconConfirm || <CheckIcon /> } onClose={ onDeny }
key='confirm' title={ title }
label={ labelConfirm || DEFAULT_YES } open
onClick={ onConfirm } >
/> <div className={ styles.body }>
] } { children }
busy={ busy } </div>
className={ className } </Portal>
isSmallModal );
onClose={ onDeny }
title={ title }
open
>
<div className={ styles.body }>
{ children }
</div>
</Portal>
);
}
} }
ConfirmDialog.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
disabledConfirm: PropTypes.bool,
disabledDeny: PropTypes.bool,
busy: PropTypes.bool,
iconConfirm: PropTypes.node,
iconDeny: PropTypes.node,
labelConfirm: PropTypes.string,
labelDeny: PropTypes.string,
onConfirm: PropTypes.func.isRequired,
onDeny: PropTypes.func.isRequired,
open: PropTypes.bool,
title: nodeOrStringProptype().isRequired,
visible: PropTypes.bool
};

View File

@ -17,9 +17,9 @@
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import VaultSelector from '~/modals/VaultSelector';
import VaultStore from '~/views/Vaults/store'; import VaultStore from '~/views/Vaults/store';
import VaultSelector from './VaultSelector';
import InputAddress from '../InputAddress'; import InputAddress from '../InputAddress';
export default class VaultSelect extends Component { export default class VaultSelect extends Component {

View File

@ -14,28 +14,24 @@
// 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 React, { PropTypes } from 'react';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
import styles from './busy.css'; import styles from './busy.css';
export default class Busy extends Component { export default function Busy ({ children, state, title }) {
static propTypes = { return (
children: PropTypes.node, <div className={ styles.center }>
state: nodeOrStringProptype(), <div className={ styles.title }>{ title }</div>
title: nodeOrStringProptype() <div className={ styles.state }>{ state }</div>
} { children }
</div>
render () { );
const { children, state, title } = this.props;
return (
<div className={ styles.center }>
<div className={ styles.title }>{ title }</div>
<div className={ styles.state }>{ state }</div>
{ children }
</div>
);
}
} }
Busy.propTypes = {
children: PropTypes.node,
state: nodeOrStringProptype(),
title: nodeOrStringProptype()
};

View File

@ -14,22 +14,18 @@
// 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 React, { PropTypes } from 'react';
import styles from './completed.css'; import styles from './completed.css';
export default class Completed extends Component { export default function Completed ({ children }) {
static propTypes = { return (
children: PropTypes.node <div className={ styles.body }>
} { children }
</div>
render () { );
const { children } = this.props;
return (
<div className={ styles.body }>
{ children }
</div>
);
}
} }
Completed.propTypes = {
children: PropTypes.node
};

View File

@ -14,50 +14,46 @@
// 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 React, { PropTypes } from 'react';
import Actionbar from '../Actionbar'; import Actionbar from '../Actionbar';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
import styles from './page.css'; import styles from './page.css';
export default class Page extends Component { export default function Page ({ buttons, className, children, padded, title }) {
static propTypes = { return (
buttons: PropTypes.array, <div>
className: PropTypes.string, {
children: PropTypes.node, title || buttons
padded: PropTypes.bool, ? (
title: nodeOrStringProptype() <Actionbar
}; buttons={ buttons }
title={ title }
render () { />
const { buttons, className, children, padded, title } = this.props; )
: null
return ( }
<div> <div
{ className={
title || buttons [
? ( padded
<Actionbar ? styles.layoutPadded
buttons={ buttons } : styles.layout,
title={ title } className
/> ].join(' ')
)
: null
} }
<div >
className={ { children }
[
padded
? styles.layoutPadded
: styles.layout,
className
].join(' ')
}
>
{ children }
</div>
</div> </div>
); </div>
} );
} }
Page.propTypes = {
buttons: PropTypes.array,
className: PropTypes.string,
children: PropTypes.node,
padded: PropTypes.bool,
title: nodeOrStringProptype()
};

View File

@ -14,29 +14,25 @@
// 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 React, { PropTypes } from 'react';
import styles from './shortenedHash.css'; import styles from './shortenedHash.css';
export default class ShortenedHash extends Component { export default function ShortenedHash ({ data }) {
static propTypes = { let shortened = data.toLowerCase();
data: PropTypes.string.isRequired
if (shortened.slice(0, 2) === '0x') {
shortened = shortened.slice(2);
}
if (shortened.length > (6 + 6)) {
shortened = shortened.slice(0, 6) + '…' + shortened.slice(-6);
} }
render () { return (
const { data } = this.props; <abbr className={ styles.hash } title={ data }>{ shortened }</abbr>
);
let shortened = data.toLowerCase();
if (shortened.slice(0, 2) === '0x') {
shortened = shortened.slice(2);
}
if (shortened.length > (6 + 6)) {
shortened = shortened.slice(0, 6) + '…' + shortened.slice(-6);
}
return (
<abbr className={ styles.hash } title={ data }>{ shortened }</abbr>
);
}
} }
ShortenedHash.propTypes = {
data: PropTypes.string.isRequired
};

View File

@ -14,40 +14,36 @@
// 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 React, { PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { keccak_256 } from 'js-sha3'; // eslint-disable-line camelcase import { keccak_256 } from 'js-sha3'; // eslint-disable-line camelcase
import IdentityIcon from '../IdentityIcon'; import IdentityIcon from '../IdentityIcon';
import { FingerprintIcon } from '../Icons'; import { FingerprintIcon } from '../Icons';
class SignerIcon extends Component { function SignerIcon ({ className, secureToken }) {
static propTypes = { if (!secureToken) {
className: PropTypes.string,
secureToken: PropTypes.string
}
render () {
const { className, secureToken } = this.props;
if (!secureToken) {
return (
<FingerprintIcon />
);
}
const signerSha = keccak_256(secureToken);
return ( return (
<IdentityIcon <FingerprintIcon />
address={ signerSha }
center
className={ className }
/>
); );
} }
const signerSha = keccak_256(secureToken);
return (
<IdentityIcon
address={ signerSha }
center
className={ className }
/>
);
} }
SignerIcon.propTypes = {
className: PropTypes.string,
secureToken: PropTypes.string
};
function mapStateToProps (state) { function mapStateToProps (state) {
const { secureToken } = state.nodeStatus; const { secureToken } = state.nodeStatus;

View File

@ -14,48 +14,44 @@
// 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 React, { PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import unknownImage from '~/../assets/images/contracts/unknown-64x64.png'; import unknownImage from '~/../assets/images/contracts/unknown-64x64.png';
class TokenImage extends Component { function TokenImage ({ image, token }, context) {
static contextTypes = { const { api } = context;
api: PropTypes.object const imageurl = token.image || image;
}; let imagesrc = unknownImage;
static propTypes = { if (imageurl) {
image: PropTypes.string, const host = /^(\/)?api/.test(imageurl)
token: PropTypes.shape({ ? api.dappsUrl
image: PropTypes.string, : '';
address: PropTypes.string
}).isRequired
};
render () { imagesrc = `${host}${imageurl}`;
const { api } = this.context;
const { image, token } = this.props;
const imageurl = token.image || image;
let imagesrc = unknownImage;
if (imageurl) {
const host = /^(\/)?api/.test(imageurl)
? api.dappsUrl
: '';
imagesrc = `${host}${imageurl}`;
}
return (
<img
src={ imagesrc }
alt={ token.name }
/>
);
} }
return (
<img
src={ imagesrc }
alt={ token.name }
/>
);
} }
TokenImage.contextTypes = {
api: PropTypes.object
};
TokenImage.propTypes = {
image: PropTypes.string,
token: PropTypes.shape({
image: PropTypes.string,
address: PropTypes.string
}).isRequired
};
function mapStateToProps (iniState) { function mapStateToProps (iniState) {
const { images } = iniState; const { images } = iniState;

View File

@ -0,0 +1,66 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import DappLink from '~/ui/DappLink';
import IdentityIcon from '~/ui/IdentityIcon';
import styles from '../vaultCard.css';
export default function Accounts ({ accounts, hideAccounts }) {
if (hideAccounts) {
return null;
}
if (!accounts || !accounts.length) {
return (
<div className={ styles.empty }>
<FormattedMessage
id='vaults.accounts.empty'
defaultMessage='There are no accounts in this vault'
/>
</div>
);
}
return (
<div className={ styles.accounts }>
{
accounts.map((address) => {
return (
<DappLink
key={ address }
to={ `/accounts/${address}` }
>
<IdentityIcon
address={ address }
center
className={ styles.account }
/>
</DappLink>
);
})
}
</div>
);
}
Accounts.propTypes = {
accounts: PropTypes.array,
hideAccounts: PropTypes.bool
};

View File

@ -14,4 +14,4 @@
// 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/>.
export default from './addDapps'; export default from './accounts';

View File

@ -0,0 +1,52 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { PropTypes } from 'react';
import Button from '~/ui/Button';
import { LockedIcon, UnlockedIcon } from '~/ui/Icons';
import styles from '../vaultCard.css';
export default function Buttons ({ buttons, hideButtons, vault }) {
const { isOpen } = vault;
if (hideButtons) {
return null;
}
return (
<div className={ styles.buttons }>
<Button
className={ styles.status }
disabled
icon={
isOpen
? <UnlockedIcon />
: <LockedIcon />
}
key='status'
/>
{ buttons }
</div>
);
}
Buttons.propTypes = {
buttons: PropTypes.array,
hideButtons: PropTypes.bool,
vault: PropTypes.object.isRequired
};

View File

@ -0,0 +1,17 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './buttons';

View File

@ -14,113 +14,52 @@
// 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 React, { PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
import Button from '~/ui/Button';
import Container from '~/ui/Container'; import Container from '~/ui/Container';
import IdentityIcon from '~/ui/IdentityIcon';
import { LockedIcon, UnlockedIcon } from '~/ui/Icons';
import Accounts from './Accounts';
import Buttons from './Buttons';
import Layout from './Layout'; import Layout from './Layout';
import styles from './vaultCard.css'; import styles from './vaultCard.css';
export default class VaultCard extends Component { export default function VaultCard ({ accounts, buttons, children, hideAccounts, hideButtons, vault }) {
static propTypes = { const { isOpen } = vault;
accounts: PropTypes.array,
buttons: PropTypes.array,
children: PropTypes.node,
hideAccounts: PropTypes.bool,
hideButtons: PropTypes.bool,
vault: PropTypes.object.isRequired
};
static Layout = Layout; return (
<Container
render () { className={ styles.container }
const { children, vault } = this.props; hover={
const { isOpen } = vault; isOpen
? (
return ( <Accounts
<Container accounts={ accounts }
className={ styles.container } hideAccounts={ hideAccounts }
hover={ />
isOpen )
? this.renderAccounts() : null
: null }
} >
> <Buttons
{ this.renderButtons() } buttons={ buttons }
<Layout vault={ vault }> hideButtons={ hideButtons }
{ children } vault={ vault }
</Layout> />
</Container> <Layout vault={ vault }>
); { children }
} </Layout>
</Container>
renderAccounts () { );
const { accounts, hideAccounts } = this.props;
if (hideAccounts) {
return null;
}
if (!accounts || !accounts.length) {
return (
<div className={ styles.empty }>
<FormattedMessage
id='vaults.accounts.empty'
defaultMessage='There are no accounts in this vault'
/>
</div>
);
}
return (
<div className={ styles.accounts }>
{
accounts.map((address) => {
return (
<Link
key={ address }
to={ `/accounts/${address}` }
>
<IdentityIcon
address={ address }
center
className={ styles.account }
/>
</Link>
);
})
}
</div>
);
}
renderButtons () {
const { buttons, hideButtons, vault } = this.props;
const { isOpen } = vault;
if (hideButtons) {
return null;
}
return (
<div className={ styles.buttons }>
<Button
className={ styles.status }
disabled
icon={
isOpen
? <UnlockedIcon />
: <LockedIcon />
}
key='status'
/>
{ buttons }
</div>
);
}
} }
VaultCard.propTypes = {
accounts: PropTypes.array,
buttons: PropTypes.array,
children: PropTypes.node,
hideAccounts: PropTypes.bool,
hideButtons: PropTypes.bool,
vault: PropTypes.object.isRequired
};
VaultCard.Layout = Layout;

View File

@ -14,32 +14,28 @@
// 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 React, { PropTypes } from 'react';
import IdentityIcon from '~/ui/IdentityIcon'; import IdentityIcon from '~/ui/IdentityIcon';
import styles from './vaultTag.css'; import styles from './vaultTag.css';
export default class VaultTag extends Component { export default function VaultTag ({ vault }) {
static propTypes = { return (
vault: PropTypes.string.isRequired <div className={ styles.vault }>
}; <div className={ styles.vaultBody }>
<IdentityIcon
render () { address={ vault }
const { vault } = this.props; inline
/>
return ( <div className={ styles.text }>
<div className={ styles.vault }> { vault }
<div className={ styles.vaultBody }>
<IdentityIcon
address={ vault }
inline
/>
<div className={ styles.text }>
{ vault }
</div>
</div> </div>
</div> </div>
); </div>
} );
} }
VaultTag.propTypes = {
vault: PropTypes.string.isRequired
};

View File

@ -14,28 +14,24 @@
// 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 } from 'react'; import React from 'react';
import { nodeOrStringProptype } from '~/util/proptypes'; import { nodeOrStringProptype } from '~/util/proptypes';
import styles from './warning.css'; import styles from './warning.css';
export default class Warning extends Component { export default function Warning ({ warning }) {
static propTypes = { if (!warning) {
warning: nodeOrStringProptype() return null;
};
render () {
const { warning } = this.props;
if (!warning) {
return null;
}
return (
<div className={ styles.warning }>
{ warning }
</div>
);
} }
return (
<div className={ styles.warning }>
{ warning }
</div>
);
} }
Warning.propTypes = {
warning: nodeOrStringProptype()
};

Some files were not shown because too many files have changed in this diff Show More