// 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 . import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import ReactTooltip from 'react-tooltip'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { bytesToHex } from '@parity/api/util/format'; import { confirmOperation, revokeOperation } from '@parity/shared/redux/providers/walletActions'; import { Container, Dropdown, InputAddress, IdentityIcon, Progress } from '@parity/ui'; import TxRow from '@parity/ui/TxList/TxRow'; import styles from '../wallet.css'; import txListStyles from '@parity/ui/TxList/txList.css'; class WalletConfirmations extends Component { static contextTypes = { api: PropTypes.object.isRequired }; static propTypes = { accounts: PropTypes.object.isRequired, address: PropTypes.string.isRequired, netVersion: PropTypes.string.isRequired, owners: PropTypes.array.isRequired, require: PropTypes.object.isRequired, confirmOperation: PropTypes.func.isRequired, revokeOperation: PropTypes.func.isRequired, confirmations: PropTypes.array }; static defaultProps = { confirmations: [] }; render () { return (
} > { this.renderConfirmations() }
); } renderConfirmations () { const { confirmations, ...others } = this.props; const realConfirmations = confirmations && confirmations .filter((conf) => conf.confirmedBy.length > 0); if (!realConfirmations) { return null; } if (realConfirmations.length === 0) { return (

); } return realConfirmations.map((confirmation) => ( )); } } function mapStateToProps (state) { const { accounts } = state.personal; return { accounts }; } function mapDispatchToProps (dispatch) { return bindActionCreators({ confirmOperation, revokeOperation }, dispatch); } export default connect( mapStateToProps, mapDispatchToProps )(WalletConfirmations); class WalletConfirmation extends Component { static propTypes = { accounts: PropTypes.object.isRequired, confirmation: PropTypes.object.isRequired, address: PropTypes.string.isRequired, netVersion: PropTypes.string.isRequired, owners: PropTypes.array.isRequired, require: PropTypes.object.isRequired, confirmOperation: PropTypes.func.isRequired, revokeOperation: PropTypes.func.isRequired }; render () { const { confirmation } = this.props; const { pending } = confirmation; const confirmationsRows = []; const className = styles.light; const txRow = this.renderTransactionRow(confirmation, className); const detailsRow = this.renderConfirmedBy(confirmation, className); const progressRow = this.renderProgress(confirmation, className); const actionsRow = this.renderActions(confirmation, className); confirmationsRows.push(progressRow); confirmationsRows.push(detailsRow); confirmationsRows.push(txRow); confirmationsRows.push(actionsRow); return (
{ confirmationsRows }
{ pending && (
) }
); } handleConfirm = (event, owner) => { const { confirmOperation, confirmation, address } = this.props; confirmOperation(address, owner, confirmation.operation); } handleRevoke = (event, owner) => { const { revokeOperation, confirmation, address } = this.props; revokeOperation(address, owner, confirmation.operation); } renderActions (confirmation, className) { const { owners, accounts } = this.props; const { operation, confirmedBy } = confirmation; const addresses = Object.keys(accounts); const possibleConfirm = owners .filter((owner) => addresses.includes(owner)) .filter((owner) => !confirmedBy.includes(owner)); const possibleRevoke = owners .filter((owner) => addresses.includes(owner)) .filter((owner) => confirmedBy.includes(owner)); return (
} onChange={ this.handleConfirm } options={ possibleConfirm.map((address) => this.renderAccountItem(address)) } /> } onChange={ this.handleRevoke } oprions={ possibleRevoke.map((address) => this.renderAccountItem(address)) } />
); } renderAccountItem (address) { const account = this.props.accounts[address]; const name = account.name.toUpperCase() || account.address; return { key: address, label: (
{ name }
), value: name }; } renderProgress (confirmation) { const { require } = this.props; const { operation, confirmedBy, pending } = confirmation; const style = { borderRadius: 0 }; return (
{ pending ? ( ) : ( ) }
); } renderTransactionRow (confirmation, className) { const { address, netVersion } = this.props; const { operation, transactionHash, blockNumber, value, to, data } = confirmation; if (value && to && data) { return ( ); } return ( { operation } ); } renderConfirmedBy (confirmation, className) { const { operation, confirmedBy } = confirmation; return (
{ confirmedBy.map((owner) => ( )) }
); } }