From b95eb30ec60e4d169a61d987ad86fe333aa49523 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 20 Sep 2018 13:36:23 -0230 Subject: Adds redesign for the customize gas advanced tab. --- .../advanced-tab-content.component.js | 35 +++++------ .../advanced-tab-content/index.scss | 44 +++++++++----- .../tests/advanced-tab-content-component.test.js | 56 +++++++++++------- .../advanced-tab-content/time-remaining/index.scss | 8 ++- .../basic-tab-content/index.scss | 1 + .../gas-modal-page-container.component.js | 63 +++++++++++--------- .../gas-modal-page-container.container.js | 36 +++++++----- .../gas-modal-page-container/index.scss | 68 ++++++++++++++++++++-- .../gas-modal-page-container-component.test.js | 67 ++++++++++++--------- .../gas-modal-page-container-container.test.js | 21 ++++--- .../gas-price-chart/gas-price-chart.component.js | 16 +++++ .../gas-customization/gas-price-chart/index.js | 1 + .../gas-customization/gas-price-chart/index.scss | 6 ++ .../tests/gas-price-chart.component.test.js | 25 ++++++++ ui/app/components/gas-customization/index.scss | 2 + .../page-container-footer.component.js | 6 +- .../page-container-header.component.js | 13 +++-- .../page-container/page-container.component.js | 6 ++ ui/app/ducks/gas.duck.js | 10 ++++ 19 files changed, 332 insertions(+), 152 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js create mode 100644 ui/app/components/gas-customization/gas-price-chart/index.js create mode 100644 ui/app/components/gas-customization/gas-price-chart/index.scss create mode 100644 ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js 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 index 56d10cc2b..5218dd477 100644 --- 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 @@ -1,6 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import TimeRemaining from './time-remaining' +import GasPriceChart from '../../gas-price-chart' export default class AdvancedTabContent extends Component { static contextTypes = { @@ -14,6 +14,7 @@ export default class AdvancedTabContent extends Component { customGasLimit: PropTypes.number, millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, + timeRemaining: PropTypes.string, } gasInput (value, onChange, min, precision, showGWEI) { @@ -27,9 +28,6 @@ export default class AdvancedTabContent extends Component { precision={precision} onChange={event => onChange(Number(event.target.value))} /> - {showGWEI - ? GWEI - : null} ) } @@ -38,7 +36,7 @@ export default class AdvancedTabContent extends Component { return } - renderDataSummary (totalFee, millisecondsRemaining) { + renderDataSummary (totalFee, timeRemaining) { return (
@@ -49,9 +47,7 @@ export default class AdvancedTabContent extends Component {
{totalFee}
- +
{timeRemaining}
) @@ -72,7 +68,7 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
- { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } + { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
) @@ -82,7 +78,7 @@ export default class AdvancedTabContent extends Component { const { updateCustomGasPrice, updateCustomGasLimit, - millisecondsRemaining, + timeRemaining, customGasPrice, customGasLimit, totalFee, @@ -90,17 +86,16 @@ export default class AdvancedTabContent extends Component { return (
- { this.renderDataSummary(totalFee, millisecondsRemaining) } -
- { this.context.t('feeChartTitle') } + { this.renderDataSummary(totalFee, timeRemaining) } +
+ { this.renderGasEditRows( + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit + ) } +
-
- { this.renderGasEditRows( - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit - ) }
) } 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 index aced75449..ae99ba4aa 100644 --- 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 @@ -3,11 +3,9 @@ .advanced-tab { display: flex; flex-flow: column; - height: 430px; &__transaction-data-summary, - &__fee-chart-title, - &__gas-edit-row { + &__fee-chart-title { padding-left: 24px; padding-right: 24px; } @@ -17,6 +15,8 @@ flex-flow: column; color: $mid-gray; margin-top: 12px; + padding-left: 18px; + padding-right: 18px; &__titles, &__container { @@ -24,11 +24,17 @@ flex-flow: row; justify-content: space-between; font-size: 12px; + color: #888EA3; } &__container { - font-size: 26px; - margin-top: 6px; + font-size: 16px; + margin-top: 0px; + } + + &__fee { + font-size: 16px; + color: #313A5E; } } @@ -40,8 +46,11 @@ &__fee-chart { padding-left: 10px; - margin-top: 24px; - height: 134px; + margin-top: 8px; + height: 258px; + background: #F8F9FB; + border-bottom: 1px solid #d2d8dd; + border-top: 1px solid #d2d8dd; } &__slider-container { @@ -50,21 +59,25 @@ } &__gas-edit-rows { - margin-top: 44px; height: 87px; display: flex; - flex-flow: column; + flex-flow: row; justify-content: space-between; + margin-left: 10px; + margin-right: 10px; + margin-top: 9px; } &__gas-edit-row { display: flex; - flex-flow: row; - justify-content: space-between; + flex-flow: column; &__label { - color: $mid-gray; - font-size: 16px; + color: #313B5E; + font-size: 14px; + display: flex; + justify-content: space-between; + align-items: center; .fa-info-circle { color: $silver; @@ -87,10 +100,11 @@ border-radius: 4px; color: $mid-gray; font-size: 16px; - height: 37px; - width: 163px; + height: 24px; + width: 155px; padding-left: 8px; padding-top: 2px; + margin-top: 7px; } input[type="number"]::-webkit-inner-spin-button { 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 index 0ef286b8a..1489c7696 100644 --- 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 @@ -4,7 +4,7 @@ import shallow from '../../../../../../lib/shallow-with-context' import sinon from 'sinon' import AdvancedTabContent from '../advanced-tab-content.component.js' -import TimeRemaining from '../time-remaining' +import GasPriceChart from '../../../gas-price-chart' const propsMethodSpies = { updateCustomGasPrice: sinon.spy(), @@ -13,6 +13,8 @@ const propsMethodSpies = { sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') sinon.spy(AdvancedTabContent.prototype, 'gasInput') +sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRows') +sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') describe('AdvancedTabContent Component', function () { let wrapper @@ -23,7 +25,7 @@ describe('AdvancedTabContent Component', function () { updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} customGasPrice={11} customGasLimit={23456} - millisecondsRemaining={21500} + timeRemaining={21500} totalFee={'$0.25'} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -31,6 +33,10 @@ describe('AdvancedTabContent Component', function () { 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()', () => { @@ -40,12 +46,31 @@ describe('AdvancedTabContent Component', function () { it('should render the expected four children of the advanced-tab div', () => { const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 4) + assert.equal(advancedTabChildren.length, 2) assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart-title')) - assert(advancedTabChildren.at(2).hasClass('advanced-tab__fee-chart')) - assert(advancedTabChildren.at(3).hasClass('advanced-tab__gas-edit-rows')) + 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).is(GasPriceChart)) + }) + + 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]) + + assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) + const renderGasEditRowArgs = AdvancedTabContent.prototype.renderGasEditRows.getCall(0).args + assert.deepEqual(renderGasEditRowArgs, [ + 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, + ]) + }) + + it('should call renderGasEditRows with the expected params', () => { + }) }) @@ -71,8 +96,8 @@ describe('AdvancedTabContent Component', function () { 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).is(TimeRemaining)) - assert.equal(dataNode.children().at(1).props().milliseconds, 'mockMsRemaining') + assert(dataNode.children().at(1).hasClass('time-remaining')) + assert.equal(dataNode.children().at(1).text(), 'mockMsRemaining') }) }) @@ -138,7 +163,7 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, + 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0, @@ -186,19 +211,6 @@ describe('AdvancedTabContent Component', function () { assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) }) - it('should show GWEI if the showGWEI prop is truthy', () => { - const gasInputWithGWEI = shallow(wrapper.instance().gasInput( - 321, - value => value + 7, - 0, - 8, - true - )) - assert.equal(gasInputWithGWEI.children().length, 2) - assert(gasInputWithGWEI.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) - assert(gasInputWithGWEI.children().at(1).hasClass('advanced-tab__gas-edit-row__gwei-symbol')) - }) - it('should pass the correct value min and precision props to the input', () => { const inputProps = gasInput.find('input').props() assert.equal(inputProps.min, 0) 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 index 01bb06268..e2115af7f 100644 --- 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 @@ -1,13 +1,17 @@ .time-remaining { + color: #313A5E; + font-size: 16px; + .minutes-num, .seconds-num { - font-size: 26px; + font-size: 16px; } .seconds-num { margin-left: 7px; + font-size: 16px; } .minutes-label, .seconds-label { - font-size: 14px; + font-size: 16px; } } \ No newline at end of file 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 index d5eb5d414..b7b6c0f94 100644 --- 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 @@ -3,6 +3,7 @@ flex-direction: column; align-items: center; margin-bottom: 22px; + height: 291px; &__title { margin-top: 19px; 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 index 41fe901fa..07e55a1f0 100644 --- 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 @@ -24,8 +24,9 @@ export default class GasModalPageContainer extends Component { newTotalEth: PropTypes.string, }), onSubmit: PropTypes.func, - customGasPriceInHex: PropTypes.string, - customGasLimitInHex: PropTypes.string, + customModalGasPriceInHex: PropTypes.string, + customModalGasLimitInHex: PropTypes.string, + cancelAndClose: PropTypes.func, } state = {} @@ -51,32 +52,34 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={convertThenUpdateCustomGasLimit} customGasPrice={customGasPrice} customGasLimit={customGasLimit} - millisecondsRemaining={91000} + timeRemaining={'1 min 31 sec'} totalFee={newTotalFiat} /> ) } - renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { - return ( -
-
- {`${this.context.t(totalLabelKey)}:`} - {fiatTotal} -
-
- {`${this.context.t('amountPlusTxFee')}`} - {cryptoTotal} -
-
- ) - } + renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { + const baseClassName = 'gas-modal-content__info-row' - renderInfoRows (originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) { return (
- { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) } - { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) } +
+
+ {`Send Amount`} + {sendAmount} +
+
+ {`Transaction Fee`} + {transactionFee} +
+
+ {`New Total`} + {newTotalEth} +
+
+ {newTotalFiat} +
+
) } @@ -86,6 +89,8 @@ export default class GasModalPageContainer extends Component { originalTotalEth, newTotalFiat, newTotalEth, + sendAmount, + transactionFee, }, { gasPriceButtonGroupProps, @@ -106,7 +111,7 @@ export default class GasModalPageContainer extends Component { {tabsToRender.map(({ name, content }, i) =>
{ content } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } + { this.renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) }
)} @@ -116,11 +121,11 @@ export default class GasModalPageContainer extends Component { render () { const { - hideModal, + cancelAndClose, infoRowProps, onSubmit, - customGasPriceInHex, - customGasLimitInHex, + customModalGasPriceInHex, + customModalGasLimitInHex, ...tabProps } = this.props @@ -131,13 +136,15 @@ export default class GasModalPageContainer extends Component { subtitle={this.context.t('customGasSubTitle')} tabsComponent={this.renderTabs(infoRowProps, tabProps)} disabled={false} - onCancel={() => hideModal()} - onClose={() => hideModal()} + onCancel={() => cancelAndClose()} + onClose={() => cancelAndClose()} onSubmit={() => { - onSubmit(customGasLimitInHex, customGasPriceInHex) - hideModal() + onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) + cancelAndClose() }} 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 index f9ed1cebb..ae233578b 100644 --- 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 @@ -9,6 +9,7 @@ import { import { setCustomGasPrice, setCustomGasLimit, + resetCustomData, } from '../../../ducks/gas.duck' import { hideGasButtonGroup, @@ -48,12 +49,12 @@ import { addHexPrefix } from 'ethereumjs-util' const mapStateToProps = state => { const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const { gasPrice, gas: gasLimit, value } = getTxParams(state) - const gasTotal = calcGasTotal(gasLimit, gasPrice) + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state) + const gasTotal = calcGasTotal(currentGasLimit, currentGasPrice) - const customGasPriceInHex = getCustomGasPrice(state) - const customGasLimitInHex = getCustomGasLimit(state) - const customGasTotal = calcGasTotal(customGasLimitInHex || gasLimit, customGasPriceInHex || gasPrice) + const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice + const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit + const customGasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex) const gasButtonInfo = getRenderableBasicEstimateData(state) @@ -67,14 +68,14 @@ const mapStateToProps = state => { return { hideBasic, isConfirm: isConfirm(state), - customGasPriceInHex, - customGasLimitInHex, - customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice), - customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit), + customModalGasPriceInHex, + customModalGasLimitInHex, + customGasPrice: calcCustomGasPrice(customModalGasPriceInHex), + customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, gasPriceButtonGroupProps: { buttonDataLoading, - defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customGasPriceInHex, gasPrice), + defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), gasButtonInfo, }, infoRowProps: { @@ -82,6 +83,8 @@ const mapStateToProps = state => { originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), newTotalFiat, newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), + transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), + sendAmount: addHexWEIsToRenderableEth(value, '0x0'), }, } } @@ -90,7 +93,10 @@ const mapDispatchToProps = dispatch => { const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice))) return { - hideModal: () => dispatch(hideModal()), + cancelAndClose: () => { + dispatch(resetCustomData()) + dispatch(hideModal()) + }, updateCustomGasPrice, convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), @@ -138,12 +144,12 @@ function isConfirm (state) { return Boolean(Object.keys(state.confirmTransaction.txData).length) } -function calcCustomGasPrice (customGasPriceInHex, gasPrice) { - return Number(hexWEIToDecGWEI(customGasPriceInHex || gasPrice)) +function calcCustomGasPrice (customGasPriceInHex) { + return Number(hexWEIToDecGWEI(customGasPriceInHex)) } -function calcCustomGasLimit (customGasLimitInHex, gasLimit) { - return parseInt(customGasLimitInHex || gasLimit, 16) +function calcCustomGasLimit (customGasLimitInHex) { + return parseInt(customGasLimitInHex, 16) } function getTxParams (state) { 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 index f02045fe3..c49d69bf7 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -4,6 +4,57 @@ .gas-modal-page-container { .page-container { width: 391px; + + &__header { + padding: 0px; + padding-top: 16px; + + &--no-padding-bottom { + padding-bottom: 0; + } + } + + &__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; + } + + &__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; + } + } } } @@ -20,30 +71,35 @@ display: flex; flex-flow: column; color: $scorpion; + font-size: 12px; - &__total-info, &__sum-info { + &__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 { - &__total-label { + &__label { font-size: 16px; } - &__total-value { + &__value { font-size: 16px; font-weight: bold; } } - &__sum-info { - &__sum-label { + &__transaction-info, &__send-info { + &__label { font-size: 12px; } - &__sum-value { + &__value { font-size: 14px; } } 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 index fdd7709d9..714f01538 100644 --- 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 @@ -9,7 +9,7 @@ import PageContainer from '../../../page-container' import { Tab } from '../../../tabs' const propsMethodSpies = { - hideModal: sinon.spy(), + cancelAndClose: sinon.spy(), onSubmit: sinon.spy(), } @@ -39,12 +39,16 @@ const mockGasPriceButtonGroupProps = { 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 @@ -53,7 +57,7 @@ describe('GasModalPageContainer Component', function () { beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} @@ -67,7 +71,7 @@ describe('GasModalPageContainer Component', function () { }) afterEach(() => { - propsMethodSpies.hideModal.resetHistory() + propsMethodSpies.cancelAndClose.resetHistory() }) describe('render', () => { @@ -91,11 +95,11 @@ describe('GasModalPageContainer Component', function () { onCancel, onClose, } = wrapper.find(PageContainer).props() - assert.equal(propsMethodSpies.hideModal.callCount, 0) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 0) onCancel() - assert.equal(propsMethodSpies.hideModal.callCount, 1) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 1) onClose() - assert.equal(propsMethodSpies.hideModal.callCount, 2) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 2) }) it('should pass the correct renderTabs property to PageContainer', () => { @@ -158,8 +162,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(GP.renderInfoRows.callCount, 2) - assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) - assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) + 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', () => { @@ -176,25 +180,6 @@ describe('GasModalPageContainer Component', function () { }) }) - describe('renderInfoRow', () => { - it('should render a div with the passed className and two children, each with the expected text', () => { - const renderInfoRowResult = wrapper.instance().renderInfoRow('mockClassName', 'mockLabelKey', 'mockFiatAmount', 'mockCryptoAmount') - const renderedInfoRow = shallow(renderInfoRowResult) - assert.equal(renderedInfoRow.props().className, 'mockClassName') - - const firstChild = renderedInfoRow.childAt(0) - const secondhild = renderedInfoRow.childAt(1) - - assert.equal(firstChild.props().className, 'mockClassName__total-info') - assert.equal(secondhild.props().className, 'mockClassName__sum-info') - - assert.equal(firstChild.childAt(0).text(), 'mockLabelKey:') - assert.equal(firstChild.childAt(1).text(), 'mockFiatAmount') - assert.equal(secondhild.childAt(0).text(), 'amountPlusTxFee') - assert.equal(secondhild.childAt(1).text(), 'mockCryptoAmount') - }) - }) - describe('renderBasicTabContent', () => { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps) @@ -220,8 +205,34 @@ describe('GasModalPageContainer Component', function () { assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') assert.equal(advancedTabContentProps.customGasPrice, 123) assert.equal(advancedTabContentProps.customGasLimit, 456) - assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) + assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') assert.equal(advancedTabContentProps.totalFee, '$0.30') }) }) + + 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(), 'Send Amount mockSendAmount') + assert.equal(renderedInfoRows.at(1).text(), 'Transaction Fee mockTransactionFee') + assert.equal(renderedInfoRows.at(2).text(), 'New Total 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 index 238f27ed6..3d9fb2624 100644 --- 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 @@ -15,6 +15,7 @@ const actionSpies = { const gasActionSpies = { setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), + resetCustomData: sinon.spy(), } const confirmTransactionActionSpies = { @@ -37,7 +38,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../selectors/custom-gas': { getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`, - getDefaultActiveButtonIndex: (a, b, c) => a + b + c, + getDefaultActiveButtonIndex: (a, b) => a + b, }, '../../../actions': actionSpies, '../../../ducks/gas.duck': gasActionSpies, @@ -89,15 +90,14 @@ describe('gas-modal-page-container container', () => { assert.deepEqual(result2, { isConfirm: true, - customGasPriceInHex: 'ffffffff', - customGasLimitInHex: 'aaaaaaaa', customGasPrice: 4.294967295, customGasLimit: 2863311530, newTotalFiat: '637.41', - gasPriceButtonGroupProps: - { + customModalGasLimitInHex: 'aaaaaaaa', + customModalGasPriceInHex: 'ffffffff', + gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff0x3200000', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, hideBasic: true, @@ -106,6 +106,8 @@ describe('gas-modal-page-container container', () => { originalTotalEth: '0.451569 ETH', newTotalFiat: '637.41', newTotalEth: '12.748189 ETH', + sendAmount: '0.45036 ETH', + transactionFee: '12.297829 ETH', }, }) }) @@ -135,11 +137,12 @@ describe('gas-modal-page-container container', () => { }) }) - describe('hideModal()', () => { + describe('cancelAndClose()', () => { it('should dispatch a hideModal action', () => { - mapDispatchToPropsObject.hideModal() - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.cancelAndClose() + assert(dispatchSpy.calledTwice) assert(actionSpies.hideModal.calledOnce) + assert(gasActionSpies.resetCustomData.calledOnce) }) }) 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 new file mode 100644 index 000000000..7c32058b7 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +export default class GasPriceChart extends Component { + static contextTypes = { + t: PropTypes.func, + } + + render () { + return ( +
+
+
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-price-chart/index.js b/ui/app/components/gas-customization/gas-price-chart/index.js new file mode 100644 index 000000000..9895acb62 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/index.js @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..14e7a12a8 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/index.scss @@ -0,0 +1,6 @@ +.gas-price-chart { + &__container { + display: flex; + position: relative; + } +} 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 new file mode 100644 index 000000000..474b7b7b6 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js @@ -0,0 +1,25 @@ +import React from 'react' +import assert from 'assert' +import shallow from '../../../../../lib/shallow-with-context' +import GasPriceChart from '../gas-price-chart.component.js' + +describe('GasPriceChart Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + describe('render()', () => { + it('should render', () => { + console.log('wrapper', wrapper.html()) + assert(wrapper.hasClass('gas-price-chart')) + }) + + it('should render the chart div', () => { + assert(wrapper.childAt(0).hasClass('gas-price-chart__container')) + assert.equal(wrapper.childAt(0).props().id, 'chart') + }) + }) + +}) diff --git a/ui/app/components/gas-customization/index.scss b/ui/app/components/gas-customization/index.scss index 91ca5004e..e99d4e57f 100644 --- a/ui/app/components/gas-customization/index.scss +++ b/ui/app/components/gas-customization/index.scss @@ -1,3 +1,5 @@ @import './gas-slider/index'; @import './gas-modal-page-container/index'; + +@import './gas-price-chart/index'; diff --git a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js index 773fe1f56..5725c22ac 100644 --- a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js +++ b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js @@ -12,6 +12,7 @@ export default class PageContainerFooter extends Component { submitText: PropTypes.string, disabled: PropTypes.bool, submitButtonType: PropTypes.string, + hideCancel: PropTypes.func, } static contextTypes = { @@ -27,20 +28,21 @@ export default class PageContainerFooter extends Component { submitText, disabled, submitButtonType, + hideCancel, } = this.props return (
- + }