From fbc6f4e603c6f5f4054a52f17c792bf4ef54c462 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Tue, 23 Nov 2021 22:22:50 +0530 Subject: [PATCH] Adding network status section on edit gas fee modal (#12704) --- app/_locales/en/messages.json | 17 +++- ui/components/app/app-components.scss | 2 + .../edit-gas-fee-popover.js | 26 ++++++- .../app/edit-gas-fee-popover/index.scss | 12 ++- .../network-status/index.js | 1 + .../network-status/index.scss | 41 ++++++++++ .../network-status/network-status.js | 59 ++++++++++++++ .../network-status/network-status.test.js | 77 +++++++++++++++++++ .../network-status/status-slider/index.js | 1 + .../network-status/status-slider/index.scss | 42 ++++++++++ .../status-slider/status-slider.js | 53 +++++++++++++ .../status-slider/status-slider.test.js | 51 ++++++++++++ ui/css/design-system/attributes.scss | 2 +- 13 files changed, 378 insertions(+), 6 deletions(-) create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/index.js create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/index.scss create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/network-status.js create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/network-status.test.js create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.js create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.scss create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.js create mode 100644 ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.test.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 072577a8b..3a3d89906 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -323,6 +323,9 @@ "builtAroundTheWorld": { "message": "MetaMask is designed and built around the world." }, + "busy": { + "message": "Busy" + }, "buy": { "message": "Buy" }, @@ -1318,8 +1321,11 @@ "layer1Fees": { "message": "Layer 1 fees" }, + "learmMoreAboutGas": { + "message": "Want to $1 about gas?" + }, "learnMore": { - "message": "Learn more" + "message": "learn more" }, "learnScamRisk": { "message": "scams and security risks." @@ -1585,6 +1591,9 @@ "networkSettingsDescription": { "message": "Add and edit custom RPC networks" }, + "networkStatus": { + "message": "Network status" + }, "networkURL": { "message": "Network URL" }, @@ -1689,6 +1698,9 @@ "nonceFieldHeading": { "message": "Custom Nonce" }, + "notBusy": { + "message": "Not busy" + }, "notCurrentAccount": { "message": "Is this the correct account? It's different from the currently selected account in your wallet" }, @@ -2381,6 +2393,9 @@ "spendLimitTooLarge": { "message": "Spend limit too large" }, + "stable": { + "message": "Stable" + }, "stateLogError": { "message": "Error in retrieving state logs." }, diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index e5a5a1882..e5e245d87 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -15,6 +15,8 @@ @import 'edit-gas-display-education/index'; @import 'edit-gas-fee-popover/index'; @import 'edit-gas-fee-popover/edit-gas-item/index'; +@import 'edit-gas-fee-popover/network-status/index'; +@import 'edit-gas-fee-popover/network-status/status-slider/index'; @import 'gas-customization/gas-modal-page-container/index'; @import 'gas-customization/gas-price-button-group/index'; @import 'gas-customization/index'; diff --git a/ui/components/app/edit-gas-fee-popover/edit-gas-fee-popover.js b/ui/components/app/edit-gas-fee-popover/edit-gas-fee-popover.js index afbaefc53..abfdbca98 100644 --- a/ui/components/app/edit-gas-fee-popover/edit-gas-fee-popover.js +++ b/ui/components/app/edit-gas-fee-popover/edit-gas-fee-popover.js @@ -3,11 +3,14 @@ import PropTypes from 'prop-types'; import { PRIORITY_LEVELS } from '../../../../shared/constants/gas'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import Popover from '../../ui/popover'; import I18nValue from '../../ui/i18n-value'; import LoadingHeartBeat from '../../ui/loading-heartbeat'; +import Popover from '../../ui/popover'; +import Typography from '../../ui/typography/typography'; +import { COLORS } from '../../../helpers/constants/design-system'; import EditGasItem from './edit-gas-item'; +import NetworkStatus from './network-status'; const EditGasFeePopover = ({ onClose }) => { const t = useI18nContext(); @@ -54,6 +57,27 @@ const EditGasFeePopover = ({ onClose }) => { priorityLevel={PRIORITY_LEVELS.CUSTOM} onClose={onClose} /> + + + + + , + ]} + /> + diff --git a/ui/components/app/edit-gas-fee-popover/index.scss b/ui/components/app/edit-gas-fee-popover/index.scss index f892e8a71..e701d7137 100644 --- a/ui/components/app/edit-gas-fee-popover/index.scss +++ b/ui/components/app/edit-gas-fee-popover/index.scss @@ -1,7 +1,5 @@ .edit-gas-fee-popover { - @media screen and (min-width: $break-large) { - max-height: 84vh; - } + height: 500px; &__wrapper { border-top: 1px solid $ui-grey; @@ -37,4 +35,12 @@ margin: 8px 12px; } } + + &__network-status { + margin-top: 36px; + } + + &__know-more a { + color: $primary-1; + } } diff --git a/ui/components/app/edit-gas-fee-popover/network-status/index.js b/ui/components/app/edit-gas-fee-popover/network-status/index.js new file mode 100644 index 000000000..0ba1f18f3 --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/index.js @@ -0,0 +1 @@ +export { default } from './network-status'; diff --git a/ui/components/app/edit-gas-fee-popover/network-status/index.scss b/ui/components/app/edit-gas-fee-popover/network-status/index.scss new file mode 100644 index 000000000..db6d37299 --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/index.scss @@ -0,0 +1,41 @@ +.network-status { + margin: 24px 0 12px; + + &__info { + border-top: 1px solid $ui-2; + border-bottom: 1px solid $ui-2; + height: 56px; + display: flex; + align-items: center; + + &__separator { + border-left: 1px solid $ui-2; + height: 65%; + } + + &__field { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 30%; + + &--priority-fee { + width: 40%; + } + + &-data { + color: $ui-4; + font-size: 12px; + text-align: center; + } + + &-label { + color: $Black-100; + font-size: 10px; + font-weight: bold; + margin-top: 4px; + } + } + } +} diff --git a/ui/components/app/edit-gas-fee-popover/network-status/network-status.js b/ui/components/app/edit-gas-fee-popover/network-status/network-status.js new file mode 100644 index 000000000..ca6a3ccff --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/network-status.js @@ -0,0 +1,59 @@ +import React from 'react'; + +import { toBigNumber } from '../../../../../shared/modules/conversion.utils'; +import { COLORS } from '../../../../helpers/constants/design-system'; +import { useGasFeeContext } from '../../../../contexts/gasFee'; +import I18nValue from '../../../ui/i18n-value'; +import Typography from '../../../ui/typography/typography'; + +import StatusSlider from './status-slider'; + +const NetworkStatus = () => { + const { gasFeeEstimates } = useGasFeeContext(); + let estBaseFee = null; + if (gasFeeEstimates?.estimatedBaseFee) { + // estimatedBaseFee is not likely to be below 1, value .01 is used as test networks sometimes + // show have small values for it and more decimal places may cause UI to look broken. + estBaseFee = toBigNumber.dec(gasFeeEstimates?.estimatedBaseFee); + estBaseFee = estBaseFee.lessThan(0.01) ? 0.01 : estBaseFee.toFixed(2); + } + + return ( +
+ + + +
+
+ + {estBaseFee !== null && `${estBaseFee} GWEI`} + + Base fee +
+
+
+ + 0.5 - 22 GWEI + + + Priority fee + +
+
+
+ +
+
+
+ ); +}; + +NetworkStatus.propTypes = {}; + +export default NetworkStatus; diff --git a/ui/components/app/edit-gas-fee-popover/network-status/network-status.test.js b/ui/components/app/edit-gas-fee-popover/network-status/network-status.test.js new file mode 100644 index 000000000..df5e30411 --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/network-status.test.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; + +import { renderWithProvider } from '../../../../../test/jest'; +import { ETH } from '../../../../helpers/constants/common'; +import { GasFeeContextProvider } from '../../../../contexts/gasFee'; +import configureStore from '../../../../store/store'; + +import NetworkStatus from './network-status'; + +jest.mock('../../../../store/actions', () => ({ + disconnectGasFeeEstimatePoller: jest.fn(), + getGasFeeEstimatesAndStartPolling: jest + .fn() + .mockImplementation(() => Promise.resolve()), + addPollingTokenToAppState: jest.fn(), + getGasFeeTimeEstimate: jest + .fn() + .mockImplementation(() => Promise.resolve('unknown')), +})); + +const MOCK_FEE_ESTIMATE = { + estimatedBaseFee: '50.0112', +}; + +const renderComponent = (props) => { + const store = configureStore({ + metamask: { + nativeCurrency: ETH, + provider: {}, + cachedBalances: {}, + accounts: { + '0xAddress': { + address: '0xAddress', + balance: '0x176e5b6f173ebe66', + }, + }, + selectedAddress: '0xAddress', + featureFlags: { advancedInlineGas: true }, + gasFeeEstimates: MOCK_FEE_ESTIMATE, + ...props, + }, + }); + + return renderWithProvider( + + + , + store, + ); +}; + +describe('NetworkStatus', () => { + it('should renders labels', () => { + renderComponent(); + expect(screen.queryByText('Base fee')).toBeInTheDocument(); + expect(screen.queryByText('Priority fee')).toBeInTheDocument(); + }); + + it('should renders current base fee value rounded to 2 decimal places', () => { + renderComponent(); + expect( + screen.queryByText( + `${parseFloat(MOCK_FEE_ESTIMATE.estimatedBaseFee).toFixed(2)} GWEI`, + ), + ).toBeInTheDocument(); + }); + + it('should .01 as estimates base fee if estimated base fee is < .01', () => { + renderComponent({ + gasFeeEstimates: { + estimatedBaseFee: '0.0012', + }, + }); + expect(screen.queryByText('0.01 GWEI')).toBeInTheDocument(); + }); +}); diff --git a/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.js b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.js new file mode 100644 index 000000000..a9105f5f7 --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.js @@ -0,0 +1 @@ +export { default } from './status-slider'; diff --git a/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.scss b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.scss new file mode 100644 index 000000000..d8274d3d3 --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/index.scss @@ -0,0 +1,42 @@ +.status-slider { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 65%; + + &__line { + background-image: linear-gradient(to right, #037dd6, #d73a49); + height: 4px; + width: 100%; + border-radius: 100px; + display: block; + } + + &__label { + font-size: 10px; + font-weight: bold; + margin-top: 4px; + } + + &__arrow-border { + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-top: 10px solid white; + position: relative; + margin-bottom: -2px; + } + + &__arrow { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid black; + position: absolute; + bottom: 3px; + left: -5px; + } +} diff --git a/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.js b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.js new file mode 100644 index 000000000..8271cac6a --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.js @@ -0,0 +1,53 @@ +import React from 'react'; + +import I18nValue from '../../../../ui/i18n-value'; + +const GRADIENT_COLORS = [ + '#037DD6', + '#1876C8', + '#2D70BA', + '#4369AB', + '#57629E', + '#6A5D92', + '#805683', + '#9A4D71', + '#B44561', + '#C54055', +]; + +const StatusSlider = () => { + // todo: value below to be replaced with dynamic values from api once it is available + // corresponding test cases also to be added + const statusValue = 0.5; + const sliderValueNumeric = Math.round(statusValue * 10); + + let statusLabel = 'stable'; + if (statusValue <= 0.33) { + statusLabel = 'notBusy'; + } else if (statusValue > 0.66) { + statusLabel = 'busy'; + } + + return ( +
+
+
+
+
+
+ +
+
+ ); +}; + +export default StatusSlider; diff --git a/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.test.js b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.test.js new file mode 100644 index 000000000..a10ed82bb --- /dev/null +++ b/ui/components/app/edit-gas-fee-popover/network-status/status-slider/status-slider.test.js @@ -0,0 +1,51 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; + +import { renderWithProvider } from '../../../../../../test/jest'; +import { ETH } from '../../../../../helpers/constants/common'; +import { GasFeeContextProvider } from '../../../../../contexts/gasFee'; +import configureStore from '../../../../../store/store'; + +import StatusSlider from './status-slider'; + +jest.mock('../../../../../store/actions', () => ({ + disconnectGasFeeEstimatePoller: jest.fn(), + getGasFeeEstimatesAndStartPolling: jest + .fn() + .mockImplementation(() => Promise.resolve()), + addPollingTokenToAppState: jest.fn(), + getGasFeeTimeEstimate: jest + .fn() + .mockImplementation(() => Promise.resolve('unknown')), +})); + +const renderComponent = () => { + const store = configureStore({ + metamask: { + nativeCurrency: ETH, + provider: {}, + cachedBalances: {}, + accounts: { + '0xAddress': { + address: '0xAddress', + balance: '0x176e5b6f173ebe66', + }, + }, + selectedAddress: '0xAddress', + }, + }); + + return renderWithProvider( + + + , + store, + ); +}; + +describe('NetworkStatus', () => { + it('should renders stable for statusValue > 0.33 and <= 0.66', () => { + renderComponent(); + expect(screen.queryByText('Stable')).toBeInTheDocument(); + }); +}); diff --git a/ui/css/design-system/attributes.scss b/ui/css/design-system/attributes.scss index 8b920b7eb..4a187a949 100644 --- a/ui/css/design-system/attributes.scss +++ b/ui/css/design-system/attributes.scss @@ -82,4 +82,4 @@ $display: block, grid, flex, inline-block, inline-grid, inline-flex, list-item; $text-align: left, right, center, justify, end; $font-weight: bold, normal, 100, 200, 300, 400, 500, 600, 700, 800, 900; $font-style: normal, italic, oblique; -$font-size: 12px; +$font-size: 10px, 12px;