From cafb75c5ac5e8e3ee11bed93f7b5834cf1a12add Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 27 Sep 2019 16:45:18 +0400 Subject: [PATCH 01/22] Add defaultRowsPerPage to Table component --- package.json | 8 +-- src/components/Table/index.jsx | 14 +++-- src/routes/safe/components/Balances/index.jsx | 1 + yarn.lock | 53 +++++++++++-------- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 860e3e91..36f02570 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "@storybook/addon-knobs": "5.2.1", "@storybook/addon-links": "5.2.1", "@storybook/react": "5.2.1", - "@testing-library/react": "9.1.4", + "@testing-library/react": "9.2.0", "autoprefixer": "9.6.1", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "10.0.3", @@ -132,15 +132,15 @@ "storybook-host": "5.1.0", "storybook-router": "^0.3.3", "style-loader": "1.0.0", - "truffle": "5.0.37", + "truffle": "5.0.38", "truffle-contract": "4.0.31", "truffle-solidity-loader": "0.1.32", "uglifyjs-webpack-plugin": "2.2.0", "url-loader": "^2.1.0", "webpack": "4.41.0", - "webpack-bundle-analyzer": "3.5.1", + "webpack-bundle-analyzer": "3.5.2", "webpack-cli": "3.3.9", "webpack-dev-server": "3.8.1", - "webpack-manifest-plugin": "2.1.1" + "webpack-manifest-plugin": "2.1.2" } } diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index 577277aa..258bc14c 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -21,6 +21,7 @@ type Props = { children: Function, size: number, defaultFixed: boolean, + defaultRowsPerPage: number, defaultOrder: 'desc' | 'asc', noBorder: boolean, disablePagination: boolean, @@ -31,7 +32,7 @@ type State = { order?: Order, orderBy?: string, orderProp: boolean, - rowsPerPage: number, + rowsPerPage?: number, fixed?: boolean, } @@ -83,7 +84,7 @@ class GnoTable extends React.Component, State> { orderBy: undefined, fixed: undefined, orderProp: false, - rowsPerPage: 5, + rowsPerPage: undefined, } } @@ -147,6 +148,7 @@ class GnoTable extends React.Component, State> { defaultOrderBy, defaultOrder, defaultFixed, + defaultRowsPerPage, noBorder, } = this.props const { @@ -154,6 +156,7 @@ class GnoTable extends React.Component, State> { } = this.state const orderByParam = orderBy || defaultOrderBy const orderParam = order || defaultOrder + const displayRows = rowsPerPage || defaultRowsPerPage const fixedParam = typeof fixed !== 'undefined' ? fixed : !!defaultFixed const paginationClasses = { @@ -165,10 +168,10 @@ class GnoTable extends React.Component, State> { let sortedData = stableSort(data, getSorting(orderParam, orderByParam, orderProp), fixedParam) if (!disablePagination) { - sortedData = sortedData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + sortedData = sortedData.slice(page * displayRows, page * displayRows + displayRows) } - const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage) + const emptyRows = displayRows - Math.min(displayRows, data.length - page * displayRows) const isEmpty = size === 0 return ( @@ -191,7 +194,7 @@ class GnoTable extends React.Component, State> { extends React.Component, State> { GnoTable.defaultProps = { defaultOrder: 'asc', disablePagination: false, + defaultRowsPerPage: 5, } export default withStyles(styles)(GnoTable) diff --git a/src/routes/safe/components/Balances/index.jsx b/src/routes/safe/components/Balances/index.jsx index ee382025..2f0a5a88 100644 --- a/src/routes/safe/components/Balances/index.jsx +++ b/src/routes/safe/components/Balances/index.jsx @@ -155,6 +155,7 @@ class Balances extends React.Component { =3.5 <5" @@ -20267,4 +20274,4 @@ yauzl@^2.4.2: integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= dependencies: buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" \ No newline at end of file + fd-slicer "~1.1.0" From ab1d0c44d3dbee14a8ae2acd80b873417f7be978 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 27 Sep 2019 16:52:24 +0400 Subject: [PATCH 02/22] fix displaying of 100 in pagination select --- src/theme/mui.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/theme/mui.js b/src/theme/mui.js index 01d96c8a..e67070c1 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -245,6 +245,10 @@ export default createMuiTheme({ width: '60px', padding: `0 ${md} 0 0`, }, + select: { + paddingRight: 30, + minWidth: '20px', + }, actions: { order: 4, color: disabled, From 3c777fac9418fba1888d967144a3870984781670 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 27 Sep 2019 17:30:49 +0400 Subject: [PATCH 03/22] add learn more link to welcome screen, fix add custom token button label --- .../Tokens/screens/TokenList/index.jsx | 2 +- src/routes/welcome/components/Layout.jsx | 18 +++++++++++++++--- src/routes/welcome/components/Layout.scss | 4 ++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx index ad39c8cc..f69de267 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx @@ -146,7 +146,7 @@ class Tokens extends React.Component { onClick={switchToAddCustomTokenScreen} testId={ADD_CUSTOM_TOKEN_BUTTON_TEST_ID} > - + ADD CUSTOM TOKEN + + Add custom token diff --git a/src/routes/welcome/components/Layout.jsx b/src/routes/welcome/components/Layout.jsx index 42e44d0c..4d83d65b 100644 --- a/src/routes/welcome/components/Layout.jsx +++ b/src/routes/welcome/components/Layout.jsx @@ -1,12 +1,13 @@ // @flow import * as React from 'react' +import OpenInNew from '@material-ui/icons/OpenInNew' import Block from '~/components/layout/Block' import Heading from '~/components/layout/Heading' import Img from '~/components/layout/Img' import Button from '~/components/layout/Button' import Link from '~/components/layout/Link' import { OPEN_ADDRESS, LOAD_ADDRESS } from '~/routes/routes' -import { marginButtonImg } from '~/theme/variables' +import { marginButtonImg, secondary } from '~/theme/variables' import styles from './Layout.scss' const safe = require('../assets/safe.svg') @@ -16,6 +17,12 @@ type Props = { provider: string, } +const openIconStyle = { + height: '13px', + color: secondary, + marginBottom: '-2px', +} + type SafeProps = { provider: string, size?: 'small' | 'medium' | 'large', @@ -59,9 +66,9 @@ export const LoadSafe = ({ size, provider }: SafeProps) => ( const Welcome = ({ provider }: Props) => ( - Welcome to the Gnosis + Welcome to
- Safe Team Edition + Gnosis Safe For Teams
The Gnosis Safe for Teams is geared towards teams managing shared @@ -71,6 +78,11 @@ const Welcome = ({ provider }: Props) => ( wallet with redesigned smart contracts, cheaper setup and transaction
costs as well as an enhanced user experience. + {' '} + + Learn more + +
diff --git a/src/routes/welcome/components/Layout.scss b/src/routes/welcome/components/Layout.scss index aeb5a001..b5e15126 100644 --- a/src/routes/welcome/components/Layout.scss +++ b/src/routes/welcome/components/Layout.scss @@ -13,3 +13,7 @@ display: flex; justify-content: center; } + +.learnMoreLink { + color: $secondary; +} From 86cebf604b3b7c6390b4fe323dd8599c03f52c38 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 27 Sep 2019 18:18:47 +0400 Subject: [PATCH 04/22] Update add custom token button label font size, fix token item padding, update manage tokens modal title font size --- src/routes/safe/components/Balances/Tokens/index.jsx | 2 +- .../components/Balances/Tokens/screens/TokenList/index.jsx | 3 ++- .../components/Balances/Tokens/screens/TokenList/style.js | 7 +++++++ src/routes/safe/components/Balances/Tokens/style.js | 7 ++----- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/routes/safe/components/Balances/Tokens/index.jsx b/src/routes/safe/components/Balances/Tokens/index.jsx index 70f80291..18483d07 100644 --- a/src/routes/safe/components/Balances/Tokens/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/index.jsx @@ -42,7 +42,7 @@ const Tokens = (props: Props) => { return ( <> - + Manage Tokens diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx index f69de267..aa4bc9db 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx @@ -143,6 +143,7 @@ class Tokens extends React.Component { size="small" color="primary" className={classes.add} + classes={{ label: classes.addBtnLabel }} onClick={switchToAddCustomTokenScreen} testId={ADD_CUSTOM_TOKEN_BUTTON_TEST_ID} > @@ -161,7 +162,7 @@ class Tokens extends React.Component { const isActive = activeTokensAddresses.has(token.address) return ( - + {token.name} diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js index fbb88d69..578e72ef 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js @@ -20,6 +20,9 @@ export const styles = () => ({ paddingRight: md, paddingLeft: md, }, + addBtnLabel: { + fontSize: mediumFontSize, + }, actions: { height: '50px', }, @@ -33,6 +36,10 @@ export const styles = () => ({ minHeight: '50px', borderBottom: `1px solid ${border}`, }, + tokenRoot: { + paddingTop: 0, + paddingBottom: 0, + }, searchInput: { backgroundColor: 'transparent', lineHeight: 'initial', diff --git a/src/routes/safe/components/Balances/Tokens/style.js b/src/routes/safe/components/Balances/Tokens/style.js index 18980b13..70f1556a 100644 --- a/src/routes/safe/components/Balances/Tokens/style.js +++ b/src/routes/safe/components/Balances/Tokens/style.js @@ -1,16 +1,13 @@ // @flow -import { lg, sm } from '~/theme/variables' +import { lg, md } from '~/theme/variables' export const styles = () => ({ heading: { - padding: `${sm} ${lg}`, + padding: `${md} ${lg}`, justifyContent: 'space-between', maxHeight: '75px', boxSizing: 'border-box', }, - manage: { - fontSize: '24px', - }, close: { height: '35px', width: '35px', From 60fcce14fe925110804ef3775adb22271cda23c4 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 30 Sep 2019 16:11:33 +0400 Subject: [PATCH 05/22] add copy/etherscan buttons to safe address on safe view page --- package.json | 2 +- src/routes/safe/components/Layout.jsx | 33 +++---- src/routes/safe/components/style.js | 3 + yarn.lock | 124 +------------------------- 4 files changed, 17 insertions(+), 145 deletions(-) diff --git a/package.json b/package.json index 62b1ead4..14bde879 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "classnames": "^2.2.6", "css-loader": "3.2.0", "detect-port": "^1.3.0", - "eslint": "6.4.0", + "eslint": "5.16.0", "eslint-config-airbnb": "18.0.1", "eslint-plugin-flowtype": "4.3.0", "eslint-plugin-import": "2.18.2", diff --git a/src/routes/safe/components/Layout.jsx b/src/routes/safe/components/Layout.jsx index d49c838e..2071dcef 100644 --- a/src/routes/safe/components/Layout.jsx +++ b/src/routes/safe/components/Layout.jsx @@ -1,7 +1,6 @@ // @flow import * as React from 'react' import classNames from 'classnames/bind' -import OpenInNew from '@material-ui/icons/OpenInNew' import Tabs from '@material-ui/core/Tabs' import Tab from '@material-ui/core/Tab' import CallMade from '@material-ui/icons/CallMade' @@ -13,7 +12,8 @@ import Identicon from '~/components/Identicon' import Heading from '~/components/layout/Heading' import Row from '~/components/layout/Row' import Button from '~/components/layout/Button' -import Link from '~/components/layout/Link' +import EtherscanBtn from '~/components/EtherscanBtn' +import CopyBtn from '~/components/CopyBtn' import Paragraph from '~/components/layout/Paragraph' import Modal from '~/components/Modal' import SendModal from './Balances/SendModal' @@ -21,9 +21,7 @@ import Receive from './Balances/Receive' import NoSafe from '~/components/NoSafe' import { type SelectorProps } from '~/routes/safe/container/selector' import { getEtherScanLink } from '~/logic/wallets/getWeb3' -import { - secondary, border, -} from '~/theme/variables' +import { border } from '~/theme/variables' import { copyToClipboard } from '~/utils/clipboard' import { type Actions } from '../container/actions' import Balances from './Balances' @@ -49,14 +47,9 @@ type Props = SelectorProps & onShow: Function, onHide: Function, showSendFunds: Function, - hideSendFunds: Function + hideSendFunds: Function, } -const openIconStyle = { - height: '16px', - color: secondary, -} - class Layout extends React.Component { constructor(props) { super(props) @@ -120,12 +113,11 @@ class Layout extends React.Component { {!granted && Read Only} - + {address} - - - + + @@ -139,7 +131,7 @@ class Layout extends React.Component { disabled={!granted} > - Send + Send @@ -221,12 +213,7 @@ class Layout extends React.Component { open={showReceive} paperClassName={classes.receiveModal} > - + ) diff --git a/src/routes/safe/components/style.js b/src/routes/safe/components/style.js index 4846b3ba..d50e8532 100644 --- a/src/routes/safe/components/style.js +++ b/src/routes/safe/components/style.js @@ -14,6 +14,9 @@ export const styles = () => ({ overflow: 'hidden', whiteSpace: 'nowrap', }, + address: { + marginRight: sm, + }, user: { justifyContent: 'left', }, diff --git a/yarn.lock b/yarn.lock index e8a8cf45..28dd62ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3044,11 +3044,6 @@ acorn-jsx@^5.0.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== -acorn-jsx@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" - integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== - acorn-walk@^6.0.1, acorn-walk@^6.1.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" @@ -3074,11 +3069,6 @@ acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.0, acorn@^6.2.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== -acorn@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a" - integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ== - address@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" @@ -7376,14 +7366,6 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" - integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - eslint-utils@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c" @@ -7391,67 +7373,12 @@ eslint-utils@^1.3.1: dependencies: eslint-visitor-keys "^1.0.0" -eslint-utils@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" - integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== - dependencies: - eslint-visitor-keys "^1.0.0" - eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - -eslint@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" - integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.2" - eslint-visitor-keys "^1.1.0" - espree "^6.1.1" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.4.1" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -eslint@^5.0.0, eslint@^5.5.0: +eslint@5.16.0, eslint@^5.0.0, eslint@^5.5.0: version "5.16.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== @@ -7510,15 +7437,6 @@ espree@^5.0.1: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" -espree@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" - integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== - dependencies: - acorn "^7.0.0" - acorn-jsx "^5.0.2" - eslint-visitor-keys "^1.1.0" - esprima@^3.1.3, esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -9093,13 +9011,6 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" - integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== - dependencies: - is-glob "^4.0.1" - glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -10097,25 +10008,6 @@ inquirer@^6.2.0, inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^6.4.1: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - internal-ip@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" @@ -10406,7 +10298,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -16087,7 +15979,7 @@ semver@6.2.0, semver@^6.0.0, semver@^6.1.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== -semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -16888,11 +16780,6 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -strip-json-comments@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" - integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== - style-loader@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.0.tgz#1d5296f9165e8e2c85d24eee0b7caf9ec8ca1f82" @@ -18486,11 +18373,6 @@ v8-compile-cache@2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== -v8-compile-cache@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" - integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== - v8flags@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" From e8271d2b0294a4be103e1540a92340ff236d83b9 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Oct 2019 13:05:23 +0400 Subject: [PATCH 06/22] Add Early access label --- package.json | 4 +- .../Header/component/EarlyAccessLabel.jsx | 38 +++++++++++++++++++ src/components/Header/component/Layout.jsx | 2 + yarn.lock | 34 ++++++++--------- 4 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 src/components/Header/component/EarlyAccessLabel.jsx diff --git a/package.json b/package.json index 93a0be87..55cd725b 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "react-infinite-scroll-component": "4.5.3", "react-qr-reader": "^2.2.1", "react-redux": "7.1.1", - "react-router-dom": "5.1.1", + "react-router-dom": "5.1.2", "recompose": "^0.30.0", "redux": "4.0.4", "redux-actions": "^2.6.5", @@ -114,7 +114,7 @@ "eslint-plugin-import": "2.18.2", "eslint-plugin-jest": "22.17.0", "eslint-plugin-jsx-a11y": "6.2.3", - "eslint-plugin-react": "7.14.3", + "eslint-plugin-react": "7.15.0", "ethereumjs-abi": "0.6.8", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "4.2.0", diff --git a/src/components/Header/component/EarlyAccessLabel.jsx b/src/components/Header/component/EarlyAccessLabel.jsx new file mode 100644 index 00000000..bcfb81eb --- /dev/null +++ b/src/components/Header/component/EarlyAccessLabel.jsx @@ -0,0 +1,38 @@ +// @flow +import * as React from 'react' +import { makeStyles } from '@material-ui/core/styles' +import Paragraph from '~/components/layout/Paragraph' +import Col from '~/components/layout/Col' +import { + xs, sm, md, border, +} from '~/theme/variables' + +export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN' + +const useStyles = makeStyles({ + container: { + flexGrow: 0, + padding: `0 ${md}`, + }, + counter: { + background: border, + padding: `${xs} ${sm}`, + borderRadius: '3px', + marginLeft: sm, + lineHeight: 'normal', + }, +}) + +const EarlyAccessLabel = () => { + const classes = useStyles() + + return ( +
+ + Early access + + + ) +} + +export default EarlyAccessLabel diff --git a/src/components/Header/component/Layout.jsx b/src/components/Header/component/Layout.jsx index d5e5f85e..474f9df6 100644 --- a/src/components/Header/component/Layout.jsx +++ b/src/components/Header/component/Layout.jsx @@ -16,6 +16,7 @@ import { border, sm, md, headerHeight, } from '~/theme/variables' import Provider from './Provider' +import EarlyAccessLabel from './EarlyAccessLabel' import SafeListHeader from './SafeListHeader' const logo = require('../assets/gnosis-safe-logo.svg') @@ -66,6 +67,7 @@ const Layout = openHoc(({ + {(providerRef) => ( diff --git a/yarn.lock b/yarn.lock index 28dd62ef..4bb821b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7335,20 +7335,20 @@ eslint-plugin-jsx-a11y@6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-react@7.14.3: - version "7.14.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" - integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== +eslint-plugin-react@7.15.0: + version "7.15.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.15.0.tgz#4808b19cf7b4c439454099d4eb8f0cf0e9fe31dd" + integrity sha512-NbIh/yVXoltm8Df28PiPRanfCZAYubGqXU391MTCpW955Vum7S0nZdQYXGAvDh9ye4aNCmOR6YcYZsfMbEQZQA== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.1.0" + jsx-ast-utils "^2.2.1" object.entries "^1.1.0" object.fromentries "^2.0.0" object.values "^1.1.0" prop-types "^15.7.2" - resolve "^1.10.1" + resolve "^1.12.0" eslint-scope@^3.7.1: version "3.7.3" @@ -11359,7 +11359,7 @@ jss@10.0.0-alpha.25: is-in-browser "^1.1.3" tiny-warning "^1.0.2" -jsx-ast-utils@^2.1.0, jsx-ast-utils@^2.2.1: +jsx-ast-utils@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz#4d4973ebf8b9d2837ee91a8208cc66f3a2776cfb" integrity sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ== @@ -14792,23 +14792,23 @@ react-redux@7.1.1: prop-types "^15.7.2" react-is "^16.9.0" -react-router-dom@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.1.tgz#53caa089c291f64c1d597a52827b978b54d7c25d" - integrity sha512-r8R8H0Vt2ISqpk02rR6VZBLk+JZdR6pZV+h9K1y0ISh3/G4GGByNevYBS69x6czcOcWVRcZmXjwY8l9UBCKV+w== +react-router-dom@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" + integrity sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew== dependencies: "@babel/runtime" "^7.1.2" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.1.1" + react-router "5.1.2" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.1.tgz#9d65f54795f938c0c5b69eaeef58728134ce7c7c" - integrity sha512-ozTXqxKZsn4GfZqpG5rVFHSSxlNuDoMNxgyjM+mFJVhqlnPwwkRsAPkDm1PcNjBdYxMzqAhtz48HkQB6fSYaAQ== +react-router@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.2.tgz#6ea51d789cb36a6be1ba5f7c0d48dd9e817d3418" + integrity sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A== dependencies: "@babel/runtime" "^7.1.2" history "^4.9.0" @@ -15585,7 +15585,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1, resolve@~1.11.1: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1, resolve@~1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== From 969a3898366a5d706b3ca6edc27b4a3e4a111f1b Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Oct 2019 16:12:45 +0400 Subject: [PATCH 07/22] add Legal links to sidebar, rename Block layout component prop --- .../component/ProviderDetails/UserDetails.jsx | 2 +- src/components/Sidebar/LegalLinks.jsx | 37 +++++++++++++++++++ .../Sidebar/SafeList/DefaultBadge.jsx | 2 +- src/components/Sidebar/index.jsx | 7 +++- src/components/layout/Block/index.jsx | 6 +-- src/components/layout/Block/index.scss | 6 +++ src/logic/wallets/getWeb3.js | 9 ++--- .../components/ReviewInformation/index.jsx | 2 +- .../components/ReviewInformation/index.jsx | 2 +- .../ScanQRModal/index.jsx | 2 +- .../Balances/AssetTableCell/index.jsx | 2 +- .../components/Balances/Receive/index.jsx | 2 +- .../Tokens/screens/AddCustomToken/index.jsx | 2 +- .../Tokens/screens/TokenList/index.jsx | 2 +- src/routes/safe/components/Layout.jsx | 2 +- .../AddOwnerModal/screens/Review/index.jsx | 4 +- .../ManageOwners/EditOwnerModal/index.jsx | 2 +- .../OwnerAddressTableCell/index.jsx | 2 +- .../screens/CheckOwner/index.jsx | 2 +- .../RemoveOwnerModal/screens/Review/index.jsx | 4 +- .../screens/OwnerForm/index.jsx | 2 +- .../screens/Review/index.jsx | 6 +-- .../Settings/RemoveSafeModal/index.jsx | 2 +- 23 files changed, 76 insertions(+), 33 deletions(-) create mode 100644 src/components/Sidebar/LegalLinks.jsx diff --git a/src/components/Header/component/ProviderDetails/UserDetails.jsx b/src/components/Header/component/ProviderDetails/UserDetails.jsx index 48d1f819..a398be56 100644 --- a/src/components/Header/component/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/component/ProviderDetails/UserDetails.jsx @@ -118,7 +118,7 @@ const UserDetails = ({ )} - + {address} diff --git a/src/components/Sidebar/LegalLinks.jsx b/src/components/Sidebar/LegalLinks.jsx new file mode 100644 index 00000000..a3c79b5c --- /dev/null +++ b/src/components/Sidebar/LegalLinks.jsx @@ -0,0 +1,37 @@ +// @flow +import React from 'react' +import { makeStyles } from '@material-ui/core/styles' +import Block from '~/components/layout/Block' +import Link from '~/components/layout/Link' +import { sm, primary } from '~/theme/variables' + +const useStyles = makeStyles({ + container: { + padding: `${sm} 0`, + }, + link: { + color: primary, + }, +}) + +const LegalLinks = () => { + const classes = useStyles() + return ( + + + Terms + + + Privacy + + + Licenses + + + Imprint + + + ) +} + +export default LegalLinks diff --git a/src/components/Sidebar/SafeList/DefaultBadge.jsx b/src/components/Sidebar/SafeList/DefaultBadge.jsx index 467b605d..a0c441a5 100644 --- a/src/components/Sidebar/SafeList/DefaultBadge.jsx +++ b/src/components/Sidebar/SafeList/DefaultBadge.jsx @@ -24,7 +24,7 @@ const DefaultBadge = () => { const classes = useStyles() return ( - + Star Icon default diff --git a/src/components/Sidebar/index.jsx b/src/components/Sidebar/index.jsx index 07f3f9d1..4debf19d 100644 --- a/src/components/Sidebar/index.jsx +++ b/src/components/Sidebar/index.jsx @@ -12,13 +12,15 @@ import Link from '~/components/layout/Link' import Spacer from '~/components/Spacer' import Hairline from '~/components/layout/Hairline' import Row from '~/components/layout/Row' +import { WELCOME_ADDRESS } from '~/routes/routes' import { type Safe } from '~/routes/safe/store/models/safe' import { defaultSafeSelector } from '~/routes/safe/store/selectors' import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe' import { sortedSafeListSelector } from './selectors' -import useSidebarStyles from './style' import SafeList from './SafeList' -import { WELCOME_ADDRESS } from '~/routes/routes' +import LegalLinks from './LegalLinks' +import useSidebarStyles from './style' + const { useState, useEffect } = React @@ -128,6 +130,7 @@ const Sidebar = ({ setDefaultSafe={setDefaultSafeAction} defaultSafe={defaultSafe} /> + {children} diff --git a/src/components/layout/Block/index.jsx b/src/components/layout/Block/index.jsx index e1aced02..4e9ec7db 100644 --- a/src/components/layout/Block/index.jsx +++ b/src/components/layout/Block/index.jsx @@ -12,7 +12,7 @@ const cx = classNames.bind(styles) type Props = { margin?: Size, padding?: Size, - align?: 'center' | 'right' | 'left', + justify?: 'center' | 'right' | 'left' | 'space-around', children: React.Node, className?: string, } @@ -20,12 +20,12 @@ type Props = { class Block extends PureComponent { render() { const { - margin, padding, align, children, className, ...props + margin, padding, justify, children, className, ...props } = this.props const paddingStyle = padding ? capitalize(padding, 'padding') : undefined return ( -
+
{children}
) diff --git a/src/components/layout/Block/index.scss b/src/components/layout/Block/index.scss index 54709a6a..cdc5383f 100644 --- a/src/components/layout/Block/index.scss +++ b/src/components/layout/Block/index.scss @@ -52,6 +52,12 @@ align-items: center; } +.space-around { + display: flex; + align-items: center; + justify-content: space-around; +} + .right { display: flex; align-items: center; diff --git a/src/logic/wallets/getWeb3.js b/src/logic/wallets/getWeb3.js index a849e047..051b3fa0 100644 --- a/src/logic/wallets/getWeb3.js +++ b/src/logic/wallets/getWeb3.js @@ -47,7 +47,7 @@ export const getEtherScanLink = (type: 'address' | 'tx', value: string) => { let web3 export const getWeb3 = () => web3 || (window.web3 && new Web3(window.web3.currentProvider)) || (window.ethereum && new Web3(window.ethereum)) -const getProviderName: Function = (web3Provider): boolean => { +const getProviderName: Function = (web3Provider): string => { let name switch (web3Provider.currentProvider.constructor.name) { @@ -58,7 +58,7 @@ const getProviderName: Function = (web3Provider): boolean => { name = WALLET_PROVIDER.METAMASK break default: - name = 'UNKNOWN' + name = 'Wallet' } return name @@ -86,10 +86,7 @@ export const getProviderInfo: Function = async (): Promise => { if (window.ethereum) { web3Provider = window.ethereum try { - const accounts = await web3Provider.enable() - if (!accounts) { - throw new Error() - } + await web3Provider.enable() } catch (error) { console.error('Error when enabling web3 provider', error) } diff --git a/src/routes/load/components/ReviewInformation/index.jsx b/src/routes/load/components/ReviewInformation/index.jsx index 72617944..4f84e8ea 100644 --- a/src/routes/load/components/ReviewInformation/index.jsx +++ b/src/routes/load/components/ReviewInformation/index.jsx @@ -164,7 +164,7 @@ class ReviewComponent extends React.PureComponent { {values[getOwnerNameBy(index)]} - + {address} diff --git a/src/routes/open/components/ReviewInformation/index.jsx b/src/routes/open/components/ReviewInformation/index.jsx index 296cea50..bcfadb71 100644 --- a/src/routes/open/components/ReviewInformation/index.jsx +++ b/src/routes/open/components/ReviewInformation/index.jsx @@ -144,7 +144,7 @@ const ReviewComponent = ({ values, classes, userAccount }: Props) => { {name} - + {addresses[index]} diff --git a/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx b/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx index 65b9ef99..8cc3e2ce 100644 --- a/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx +++ b/src/routes/open/components/SafeOwnersConfirmationsForm/ScanQRModal/index.jsx @@ -66,7 +66,7 @@ const ScanQRModal = ({
{hasWebcam === null ? ( - + ) : ( diff --git a/src/routes/safe/components/Balances/AssetTableCell/index.jsx b/src/routes/safe/components/Balances/AssetTableCell/index.jsx index d9dfbffb..1e98ba17 100644 --- a/src/routes/safe/components/Balances/AssetTableCell/index.jsx +++ b/src/routes/safe/components/Balances/AssetTableCell/index.jsx @@ -16,7 +16,7 @@ const AssetTableCell = (props: Props) => { const { asset } = props return ( - + {asset.name} {asset.name} diff --git a/src/routes/safe/components/Balances/Receive/index.jsx b/src/routes/safe/components/Balances/Receive/index.jsx index d45183a0..66c170a6 100644 --- a/src/routes/safe/components/Balances/Receive/index.jsx +++ b/src/routes/safe/components/Balances/Receive/index.jsx @@ -92,7 +92,7 @@ const Receive = ({ - + { diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.jsx index dbe9cc5d..d69c212e 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.jsx @@ -174,7 +174,7 @@ const AddCustomToken = (props: Props) => { className={classes.addressInput} testId={ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID} /> - + Activate token for all Safes diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx index aa4bc9db..8e6dc9a2 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx @@ -154,7 +154,7 @@ class Tokens extends React.Component { {!tokens.size && ( - + )} diff --git a/src/routes/safe/components/Layout.jsx b/src/routes/safe/components/Layout.jsx index 2071dcef..2daa7266 100644 --- a/src/routes/safe/components/Layout.jsx +++ b/src/routes/safe/components/Layout.jsx @@ -112,7 +112,7 @@ class Layout extends React.Component { {!granted && Read Only} - + {address} diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.jsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.jsx index ec6b9054..920e852f 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.jsx @@ -106,7 +106,7 @@ const ReviewAddOwner = ({ {owner.name} - + {owner.address} @@ -135,7 +135,7 @@ const ReviewAddOwner = ({ {values.ownerName} - + {values.ownerAddress} diff --git a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.jsx b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.jsx index 54c2d0d8..867d9db3 100644 --- a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.jsx @@ -98,7 +98,7 @@ const EditOwnerComponent = ({ /> - + {ownerAddress} diff --git a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.jsx b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.jsx index 5b7b8c9c..acfb1fe2 100644 --- a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.jsx @@ -11,7 +11,7 @@ type Props = { const OwnerAddressTableCell = (props: Props) => { const { address } = props return ( - + {address} diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.jsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.jsx index d4eb2a21..58096ae1 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.jsx @@ -64,7 +64,7 @@ const CheckOwner = ({ {ownerName} - + {ownerAddress} diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.jsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.jsx index 1f29c38b..6d61189a 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.jsx @@ -118,7 +118,7 @@ const ReviewRemoveOwner = ({ {owner.name} - + {owner.address} @@ -152,7 +152,7 @@ const ReviewRemoveOwner = ({ {ownerName} - + {ownerAddress} diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.jsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.jsx index ce62108e..e573fba9 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.jsx @@ -95,7 +95,7 @@ const OwnerForm = ({ {ownerName} - + {ownerAddress} diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.jsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.jsx index 0a956687..aa677ce6 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.jsx @@ -121,7 +121,7 @@ const ReviewRemoveOwner = ({ {owner.name} - + {owner.address} @@ -155,7 +155,7 @@ const ReviewRemoveOwner = ({ {ownerName} - + {ownerAddress} @@ -181,7 +181,7 @@ const ReviewRemoveOwner = ({ {values.ownerName} - + {values.ownerAddress} diff --git a/src/routes/safe/components/Settings/RemoveSafeModal/index.jsx b/src/routes/safe/components/Settings/RemoveSafeModal/index.jsx index 19a68bde..c0c68568 100644 --- a/src/routes/safe/components/Settings/RemoveSafeModal/index.jsx +++ b/src/routes/safe/components/Settings/RemoveSafeModal/index.jsx @@ -58,7 +58,7 @@ const RemoveSafeComponent = ({ {safeName} - + {safeAddress} From b3b4887fdba75c9654283c6eeaab1b5c2812ff7c Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Oct 2019 19:25:10 +0400 Subject: [PATCH 08/22] formatAmounts wip --- src/logic/tokens/utils/formatAmounts.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/logic/tokens/utils/formatAmounts.js diff --git a/src/logic/tokens/utils/formatAmounts.js b/src/logic/tokens/utils/formatAmounts.js new file mode 100644 index 00000000..e3d35935 --- /dev/null +++ b/src/logic/tokens/utils/formatAmounts.js @@ -0,0 +1,10 @@ +// @flow +export const formatAmount = (number: string | number) => { + let numberFloat = parseFloat(number) + + if (numberFloat < 999.999999) { + numberFloat = numberFloat.toFixed(2).toLocaleString() + } + + return numberFloat +} From f5d324fff8d1e727752d37d93b34876feacc903a Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Oct 2019 19:31:25 +0400 Subject: [PATCH 09/22] formatAmounts wip --- src/logic/tokens/utils/{formatAmounts.js => formatAmount.js} | 3 ++- src/routes/safe/components/Balances/dataFetcher.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/logic/tokens/utils/{formatAmounts.js => formatAmount.js} (52%) diff --git a/src/logic/tokens/utils/formatAmounts.js b/src/logic/tokens/utils/formatAmount.js similarity index 52% rename from src/logic/tokens/utils/formatAmounts.js rename to src/logic/tokens/utils/formatAmount.js index e3d35935..b1bd325b 100644 --- a/src/logic/tokens/utils/formatAmounts.js +++ b/src/logic/tokens/utils/formatAmount.js @@ -1,9 +1,10 @@ // @flow +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat export const formatAmount = (number: string | number) => { let numberFloat = parseFloat(number) if (numberFloat < 999.999999) { - numberFloat = numberFloat.toFixed(2).toLocaleString() + numberFloat = numberFloat.toFixed(5).toLocaleString() } return numberFloat diff --git a/src/routes/safe/components/Balances/dataFetcher.js b/src/routes/safe/components/Balances/dataFetcher.js index 568a804a..11b5c509 100644 --- a/src/routes/safe/components/Balances/dataFetcher.js +++ b/src/routes/safe/components/Balances/dataFetcher.js @@ -3,6 +3,7 @@ import { List } from 'immutable' import { type Token } from '~/logic/tokens/store/model/token' import { buildOrderFieldFrom, FIXED, type SortRow } from '~/components/Table/sorting' import { type Column } from '~/components/Table/TableHead' +import { formatAmount } from '~/logic/tokens/utils/formatAmount' export const BALANCE_TABLE_ASSET_ID = 'asset' export const BALANCE_TABLE_BALANCE_ID = 'balance' @@ -19,7 +20,7 @@ export const getBalanceData = (activeTokens: List): List => { const rows = activeTokens.map((token: Token) => ({ [BALANCE_TABLE_ASSET_ID]: { name: token.name, logoUri: token.logoUri }, [buildOrderFieldFrom(BALANCE_TABLE_ASSET_ID)]: token.name, - [BALANCE_TABLE_BALANCE_ID]: `${token.balance} ${token.symbol}`, + [BALANCE_TABLE_BALANCE_ID]: `${formatAmount(token.balance)} ${token.symbol}`, [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: Number(token.balance), [FIXED]: token.get('symbol') === 'ETH', })) From f909ddc69954093ea631ea0d54bde6e4639b1a58 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 1 Oct 2019 19:58:21 +0400 Subject: [PATCH 10/22] formatAmount wip, use Intl.Numberformat --- src/logic/tokens/utils/formatAmount.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/logic/tokens/utils/formatAmount.js b/src/logic/tokens/utils/formatAmount.js index b1bd325b..460e12e7 100644 --- a/src/logic/tokens/utils/formatAmount.js +++ b/src/logic/tokens/utils/formatAmount.js @@ -1,10 +1,25 @@ // @flow -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat + +// Locale is an empty array because we want it to use user's locale +const lt1000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 5 }) +const lt10000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 4 }) +const lt100000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 3 }) +const lt1000000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 2 }) +const lt10000000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 1 }) + export const formatAmount = (number: string | number) => { let numberFloat = parseFloat(number) - if (numberFloat < 999.999999) { - numberFloat = numberFloat.toFixed(5).toLocaleString() + if (numberFloat < 1000) { + numberFloat = lt1000Formatter.format(numberFloat) + } else if (numberFloat < 10000) { + numberFloat = lt10000Formatter.format(numberFloat) + } else if (numberFloat < 100000) { + numberFloat = lt100000Formatter.format(numberFloat) + } else if (numberFloat < 1000000) { + numberFloat = lt1000000Formatter.format(numberFloat) + } else if (numberFloat < 10000000) { + numberFloat = lt10000000Formatter.format(numberFloat) } return numberFloat From 2d90d804a3cb4dda6255234671706f3fd7bc2392 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 2 Oct 2019 13:25:46 +0400 Subject: [PATCH 11/22] formatAmount wip --- src/logic/tokens/utils/formatAmount.js | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/logic/tokens/utils/formatAmount.js b/src/logic/tokens/utils/formatAmount.js index 460e12e7..69bab864 100644 --- a/src/logic/tokens/utils/formatAmount.js +++ b/src/logic/tokens/utils/formatAmount.js @@ -1,25 +1,35 @@ // @flow +// This is pretty new so I'll leave the docs here +// https://v8.dev/features/intl-numberformat +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat + // Locale is an empty array because we want it to use user's locale -const lt1000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 5 }) -const lt10000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 4 }) -const lt100000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 3 }) -const lt1000000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 2 }) -const lt10000000Formatter = new Intl.NumberFormat([], { maximumFractionDigits: 1 }) +const lt1kFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 5 }) +const lt10kFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 4 }) +const lt100kFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 3 }) +const lt1mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 2 }) +const lt10mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 1 }) +const lt100mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 0 }) +const lt1tFormatter = new Intl.NumberFormat([], { notation: 'compact' }) export const formatAmount = (number: string | number) => { let numberFloat = parseFloat(number) if (numberFloat < 1000) { - numberFloat = lt1000Formatter.format(numberFloat) + numberFloat = lt1kFormatter.format(numberFloat) } else if (numberFloat < 10000) { - numberFloat = lt10000Formatter.format(numberFloat) + numberFloat = lt10kFormatter.format(numberFloat) } else if (numberFloat < 100000) { - numberFloat = lt100000Formatter.format(numberFloat) + numberFloat = lt100kFormatter.format(numberFloat) } else if (numberFloat < 1000000) { - numberFloat = lt1000000Formatter.format(numberFloat) + numberFloat = lt1mFormatter.format(numberFloat) } else if (numberFloat < 10000000) { - numberFloat = lt10000000Formatter.format(numberFloat) + numberFloat = lt10mFormatter.format(numberFloat) + } else if (numberFloat < 100000000) { + numberFloat = lt100mFormatter.format(numberFloat) + } else if (numberFloat < 1000000000) { + numberFloat = lt1tFormatter.format(numberFloat) } return numberFloat From 6bbfd04910ac19e338b4f7002d1b761641e049c9 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 2 Oct 2019 15:47:06 +0400 Subject: [PATCH 12/22] Add util function for formatting amounts --- src/logic/tokens/utils/formatAmount.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/logic/tokens/utils/formatAmount.js b/src/logic/tokens/utils/formatAmount.js index 69bab864..0751c8a5 100644 --- a/src/logic/tokens/utils/formatAmount.js +++ b/src/logic/tokens/utils/formatAmount.js @@ -11,7 +11,8 @@ const lt100kFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 3 }) const lt1mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 2 }) const lt10mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 1 }) const lt100mFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 0 }) -const lt1tFormatter = new Intl.NumberFormat([], { notation: 'compact' }) +// same format for billions and trillions +const lt1000tFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 3, notation: 'compact' }) export const formatAmount = (number: string | number) => { let numberFloat = parseFloat(number) @@ -28,8 +29,10 @@ export const formatAmount = (number: string | number) => { numberFloat = lt10mFormatter.format(numberFloat) } else if (numberFloat < 100000000) { numberFloat = lt100mFormatter.format(numberFloat) - } else if (numberFloat < 1000000000) { - numberFloat = lt1tFormatter.format(numberFloat) + } else if (numberFloat < 10 ** 15) { + numberFloat = lt1000tFormatter.format(numberFloat) + } else { + numberFloat = '> 1000T' } return numberFloat From 49252889b072c2c2c26151be83f5eccf7111f88a Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 2 Oct 2019 18:28:33 +0400 Subject: [PATCH 13/22] Add react-window in token list for displaying tokens --- package.json | 3 +- src/logic/tokens/api/fetchTokenList.js | 6 +- src/routes/load/container/Load.jsx | 2 +- .../SendFunds/TokenSelectField/index.jsx | 11 +-- .../Tokens/screens/TokenList/TokenRow.jsx | 57 +++++++++++++++ .../Tokens/screens/TokenList/index.jsx | 71 +++++++++---------- .../Tokens/screens/TokenList/style.js | 2 + yarn.lock | 29 +++++--- 8 files changed, 128 insertions(+), 53 deletions(-) create mode 100644 src/routes/safe/components/Balances/Tokens/screens/TokenList/TokenRow.jsx diff --git a/package.json b/package.json index 55cd725b..c8dffd7d 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react-qr-reader": "^2.2.1", "react-redux": "7.1.1", "react-router-dom": "5.1.2", + "react-window": "^1.8.5", "recompose": "^0.30.0", "redux": "4.0.4", "redux-actions": "^2.6.5", @@ -114,7 +115,7 @@ "eslint-plugin-import": "2.18.2", "eslint-plugin-jest": "22.17.0", "eslint-plugin-jsx-a11y": "6.2.3", - "eslint-plugin-react": "7.15.0", + "eslint-plugin-react": "7.14.3", "ethereumjs-abi": "0.6.8", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "4.2.0", diff --git a/src/logic/tokens/api/fetchTokenList.js b/src/logic/tokens/api/fetchTokenList.js index 63b3b9eb..82cbb7ba 100644 --- a/src/logic/tokens/api/fetchTokenList.js +++ b/src/logic/tokens/api/fetchTokenList.js @@ -6,7 +6,11 @@ const fetchTokenList = () => { const apiUrl = getRelayUrl() const url = `${apiUrl}/tokens` - return axios.get(url) + return axios.get(url, { + params: { + limit: 300, + }, + }) } export default fetchTokenList diff --git a/src/routes/load/container/Load.jsx b/src/routes/load/container/Load.jsx index 181d0ec8..82b825e0 100644 --- a/src/routes/load/container/Load.jsx +++ b/src/routes/load/container/Load.jsx @@ -19,7 +19,7 @@ type Props = SelectorProps & Actions export const loadSafe = async ( safeName: string, safeAddress: string, - owners: Array, + owners: Array<*>, addSafe: Function, ) => { const safeProps = await buildSafe(safeAddress, safeName) diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx index 873df0d0..61264c67 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx @@ -12,6 +12,7 @@ import SelectField from '~/components/forms/SelectField' import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils' import { required } from '~/components/forms/validator' import { type Token } from '~/logic/tokens/store/model/token' +import { formatAmount } from '~/logic/tokens/utils/formatAmount' import { selectedTokenStyles, selectStyles } from './style' type SelectFieldProps = { @@ -35,7 +36,7 @@ const SelectedToken = ({ token, classes }: SelectedTokenProps) => ( ) : ( @@ -54,7 +55,7 @@ const TokenSelectField = ({ tokens, classes, initialValue }: SelectFieldProps) = const [initialToken, setInitialToken] = useState('') useEffect(() => { - const selectedToken = tokens.find(token => token.name === initialValue) + const selectedToken = tokens.find((token) => token.name === initialValue) setInitialToken(selectedToken || '') }, [initialValue]) @@ -64,16 +65,16 @@ const TokenSelectField = ({ tokens, classes, initialValue }: SelectFieldProps) = component={SelectField} classes={{ selectMenu: classes.selectMenu }} validate={required} - renderValue={token => } + renderValue={(token) => } initialValue={initialToken} displayEmpty > - {tokens.map(token => ( + {tokens.map((token) => ( {token.name} - + ))} diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/TokenRow.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/TokenRow.jsx new file mode 100644 index 00000000..9d3e3b73 --- /dev/null +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/TokenRow.jsx @@ -0,0 +1,57 @@ +// @flow +import React, { memo } from 'react' +import { List, Set } from 'immutable' +import { withStyles } from '@material-ui/core/styles' +import ListItem from '@material-ui/core/ListItem' +import ListItemIcon from '@material-ui/core/ListItemIcon' +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction' +import ListItemText from '@material-ui/core/ListItemText' +import Switch from '@material-ui/core/Switch' +import Img from '~/components/layout/Img' +import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils' +import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers' +import { type Token } from '~/logic/tokens/store/model/token' +import { styles } from './style' + +export const TOGGLE_TOKEN_TEST_ID = 'toggle-token-btn' + +type Props = { + data: { + activeTokensAddresses: Set, + tokens: List, + onSwitch: Function, + }, + style: Object, + index: number, + classes: Object, +} + +const TokenRow = memo(({ + data, index, classes, style, +}: Props) => { + const { tokens, activeTokensAddresses, onSwitch } = data + const token: Token = tokens.get(index) + const isActive = activeTokensAddresses.has(token.address) + + return ( +
+ + + {token.name} + + + {token.address !== ETH_ADDRESS && ( + + + + )} + +
+ ) +}) + +export default withStyles(styles)(TokenRow) diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx index 8e6dc9a2..c2ae1f9e 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx @@ -2,30 +2,23 @@ import * as React from 'react' import { List, Set } from 'immutable' import cn from 'classnames' +import { FixedSizeList } from 'react-window' import SearchBar from 'material-ui-search-bar' import { withStyles } from '@material-ui/core/styles' import MuiList from '@material-ui/core/List' -import ListItem from '@material-ui/core/ListItem' -import ListItemIcon from '@material-ui/core/ListItemIcon' import CircularProgress from '@material-ui/core/CircularProgress' -import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction' -import ListItemText from '@material-ui/core/ListItemText' -import Switch from '@material-ui/core/Switch' import Search from '@material-ui/icons/Search' -import Img from '~/components/layout/Img' import Block from '~/components/layout/Block' import Button from '~/components/layout/Button' import Divider from '~/components/layout/Divider' import Hairline from '~/components/layout/Hairline' import Spacer from '~/components/Spacer' import Row from '~/components/layout/Row' -import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers' import { type Token } from '~/logic/tokens/store/model/token' -import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils' +import TokenRow from './TokenRow' import { styles } from './style' export const ADD_CUSTOM_TOKEN_BUTTON_TEST_ID = 'add-custom-token-btn' -export const TOGGLE_TOKEN_TEST_ID = 'toggle-token-btn' type Props = { classes: Object, @@ -110,6 +103,18 @@ class Tokens extends React.Component { } } + createItemData = (tokens, activeTokensAddresses) => ({ + tokens, + activeTokensAddresses, + onSwitch: this.onSwitch, + }) + + getItemKey = (index, { tokens }) => { + const token: Token = tokens.get(index) + + return token.address + } + render() { const { classes, tokens, setActiveScreen } = this.props const { filter, activeTokensAddresses } = this.state @@ -122,6 +127,7 @@ class Tokens extends React.Component { const switchToAddCustomTokenScreen = () => setActiveScreen('addCustomToken') const filteredTokens = filterBy(filter, tokens) + const itemData = this.createItemData(filteredTokens, activeTokensAddresses) return ( <> @@ -152,34 +158,25 @@ class Tokens extends React.Component {
- - {!tokens.size && ( - - - - )} - {filteredTokens.map((token: Token) => { - const isActive = activeTokensAddresses.has(token.address) - - return ( - - - {token.name} - - - {token.address !== ETH_ADDRESS && ( - - - - )} - - ) - })} - + {!tokens.size && ( + + + + )} + {tokens.size > 0 && ( + + + {TokenRow} + + + )} ) } diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js index 578e72ef..4ba04d2a 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js @@ -56,6 +56,8 @@ export const styles = () => ({ }, tokenIcon: { marginRight: md, + height: '28px', + width: '28px', }, progressContainer: { width: '100%', diff --git a/yarn.lock b/yarn.lock index 4bb821b4..32a4e9d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7335,20 +7335,20 @@ eslint-plugin-jsx-a11y@6.2.3: has "^1.0.3" jsx-ast-utils "^2.2.1" -eslint-plugin-react@7.15.0: - version "7.15.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.15.0.tgz#4808b19cf7b4c439454099d4eb8f0cf0e9fe31dd" - integrity sha512-NbIh/yVXoltm8Df28PiPRanfCZAYubGqXU391MTCpW955Vum7S0nZdQYXGAvDh9ye4aNCmOR6YcYZsfMbEQZQA== +eslint-plugin-react@7.14.3: + version "7.14.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" + integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.2.1" + jsx-ast-utils "^2.1.0" object.entries "^1.1.0" object.fromentries "^2.0.0" object.values "^1.1.0" prop-types "^15.7.2" - resolve "^1.12.0" + resolve "^1.10.1" eslint-scope@^3.7.1: version "3.7.3" @@ -11359,7 +11359,7 @@ jss@10.0.0-alpha.25: is-in-browser "^1.1.3" tiny-warning "^1.0.2" -jsx-ast-utils@^2.2.1: +jsx-ast-utils@^2.1.0, jsx-ast-utils@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz#4d4973ebf8b9d2837ee91a8208cc66f3a2776cfb" integrity sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ== @@ -12133,6 +12133,11 @@ memdown@~3.0.0: ltgt "~2.2.0" safe-buffer "~5.1.1" +"memoize-one@>=3.1.1 <6": + version "5.1.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" + integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== + memoize-one@^5.0.0: version "5.0.5" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e" @@ -14899,6 +14904,14 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-window@^1.8.5: + version "1.8.5" + resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.5.tgz#a56b39307e79979721021f5d06a67742ecca52d1" + integrity sha512-HeTwlNa37AFa8MDZFZOKcNEkuF2YflA0hpGPiTT9vR7OawEt+GZbfM6wqkBahD3D3pUjIabQYzsnY/BSJbgq6Q== + dependencies: + "@babel/runtime" "^7.0.0" + memoize-one ">=3.1.1 <6" + react@16.10.1: version "16.10.1" resolved "https://registry.yarnpkg.com/react/-/react-16.10.1.tgz#967c1e71a2767dfa699e6ba702a00483e3b0573f" @@ -15592,7 +15605,7 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.3.2 dependencies: path-parse "^1.0.6" -resolve@^1.12.0: +resolve@^1.10.1, resolve@^1.12.0: version "1.12.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== From 3b457d86479dc7054a27debd88987f4176679f1c Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 2 Oct 2019 18:45:39 +0400 Subject: [PATCH 14/22] Fix token list styles --- .../safe/components/Balances/Tokens/screens/TokenList/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js index 4ba04d2a..293a1090 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.js @@ -5,7 +5,7 @@ import { export const styles = () => ({ root: { - minHeight: '48px', + minHeight: '52px', }, search: { color: secondaryText, From 9ba01b3c56209465cd43befe2fc2b4627a253515 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 2 Oct 2019 18:51:40 +0400 Subject: [PATCH 15/22] add useMemo to sidebar --- src/components/Sidebar/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Sidebar/index.jsx b/src/components/Sidebar/index.jsx index 4debf19d..d32552b3 100644 --- a/src/components/Sidebar/index.jsx +++ b/src/components/Sidebar/index.jsx @@ -22,7 +22,7 @@ import LegalLinks from './LegalLinks' import useSidebarStyles from './style' -const { useState, useEffect } = React +const { useState, useEffect, useMemo } = React type TSidebarContext = { isOpen: boolean, @@ -85,7 +85,7 @@ const Sidebar = ({ } } - const filteredSafes = filterBy(filter, safes) + const filteredSafes = useMemo(() => filterBy(filter, safes), [safes, filter]) return ( From 04bfe0a57912e7c7e401920e36af8d7f60267aba Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Thu, 3 Oct 2019 18:25:21 +0400 Subject: [PATCH 16/22] Refactor safe model --- package.json | 10 +- .../Tokens/screens/TokenList/index.jsx | 9 +- src/routes/safe/container/selector.js | 7 +- .../safe/store/actions/fetchTokenBalances.js | 16 +- .../safe/store/actions/updateActiveTokens.js | 4 +- src/routes/safe/store/models/safe.js | 13 +- src/routes/safe/store/models/tokenBalance.js | 17 -- src/routes/safe/store/reducer/safe.js | 7 +- src/test/safe.dom.balances.test.js | 12 +- src/test/safe.dom.funds.threshold=1.test.js | 13 +- src/test/safe.dom.sidebar.test.js | 10 +- src/test/tokens.dom.enabling.test.js | 19 +- src/test/utils/DOMNavigation/tokens.js | 28 ++- yarn.lock | 198 +++++++++--------- 14 files changed, 180 insertions(+), 183 deletions(-) delete mode 100644 src/routes/safe/store/models/tokenBalance.js diff --git a/package.json b/package.json index c8dffd7d..6389c48b 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "dependencies": { "@gnosis.pm/safe-contracts": "^1.0.0", "@gnosis.pm/util-contracts": "2.0.4", - "@material-ui/core": "4.4.3", + "@material-ui/core": "4.5.0", "@material-ui/icons": "4.4.3", "@testing-library/jest-dom": "4.1.0", "@welldone-software/why-did-you-render": "3.3.5", @@ -119,7 +119,7 @@ "ethereumjs-abi": "0.6.8", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "4.2.0", - "flow-bin": "0.108.0", + "flow-bin": "0.109.0", "fs-extra": "8.1.0", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", @@ -136,7 +136,7 @@ "storybook-host": "5.1.0", "storybook-router": "^0.3.4", "style-loader": "1.0.0", - "truffle": "5.0.38", + "truffle": "5.0.39", "truffle-contract": "4.0.31", "truffle-solidity-loader": "0.1.32", "uglifyjs-webpack-plugin": "2.2.0", @@ -144,7 +144,7 @@ "webpack": "4.41.0", "webpack-bundle-analyzer": "3.5.2", "webpack-cli": "3.3.9", - "webpack-dev-server": "3.8.1", - "webpack-manifest-plugin": "2.1.2" + "webpack-dev-server": "3.8.2", + "webpack-manifest-plugin": "2.2.0" } } diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx index c2ae1f9e..1a540856 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.jsx @@ -43,10 +43,12 @@ const filterBy = (filter: string, tokens: List): List => tokens.fi // OPTIMIZATION IDEA (Thanks Andre) // Calculate active tokens on component mount, store it in component state -// After user closes modal, dispatch an action so we dont have 100500 actions -// And selectors dont recalculate +// After user closes modal, dispatch an action so we don't have 100500 actions +// And selectors don't recalculate class Tokens extends React.Component { + renderCount = 0 + state = { filter: '', activeTokensAddresses: Set([]), @@ -78,7 +80,7 @@ class Tokens extends React.Component { const { activeTokensAddresses } = this.state const { updateActiveTokens, safeAddress } = this.props - updateActiveTokens(safeAddress, activeTokensAddresses.toList()) + updateActiveTokens(safeAddress, activeTokensAddresses) } onCancelSearch = () => { @@ -168,6 +170,7 @@ class Tokens extends React.Component { safeBalancesSelector, tokensSelector, safeEthAsTokenSelector, - (safeTokens: List, balances: List, tokensList: Map, ethAsToken: Token) => { + (safeTokens: List, balances: Map, tokensList: Map, ethAsToken: Token) => { const extendedTokens = Map().withMutations((map) => { safeTokens.forEach((tokenAddress: string) => { const baseToken = tokensList.get(tokenAddress) - const tokenBalance = balances.find((tknBalance) => tknBalance.address === tokenAddress) + const tokenBalance = balances.get(tokenAddress) if (baseToken) { - map.set(tokenAddress, baseToken.set('balance', tokenBalance ? tokenBalance.balance : '0')) + map.set(tokenAddress, baseToken.set('balance', tokenBalance || '0')) } }) diff --git a/src/routes/safe/store/actions/fetchTokenBalances.js b/src/routes/safe/store/actions/fetchTokenBalances.js index 26501fbe..ab69d87b 100644 --- a/src/routes/safe/store/actions/fetchTokenBalances.js +++ b/src/routes/safe/store/actions/fetchTokenBalances.js @@ -1,10 +1,9 @@ // @flow import type { Dispatch as ReduxDispatch } from 'redux' -import { List } from 'immutable' +import { Map, List } from 'immutable' import { BigNumber } from 'bignumber.js' import { type GlobalState } from '~/store/index' import { type Token } from '~/logic/tokens/store/model/token' -import TokenBalanceRecord from '~/routes/safe/store/models/tokenBalance' import { getStandardTokenContract } from '~/logic/tokens/store/actions/fetchTokens' import updateSafe from './updateSafe' import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers' @@ -36,13 +35,20 @@ const fetchTokenBalances = (safeAddress: string, tokens: List) => async ( const withBalances = await Promise.all( tokens.map(async (token) => { const balance = await calculateBalanceOf(token.address, safeAddress, token.decimals) - return TokenBalanceRecord({ + return { address: token.address, balance, - }) + } }), ) - dispatch(updateSafe({ address: safeAddress, balances: List(withBalances) })) + + const balances = Map().withMutations((map) => { + withBalances.forEach(({ address, balance }) => { + map.set(address, balance) + }) + }) + + dispatch(updateSafe({ address: safeAddress, balances })) } catch (err) { // eslint-disable-next-line console.error('Error when fetching token balances:', err) diff --git a/src/routes/safe/store/actions/updateActiveTokens.js b/src/routes/safe/store/actions/updateActiveTokens.js index 630e353d..e7c7c168 100644 --- a/src/routes/safe/store/actions/updateActiveTokens.js +++ b/src/routes/safe/store/actions/updateActiveTokens.js @@ -1,5 +1,5 @@ // @flow -import { List } from 'immutable' +import { Set } from 'immutable' import type { Dispatch as ReduxDispatch } from 'redux' import { type GlobalState } from '~/store' import updateSafe from './updateSafe' @@ -14,7 +14,7 @@ import updateSafe from './updateSafe' // }, // }) -const updateActiveTokens = (safeAddress: string, activeTokens: List) => async ( +const updateActiveTokens = (safeAddress: string, activeTokens: Set) => async ( dispatch: ReduxDispatch, ) => { dispatch(updateSafe({ address: safeAddress, activeTokens })) diff --git a/src/routes/safe/store/models/safe.js b/src/routes/safe/store/models/safe.js index 480f95df..9603aa0a 100644 --- a/src/routes/safe/store/models/safe.js +++ b/src/routes/safe/store/models/safe.js @@ -1,16 +1,17 @@ // @flow -import { List, Record } from 'immutable' +import { + List, Record, Map, Set, +} from 'immutable' import type { RecordFactory, RecordOf } from 'immutable' import type { Owner } from '~/routes/safe/store/models/owner' -import TokenBalance from '~/routes/safe/store/models/tokenBalance' export type SafeProps = { name: string, address: string, threshold: number, owners: List, - balances?: List, - activeTokens?: List, + balances: Map, + activeTokens: Set, ethBalance?: string, } @@ -20,8 +21,8 @@ const SafeRecord: RecordFactory = Record({ threshold: 0, ethBalance: 0, owners: List([]), - activeTokens: List([]), - balances: List([]), + activeTokens: new Set([]), + balances: Map({}), }) export type Safe = RecordOf diff --git a/src/routes/safe/store/models/tokenBalance.js b/src/routes/safe/store/models/tokenBalance.js deleted file mode 100644 index b8f1ed80..00000000 --- a/src/routes/safe/store/models/tokenBalance.js +++ /dev/null @@ -1,17 +0,0 @@ -// @flow -import { Record } from 'immutable' -import type { RecordFactory, RecordOf } from 'immutable' - -export type TokenBalanceProps = { - address: string, - balance: string, -} - -const TokenBalanceRecord: RecordFactory = Record({ - address: '', - balance: '0', -}) - -export type TokenBalance = RecordOf - -export default TokenBalanceRecord diff --git a/src/routes/safe/store/reducer/safe.js b/src/routes/safe/store/reducer/safe.js index 09dfd5d8..bdb4e393 100644 --- a/src/routes/safe/store/reducer/safe.js +++ b/src/routes/safe/store/reducer/safe.js @@ -1,9 +1,8 @@ // @flow -import { Map, List } from 'immutable' +import { Map, Set } from 'immutable' import { handleActions, type ActionType } from 'redux-actions' import { ADD_SAFE, buildOwnersFrom } from '~/routes/safe/store/actions/addSafe' import SafeRecord, { type SafeProps } from '~/routes/safe/store/models/safe' -import TokenBalance from '~/routes/safe/store/models/tokenBalance' import { makeOwner, type OwnerProps } from '~/routes/safe/store/models/owner' import { UPDATE_SAFE } from '~/routes/safe/store/actions/updateSafe' import { ACTIVATE_TOKEN_FOR_ALL_SAFES } from '~/routes/safe/store/actions/activateTokenForAllSafes' @@ -22,8 +21,8 @@ export const buildSafe = (storedSafe: SafeProps) => { const names = storedSafe.owners.map((owner: OwnerProps) => owner.name) const addresses = storedSafe.owners.map((owner: OwnerProps) => owner.address) const owners = buildOwnersFrom(Array.from(names), Array.from(addresses)) - const activeTokens = List(storedSafe.activeTokens) - const balances = storedSafe.balances.map((balance) => TokenBalance(balance)) + const activeTokens = Set(storedSafe.activeTokens) + const balances = Map(storedSafe.balances) const safe: SafeProps = { ...storedSafe, diff --git a/src/test/safe.dom.balances.test.js b/src/test/safe.dom.balances.test.js index d75d3bd7..53815244 100644 --- a/src/test/safe.dom.balances.test.js +++ b/src/test/safe.dom.balances.test.js @@ -1,13 +1,12 @@ // @flow import { waitForElement } from '@testing-library/react' -import { List } from 'immutable' +import { Set, Map } from 'immutable' import { aNewStore } from '~/store' import { sleep } from '~/utils/timer' import { aMinedSafe } from '~/test/builder/safe.redux.builder' import { sendTokenTo, sendEtherTo } from '~/test/utils/tokenMovements' import { renderSafeView } from '~/test/builder/safe.dom.utils' import { dispatchAddTokenToList } from '~/test/utils/transactions/moveTokens.helper' -import TokenBalanceRecord from '~/routes/safe/store/models/tokenBalance' import { calculateBalanceOf } from '~/routes/safe/store/actions/fetchTokenBalances' import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens' import '@testing-library/jest-dom/extend-expect' @@ -34,12 +33,11 @@ describe('DOM > Feature > Balances', () => { const safeTokenBalance = await calculateBalanceOf(tokenAddress, safeAddress, 18) expect(safeTokenBalance).toBe(tokensAmount) - const balanceAsRecord = TokenBalanceRecord({ - address: tokenAddress, - balance: safeTokenBalance, + const balances = Map({ + [tokenAddress]: safeTokenBalance, }) - store.dispatch(updateActiveTokens(safeAddress, List([tokenAddress]))) - store.dispatch(updateSafe({ address: safeAddress, balances: List([balanceAsRecord]) })) + store.dispatch(updateActiveTokens(safeAddress, Set([tokenAddress]))) + store.dispatch(updateSafe({ address: safeAddress, balances })) await sleep(1000) const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID) diff --git a/src/test/safe.dom.funds.threshold=1.test.js b/src/test/safe.dom.funds.threshold=1.test.js index 146b53bb..e4c0f90f 100644 --- a/src/test/safe.dom.funds.threshold=1.test.js +++ b/src/test/safe.dom.funds.threshold=1.test.js @@ -1,6 +1,6 @@ // @flow import { fireEvent } from '@testing-library/react' -import { List } from 'immutable' +import { Map, Set } from 'immutable' import { aNewStore } from '~/store' import { aMinedSafe } from '~/test/builder/safe.redux.builder' import { sendTokenTo, sendEtherTo } from '~/test/utils/tokenMovements' @@ -8,7 +8,6 @@ import { renderSafeView } from '~/test/builder/safe.dom.utils' import { getWeb3, getBalanceInEtherOf } from '~/logic/wallets/getWeb3' import { dispatchAddTokenToList } from '~/test/utils/transactions/moveTokens.helper' import { sleep } from '~/utils/timer' -import TokenBalanceRecord from '~/routes/safe/store/models/tokenBalance' import { calculateBalanceOf } from '~/routes/safe/store/actions/fetchTokenBalances' import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens' import '@testing-library/jest-dom/extend-expect' @@ -78,12 +77,12 @@ describe('DOM > Feature > Sending Funds', () => { const safeTokenBalance = await calculateBalanceOf(tokenAddress, safeAddress, 18) expect(safeTokenBalance).toBe(tokensAmount) - const balanceAsRecord = TokenBalanceRecord({ - address: tokenAddress, - balance: safeTokenBalance, + const balances = Map({ + [tokenAddress]: safeTokenBalance, }) - store.dispatch(updateActiveTokens(safeAddress, List([tokenAddress]))) - store.dispatch(updateSafe({ address: safeAddress, balances: List([balanceAsRecord]) })) + + store.dispatch(updateActiveTokens(safeAddress, Set([tokenAddress]))) + store.dispatch(updateSafe({ address: safeAddress, balances })) await sleep(1000) // Open send funds modal diff --git a/src/test/safe.dom.sidebar.test.js b/src/test/safe.dom.sidebar.test.js index a6545a50..d1f4bfa5 100644 --- a/src/test/safe.dom.sidebar.test.js +++ b/src/test/safe.dom.sidebar.test.js @@ -39,17 +39,19 @@ describe('DOM > Feature > Sidebar', () => { fireEvent.click(SafeDom.getByTestId(TOGGLE_SIDEBAR_BTN_TESTID)) }) + await sleep(400) + const safes = SafeDom.getAllByTestId(SIDEBAR_SAFELIST_ROW_TESTID) expect(safes.length).toBe(2) - expect(safes[1]).toContainElement(SafeDom.getByText('default')) - expect(safes[0]).toContainElement(SafeDom.getByText('Make default')) + expect(safes[0]).toContainElement(SafeDom.getByText('default')) + expect(safes[1]).toContainElement(SafeDom.getByText('Make default')) act(() => { fireEvent.click(SafeDom.getByText('Make default')) }) - expect(safes[0]).toContainElement(SafeDom.getByText('default')) - expect(safes[1]).toContainElement(SafeDom.getByText('Make default')) + expect(safes[1]).toContainElement(SafeDom.getByText('default')) + expect(safes[0]).toContainElement(SafeDom.getByText('Make default')) }) }) diff --git a/src/test/tokens.dom.enabling.test.js b/src/test/tokens.dom.enabling.test.js index c41e21b8..b290970d 100644 --- a/src/test/tokens.dom.enabling.test.js +++ b/src/test/tokens.dom.enabling.test.js @@ -1,4 +1,5 @@ // @flow +import { waitForElement } from '@testing-library/react' import { List } from 'immutable' import { getWeb3 } from '~/logic/wallets/getWeb3' import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements' @@ -52,26 +53,25 @@ describe('DOM > Feature > Enable and disable default tokens', () => { // WHEN const TokensDom = await renderSafeView(store, safeAddress) - await sleep(400) // Check if only ETH is enabled - let balanceRows = TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID) + let balanceRows = await waitForElement(() => TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID)) expect(balanceRows.length).toBe(1) // THEN clickOnManageTokens(TokensDom) - toggleToken(TokensDom, 'FTE') - toggleToken(TokensDom, 'STE') + await toggleToken(TokensDom, 'FTE') + await toggleToken(TokensDom, 'STE') closeManageTokensModal(TokensDom) + // Wait for active tokens to save + await sleep(1500) + // Check if tokens were enabled balanceRows = TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID) expect(balanceRows.length).toBe(3) expect(balanceRows[1]).toHaveTextContent('FTE') expect(balanceRows[2]).toHaveTextContent('STE') - - await sleep(1000) - const tokensFromStorage = await getActiveTokens() expect(Object.keys(tokensFromStorage)).toContain(firstErc20Token.address) @@ -79,9 +79,10 @@ describe('DOM > Feature > Enable and disable default tokens', () => { // disable tokens clickOnManageTokens(TokensDom) - toggleToken(TokensDom, 'FTE') - toggleToken(TokensDom, 'STE') + await toggleToken(TokensDom, 'FTE') + await toggleToken(TokensDom, 'STE') closeManageTokensModal(TokensDom) + await sleep(1500) // check if tokens were disabled balanceRows = TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID) diff --git a/src/test/utils/DOMNavigation/tokens.js b/src/test/utils/DOMNavigation/tokens.js index 698933fd..dec6eeba 100644 --- a/src/test/utils/DOMNavigation/tokens.js +++ b/src/test/utils/DOMNavigation/tokens.js @@ -1,32 +1,38 @@ // @flow -import { fireEvent } from '@testing-library/react' +import { fireEvent, waitForElement, act } from '@testing-library/react' import { MANAGE_TOKENS_BUTTON_TEST_ID } from '~/routes/safe/components/Balances' -import { - ADD_CUSTOM_TOKEN_BUTTON_TEST_ID, - TOGGLE_TOKEN_TEST_ID, -} from '~/routes/safe/components/Balances/Tokens/screens/TokenList' +import { ADD_CUSTOM_TOKEN_BUTTON_TEST_ID } from '~/routes/safe/components/Balances/Tokens/screens/TokenList' +import { TOGGLE_TOKEN_TEST_ID } from '~/routes/safe/components/Balances/Tokens/screens/TokenList/TokenRow' import { MANAGE_TOKENS_MODAL_CLOSE_BUTTON_TEST_ID } from '~/routes/safe/components/Balances/Tokens' export const clickOnManageTokens = (dom: any): void => { const btn = dom.getByTestId(MANAGE_TOKENS_BUTTON_TEST_ID) - fireEvent.click(btn) + act(() => { + fireEvent.click(btn) + }) } export const clickOnAddCustomToken = (dom: any): void => { const btn = dom.getByTestId(ADD_CUSTOM_TOKEN_BUTTON_TEST_ID) - fireEvent.click(btn) + act(() => { + fireEvent.click(btn) + }) } -export const toggleToken = (dom: any, symbol: string): void => { - const btn = dom.getByTestId(`${symbol}_${TOGGLE_TOKEN_TEST_ID}`) +export const toggleToken = async (dom: any, symbol: string): Promise => { + const btn = await waitForElement(() => dom.getByTestId(`${symbol}_${TOGGLE_TOKEN_TEST_ID}`)) - fireEvent.click(btn) + act(() => { + fireEvent.click(btn) + }) } export const closeManageTokensModal = (dom: any) => { const btn = dom.getByTestId(MANAGE_TOKENS_MODAL_CLOSE_BUTTON_TEST_ID) - fireEvent.click(btn) + act(() => { + fireEvent.click(btn) + }) } diff --git a/yarn.lock b/yarn.lock index 32a4e9d8..9abf83aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1760,14 +1760,14 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@material-ui/core@4.4.3": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.4.3.tgz#65665d2c4e9cb84e018774e1471f6d0417f4535e" - integrity sha512-Lz8sMFeCrtq5/pbhqClWFHpveL0huixjca0tw7uvh9xKKB7VyyYOyTu7RamSZLxb34UCSMPlobR+KK25Nqzkqw== +"@material-ui/core@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.5.0.tgz#7e57cc40988c71b6340e3b2569b47dbac1820351" + integrity sha512-UHVAjU+1uDtA+OMBNBHb4RlCZOu514XeYPafNJv+GTdXBDr1SCPK7yqRE6TV1/bulxlDusTgu5Q6BAUgpmO4MA== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/styles" "^4.4.3" - "@material-ui/system" "^4.4.3" + "@material-ui/styles" "^4.5.0" + "@material-ui/system" "^4.5.0" "@material-ui/types" "^4.1.1" "@material-ui/utils" "^4.4.0" "@types/react-transition-group" "^4.2.0" @@ -1788,10 +1788,10 @@ dependencies: "@babel/runtime" "^7.4.4" -"@material-ui/styles@^4.4.3": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.4.3.tgz#78239177723660093cc9a277db5759c01c693c2a" - integrity sha512-kNUdHFWsrvWKIEPx8Xy2/qayqsGMrYmCMq+FIiJiYczVZl5hiS8j5+KayonnpVta/O+Dktk+cxWkVcgwtxMrHg== +"@material-ui/styles@^4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.5.0.tgz#4e591b8d44c7ecce318634bd8ac652499b6c277a" + integrity sha512-O0NSAECHK9f3DZK6wy56PZzp8b/7KSdfpJs8DSC7vnXUAoMPCTtchBKLzMtUsNlijiJFeJjSxNdQfjWXgyur5A== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.7.1" @@ -1801,20 +1801,20 @@ csstype "^2.5.2" deepmerge "^4.0.0" hoist-non-react-statics "^3.2.1" - jss "10.0.0-alpha.25" - jss-plugin-camel-case "10.0.0-alpha.25" - jss-plugin-default-unit "10.0.0-alpha.25" - jss-plugin-global "10.0.0-alpha.25" - jss-plugin-nested "10.0.0-alpha.25" - jss-plugin-props-sort "10.0.0-alpha.25" - jss-plugin-rule-value-function "10.0.0-alpha.25" - jss-plugin-vendor-prefixer "10.0.0-alpha.25" + jss "^10.0.0" + jss-plugin-camel-case "^10.0.0" + jss-plugin-default-unit "^10.0.0" + jss-plugin-global "^10.0.0" + jss-plugin-nested "^10.0.0" + jss-plugin-props-sort "^10.0.0" + jss-plugin-rule-value-function "^10.0.0" + jss-plugin-vendor-prefixer "^10.0.0" prop-types "^15.7.2" -"@material-ui/system@^4.4.3": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.4.3.tgz#68ca8cf83614255fcd5b9d3a72ce8ee58a43a5c7" - integrity sha512-Cb05vLXsaCzssXD/iZKa0/qC6YOwbFWnYdnOEdkXZ3Fn2Ytz7rsnMgFejUSQV1luVhUBlEIm8DVz40N25WwW7w== +"@material-ui/system@^4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.5.0.tgz#3235f5d7da8b8af4df425e4f065990c16dee8097" + integrity sha512-vR0PbMTzLnuuVCoYNQ13zyhLa/4s/UA9P9JbNuHBOOkfrHn53ShINiG0v05EgfwizfULLtc7mNvsGAgIyyp/hQ== dependencies: "@babel/runtime" "^7.4.4" deepmerge "^4.0.0" @@ -8513,10 +8513,10 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== -flow-bin@0.108.0: - version "0.108.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.108.0.tgz#6a42c85fd664d23dd937d925851e8e6ab5d71393" - integrity sha512-hPEyCP1J8rdhNDfCAA5w7bN6HUNBDcHVg/ABU5JVo0gUFMx+uRewpyEH8LlLBGjVQuIpbaPpaqpoaQhAVyaYww== +flow-bin@0.109.0: + version "0.109.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.109.0.tgz#dcdcb7402dd85b58200392d8716ccf14e5a8c24c" + integrity sha512-tpcMTpAGIRivYhFV3KJq+zHI2HzcXo8MoGe9pXS4G/UZuey2Faq/e8/gdph2WF0erRlML5hmwfwiq7v9c25c7w== flow-stoplight@^1.0.0: version "1.0.0" @@ -9744,7 +9744,7 @@ http-https@^1.0.0: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= -http-proxy-middleware@^0.19.1: +http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== @@ -10070,10 +10070,10 @@ is-absolute-url@^2.0.0: resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= -is-absolute-url@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.2.tgz#554f2933e7385cc46e94351977ca2081170a206e" - integrity sha512-+5g/wLlcm1AcxSP7014m6GvbPHswDx980vD/3bZaap8aGV9Yfs7Q6y6tfaupgZ5O74Byzc8dGrSCJ+bFXx0KdA== +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== is-absolute@^1.0.0: version "1.0.0" @@ -11290,69 +11290,69 @@ jsqr@^1.2.0: resolved "https://registry.yarnpkg.com/jsqr/-/jsqr-1.2.0.tgz#f93fc65fa7d1ded78b1bcb020fa044352b04261a" integrity sha512-wKcQS9QC2VHGk7aphWCp1RrFyC0CM6fMgC5prZZ2KV/Lk6OKNoCod9IR6bao+yx3KPY0gZFC5dc+h+KFzCI0Wg== -jss-plugin-camel-case@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.25.tgz#ea4389de47ccf3b4757f76e62cbb2e8b96b7a2c2" - integrity sha512-J5ZEGDTy9ddqdTUPAF4SJQ25u5kiG1ORP8F+ZPEZAkkiMQJp+/Aol4I7xhTS2aW1Lhg8xNxdhdRfBi5yU7wOvg== +jss-plugin-camel-case@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0.tgz#d601bae2e8e2041cc526add289dcd7062db0a248" + integrity sha512-yALDL00+pPR4FJh+k07A8FeDvfoPPuXU48HLy63enAubcVd3DnS+2rgqPXglHDGixIDVkCSXecl/l5GAMjzIbA== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss-plugin-default-unit@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.25.tgz#df5b39bbc0114146101bb3cf8bc7e281e3d0f454" - integrity sha512-auOG459B+yEqkojgaXH02SYO9+xjmAxlmP+WbzhVpXqOFJ2CN/kaxd8P4NJZLdj3BQxHiM7WIyMVh786StE+EA== +jss-plugin-default-unit@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0.tgz#601caf5f576fc0c66986fbe8a9aa37307a3a3ea3" + integrity sha512-sURozIOdCtGg9ap18erQ+ijndAfEGtTaetxfU3H4qwC18Bi+fdvjlY/ahKbuu0ASs7R/+WKCP7UaRZOjUDMcdQ== dependencies: "@babel/runtime" "^7.3.1" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss-plugin-global@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.25.tgz#2b6a6a14ef6cdb9994dbadf709e480d5c871b5f6" - integrity sha512-cS98Q8X8jwltuaBZd9eYuxMXxkUL+mJGl2Ok3/nmJzH9nLzj6i7kLxSoDtuJNqsRmbP7ogIXVozJUq9lUu2hlQ== +jss-plugin-global@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.0.0.tgz#0fed1b6461e0d57d6e394f877529009bc1cb3cb6" + integrity sha512-80ofWKSQUo62bxLtRoTNe0kFPtHgUbAJeOeR36WEGgWIBEsXLyXOnD5KNnjPqG4heuEkz9eSLccjYST50JnI7Q== dependencies: "@babel/runtime" "^7.3.1" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss-plugin-nested@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.25.tgz#b8e29d336e1850047914511681d56330e3ea24ac" - integrity sha512-7sk7/6mX1YTgXe+AyeD1zEyKTgIGbbhYtg+wWQcHJlE1flW2JHfcQ5mw84FgHcHQRQ8Dq3l9I3aEY51ev0J1Wg== +jss-plugin-nested@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.0.0.tgz#d37ecc013c3b0d0e4acc2b48f6b62da6ae53948b" + integrity sha512-waxxwl/po1hN3azTyixKnr8ReEqUv5WK7WsO+5AWB0bFndML5Yqnt8ARZ90HEg8/P6WlqE/AB2413TkCRZE8bA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.0.0-alpha.25" + jss "10.0.0" tiny-warning "^1.0.2" -jss-plugin-props-sort@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.25.tgz#dfaa1a6bf9863ae9593b99bf51cd26caea2fe0ec" - integrity sha512-8B/6QLQuUX8cIlZbXdjEm5l0jCX4EgacYMcFJhdKwDKEZYeAghpgQQrCKl0/CYHW7iFge5wim67P+uL6QxMzyw== +jss-plugin-props-sort@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0.tgz#38a13407384c2a4a7c026659488350669b953b18" + integrity sha512-41mf22CImjwNdtOG3r+cdC8+RhwNm616sjHx5YlqTwtSJLyLFinbQC/a4PIFk8xqf1qpFH1kEAIw+yx9HaqZ3g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss-plugin-rule-value-function@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.25.tgz#35350da52334a6031808e197526227434c194277" - integrity sha512-CQQtWO+/OZRGaFRBSGQUgAci9YlVtdoXcWQKBNo70tmpp+kaXKlFNCYaL3jmHbJHMiwKQYG2RYFQNIrwJ9SGmA== +jss-plugin-rule-value-function@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0.tgz#3ec1b781b7c86080136dbef6c36e91f20244b72e" + integrity sha512-Jw+BZ8JIw1f12V0SERqGlBT1JEPWax3vuZpMym54NAXpPb7R1LYHiCTIlaJUyqvIfEy3kiHMtgI+r2whGgRIxQ== dependencies: "@babel/runtime" "^7.3.1" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss-plugin-vendor-prefixer@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.25.tgz#bc0c4b6dcb28d4801775cbad70ad9bc7e0c7707b" - integrity sha512-5FXpB/TiwckbrkoDCmd27YsWCESl1K4hAX/oro2/geEXgnVQvDgQOf2eWCsjYO2K1lYPPXtskMfws/Q3eKmbYg== +jss-plugin-vendor-prefixer@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0.tgz#400280535b0f483a9c78105afe4eee61b70018eb" + integrity sha512-qslqvL0MUbWuzXJWdUxpj6mdNUX8jr4FFTo3aZnAT65nmzWL7g8oTr9ZxmTXXgdp7ANhS1QWE7036/Q2isFBpw== dependencies: "@babel/runtime" "^7.3.1" css-vendor "^2.0.6" - jss "10.0.0-alpha.25" + jss "10.0.0" -jss@10.0.0-alpha.25: - version "10.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.0.0-alpha.25.tgz#20a506d8159e3f6bd91e133d54ffd3df0ffd3010" - integrity sha512-zqKnXv181B9vue2yYhmVhc+6ggbbxHF/33rjXfXEjaa22nOvknTI21QDfq3oZ8uCC50kcFp3Z8KU1ghUXdFvIA== +jss@10.0.0, jss@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.0.0.tgz#998d5026c02accae15708de83bd6ba57bac977d2" + integrity sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ== dependencies: "@babel/runtime" "^7.3.1" csstype "^2.6.5" @@ -12650,10 +12650,10 @@ node-fetch@^2.6.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== -node-forge@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.8.2.tgz#b4bcc59fb12ce77a8825fc6a783dfe3182499c5a" - integrity sha512-mXQ9GBq1N3uDCyV1pdSzgIguwgtVpM7f5/5J4ipz12PKWElmPpVWLDuWl8iXmhysr21+WmX/OJ5UKx82wjomgg== +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== node-int64@^0.4.0: version "0.4.0" @@ -15958,12 +15958,12 @@ select@^1.1.2: resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= -selfsigned@^1.10.6: - version "1.10.6" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.6.tgz#7b3cd37ed9c2034261a173af1a1aae27d8169b67" - integrity sha512-i3+CeqxL7DpAazgVpAGdKMwHuL63B5nhJMh9NQ7xmChGkA3jNFflq6Jyo1LLJYcr3idWiNOPWHCrm4zMayLG4w== +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== dependencies: - node-forge "0.8.2" + node-forge "0.9.0" semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: version "1.1.0" @@ -17865,10 +17865,10 @@ truffle-workflow-compile@^2.1.3: truffle-external-compile "^1.0.15" truffle-resolver "^5.0.15" -truffle@5.0.38: - version "5.0.38" - resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.0.38.tgz#f306ad1bddea7ad87b795783da2ca9f19a8345dc" - integrity sha512-RmbhEFROg+SGyQRM0tWk4NHUrS/uqHDTcc/ZY0k3JFd4cbr2vGD2csdWCfVW2/+SQ2qufXymurt9aRNvkpYQDA== +truffle@5.0.39: + version "5.0.39" + resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.0.39.tgz#5710ba8f60a7184d9eb51d632308f2af0a2e8aff" + integrity sha512-2a17t4o6r0rNMpeQXBc51nXigtIaP9/sU8N2zflaazvzYgDgLMZfqh/dir2mTfyybOsrR47NL310p+6+c8u8VA== dependencies: app-module-path "^2.2.0" mocha "5.2.0" @@ -19623,10 +19623,10 @@ webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-middleware@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.1.tgz#1167aea02afa034489869b8368fe9fed1aea7d09" - integrity sha512-5MWu9SH1z3hY7oHOV6Kbkz5x7hXbxK56mGHNqHTe6d+ewxOwKUxoUJBs7QIaJb33lPjl9bJZ3X0vCoooUzC36A== +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== dependencies: memory-fs "^0.4.1" mime "^2.4.4" @@ -19634,10 +19634,10 @@ webpack-dev-middleware@^3.7.1: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.8.1.tgz#485b64c4aadc23f601e72114b40c1b1fea31d9f1" - integrity sha512-9F5DnfFA9bsrhpUCAfQic/AXBVHvq+3gQS+x6Zj0yc1fVVE0erKh2MV4IV12TBewuTrYeeTIRwCH9qLMvdNvTw== +webpack-dev-server@3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.8.2.tgz#3292427bf6510da9a3ac2d500b924a4197667ff9" + integrity sha512-0xxogS7n5jHDQWy0WST0q6Ykp7UGj4YvWh+HVN71JoE7BwPxMZrwgraBvmdEMbDVMBzF0u+mEzn8TQzBm5NYJQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -19648,18 +19648,18 @@ webpack-dev-server@3.8.1: del "^4.1.1" express "^4.17.1" html-entities "^1.2.1" - http-proxy-middleware "^0.19.1" + http-proxy-middleware "0.19.1" import-local "^2.0.0" internal-ip "^4.3.0" ip "^1.1.5" - is-absolute-url "^3.0.2" + is-absolute-url "^3.0.3" killable "^1.0.1" loglevel "^1.6.4" opn "^5.5.0" p-retry "^3.0.1" portfinder "^1.0.24" schema-utils "^1.0.0" - selfsigned "^1.10.6" + selfsigned "^1.10.7" semver "^6.3.0" serve-index "^1.9.1" sockjs "0.3.19" @@ -19668,7 +19668,7 @@ webpack-dev-server@3.8.1: strip-ansi "^3.0.1" supports-color "^6.1.0" url "^0.11.0" - webpack-dev-middleware "^3.7.1" + webpack-dev-middleware "^3.7.2" webpack-log "^2.0.0" ws "^6.2.1" yargs "12.0.5" @@ -19691,10 +19691,10 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-manifest-plugin@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.1.2.tgz#990c448b4cfe1cf0b2dfad4a422264aabc4c98eb" - integrity sha512-XWjPY0NXXJ1tGQZgtOMZtEsm8mST23nvO7q5e5H26NH4pv7wfYbHaX9Uwogve+IF6Ilv4j1e3hPr9N3JGZdilA== +webpack-manifest-plugin@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz#19ca69b435b0baec7e29fbe90fb4015de2de4f16" + integrity sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ== dependencies: fs-extra "^7.0.0" lodash ">=3.5 <5" From fec212f2d63e5be83cbaa20996b580676733744a Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 12:01:17 +0400 Subject: [PATCH 17/22] dep bump, add copy/etherscan buttons to header provider details dropdown --- package.json | 6 ++-- .../component/ProviderDetails/UserDetails.jsx | 32 ++++++++--------- yarn.lock | 34 +++++++++---------- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index d7c186c1..5bf88bb4 100644 --- a/package.json +++ b/package.json @@ -50,8 +50,8 @@ "notistack": "https://github.com/gnosis/notistack.git#v0.9.4", "optimize-css-assets-webpack-plugin": "5.0.3", "qrcode.react": "^0.9.3", - "react": "16.10.1", - "react-dom": "16.10.1", + "react": "16.10.2", + "react-dom": "16.10.2", "react-final-form": "6.3.0", "react-final-form-listeners": "^1.0.2", "react-hot-loader": "4.12.14", @@ -97,7 +97,7 @@ "@storybook/addon-knobs": "5.2.1", "@storybook/addon-links": "5.2.1", "@storybook/react": "5.2.1", - "@testing-library/react": "9.2.0", + "@testing-library/react": "9.3.0", "autoprefixer": "9.6.1", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "10.0.3", diff --git a/src/components/Header/component/ProviderDetails/UserDetails.jsx b/src/components/Header/component/ProviderDetails/UserDetails.jsx index a398be56..fa0c2939 100644 --- a/src/components/Header/component/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/component/ProviderDetails/UserDetails.jsx @@ -1,11 +1,11 @@ // @flow import * as React from 'react' import classNames from 'classnames' -import OpenInNew from '@material-ui/icons/OpenInNew' import { withStyles } from '@material-ui/core/styles' import Dot from '@material-ui/icons/FiberManualRecord' +import EtherscanBtn from '~/components/EtherscanBtn' +import CopyBtn from '~/components/CopyBtn' import Paragraph from '~/components/layout/Paragraph' -import Link from '~/components/layout/Link' import Button from '~/components/layout/Button' import Identicon from '~/components/Identicon' import Hairline from '~/components/layout/Hairline' @@ -14,11 +14,10 @@ import Row from '~/components/layout/Row' import Block from '~/components/layout/Block' import Spacer from '~/components/Spacer' import { - xs, sm, md, lg, background, secondary, warning, connected as connectedBg, + xs, sm, md, lg, background, warning, connected as connectedBg, } from '~/theme/variables' import { upperFirst } from '~/utils/css' import { shortVersionOf } from '~/logic/wallets/ethAddresses' -import { getEtherScanLink } from '~/logic/wallets/getWeb3' import CircleDot from '~/components/Header/component/CircleDot' const metamaskIcon = require('../../assets/metamask-icon.svg') @@ -34,11 +33,6 @@ type Props = { onDisconnect: Function, } -const openIconStyle = { - height: '16px', - color: secondary, -} - const styles = () => ({ container: { padding: `${md} 12px`, @@ -65,7 +59,7 @@ const styles = () => ({ flexGrow: 1, textAlign: 'center', letterSpacing: '-0.5px', - fontSize: '12px', + marginRight: sm, }, labels: { fontSize: '12px', @@ -119,13 +113,15 @@ const UserDetails = ({ )} - + {address} {userAddress && ( - - - + <> + {' '} + + + )}
@@ -146,9 +142,11 @@ const UserDetails = ({ Wallet
- {provider === 'safe' - ? Safe client - : Metamask client} + {provider === 'safe' ? ( + Safe client + ) : ( + Metamask client + )} {upperFirst(provider)} diff --git a/yarn.lock b/yarn.lock index 87a59796..2c5d7105 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2531,10 +2531,10 @@ pretty-format "^24.0.0" redent "^3.0.0" -"@testing-library/react@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.2.0.tgz#143ad2d96b03c3c334e47aaf33cc2c9b7d007123" - integrity sha512-Hr87KZflfI+vPZjgyzBKQHolQHiXGU5aTGjQSCJdH/yGPbm+IzrvuWPS97GD3RUH3rSS1IXq1e2Sn8Hmyw2ctA== +"@testing-library/react@9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.3.0.tgz#1dabf46d1ea018a1c89acecc0e7b86859b34c0f8" + integrity sha512-FTPCwmLo0tLtP50Au2uGz4/N1BcJTnBx4StDVHZ47zPMEj1/+J2rk/RTj8SLoHRKWCtcmhN4wRmudOXQNP29/w== dependencies: "@babel/runtime" "^7.6.0" "@testing-library/dom" "^6.3.0" @@ -14609,15 +14609,15 @@ react-docgen@^4.1.0: node-dir "^0.1.10" recast "^0.17.3" -react-dom@16.10.1: - version "16.10.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.1.tgz#479a6511ba34a429273c213cbc2a9ac4d296dac1" - integrity sha512-SmM4ZW0uug0rn95U8uqr52I7UdNf6wdGLeXDmNLfg3y5q5H9eAbdjF5ubQc3bjDyRrvdAB2IKG7X0GzSpnn5Mg== +react-dom@16.10.2: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.2.tgz#4840bce5409176bc3a1f2bd8cb10b92db452fda6" + integrity sha512-kWGDcH3ItJK4+6Pl9DZB16BXYAZyrYQItU4OMy0jAkv5aNqc+mAKb4TpFtAteI6TJZu+9ZlNhaeNQSVQDHJzkw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.16.1" + scheduler "^0.16.2" react-dom@^16.8.3: version "16.8.6" @@ -14912,10 +14912,10 @@ react-window@^1.8.5: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@16.10.1: - version "16.10.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.10.1.tgz#967c1e71a2767dfa699e6ba702a00483e3b0573f" - integrity sha512-2bisHwMhxQ3XQz4LiJJwG3360pY965pTl/MRrZYxIBKVj4fOHoDs5aZAkYXGxDRO1Li+SyjTAilQEbOmtQJHzA== +react@16.10.2: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.10.2.tgz#a5ede5cdd5c536f745173c8da47bda64797a4cf0" + integrity sha512-MFVIq0DpIhrHFyqLU0S3+4dIcBhhOvBE8bJ/5kHPVOVaGdo0KuiQzpcjCPsf585WvhypqtrMILyoE2th6dT+Lw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -15817,10 +15817,10 @@ scheduler@^0.13.6: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.1.tgz#a6fb6ddec12dc2119176e6eb54ecfe69a9eba8df" - integrity sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg== +scheduler@^0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" + integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" From 673cbaadf977f6c115c38fbbdc7c37dc9fa163e4 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 12:23:15 +0400 Subject: [PATCH 18/22] eslint fix --- src/components/Header/component/ProviderDetails/UserDetails.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Header/component/ProviderDetails/UserDetails.jsx b/src/components/Header/component/ProviderDetails/UserDetails.jsx index fa0c2939..342ecf13 100644 --- a/src/components/Header/component/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/component/ProviderDetails/UserDetails.jsx @@ -118,7 +118,6 @@ const UserDetails = ({ {userAddress && ( <> - {' '} From d8d39b38a5ae3fc61ed207f0d53a278dea53dfd5 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 18:55:34 +0400 Subject: [PATCH 19/22] Fix header copy button tooltip not displayed: add a boolean prop to increase z-index --- src/components/CopyBtn/index.jsx | 16 +++++++++++----- .../component/ProviderDetails/UserDetails.jsx | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/CopyBtn/index.jsx b/src/components/CopyBtn/index.jsx index 8cba470f..dd076ffd 100644 --- a/src/components/CopyBtn/index.jsx +++ b/src/components/CopyBtn/index.jsx @@ -1,13 +1,13 @@ // @flow import React, { useState } from 'react' import Tooltip from '@material-ui/core/Tooltip' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Img from '~/components/layout/Img' import { copyToClipboard } from '~/utils/clipboard' import { xs } from '~/theme/variables' import CopyIcon from './copy.svg' -const styles = () => ({ +const useStyles = makeStyles({ container: { display: 'flex', justifyContent: 'center', @@ -20,19 +20,24 @@ const styles = () => ({ backgroundColor: '#F0EFEE', }, }, + inreasedPopperZindex: { + zIndex: 2001, + }, }) type CopyBtnProps = { content: string, - classes: Object, + increaseZindex?: boolean, } -const CopyBtn = ({ content, classes }: CopyBtnProps) => { +const CopyBtn = ({ content, increaseZindex = false }: CopyBtnProps) => { if (!navigator.clipboard) { return null } const [clicked, setClicked] = useState(false) + const classes = useStyles() + const customClasses = increaseZindex ? { popper: classes.inreasedPopperZindex } : {} return ( { } }, 300) }} + classes={customClasses} >
{ ) } -export default withStyles(styles)(CopyBtn) +export default CopyBtn diff --git a/src/components/Header/component/ProviderDetails/UserDetails.jsx b/src/components/Header/component/ProviderDetails/UserDetails.jsx index 342ecf13..72635cdb 100644 --- a/src/components/Header/component/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/component/ProviderDetails/UserDetails.jsx @@ -118,7 +118,7 @@ const UserDetails = ({ {userAddress && ( <> - + )} From 27bf8f1824b8f3b6a97bdcc6dbfab9166d33c281 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 19:06:24 +0400 Subject: [PATCH 20/22] Fix pagination element ordering --- src/theme/mui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme/mui.js b/src/theme/mui.js index 4f6e46ae..3d88cd59 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -246,7 +246,7 @@ export default createMuiTheme({ caption: { fontFamily: 'Averta, monospace', fontSize: mediumFontSize, - order: 3, + order: 2, color: disabled, }, input: { From 5c8589cd27f19e64fba16993615a9888abcc819d Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 19:10:32 +0400 Subject: [PATCH 21/22] add increaseZindex prop to EtherscanBtn to fix tooltip in provider dropdown in header --- src/components/EtherscanBtn/index.jsx | 44 ++++++++++--------- .../component/ProviderDetails/UserDetails.jsx | 2 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/EtherscanBtn/index.jsx b/src/components/EtherscanBtn/index.jsx index be02c48a..ea1dc738 100644 --- a/src/components/EtherscanBtn/index.jsx +++ b/src/components/EtherscanBtn/index.jsx @@ -1,13 +1,13 @@ // @flow import React from 'react' import Tooltip from '@material-ui/core/Tooltip' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Img from '~/components/layout/Img' import { getEtherScanLink } from '~/logic/wallets/getWeb3' import { xs } from '~/theme/variables' import SearchIcon from './search.svg' -const styles = () => ({ +const useStyles = makeStyles({ container: { display: 'flex', justifyContent: 'center', @@ -19,30 +19,34 @@ const styles = () => ({ backgroundColor: '#F0EFEE', }, }, + inreasedPopperZindex: { + zIndex: 2001, + }, }) type EtherscanBtnProps = { type: 'tx' | 'address', value: string, - classes: Object, + increaseZindex?: boolean, } -const EtherscanBtn = ({ - type, value, classes, -}: EtherscanBtnProps) => ( - - - Etherscan - - -) +const EtherscanBtn = ({ type, value, increaseZindex = false }: EtherscanBtnProps) => { + const classes = useStyles() + const customClasses = increaseZindex ? { popper: classes.inreasedPopperZindex } : {} -const EtherscanBtnWithStyles = withStyles(styles)(EtherscanBtn) + return ( + + + Etherscan + + + ) +} -export default EtherscanBtnWithStyles +export default EtherscanBtn diff --git a/src/components/Header/component/ProviderDetails/UserDetails.jsx b/src/components/Header/component/ProviderDetails/UserDetails.jsx index 72635cdb..a0d30435 100644 --- a/src/components/Header/component/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/component/ProviderDetails/UserDetails.jsx @@ -119,7 +119,7 @@ const UserDetails = ({ {userAddress && ( <> - + )} From c753c55fd02c55be21d76f18b96c58677088b549 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 4 Oct 2019 19:13:02 +0400 Subject: [PATCH 22/22] Use formatAmount for balances in safe list sidebar --- src/components/Sidebar/SafeList/index.jsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/Sidebar/SafeList/index.jsx b/src/components/Sidebar/SafeList/index.jsx index 8e2f1232..0848c068 100644 --- a/src/components/Sidebar/SafeList/index.jsx +++ b/src/components/Sidebar/SafeList/index.jsx @@ -14,6 +14,7 @@ import Identicon from '~/components/Identicon' import { mediumFontSize, sm, secondary, primary, } from '~/theme/variables' +import { formatAmount } from '~/logic/tokens/utils/formatAmount' import { shortVersionOf, sameAddress } from '~/logic/wallets/ethAddresses' import { type Safe } from '~/routes/safe/store/models/safe' import { SAFELIST_ADDRESS } from '~/routes/routes' @@ -71,7 +72,11 @@ const SafeList = ({ {safes.map((safe) => ( - + @@ -82,9 +87,7 @@ const SafeList = ({ classes={{ primary: classes.safeName, secondary: classes.safeAddress }} /> - {safe.ethBalance} - {' '} -ETH + {`${formatAmount(safe.ethBalance)} ETH`} {sameAddress(defaultSafe, safe.address) ? (