diff options
6 files changed, 203 insertions, 0 deletions
diff --git a/app/images/arrow-popout.svg b/app/images/arrow-popout.svg new file mode 100644 index 000000000..7e25f7cd2 --- /dev/null +++ b/app/images/arrow-popout.svg @@ -0,0 +1,3 @@ +<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.67589 0.641872C8.65169 0.642635 8.62756 0.644749 8.6036 0.648202H4.79279C4.55863 0.644896 4.34082 0.767704 4.22278 0.969601C4.10473 1.1715 4.10473 1.4212 4.22278 1.6231C4.34082 1.825 4.55863 1.9478 4.79279 1.9445H7.12113L0.437932 8.61587C0.268309 8.77843 0.19998 9.01984 0.259298 9.24697C0.318616 9.47411 0.496311 9.65149 0.723852 9.71071C0.951393 9.76992 1.19322 9.70171 1.35608 9.53239L8.03927 2.86102V5.18524C8.03596 5.41898 8.15899 5.6364 8.36124 5.75424C8.56349 5.87208 8.81364 5.87208 9.0159 5.75424C9.21815 5.6364 9.34118 5.41898 9.33787 5.18524V1.37863C9.36404 1.18976 9.30558 0.998955 9.17804 0.857009C9.0505 0.715062 8.86682 0.636369 8.67589 0.641872Z" fill="#359BDD"/> +</svg> diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index e39dfe091..983d6b98a 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -28,6 +28,8 @@ @import './transaction-activity-log/index'; +@import './transaction-breakdown/index'; + @import './transaction-view/index'; @import './transaction-view-balance/index'; @@ -36,6 +38,8 @@ @import './transaction-list-item/index'; +@import './transaction-list-item-details/index'; + @import './transaction-status/index'; @import './app-header/index'; diff --git a/ui/app/components/transaction-list-item-details/index.js b/ui/app/components/transaction-list-item-details/index.js new file mode 100644 index 000000000..0e878d032 --- /dev/null +++ b/ui/app/components/transaction-list-item-details/index.js @@ -0,0 +1 @@ +export { default } from './transaction-list-item-details.component' diff --git a/ui/app/components/transaction-list-item-details/index.scss b/ui/app/components/transaction-list-item-details/index.scss new file mode 100644 index 000000000..54cf834cc --- /dev/null +++ b/ui/app/components/transaction-list-item-details/index.scss @@ -0,0 +1,49 @@ +.transaction-list-item-details { + &__header { + margin-bottom: 8px; + display: flex; + justify-content: space-between; + align-items: center; + } + + &__header-buttons { + display: flex; + flex-direction: row; + } + + &__header-button { + font-size: .625rem; + + &:not(:last-child) { + margin-right: 8px; + } + } + + &__sender-to-recipient-container { + margin-bottom: 8px; + } + + &__cards-container { + display: flex; + flex-direction: row; + + @media screen and (max-width: $break-small) { + flex-direction: column; + } + } + + &__transaction-breakdown { + flex: 1; + margin-right: 8px; + min-width: 0; + + @media screen and (max-width: $break-small) { + margin: 0 0 8px 0; + } + } + + &__transaction-activity-log { + flex: 2; + min-width: 0; + } +} diff --git a/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js new file mode 100644 index 000000000..f2bbe8789 --- /dev/null +++ b/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js @@ -0,0 +1,66 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import TransactionListItemDetails from '../transaction-list-item-details.component' +import Button from '../../button' +import SenderToRecipient from '../../sender-to-recipient' +import TransactionBreakdown from '../../transaction-breakdown' +import TransactionActivityLog from '../../transaction-activity-log' + +describe('TransactionListItemDetails Component', () => { + it('should render properly', () => { + const transaction = { + history: [], + id: 1, + status: 'confirmed', + txParams: { + from: '0x1', + gas: '0x5208', + gasPrice: '0x3b9aca00', + nonce: '0xa4', + to: '0x2', + value: '0x2386f26fc10000', + }, + } + + const wrapper = shallow( + <TransactionListItemDetails + transaction={transaction} + />, + { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } + ) + + assert.ok(wrapper.hasClass('transaction-list-item-details')) + assert.equal(wrapper.find(Button).length, 1) + assert.equal(wrapper.find(SenderToRecipient).length, 1) + assert.equal(wrapper.find(TransactionBreakdown).length, 1) + assert.equal(wrapper.find(TransactionActivityLog).length, 1) + }) + + it('should render a retry button', () => { + const transaction = { + history: [], + id: 1, + status: 'confirmed', + txParams: { + from: '0x1', + gas: '0x5208', + gasPrice: '0x3b9aca00', + nonce: '0xa4', + to: '0x2', + value: '0x2386f26fc10000', + }, + } + + const wrapper = shallow( + <TransactionListItemDetails + transaction={transaction} + showRetry={true} + />, + { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } + ) + + assert.ok(wrapper.hasClass('transaction-list-item-details')) + assert.equal(wrapper.find(Button).length, 2) + }) +}) diff --git a/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js new file mode 100644 index 000000000..d57ff130a --- /dev/null +++ b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js @@ -0,0 +1,80 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import SenderToRecipient from '../sender-to-recipient' +import { CARDS_VARIANT } from '../sender-to-recipient/sender-to-recipient.constants' +import TransactionActivityLog from '../transaction-activity-log' +import TransactionBreakdown from '../transaction-breakdown' +import Button from '../button' +import prefixForNetwork from '../../../lib/etherscan-prefix-for-network' + +export default class TransactionListItemDetails extends PureComponent { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + transaction: PropTypes.object, + showRetry: PropTypes.bool, + } + + handleEtherscanClick = () => { + const { hash, metamaskNetworkId } = this.props.transaction + + const prefix = prefixForNetwork(metamaskNetworkId) + const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}` + global.platform.openWindow({ url: etherscanUrl }) + this.setState({ showTransactionDetails: true }) + } + + render () { + const { t } = this.context + const { transaction, showRetry } = this.props + const { txParams: { to, from } = {} } = transaction + + return ( + <div className="transaction-list-item-details"> + <div className="transaction-list-item-details__header"> + <div>Details</div> + <div className="transaction-list-item-details__header-buttons"> + { + showRetry && ( + <Button + type="raised" + onClick={this.handleEtherscanClick} + className="transaction-list-item-details__header-button" + > + { t('speedUp') } + </Button> + ) + } + <Button + type="raised" + onClick={this.handleEtherscanClick} + className="transaction-list-item-details__header-button" + > + <img src="/images/arrow-popout.svg" /> + </Button> + </div> + </div> + <div className="transaction-list-item-details__sender-to-recipient-container"> + <SenderToRecipient + variant={CARDS_VARIANT} + addressOnly + recipientAddress={to} + senderAddress={from} + /> + </div> + <div className="transaction-list-item-details__cards-container"> + <TransactionBreakdown + transaction={transaction} + className="transaction-list-item-details__transaction-breakdown" + /> + <TransactionActivityLog + transaction={transaction} + className="transaction-list-item-details__transaction-activity-log" + /> + </div> + </div> + ) + } +} |