From 31175625b446cb5d18b17db23018bca8b14d280c Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Thu, 21 Mar 2019 16:03:30 -0700 Subject: Folder restructure (#6304) * Remove ui/app/keychains/ * Remove ui/app/img/ (unused images) * Move conversion-util to helpers/utils/ * Move token-util to helpers/utils/ * Move /helpers/*.js inside /helpers/utils/ * Move util tests inside /helpers/utils/ * Renameand move confirm-transaction/util.js to helpers/utils/ * Move higher-order-components to helpers/higher-order-components/ * Move infura-conversion.json to helpers/constants/ * Move all utility functions to helpers/utils/ * Move pages directory to top-level * Move all constants to helpers/constants/ * Move metametrics inside helpers/ * Move app and root inside pages/ * Move routes inside helpers/ * Re-organize ducks/ * Move reducers to ducks/ * Move selectors inside selectors/ * Move test out of test folder * Move action, reducer, store inside store/ * Move ui components inside ui/ * Move UI components inside ui/ * Move connected components inside components/app/ * Move i18n-helper inside helpers/ * Fix unit tests * Fix unit test * Move pages components * Rename routes component * Move reducers to ducks/index * Fix bad path in unit test --- .../advanced-gas-inputs.component.js | 156 -------- .../advanced-gas-inputs.container.js | 38 -- .../gas-customization/advanced-gas-inputs/index.js | 1 - .../advanced-gas-inputs/index.scss | 133 ------- .../advanced-tab-content.component.js | 219 ----------- .../advanced-tab-content/index.js | 1 - .../advanced-tab-content/index.scss | 203 ---------- .../tests/advanced-tab-content-component.test.js | 364 ------------------ .../advanced-tab-content/time-remaining/index.js | 1 - .../advanced-tab-content/time-remaining/index.scss | 17 - .../tests/time-remaining-component.test.js | 30 -- .../time-remaining/time-remaining.component.js | 33 -- .../time-remaining/time-remaining.utils.js | 11 - .../basic-tab-content.component.js | 35 -- .../basic-tab-content/index.js | 1 - .../basic-tab-content/index.scss | 28 -- .../tests/basic-tab-content-component.test.js | 82 ---- .../gas-modal-page-container.component.js | 186 --------- .../gas-modal-page-container.container.js | 291 -------------- .../gas-modal-page-container/index.js | 1 - .../gas-modal-page-container/index.scss | 146 ------- .../gas-modal-page-container-component.test.js | 274 ------------- .../gas-modal-page-container-container.test.js | 425 --------------------- .../gas-price-button-group.component.js | 89 ----- .../gas-price-button-group/index.js | 1 - .../gas-price-button-group/index.scss | 238 ------------ .../tests/gas-price-button-group-component.test.js | 233 ----------- .../gas-price-chart/gas-price-chart.component.js | 108 ------ .../gas-price-chart/gas-price-chart.utils.js | 354 ----------------- .../gas-customization/gas-price-chart/index.js | 1 - .../gas-customization/gas-price-chart/index.scss | 132 ------- .../tests/gas-price-chart.component.test.js | 218 ----------- .../gas-slider/gas-slider.component.js | 48 --- .../gas-customization/gas-slider/index.js | 1 - .../gas-customization/gas-slider/index.scss | 54 --- .../components/gas-customization/gas.selectors.js | 14 - ui/app/components/gas-customization/index.scss | 7 - 37 files changed, 4174 deletions(-) delete mode 100644 ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js delete mode 100644 ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js delete mode 100644 ui/app/components/gas-customization/advanced-gas-inputs/index.js delete mode 100644 ui/app/components/gas-customization/advanced-gas-inputs/index.scss delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.scss delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js delete mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js delete mode 100644 ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js delete mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.js delete mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.scss delete mode 100644 ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js delete mode 100644 ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js delete mode 100644 ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js delete mode 100644 ui/app/components/gas-customization/gas-price-chart/index.js delete mode 100644 ui/app/components/gas-customization/gas-price-chart/index.scss delete mode 100644 ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js delete mode 100644 ui/app/components/gas-customization/gas-slider/gas-slider.component.js delete mode 100644 ui/app/components/gas-customization/gas-slider/index.js delete mode 100644 ui/app/components/gas-customization/gas-slider/index.scss delete mode 100644 ui/app/components/gas-customization/gas.selectors.js delete mode 100644 ui/app/components/gas-customization/index.scss (limited to 'ui/app/components/gas-customization') diff --git a/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js deleted file mode 100644 index 95894140c..000000000 --- a/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ /dev/null @@ -1,156 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import debounce from 'lodash.debounce' - -export default class AdvancedTabContent extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - updateCustomGasPrice: PropTypes.func, - updateCustomGasLimit: PropTypes.func, - customGasPrice: PropTypes.number, - customGasLimit: PropTypes.number, - insufficientBalance: PropTypes.bool, - customPriceIsSafe: PropTypes.bool, - isSpeedUp: PropTypes.bool, - showGasPriceInfoModal: PropTypes.func, - showGasLimitInfoModal: PropTypes.func, - } - - debouncedGasLimitReset = debounce((dVal) => { - if (dVal < 21000) { - this.props.updateCustomGasLimit(21000) - } - }, 1000, { trailing: true }) - - onChangeGasLimit = (val) => { - this.props.updateCustomGasLimit(val) - this.debouncedGasLimitReset(val) - } - - gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { - const { t } = this.context - let errorText - let errorType - let isInError = true - - - if (insufficientBalance) { - errorText = t('insufficientBalance') - errorType = 'error' - } else if (labelKey === 'gasPrice' && isSpeedUp && value === 0) { - errorText = t('zeroGasPriceOnSpeedUpError') - errorType = 'error' - } else if (labelKey === 'gasPrice' && !customPriceIsSafe) { - errorText = t('gasPriceExtremelyLow') - errorType = 'warning' - } else { - isInError = false - } - - return { - isInError, - errorText, - errorType, - } - } - - gasInput ({ labelKey, value, onChange, insufficientBalance, showGWEI, customPriceIsSafe, isSpeedUp }) { - const { - isInError, - errorText, - errorType, - } = this.gasInputError({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) - - return ( -
- onChange(Number(event.target.value))} - /> -
-
onChange(value + 1)} - > - -
-
onChange(Math.max(value - 1, 0))} - > - -
-
- { isInError - ?
- { errorText } -
- : null } -
- ) - } - - infoButton (onClick) { - return - } - - renderGasEditRow (gasInputArgs) { - return ( -
-
- { this.context.t(gasInputArgs.labelKey) } - { this.infoButton(() => gasInputArgs.infoOnClick()) } -
- { this.gasInput(gasInputArgs) } -
- ) - } - - render () { - const { - customGasPrice, - updateCustomGasPrice, - customGasLimit, - insufficientBalance, - customPriceIsSafe, - isSpeedUp, - showGasPriceInfoModal, - showGasLimitInfoModal, - } = this.props - - return ( -
- { this.renderGasEditRow({ - labelKey: 'gasPrice', - value: customGasPrice, - onChange: updateCustomGasPrice, - insufficientBalance, - customPriceIsSafe, - showGWEI: true, - isSpeedUp, - infoOnClick: showGasPriceInfoModal, - }) } - { this.renderGasEditRow({ - labelKey: 'gasLimit', - value: customGasLimit, - onChange: this.onChangeGasLimit, - insufficientBalance, - customPriceIsSafe, - infoOnClick: showGasLimitInfoModal, - }) } -
- ) - } -} diff --git a/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js b/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js deleted file mode 100644 index a71d37b43..000000000 --- a/ui/app/components/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js +++ /dev/null @@ -1,38 +0,0 @@ -import { connect } from 'react-redux' -import { showModal } from '../../../actions' -import { - decGWEIToHexWEI, - decimalToHex, - hexWEIToDecGWEI, -} from '../../../helpers/conversions.util' -import AdvancedGasInputs from './advanced-gas-inputs.component' - -function convertGasPriceForInputs (gasPriceInHexWEI) { - return Number(hexWEIToDecGWEI(gasPriceInHexWEI)) -} - -function convertGasLimitForInputs (gasLimitInHexWEI) { - return parseInt(gasLimitInHexWEI, 16) -} - -const mapDispatchToProps = dispatch => { - return { - showGasPriceInfoModal: modalName => dispatch(showModal({ name: 'GAS_PRICE_INFO_MODAL' })), - showGasLimitInfoModal: modalName => dispatch(showModal({ name: 'GAS_LIMIT_INFO_MODAL' })), - } -} - -const mergeProps = (stateProps, dispatchProps, ownProps) => { - const {customGasPrice, customGasLimit, updateCustomGasPrice, updateCustomGasLimit} = ownProps - return { - ...stateProps, - ...dispatchProps, - ...ownProps, - customGasPrice: convertGasPriceForInputs(customGasPrice), - customGasLimit: convertGasLimitForInputs(customGasLimit), - updateCustomGasPrice: (price) => updateCustomGasPrice(decGWEIToHexWEI(price)), - updateCustomGasLimit: (limit) => updateCustomGasLimit(decimalToHex(limit)), - } -} - -export default connect(null, mapDispatchToProps, mergeProps)(AdvancedGasInputs) diff --git a/ui/app/components/gas-customization/advanced-gas-inputs/index.js b/ui/app/components/gas-customization/advanced-gas-inputs/index.js deleted file mode 100644 index bd8abaa3e..000000000 --- a/ui/app/components/gas-customization/advanced-gas-inputs/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './advanced-gas-inputs.container' diff --git a/ui/app/components/gas-customization/advanced-gas-inputs/index.scss b/ui/app/components/gas-customization/advanced-gas-inputs/index.scss deleted file mode 100644 index 50953cbe5..000000000 --- a/ui/app/components/gas-customization/advanced-gas-inputs/index.scss +++ /dev/null @@ -1,133 +0,0 @@ -.advanced-gas-inputs { - &__gas-edit-rows { - display: flex; - flex-flow: row; - justify-content: space-between; - } - - &__gas-edit-row { - display: flex; - flex-flow: column; - width: 47.5%; - - &__label { - color: #313B5E; - font-size: 12px; - display: flex; - justify-content: space-between; - align-items: center; - - @media screen and (max-width: 576px) { - font-size: 10px; - } - - .fa-info-circle { - color: $silver; - margin-left: 10px; - cursor: pointer; - } - - .fa-info-circle:hover { - color: $mid-gray; - } - } - - &__error-text { - font-size: 12px; - color: red; - } - - &__warning-text { - font-size: 12px; - color: orange; - } - - &__input-wrapper { - position: relative; - } - - &__input { - border: 1px solid $dusty-gray; - border-radius: 4px; - color: $mid-gray; - font-size: 16px; - height: 24px; - width: 100%; - padding-left: 8px; - padding-top: 2px; - margin-top: 7px; - } - - &__input--error { - border: 1px solid $red; - } - - &__input--warning { - border: 1px solid $orange; - } - - &__input-arrows { - position: absolute; - top: 7px; - right: 0px; - width: 17px; - height: 24px; - border: 1px solid #dadada; - border-top-right-radius: 4px; - display: flex; - flex-direction: column; - color: #9b9b9b; - font-size: .8em; - border-bottom-right-radius: 4px; - cursor: pointer; - - &__i-wrap { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - cursor: pointer; - } - - &__i-wrap:hover { - background: #4EADE7; - color: $white; - } - - i:hover { - background: #4EADE7; - } - - i { - font-size: 10px; - } - } - - &__input-arrows--error { - border: 1px solid $red; - } - - &__input-arrows--warning { - border: 1px solid $orange; - } - - input[type="number"]::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - input[type="number"]:hover::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - &__gwei-symbol { - position: absolute; - top: 8px; - right: 10px; - color: $dusty-gray; - } - } -} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js deleted file mode 100644 index a3a3f96d8..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ /dev/null @@ -1,219 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import classnames from 'classnames' -import Loading from '../../../loading-screen' -import GasPriceChart from '../../gas-price-chart' -import debounce from 'lodash.debounce' - -export default class AdvancedTabContent extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - updateCustomGasPrice: PropTypes.func, - updateCustomGasLimit: PropTypes.func, - customGasPrice: PropTypes.number, - customGasLimit: PropTypes.number, - gasEstimatesLoading: PropTypes.bool, - millisecondsRemaining: PropTypes.number, - transactionFee: PropTypes.string, - timeRemaining: PropTypes.string, - gasChartProps: PropTypes.object, - insufficientBalance: PropTypes.bool, - customPriceIsSafe: PropTypes.bool, - isSpeedUp: PropTypes.bool, - } - - constructor (props) { - super(props) - - this.debouncedGasLimitReset = debounce((dVal) => { - if (dVal < 21000) { - props.updateCustomGasLimit(21000) - } - }, 1000, { trailing: true }) - this.onChangeGasLimit = (val) => { - props.updateCustomGasLimit(val) - this.debouncedGasLimitReset(val) - } - } - - gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { - const { t } = this.context - let errorText - let errorType - let isInError = true - - - if (insufficientBalance) { - errorText = t('insufficientBalance') - errorType = 'error' - } else if (labelKey === 'gasPrice' && isSpeedUp && value === 0) { - errorText = t('zeroGasPriceOnSpeedUpError') - errorType = 'error' - } else if (labelKey === 'gasPrice' && !customPriceIsSafe) { - errorText = t('gasPriceExtremelyLow') - errorType = 'warning' - } else { - isInError = false - } - - return { - isInError, - errorText, - errorType, - } - } - - gasInput ({ labelKey, value, onChange, insufficientBalance, showGWEI, customPriceIsSafe, isSpeedUp }) { - const { - isInError, - errorText, - errorType, - } = this.gasInputError({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) - - return ( -
- onChange(Number(event.target.value))} - /> -
-
onChange(value + 1)} - > - -
-
onChange(Math.max(value - 1, 0))} - > - -
-
- { isInError - ?
- { errorText } -
- : null } -
- ) - } - - infoButton (onClick) { - return - } - - renderDataSummary (transactionFee, timeRemaining) { - return ( -
-
- { this.context.t('newTransactionFee') } - ~{ this.context.t('transactionTime') } -
-
-
- {transactionFee} -
-
{timeRemaining}
-
-
- ) - } - - renderGasEditRow (gasInputArgs) { - return ( -
-
- { this.context.t(gasInputArgs.labelKey) } - { this.infoButton(() => {}) } -
- { this.gasInput(gasInputArgs) } -
- ) - } - - renderGasEditRows ({ - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit, - insufficientBalance, - customPriceIsSafe, - isSpeedUp, - }) { - return ( -
- { this.renderGasEditRow({ - labelKey: 'gasPrice', - value: customGasPrice, - onChange: updateCustomGasPrice, - insufficientBalance, - customPriceIsSafe, - showGWEI: true, - isSpeedUp, - }) } - { this.renderGasEditRow({ - labelKey: 'gasLimit', - value: customGasLimit, - onChange: this.onChangeGasLimit, - insufficientBalance, - customPriceIsSafe, - }) } -
- ) - } - - render () { - const { t } = this.context - const { - updateCustomGasPrice, - updateCustomGasLimit, - timeRemaining, - customGasPrice, - customGasLimit, - insufficientBalance, - gasChartProps, - gasEstimatesLoading, - customPriceIsSafe, - isSpeedUp, - transactionFee, - } = this.props - - return ( -
- { this.renderDataSummary(transactionFee, timeRemaining) } -
- { this.renderGasEditRows({ - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit, - insufficientBalance, - customPriceIsSafe, - isSpeedUp, - }) } -
{ t('liveGasPricePredictions') }
- {!gasEstimatesLoading - ? - : - } -
- { t('slower') } - { t('faster') } -
-
-
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js deleted file mode 100644 index 492037f25..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './advanced-tab-content.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss deleted file mode 100644 index 53cb84791..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ /dev/null @@ -1,203 +0,0 @@ -@import './time-remaining/index'; - -.advanced-tab { - display: flex; - flex-flow: column; - - &__transaction-data-summary, - &__fee-chart-title { - padding-left: 24px; - padding-right: 24px; - } - - &__transaction-data-summary { - display: flex; - flex-flow: column; - color: $mid-gray; - margin-top: 12px; - padding-left: 18px; - padding-right: 18px; - - &__titles, - &__container { - display: flex; - flex-flow: row; - justify-content: space-between; - font-size: 12px; - color: #888EA3; - } - - &__container { - font-size: 16px; - margin-top: 0px; - } - - &__fee { - font-size: 16px; - color: #313A5E; - } - } - - &__fee-chart { - margin-top: 8px; - height: 265px; - background: #F8F9FB; - border-bottom: 1px solid #d2d8dd; - border-top: 1px solid #d2d8dd; - position: relative; - - &__title { - font-size: 12px; - color: #313A5E; - margin-left: 22px; - } - - &__speed-buttons { - position: absolute; - bottom: 13px; - display: flex; - justify-content: space-between; - padding-left: 20px; - padding-right: 19px; - width: 100%; - font-size: 10px; - color: #888EA3; - } - } - - &__slider-container { - padding-left: 27px; - padding-right: 27px; - } - - &__gas-edit-rows { - height: 73px; - display: flex; - flex-flow: row; - justify-content: space-between; - margin-left: 20px; - margin-right: 10px; - margin-top: 9px; - } - - &__gas-edit-row { - display: flex; - flex-flow: column; - - &__label { - color: #313B5E; - font-size: 14px; - display: flex; - justify-content: space-between; - align-items: center; - - .fa-info-circle { - color: $silver; - margin-left: 10px; - cursor: pointer; - } - - .fa-info-circle:hover { - color: $mid-gray; - } - } - - &__error-text { - font-size: 12px; - color: red; - } - - &__warning-text { - font-size: 12px; - color: orange; - } - - &__input-wrapper { - position: relative; - } - - &__input { - border: 1px solid $dusty-gray; - border-radius: 4px; - color: $mid-gray; - font-size: 16px; - height: 24px; - width: 155px; - padding-left: 8px; - padding-top: 2px; - margin-top: 7px; - } - - &__input--error { - border: 1px solid $red; - } - - &__input--warning { - border: 1px solid $orange; - } - - &__input-arrows { - position: absolute; - top: 7px; - right: 0px; - width: 17px; - height: 24px; - border: 1px solid #dadada; - border-top-right-radius: 4px; - display: flex; - flex-direction: column; - color: #9b9b9b; - font-size: .8em; - border-bottom-right-radius: 4px; - cursor: pointer; - - &__i-wrap { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - cursor: pointer; - } - - &__i-wrap:hover { - background: #4EADE7; - color: $white; - } - - i:hover { - background: #4EADE7; - } - - i { - font-size: 10px; - } - } - - &__input-arrows--error { - border: 1px solid $red; - } - - &__input-arrows--warning { - border: 1px solid $orange; - } - - input[type="number"]::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - input[type="number"]:hover::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - &__gwei-symbol { - position: absolute; - top: 8px; - right: 10px; - color: $dusty-gray; - } - } -} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js deleted file mode 100644 index 2500ee267..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ /dev/null @@ -1,364 +0,0 @@ -import React from 'react' -import assert from 'assert' -import shallow from '../../../../../../lib/shallow-with-context' -import sinon from 'sinon' -import AdvancedTabContent from '../advanced-tab-content.component.js' - -import GasPriceChart from '../../../gas-price-chart' -import Loading from '../../../../loading-screen' - -const propsMethodSpies = { - updateCustomGasPrice: sinon.spy(), - updateCustomGasLimit: sinon.spy(), -} - -sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') -sinon.spy(AdvancedTabContent.prototype, 'gasInput') -sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRows') -sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') -sinon.spy(AdvancedTabContent.prototype, 'gasInputError') - -describe('AdvancedTabContent Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) - }) - - afterEach(() => { - propsMethodSpies.updateCustomGasPrice.resetHistory() - propsMethodSpies.updateCustomGasLimit.resetHistory() - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - AdvancedTabContent.prototype.gasInput.resetHistory() - AdvancedTabContent.prototype.renderGasEditRows.resetHistory() - AdvancedTabContent.prototype.renderDataSummary.resetHistory() - }) - - describe('render()', () => { - it('should render the advanced-tab root node', () => { - assert(wrapper.hasClass('advanced-tab')) - }) - - it('should render the expected four children of the advanced-tab div', () => { - const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) - - assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) - assert(feeChartDiv.childAt(1).hasClass('advanced-tab__fee-chart__title')) - assert(feeChartDiv.childAt(2).is(GasPriceChart)) - assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons')) - }) - - it('should render a loading component instead of the chart if gasEstimatesLoading is true', () => { - wrapper.setProps({ gasEstimatesLoading: true }) - const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) - - assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) - assert(feeChartDiv.childAt(1).hasClass('advanced-tab__fee-chart__title')) - assert(feeChartDiv.childAt(2).is(Loading)) - assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons')) - }) - - it('should call renderDataSummary with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) - const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args - assert.deepEqual(renderDataSummaryArgs, ['$0.25', 21500]) - }) - - it('should call renderGasEditRows with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) - const renderGasEditRowArgs = AdvancedTabContent.prototype.renderGasEditRows.getCall(0).args - assert.deepEqual(renderGasEditRowArgs, [{ - customGasPrice: 11, - customGasLimit: 23456, - insufficientBalance: false, - customPriceIsSafe: true, - updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, - updateCustomGasLimit: propsMethodSpies.updateCustomGasLimit, - isSpeedUp: false, - }]) - }) - }) - - describe('renderDataSummary()', () => { - let dataSummary - - beforeEach(() => { - dataSummary = shallow(wrapper.instance().renderDataSummary('mockTotalFee', 'mockMsRemaining')) - }) - - it('should render the transaction-data-summary root node', () => { - assert(dataSummary.hasClass('advanced-tab__transaction-data-summary')) - }) - - it('should render titles of the data', () => { - const titlesNode = dataSummary.children().at(0) - assert(titlesNode.hasClass('advanced-tab__transaction-data-summary__titles')) - assert.equal(titlesNode.children().at(0).text(), 'newTransactionFee') - assert.equal(titlesNode.children().at(1).text(), '~transactionTime') - }) - - it('should render the data', () => { - const dataNode = dataSummary.children().at(1) - assert(dataNode.hasClass('advanced-tab__transaction-data-summary__container')) - assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') - assert(dataNode.children().at(1).hasClass('time-remaining')) - assert.equal(dataNode.children().at(1).text(), 'mockMsRemaining') - }) - }) - - describe('renderGasEditRow()', () => { - let gasEditRow - - beforeEach(() => { - AdvancedTabContent.prototype.gasInput.resetHistory() - gasEditRow = shallow(wrapper.instance().renderGasEditRow({ - labelKey: 'mockLabelKey', - someArg: 'argA', - })) - }) - - it('should render the gas-edit-row root node', () => { - assert(gasEditRow.hasClass('advanced-tab__gas-edit-row')) - }) - - it('should render a label and an input', () => { - const gasEditRowChildren = gasEditRow.children() - assert.equal(gasEditRowChildren.length, 2) - assert(gasEditRowChildren.at(0).hasClass('advanced-tab__gas-edit-row__label')) - assert(gasEditRowChildren.at(1).hasClass('advanced-tab__gas-edit-row__input-wrapper')) - }) - - it('should render the label key and info button', () => { - const gasRowLabelChildren = gasEditRow.children().at(0).children() - assert.equal(gasRowLabelChildren.length, 2) - assert(gasRowLabelChildren.at(0), 'mockLabelKey') - assert(gasRowLabelChildren.at(1).hasClass('fa-info-circle')) - }) - - it('should call this.gasInput with the correct args', () => { - const gasInputSpyArgs = AdvancedTabContent.prototype.gasInput.args - assert.deepEqual(gasInputSpyArgs[0], [ { labelKey: 'mockLabelKey', someArg: 'argA' } ]) - }) - }) - - describe('renderGasEditRows()', () => { - let gasEditRows - let tempOnChangeGasLimit - - beforeEach(() => { - tempOnChangeGasLimit = wrapper.instance().onChangeGasLimit - wrapper.instance().onChangeGasLimit = () => 'mockOnChangeGasLimit' - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - gasEditRows = shallow(wrapper.instance().renderGasEditRows( - 'mockGasPrice', - () => 'mockUpdateCustomGasPriceReturn', - 'mockGasLimit', - () => 'mockUpdateCustomGasLimitReturn', - false - )) - }) - - afterEach(() => { - wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit - }) - - it('should render the gas-edit-rows root node', () => { - assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows')) - }) - - it('should render two rows', () => { - const gasEditRowsChildren = gasEditRows.children() - assert.equal(gasEditRowsChildren.length, 2) - assert(gasEditRowsChildren.at(0).hasClass('advanced-tab__gas-edit-row')) - assert(gasEditRowsChildren.at(1).hasClass('advanced-tab__gas-edit-row')) - }) - - it('should call this.renderGasEditRow twice, with the expected args', () => { - const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args - assert.equal(renderGasEditRowSpyArgs.length, 2) - assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [{ - labelKey: 'gasPrice', - value: 'mockGasLimit', - onChange: () => 'mockOnChangeGasLimit', - insufficientBalance: false, - customPriceIsSafe: true, - showGWEI: true, - }].map(String)) - assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [{ - labelKey: 'gasPrice', - value: 'mockGasPrice', - onChange: () => 'mockUpdateCustomGasPriceReturn', - insufficientBalance: false, - customPriceIsSafe: true, - showGWEI: true, - }].map(String)) - }) - }) - - describe('infoButton()', () => { - let infoButton - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - infoButton = shallow(wrapper.instance().infoButton(() => 'mockOnClickReturn')) - }) - - it('should render the i element', () => { - assert(infoButton.hasClass('fa-info-circle')) - }) - - it('should pass the onClick argument to the i tag onClick prop', () => { - assert(infoButton.props().onClick(), 'mockOnClickReturn') - }) - }) - - describe('gasInput()', () => { - let gasInput - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - AdvancedTabContent.prototype.gasInputError.resetHistory() - gasInput = shallow(wrapper.instance().gasInput({ - labelKey: 'gasPrice', - value: 321, - onChange: value => value + 7, - insufficientBalance: false, - showGWEI: true, - customPriceIsSafe: true, - isSpeedUp: false, - })) - }) - - it('should render the input-wrapper root node', () => { - assert(gasInput.hasClass('advanced-tab__gas-edit-row__input-wrapper')) - }) - - it('should render two children, including an input', () => { - assert.equal(gasInput.children().length, 2) - assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) - }) - - it('should call the passed onChange method with the value of the input onChange event', () => { - const inputOnChange = gasInput.find('input').props().onChange - assert.equal(inputOnChange({ target: { value: 8} }), 15) - }) - - it('should have two input arrows', () => { - const upArrow = gasInput.find('.fa-angle-up') - assert.equal(upArrow.length, 1) - const downArrow = gasInput.find('.fa-angle-down') - assert.equal(downArrow.length, 1) - }) - - it('should call onChange with the value incremented decremented when its onchange method is called', () => { - const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0) - assert.equal(upArrow.props().onClick(), 329) - const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1) - assert.equal(downArrow.props().onClick(), 327) - }) - - it('should call gasInputError with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.gasInputError.callCount, 1) - const gasInputErrorArgs = AdvancedTabContent.prototype.gasInputError.getCall(0).args - assert.deepEqual(gasInputErrorArgs, [{ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: true, - value: 321, - isSpeedUp: false, - }]) - }) - }) - - describe('gasInputError()', () => { - let gasInputError - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - gasInputError = wrapper.instance().gasInputError({ - labelKey: '', - insufficientBalance: false, - customPriceIsSafe: true, - isSpeedUp: false, - }) - }) - - it('should return an insufficientBalance error', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: true, - customPriceIsSafe: true, - isSpeedUp: false, - value: 1, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'insufficientBalance', - errorType: 'error', - }) - }) - - it('should return a zero gas on retry error', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: false, - isSpeedUp: true, - value: 0, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'zeroGasPriceOnSpeedUpError', - errorType: 'error', - }) - }) - - it('should return a low gas warning', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: false, - isSpeedUp: false, - value: 1, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'gasPriceExtremelyLow', - errorType: 'warning', - }) - }) - - it('should return isInError false if there is no error', () => { - gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: true, - value: 1, - }) - assert.equal(gasInputError.isInError, false) - }) - }) - -}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js deleted file mode 100644 index 61b681e1a..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './time-remaining.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss deleted file mode 100644 index e2115af7f..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss +++ /dev/null @@ -1,17 +0,0 @@ -.time-remaining { - color: #313A5E; - font-size: 16px; - - .minutes-num, .seconds-num { - font-size: 16px; - } - - .seconds-num { - margin-left: 7px; - font-size: 16px; - } - - .minutes-label, .seconds-label { - font-size: 16px; - } -} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js deleted file mode 100644 index d8490272f..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import assert from 'assert' -import shallow from '../../../../../../../lib/shallow-with-context' -import TimeRemaining from '../time-remaining.component.js' - -describe('TimeRemaining Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow() - }) - - describe('render()', () => { - it('should render the time-remaining root node', () => { - assert(wrapper.hasClass('time-remaining')) - }) - - it('should render minutes and seconds numbers and labels', () => { - const timeRemainingChildren = wrapper.children() - assert.equal(timeRemainingChildren.length, 4) - assert.equal(timeRemainingChildren.at(0).text(), 8) - assert.equal(timeRemainingChildren.at(1).text(), 'minutesShorthand') - assert.equal(timeRemainingChildren.at(2).text(), 15) - assert.equal(timeRemainingChildren.at(3).text(), 'secondsShorthand') - }) - }) - -}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js deleted file mode 100644 index 826d41f9c..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js +++ /dev/null @@ -1,33 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { getTimeBreakdown } from './time-remaining.utils' - -export default class TimeRemaining extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - milliseconds: PropTypes.number, - } - - render () { - const { - milliseconds, - } = this.props - - const { - minutes, - seconds, - } = getTimeBreakdown(milliseconds) - - return ( -
- {minutes} - {this.context.t('minutesShorthand')} - {seconds} - {this.context.t('secondsShorthand')} -
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js deleted file mode 100644 index cf43e0acb..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js +++ /dev/null @@ -1,11 +0,0 @@ -function getTimeBreakdown (milliseconds) { - return { - hours: Math.floor(milliseconds / 3600000), - minutes: Math.floor((milliseconds % 3600000) / 60000), - seconds: Math.floor((milliseconds % 60000) / 1000), - } -} - -module.exports = { - getTimeBreakdown, -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js deleted file mode 100644 index 05b8f700b..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import Loading from '../../../loading-screen' -import GasPriceButtonGroup from '../../gas-price-button-group' - -export default class BasicTabContent extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - gasPriceButtonGroupProps: PropTypes.object, - } - - render () { - const { t } = this.context - const { gasPriceButtonGroupProps } = this.props - - return ( -
-
{ t('estimatedProcessingTimes') }
-
{ t('selectAHigherGasFee') }
- {!gasPriceButtonGroupProps.loading - ? - : - } -
{ t('acceleratingATransaction') }
-
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js deleted file mode 100644 index 078d50fce..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './basic-tab-content.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss deleted file mode 100644 index e34e4e328..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss +++ /dev/null @@ -1,28 +0,0 @@ -.basic-tab-content { - display: flex; - flex-direction: column; - align-items: flex-start; - padding-left: 21px; - height: 324px; - background: #F5F7F8; - border-bottom: 1px solid #d2d8dd; - - &__title { - margin-top: 19px; - font-size: 16px; - color: $black; - } - - &__blurb { - font-size: 12px; - color: $black; - margin-top: 5px; - margin-bottom: 15px; - } - - &__footer-blurb { - font-size: 12px; - color: #979797; - margin-top: 15px; - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js deleted file mode 100644 index 47864fcab..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import assert from 'assert' -import shallow from '../../../../../../lib/shallow-with-context' -import BasicTabContent from '../basic-tab-content.component' - -import GasPriceButtonGroup from '../../../gas-price-button-group/' -import Loading from '../../../../loading-screen' - -const mockGasPriceButtonGroupProps = { - buttonDataLoading: false, - className: 'gas-price-button-group', - gasButtonInfo: [ - { - feeInPrimaryCurrency: '$0.52', - feeInSecondaryCurrency: '0.0048 ETH', - timeEstimate: '~ 1 min 0 sec', - priceInHexWei: '0xa1b2c3f', - }, - { - feeInPrimaryCurrency: '$0.39', - feeInSecondaryCurrency: '0.004 ETH', - timeEstimate: '~ 1 min 30 sec', - priceInHexWei: '0xa1b2c39', - }, - { - feeInPrimaryCurrency: '$0.30', - feeInSecondaryCurrency: '0.00354 ETH', - timeEstimate: '~ 2 min 1 sec', - priceInHexWei: '0xa1b2c30', - }, - ], - handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), - noButtonActiveByDefault: true, - showCheck: true, -} - -describe('BasicTabContent Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow() - }) - - describe('render', () => { - it('should have a title', () => { - assert(wrapper.find('.basic-tab-content').childAt(0).hasClass('basic-tab-content__title')) - }) - - it('should render a GasPriceButtonGroup compenent', () => { - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) - }) - - it('should pass correct props to GasPriceButtonGroup', () => { - const { - buttonDataLoading, - className, - gasButtonInfo, - handleGasPriceSelection, - noButtonActiveByDefault, - showCheck, - } = wrapper.find(GasPriceButtonGroup).props() - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) - assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading) - assert.equal(className, mockGasPriceButtonGroupProps.className) - assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault) - assert.equal(showCheck, mockGasPriceButtonGroupProps.showCheck) - assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo) - assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection)) - }) - - it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', () => { - wrapper.setProps({ - gasPriceButtonGroupProps: { ...mockGasPriceButtonGroupProps, loading: true }, - }) - - assert.equal(wrapper.find(GasPriceButtonGroup).length, 0) - assert.equal(wrapper.find(Loading).length, 1) - }) - }) -}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js deleted file mode 100644 index 174bd8ea8..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ /dev/null @@ -1,186 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import PageContainer from '../../page-container' -import { Tabs, Tab } from '../../tabs' -import AdvancedTabContent from './advanced-tab-content' -import BasicTabContent from './basic-tab-content' - -export default class GasModalPageContainer extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - hideModal: PropTypes.func, - hideBasic: PropTypes.bool, - updateCustomGasPrice: PropTypes.func, - updateCustomGasLimit: PropTypes.func, - customGasPrice: PropTypes.number, - customGasLimit: PropTypes.number, - fetchBasicGasAndTimeEstimates: PropTypes.func, - fetchGasEstimates: PropTypes.func, - gasPriceButtonGroupProps: PropTypes.object, - infoRowProps: PropTypes.shape({ - originalTotalFiat: PropTypes.string, - originalTotalEth: PropTypes.string, - newTotalFiat: PropTypes.string, - newTotalEth: PropTypes.string, - }), - onSubmit: PropTypes.func, - customModalGasPriceInHex: PropTypes.string, - customModalGasLimitInHex: PropTypes.string, - cancelAndClose: PropTypes.func, - transactionFee: PropTypes.string, - blockTime: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, - ]), - customPriceIsSafe: PropTypes.bool, - isSpeedUp: PropTypes.bool, - disableSave: PropTypes.bool, - } - - state = {} - - componentDidMount () { - const promise = this.props.hideBasic - ? Promise.resolve(this.props.blockTime) - : this.props.fetchBasicGasAndTimeEstimates() - .then(basicEstimates => basicEstimates.blockTime) - - promise - .then(blockTime => { - this.props.fetchGasEstimates(blockTime) - }) - } - - renderBasicTabContent (gasPriceButtonGroupProps) { - return ( - - ) - } - - renderAdvancedTabContent ({ - convertThenUpdateCustomGasPrice, - convertThenUpdateCustomGasLimit, - customGasPrice, - customGasLimit, - newTotalFiat, - gasChartProps, - currentTimeEstimate, - insufficientBalance, - gasEstimatesLoading, - customPriceIsSafe, - isSpeedUp, - transactionFee, - }) { - return ( - - ) - } - - renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { - return ( -
-
-
- {this.context.t('sendAmount')} - {sendAmount} -
-
- {this.context.t('transactionFee')} - {transactionFee} -
-
- {this.context.t('newTotal')} - {newTotalEth} -
-
- {newTotalFiat} -
-
-
- ) - } - - renderTabs ({ - originalTotalFiat, - originalTotalEth, - newTotalFiat, - newTotalEth, - sendAmount, - transactionFee, - }, - { - gasPriceButtonGroupProps, - hideBasic, - ...advancedTabProps - }) { - let tabsToRender = [ - { name: 'basic', content: this.renderBasicTabContent(gasPriceButtonGroupProps) }, - { name: 'advanced', content: this.renderAdvancedTabContent({ transactionFee, ...advancedTabProps }) }, - ] - - if (hideBasic) { - tabsToRender = tabsToRender.slice(1) - } - - return ( - - {tabsToRender.map(({ name, content }, i) => -
- { content } - { this.renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) } -
-
- )} -
- ) - } - - render () { - const { - cancelAndClose, - infoRowProps, - onSubmit, - customModalGasPriceInHex, - customModalGasLimitInHex, - disableSave, - ...tabProps - } = this.props - - return ( -
- cancelAndClose()} - onClose={() => cancelAndClose()} - onSubmit={() => { - onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) - }} - submitText={this.context.t('save')} - headerCloseText={'Close'} - hideCancel={true} - /> -
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js deleted file mode 100644 index 6692fb363..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ /dev/null @@ -1,291 +0,0 @@ -import { connect } from 'react-redux' -import { pipe, partialRight } from 'ramda' -import GasModalPageContainer from './gas-modal-page-container.component' -import { - hideModal, - setGasLimit, - setGasPrice, - createSpeedUpTransaction, - hideSidebar, -} from '../../../actions' -import { - setCustomGasPrice, - setCustomGasLimit, - resetCustomData, - setCustomTimeEstimate, - fetchGasEstimates, - fetchBasicGasAndTimeEstimates, -} from '../../../ducks/gas.duck' -import { - hideGasButtonGroup, -} from '../../../ducks/send.duck' -import { - updateGasAndCalculate, -} from '../../../ducks/confirm-transaction.duck' -import { - getCurrentCurrency, - conversionRateSelector as getConversionRate, - getSelectedToken, - getCurrentEthBalance, -} from '../../../selectors.js' -import { - formatTimeEstimate, - getFastPriceEstimateInHexWEI, - getBasicGasEstimateLoadingStatus, - getGasEstimatesLoadingStatus, - getCustomGasLimit, - getCustomGasPrice, - getDefaultActiveButtonIndex, - getEstimatedGasPrices, - getEstimatedGasTimes, - getRenderableBasicEstimateData, - getBasicGasEstimateBlockTime, - isCustomPriceSafe, -} from '../../../selectors/custom-gas' -import { - submittedPendingTransactionsSelector, -} from '../../../selectors/transactions' -import { - formatCurrency, -} from '../../../helpers/confirm-transaction/util' -import { - addHexWEIsToDec, - decEthToConvertedCurrency as ethTotalToConvertedCurrency, - decGWEIToHexWEI, - hexWEIToDecGWEI, -} from '../../../helpers/conversions.util' -import { - formatETHFee, -} from '../../../helpers/formatters' -import { - calcGasTotal, - isBalanceSufficient, -} from '../../send/send.utils' -import { addHexPrefix } from 'ethereumjs-util' -import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price-chart.utils' -import {getIsMainnet, preferencesSelector} from '../../../selectors' - -const mapStateToProps = (state, ownProps) => { - const { transaction = {} } = ownProps - const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) - - const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id) - const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice - const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit - const gasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex) - - const customGasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex) - - const gasButtonInfo = getRenderableBasicEstimateData(state, customModalGasLimitInHex) - - const currentCurrency = getCurrentCurrency(state) - const conversionRate = getConversionRate(state) - - const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) - - const hideBasic = state.appState.modal.modalState.props.hideBasic - - const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex) - - const gasPrices = getEstimatedGasPrices(state) - const estimatedTimes = getEstimatedGasTimes(state) - const balance = getCurrentEthBalance(state) - - const { showFiatInTestnets } = preferencesSelector(state) - const isMainnet = getIsMainnet(state) - const showFiat = Boolean(isMainnet || showFiatInTestnets) - - const insufficientBalance = !isBalanceSufficient({ - amount: value, - gasTotal, - balance, - conversionRate, - }) - - return { - hideBasic, - isConfirm: isConfirm(state), - customModalGasPriceInHex, - customModalGasLimitInHex, - customGasPrice, - customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), - newTotalFiat, - currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, gasPrices, estimatedTimes), - blockTime: getBasicGasEstimateBlockTime(state), - customPriceIsSafe: isCustomPriceSafe(state), - gasPriceButtonGroupProps: { - buttonDataLoading, - defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), - gasButtonInfo, - }, - gasChartProps: { - currentPrice: customGasPrice, - gasPrices, - estimatedTimes, - gasPricesMax: gasPrices[gasPrices.length - 1], - estimatedTimesMax: estimatedTimes[0], - }, - infoRowProps: { - originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), - originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), - newTotalFiat: showFiat ? newTotalFiat : '', - newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), - transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), - sendAmount: addHexWEIsToRenderableEth(value, '0x0'), - }, - isSpeedUp: transaction.status === 'submitted', - txId: transaction.id, - insufficientBalance, - gasEstimatesLoading, - } -} - -const mapDispatchToProps = dispatch => { - const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice))) - - return { - cancelAndClose: () => { - dispatch(resetCustomData()) - dispatch(hideModal()) - }, - hideModal: () => dispatch(hideModal()), - updateCustomGasPrice, - convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), - convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), - setGasData: (newLimit, newPrice) => { - dispatch(setGasLimit(newLimit)) - dispatch(setGasPrice(newPrice)) - }, - updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { - updateCustomGasPrice(gasPrice) - dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))) - return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) - }, - createSpeedUpTransaction: (txId, gasPrice) => { - return dispatch(createSpeedUpTransaction(txId, gasPrice)) - }, - hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), - setCustomTimeEstimate: (timeEstimateInSeconds) => dispatch(setCustomTimeEstimate(timeEstimateInSeconds)), - hideSidebar: () => dispatch(hideSidebar()), - fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), - fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), - } -} - -const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { gasPriceButtonGroupProps, isConfirm, txId, isSpeedUp, insufficientBalance, customGasPrice } = stateProps - const { - updateCustomGasPrice: dispatchUpdateCustomGasPrice, - hideGasButtonGroup: dispatchHideGasButtonGroup, - setGasData: dispatchSetGasData, - updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, - createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, - hideSidebar: dispatchHideSidebar, - cancelAndClose: dispatchCancelAndClose, - hideModal: dispatchHideModal, - ...otherDispatchProps - } = dispatchProps - - return { - ...stateProps, - ...otherDispatchProps, - ...ownProps, - onSubmit: (gasLimit, gasPrice) => { - if (isConfirm) { - dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice) - dispatchHideModal() - } else if (isSpeedUp) { - dispatchCreateSpeedUpTransaction(txId, gasPrice) - dispatchHideSidebar() - dispatchCancelAndClose() - } else { - dispatchSetGasData(gasLimit, gasPrice) - dispatchHideGasButtonGroup() - dispatchCancelAndClose() - } - }, - gasPriceButtonGroupProps: { - ...gasPriceButtonGroupProps, - handleGasPriceSelection: dispatchUpdateCustomGasPrice, - }, - cancelAndClose: () => { - dispatchCancelAndClose() - if (isSpeedUp) { - dispatchHideSidebar() - } - }, - disableSave: insufficientBalance || (isSpeedUp && customGasPrice === 0), - } -} - -export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(GasModalPageContainer) - -function isConfirm (state) { - return Boolean(Object.keys(state.confirmTransaction.txData).length) -} - -function calcCustomGasPrice (customGasPriceInHex) { - return Number(hexWEIToDecGWEI(customGasPriceInHex)) -} - -function calcCustomGasLimit (customGasLimitInHex) { - return parseInt(customGasLimitInHex, 16) -} - -function getTxParams (state, transactionId) { - const { confirmTransaction: { txData }, metamask: { send } } = state - const pendingTransactions = submittedPendingTransactionsSelector(state) - const pendingTransaction = pendingTransactions.find(({ id }) => id === transactionId) - const { txParams: pendingTxParams } = pendingTransaction || {} - return txData.txParams || pendingTxParams || { - from: send.from, - gas: send.gasLimit || '0x5208', - gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), - to: send.to, - value: getSelectedToken(state) ? '0x0' : send.amount, - } -} - -function addHexWEIsToRenderableEth (aHexWEI, bHexWEI) { - return pipe( - addHexWEIsToDec, - formatETHFee - )(aHexWEI, bHexWEI) -} - -function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conversionRate) { - return pipe( - addHexWEIsToDec, - partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), - partialRight(formatCurrency, [convertedCurrency]), - )(aHexWEI, bHexWEI) -} - -function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) { - const minGasPrice = gasPrices[0] - const maxGasPrice = gasPrices[gasPrices.length - 1] - let priceForEstimation = currentGasPrice - if (currentGasPrice < minGasPrice) { - priceForEstimation = minGasPrice - } else if (currentGasPrice > maxGasPrice) { - priceForEstimation = maxGasPrice - } - - const { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue, - closestLowerValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation }) - - const newTimeEstimate = extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: priceForEstimation, - }) - - return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice) -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.js b/ui/app/components/gas-customization/gas-modal-page-container/index.js deleted file mode 100644 index ec0ebad22..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-modal-page-container.container' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss deleted file mode 100644 index b9e0f59c4..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ /dev/null @@ -1,146 +0,0 @@ -@import './advanced-tab-content/index'; -@import './basic-tab-content/index'; - -.gas-modal-page-container { - .page-container { - max-width: 391px; - min-height: 585px; - overflow-y: initial; - - @media screen and (max-width: $break-small) { - &__content { - display: flex; - overflow-y: initial; - } - } - - &__header { - padding: 0px; - padding-top: 16px; - - &--no-padding-bottom { - padding-bottom: 0; - } - } - - &__footer { - header { - padding-top: 12px; - padding-bottom: 12px; - } - } - - &__header-close-text { - font-size: 14px; - color: #4EADE7; - position: absolute; - top: 16px; - right: 16px; - cursor: pointer; - overflow: hidden; - } - - &__title { - color: $black; - font-size: 16px; - font-weight: 500; - line-height: 16px; - display: flex; - justify-content: center; - align-items: flex-start; - margin-right: 0; - } - - &__subtitle { - display: none; - } - - &__tabs { - margin-top: 0px; - } - - &__tab { - width: 100%; - font-size: 14px; - - &:last-of-type { - margin-right: 0; - } - - &--selected { - color: $curious-blue; - border-bottom: 2px solid $curious-blue; - } - } - } -} - -.gas-modal-content { - @media screen and (max-width: $break-small) { - width: 100%; - } - - &__basic-tab { - height: 219px; - } - - - &__info-row, &__info-row--fade { - width: 100%; - background: $polar; - padding: 15px 21px; - display: flex; - flex-flow: column; - color: $scorpion; - font-size: 12px; - - @media screen and (max-width: $break-small) { - padding: 4px 21px; - } - - &__send-info, &__transaction-info, &__total-info, &__fiat-total-info { - display: flex; - flex-flow: row; - justify-content: space-between; - } - - &__fiat-total-info { - justify-content: flex-end; - } - - &__total-info { - &__label { - font-size: 16px; - - @media screen and (max-width: $break-small) { - font-size: 14px; - } - } - - &__value { - font-size: 16px; - font-weight: bold; - - @media screen and (max-width: $break-small) { - font-size: 14px; - } - } - } - - &__transaction-info, &__send-info { - &__label { - font-size: 12px; - } - - &__value { - font-size: 14px; - } - } - } - - &__info-row--fade { - background: white; - color: $dusty-gray; - border-top: 1px solid $mischka; - } -} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js deleted file mode 100644 index 1761ad2b0..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ /dev/null @@ -1,274 +0,0 @@ -import React from 'react' -import assert from 'assert' -import shallow from '../../../../../lib/shallow-with-context' -import sinon from 'sinon' -import GasModalPageContainer from '../gas-modal-page-container.component.js' -import timeout from '../../../../../lib/test-timeout' - -import PageContainer from '../../../page-container' - -import { Tab } from '../../../tabs' - -const mockBasicGasEstimates = { - blockTime: 'mockBlockTime', -} - -const propsMethodSpies = { - cancelAndClose: sinon.spy(), - onSubmit: sinon.spy(), - fetchBasicGasAndTimeEstimates: sinon.stub().returns(Promise.resolve(mockBasicGasEstimates)), - fetchGasEstimates: sinon.spy(), -} - -const mockGasPriceButtonGroupProps = { - buttonDataLoading: false, - className: 'gas-price-button-group', - gasButtonInfo: [ - { - feeInPrimaryCurrency: '$0.52', - feeInSecondaryCurrency: '0.0048 ETH', - timeEstimate: '~ 1 min 0 sec', - priceInHexWei: '0xa1b2c3f', - }, - { - feeInPrimaryCurrency: '$0.39', - feeInSecondaryCurrency: '0.004 ETH', - timeEstimate: '~ 1 min 30 sec', - priceInHexWei: '0xa1b2c39', - }, - { - feeInPrimaryCurrency: '$0.30', - feeInSecondaryCurrency: '0.00354 ETH', - timeEstimate: '~ 2 min 1 sec', - priceInHexWei: '0xa1b2c30', - }, - ], - handleGasPriceSelection: 'mockSelectionFunction', - noButtonActiveByDefault: true, - showCheck: true, - newTotalFiat: 'mockNewTotalFiat', - newTotalEth: 'mockNewTotalEth', -} -const mockInfoRowProps = { - originalTotalFiat: 'mockOriginalTotalFiat', - originalTotalEth: 'mockOriginalTotalEth', - newTotalFiat: 'mockNewTotalFiat', - newTotalEth: 'mockNewTotalEth', - sendAmount: 'mockSendAmount', - transactionFee: 'mockTransactionFee', -} - -const GP = GasModalPageContainer.prototype -describe('GasModalPageContainer Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow( 'mockupdateCustomGasPrice'} - updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} - customGasPrice={21} - customGasLimit={54321} - gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} - infoRowProps={mockInfoRowProps} - currentTimeEstimate={'1 min 31 sec'} - customGasPriceInHex={'mockCustomGasPriceInHex'} - customGasLimitInHex={'mockCustomGasLimitInHex'} - insufficientBalance={false} - disableSave={false} - />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) - }) - - afterEach(() => { - propsMethodSpies.cancelAndClose.resetHistory() - }) - - describe('componentDidMount', () => { - it('should call props.fetchBasicGasAndTimeEstimates', () => { - propsMethodSpies.fetchBasicGasAndTimeEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 0) - wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 1) - }) - - it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasAndTimeEstimates', async () => { - propsMethodSpies.fetchGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - await timeout(250) - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) - assert.equal(propsMethodSpies.fetchGasEstimates.getCall(0).args[0], 'mockBlockTime') - }) - }) - - describe('render', () => { - it('should render a PageContainer compenent', () => { - assert.equal(wrapper.find(PageContainer).length, 1) - }) - - it('should pass correct props to PageContainer', () => { - const { - title, - subtitle, - disabled, - } = wrapper.find(PageContainer).props() - assert.equal(title, 'customGas') - assert.equal(subtitle, 'customGasSubTitle') - assert.equal(disabled, false) - }) - - it('should pass the correct onCancel and onClose methods to PageContainer', () => { - const { - onCancel, - onClose, - } = wrapper.find(PageContainer).props() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 0) - onCancel() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 1) - onClose() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 2) - }) - - it('should pass the correct renderTabs property to PageContainer', () => { - sinon.stub(GP, 'renderTabs').returns('mockTabs') - const renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) - const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props() - assert.equal(tabsComponent, 'mockTabs') - GasModalPageContainer.prototype.renderTabs.restore() - }) - }) - - describe('renderTabs', () => { - beforeEach(() => { - sinon.spy(GP, 'renderBasicTabContent') - sinon.spy(GP, 'renderAdvancedTabContent') - sinon.spy(GP, 'renderInfoRows') - }) - - afterEach(() => { - GP.renderBasicTabContent.restore() - GP.renderAdvancedTabContent.restore() - GP.renderInfoRows.restore() - }) - - it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { - const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, - otherProps: 'mockAdvancedTabProps', - }) - const renderedTabs = shallow(renderTabsResult) - assert.equal(renderedTabs.props().className, 'tabs') - - const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 2) - - assert.equal(tabs.at(0).props().name, 'basic') - assert.equal(tabs.at(1).props().name, 'advanced') - - assert.equal(tabs.at(0).childAt(0).props().className, 'gas-modal-content') - assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') - }) - - it('should call renderBasicTabContent and renderAdvancedTabContent with the expected props', () => { - assert.equal(GP.renderBasicTabContent.callCount, 0) - assert.equal(GP.renderAdvancedTabContent.callCount, 0) - - wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - - assert.equal(GP.renderBasicTabContent.callCount, 1) - assert.equal(GP.renderAdvancedTabContent.callCount, 1) - - assert.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps) - assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { transactionFee: 'mockTransactionFee', otherProps: 'mockAdvancedTabProps' }) - }) - - it('should call renderInfoRows with the expected props', () => { - assert.equal(GP.renderInfoRows.callCount, 0) - - wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - - assert.equal(GP.renderInfoRows.callCount, 2) - - assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee']) - assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee']) - }) - - it('should not render the basic tab if hideBasic is true', () => { - const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, - otherProps: 'mockAdvancedTabProps', - hideBasic: true, - }) - - const renderedTabs = shallow(renderTabsResult) - const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 1) - assert.equal(tabs.at(0).props().name, 'advanced') - }) - }) - - describe('renderBasicTabContent', () => { - it('should render', () => { - const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps) - - assert.deepEqual( - renderBasicTabContentResult.props.gasPriceButtonGroupProps, - mockGasPriceButtonGroupProps - ) - }) - }) - - describe('renderAdvancedTabContent', () => { - it('should render with the correct props', () => { - const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent({ - convertThenUpdateCustomGasPrice: () => 'mockConvertThenUpdateCustomGasPrice', - convertThenUpdateCustomGasLimit: () => 'mockConvertThenUpdateCustomGasLimit', - customGasPrice: 123, - customGasLimit: 456, - newTotalFiat: '$0.30', - currentTimeEstimate: '1 min 31 sec', - gasEstimatesLoading: 'mockGasEstimatesLoading', - }) - const advancedTabContentProps = renderAdvancedTabContentResult.props - assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') - assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') - assert.equal(advancedTabContentProps.customGasPrice, 123) - assert.equal(advancedTabContentProps.customGasLimit, 456) - assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') - assert.equal(advancedTabContentProps.totalFee, '$0.30') - assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading') - }) - }) - - describe('renderInfoRows', () => { - it('should render the info rows with the passed data', () => { - const baseClassName = 'gas-modal-content__info-row' - const renderedInfoRowsContainer = shallow(wrapper.instance().renderInfoRows( - 'mockNewTotalFiat', - ' mockNewTotalEth', - ' mockSendAmount', - ' mockTransactionFee' - )) - - assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)) - - const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children() - assert.equal(renderedInfoRows.length, 4) - assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)) - assert(renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`)) - assert(renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`)) - assert(renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`)) - - assert.equal(renderedInfoRows.at(0).text(), 'sendAmount mockSendAmount') - assert.equal(renderedInfoRows.at(1).text(), 'transactionFee mockTransactionFee') - assert.equal(renderedInfoRows.at(2).text(), 'newTotal mockNewTotalEth') - assert.equal(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') - }) - }) -}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js deleted file mode 100644 index fb6a01fff..000000000 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ /dev/null @@ -1,425 +0,0 @@ -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' - -let mapStateToProps -let mapDispatchToProps -let mergeProps - -const actionSpies = { - hideModal: sinon.spy(), - setGasLimit: sinon.spy(), - setGasPrice: sinon.spy(), -} - -const gasActionSpies = { - setCustomGasPrice: sinon.spy(), - setCustomGasLimit: sinon.spy(), - resetCustomData: sinon.spy(), -} - -const confirmTransactionActionSpies = { - updateGasAndCalculate: sinon.spy(), -} - -const sendActionSpies = { - hideGasButtonGroup: sinon.spy(), -} - -proxyquire('../gas-modal-page-container.container.js', { - 'react-redux': { - connect: (ms, md, mp) => { - mapStateToProps = ms - mapDispatchToProps = md - mergeProps = mp - return () => ({}) - }, - }, - '../../../selectors/custom-gas': { - getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, - getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`, - getDefaultActiveButtonIndex: (a, b) => a + b, - }, - '../../../actions': actionSpies, - '../../../ducks/gas.duck': gasActionSpies, - '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, - '../../../ducks/send.duck': sendActionSpies, - '../../../selectors.js': { - getCurrentEthBalance: (state) => state.metamask.balance || '0x0', - }, -}) - -describe('gas-modal-page-container container', () => { - - describe('mapStateToProps()', () => { - it('should map the correct properties to props', () => { - const baseMockState = { - appState: { - modal: { - modalState: { - props: { - hideBasic: true, - }, - }, - }, - }, - metamask: { - send: { - gasLimit: '16', - gasPrice: '32', - amount: '64', - }, - currentCurrency: 'abc', - conversionRate: 50, - preferences: { - showFiatInTestnets: false, - }, - provider: { - type: 'mainnet', - }, - }, - gas: { - basicEstimates: { - blockTime: 12, - safeLow: 2, - }, - customData: { - limit: 'aaaaaaaa', - price: 'ffffffff', - }, - gasEstimatesLoading: false, - priceAndTimeEstimates: [ - { gasprice: 3, expectedTime: 31 }, - { gasprice: 4, expectedTime: 62 }, - { gasprice: 5, expectedTime: 93 }, - { gasprice: 6, expectedTime: 124 }, - ], - }, - confirmTransaction: { - txData: { - txParams: { - gas: '0x1600000', - gasPrice: '0x3200000', - value: '0x640000000000000', - }, - }, - }, - } - const baseExpectedResult = { - isConfirm: true, - customGasPrice: 4.294967295, - customGasLimit: 2863311530, - currentTimeEstimate: '~1 min 11 sec', - newTotalFiat: '637.41', - blockTime: 12, - customModalGasLimitInHex: 'aaaaaaaa', - customModalGasPriceInHex: 'ffffffff', - customPriceIsSafe: true, - gasChartProps: { - 'currentPrice': 4.294967295, - estimatedTimes: [31, 62, 93, 124], - estimatedTimesMax: '31', - gasPrices: [3, 4, 5, 6], - gasPricesMax: 6, - }, - gasPriceButtonGroupProps: { - buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', - gasButtonInfo: 'mockRenderableBasicEstimateData:4', - }, - gasEstimatesLoading: false, - hideBasic: true, - infoRowProps: { - originalTotalFiat: '637.41', - originalTotalEth: '12.748189 ETH', - newTotalFiat: '637.41', - newTotalEth: '12.748189 ETH', - sendAmount: '0.45036 ETH', - transactionFee: '12.297829 ETH', - }, - insufficientBalance: true, - isSpeedUp: false, - txId: 34, - } - const baseMockOwnProps = { transaction: { id: 34 } } - const tests = [ - { mockState: baseMockState, expectedResult: baseExpectedResult, mockOwnProps: baseMockOwnProps }, - { - mockState: Object.assign({}, baseMockState, { - metamask: { ...baseMockState.metamask, balance: '0xfffffffffffffffffffff' }, - }), - expectedResult: Object.assign({}, baseExpectedResult, { insufficientBalance: false }), - mockOwnProps: baseMockOwnProps, - }, - { - mockState: baseMockState, - mockOwnProps: Object.assign({}, baseMockOwnProps, { - transaction: { id: 34, status: 'submitted' }, - }), - expectedResult: Object.assign({}, baseExpectedResult, { isSpeedUp: true }), - }, - { - mockState: Object.assign({}, baseMockState, { - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: false, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'rinkeby', - }, - }, - }), - mockOwnProps: baseMockOwnProps, - expectedResult: { - ...baseExpectedResult, - infoRowProps: { - ...baseExpectedResult.infoRowProps, - newTotalFiat: '', - }, - }, - }, - { - mockState: Object.assign({}, baseMockState, { - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: true, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'rinkeby', - }, - }, - }), - mockOwnProps: baseMockOwnProps, - expectedResult: baseExpectedResult, - }, - { - mockState: Object.assign({}, baseMockState, { - metamask: { - ...baseMockState.metamask, - preferences: { - ...baseMockState.metamask.preferences, - showFiatInTestnets: true, - }, - provider: { - ...baseMockState.metamask.provider, - type: 'mainnet', - }, - }, - }), - mockOwnProps: baseMockOwnProps, - expectedResult: baseExpectedResult, - }, - ] - - let result - tests.forEach(({ mockState, mockOwnProps, expectedResult}) => { - result = mapStateToProps(mockState, mockOwnProps) - assert.deepEqual(result, expectedResult) - }) - }) - - }) - - describe('mapDispatchToProps()', () => { - let dispatchSpy - let mapDispatchToPropsObject - - beforeEach(() => { - dispatchSpy = sinon.spy() - mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) - }) - - afterEach(() => { - actionSpies.hideModal.resetHistory() - gasActionSpies.setCustomGasPrice.resetHistory() - gasActionSpies.setCustomGasLimit.resetHistory() - }) - - describe('hideGasButtonGroup()', () => { - it('should dispatch a hideGasButtonGroup action', () => { - mapDispatchToPropsObject.hideGasButtonGroup() - assert(dispatchSpy.calledOnce) - assert(sendActionSpies.hideGasButtonGroup.calledOnce) - }) - }) - - describe('cancelAndClose()', () => { - it('should dispatch a hideModal action', () => { - mapDispatchToPropsObject.cancelAndClose() - assert(dispatchSpy.calledTwice) - assert(actionSpies.hideModal.calledOnce) - assert(gasActionSpies.resetCustomData.calledOnce) - }) - }) - - describe('updateCustomGasPrice()', () => { - it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => { - mapDispatchToPropsObject.updateCustomGasPrice('ffff') - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasPrice.calledOnce) - assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff') - }) - }) - - describe('convertThenUpdateCustomGasPrice()', () => { - it('should dispatch a setCustomGasPrice action with the arg passed to convertThenUpdateCustomGasPrice converted to WEI', () => { - mapDispatchToPropsObject.convertThenUpdateCustomGasPrice('0xffff') - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasPrice.calledOnce) - assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0x3b9a8e653600') - }) - }) - - - describe('convertThenUpdateCustomGasLimit()', () => { - it('should dispatch a setCustomGasLimit action with the arg passed to convertThenUpdateCustomGasLimit converted to hex', () => { - mapDispatchToPropsObject.convertThenUpdateCustomGasLimit(16) - assert(dispatchSpy.calledOnce) - assert(gasActionSpies.setCustomGasLimit.calledOnce) - assert.equal(gasActionSpies.setCustomGasLimit.getCall(0).args[0], '0x10') - }) - }) - - describe('setGasData()', () => { - it('should dispatch a setGasPrice and setGasLimit action with the correct props', () => { - mapDispatchToPropsObject.setGasData('ffff', 'aaaa') - assert(dispatchSpy.calledTwice) - assert(actionSpies.setGasPrice.calledOnce) - assert(actionSpies.setGasLimit.calledOnce) - assert.equal(actionSpies.setGasLimit.getCall(0).args[0], 'ffff') - assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa') - }) - }) - - describe('updateConfirmTxGasAndCalculate()', () => { - it('should dispatch a updateGasAndCalculate action with the correct props', () => { - mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') - assert.equal(dispatchSpy.callCount, 3) - assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) - assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) - }) - }) - - }) - - describe('mergeProps', () => { - let stateProps - let dispatchProps - let ownProps - - beforeEach(() => { - stateProps = { - gasPriceButtonGroupProps: { - someGasPriceButtonGroupProp: 'foo', - anotherGasPriceButtonGroupProp: 'bar', - }, - isConfirm: true, - someOtherStateProp: 'baz', - } - dispatchProps = { - updateCustomGasPrice: sinon.spy(), - hideGasButtonGroup: sinon.spy(), - setGasData: sinon.spy(), - updateConfirmTxGasAndCalculate: sinon.spy(), - someOtherDispatchProp: sinon.spy(), - createSpeedUpTransaction: sinon.spy(), - hideSidebar: sinon.spy(), - hideModal: sinon.spy(), - cancelAndClose: sinon.spy(), - } - ownProps = { someOwnProp: 123 } - }) - - afterEach(() => { - dispatchProps.updateCustomGasPrice.resetHistory() - dispatchProps.hideGasButtonGroup.resetHistory() - dispatchProps.setGasData.resetHistory() - dispatchProps.updateConfirmTxGasAndCalculate.resetHistory() - dispatchProps.someOtherDispatchProp.resetHistory() - dispatchProps.createSpeedUpTransaction.resetHistory() - dispatchProps.hideSidebar.resetHistory() - dispatchProps.hideModal.resetHistory() - }) - it('should return the expected props when isConfirm is true', () => { - const result = mergeProps(stateProps, dispatchProps, ownProps) - - assert.equal(result.isConfirm, true) - assert.equal(result.someOtherStateProp, 'baz') - assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') - assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') - assert.equal(result.someOwnProp, 123) - - assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) - assert.equal(dispatchProps.setGasData.callCount, 0) - assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.equal(dispatchProps.hideModal.callCount, 0) - - result.onSubmit() - - assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1) - assert.equal(dispatchProps.setGasData.callCount, 0) - assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.equal(dispatchProps.hideModal.callCount, 1) - - assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) - result.gasPriceButtonGroupProps.handleGasPriceSelection() - assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) - - assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) - result.someOtherDispatchProp() - assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) - }) - - it('should return the expected props when isConfirm is false', () => { - const result = mergeProps(Object.assign({}, stateProps, { isConfirm: false }), dispatchProps, ownProps) - - assert.equal(result.isConfirm, false) - assert.equal(result.someOtherStateProp, 'baz') - assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') - assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') - assert.equal(result.someOwnProp, 123) - - assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) - assert.equal(dispatchProps.setGasData.callCount, 0) - assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.equal(dispatchProps.cancelAndClose.callCount, 0) - - result.onSubmit('mockNewLimit', 'mockNewPrice') - - assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) - assert.equal(dispatchProps.setGasData.callCount, 1) - assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice']) - assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1) - assert.equal(dispatchProps.cancelAndClose.callCount, 1) - - assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) - result.gasPriceButtonGroupProps.handleGasPriceSelection() - assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) - - assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) - result.someOtherDispatchProp() - assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) - }) - - it('should dispatch the expected actions from obSubmit when isConfirm is false and isSpeedUp is true', () => { - const result = mergeProps(Object.assign({}, stateProps, { isSpeedUp: true, isConfirm: false }), dispatchProps, ownProps) - - result.onSubmit() - - assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) - assert.equal(dispatchProps.setGasData.callCount, 0) - assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) - assert.equal(dispatchProps.cancelAndClose.callCount, 1) - - assert.equal(dispatchProps.createSpeedUpTransaction.callCount, 1) - assert.equal(dispatchProps.hideSidebar.callCount, 1) - }) - }) - -}) diff --git a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js deleted file mode 100644 index 8ad063b21..000000000 --- a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ /dev/null @@ -1,89 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import ButtonGroup from '../../button-group' -import Button from '../../button' - -const GAS_OBJECT_PROPTYPES_SHAPE = { - label: PropTypes.string, - feeInPrimaryCurrency: PropTypes.string, - feeInSecondaryCurrency: PropTypes.string, - timeEstimate: PropTypes.string, - priceInHexWei: PropTypes.string, -} - -export default class GasPriceButtonGroup extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - buttonDataLoading: PropTypes.bool, - className: PropTypes.string, - defaultActiveButtonIndex: PropTypes.number, - gasButtonInfo: PropTypes.arrayOf(PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE)), - handleGasPriceSelection: PropTypes.func, - newActiveButtonIndex: PropTypes.number, - noButtonActiveByDefault: PropTypes.bool, - showCheck: PropTypes.bool, - } - - renderButtonContent ({ - labelKey, - feeInPrimaryCurrency, - feeInSecondaryCurrency, - timeEstimate, - }, { - className, - showCheck, - }) { - return (
- { labelKey &&
{ this.context.t(labelKey) }
} - { timeEstimate &&
{ timeEstimate }
} - { feeInPrimaryCurrency &&
{ feeInPrimaryCurrency }
} - { feeInSecondaryCurrency &&
{ feeInSecondaryCurrency }
} - { showCheck &&
} -
) - } - - renderButton ({ - priceInHexWei, - ...renderableGasInfo - }, { - buttonDataLoading, - handleGasPriceSelection, - ...buttonContentPropsAndFlags - }, index) { - return ( - - ) - } - - render () { - const { - gasButtonInfo, - defaultActiveButtonIndex = 1, - newActiveButtonIndex, - noButtonActiveByDefault = false, - buttonDataLoading, - ...buttonPropsAndFlags - } = this.props - - return ( - !buttonDataLoading - ? - { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } - - :
{ this.context.t('loading') }
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.js b/ui/app/components/gas-customization/gas-price-button-group/index.js deleted file mode 100644 index 775648330..000000000 --- a/ui/app/components/gas-customization/gas-price-button-group/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-price-button-group.component' diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss deleted file mode 100644 index cb2f3ecf1..000000000 --- a/ui/app/components/gas-customization/gas-price-button-group/index.scss +++ /dev/null @@ -1,238 +0,0 @@ -.gas-price-button-group { - margin-top: 22px; - display: flex; - justify-content: space-evenly; - width: 100%; - padding-left: 20px; - padding-right: 20px; - - &__primary-currency { - font-size: 18px; - height: 20.5px; - margin-bottom: 7.5px; - } - - &__time-estimate { - margin-top: 5.5px; - color: $silver-chalice; - height: 15.4px; - } - - &__loading-container { - height: 130px; - } - - .button-group__button, .button-group__button--active { - height: 130px; - max-width: 108px; - font-size: 12px; - flex-direction: column; - align-items: center; - display: flex; - padding-top: 17px; - border-radius: 4px; - border: 2px solid $spindle; - background: $white; - color: $scorpion; - - div { - display: flex; - flex-direction: column; - align-items: center; - } - - i { - &:last-child { - display: none; - } - } - } - - .button-group__button--active { - border: 2px solid $curious-blue; - color: $scorpion; - - i { - &:last-child { - display: flex; - color: $curious-blue; - margin-top: 8px - } - } - } -} - -.gas-price-button-group--small { - display: flex; - justify-content: stretch; - - @media screen and (max-width: $break-small) { - max-width: 260px; - } - - &__button-fiat-price { - font-size: 13px; - } - - &__button-label { - font-size: 16px; - } - - &__label { - font-weight: 500; - } - - &__primary-currency { - font-size: 12px; - - @media screen and (max-width: 575px) { - font-size: 10px; - } - } - - &__secondary-currency { - font-size: 12px; - - @media screen and (max-width: 575px) { - font-size: 10px; - } - } - - &__loading-container { - height: 78px; - } - - .button-group__button, .button-group__button--active { - height: 78px; - background: white; - color: $scorpion; - padding-top: 9px; - padding-left: 8.5px; - - @media screen and (max-width: $break-small) { - padding-left: 4px; - } - - div { - display: flex; - flex-flow: column; - align-items: flex-start; - justify-content: flex-start; - } - - i { - &:last-child { - display: none; - } - } - } - - .button-group__button--active { - color: $white; - background: $dodger-blue; - - i { - &:last-child { - display: flex; - color: $curious-blue; - margin-top: 10px - } - } - } -} - -.gas-price-button-group--alt { - display: flex; - justify-content: stretch; - width: 95%; - - &__button-fiat-price { - font-size: 13px; - } - - &__button-label { - font-size: 16px; - } - - &__label { - font-weight: 500; - font-size: 10px; - text-transform: capitalize; - } - - &__primary-currency { - font-size: 11px; - margin-top: 3px; - } - - &__secondary-currency { - font-size: 11px; - } - - &__loading-container { - height: 78px; - } - - &__time-estimate { - font-size: 14px; - font-weight: 500; - margin-top: 4px; - color: $black; - } - - .button-group__button, .button-group__button--active { - height: 78px; - background: white; - color: #2A4055; - width: 108px; - height: 97px; - box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.151579); - border-radius: 6px; - border: none; - - div { - display: flex; - flex-flow: column;; - align-items: flex-start; - justify-content: flex-start; - position: relative; - } - - .button-check-wrapper { - display: none; - } - - &:first-child { - margin-right: 6px; - } - - &:last-child { - margin-left: 6px; - } - } - - .button-group__button--active { - background: #F7FCFF; - border: 2px solid #2C8BDC; - - .button-check-wrapper { - height: 16px; - width: 16px; - border-radius: 8px; - position: absolute; - top: -11px; - right: -10px; - background: #D5ECFA; - display: flex; - flex-flow: row; - justify-content: center; - align-items: center; - } - - i { - display: flex; - color: $curious-blue; - font-size: 12px; - } - } -} diff --git a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js deleted file mode 100644 index 79f74f8e4..000000000 --- a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ /dev/null @@ -1,233 +0,0 @@ -import React from 'react' -import assert from 'assert' -import shallow from '../../../../../lib/shallow-with-context' -import sinon from 'sinon' -import GasPriceButtonGroup from '../gas-price-button-group.component' - -import ButtonGroup from '../../../button-group/' - -const mockGasPriceButtonGroupProps = { - buttonDataLoading: false, - className: 'gas-price-button-group', - gasButtonInfo: [ - { - feeInPrimaryCurrency: '$0.52', - feeInSecondaryCurrency: '0.0048 ETH', - timeEstimate: '~ 1 min 0 sec', - priceInHexWei: '0xa1b2c3f', - }, - { - feeInPrimaryCurrency: '$0.39', - feeInSecondaryCurrency: '0.004 ETH', - timeEstimate: '~ 1 min 30 sec', - priceInHexWei: '0xa1b2c39', - }, - { - feeInPrimaryCurrency: '$0.30', - feeInSecondaryCurrency: '0.00354 ETH', - timeEstimate: '~ 2 min 1 sec', - priceInHexWei: '0xa1b2c30', - }, - ], - handleGasPriceSelection: sinon.spy(), - noButtonActiveByDefault: true, - defaultActiveButtonIndex: 2, - showCheck: true, -} - -const mockButtonPropsAndFlags = Object.assign({}, { - className: mockGasPriceButtonGroupProps.className, - handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, - showCheck: mockGasPriceButtonGroupProps.showCheck, -}) - -sinon.spy(GasPriceButtonGroup.prototype, 'renderButton') -sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent') - -describe('GasPriceButtonGroup Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow() - }) - - afterEach(() => { - GasPriceButtonGroup.prototype.renderButton.resetHistory() - GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() - mockGasPriceButtonGroupProps.handleGasPriceSelection.resetHistory() - }) - - describe('render', () => { - it('should render a ButtonGroup', () => { - assert(wrapper.is(ButtonGroup)) - }) - - it('should render the correct props on the ButtonGroup', () => { - const { - className, - defaultActiveButtonIndex, - noButtonActiveByDefault, - } = wrapper.props() - assert.equal(className, 'gas-price-button-group') - assert.equal(defaultActiveButtonIndex, 2) - assert.equal(noButtonActiveByDefault, true) - }) - - function renderButtonArgsTest (i, mockButtonPropsAndFlags) { - assert.deepEqual( - GasPriceButtonGroup.prototype.renderButton.getCall(i).args, - [ - Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[i]), - mockButtonPropsAndFlags, - i, - ] - ) - } - - it('should call this.renderButton 3 times, with the correct args', () => { - assert.equal(GasPriceButtonGroup.prototype.renderButton.callCount, 3) - renderButtonArgsTest(0, mockButtonPropsAndFlags) - renderButtonArgsTest(1, mockButtonPropsAndFlags) - renderButtonArgsTest(2, mockButtonPropsAndFlags) - }) - - it('should show loading if buttonDataLoading', () => { - wrapper.setProps({ buttonDataLoading: true }) - assert(wrapper.is('div')) - assert(wrapper.hasClass('gas-price-button-group__loading-container')) - assert.equal(wrapper.text(), 'loading') - }) - }) - - describe('renderButton', () => { - let wrappedRenderButtonResult - - beforeEach(() => { - GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() - const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( - Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), - mockButtonPropsAndFlags - ) - wrappedRenderButtonResult = shallow(renderButtonResult) - }) - - it('should render a button', () => { - assert.equal(wrappedRenderButtonResult.type(), 'button') - }) - - it('should call the correct method when clicked', () => { - assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 0) - wrappedRenderButtonResult.props().onClick() - assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 1) - assert.deepEqual( - mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, - [mockGasPriceButtonGroupProps.gasButtonInfo[0].priceInHexWei] - ) - }) - - it('should call this.renderButtonContent with the correct args', () => { - assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 1) - const { - feeInPrimaryCurrency, - feeInSecondaryCurrency, - timeEstimate, - } = mockGasPriceButtonGroupProps.gasButtonInfo[0] - const { - showCheck, - className, - } = mockGasPriceButtonGroupProps - assert.deepEqual( - GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, - [ - { - feeInPrimaryCurrency, - feeInSecondaryCurrency, - timeEstimate, - }, - { - showCheck, - className, - }, - ] - ) - }) - }) - - describe('renderButtonContent', () => { - it('should render a label if passed a labelKey', () => { - const renderButtonContentResult = wrapper.instance().renderButtonContent({ - labelKey: 'mockLabelKey', - }, { - className: 'someClass', - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabelKey') - }) - - it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', - }, { - className: 'someClass', - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__primary-currency').text(), 'mockFeeInPrimaryCurrency') - }) - - it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', - }, { - className: 'someClass', - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__secondary-currency').text(), 'mockFeeInSecondaryCurrency') - }) - - it('should render a timeEstimate if passed a timeEstimate', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - timeEstimate: 'mockTimeEstimate', - }, { - className: 'someClass', - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__time-estimate').text(), 'mockTimeEstimate') - }) - - it('should render a check if showCheck is true', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, { - className: 'someClass', - showCheck: true, - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.find('.fa-check').length, 1) - }) - - it('should render all elements if all args passed', () => { - const renderButtonContentResult = wrapper.instance().renderButtonContent({ - labelKey: 'mockLabel', - feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', - feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', - timeEstimate: 'mockTimeEstimate', - }, { - className: 'someClass', - showCheck: true, - }) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.children().length, 5) - }) - - - it('should render no elements if all args passed', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, {}) - const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) - assert.equal(wrappedRenderButtonContentResult.children().length, 0) - }) - }) -}) diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js deleted file mode 100644 index c0eaf4852..000000000 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js +++ /dev/null @@ -1,108 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import * as d3 from 'd3' -import { - generateChart, - getCoordinateData, - handleChartUpdate, - hideDataUI, - setTickPosition, - handleMouseMove, -} from './gas-price-chart.utils.js' - -export default class GasPriceChart extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - gasPrices: PropTypes.array, - estimatedTimes: PropTypes.array, - gasPricesMax: PropTypes.number, - estimatedTimesMax: PropTypes.number, - currentPrice: PropTypes.number, - updateCustomGasPrice: PropTypes.func, - } - - renderChart ({ - currentPrice, - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, - updateCustomGasPrice, - }) { - const chart = generateChart(gasPrices, estimatedTimes, gasPricesMax, estimatedTimesMax, this.context.t) - setTimeout(function () { - setTickPosition('y', 0, -5, 8) - setTickPosition('y', 1, -3, -5) - setTickPosition('x', 0, 3) - setTickPosition('x', 1, 3, -8) - - const { x: domainX } = getCoordinateData('.domain') - const { x: yAxisX } = getCoordinateData('.c3-axis-y-label') - const { x: tickX } = getCoordinateData('.c3-axis-x .tick') - - d3.select('.c3-axis-x .tick').attr('transform', 'translate(' + (domainX - tickX) / 2 + ', 0)') - d3.select('.c3-axis-x-label').attr('transform', 'translate(0,-15)') - d3.select('.c3-axis-y-label').attr('transform', 'translate(' + (domainX - yAxisX - 12) + ', 2) rotate(-90)') - d3.select('.c3-xgrid-focus line').attr('y2', 98) - - d3.select('.c3-chart').on('mouseout', () => { - hideDataUI(chart, '#overlayed-circle') - }) - - d3.select('.c3-chart').on('click', () => { - const { x: newGasPrice } = d3.select('#overlayed-circle').datum() - updateCustomGasPrice(newGasPrice) - }) - - const { x: chartXStart, width: chartWidth } = getCoordinateData('.c3-areas-data1') - - handleChartUpdate({ - chart, - gasPrices, - newPrice: currentPrice, - cssId: '#set-circle', - }) - - d3.select('.c3-chart').on('mousemove', function () { - handleMouseMove({ - xMousePos: d3.event.clientX, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - chart, - }) - }) - }, 0) - - this.chart = chart - } - - componentDidUpdate (prevProps) { - const { gasPrices, currentPrice: newPrice } = this.props - - if (prevProps.currentPrice !== newPrice) { - handleChartUpdate({ - chart: this.chart, - gasPrices, - newPrice, - cssId: '#set-circle', - }) - } - } - - componentDidMount () { - this.renderChart(this.props) - } - - render () { - return ( -
-
-
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js deleted file mode 100644 index f19dafcc1..000000000 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ /dev/null @@ -1,354 +0,0 @@ -import * as d3 from 'd3' -import c3 from 'c3' -import BigNumber from 'bignumber.js' - -const newBigSigDig = n => (new BigNumber(n.toPrecision(15))) -const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b)) -const bigNumMinus = (a = 0, b = 0) => createOp(a, b, 'minus') -const bigNumDiv = (a = 0, b = 1) => createOp(a, b, 'div') - -export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) { - const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - }) - - if (currentPosValue === null && newTimeEstimate === null) { - hideDataUI(chart, '#overlayed-circle') - return - } - - const indexOfNewCircle = estimatedTimes.length + 1 - const dataUIObj = generateDataUIObj(currentPosValue, indexOfNewCircle, newTimeEstimate) - - chart.internal.overlayPoint(dataUIObj, indexOfNewCircle) - chart.internal.showTooltip([dataUIObj], d3.select('.c3-areas-data1')._groups[0]) - chart.internal.showXGridFocus([dataUIObj]) -} - -export function getCoordinateData (selector) { - const node = d3.select(selector).node() - return node ? node.getBoundingClientRect() : {} -} - -export function generateDataUIObj (x, index, value) { - return { - x, - value, - index, - id: 'data1', - name: 'data1', - } -} - -export function handleChartUpdate ({ chart, gasPrices, newPrice, cssId }) { - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: newPrice }) - - if (closestLowerValue && closestHigherValue) { - setSelectedCircle({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - }) - } else { - hideDataUI(chart, cssId) - } -} - -export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) { - const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition) - const closestHigherValueIndex = gasPrices.findIndex((e, i, a) => e > priceToPosition) - return { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue: gasPrices[closestHigherValueIndex], - closestLowerValue: gasPrices[closestLowerValueIndex], - } -} - -export function extrapolateY ({ higherY = 0, lowerY = 0, higherX = 0, lowerX = 0, xForExtrapolation = 0 }) { - const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX)) - const newTimeEstimate = slope.times(bigNumMinus(higherX, xForExtrapolation)).minus(newBigSigDig(higherY)).negated() - - return newTimeEstimate.toNumber() -} - - -export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) { - const chartMouseXPos = bigNumMinus(xMousePos, chartXStart) - const posPercentile = bigNumDiv(chartMouseXPos, chartWidth) - - const currentPosValue = (bigNumMinus(gasPrices[gasPrices.length - 1], gasPrices[0])) - .times(newBigSigDig(posPercentile)) - .plus(newBigSigDig(gasPrices[0])) - .toNumber() - - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentPosValue }) - - return !closestHigherValue || !closestLowerValue - ? { - currentPosValue: null, - newTimeEstimate: null, - } - : { - currentPosValue, - newTimeEstimate: extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: currentPosValue, - }), - } -} - -export function hideDataUI (chart, dataNodeId) { - const overLayedCircle = d3.select(dataNodeId) - if (!overLayedCircle.empty()) { - overLayedCircle.remove() - } - d3.select('.c3-tooltip-container').style('display', 'none !important') - chart.internal.hideXGridFocus() -} - -export function setTickPosition (axis, n, newPosition, secondNewPosition) { - const positionToShift = axis === 'y' ? 'x' : 'y' - const secondPositionToShift = axis === 'y' ? 'y' : 'x' - d3.select('#chart') - .select(`.c3-axis-${axis}`) - .selectAll('.tick') - .filter((d, i) => i === n) - .select('text') - .attr(positionToShift, 0) - .select('tspan') - .attr(positionToShift, newPosition) - .attr(secondPositionToShift, secondNewPosition || 0) - .style('visibility', 'visible') -} - -export function appendOrUpdateCircle ({ data, itemIndex, cx, cy, cssId, appendOnly }) { - const circle = this.main - .select('.c3-selected-circles' + this.getTargetSelectorSuffix(data.id)) - .selectAll(`.c3-selected-circle-${itemIndex}`) - - if (appendOnly || circle.empty()) { - circle.data([data]) - .enter().append('circle') - .attr('class', () => this.generateClass('c3-selected-circle', itemIndex)) - .attr('id', cssId) - .attr('cx', cx) - .attr('cy', cy) - .attr('stroke', () => this.color(data)) - .attr('r', 6) - } else { - circle.data([data]) - .attr('cx', cx) - .attr('cy', cy) - } -} - -export function setSelectedCircle ({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, -}) { - const numberOfValues = chart.internal.data.xs.data1.length - - const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) - let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) - let count = closestHigherValueIndex + 1 - - if (lowerX && higherX) { - while (lowerX === higherX) { - higherX = getCoordinateData(`.c3-circle-${count}`).x - higherY = getCoordinateData(`.c3-circle-${count}`).y - count++ - } - } - - const currentX = bigNumMinus(higherX, lowerX) - .times(bigNumMinus(newPrice, closestLowerValue)) - .div(bigNumMinus(closestHigherValue, closestLowerValue)) - .plus(newBigSigDig(lowerX)) - - const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) - - chart.internal.selectPoint( - generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate), - numberOfValues - ) -} - - -export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimatedTimesMax) { - const gasPricesMaxPadded = gasPricesMax + 1 - const chart = c3.generate({ - size: { - height: 165, - }, - transition: { - duration: 0, - }, - padding: {left: 20, right: 15, top: 6, bottom: 10}, - data: { - x: 'x', - columns: [ - ['x', ...gasPrices], - ['data1', ...estimatedTimes], - ], - types: { - data1: 'area', - }, - selection: { - enabled: false, - }, - }, - color: { - data1: '#259de5', - }, - axis: { - x: { - min: gasPrices[0], - max: gasPricesMax, - tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], - outer: false, - format: function (val) { return val + ' GWEI' }, - }, - padding: {left: gasPricesMax / 50, right: gasPricesMax / 50}, - label: { - text: 'Gas Price ($)', - position: 'outer-center', - }, - }, - y: { - padding: {top: 7, bottom: 7}, - tick: { - values: [Math.floor(estimatedTimesMax * 0.05), Math.ceil(estimatedTimesMax * 0.97)], - outer: false, - }, - label: { - text: 'Confirmation time (sec)', - position: 'outer-middle', - }, - min: 0, - }, - }, - legend: { - show: false, - }, - grid: { - x: {}, - lines: { - front: false, - }, - }, - point: { - focus: { - expand: { - enabled: false, - r: 3.5, - }, - }, - }, - tooltip: { - format: { - title: (v) => v.toPrecision(4), - }, - contents: function (d) { - const titleFormat = this.config.tooltip_format_title - let text - d.forEach(el => { - if (el && (el.value || el.value === 0) && !text) { - text = "" + "' - } - }) - return text + '
" + titleFormat(el.x) + '
' + "
" - }, - position: function (data) { - if (d3.select('#overlayed-circle').empty()) { - return { top: -100, left: -100 } - } - - const { x: circleX, y: circleY, width: circleWidth } = getCoordinateData('#overlayed-circle') - const { x: chartXStart, y: chartYStart } = getCoordinateData('.c3-chart') - - // TODO: Confirm the below constants work with all data sets and screen sizes - const flipTooltip = circleY - circleWidth < chartYStart + 5 - - d3 - .select('.tooltip-arrow') - .style('margin-top', flipTooltip ? '-16px' : '4px') - - return { - top: bigNumMinus(circleY, chartYStart).minus(19).plus(flipTooltip ? circleWidth + 38 : 0).toNumber(), - left: bigNumMinus(circleX, chartXStart).plus(newBigSigDig(circleWidth)).minus(bigNumDiv(gasPricesMaxPadded, 50)).toNumber(), - } - }, - show: true, - }, - }) - - chart.internal.selectPoint = function (data, itemIndex = (data.index || 0)) { - const { x: chartXStart, y: chartYStart } = getCoordinateData('.c3-areas-data1') - - d3.select('#set-circle').remove() - - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(), - cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(), - cssId: 'set-circle', - appendOnly: true, - }) - } - - chart.internal.overlayPoint = function (data, itemIndex) { - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: this.circleX.bind(this), - cy: this.circleY.bind(this), - cssId: 'overlayed-circle', - }) - } - - chart.internal.showTooltip = function (selectedData, element) { - const dataToShow = selectedData.filter((d) => d && (d.value || d.value === 0)) - - if (dataToShow.length) { - this.tooltip.html( - this.config.tooltip_contents.call(this, selectedData, this.axis.getXAxisTickFormat(), this.getYFormat(), this.color) - ).style('display', 'flex') - - // Get tooltip dimensions - const tWidth = this.tooltip.property('offsetWidth') - const tHeight = this.tooltip.property('offsetHeight') - const position = this.config.tooltip_position.call(this, dataToShow, tWidth, tHeight, element) - // Set tooltip - this.tooltip.style('top', position.top + 'px').style('left', position.left + 'px') - } - } - - return chart -} diff --git a/ui/app/components/gas-customization/gas-price-chart/index.js b/ui/app/components/gas-customization/gas-price-chart/index.js deleted file mode 100644 index 9895acb62..000000000 --- a/ui/app/components/gas-customization/gas-price-chart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-price-chart.component' diff --git a/ui/app/components/gas-customization/gas-price-chart/index.scss b/ui/app/components/gas-customization/gas-price-chart/index.scss deleted file mode 100644 index 097543104..000000000 --- a/ui/app/components/gas-customization/gas-price-chart/index.scss +++ /dev/null @@ -1,132 +0,0 @@ -.gas-price-chart { - display: flex; - position: relative; - justify-content: center; - - &__root { - max-height: 154px; - max-width: 391px; - position: relative; - overflow: hidden; - - @media screen and (max-width: $break-small) { - max-width: 326px; - } - } - - .tick text, .c3-axis-x-label, .c3-axis-y-label { - font-family: Roboto; - font-style: normal; - font-weight: bold; - line-height: normal; - font-size: 8px; - text-align: center; - fill: #9A9CA6 !important; - } - - .c3-tooltip-container { - display: flex; - justify-content: center !important; - align-items: flex-end !important; - } - - .custom-tooltip { - background: rgba(0, 0, 0, 1); - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - border-radius: 3px; - opacity: 1 !important; - height: 21px; - z-index: 1; - } - - .tooltip-arrow { - background: black; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - opacity: 1 !important; - width: 9px; - height: 9px; - margin-top: 4px; - } - - .custom-tooltip th { - font-family: Roboto; - font-style: normal; - font-weight: 500; - line-height: normal; - font-size: 10px; - text-align: center; - padding: 3px; - color: #FFFFFF; - } - - .c3-circle { - visibility: hidden; - } - - .c3-selected-circle, .c3-circle._expanded_ { - fill: #FFFFFF !important; - stroke-width: 2.4px !important; - stroke: #2d9fd9 !important; - /* visibility: visible; */ - } - - #set-circle { - fill: #313A5E !important; - stroke: #313A5E !important; - } - - .c3-axis-x-label, .c3-axis-y-label { - font-weight: normal; - } - - .tick text tspan { - visibility: hidden; - } - - .c3-circle { - fill: #2d9fd9 !important; - } - - .c3-line-data1 { - stroke: #2d9fd9 !important; - background: rgba(0,0,0,0) !important; - color: rgba(0,0,0,0) !important; - } - - .c3 path { - fill: none; - } - - .c3 path.c3-area-data1 { - opacity: 1; - fill: #e9edf1 !important; - } - - .c3-xgrid-line line { - stroke: #B8B8B8 !important; - } - - .c3-xgrid-focus { - stroke: #aaa; - } - - .c3-axis-x .domain { - fill: none; - stroke: none; - } - - .c3-axis-y .domain { - fill: none; - stroke: #C8CCD6; - } - - .c3-event-rect { - cursor: pointer; - } -} - -#chart { - background: #F8F9FB -} diff --git a/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js deleted file mode 100644 index 74eddae42..000000000 --- a/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js +++ /dev/null @@ -1,218 +0,0 @@ -import React from 'react' -import assert from 'assert' -import proxyquire from 'proxyquire' -import sinon from 'sinon' -import shallow from '../../../../../lib/shallow-with-context' -import * as d3 from 'd3' - -function timeout (time) { - return new Promise((resolve, reject) => { - setTimeout(resolve, time) - }) -} - -const propsMethodSpies = { - updateCustomGasPrice: sinon.spy(), -} - -const selectReturnSpies = { - empty: sinon.spy(), - remove: sinon.spy(), - style: sinon.spy(), - select: d3.select, - attr: sinon.spy(), - on: sinon.spy(), - datum: sinon.stub().returns({ x: 'mockX' }), -} - -const mockSelectReturn = { - ...d3.select('div'), - node: () => ({ - getBoundingClientRect: () => ({ x: 123, y: 321, width: 400 }), - }), - ...selectReturnSpies, -} - -const gasPriceChartUtilsSpies = { - appendOrUpdateCircle: sinon.spy(), - generateChart: sinon.stub().returns({ mockChart: true }), - generateDataUIObj: sinon.spy(), - getAdjacentGasPrices: sinon.spy(), - getCoordinateData: sinon.stub().returns({ x: 'mockCoordinateX', width: 'mockWidth' }), - getNewXandTimeEstimate: sinon.spy(), - handleChartUpdate: sinon.spy(), - hideDataUI: sinon.spy(), - setSelectedCircle: sinon.spy(), - setTickPosition: sinon.spy(), - handleMouseMove: sinon.spy(), -} - -const testProps = { - gasPrices: [1.5, 2.5, 4, 8], - estimatedTimes: [100, 80, 40, 10], - gasPricesMax: 9, - estimatedTimesMax: '100', - currentPrice: 6, - updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, -} - -const GasPriceChart = proxyquire('../gas-price-chart.component.js', { - './gas-price-chart.utils.js': gasPriceChartUtilsSpies, - 'd3': { - ...d3, - select: function (...args) { - const result = d3.select(...args) - return result.empty() - ? mockSelectReturn - : result - }, - event: { - clientX: 'mockClientX', - }, - }, -}).default - -sinon.spy(GasPriceChart.prototype, 'renderChart') - -describe('GasPriceChart Component', function () { - let wrapper - - beforeEach(() => { - wrapper = shallow() - }) - - describe('render()', () => { - it('should render', () => { - assert(wrapper.hasClass('gas-price-chart')) - }) - - it('should render the chart div', () => { - assert(wrapper.childAt(0).hasClass('gas-price-chart__root')) - assert.equal(wrapper.childAt(0).props().id, 'chart') - }) - }) - - describe('componentDidMount', () => { - it('should call this.renderChart with the components props', () => { - assert(GasPriceChart.prototype.renderChart.callCount, 1) - wrapper.instance().componentDidMount() - assert(GasPriceChart.prototype.renderChart.callCount, 2) - assert.deepEqual(GasPriceChart.prototype.renderChart.getCall(1).args, [{...testProps}]) - }) - }) - - describe('componentDidUpdate', () => { - it('should call handleChartUpdate if props.currentPrice has changed', () => { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 1) - }) - - it('should call handleChartUpdate with the correct props', () => { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.deepEqual(gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, [{ - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }]) - }) - - it('should not call handleChartUpdate if props.currentPrice has not changed', () => { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 6 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 0) - }) - }) - - describe('renderChart', () => { - it('should call setTickPosition 4 times, with the expected props', async () => { - await timeout(0) - gasPriceChartUtilsSpies.setTickPosition.resetHistory() - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 4) - assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(0).args, ['y', 0, -5, 8]) - assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(1).args, ['y', 1, -3, -5]) - assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(2).args, ['x', 0, 3]) - assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(3).args, ['x', 1, 3, -8]) - }) - - it('should call handleChartUpdate with the correct props', async () => { - await timeout(0) - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.deepEqual(gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, [{ - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }]) - }) - - it('should add three events to the chart', async () => { - await timeout(0) - selectReturnSpies.on.resetHistory() - assert.equal(selectReturnSpies.on.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(selectReturnSpies.on.callCount, 3) - - const firstOnEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(firstOnEventArgs[0], 'mouseout') - const secondOnEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(secondOnEventArgs[0], 'click') - const thirdOnEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(thirdOnEventArgs[0], 'mousemove') - }) - - it('should hide the data UI on mouseout', async () => { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.hideDataUI.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 1) - assert.deepEqual(gasPriceChartUtilsSpies.hideDataUI.getCall(0).args, [{ mockChart: true }, '#overlayed-circle']) - }) - - it('should updateCustomGasPrice on click', async () => { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - propsMethodSpies.updateCustomGasPrice.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 1) - assert.equal(propsMethodSpies.updateCustomGasPrice.getCall(0).args[0], 'mockX') - }) - - it('should handle mousemove', async () => { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.handleMouseMove.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 1) - assert.deepEqual(gasPriceChartUtilsSpies.handleMouseMove.getCall(0).args, [{ - xMousePos: 'mockClientX', - chartXStart: 'mockCoordinateX', - chartWidth: 'mockWidth', - gasPrices: testProps.gasPrices, - estimatedTimes: testProps.estimatedTimes, - chart: { mockChart: true }, - }]) - }) - }) -}) diff --git a/ui/app/components/gas-customization/gas-slider/gas-slider.component.js b/ui/app/components/gas-customization/gas-slider/gas-slider.component.js deleted file mode 100644 index 5836e7dfc..000000000 --- a/ui/app/components/gas-customization/gas-slider/gas-slider.component.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' - -export default class AdvancedTabContent extends Component { - static propTypes = { - onChange: PropTypes.func, - lowLabel: PropTypes.string, - highLabel: PropTypes.string, - value: PropTypes.number, - step: PropTypes.number, - max: PropTypes.number, - min: PropTypes.number, - } - - render () { - const { - onChange, - lowLabel, - highLabel, - value, - step, - max, - min, - } = this.props - - return ( -
- onChange(event.target.value)} - /> -
-
-
-
- {lowLabel} - {highLabel} -
-
- ) - } -} diff --git a/ui/app/components/gas-customization/gas-slider/index.js b/ui/app/components/gas-customization/gas-slider/index.js deleted file mode 100644 index f1752c93f..000000000 --- a/ui/app/components/gas-customization/gas-slider/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-slider.component' diff --git a/ui/app/components/gas-customization/gas-slider/index.scss b/ui/app/components/gas-customization/gas-slider/index.scss deleted file mode 100644 index e6c734367..000000000 --- a/ui/app/components/gas-customization/gas-slider/index.scss +++ /dev/null @@ -1,54 +0,0 @@ -.gas-slider { - position: relative; - width: 322px; - - &__input { - width: 322px; - margin-left: -2px; - z-index: 2; - } - - input[type=range] { - -webkit-appearance: none !important; - } - - input[type=range]::-webkit-slider-thumb { - -webkit-appearance: none !important; - height: 34px; - width: 34px; - background-color: $curious-blue; - box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08); - border-radius: 50%; - position: relative; - z-index: 10; - } - - &__bar { - height: 6px; - width: 322px; - background: $alto; - display: flex; - justify-content: space-between; - position: absolute; - top: 16px; - z-index: 0; - border-radius: 4px; - } - - &__colored { - height: 6px; - border-radius: 4px; - margin-left: 102px; - width: 322px; - z-index: 1; - background-color: $blizzard-blue; - } - - &__labels { - display: flex; - justify-content: space-between; - font-size: 12px; - margin-top: -6px; - color: $mid-gray; - } -} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas.selectors.js b/ui/app/components/gas-customization/gas.selectors.js deleted file mode 100644 index 89374b5f1..000000000 --- a/ui/app/components/gas-customization/gas.selectors.js +++ /dev/null @@ -1,14 +0,0 @@ -const selectors = { - getCurrentBlockTime, - getBasicGasEstimateLoadingStatus, -} - -module.exports = selectors - -function getCurrentBlockTime (state) { - return state.gas.currentBlockTime -} - -function getBasicGasEstimateLoadingStatus (state) { - return state.gas.basicEstimateIsLoading -} diff --git a/ui/app/components/gas-customization/index.scss b/ui/app/components/gas-customization/index.scss deleted file mode 100644 index b06c1d044..000000000 --- a/ui/app/components/gas-customization/index.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import './gas-slider/index'; - -@import './gas-modal-page-container/index'; - -@import './gas-price-chart/index'; - -@import './advanced-gas-inputs/index'; -- cgit