From f9aa5a70defdad3ce13a257dc689add1d4b7d736 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 30 Jul 2018 23:58:05 -0230 Subject: Adds new gas customization modal container (without content) --- .../gas-modal-page-container.component.js | 79 +++++++++++ .../gas-modal-page-container.container.js | 11 ++ .../gas-modal-page-container/index.js | 1 + .../gas-modal-page-container/index.scss | 50 +++++++ .../gas-modal-page-container-component.test.js | 156 +++++++++++++++++++++ .../gas-modal-page-container-container.test.js | 44 ++++++ 6 files changed, 341 insertions(+) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 new file mode 100644 index 000000000..dfc011c1e --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -0,0 +1,79 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import PageContainer from '../../page-container' +import { Tabs, Tab } from '../../tabs' + +export default class GasModalPageContainer extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + hideModal: PropTypes.func, + } + + state = {} + + renderBasicTabContent () { + return ( +
+ ) + } + + renderAdvancedTabContent () { + return ( +
+ ) + } + + renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { + return ( +
+
+ {`${this.context.t(totalLabelKey)}:`}{fiatTotal} +
+
+ {`${this.context.t('amountPlusTxFee')}`}{cryptoTotal} +
+
+ ) + } + + renderTabContent (mainTabContent) { + return ( +
+ { mainTabContent() } + { this.renderInfoRow('info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } +
+ ) + } + + renderTabs () { + return ( + + + { this.renderTabContent(this.renderBasicTabContent) } + + + { this.renderTabContent(this.renderAdvancedTabContent) } + + + ) + } + + render () { + const { hideModal } = this.props + + return ( + hideModal()} + onClose={() => hideModal()} + /> + ) + } +} 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 new file mode 100644 index 000000000..71c700507 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -0,0 +1,11 @@ +import { connect } from 'react-redux' +import GasModalPageContainer from './gas-modal-page-container.component' +import { hideModal } from '../../../actions' + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + } +} + +export default connect(null, mapDispatchToProps)(GasModalPageContainer) 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 new file mode 100644 index 000000000..ec0ebad22 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.js @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..2d2250212 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -0,0 +1,50 @@ +.gas-modal-content { + .basic-tab { + height: 219px; + } + + .advanced-tab { + height: 475px; + } + + .info-row, .info-row--fade { + width: 100%; + background: $polar; + padding: 15px 21px; + display: flex; + flex-flow: column; + color: $scorpion; + + .total-info, .sum-info { + display: flex; + flex-flow: row; + justify-content: space-between; + } + + .total-info { + .total-label { + font-size: 16px; + } + + .total-value { + font-size: 16px; + font-weight: bold; + } + } + + .sum-info { + .sum-label { + font-size: 12px; + } + + .sum-value { + font-size: 14px; + } + } + } + + .info-row--fade { + background: white; + color: $dusty-gray; + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..ffe242de2 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -0,0 +1,156 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import GasModalPageContainer from '../gas-modal-page-container.component.js' + +import PageContainer from '../../../page-container' +import { Tab } from '../../../tabs' + +const propsMethodSpies = { + hideModal: sinon.spy(), +} + +describe('GasModalPageContainer Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + }) + + afterEach(() => { + propsMethodSpies.hideModal.resetHistory() + }) + + 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, 'customGasSpeedUp') + 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.hideModal.callCount, 0) + onCancel() + assert.equal(propsMethodSpies.hideModal.callCount, 1) + onClose() + assert.equal(propsMethodSpies.hideModal.callCount, 2) + }) + + it('should pass the correct renderTabs property to PageContainer', () => { + sinon.stub(GasModalPageContainer.prototype, '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', () => { + it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { + const renderTabsResult = wrapper.instance().renderTabs() + 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 render the expected children of each tab', () => { + const GP = GasModalPageContainer.prototype + sinon.spy(GP, 'renderTabContent') + assert.equal(GP.renderTabContent.callCount, 0) + + wrapper.instance().renderTabs() + + assert.equal(GP.renderTabContent.callCount, 2) + + assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent]) + assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent]) + + GP.renderTabContent.restore() + }) + }) + + describe('renderTabContent', () => { + it('should render a root gas-modal-content div', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(() => {}) + const renderedTabContent = shallow(renderTabContentResult) + assert.equal(renderedTabContent.props().className, 'gas-modal-content') + }) + + it('should render the element returned by the passed func as its first child', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + const renderedTabContent = shallow(renderTabContentResult) + assert(renderedTabContent.childAt(0).equals(Mock content)) + }) + + it('should render the element results of renderInfoRow calls as second and third childs', () => { + const GP = GasModalPageContainer.prototype + sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(',')) + + const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + const renderedTabContent = shallow(renderTabContentResult) + assert.equal(renderedTabContent.childAt(1).text(), 'info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(2).text(), 'info-row,newTotal,$20.02 USD,0.06685 ETH') + + GP.renderInfoRow.restore() + }) + }) + + 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, 'total-info') + assert.equal(secondhild.props().className, '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() + const renderedBasicTabContent = shallow(renderBasicTabContentResult) + assert.equal(renderedBasicTabContent.props().className, 'basic-tab') + }) + }) + + describe('renderAdvancedTabContent', () => { + it('should render', () => { + const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() + const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) + assert.equal(renderedAdvancedTabContent.props().className, 'advanced-tab') + }) + }) +}) 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 new file mode 100644 index 000000000..5b133fbe2 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -0,0 +1,44 @@ +import assert from 'assert' +import proxyquire from 'proxyquire' +import sinon from 'sinon' + +// let mapStateToProps +let mapDispatchToProps + +const actionSpies = { + hideModal: sinon.spy(), +} + +proxyquire('../gas-modal-page-container.container.js', { + 'react-redux': { + connect: (ms, md) => { + // mapStateToProps = ms + mapDispatchToProps = md + return () => ({}) + }, + }, + '../../../actions': actionSpies, +}) + +describe('gas-modal-page-container container', () => { + + describe('mapDispatchToProps()', () => { + let dispatchSpy + let mapDispatchToPropsObject + + beforeEach(() => { + dispatchSpy = sinon.spy() + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) + }) + + describe('hideModal()', () => { + it('should dispatch a hideModal action', () => { + mapDispatchToPropsObject.hideModal() + assert(dispatchSpy.calledOnce) + assert(actionSpies.hideModal.calledOnce) + }) + }) + + }) + +}) -- cgit From 88d8eb289edd7bec86993aac946ac85e4e5219ec Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 6 Aug 2018 11:47:58 -0230 Subject: Use correct message key in gas-modal-page-container.component.js --- .../gas-modal-page-container/gas-modal-page-container.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 dfc011c1e..51a202df1 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 @@ -68,7 +68,7 @@ export default class GasModalPageContainer extends Component { return ( hideModal()} -- cgit From 5e7409482b6fc55eafc330e4bc119f7485f068bb Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 6 Aug 2018 12:04:06 -0230 Subject: Use BEM for css in gas-modal-page-container --- .../gas-modal-page-container.component.js | 18 ++++++++++-------- .../gas-modal-page-container/index.scss | 22 +++++++++++----------- .../gas-modal-page-container-component.test.js | 14 +++++++------- 3 files changed, 28 insertions(+), 26 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 51a202df1..697594ec9 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 @@ -16,24 +16,26 @@ export default class GasModalPageContainer extends Component { renderBasicTabContent () { return ( -
+
) } renderAdvancedTabContent () { return ( -
+
) } renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { return (
-
- {`${this.context.t(totalLabelKey)}:`}{fiatTotal} +
+ {`${this.context.t(totalLabelKey)}:`} + {fiatTotal}
-
- {`${this.context.t('amountPlusTxFee')}`}{cryptoTotal} +
+ {`${this.context.t('amountPlusTxFee')}`} + {cryptoTotal}
) @@ -43,8 +45,8 @@ export default class GasModalPageContainer extends Component { return (
{ mainTabContent() } - { this.renderInfoRow('info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } - { this.renderInfoRow('info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
) } 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 2d2250212..a6609a385 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 @@ -1,13 +1,13 @@ .gas-modal-content { - .basic-tab { + &__basic-tab { height: 219px; } - .advanced-tab { + &__advanced-tab { height: 475px; } - .info-row, .info-row--fade { + &__info-row, &__info-row--fade { width: 100%; background: $polar; padding: 15px 21px; @@ -15,35 +15,35 @@ flex-flow: column; color: $scorpion; - .total-info, .sum-info { + &__total-info, &__sum-info { display: flex; flex-flow: row; justify-content: space-between; } - .total-info { - .total-label { + &__total-info { + &__total-label { font-size: 16px; } - .total-value { + &__total-value { font-size: 16px; font-weight: bold; } } - .sum-info { - .sum-label { + &__sum-info { + &__sum-label { font-size: 12px; } - .sum-value { + &__sum-value { font-size: 14px; } } } - .info-row--fade { + &__info-row--fade { background: white; color: $dusty-gray; } 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 ffe242de2..32f644765 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 @@ -36,7 +36,7 @@ describe('GasModalPageContainer Component', function () { disabled, } = wrapper.find(PageContainer).props() assert.equal(title, 'customGas') - assert.equal(subtitle, 'customGasSpeedUp') + assert.equal(subtitle, 'customGasSubTitle') assert.equal(disabled, false) }) @@ -112,8 +112,8 @@ describe('GasModalPageContainer Component', function () { const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.childAt(1).text(), 'info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') - assert.equal(renderedTabContent.childAt(2).text(), 'info-row,newTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(1).text(), 'gas-modal-content__info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(2).text(), 'gas-modal-content__info-row,newTotal,$20.02 USD,0.06685 ETH') GP.renderInfoRow.restore() }) @@ -128,8 +128,8 @@ describe('GasModalPageContainer Component', function () { const firstChild = renderedInfoRow.childAt(0) const secondhild = renderedInfoRow.childAt(1) - assert.equal(firstChild.props().className, 'total-info') - assert.equal(secondhild.props().className, 'sum-info') + 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') @@ -142,7 +142,7 @@ describe('GasModalPageContainer Component', function () { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() const renderedBasicTabContent = shallow(renderBasicTabContentResult) - assert.equal(renderedBasicTabContent.props().className, 'basic-tab') + assert.equal(renderedBasicTabContent.props().className, 'gas-modal-content__basic-tab') }) }) @@ -150,7 +150,7 @@ describe('GasModalPageContainer Component', function () { it('should render', () => { const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) - assert.equal(renderedAdvancedTabContent.props().className, 'advanced-tab') + assert.equal(renderedAdvancedTabContent.props().className, 'gas-modal-content__advanced-tab') }) }) }) -- cgit From 342dc95410b10f042b3f8ee4135f5fef1fd6fe93 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 2 Aug 2018 13:32:22 -0230 Subject: Adds the content of the advanced tab - w/o chart or dynamic content - to gas customize modal. --- .../advanced-tab-content.component.js | 105 ++++++++++++++++++++ .../advanced-tab-content/index.js | 1 + .../advanced-tab-content/index.scss | 109 +++++++++++++++++++++ .../advanced-tab-content/time-remaining/index.js | 1 + .../advanced-tab-content/time-remaining/index.scss | 13 +++ .../time-remaining/time-remaining.component.js | 33 +++++++ .../time-remaining/time-remaining.utils.js | 11 +++ .../gas-modal-page-container.component.js | 40 ++++++-- .../gas-modal-page-container.container.js | 19 +++- .../gas-modal-page-container/index.scss | 8 ++ 10 files changed, 329 insertions(+), 11 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 new file mode 100644 index 000000000..7ddf13e51 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -0,0 +1,105 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { + MIN_GAS_PRICE_DEC, + MIN_GAS_LIMIT_DEC, +} from '../../../send/send.constants' +import GasSlider from '../../gas-slider' +import TimeRemaining from './time-remaining' + +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, + millisecondsRemaining: PropTypes.number, + } + + gasInput (value, onChange, min, precision, showGWEI) { + return ( +
+ onChange(Number(event.target.value))} + /> + {showGWEI + ? GWEI + : null} +
+ ) + } + + infoButton (onClick) { + return + } + + render () { + const { + updateCustomGasPrice, + updateCustomGasLimit, + millisecondsRemaining, + customGasPrice, + customGasLimit, + } = this.props + + return ( +
+
+
+ New Transaction Fee + ~Transaction Time +
+
+
+ $0.30 +
+ +
+
+
+ Live Transaction Fee Predictions +
+
+
+ { + updateCustomGasPrice(Number(value)) + }} + lowLabel={'Cheaper'} + highLabel={'Faster'} + value={customGasPrice} + step={0.1} + max={200} + min={0} + coloredStart={{}} + /> +
+
+
+
+ Gas Price + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } +
+
+
+ Gas Limit + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } +
+
+
+ ) + } +} 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 new file mode 100644 index 000000000..492037f25 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..5dc30e061 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -0,0 +1,109 @@ +@import './time-remaining/index'; + +.advanced-tab { + display: flex; + flex-flow: column; + border-bottom: 1px solid $alto; + + &__transaction-data-summary, + &__fee-chart-title, + &__gas-edit-row { + padding-left: 24px; + padding-right: 24px; + } + + &__transaction-data-summary { + display: flex; + flex-flow: column; + color: $mid-gray; + margin-top: 12px; + + &__titles, + &__container { + display: flex; + flex-flow: row; + justify-content: space-between; + font-size: 12px; + } + + &__container { + font-size: 26px; + margin-top: 6px; + } + } + + &__fee-chart-title { + font-size: 14px; + color: $scorpion; + margin-top: 22px; + } + + &__fee-chart { + padding-left: 10px; + margin-top: 24px; + height: 134px; + } + + &__slider-container { + padding-left: 27px; + padding-right: 27px; + } + + &__gas-edit-rows { + margin-top: 44px; + height: 87px; + display: flex; + flex-flow: column; + justify-content: space-between; + } + + &__gas-edit-row { + display: flex; + flex-flow: row; + justify-content: space-between; + + &__label { + color: $mid-gray; + font-size: 16px; + + .info-circle { + color: $silver; + margin-left: 10px; + } + } + + + &__input-wrapper { + position: relative; + } + + &__input { + border: 1px solid $dusty-gray; + border-radius: 4px; + color: $mid-gray; + font-size: 16px; + height: 37px; + width: 163px; + padding: 8px 10px 10px 10px; + } + + 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/time-remaining/index.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js new file mode 100644 index 000000000..61b681e1a --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..01bb06268 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss @@ -0,0 +1,13 @@ +.time-remaining { + .minutes-num, .seconds-num { + font-size: 26px; + } + + .seconds-num { + margin-left: 7px; + } + + .minutes-label, .seconds-label { + font-size: 14px; + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..826d41f9c --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js @@ -0,0 +1,33 @@ +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 new file mode 100644 index 000000000..cf43e0acb --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js @@ -0,0 +1,11 @@ +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/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 697594ec9..1d7a9d986 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 @@ -2,6 +2,7 @@ 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' export default class GasModalPageContainer extends Component { static contextTypes = { @@ -10,6 +11,10 @@ export default class GasModalPageContainer extends Component { static propTypes = { hideModal: PropTypes.func, + updateCustomGasPrice: PropTypes.func, + updateCustomGasLimit: PropTypes.func, + customGasPrice: PropTypes.number, + customGasLimit: PropTypes.number, } state = {} @@ -20,9 +25,22 @@ export default class GasModalPageContainer extends Component { ) } - renderAdvancedTabContent () { + renderAdvancedTabContent = () => { + const { + updateCustomGasPrice, + updateCustomGasLimit, + customGasPrice, + customGasLimit, + } = this.props + return ( -
+ ) } @@ -68,14 +86,16 @@ export default class GasModalPageContainer extends Component { const { hideModal } = this.props return ( - hideModal()} - onClose={() => hideModal()} - /> +
+ hideModal()} + onClose={() => hideModal()} + /> +
) } } 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 71c700507..f7ac91a38 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 @@ -1,11 +1,28 @@ import { connect } from 'react-redux' import GasModalPageContainer from './gas-modal-page-container.component' import { hideModal } from '../../../actions' +import { + setCustomGasPrice, + setCustomGasLimit, +} from '../../../ducks/custom-gas' +import { + getCustomGasPrice, + getCustomGasLimit, +} from '../../../selectors/custom-gas' + +const mapStateToProps = state => { + return { + customGasPrice: getCustomGasPrice(state), + customGasLimit: getCustomGasLimit(state), + } +} const mapDispatchToProps = dispatch => { return { hideModal: () => dispatch(hideModal()), + updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), + updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), } } -export default connect(null, mapDispatchToProps)(GasModalPageContainer) +export default connect(mapStateToProps, mapDispatchToProps)(GasModalPageContainer) 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 a6609a385..027165b48 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 @@ -1,3 +1,11 @@ +@import './advanced-tab-content/index'; + +.gas-modal-page-container { + .page-container { + width: 391px; + } +} + .gas-modal-content { &__basic-tab { height: 219px; -- cgit From d55a2615a4af1a0e4d589d0b82904f46cfbff6f7 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 7 Aug 2018 12:27:42 -0230 Subject: Split advanced-tab-content.component.js render() method into smaller pieces; add translations to the same file. --- .../advanced-tab-content.component.js | 81 +++++++++++++--------- .../gas-modal-page-container.component.js | 1 + 2 files changed, 51 insertions(+), 31 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 7ddf13e51..8e593f029 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 @@ -18,6 +18,7 @@ export default class AdvancedTabContent extends Component { customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, millisecondsRemaining: PropTypes.number, + totalFee: PropTypes.string, } gasInput (value, onChange, min, precision, showGWEI) { @@ -40,6 +41,46 @@ export default class AdvancedTabContent extends Component { return } + renderDataSummary (totalFee, millisecondsRemaining) { + return ( +
+
+ { this.context.t('newTransactionFee') } + ~{ this.context.t('transactionTime') } +
+
+
+ {totalFee} +
+ +
+
+ ) + } + + renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { + return ( +
+
+
+ { this.context.t('gasPriceNoDenom') } + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } +
+
+
+ { this.context.t('gasLimit') } + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } +
+
+ ) + } + render () { const { updateCustomGasPrice, @@ -47,26 +88,14 @@ export default class AdvancedTabContent extends Component { millisecondsRemaining, customGasPrice, customGasLimit, + totalFee, } = this.props return (
-
-
- New Transaction Fee - ~Transaction Time -
-
-
- $0.30 -
- -
-
+ { this.renderDataSummary(totalFee, millisecondsRemaining) }
- Live Transaction Fee Predictions + { this.context.t('feeChartTitle') }
@@ -83,22 +112,12 @@ export default class AdvancedTabContent extends Component { coloredStart={{}} />
-
-
-
- Gas Price - { this.infoButton(() => {}) } -
- { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } -
-
-
- Gas Limit - { this.infoButton(() => {}) } -
- { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } -
-
+ { this.renderGasEditRows( + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit + ) }
) } 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 1d7a9d986..e47ebaf65 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 @@ -40,6 +40,7 @@ export default class GasModalPageContainer extends Component { customGasPrice={customGasPrice} customGasLimit={customGasLimit} millisecondsRemaining={91000} + totalFee={'$0.30'} /> ) } -- cgit From 3b9ec8e1bc8f3db9cfd645b10e4908f06096c70c Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 7 Aug 2018 12:29:14 -0230 Subject: Remove gas slider from advance-tab-content.component --- .../advanced-tab-content.component.js | 15 --------------- .../advanced-tab-content/index.scss | 1 + .../gas-customization/gas-modal-page-container/index.scss | 5 +---- 3 files changed, 2 insertions(+), 19 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 8e593f029..a09869a46 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 @@ -4,7 +4,6 @@ import { MIN_GAS_PRICE_DEC, MIN_GAS_LIMIT_DEC, } from '../../../send/send.constants' -import GasSlider from '../../gas-slider' import TimeRemaining from './time-remaining' export default class AdvancedTabContent extends Component { @@ -98,20 +97,6 @@ export default class AdvancedTabContent extends Component { { this.context.t('feeChartTitle') }
-
- { - updateCustomGasPrice(Number(value)) - }} - lowLabel={'Cheaper'} - highLabel={'Faster'} - value={customGasPrice} - step={0.1} - max={200} - min={0} - coloredStart={{}} - /> -
{ this.renderGasEditRows( customGasPrice, updateCustomGasPrice, 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 5dc30e061..0c95afc48 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 @@ -4,6 +4,7 @@ display: flex; flex-flow: column; border-bottom: 1px solid $alto; + height: 430px; &__transaction-data-summary, &__fee-chart-title, 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 027165b48..ff512537e 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 @@ -11,11 +11,8 @@ height: 219px; } - &__advanced-tab { - height: 475px; - } - &__info-row, &__info-row--fade { + .info-row, .info-row--fade { width: 100%; background: $polar; padding: 15px 21px; -- cgit From 99c8804eeb8c3e407fa9f2d806c145113ec6ec2c Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 8 Aug 2018 11:21:06 -0230 Subject: Add tests for advanced-tab-component.js and subcomponents. --- .../advanced-tab-content.component.js | 30 +-- .../tests/advanced-tab-content-component.test.js | 215 +++++++++++++++++++++ .../tests/time-remaining-component.test.js | 30 +++ .../gas-modal-page-container-component.test.js | 18 +- 4 files changed, 275 insertions(+), 18 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 a09869a46..69cd06cde 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 @@ -27,6 +27,8 @@ export default class AdvancedTabContent extends Component { className="advanced-tab__gas-edit-row__input" type="number" value={value} + min={min} + precision={precision} onChange={event => onChange(Number(event.target.value))} /> {showGWEI @@ -59,23 +61,23 @@ export default class AdvancedTabContent extends Component { ) } + renderGasEditRow (labelKey, ...gasInputArgs) { + return ( +
+
+ { this.context.t(labelKey) } + { this.infoButton(() => {}) } +
+ { this.gasInput(...gasInputArgs) } +
+ ) + } + renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
-
-
- { this.context.t('gasPriceNoDenom') } - { this.infoButton(() => {}) } -
- { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } -
-
-
- { this.context.t('gasLimit') } - { this.infoButton(() => {}) } -
- { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } -
+ { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) }
) } 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 new file mode 100644 index 000000000..3efe1d2a9 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -0,0 +1,215 @@ +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 TimeRemaining from '../time-remaining' + +const propsMethodSpies = { + updateCustomGasPrice: sinon.spy(), + updateCustomGasLimit: sinon.spy(), +} + +sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') +sinon.spy(AdvancedTabContent.prototype, 'gasInput') + +describe('AdvancedTabContent Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + }) + + afterEach(() => { + propsMethodSpies.updateCustomGasPrice.resetHistory() + propsMethodSpies.updateCustomGasLimit.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, 4) + + 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')) + }) + }) + + 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).is(TimeRemaining)) + assert.equal(dataNode.children().at(1).props().milliseconds, 'mockMsRemaining') + }) + }) + + describe('renderGasEditRow()', () => { + let gasEditRow + + beforeEach(() => { + AdvancedTabContent.prototype.gasInput.resetHistory() + gasEditRow = shallow(wrapper.instance().renderGasEditRow( + 'mockLabelKey', 'argA', 'argB' + )) + }) + + 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('info-circle')) + }) + + it('should call this.gasInput with the correct args', () => { + const gasInputSpyArgs = AdvancedTabContent.prototype.gasInput.args + assert.deepEqual(gasInputSpyArgs[0], [ 'argA', 'argB' ]) + }) + }) + + describe('renderGasEditRows()', () => { + let gasEditRows + + beforeEach(() => { + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + gasEditRows = shallow(wrapper.instance().renderGasEditRows( + 'mockGasPrice', + () => 'mockUpdateCustomGasPriceReturn', + 'mockGasLimit', + () => 'mockUpdateCustomGasLimitReturn' + )) + }) + + 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), [ + 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true, + ].map(String)) + assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ + 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0', + ].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('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() + gasInput = shallow(wrapper.instance().gasInput( + 321, + value => value + 7, + 0, + 8, + false + )) + }) + + it('should render the input-wrapper root node', () => { + assert(gasInput.hasClass('advanced-tab__gas-edit-row__input-wrapper')) + }) + + it('should render an input, but not a GWEI symbol', () => { + assert.equal(gasInput.children().length, 1) + 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) + assert.equal(inputProps.value, 321) + assert.equal(inputProps.precision, 8) + }) + + 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) + }) + }) + +}) 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 new file mode 100644 index 000000000..d8490272f --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js @@ -0,0 +1,30 @@ +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/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 32f644765..8bf72647a 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 @@ -1,6 +1,6 @@ import React from 'react' import assert from 'assert' -import { shallow } from 'enzyme' +import shallow from '../../../../../lib/shallow-with-context' import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' @@ -17,6 +17,10 @@ describe('GasModalPageContainer Component', function () { beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} + updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} + customGasPrice={21} + customGasLimit={54321} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -147,10 +151,16 @@ describe('GasModalPageContainer Component', function () { }) describe('renderAdvancedTabContent', () => { - it('should render', () => { + it('should render with the correct props', () => { const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() - const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) - assert.equal(renderedAdvancedTabContent.props().className, 'gas-modal-content__advanced-tab') + const advancedTabContentProps = renderAdvancedTabContentResult.props + assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice') + assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit') + assert.equal(advancedTabContentProps.customGasPrice, 21) + assert.equal(advancedTabContentProps.customGasLimit, 54321) + assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) + assert.equal(advancedTabContentProps.totalFee, '$0.30') + assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab')) }) }) }) -- cgit From 57cd721800aff67cd18e9e530d92eb94ff75d473 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 8 Aug 2018 11:40:17 -0230 Subject: Improve styling of advanced-tab-content gasInput row --- .../advanced-tab-content/advanced-tab-content.component.js | 2 +- .../gas-modal-page-container/advanced-tab-content/index.scss | 10 ++++++++-- .../tests/advanced-tab-content-component.test.js | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 69cd06cde..cd5ca7d35 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 @@ -39,7 +39,7 @@ export default class AdvancedTabContent extends Component { } infoButton (onClick) { - return + return } renderDataSummary (totalFee, millisecondsRemaining) { 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 0c95afc48..28e2fde9b 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 @@ -67,9 +67,14 @@ color: $mid-gray; font-size: 16px; - .info-circle { + .fa-info-circle { color: $silver; margin-left: 10px; + cursor: pointer; + } + + .fa-info-circle:hover { + color: $mid-gray; } } @@ -85,7 +90,8 @@ font-size: 16px; height: 37px; width: 163px; - padding: 8px 10px 10px 10px; + padding-left: 8px; + padding-top: 2px; } 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 3efe1d2a9..5cdcf687e 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 @@ -101,7 +101,7 @@ describe('AdvancedTabContent Component', function () { const gasRowLabelChildren = gasEditRow.children().at(0).children() assert.equal(gasRowLabelChildren.length, 2) assert(gasRowLabelChildren.at(0), 'mockLabelKey') - assert(gasRowLabelChildren.at(1).hasClass('info-circle')) + assert(gasRowLabelChildren.at(1).hasClass('fa-info-circle')) }) it('should call this.gasInput with the correct args', () => { @@ -155,7 +155,7 @@ describe('AdvancedTabContent Component', function () { }) it('should render the i element', () => { - assert(infoButton.hasClass('info-circle')) + assert(infoButton.hasClass('fa-info-circle')) }) it('should pass the onClick argument to the i tag onClick prop', () => { -- cgit From 112d18e316df312a648b8c8ac17c201314fc9ed6 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 9 Aug 2018 13:44:03 -0230 Subject: Adds basic tab content to gas customizer, with styled button group (static, for now). --- .../basic-tab-content.component.js | 22 +++++++ .../basic-tab-content/index.js | 1 + .../basic-tab-content/index.scss | 11 ++++ .../tests/basic-tab-content-component.test.js | 71 ++++++++++++++++++++++ .../gas-modal-page-container.component.js | 10 +-- .../gas-modal-page-container.container.js | 29 +++++++++ .../gas-modal-page-container/index.scss | 7 ++- .../gas-modal-page-container-component.test.js | 47 ++++++++++++-- .../gas-modal-page-container-container.test.js | 39 +++++++++++- 9 files changed, 223 insertions(+), 14 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 new file mode 100644 index 000000000..751042871 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import GasPriceButtonGroup from '../../gas-price-button-group' + +export default class BasicTabContent extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + gasPriceButtonGroupProps: PropTypes.object, + } + + render () { + return ( +
+
Suggest gas fee increases
+ +
+ ) + } +} 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 new file mode 100644 index 000000000..078d50fce --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..ba665716c --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -0,0 +1,11 @@ +.basic-tab-content { + display: flex; + flex-direction: column; + align-items: center; + + &__title { + margin-top: 19px; + font-size: 20px; + color: $scorpion; + } +} 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 new file mode 100644 index 000000000..0c9c6ac63 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -0,0 +1,71 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import BasicTabContent from '../basic-tab-content.component' + +import GasPriceButtonGroup from '../../../gas-price-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: 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(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)) + }) + }) +}) 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 e47ebaf65..9a0070b2a 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 @@ -3,6 +3,7 @@ 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 = { @@ -15,13 +16,14 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasPriceButtonGroupProps: PropTypes.object, } state = {} renderBasicTabContent () { return ( -
+ ) } @@ -63,7 +65,7 @@ export default class GasModalPageContainer extends Component { renderTabContent (mainTabContent) { return (
- { mainTabContent() } + { mainTabContent } { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
@@ -74,10 +76,10 @@ export default class GasModalPageContainer extends Component { return ( - { this.renderTabContent(this.renderBasicTabContent) } + { this.renderTabContent(this.renderBasicTabContent()) } - { this.renderTabContent(this.renderAdvancedTabContent) } + { this.renderTabContent(this.renderAdvancedTabContent()) } ) 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 f7ac91a38..2354d578c 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 @@ -10,10 +10,39 @@ import { getCustomGasLimit, } from '../../../selectors/custom-gas' +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, +} + const mapStateToProps = state => { return { customGasPrice: getCustomGasPrice(state), customGasLimit: getCustomGasLimit(state), + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, } } 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 ff512537e..427b58888 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 @@ -1,4 +1,5 @@ @import './advanced-tab-content/index'; +@import './basic-tab-content/index'; .gas-modal-page-container { .page-container { @@ -12,7 +13,7 @@ } - .info-row, .info-row--fade { + &__info-row, &__info-row--fade { width: 100%; background: $polar; padding: 15px 21px; @@ -51,5 +52,7 @@ &__info-row--fade { background: white; color: $dusty-gray; + border-top: 1px solid $mischka; + margin-top: 22px; } -} \ No newline at end of file +} 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 8bf72647a..86286b615 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 @@ -5,12 +5,43 @@ import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' import PageContainer from '../../../page-container' +import BasicTabContent from '../basic-tab-content' +import AdvancedTabContent from '../advanced-tab-content' + import { Tab } from '../../../tabs' const propsMethodSpies = { hideModal: 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, +} + describe('GasModalPageContainer Component', function () { let wrapper @@ -21,6 +52,7 @@ describe('GasModalPageContainer Component', function () { updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} customGasLimit={54321} + gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -90,8 +122,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(GP.renderTabContent.callCount, 2) - assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent]) - assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent]) + assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type) + assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type) GP.renderTabContent.restore() }) @@ -104,8 +136,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(renderedTabContent.props().className, 'gas-modal-content') }) - it('should render the element returned by the passed func as its first child', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + it('should render the passed element as its first child', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(Mock content) const renderedTabContent = shallow(renderTabContentResult) assert(renderedTabContent.childAt(0).equals(Mock content)) }) @@ -145,8 +177,11 @@ describe('GasModalPageContainer Component', function () { describe('renderBasicTabContent', () => { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() - const renderedBasicTabContent = shallow(renderBasicTabContentResult) - assert.equal(renderedBasicTabContent.props().className, 'gas-modal-content__basic-tab') + + assert.deepEqual( + renderBasicTabContentResult.props.gasPriceButtonGroupProps, + mockGasPriceButtonGroupProps + ) }) }) 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 5b133fbe2..119ae640b 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 @@ -2,26 +2,45 @@ import assert from 'assert' import proxyquire from 'proxyquire' import sinon from 'sinon' -// let mapStateToProps +let mapStateToProps let mapDispatchToProps const actionSpies = { hideModal: sinon.spy(), } +const customGasActionSpies = { + setCustomGasPrice: sinon.spy(), + setCustomGasLimit: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md) => { - // mapStateToProps = ms + mapStateToProps = ms mapDispatchToProps = md return () => ({}) }, }, + '../../../selectors/custom-gas': { + getCustomGasPrice: (s) => `mockGasPrice:${s}`, + getCustomGasLimit: (s) => `mockGasLimit:${s}`, + }, '../../../actions': actionSpies, + '../../../ducks/custom-gas': customGasActionSpies, }) describe('gas-modal-page-container container', () => { + describe('mapStateToProps()', () => { + + it('should map the correct properties to props', () => { + assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') + assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') + }) + + }) + describe('mapDispatchToProps()', () => { let dispatchSpy let mapDispatchToPropsObject @@ -39,6 +58,22 @@ describe('gas-modal-page-container container', () => { }) }) + describe('updateCustomGasPrice()', () => { + it('should dispatch a setCustomGasPrice action', () => { + mapDispatchToPropsObject.updateCustomGasPrice() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasPrice.calledOnce) + }) + }) + + describe('updateCustomGasLimit()', () => { + it('should dispatch a setCustomGasLimit action', () => { + mapDispatchToPropsObject.updateCustomGasLimit() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasLimit.calledOnce) + }) + }) + }) }) -- cgit From 0a7dfcd55d02a7204d8f0773ff9d91f325aabea8 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 16 Aug 2018 09:58:27 -0230 Subject: Connect the gas-button-group component to redux and a live api. --- .../basic-tab-content.component.js | 8 ++++- .../gas-modal-page-container.component.js | 4 ++- .../gas-modal-page-container.container.js | 39 +++++----------------- .../gas-modal-page-container-container.test.js | 6 +++- 4 files changed, 24 insertions(+), 33 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 index 751042871..99ef28b5e 100644 --- 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 @@ -15,7 +15,13 @@ export default class BasicTabContent extends Component { return (
Suggest gas fee increases
- + console.log('New Price:', newPrice)} + />
) } 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 9a0070b2a..399520baf 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 @@ -23,7 +23,9 @@ export default class GasModalPageContainer extends Component { renderBasicTabContent () { return ( - + ) } 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 2354d578c..ebdd035ea 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 @@ -4,45 +4,23 @@ import { hideModal } from '../../../actions' import { setCustomGasPrice, setCustomGasLimit, -} from '../../../ducks/custom-gas' +} from '../../../ducks/gas.duck' import { getCustomGasPrice, getCustomGasLimit, + getRenderableBasicEstimateData, + getBasicGasEstimateLoadingStatus, } from '../../../selectors/custom-gas' -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, -} - const mapStateToProps = state => { + const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) return { customGasPrice: getCustomGasPrice(state), customGasLimit: getCustomGasLimit(state), - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + gasPriceButtonGroupProps: { + buttonDataLoading, + gasButtonInfo: getRenderableBasicEstimateData(state), + }, } } @@ -51,6 +29,7 @@ const mapDispatchToProps = dispatch => { hideModal: () => dispatch(hideModal()), updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), } } 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 119ae640b..4067265b5 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 @@ -25,9 +25,11 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../selectors/custom-gas': { getCustomGasPrice: (s) => `mockGasPrice:${s}`, getCustomGasLimit: (s) => `mockGasLimit:${s}`, + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, + getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`, }, '../../../actions': actionSpies, - '../../../ducks/custom-gas': customGasActionSpies, + '../../../ducks/gas.duck': customGasActionSpies, }) describe('gas-modal-page-container container', () => { @@ -37,6 +39,8 @@ describe('gas-modal-page-container container', () => { it('should map the correct properties to props', () => { assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') + assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState') + assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState') }) }) -- cgit From d07d40cf7cf013bd9b9968fa6bc37bcfd1367cf9 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Sun, 9 Sep 2018 13:48:34 -0230 Subject: Improvements to propdefaults in button-group.component and basic-tab-content.component --- .../basic-tab-content/basic-tab-content.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 index 99ef28b5e..164da4a32 100644 --- 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 @@ -16,11 +16,11 @@ export default class BasicTabContent extends Component {
Suggest gas fee increases
console.log('New Price:', newPrice)} + {...this.props.gasPriceButtonGroupProps} />
) -- cgit From 58feb24fa72bac5c79daa96956810dd2233adf02 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Sun, 9 Sep 2018 15:17:49 -0230 Subject: Styling fixes for gas customization advanced tab content. --- .../advanced-tab-content/advanced-tab-content.component.js | 2 +- .../gas-modal-page-container/advanced-tab-content/index.scss | 1 - .../gas-modal-page-container/basic-tab-content/index.scss | 1 + ui/app/components/gas-customization/gas-modal-page-container/index.scss | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 cd5ca7d35..38fa117f9 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 @@ -39,7 +39,7 @@ export default class AdvancedTabContent extends Component { } infoButton (onClick) { - return + return } renderDataSummary (totalFee, millisecondsRemaining) { 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 28e2fde9b..aced75449 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,7 +3,6 @@ .advanced-tab { display: flex; flex-flow: column; - border-bottom: 1px solid $alto; height: 430px; &__transaction-data-summary, 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 ba665716c..d5eb5d414 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 @@ -2,6 +2,7 @@ display: flex; flex-direction: column; align-items: center; + margin-bottom: 22px; &__title { margin-top: 19px; 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 427b58888..f02045fe3 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 @@ -53,6 +53,5 @@ background: white; color: $dusty-gray; border-top: 1px solid $mischka; - margin-top: 22px; } } -- cgit From 7de3f22d63748ed5a81e947755db056d4cdef3db Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 13 Sep 2018 06:17:05 -0230 Subject: Connects remained of the gas customization component to redux. --- .../advanced-tab-content.component.js | 8 +- .../tests/advanced-tab-content-component.test.js | 4 +- .../basic-tab-content.component.js | 2 - .../gas-modal-page-container.component.js | 80 ++++++++---- .../gas-modal-page-container.container.js | 141 +++++++++++++++++++-- .../gas-modal-page-container-component.test.js | 97 ++++++++------ .../gas-modal-page-container-container.test.js | 122 +++++++++++++++--- 7 files changed, 354 insertions(+), 100 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 38fa117f9..56d10cc2b 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,9 +1,5 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { - MIN_GAS_PRICE_DEC, - MIN_GAS_LIMIT_DEC, -} from '../../../send/send.constants' import TimeRemaining from './time-remaining' export default class AdvancedTabContent extends Component { @@ -76,8 +72,8 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
- { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } + { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
) } 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 5cdcf687e..0ef286b8a 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 @@ -138,10 +138,10 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true, + 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0', + 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0, ].map(String)) }) }) 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 index 164da4a32..0e5f15519 100644 --- 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 @@ -17,9 +17,7 @@ export default class BasicTabContent extends Component {
Suggest gas fee increases
console.log('New Price:', newPrice)} {...this.props.gasPriceButtonGroupProps} />
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 399520baf..89065472d 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 @@ -17,34 +17,42 @@ export default class GasModalPageContainer extends Component { customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, gasPriceButtonGroupProps: PropTypes.object, + infoRowProps: PropTypes.shape({ + originalTotalFiat: PropTypes.string, + originalTotalEth: PropTypes.string, + newTotalFiat: PropTypes.string, + newTotalEth: PropTypes.string, + }), + onSubmit: PropTypes.func, + customGasPriceInHex: PropTypes.string, + customGasLimitInHex: PropTypes.string, } state = {} - renderBasicTabContent () { + renderBasicTabContent (gasPriceButtonGroupProps) { return ( ) } - renderAdvancedTabContent = () => { - const { - updateCustomGasPrice, - updateCustomGasLimit, - customGasPrice, - customGasLimit, - } = this.props - + renderAdvancedTabContent ({ + convertThenUpdateCustomGasPrice, + convertThenUpdateCustomGasLimit, + customGasPrice, + customGasLimit, + newTotalFiat, + }) { return ( ) } @@ -64,41 +72,67 @@ export default class GasModalPageContainer extends Component { ) } - renderTabContent (mainTabContent) { + renderInfoRows (originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) { return ( -
- { mainTabContent } - { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } - { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } +
+ { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) } + { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) }
) } - renderTabs () { + renderTabs ({ + originalTotalFiat, + originalTotalEth, + newTotalFiat, + newTotalEth, + }, + { + gasPriceButtonGroupProps, + ...advancedTabProps + }) { return ( - { this.renderTabContent(this.renderBasicTabContent()) } +
+ { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
- { this.renderTabContent(this.renderAdvancedTabContent()) } +
+ { this.renderAdvancedTabContent(advancedTabProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
) } render () { - const { hideModal } = this.props + const { + hideModal, + infoRowProps, + onSubmit, + customGasPriceInHex, + customGasLimitInHex, + ...tabProps + } = this.props return (
hideModal()} onClose={() => hideModal()} + onSubmit={() => { + onSubmit(customGasLimitInHex, customGasPriceInHex) + hideModal() + }} + submitText={this.context.t('save')} />
) 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 ebdd035ea..7e2a7e144 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 @@ -1,36 +1,161 @@ import { connect } from 'react-redux' +import { pipe, partialRight } from 'ramda' import GasModalPageContainer from './gas-modal-page-container.component' -import { hideModal } from '../../../actions' +import { + hideModal, + setGasLimit, + setGasPrice, +} from '../../../actions' import { setCustomGasPrice, setCustomGasLimit, } from '../../../ducks/gas.duck' +import { + updateGasAndCalculate, +} from '../../../ducks/confirm-transaction.duck' +import { + getCurrentCurrency, + conversionRateSelector as getConversionRate, + getSelectedToken, +} from '../../../selectors.js' import { getCustomGasPrice, getCustomGasLimit, getRenderableBasicEstimateData, getBasicGasEstimateLoadingStatus, + getAveragePriceEstimateInHexWEI, + getDefaultActiveButtonIndex, } from '../../../selectors/custom-gas' +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, +} from '../../send/send.utils' +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 customGasPriceInHex = getCustomGasPrice(state) + const customGasLimitInHex = getCustomGasLimit(state) + const customGasTotal = calcGasTotal(customGasLimitInHex || gasLimit, customGasPriceInHex || gasPrice) + + const gasButtonInfo = getRenderableBasicEstimateData(state) + + const currentCurrency = getCurrentCurrency(state) + const conversionRate = getConversionRate(state) + + const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) + return { - customGasPrice: getCustomGasPrice(state), - customGasLimit: getCustomGasLimit(state), + isConfirm: isConfirm(state), + customGasPriceInHex, + customGasLimitInHex, + customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice), + customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit), + newTotalFiat, gasPriceButtonGroupProps: { buttonDataLoading, - gasButtonInfo: getRenderableBasicEstimateData(state), + defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customGasPriceInHex, gasPrice), + gasButtonInfo, + }, + infoRowProps: { + originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), + originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), + newTotalFiat, + newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), }, } } const mapDispatchToProps = dispatch => { + const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice))) + return { hideModal: () => dispatch(hideModal()), - updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), - updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), - handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + 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) => { + return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) + }, } } -export default connect(mapStateToProps, mapDispatchToProps)(GasModalPageContainer) +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { gasPriceButtonGroupProps, isConfirm } = stateProps + const { + updateCustomGasPrice: dispatchUpdateCustomGasPrice, + setGasData: dispatchSetGasData, + updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, + ...otherDispatchProps + } = dispatchProps + + return { + ...stateProps, + ...otherDispatchProps, + ...ownProps, + onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData, + gasPriceButtonGroupProps: { + ...gasPriceButtonGroupProps, + handleGasPriceSelection: dispatchUpdateCustomGasPrice, + }, + } +} + +export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(GasModalPageContainer) + +function isConfirm (state) { + return Boolean(Object.keys(state.confirmTransaction.txData).length) +} + +function calcCustomGasPrice (customGasPriceInHex, gasPrice) { + return Number(hexWEIToDecGWEI(customGasPriceInHex || gasPrice)) +} + +function calcCustomGasLimit (customGasLimitInHex, gasLimit) { + return parseInt(customGasLimitInHex || gasLimit, 16) +} + +function getTxParams (state) { + const { confirmTransaction: { txData }, metamask: { send } } = state + + return txData.txParams || { + from: send.from, + gas: send.gasLimit, + gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state), + 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) +} 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 86286b615..c41adca83 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 @@ -5,13 +5,12 @@ import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' import PageContainer from '../../../page-container' -import BasicTabContent from '../basic-tab-content' -import AdvancedTabContent from '../advanced-tab-content' import { Tab } from '../../../tabs' const propsMethodSpies = { hideModal: sinon.spy(), + onSubmit: sinon.spy(), } const mockGasPriceButtonGroupProps = { @@ -41,18 +40,29 @@ const mockGasPriceButtonGroupProps = { noButtonActiveByDefault: true, showCheck: true, } +const mockInfoRowProps = { + originalTotalFiat: 'mockOriginalTotalFiat', + originalTotalEth: 'mockOriginalTotalEth', + newTotalFiat: 'mockNewTotalFiat', + newTotalEth: 'mockNewTotalEth', +} +const GP = GasModalPageContainer.prototype describe('GasModalPageContainer Component', function () { let wrapper beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} + infoRowProps={mockInfoRowProps} + customGasPriceInHex={'mockCustomGasPriceInHex'} + customGasLimitInHex={'mockCustomGasLimitInHex'} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -89,7 +99,7 @@ describe('GasModalPageContainer Component', function () { }) it('should pass the correct renderTabs property to PageContainer', () => { - sinon.stub(GasModalPageContainer.prototype, 'renderTabs').returns('mockTabs') + 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') @@ -98,8 +108,23 @@ describe('GasModalPageContainer Component', function () { }) 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() + const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + otherProps: 'mockAdvancedTabProps', + }) const renderedTabs = shallow(renderTabsResult) assert.equal(renderedTabs.props().className, 'tabs') @@ -113,45 +138,28 @@ describe('GasModalPageContainer Component', function () { assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') }) - it('should render the expected children of each tab', () => { - const GP = GasModalPageContainer.prototype - sinon.spy(GP, 'renderTabContent') - assert.equal(GP.renderTabContent.callCount, 0) + 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() + wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - assert.equal(GP.renderTabContent.callCount, 2) + assert.equal(GP.renderBasicTabContent.callCount, 1) + assert.equal(GP.renderAdvancedTabContent.callCount, 1) - assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type) - assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type) - - GP.renderTabContent.restore() + assert.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps) + assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { otherProps: 'mockAdvancedTabProps' }) }) - }) - describe('renderTabContent', () => { - it('should render a root gas-modal-content div', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(() => {}) - const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.props().className, 'gas-modal-content') - }) - - it('should render the passed element as its first child', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(Mock content) - const renderedTabContent = shallow(renderTabContentResult) - assert(renderedTabContent.childAt(0).equals(Mock content)) - }) + it('should call renderInfoRows with the expected props', () => { + assert.equal(GP.renderInfoRows.callCount, 0) - it('should render the element results of renderInfoRow calls as second and third childs', () => { - const GP = GasModalPageContainer.prototype - sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(',')) + wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) - const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.childAt(1).text(), 'gas-modal-content__info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') - assert.equal(renderedTabContent.childAt(2).text(), 'gas-modal-content__info-row,newTotal,$20.02 USD,0.06685 ETH') + assert.equal(GP.renderInfoRows.callCount, 2) - GP.renderInfoRow.restore() + assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) + assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) }) }) @@ -176,7 +184,7 @@ describe('GasModalPageContainer Component', function () { describe('renderBasicTabContent', () => { it('should render', () => { - const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() + const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps) assert.deepEqual( renderBasicTabContentResult.props.gasPriceButtonGroupProps, @@ -187,15 +195,20 @@ describe('GasModalPageContainer Component', function () { describe('renderAdvancedTabContent', () => { it('should render with the correct props', () => { - const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() + const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent({ + convertThenUpdateCustomGasPrice: () => 'mockConvertThenUpdateCustomGasPrice', + convertThenUpdateCustomGasLimit: () => 'mockConvertThenUpdateCustomGasLimit', + customGasPrice: 123, + customGasLimit: 456, + newTotalFiat: '$0.30', + }) const advancedTabContentProps = renderAdvancedTabContentResult.props - assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice') - assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit') - assert.equal(advancedTabContentProps.customGasPrice, 21) - assert.equal(advancedTabContentProps.customGasLimit, 54321) + assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') + assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') + assert.equal(advancedTabContentProps.customGasPrice, 123) + assert.equal(advancedTabContentProps.customGasLimit, 456) assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) assert.equal(advancedTabContentProps.totalFee, '$0.30') - assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab')) }) }) }) 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 4067265b5..e01fd3898 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 @@ -7,13 +7,19 @@ let mapDispatchToProps const actionSpies = { hideModal: sinon.spy(), + setGasLimit: sinon.spy(), + setGasPrice: sinon.spy(), } -const customGasActionSpies = { +const gasActionSpies = { setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), } +const confirmTransactionActionSpies = { + updateGasAndCalculate: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md) => { @@ -23,13 +29,13 @@ proxyquire('../gas-modal-page-container.container.js', { }, }, '../../../selectors/custom-gas': { - getCustomGasPrice: (s) => `mockGasPrice:${s}`, - getCustomGasLimit: (s) => `mockGasLimit:${s}`, - getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, - getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`, + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, + getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`, + getDefaultActiveButtonIndex: (a, b, c) => a + b + c, }, '../../../actions': actionSpies, - '../../../ducks/gas.duck': customGasActionSpies, + '../../../ducks/gas.duck': gasActionSpies, + '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, }) describe('gas-modal-page-container container', () => { @@ -37,10 +43,54 @@ describe('gas-modal-page-container container', () => { describe('mapStateToProps()', () => { it('should map the correct properties to props', () => { - assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') - assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') - assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState') - assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState') + const mockState2 = { + metamask: { + send: { + gasLimit: '16', + gasPrice: '32', + amount: '64', + }, + currentCurrency: 'abc', + conversionRate: 50, + }, + gas: { + customData: { + limit: 'aaaaaaaa', + price: 'ffffffff', + }, + }, + confirmTransaction: { + txData: { + txParams: { + gas: '0x1600000', + gasPrice: '0x3200000', + value: '0x640000000000000', + }, + }, + }, + } + const result2 = mapStateToProps(mockState2) + + assert.deepEqual(result2, { + isConfirm: true, + customGasPriceInHex: 'ffffffff', + customGasLimitInHex: 'aaaaaaaa', + customGasPrice: 4.294967295, + customGasLimit: 2863311530, + newTotalFiat: '637.41', + gasPriceButtonGroupProps: + { + buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000', + gasButtonInfo: 'mockRenderableBasicEstimateData:3', + }, + infoRowProps: { + originalTotalFiat: '22.58', + originalTotalEth: '0.451569 ETH', + newTotalFiat: '637.41', + newTotalEth: '12.748189 ETH', + }, + }) }) }) @@ -54,6 +104,12 @@ describe('gas-modal-page-container container', () => { mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) }) + afterEach(() => { + actionSpies.hideModal.resetHistory() + gasActionSpies.setCustomGasPrice.resetHistory() + gasActionSpies.setCustomGasLimit.resetHistory() + }) + describe('hideModal()', () => { it('should dispatch a hideModal action', () => { mapDispatchToPropsObject.hideModal() @@ -63,18 +119,50 @@ describe('gas-modal-page-container container', () => { }) describe('updateCustomGasPrice()', () => { - it('should dispatch a setCustomGasPrice action', () => { - mapDispatchToPropsObject.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(customGasActionSpies.setCustomGasPrice.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('updateCustomGasLimit()', () => { - it('should dispatch a setCustomGasLimit action', () => { - mapDispatchToPropsObject.updateCustomGasLimit() + describe('updateConfirmTxGasAndCalculate()', () => { + it('should dispatch a updateGasAndCalculate action with the correct props', () => { + mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') assert(dispatchSpy.calledOnce) - assert(customGasActionSpies.setCustomGasLimit.calledOnce) + assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) + assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) }) }) -- cgit From b567c78bcae73e9c73b69040d22e096e4f876a2b Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 13 Sep 2018 10:05:17 -0230 Subject: Integrate gas buttons with the send screen. --- .../gas-modal-page-container.component.js | 16 ++++++++++------ .../gas-modal-page-container.container.js | 13 ++++++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 89065472d..db730458d 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 @@ -89,16 +89,20 @@ export default class GasModalPageContainer extends Component { }, { gasPriceButtonGroupProps, + hideBasic, ...advancedTabProps }) { return ( - -
- { this.renderBasicTabContent(gasPriceButtonGroupProps) } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } -
-
+ {hideBasic + ? null + : +
+ { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
+
+ }
{ this.renderAdvancedTabContent(advancedTabProps) } 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 7e2a7e144..a150e5009 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 @@ -10,6 +10,9 @@ import { setCustomGasPrice, setCustomGasLimit, } from '../../../ducks/gas.duck' +import { + hideGasButtonGroup, +} from '../../../ducks/send.duck' import { updateGasAndCalculate, } from '../../../ducks/confirm-transaction.duck' @@ -59,7 +62,10 @@ const mapStateToProps = state => { const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) + const hideBasic = state.appState.modal.modalState.props.hideBasic + return { + hideBasic, isConfirm: isConfirm(state), customGasPriceInHex, customGasLimitInHex, @@ -95,6 +101,7 @@ const mapDispatchToProps = dispatch => { updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, + hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), } } @@ -102,6 +109,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { const { gasPriceButtonGroupProps, isConfirm } = stateProps const { updateCustomGasPrice: dispatchUpdateCustomGasPrice, + hideGasButtonGroup: dispatchHideGasButtonGroup, setGasData: dispatchSetGasData, updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, ...otherDispatchProps @@ -111,7 +119,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData, + onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => { + dispatchSetGasData(newLimit, newPrice) + dispatchHideGasButtonGroup() + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, -- cgit From 5354325fab9b9ab3091e3c49e6b940fa713d1799 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 20 Sep 2018 01:46:43 -0230 Subject: Test updates and additions for button integration with send screen. --- .../gas-modal-page-container.component.js | 23 +++-- .../gas-modal-page-container.container.js | 10 +- .../gas-modal-page-container-component.test.js | 13 +++ .../gas-modal-page-container-container.test.js | 114 ++++++++++++++++++++- 4 files changed, 141 insertions(+), 19 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 db730458d..41fe901fa 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 @@ -92,23 +92,24 @@ export default class GasModalPageContainer extends Component { hideBasic, ...advancedTabProps }) { + let tabsToRender = [ + { name: 'basic', content: this.renderBasicTabContent(gasPriceButtonGroupProps) }, + { name: 'advanced', content: this.renderAdvancedTabContent(advancedTabProps) }, + ] + + if (hideBasic) { + tabsToRender = tabsToRender.slice(1) + } + return ( - {hideBasic - ? null - : + {tabsToRender.map(({ name, content }, i) =>
- { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { content } { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
- } - -
- { this.renderAdvancedTabContent(advancedTabProps) } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } -
-
+ )}
) } 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 a150e5009..f9ed1cebb 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 @@ -119,10 +119,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => { - dispatchSetGasData(newLimit, newPrice) - dispatchHideGasButtonGroup() - }, + onSubmit: isConfirm + ? dispatchUpdateConfirmTxGasAndCalculate + : (newLimit, newPrice) => { + dispatchSetGasData(newLimit, newPrice) + dispatchHideGasButtonGroup() + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, 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 c41adca83..fdd7709d9 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 @@ -161,6 +161,19 @@ describe('GasModalPageContainer Component', function () { assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) }) + + 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('renderInfoRow', () => { 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 e01fd3898..238f27ed6 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 @@ -4,6 +4,7 @@ import sinon from 'sinon' let mapStateToProps let mapDispatchToProps +let mergeProps const actionSpies = { hideModal: sinon.spy(), @@ -20,11 +21,16 @@ const confirmTransactionActionSpies = { updateGasAndCalculate: sinon.spy(), } +const sendActionSpies = { + hideGasButtonGroup: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { - connect: (ms, md) => { + connect: (ms, md, mp) => { mapStateToProps = ms mapDispatchToProps = md + mergeProps = mp return () => ({}) }, }, @@ -36,6 +42,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../actions': actionSpies, '../../../ducks/gas.duck': gasActionSpies, '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, + '../../../ducks/send.duck': sendActionSpies, }) describe('gas-modal-page-container container', () => { @@ -44,6 +51,15 @@ describe('gas-modal-page-container container', () => { it('should map the correct properties to props', () => { const mockState2 = { + appState: { + modal: { + modalState: { + props: { + hideBasic: true, + }, + }, + }, + }, metamask: { send: { gasLimit: '16', @@ -80,10 +96,11 @@ describe('gas-modal-page-container container', () => { newTotalFiat: '637.41', gasPriceButtonGroupProps: { - buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000', - gasButtonInfo: 'mockRenderableBasicEstimateData:3', + buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff0x3200000', + gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + hideBasic: true, infoRowProps: { originalTotalFiat: '22.58', originalTotalEth: '0.451569 ETH', @@ -110,6 +127,14 @@ describe('gas-modal-page-container container', () => { gasActionSpies.setCustomGasLimit.resetHistory() }) + describe('hideGasButtonGroup()', () => { + it('should dispatch a hideGasButtonGroup action', () => { + mapDispatchToPropsObject.hideGasButtonGroup() + assert(dispatchSpy.calledOnce) + assert(sendActionSpies.hideGasButtonGroup.calledOnce) + }) + }) + describe('hideModal()', () => { it('should dispatch a hideModal action', () => { mapDispatchToPropsObject.hideModal() @@ -168,4 +193,85 @@ describe('gas-modal-page-container container', () => { }) + 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(), + } + ownProps = { someOwnProp: 123 } + }) + 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) + + result.onSubmit() + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + 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) + + 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.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) + }) + }) + }) -- cgit 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 ++++--- 10 files changed, 254 insertions(+), 145 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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) }) }) -- cgit From 6f8e2b1ad94fd70c3be976ef88179dc00ceebb45 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 9 Oct 2018 14:23:48 -0230 Subject: Clean up for advanced gas tab customization changes. --- .../tests/advanced-tab-content-component.test.js | 4 ---- .../gas-modal-page-container.component.js | 28 ++++++++++------------ 2 files changed, 13 insertions(+), 19 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 1489c7696..14863e59d 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 @@ -68,10 +68,6 @@ describe('AdvancedTabContent Component', function () { 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, ]) }) - - it('should call renderGasEditRows with the expected params', () => { - - }) }) describe('renderDataSummary()', () => { 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 07e55a1f0..88ef921c5 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 @@ -52,32 +52,30 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={convertThenUpdateCustomGasLimit} customGasPrice={customGasPrice} customGasLimit={customGasLimit} - timeRemaining={'1 min 31 sec'} + timeRemaining="1 min 31 sec" totalFee={newTotalFiat} /> ) } renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { - const baseClassName = 'gas-modal-content__info-row' - return (
-
-
- {`Send Amount`} - {sendAmount} +
+
+ {this.context.t('sendAmount')} + {sendAmount}
-
- {`Transaction Fee`} - {transactionFee} +
+ {this.context.t('transactionFee')} + {transactionFee}
-
- {`New Total`} - {newTotalEth} +
+ {this.context.t('newTotal')} + {newTotalEth}
-
- {newTotalFiat} +
+ {newTotalFiat}
-- cgit From 6dd1028c71a343b2a60768bf988ba0ed33c84fb3 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 10 Oct 2018 20:36:14 -0230 Subject: Lint and unit test fixes. --- .../tests/gas-modal-page-container-component.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 714f01538..bb1a28136 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 @@ -229,9 +229,9 @@ describe('GasModalPageContainer Component', function () { 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(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') }) }) -- cgit From 0ba6f7d9bb5c2183d8a370fd0955e18d45616207 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 20 Sep 2018 13:36:23 -0230 Subject: Adds not yet functional gas price chart. --- .../advanced-tab-content.component.js | 5 ++++ .../advanced-tab-content/index.scss | 33 +++++++++++++++------- .../tests/advanced-tab-content-component.test.js | 4 ++- .../gas-modal-page-container.container.js | 2 +- .../gas-modal-page-container/index.scss | 3 +- 5 files changed, 34 insertions(+), 13 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 5218dd477..f90da0a88 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 @@ -94,7 +94,12 @@ export default class AdvancedTabContent extends Component { customGasLimit, updateCustomGasLimit ) } +
Live Gas Price Predictions
+
+ Slower + Faster +
) 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 ae99ba4aa..9c89688e2 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 @@ -38,19 +38,32 @@ } } - &__fee-chart-title { - font-size: 14px; - color: $scorpion; - margin-top: 22px; - } - &__fee-chart { - padding-left: 10px; margin-top: 8px; - height: 258px; + 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; + margin-bottom: 11px; + } + + &__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 { @@ -59,11 +72,11 @@ } &__gas-edit-rows { - height: 87px; + height: 73px; display: flex; flex-flow: row; justify-content: space-between; - margin-left: 10px; + margin-left: 20px; margin-right: 10px; margin-top: 9px; } 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 14863e59d..27a2326b8 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 @@ -54,7 +54,9 @@ describe('AdvancedTabContent Component', function () { const feeChartDiv = advancedTabChildren.at(1) assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) - assert(feeChartDiv.childAt(1).is(GasPriceChart)) + 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 call renderDataSummary with the expected params', () => { 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 ae233578b..0d8d9d8e4 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 @@ -154,7 +154,7 @@ function calcCustomGasLimit (customGasLimitInHex) { function getTxParams (state) { const { confirmTransaction: { txData }, metamask: { send } } = state - + console.log('txData', txData) return txData.txParams || { from: send.from, gas: send.gasLimit, 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 c49d69bf7..debd9b5ee 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 @@ -3,7 +3,8 @@ .gas-modal-page-container { .page-container { - width: 391px; + max-width: 391px; + min-height: 585px; &__header { padding: 0px; -- cgit From 2dbae581ac3f9190ddd1c3457bd51b41eef8051b Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 3 Oct 2018 10:50:05 -0230 Subject: Gas price chart improvements, redesign, bug fixes, and set up to receive external data --- .../gas-modal-page-container/advanced-tab-content/index.scss | 1 - .../gas-modal-page-container/gas-modal-page-container.component.js | 3 +++ .../gas-modal-page-container/gas-modal-page-container.container.js | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 9c89688e2..0fc9f4578 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 @@ -50,7 +50,6 @@ font-size: 12px; color: #313A5E; margin-left: 22px; - margin-bottom: 11px; } &__speed-buttons { 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 88ef921c5..ac5981ab7 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 @@ -27,6 +27,7 @@ export default class GasModalPageContainer extends Component { customModalGasPriceInHex: PropTypes.string, customModalGasLimitInHex: PropTypes.string, cancelAndClose: PropTypes.func, + transactionFee: PropTypes.string, } state = {} @@ -46,6 +47,7 @@ export default class GasModalPageContainer extends Component { customGasLimit, newTotalFiat, }) { + const { transactionFee } = this.props return ( ) 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 0d8d9d8e4..9d6dd3fb5 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 @@ -73,6 +73,7 @@ const mapStateToProps = state => { customGasPrice: calcCustomGasPrice(customModalGasPriceInHex), customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, + transactionFee: addHexWEIsToRenderableFiat('0x0', customGasTotal, currentCurrency, conversionRate), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), -- cgit From a2bbf504b891a63f32070961118ec1ae6fa5fdd8 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 9 Oct 2018 14:05:54 -0230 Subject: Read only connection of gas price chart to redux --- .../advanced-tab-content/advanced-tab-content.component.js | 4 +++- .../gas-modal-page-container/gas-modal-page-container.component.js | 2 ++ .../gas-modal-page-container/gas-modal-page-container.container.js | 4 +++- .../tests/gas-modal-page-container-container.test.js | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 f90da0a88..44aba358c 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 @@ -15,6 +15,7 @@ export default class AdvancedTabContent extends Component { millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, timeRemaining: PropTypes.string, + gasChartProps: PropTypes.object, } gasInput (value, onChange, min, precision, showGWEI) { @@ -82,6 +83,7 @@ export default class AdvancedTabContent extends Component { customGasPrice, customGasLimit, totalFee, + gasChartProps, } = this.props return ( @@ -95,7 +97,7 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit ) }
Live Gas Price Predictions
- +
Slower Faster 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 ac5981ab7..de14e1b38 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 @@ -46,6 +46,7 @@ export default class GasModalPageContainer extends Component { customGasPrice, customGasLimit, newTotalFiat, + gasChartProps, }) { const { transactionFee } = this.props return ( @@ -57,6 +58,7 @@ export default class GasModalPageContainer extends Component { timeRemaining="1 min 31 sec" transactionFee={transactionFee} totalFee={newTotalFiat} + gasChartProps={gasChartProps} /> ) } 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 9d6dd3fb5..84eae1880 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 @@ -73,12 +73,14 @@ const mapStateToProps = state => { customGasPrice: calcCustomGasPrice(customModalGasPriceInHex), customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, - transactionFee: addHexWEIsToRenderableFiat('0x0', customGasTotal, currentCurrency, conversionRate), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), gasButtonInfo, }, + gasChartProps: { + priceAndTimeEstimates: state.gas.priceAndTimeEstimates, + }, infoRowProps: { originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), 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 3d9fb2624..c16a07b76 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 @@ -75,6 +75,7 @@ describe('gas-modal-page-container container', () => { limit: 'aaaaaaaa', price: 'ffffffff', }, + priceAndTimeEstimates: 'mockPriceAndTimeEstimates', }, confirmTransaction: { txData: { @@ -95,6 +96,9 @@ describe('gas-modal-page-container container', () => { newTotalFiat: '637.41', customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', + gasChartProps: { + priceAndTimeEstimates: 'mockPriceAndTimeEstimates', + }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', -- cgit From cd32c58fb4bcd731d8a83d354c9b01a38c8df219 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 10 Oct 2018 13:36:38 -0230 Subject: Complete integration of gas chart with redux. --- .../advanced-tab-content.component.js | 2 +- .../gas-modal-page-container.component.js | 3 ++- .../gas-modal-page-container.container.js | 31 +++++++++++++++++++++- .../gas-modal-page-container-component.test.js | 2 ++ .../gas-modal-page-container-container.test.js | 16 +++++++++-- 5 files changed, 49 insertions(+), 5 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 44aba358c..4dd18ce2b 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 @@ -97,7 +97,7 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit ) }
Live Gas Price Predictions
- +
Slower Faster 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 de14e1b38..8f23b22e0 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 @@ -47,6 +47,7 @@ export default class GasModalPageContainer extends Component { customGasLimit, newTotalFiat, gasChartProps, + currentTimeEstimate, }) { const { transactionFee } = this.props return ( @@ -55,7 +56,7 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={convertThenUpdateCustomGasLimit} customGasPrice={customGasPrice} customGasLimit={customGasLimit} - timeRemaining="1 min 31 sec" + timeRemaining={currentTimeEstimate} transactionFee={transactionFee} totalFee={newTotalFiat} gasChartProps={gasChartProps} 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 84eae1880..3a62d21cc 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 @@ -10,6 +10,7 @@ import { setCustomGasPrice, setCustomGasLimit, resetCustomData, + setCustomTimeEstimate, } from '../../../ducks/gas.duck' import { hideGasButtonGroup, @@ -29,6 +30,7 @@ import { getBasicGasEstimateLoadingStatus, getAveragePriceEstimateInHexWEI, getDefaultActiveButtonIndex, + formatTimeEstimate, } from '../../../selectors/custom-gas' import { formatCurrency, @@ -65,20 +67,24 @@ const mapStateToProps = state => { const hideBasic = state.appState.modal.modalState.props.hideBasic + const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex) + return { hideBasic, isConfirm: isConfirm(state), customModalGasPriceInHex, customModalGasLimitInHex, - customGasPrice: calcCustomGasPrice(customModalGasPriceInHex), + customGasPrice, customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, + currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, state.gas.priceAndTimeEstimates), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), gasButtonInfo, }, gasChartProps: { + currentPrice: customGasPrice, priceAndTimeEstimates: state.gas.priceAndTimeEstimates, }, infoRowProps: { @@ -111,6 +117,7 @@ const mapDispatchToProps = dispatch => { return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), + setCustomTimeEstimate: (timeEstimateInSeconds) => dispatch(setCustomTimeEstimate(timeEstimateInSeconds)), } } @@ -181,3 +188,25 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver partialRight(formatCurrency, [convertedCurrency]), )(aHexWEI, bHexWEI) } + +function getRenderableTimeEstimate (currentGasPrice, priceAndTimeEstimates) { + const gasPrices = priceAndTimeEstimates.map(({ gasprice }) => gasprice) + const estimatedTimes = priceAndTimeEstimates.map(({ expectedTime }) => expectedTime) + + const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => { + return e <= currentGasPrice && a[i + 1] >= currentGasPrice + }) + const closestHigherValueIndex = gasPrices.findIndex((e, i, a) => { + return e > currentGasPrice + }) + + const closestLowerValue = gasPrices[closestLowerValueIndex] + const closestHigherValue = gasPrices[closestHigherValueIndex] + const estimatedClosestLowerTimeEstimate = estimatedTimes[closestLowerValueIndex] + const estimatedClosestHigherTimeEstimate = estimatedTimes[closestHigherValueIndex] + + const slope = (estimatedClosestHigherTimeEstimate - estimatedClosestLowerTimeEstimate) / (closestHigherValue - closestLowerValue) + const newTimeEstimate = -1 * (slope * (closestHigherValue - currentGasPrice) - estimatedClosestHigherTimeEstimate) + + return formatTimeEstimate(newTimeEstimate) +} 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 bb1a28136..61871f5f3 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 @@ -65,6 +65,7 @@ describe('GasModalPageContainer Component', function () { customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} infoRowProps={mockInfoRowProps} + currentTimeEstimate={'1 min 31 sec'} customGasPriceInHex={'mockCustomGasPriceInHex'} customGasLimitInHex={'mockCustomGasLimitInHex'} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) @@ -199,6 +200,7 @@ describe('GasModalPageContainer Component', function () { customGasPrice: 123, customGasLimit: 456, newTotalFiat: '$0.30', + currentTimeEstimate: '1 min 31 sec', }) const advancedTabContentProps = renderAdvancedTabContentResult.props assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') 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 c16a07b76..3f3be8d0c 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 @@ -75,7 +75,12 @@ describe('gas-modal-page-container container', () => { limit: 'aaaaaaaa', price: 'ffffffff', }, - priceAndTimeEstimates: 'mockPriceAndTimeEstimates', + priceAndTimeEstimates: [ + { gasprice: 3, expectedTime: '31' }, + { gasprice: 4, expectedTime: '62' }, + { gasprice: 5, expectedTime: '93' }, + { gasprice: 6, expectedTime: '124' }, + ], }, confirmTransaction: { txData: { @@ -93,11 +98,18 @@ describe('gas-modal-page-container container', () => { isConfirm: true, customGasPrice: 4.294967295, customGasLimit: 2863311530, + currentTimeEstimate: '~1 min 11 sec', newTotalFiat: '637.41', customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', gasChartProps: { - priceAndTimeEstimates: 'mockPriceAndTimeEstimates', + 'currentPrice': 4.294967295, + priceAndTimeEstimates: [ + { gasprice: 3, expectedTime: '31' }, + { gasprice: 4, expectedTime: '62' }, + { gasprice: 5, expectedTime: '93' }, + { gasprice: 6, expectedTime: '124' }, + ], }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', -- cgit From aa798cc54557f0740c3e9ab3f7bc85bccdc8abc3 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 10 Oct 2018 17:07:40 -0230 Subject: Add control arrows to advanced gas tab inputs. --- .../advanced-tab-content.component.js | 4 +++ .../advanced-tab-content/index.scss | 37 ++++++++++++++++++++++ .../tests/advanced-tab-content-component.test.js | 23 +++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 4dd18ce2b..b9ae93684 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 @@ -29,6 +29,10 @@ export default class AdvancedTabContent extends Component { precision={precision} onChange={event => onChange(Number(event.target.value))} /> +
+
onChange(value + 1)} />
+
onChange(value - 1)} />
+
) } 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 0fc9f4578..69bb65f2f 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 @@ -119,6 +119,43 @@ margin-top: 7px; } + &__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; + } + + &__i-wrap:hover { + background: #4EADE7; + color: $white; + } + + i:hover { + background: #4EADE7; + } + + i { + font-size: 10px; + } + } + + input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; -moz-appearance: none; 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 27a2326b8..d4549f4cd 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 @@ -205,7 +205,7 @@ describe('AdvancedTabContent Component', function () { }) it('should render an input, but not a GWEI symbol', () => { - assert.equal(gasInput.children().length, 1) + assert.equal(gasInput.children().length, 2) assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) }) @@ -220,6 +220,27 @@ describe('AdvancedTabContent Component', function () { 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', () => { + gasInput = shallow(wrapper.instance().gasInput( + 321, + value => value + 7, + 0, + 8, + false + )) + const upArrow = gasInput.find('.fa-angle-up') + assert.equal(upArrow.props().onClick(), 329) + const downArrow = gasInput.find('.fa-angle-down') + assert.equal(downArrow.props().onClick(), 327) + }) }) }) -- cgit From 6f0406125d9d656a4a9826b616f28ffda894ec8e Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 23 Oct 2018 14:40:27 -0230 Subject: Clean up gas chart code. --- .../gas-modal-page-container.container.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 3a62d21cc..67c1ff2e3 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 @@ -69,6 +69,10 @@ const mapStateToProps = state => { const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex) + const priceAndTimeEstimates = state.gas.priceAndTimeEstimates + const gasPrices = priceAndTimeEstimates.map(({ gasprice }) => gasprice) + const estimatedTimes = priceAndTimeEstimates.map(({ expectedTime }) => expectedTime) + return { hideBasic, isConfirm: isConfirm(state), @@ -77,7 +81,7 @@ const mapStateToProps = state => { customGasPrice, customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, - currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, state.gas.priceAndTimeEstimates), + currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, priceAndTimeEstimates), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), @@ -85,7 +89,10 @@ const mapStateToProps = state => { }, gasChartProps: { currentPrice: customGasPrice, - priceAndTimeEstimates: state.gas.priceAndTimeEstimates, + gasPrices, + estimatedTimes, + gasPricesMax: gasPrices[gasPrices.length - 1] + 1, + estimatedTimesMax: estimatedTimes[0], }, infoRowProps: { originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), -- cgit From d14af8346af2517db2e50f142377948c9f2ae5e9 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 24 Oct 2018 01:52:22 -0230 Subject: Improve data management and tests for gas-modal-page-container price estimates. --- .../gas-modal-page-container.container.js | 20 +++++++++++--------- .../tests/gas-modal-page-container-container.test.js | 10 ++++------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 67c1ff2e3..64b94e66c 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 @@ -24,13 +24,16 @@ import { getSelectedToken, } from '../../../selectors.js' import { - getCustomGasPrice, - getCustomGasLimit, - getRenderableBasicEstimateData, - getBasicGasEstimateLoadingStatus, + formatTimeEstimate, getAveragePriceEstimateInHexWEI, + getBasicGasEstimateLoadingStatus, + getCustomGasLimit, + getCustomGasPrice, getDefaultActiveButtonIndex, - formatTimeEstimate, + getEstimatedGasPrices, + getEstimatedGasTimes, + getPriceAndTimeEstimates, + getRenderableBasicEstimateData, } from '../../../selectors/custom-gas' import { formatCurrency, @@ -69,9 +72,8 @@ const mapStateToProps = state => { const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex) - const priceAndTimeEstimates = state.gas.priceAndTimeEstimates - const gasPrices = priceAndTimeEstimates.map(({ gasprice }) => gasprice) - const estimatedTimes = priceAndTimeEstimates.map(({ expectedTime }) => expectedTime) + const gasPrices = getEstimatedGasPrices(state) + const estimatedTimes = getEstimatedGasTimes(state) return { hideBasic, @@ -81,7 +83,7 @@ const mapStateToProps = state => { customGasPrice, customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, - currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, priceAndTimeEstimates), + currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, getPriceAndTimeEstimates(state)), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), 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 3f3be8d0c..2170c242d 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 @@ -104,12 +104,10 @@ describe('gas-modal-page-container container', () => { customModalGasPriceInHex: 'ffffffff', gasChartProps: { 'currentPrice': 4.294967295, - priceAndTimeEstimates: [ - { gasprice: 3, expectedTime: '31' }, - { gasprice: 4, expectedTime: '62' }, - { gasprice: 5, expectedTime: '93' }, - { gasprice: 6, expectedTime: '124' }, - ], + estimatedTimes: ['31', '62', '93', '124'], + estimatedTimesMax: '31', + gasPrices: [3, 4, 5, 6], + gasPricesMax: 7, }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', -- cgit From 3ced3c9b2ab75038163f82eb77fbf97ea78d2342 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 24 Oct 2018 22:23:12 -0230 Subject: Clean up for mmui-i11-custom-gas-price-chart branch --- .../gas-modal-page-container.container.js | 37 ++++++++++------------ .../gas-modal-page-container-container.test.js | 2 +- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 64b94e66c..426f940d1 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 @@ -51,6 +51,7 @@ import { calcGasTotal, } from '../../send/send.utils' import { addHexPrefix } from 'ethereumjs-util' +import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price-chart.utils' const mapStateToProps = state => { const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) @@ -83,7 +84,7 @@ const mapStateToProps = state => { customGasPrice, customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, - currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, getPriceAndTimeEstimates(state)), + currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, gasPrices, estimatedTimes), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), @@ -93,7 +94,7 @@ const mapStateToProps = state => { currentPrice: customGasPrice, gasPrices, estimatedTimes, - gasPricesMax: gasPrices[gasPrices.length - 1] + 1, + gasPricesMax: gasPrices[gasPrices.length - 1], estimatedTimesMax: estimatedTimes[0], }, infoRowProps: { @@ -173,7 +174,6 @@ function calcCustomGasLimit (customGasLimitInHex) { function getTxParams (state) { const { confirmTransaction: { txData }, metamask: { send } } = state - console.log('txData', txData) return txData.txParams || { from: send.from, gas: send.gasLimit, @@ -198,24 +198,21 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver )(aHexWEI, bHexWEI) } -function getRenderableTimeEstimate (currentGasPrice, priceAndTimeEstimates) { - const gasPrices = priceAndTimeEstimates.map(({ gasprice }) => gasprice) - const estimatedTimes = priceAndTimeEstimates.map(({ expectedTime }) => expectedTime) - - const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => { - return e <= currentGasPrice && a[i + 1] >= currentGasPrice - }) - const closestHigherValueIndex = gasPrices.findIndex((e, i, a) => { - return e > currentGasPrice +function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) { + const { + closestLowerValueIndex, + closestHigherValueIndex, + closestHigherValue, + closestLowerValue, + } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentGasPrice }) + + const newTimeEstimate = extrapolateY({ + higherY: estimatedTimes[closestHigherValueIndex], + lowerY: estimatedTimes[closestLowerValueIndex], + higherX: closestHigherValue, + lowerX: closestLowerValue, + xForExtrapolation: currentGasPrice, }) - const closestLowerValue = gasPrices[closestLowerValueIndex] - const closestHigherValue = gasPrices[closestHigherValueIndex] - const estimatedClosestLowerTimeEstimate = estimatedTimes[closestLowerValueIndex] - const estimatedClosestHigherTimeEstimate = estimatedTimes[closestHigherValueIndex] - - const slope = (estimatedClosestHigherTimeEstimate - estimatedClosestLowerTimeEstimate) / (closestHigherValue - closestLowerValue) - const newTimeEstimate = -1 * (slope * (closestHigherValue - currentGasPrice) - estimatedClosestHigherTimeEstimate) - return formatTimeEstimate(newTimeEstimate) } 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 2170c242d..54fbfb66c 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 @@ -107,7 +107,7 @@ describe('gas-modal-page-container container', () => { estimatedTimes: ['31', '62', '93', '124'], estimatedTimesMax: '31', gasPrices: [3, 4, 5, 6], - gasPricesMax: 7, + gasPricesMax: 6, }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', -- cgit From 3162a2747c0e54f729405caaef777519e4ded4dc Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 25 Oct 2018 01:25:39 -0230 Subject: Redesign of gas customization basic tab. --- .../basic-tab-content.component.js | 6 ++++-- .../basic-tab-content/index.scss | 25 +++++++++++++++++----- .../gas-modal-page-container.container.js | 1 - 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 index 0e5f15519..4483b71df 100644 --- 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 @@ -14,12 +14,14 @@ export default class BasicTabContent extends Component { render () { return (
-
Suggest gas fee increases
+
Estimated Processing Times
+
Select a higher gas fee to accelerate the processing of your transaction.*
+
* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed.
) } 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 b7b6c0f94..e34e4e328 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 @@ -1,13 +1,28 @@ .basic-tab-content { display: flex; flex-direction: column; - align-items: center; - margin-bottom: 22px; - height: 291px; + align-items: flex-start; + padding-left: 21px; + height: 324px; + background: #F5F7F8; + border-bottom: 1px solid #d2d8dd; &__title { margin-top: 19px; - font-size: 20px; - color: $scorpion; + 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/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 426f940d1..d098d49cc 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 @@ -32,7 +32,6 @@ import { getDefaultActiveButtonIndex, getEstimatedGasPrices, getEstimatedGasTimes, - getPriceAndTimeEstimates, getRenderableBasicEstimateData, } from '../../../selectors/custom-gas' import { -- cgit From e3f015c88f30fb4243ebbb3d2f109be8f3d68196 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Fri, 26 Oct 2018 03:20:36 -0230 Subject: Adds speed up slide-in gas customization sidebar --- .../advanced-tab-content.component.js | 25 +++++--- .../advanced-tab-content/index.scss | 12 ++++ .../tests/advanced-tab-content-component.test.js | 18 +++--- .../gas-modal-page-container.component.js | 4 +- .../gas-modal-page-container.container.js | 57 +++++++++++++++---- .../gas-modal-page-container-component.test.js | 1 + .../gas-modal-page-container-container.test.js | 66 +++++++++++++++++++--- 7 files changed, 149 insertions(+), 34 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 b9ae93684..23945483d 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,5 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import classnames from 'classnames' import GasPriceChart from '../../gas-price-chart' export default class AdvancedTabContent extends Component { @@ -16,23 +17,31 @@ export default class AdvancedTabContent extends Component { totalFee: PropTypes.string, timeRemaining: PropTypes.string, gasChartProps: PropTypes.object, + insufficientBalance: PropTypes.bool, } - gasInput (value, onChange, min, precision, showGWEI) { + gasInput (value, onChange, min, insufficientBalance, precision, showGWEI) { return (
onChange(Number(event.target.value))} /> -
+
onChange(value + 1)} />
onChange(value - 1)} />
+ {insufficientBalance &&
+ Insufficient Balance +
}
) } @@ -70,11 +79,11 @@ export default class AdvancedTabContent extends Component { ) } - renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { + renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) { return (
- { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) } + { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, 9, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, insufficientBalance, 0) }
) } @@ -86,6 +95,7 @@ export default class AdvancedTabContent extends Component { timeRemaining, customGasPrice, customGasLimit, + insufficientBalance, totalFee, gasChartProps, } = this.props @@ -98,7 +108,8 @@ export default class AdvancedTabContent extends Component { customGasPrice, updateCustomGasPrice, customGasLimit, - updateCustomGasLimit + updateCustomGasLimit, + insufficientBalance ) }
Live Gas Price Predictions
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 69bb65f2f..b62919c0a 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 @@ -102,6 +102,11 @@ } } + &__insufficient-balance { + font-size: 12px; + color: red; + } + &__input-wrapper { position: relative; @@ -119,6 +124,10 @@ margin-top: 7px; } + &__input--error { + border: 1px solid $red; + } + &__input-arrows { position: absolute; top: 7px; @@ -155,6 +164,9 @@ } } + &__input-arrows--error { + border: 1px solid $red; + } input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; 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 d4549f4cd..0c25874bb 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 @@ -27,6 +27,7 @@ describe('AdvancedTabContent Component', function () { customGasLimit={23456} timeRemaining={21500} totalFee={'$0.25'} + insufficientBalance={false} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -63,11 +64,13 @@ describe('AdvancedTabContent Component', function () { 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, [ - 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, + 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, false, ]) }) }) @@ -142,7 +145,8 @@ describe('AdvancedTabContent Component', function () { 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasLimit', - () => 'mockUpdateCustomGasLimitReturn' + () => 'mockUpdateCustomGasLimitReturn', + false )) }) @@ -161,10 +165,10 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, + 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, 9, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0, + 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', false, 0, ].map(String)) }) }) @@ -195,8 +199,8 @@ describe('AdvancedTabContent Component', function () { 321, value => value + 7, 0, - 8, - false + false, + 8 )) }) @@ -204,7 +208,7 @@ describe('AdvancedTabContent Component', function () { assert(gasInput.hasClass('advanced-tab__gas-edit-row__input-wrapper')) }) - it('should render an input, but not a GWEI symbol', () => { + 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')) }) 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 8f23b22e0..a804f7b64 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 @@ -48,6 +48,7 @@ export default class GasModalPageContainer extends Component { newTotalFiat, gasChartProps, currentTimeEstimate, + insufficientBalance, }) { const { transactionFee } = this.props return ( @@ -60,6 +61,7 @@ export default class GasModalPageContainer extends Component { transactionFee={transactionFee} totalFee={newTotalFiat} gasChartProps={gasChartProps} + insufficientBalance={insufficientBalance} /> ) } @@ -139,7 +141,7 @@ export default class GasModalPageContainer extends Component { title={this.context.t('customGas')} subtitle={this.context.t('customGasSubTitle')} tabsComponent={this.renderTabs(infoRowProps, tabProps)} - disabled={false} + disabled={tabProps.insufficientBalance} onCancel={() => cancelAndClose()} onClose={() => cancelAndClose()} onSubmit={() => { 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 d098d49cc..c3b7a5960 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 @@ -5,6 +5,8 @@ import { hideModal, setGasLimit, setGasPrice, + createSpeedUpTransaction, + hideSidebar, } from '../../../actions' import { setCustomGasPrice, @@ -22,6 +24,7 @@ import { getCurrentCurrency, conversionRateSelector as getConversionRate, getSelectedToken, + getCurrentEthBalance, } from '../../../selectors.js' import { formatTimeEstimate, @@ -34,6 +37,9 @@ import { getEstimatedGasTimes, getRenderableBasicEstimateData, } from '../../../selectors/custom-gas' +import { + submittedPendingTransactionsSelector, +} from '../../../selectors/transactions' import { formatCurrency, } from '../../../helpers/confirm-transaction/util' @@ -48,17 +54,19 @@ import { } 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' -const mapStateToProps = state => { +const mapStateToProps = (state, ownProps) => { + const { transaction = {} } = ownProps const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state) - const gasTotal = calcGasTotal(currentGasLimit, currentGasPrice) - + 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) @@ -74,6 +82,14 @@ const mapStateToProps = state => { const gasPrices = getEstimatedGasPrices(state) const estimatedTimes = getEstimatedGasTimes(state) + const balance = getCurrentEthBalance(state) + + const insufficientBalance = !isBalanceSufficient({ + amount: value, + gasTotal, + balance, + conversionRate, + }) return { hideBasic, @@ -104,6 +120,9 @@ const mapStateToProps = state => { transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), sendAmount: addHexWEIsToRenderableEth(value, '0x0'), }, + isSpeedUp: transaction.status === 'submitted', + txId: transaction.id, + insufficientBalance, } } @@ -125,18 +144,24 @@ const mapDispatchToProps = dispatch => { updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, + createSpeedUpTransaction: (txId, gasPrice) => { + return dispatch(createSpeedUpTransaction(txId, gasPrice)) + }, hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), setCustomTimeEstimate: (timeEstimateInSeconds) => dispatch(setCustomTimeEstimate(timeEstimateInSeconds)), + hideSidebar: () => dispatch(hideSidebar()), } } const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { gasPriceButtonGroupProps, isConfirm } = stateProps + const { gasPriceButtonGroupProps, isConfirm, isSpeedUp, txId } = stateProps const { updateCustomGasPrice: dispatchUpdateCustomGasPrice, hideGasButtonGroup: dispatchHideGasButtonGroup, setGasData: dispatchSetGasData, updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, + createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, + hideSidebar: dispatchHideSidebar, ...otherDispatchProps } = dispatchProps @@ -144,12 +169,17 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm - ? dispatchUpdateConfirmTxGasAndCalculate - : (newLimit, newPrice) => { - dispatchSetGasData(newLimit, newPrice) + onSubmit: (gasLimit, gasPrice) => { + if (isConfirm) { + dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice) + } else if (isSpeedUp) { + dispatchCreateSpeedUpTransaction(txId, gasPrice) + dispatchHideSidebar() + } else { + dispatchSetGasData(gasLimit, gasPrice) dispatchHideGasButtonGroup() - }, + } + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, @@ -171,9 +201,12 @@ function calcCustomGasLimit (customGasLimitInHex) { return parseInt(customGasLimitInHex, 16) } -function getTxParams (state) { +function getTxParams (state, transactionId) { const { confirmTransaction: { txData }, metamask: { send } } = state - return txData.txParams || { + 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, gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state), 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 61871f5f3..16f4b8cd7 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 @@ -68,6 +68,7 @@ describe('GasModalPageContainer Component', function () { currentTimeEstimate={'1 min 31 sec'} customGasPriceInHex={'mockCustomGasPriceInHex'} customGasLimitInHex={'mockCustomGasLimitInHex'} + insufficientBalance={false} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) 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 54fbfb66c..1ed28f33e 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 @@ -44,14 +44,16 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../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 mockState2 = { + const baseMockState = { appState: { modal: { modalState: { @@ -92,9 +94,7 @@ describe('gas-modal-page-container container', () => { }, }, } - const result2 = mapStateToProps(mockState2) - - assert.deepEqual(result2, { + const baseExpectedResult = { isConfirm: true, customGasPrice: 4.294967295, customGasLimit: 2863311530, @@ -116,13 +116,40 @@ describe('gas-modal-page-container container', () => { }, hideBasic: true, infoRowProps: { - originalTotalFiat: '22.58', - originalTotalEth: '0.451569 ETH', + 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 }), + }, + ] + + let result + tests.forEach(({ mockState, mockOwnProps, expectedResult}) => { + result = mapStateToProps(mockState, mockOwnProps) + assert.deepEqual(result, expectedResult) }) }) @@ -230,9 +257,21 @@ describe('gas-modal-page-container container', () => { setGasData: sinon.spy(), updateConfirmTxGasAndCalculate: sinon.spy(), someOtherDispatchProp: sinon.spy(), + createSpeedUpTransaction: sinon.spy(), + hideSidebar: 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() + }) it('should return the expected props when isConfirm is true', () => { const result = mergeProps(stateProps, dispatchProps, ownProps) @@ -289,6 +328,19 @@ describe('gas-modal-page-container container', () => { 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.createSpeedUpTransaction.callCount, 1) + assert.equal(dispatchProps.hideSidebar.callCount, 1) + }) }) }) -- cgit From d5411e772d1efd8d723eb81403fa22b03b904f49 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 8 Nov 2018 12:33:31 -0330 Subject: Make gas customization modal responsive. --- .../gas-customization/gas-modal-page-container/index.scss | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ui/app/components/gas-customization/gas-modal-page-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 index debd9b5ee..9486eaf8f 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 @@ -6,6 +6,10 @@ max-width: 391px; min-height: 585px; + @media screen and (max-width: $break-small) { + max-width: 344px; + } + &__header { padding: 0px; padding-top: 16px; @@ -60,6 +64,10 @@ } .gas-modal-content { + @media screen and (max-width: $break-small) { + width: 100%; + } + &__basic-tab { height: 219px; } -- cgit From 4111e9f92d9b87fa46a9f28e767cdf6bfce21fa2 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 15 Nov 2018 17:02:12 -0330 Subject: Improve responsiveness of customize speed up slider. --- .../gas-modal-page-container/index.scss | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'ui/app/components/gas-customization/gas-modal-page-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 index 9486eaf8f..2532c1fc2 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 @@ -19,6 +19,13 @@ } } + &__footer { + header { + padding-top: 12px; + padding-bottom: 12px; + } + } + &__header-close-text { font-size: 14px; color: #4EADE7; @@ -82,6 +89,10 @@ 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; @@ -95,11 +106,19 @@ &__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; + } } } -- cgit From 7f2c5c09de67a67972fcbaae254d39aac6c96f56 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 13:06:52 -0330 Subject: Uses more reliable api on main send screen; caches basic api results in modal --- .../gas-modal-page-container.component.js | 19 +++++++++++++ .../gas-modal-page-container.container.js | 10 +++++-- .../gas-modal-page-container-component.test.js | 32 +++++++++++++++++++++- .../gas-modal-page-container-container.test.js | 4 +++ 4 files changed, 62 insertions(+), 3 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 a804f7b64..b5b13c849 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 @@ -12,10 +12,13 @@ export default class GasModalPageContainer extends Component { 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, @@ -28,10 +31,26 @@ export default class GasModalPageContainer extends Component { customModalGasLimitInHex: PropTypes.string, cancelAndClose: PropTypes.func, transactionFee: PropTypes.string, + blockTime: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + ]), } 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 ( { customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, gasPrices, estimatedTimes), + blockTime: getBasicGasEstimateBlockTime(state), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), @@ -150,6 +154,8 @@ const mapDispatchToProps = dispatch => { hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), setCustomTimeEstimate: (timeEstimateInSeconds) => dispatch(setCustomTimeEstimate(timeEstimateInSeconds)), hideSidebar: () => dispatch(hideSidebar()), + fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), + fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), } } @@ -209,7 +215,7 @@ function getTxParams (state, transactionId) { return txData.txParams || pendingTxParams || { from: send.from, gas: send.gasLimit, - gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state), + gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), to: send.to, value: getSelectedToken(state) ? '0x0' : send.amount, } 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 16f4b8cd7..22f2f02dd 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 @@ -3,14 +3,21 @@ 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 = { @@ -59,6 +66,8 @@ describe('GasModalPageContainer Component', function () { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} @@ -76,6 +85,24 @@ describe('GasModalPageContainer Component', function () { 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) @@ -106,7 +133,10 @@ describe('GasModalPageContainer Component', function () { 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 renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props() assert.equal(tabsComponent, 'mockTabs') GasModalPageContainer.prototype.renderTabs.restore() 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 1ed28f33e..ba2cfe282 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 @@ -73,6 +73,9 @@ describe('gas-modal-page-container container', () => { conversionRate: 50, }, gas: { + basicEstimates: { + blockTime: 12, + }, customData: { limit: 'aaaaaaaa', price: 'ffffffff', @@ -100,6 +103,7 @@ describe('gas-modal-page-container container', () => { customGasLimit: 2863311530, currentTimeEstimate: '~1 min 11 sec', newTotalFiat: '637.41', + blockTime: 12, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', gasChartProps: { -- cgit From 7ffea926f23b2542c5182df7958defcdd9398b04 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 13:32:04 -0330 Subject: Add loading spinners when waiting for APIs in the gas customization modal --- .../advanced-tab-content.component.js | 8 +++++++- .../tests/advanced-tab-content-component.test.js | 17 +++++++++++++++++ .../basic-tab-content/basic-tab-content.component.js | 16 +++++++++++----- .../tests/basic-tab-content-component.test.js | 11 +++++++++++ .../gas-modal-page-container.component.js | 2 ++ .../gas-modal-page-container.container.js | 4 ++++ .../tests/gas-modal-page-container-component.test.js | 2 ++ .../tests/gas-modal-page-container-container.test.js | 2 ++ 8 files changed, 56 insertions(+), 6 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 23945483d..ac68b833c 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,7 @@ 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' export default class AdvancedTabContent extends Component { @@ -13,6 +14,7 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasEstimatesLoading: PropTypes.bool, millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, timeRemaining: PropTypes.string, @@ -98,6 +100,7 @@ export default class AdvancedTabContent extends Component { insufficientBalance, totalFee, gasChartProps, + gasEstimatesLoading, } = this.props return ( @@ -112,7 +115,10 @@ export default class AdvancedTabContent extends Component { insufficientBalance ) }
Live Gas Price Predictions
- + {!gasEstimatesLoading + ? + : + }
Slower Faster 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 0c25874bb..f321ca696 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 @@ -5,6 +5,7 @@ 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(), @@ -60,6 +61,22 @@ describe('AdvancedTabContent Component', function () { 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 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 index 4483b71df..264d038da 100644 --- 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 @@ -1,5 +1,6 @@ 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 { @@ -12,15 +13,20 @@ export default class BasicTabContent extends Component { } render () { + const { gasPriceButtonGroupProps } = this.props + return (
Estimated Processing Times
Select a higher gas fee to accelerate the processing of your transaction.*
- + {!gasPriceButtonGroupProps.loading + ? + : + }
* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed.
) 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 index 0c9c6ac63..25abdd997 100644 --- 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 @@ -4,6 +4,7 @@ import { shallow } from 'enzyme' import BasicTabContent from '../basic-tab-content.component' import GasPriceButtonGroup from '../../../gas-price-button-group/' +import Loading from '../../../../loading-screen' const mockGasPriceButtonGroupProps = { buttonDataLoading: false, @@ -60,6 +61,7 @@ describe('BasicTabContent Component', function () { 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) @@ -67,5 +69,14 @@ describe('BasicTabContent Component', function () { 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 index b5b13c849..5d8f92a59 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 @@ -68,6 +68,7 @@ export default class GasModalPageContainer extends Component { gasChartProps, currentTimeEstimate, insufficientBalance, + gasEstimatesLoading, }) { const { transactionFee } = this.props return ( @@ -81,6 +82,7 @@ export default class GasModalPageContainer extends Component { totalFee={newTotalFiat} gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} + gasEstimatesLoading={gasEstimatesLoading} /> ) } 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 770493be0..42b96a729 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 @@ -32,6 +32,7 @@ import { formatTimeEstimate, getFastPriceEstimateInHexWEI, getBasicGasEstimateLoadingStatus, + getGasEstimatesLoadingStatus, getCustomGasLimit, getCustomGasPrice, getDefaultActiveButtonIndex, @@ -65,6 +66,8 @@ import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price 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 @@ -127,6 +130,7 @@ const mapStateToProps = (state, ownProps) => { isSpeedUp: transaction.status === 'submitted', txId: transaction.id, insufficientBalance, + gasEstimatesLoading, } } 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 22f2f02dd..2ba2fa9e7 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 @@ -232,6 +232,7 @@ describe('GasModalPageContainer Component', function () { customGasLimit: 456, newTotalFiat: '$0.30', currentTimeEstimate: '1 min 31 sec', + gasEstimatesLoading: 'mockGasEstimatesLoading', }) const advancedTabContentProps = renderAdvancedTabContentResult.props assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') @@ -240,6 +241,7 @@ describe('GasModalPageContainer Component', function () { assert.equal(advancedTabContentProps.customGasLimit, 456) assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') assert.equal(advancedTabContentProps.totalFee, '$0.30') + assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading') }) }) 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 ba2cfe282..82c6dcd69 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 @@ -80,6 +80,7 @@ describe('gas-modal-page-container container', () => { limit: 'aaaaaaaa', price: 'ffffffff', }, + gasEstimatesLoading: false, priceAndTimeEstimates: [ { gasprice: 3, expectedTime: '31' }, { gasprice: 4, expectedTime: '62' }, @@ -118,6 +119,7 @@ describe('gas-modal-page-container container', () => { defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + gasEstimatesLoading: false, hideBasic: true, infoRowProps: { originalTotalFiat: '637.41', -- cgit From d8e41a6aa5a4c64538063c6dde7afdf77b0e5793 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 27 Nov 2018 14:00:41 -0330 Subject: Final gas customization fixes --- .../advanced-tab-content.component.js | 26 ++++++++++++++----- .../advanced-tab-content/index.scss | 1 + .../tests/advanced-tab-content-component.test.js | 16 ++++++++---- .../gas-modal-page-container.component.js | 3 +-- .../gas-modal-page-container.container.js | 29 +++++++++++++++++++--- .../gas-modal-page-container/index.scss | 1 + .../gas-modal-page-container-container.test.js | 18 ++++++++++---- 7 files changed, 73 insertions(+), 21 deletions(-) (limited to 'ui/app/components/gas-customization/gas-modal-page-container') 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 ac68b833c..ba738ff75 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 @@ -3,6 +3,7 @@ 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 = { @@ -22,7 +23,21 @@ export default class AdvancedTabContent extends Component { insufficientBalance: PropTypes.bool, } - gasInput (value, onChange, min, insufficientBalance, precision, showGWEI) { + 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) + } + } + + gasInput (value, onChange, min, insufficientBalance, showGWEI) { return (
onChange(Number(event.target.value))} />
-
onChange(value + 1)} />
-
onChange(value - 1)} />
+
onChange(value + 1)}>
+
onChange(value - 1)}>
{insufficientBalance &&
Insufficient Balance @@ -84,8 +98,8 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) { return (
- { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, 9, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, insufficientBalance, 0) } + { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, this.onChangeGasLimit, customGasLimit, insufficientBalance) }
) } 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 b62919c0a..88c69faf4 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 @@ -148,6 +148,7 @@ height: 100%; display: flex; justify-content: center; + cursor: pointer; } &__i-wrap:hover { 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 f321ca696..d6920454d 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 @@ -155,8 +155,11 @@ describe('AdvancedTabContent Component', function () { 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', @@ -167,6 +170,10 @@ describe('AdvancedTabContent Component', function () { )) }) + afterEach(() => { + wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit + }) + it('should render the gas-edit-rows root node', () => { assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows')) }) @@ -182,10 +189,10 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, 9, true, + 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', false, 0, + 'gasLimit', 'mockGasLimit', () => 'mockOnChangeGasLimit', 'mockGasLimit', false, ].map(String)) }) }) @@ -234,7 +241,6 @@ describe('AdvancedTabContent Component', function () { const inputProps = gasInput.find('input').props() assert.equal(inputProps.min, 0) assert.equal(inputProps.value, 321) - assert.equal(inputProps.precision, 8) }) it('should call the passed onChange method with the value of the input onChange event', () => { @@ -257,9 +263,9 @@ describe('AdvancedTabContent Component', function () { 8, false )) - const upArrow = gasInput.find('.fa-angle-up') + 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('.fa-angle-down') + const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1) assert.equal(downArrow.props().onClick(), 327) }) }) 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 5d8f92a59..be91bef0f 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 @@ -89,7 +89,7 @@ export default class GasModalPageContainer extends Component { renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { return ( -
+
{this.context.t('sendAmount')} @@ -167,7 +167,6 @@ export default class GasModalPageContainer extends Component { onClose={() => cancelAndClose()} onSubmit={() => { onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) - cancelAndClose() }} submitText={this.context.t('save')} headerCloseText={'Close'} 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 42b96a729..c619a0988 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 @@ -142,6 +142,7 @@ const mapDispatchToProps = dispatch => { dispatch(resetCustomData()) dispatch(hideModal()) }, + hideModal: () => dispatch(hideModal()), updateCustomGasPrice, convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), @@ -150,6 +151,8 @@ const mapDispatchToProps = dispatch => { dispatch(setGasPrice(newPrice)) }, updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { + updateCustomGasPrice(gasPrice) + dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))) return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, createSpeedUpTransaction: (txId, gasPrice) => { @@ -172,6 +175,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, hideSidebar: dispatchHideSidebar, + cancelAndClose: dispatchCancelAndClose, + hideModal: dispatchHideModal, ...otherDispatchProps } = dispatchProps @@ -182,18 +187,27 @@ const mergeProps = (stateProps, dispatchProps, 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() + } + }, } } @@ -241,20 +255,29 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver } 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: currentGasPrice }) + } = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation }) const newTimeEstimate = extrapolateY({ higherY: estimatedTimes[closestHigherValueIndex], lowerY: estimatedTimes[closestLowerValueIndex], higherX: closestHigherValue, lowerX: closestLowerValue, - xForExtrapolation: currentGasPrice, + xForExtrapolation: priceForEstimation, }) - return formatTimeEstimate(newTimeEstimate) + return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice) } 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 2532c1fc2..6c76f1bdd 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 @@ -44,6 +44,7 @@ display: flex; justify-content: center; align-items: flex-start; + margin-right: 0; } &__subtitle { 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 82c6dcd69..512832866 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 @@ -82,10 +82,10 @@ describe('gas-modal-page-container container', () => { }, gasEstimatesLoading: false, priceAndTimeEstimates: [ - { gasprice: 3, expectedTime: '31' }, - { gasprice: 4, expectedTime: '62' }, - { gasprice: 5, expectedTime: '93' }, - { gasprice: 6, expectedTime: '124' }, + { gasprice: 3, expectedTime: 31 }, + { gasprice: 4, expectedTime: 62 }, + { gasprice: 5, expectedTime: 93 }, + { gasprice: 6, expectedTime: 124 }, ], }, confirmTransaction: { @@ -235,7 +235,7 @@ describe('gas-modal-page-container container', () => { describe('updateConfirmTxGasAndCalculate()', () => { it('should dispatch a updateGasAndCalculate action with the correct props', () => { mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') - assert(dispatchSpy.calledOnce) + assert.equal(dispatchSpy.callCount, 3) assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) }) @@ -265,6 +265,8 @@ describe('gas-modal-page-container container', () => { someOtherDispatchProp: sinon.spy(), createSpeedUpTransaction: sinon.spy(), hideSidebar: sinon.spy(), + hideModal: sinon.spy(), + cancelAndClose: sinon.spy(), } ownProps = { someOwnProp: 123 } }) @@ -277,6 +279,7 @@ describe('gas-modal-page-container container', () => { 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) @@ -290,12 +293,14 @@ describe('gas-modal-page-container container', () => { 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() @@ -318,6 +323,7 @@ describe('gas-modal-page-container container', () => { 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') @@ -325,6 +331,7 @@ describe('gas-modal-page-container container', () => { 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() @@ -343,6 +350,7 @@ describe('gas-modal-page-container container', () => { 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) -- cgit From 8194309a9a7319bcebd6761a4596c208375adfab Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 3 Dec 2018 16:43:32 -0330 Subject: Fix styling of send screen in extension view when hex data on. --- .../gas-customization/gas-modal-page-container/index.scss | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui/app/components/gas-customization/gas-modal-page-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 index 6c76f1bdd..efba24e02 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 @@ -5,9 +5,15 @@ .page-container { max-width: 391px; min-height: 585px; + overflow-y: initial; @media screen and (max-width: $break-small) { max-width: 344px; + + &__content { + display: flex; + overflow-y: initial; + } } &__header { -- cgit