From 95e1eff4ca3d784d6fcba21035a535f8f3398cdc Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 17 Sep 2018 18:32:35 -0700 Subject: [PATCH] Add TransactionDetails modal --- app/_locales/en/messages.json | 3 ++ ui/app/components/modal/index.scss | 8 ++-- ui/app/components/modal/modal.component.js | 18 +++++++- ui/app/components/modals/modal.js | 14 ++++++ .../modals/transaction-details/index.js | 1 + .../transaction-details.component.js | 43 +++++++++++++++++++ .../transaction-details.container.js | 4 ++ .../transaction-activity-log/index.scss | 9 ++-- .../transaction-list-item.component.js | 24 ++++++++++- .../transaction-list-item.container.js | 10 +++++ 10 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 ui/app/components/modals/transaction-details/index.js create mode 100644 ui/app/components/modals/transaction-details/transaction-details.component.js create mode 100644 ui/app/components/modals/transaction-details/transaction-details.container.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index ed2e7a119..570284126 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1112,6 +1112,9 @@ "transactionCreated": { "message": "Transaction created with a value of $1 on $2." }, + "transactionWithNonce": { + "message": "Transaction $1" + }, "transactionDropped": { "message": "Transaction dropped on $2." }, diff --git a/ui/app/components/modal/index.scss b/ui/app/components/modal/index.scss index e57156d71..2beb14633 100644 --- a/ui/app/components/modal/index.scss +++ b/ui/app/components/modal/index.scss @@ -8,12 +8,13 @@ flex-flow: column; border-radius: 8px; + @media screen and (max-width: 575px) { + max-height: 450px; + } + &__content { overflow-y: auto; flex: 1; - display: flex; - flex-direction: column; - align-items: center; padding: 16px 32px; @media screen and (max-width: 575px) { @@ -28,6 +29,7 @@ padding: 12px; justify-content: center; border-bottom: 1px solid #d2d8dd; + flex: 0 0 auto; } &__header-close::after { diff --git a/ui/app/components/modal/modal.component.js b/ui/app/components/modal/modal.component.js index 81bdd0010..f9d8c5867 100644 --- a/ui/app/components/modal/modal.component.js +++ b/ui/app/components/modal/modal.component.js @@ -22,6 +22,22 @@ export default class Modal extends PureComponent { cancelType: 'default', } + handleClose = () => { + const { onCancel, onSubmit } = this.props + + /** + * The close button should be used to dismiss the modal, without performing any actions, which + * is typically what props.onCancel does. However, if props.onCancel is undefined, that should + * mean that the modal is a simple notification modal and props.onSubmit can be used to dismiss + * it. + */ + if (onCancel && typeof onCancel === 'function') { + onCancel() + } else { + onSubmit() + } + } + render () { const { children, @@ -44,7 +60,7 @@ export default class Modal extends PureComponent {
onCancel()} + onClick={this.handleClose} />
) diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 2aec89326..6054002c8 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -27,6 +27,7 @@ import TransactionConfirmed from './transaction-confirmed' import ConfirmCustomizeGasModal from './customize-gas' import CancelTransaction from './cancel-transaction' import WelcomeBeta from './welcome-beta' +import TransactionDetails from './transaction-details' const modalContainerBaseStyle = { transform: 'translate3d(-50%, 0, 0px)', @@ -364,6 +365,19 @@ const MODALS = { }, }, + TRANSACTION_DETAILS: { + contents: h(TransactionDetails), + mobileModalStyle: { + ...modalContainerMobileStyle, + }, + laptopModalStyle: { + ...modalContainerLaptopStyle, + }, + contentStyle: { + borderRadius: '8px', + }, + }, + DEFAULT: { contents: [], mobileModalStyle: {}, diff --git a/ui/app/components/modals/transaction-details/index.js b/ui/app/components/modals/transaction-details/index.js new file mode 100644 index 000000000..1fc42c662 --- /dev/null +++ b/ui/app/components/modals/transaction-details/index.js @@ -0,0 +1 @@ +export { default } from './transaction-details.container' diff --git a/ui/app/components/modals/transaction-details/transaction-details.component.js b/ui/app/components/modals/transaction-details/transaction-details.component.js new file mode 100644 index 000000000..7eec028fe --- /dev/null +++ b/ui/app/components/modals/transaction-details/transaction-details.component.js @@ -0,0 +1,43 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import Modal from '../../modal' +import TransactionListItemDetails from '../../transaction-list-item-details' +import { hexToDecimal } from '../../../helpers/conversions.util' + +export default class TransactionConfirmed extends PureComponent { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + hideModal: PropTypes.func, + transaction: PropTypes.object, + onRetry: PropTypes.func, + showRetry: PropTypes.bool, + onCancel: PropTypes.func, + showCancel: PropTypes.bool, + } + + render () { + const { t } = this.context + const { transaction, onRetry, showRetry, onCancel, showCancel, hideModal } = this.props + const { txParams: { nonce } = {} } = transaction + const decimalNonce = nonce && hexToDecimal(nonce) + + return ( + hideModal()} + submitText={t('ok')} + headerText={t('transactionWithNonce', [`#${decimalNonce}`])} + > + onRetry()} + showRetry={showRetry} + onCancel={() => onCancel()} + showCancel={showCancel} + /> + + ) + } +} diff --git a/ui/app/components/modals/transaction-details/transaction-details.container.js b/ui/app/components/modals/transaction-details/transaction-details.container.js new file mode 100644 index 000000000..f212920bb --- /dev/null +++ b/ui/app/components/modals/transaction-details/transaction-details.container.js @@ -0,0 +1,4 @@ +import TransactionDetails from './transaction-details.component' +import withModalProps from '../../../higher-order-components/with-modal-props' + +export default withModalProps(TransactionDetails) diff --git a/ui/app/components/transaction-activity-log/index.scss b/ui/app/components/transaction-activity-log/index.scss index a9933dac6..27f3006b3 100644 --- a/ui/app/components/transaction-activity-log/index.scss +++ b/ui/app/components/transaction-activity-log/index.scss @@ -51,9 +51,12 @@ &__activity-text { color: $scorpion; font-size: .75rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + + @media screen and (min-width: $break-large) { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } } &__value { diff --git a/ui/app/components/transaction-list-item/transaction-list-item.component.js b/ui/app/components/transaction-list-item/transaction-list-item.component.js index 72389c95b..799562638 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.component.js @@ -9,6 +9,7 @@ import TransactionListItemDetails from '../transaction-list-item-details' import { CONFIRM_TRANSACTION_ROUTE } from '../../routes' import { UNAPPROVED_STATUS, TOKEN_METHOD_TRANSFER } from '../../constants/transactions' import { ETH } from '../../constants/common' +import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../app/scripts/lib/enums' export default class TransactionListItem extends PureComponent { static propTypes = { @@ -21,6 +22,7 @@ export default class TransactionListItem extends PureComponent { showCancelModal: PropTypes.func, showCancel: PropTypes.bool, showRetry: PropTypes.bool, + showTransactionDetailsModal: PropTypes.func, token: PropTypes.object, tokenData: PropTypes.object, transaction: PropTypes.object, @@ -32,16 +34,34 @@ export default class TransactionListItem extends PureComponent { } handleClick = () => { - const { transaction, history } = this.props + const { + transaction, + history, + showTransactionDetailsModal, + methodData, + showCancel, + showRetry, + } = this.props const { id, status } = transaction const { showTransactionDetails } = this.state + const windowType = window.METAMASK_UI_TYPE if (status === UNAPPROVED_STATUS) { history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`) return } - this.setState({ showTransactionDetails: !showTransactionDetails }) + if (windowType === ENVIRONMENT_TYPE_FULLSCREEN) { + this.setState({ showTransactionDetails: !showTransactionDetails }) + } else { + showTransactionDetailsModal({ + transaction, + onRetry: this.handleRetry, + showRetry: showRetry && methodData.done, + onCancel: this.handleCancel, + showCancel, + }) + } } handleCancel = () => { diff --git a/ui/app/components/transaction-list-item/transaction-list-item.container.js b/ui/app/components/transaction-list-item/transaction-list-item.container.js index 62ed7a73f..72f5f5d61 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.container.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.container.js @@ -28,6 +28,16 @@ const mapDispatchToProps = dispatch => { showCancelModal: (transactionId, originalGasPrice) => { return dispatch(showModal({ name: 'CANCEL_TRANSACTION', transactionId, originalGasPrice })) }, + showTransactionDetailsModal: ({ transaction, onRetry, showRetry, onCancel, showCancel }) => { + return dispatch(showModal({ + name: 'TRANSACTION_DETAILS', + transaction, + onRetry, + showRetry, + onCancel, + showCancel, + })) + }, } }