From 70140df4db9dc507228a283618ec2363698756af Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 8 Jun 2018 11:02:02 +0200 Subject: [PATCH 01/39] WA-234 Adding log errors when saving data in localstorage --- src/utils/localStorage.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/localStorage.js b/src/utils/localStorage.js index 072ed73317..474e3dbbf9 100644 --- a/src/utils/localStorage.js +++ b/src/utils/localStorage.js @@ -28,7 +28,8 @@ export const saveSafes = (safes: Object) => { const serializedState = JSON.stringify(safes) localStorage.setItem(SAFES_KEY, serializedState) } catch (err) { - // Ignore write errors + // eslint-disable-next-line + console.log('Error storing safe info in localstorage') } } @@ -38,7 +39,8 @@ export const setOwners = (safeAddress: string, owners: List) => { const serializedState = JSON.stringify(ownersAsMap) localStorage.setItem(`${OWNERS_KEY}-${safeAddress}`, serializedState) } catch (err) { - // Ignore write errors + // eslint-disable-next-line + console.log('Error storing owners in localstorage') } } From 666683c086838c9125e111df8aa97b6b6e0372ac Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 8 Jun 2018 11:24:45 +0200 Subject: [PATCH 02/39] WA-234 Giving more time to DOM test to refresh the DOM after creating a safe --- src/routes/open/components/Layout.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/open/components/Layout.test.js b/src/routes/open/components/Layout.test.js index 130bba707f..49aa8a74d0 100644 --- a/src/routes/open/components/Layout.test.js +++ b/src/routes/open/components/Layout.test.js @@ -59,7 +59,7 @@ describe('React DOM TESTS > Create Safe form', () => { // giving some time to the component for updating its state with safe // before destroying its context - await sleep(6000) + await sleep(9000) // THEN const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID) From 509134499cb190c05d536611c6e7e3c9d258504f Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 8 Jun 2018 12:34:58 +0200 Subject: [PATCH 03/39] WA-234 See list of TXs after changing the Threshold --- src/routes/safe/component/Safe/index.jsx | 2 +- src/routes/safe/component/Threshold/index.jsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 23588ec986..6d9d6c660a 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -64,7 +64,7 @@ class GnoSafe extends React.PureComponent { onEditThreshold = () => { const { safe } = this.props - this.setState({ component: }) + this.setState({ component: }) } onAddOwner = (e: SyntheticEvent) => { diff --git a/src/routes/safe/component/Threshold/index.jsx b/src/routes/safe/component/Threshold/index.jsx index 297b8d50b3..39c359ea6c 100644 --- a/src/routes/safe/component/Threshold/index.jsx +++ b/src/routes/safe/component/Threshold/index.jsx @@ -23,7 +23,7 @@ type State = { done: boolean, } -export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'RESET' +export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'SEE TXs' class Threshold extends React.PureComponent { state = { @@ -49,6 +49,7 @@ class Threshold extends React.PureComponent { onReset = () => { this.setState({ done: false }) + this.props.onReset() } render() { From f1ff0ca17fd2b1464b9dfbb9b52375f75e48d796 Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 8 Jun 2018 12:36:24 +0200 Subject: [PATCH 04/39] WA-234 Change Add Onwer review component and say Increase threshold? --- src/routes/safe/component/AddOwner/AddOwnerForm/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/component/AddOwner/AddOwnerForm/index.jsx b/src/routes/safe/component/AddOwner/AddOwnerForm/index.jsx index 721869f2f8..b47890b427 100644 --- a/src/routes/safe/component/AddOwner/AddOwnerForm/index.jsx +++ b/src/routes/safe/component/AddOwner/AddOwnerForm/index.jsx @@ -63,7 +63,7 @@ const AddOwnerForm = ({ addresses, numOwners, threshold }: Props) => () => ( component={Checkbox} type="checkbox" /> - Increase owner? + Increase threshold? ) From 97f0a0230987f45178c567bbe219c0a11360cecf Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 11 Jun 2018 09:55:04 +0200 Subject: [PATCH 05/39] WA-234 Update contracts --- safe-contracts/build/contracts/CreateAndAddModules.json | 8 +++++++- safe-contracts/build/contracts/DailyLimitModule.json | 8 +++++++- .../build/contracts/GnosisSafePersonalEdition.json | 8 +++++++- safe-contracts/build/contracts/GnosisSafeTeamEdition.json | 8 +++++++- safe-contracts/build/contracts/Migrations.json | 8 +++++++- safe-contracts/build/contracts/MultiSend.json | 8 +++++++- safe-contracts/build/contracts/ProxyFactory.json | 8 +++++++- safe-contracts/build/contracts/SocialRecoveryModule.json | 8 +++++++- safe-contracts/build/contracts/StateChannelModule.json | 8 +++++++- safe-contracts/build/contracts/WhitelistModule.json | 8 +++++++- 10 files changed, 70 insertions(+), 10 deletions(-) diff --git a/safe-contracts/build/contracts/CreateAndAddModules.json b/safe-contracts/build/contracts/CreateAndAddModules.json index 62751b267c..b819c6fc06 100644 --- a/safe-contracts/build/contracts/CreateAndAddModules.json +++ b/safe-contracts/build/contracts/CreateAndAddModules.json @@ -1282,8 +1282,14 @@ "links": {}, "address": "0x194371bd036c34314ded31a7ffe7e66f5461a62d", "transactionHash": "0x288775644c087eed5e41b96fecebdb23be4e6d40bef5b6fb9a2876c2a3145157" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x3910851ed9df1b8b4a1330c7331ca9c1aada5e80", + "transactionHash": "0x288775644c087eed5e41b96fecebdb23be4e6d40bef5b6fb9a2876c2a3145157" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.695Z" + "updatedAt": "2018-06-11T06:40:26.973Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/DailyLimitModule.json b/safe-contracts/build/contracts/DailyLimitModule.json index 5b0be962af..80f3042d88 100644 --- a/safe-contracts/build/contracts/DailyLimitModule.json +++ b/safe-contracts/build/contracts/DailyLimitModule.json @@ -6705,8 +6705,14 @@ "links": {}, "address": "0x0fb244fb862c95c66250c6c72e7e91a3d41a47d5", "transactionHash": "0xf501438a4ec967e2928d922e4af568a2a5365002f8b3f9e32117bbacfaa49331" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x1724133c19766a24a96ba628cc400665085d0271", + "transactionHash": "0xf501438a4ec967e2928d922e4af568a2a5365002f8b3f9e32117bbacfaa49331" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.688Z" + "updatedAt": "2018-06-11T06:40:26.975Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json index e3ea466837..c20561ec52 100644 --- a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json +++ b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json @@ -9870,8 +9870,14 @@ "links": {}, "address": "0xc3d42147f9b51c9749d3362e8b9ee6cb94861778", "transactionHash": "0x67117c1452ee2f4b904621b6f30790ff998d1f1a72f11c6b71ef47e3dd254724" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x4916d9d88c34167d364668eb7af1e98850bc30d9", + "transactionHash": "0x67117c1452ee2f4b904621b6f30790ff998d1f1a72f11c6b71ef47e3dd254724" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.672Z" + "updatedAt": "2018-06-11T06:40:26.968Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json index 9cb27b5852..510f65078e 100644 --- a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json +++ b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json @@ -6882,8 +6882,14 @@ "links": {}, "address": "0xf2bc99498b610a01d76358d8e2fe251c9783a216", "transactionHash": "0xa71d3b0b3752acc18733fa881f70c256d63562f28ccca9af910fad3beee9181a" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0xc0772c777ddd8290e2177ac0c88ed79e76a64fb6", + "transactionHash": "0xa71d3b0b3752acc18733fa881f70c256d63562f28ccca9af910fad3beee9181a" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.677Z" + "updatedAt": "2018-06-11T06:40:26.963Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/Migrations.json b/safe-contracts/build/contracts/Migrations.json index 5d1fcd5651..a07a17aa01 100644 --- a/safe-contracts/build/contracts/Migrations.json +++ b/safe-contracts/build/contracts/Migrations.json @@ -1404,8 +1404,14 @@ "links": {}, "address": "0x4aa39923aa66871debec9b8aa9008a3b220eb1df", "transactionHash": "0xb6a19a7a679a1474c09c651e4151421f210afa3f47effed019d4c0206144ee5f" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x3a3f882d20d959fb9ef0fccdf99636fd34cf9800", + "transactionHash": "0xb6a19a7a679a1474c09c651e4151421f210afa3f47effed019d4c0206144ee5f" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.697Z" + "updatedAt": "2018-06-11T06:40:26.983Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/MultiSend.json b/safe-contracts/build/contracts/MultiSend.json index 41362d48f1..27ec00eeb0 100644 --- a/safe-contracts/build/contracts/MultiSend.json +++ b/safe-contracts/build/contracts/MultiSend.json @@ -366,8 +366,14 @@ "links": {}, "address": "0xef9e7829f057e4d640bf66e17e06b3ab5cae508d", "transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x0254158d840bab3ca2531b0c2afc0eb03ce0127d", + "transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.696Z" + "updatedAt": "2018-06-11T06:40:26.982Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/ProxyFactory.json b/safe-contracts/build/contracts/ProxyFactory.json index a218d2ebe1..8934fb8056 100644 --- a/safe-contracts/build/contracts/ProxyFactory.json +++ b/safe-contracts/build/contracts/ProxyFactory.json @@ -1017,8 +1017,14 @@ "links": {}, "address": "0xaa973df8ec251cf67ec387d5627d42dbb738605f", "transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x6f8c59bca05451bf83ae86262234bef55df13910", + "transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.668Z" + "updatedAt": "2018-06-11T06:40:26.961Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/SocialRecoveryModule.json b/safe-contracts/build/contracts/SocialRecoveryModule.json index 5e7d519b21..e431a52619 100644 --- a/safe-contracts/build/contracts/SocialRecoveryModule.json +++ b/safe-contracts/build/contracts/SocialRecoveryModule.json @@ -7316,8 +7316,14 @@ "links": {}, "address": "0x9be4b89520d1dd6f2d115192587689c6c9bd1a99", "transactionHash": "0xf0cd95843453bdac02ad8018ef507479ea62989e56d69ad0ac1aad9d3a8515d2" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x097d7ddcb1c7eb9f1ec70e945a727833b81c0a1c", + "transactionHash": "0xf0cd95843453bdac02ad8018ef507479ea62989e56d69ad0ac1aad9d3a8515d2" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.692Z" + "updatedAt": "2018-06-11T06:40:26.981Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/StateChannelModule.json b/safe-contracts/build/contracts/StateChannelModule.json index 2ffa0349fa..7edc5fd5f4 100644 --- a/safe-contracts/build/contracts/StateChannelModule.json +++ b/safe-contracts/build/contracts/StateChannelModule.json @@ -5887,8 +5887,14 @@ "links": {}, "address": "0xe8abcdb37db8e7c563de32c5d207433ce44d1445", "transactionHash": "0x0396e1c9da4fa7bd313286e6033446dbb6e491f267956f8cf13202ce534fd0e6" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0x8d63548c3ad7a66dda1b9cfe1c1009bbc4970e7b", + "transactionHash": "0x0396e1c9da4fa7bd313286e6033446dbb6e491f267956f8cf13202ce534fd0e6" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.684Z" + "updatedAt": "2018-06-11T06:40:26.971Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/WhitelistModule.json b/safe-contracts/build/contracts/WhitelistModule.json index c0307ad788..125089e329 100644 --- a/safe-contracts/build/contracts/WhitelistModule.json +++ b/safe-contracts/build/contracts/WhitelistModule.json @@ -4360,8 +4360,14 @@ "links": {}, "address": "0x66c535e20f0c90530431ebab626da0ebdd55ec2d", "transactionHash": "0x463374c2fbc7eaff5b87e65c6a8fdc1177ef82c66084df6e7b88b506f99b193c" + }, + "1528699188286": { + "events": {}, + "links": {}, + "address": "0xf9012d187fbac45fe032e4da4321ffb5c5024fd2", + "transactionHash": "0x463374c2fbc7eaff5b87e65c6a8fdc1177ef82c66084df6e7b88b506f99b193c" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-06T14:51:43.700Z" + "updatedAt": "2018-06-11T06:40:26.978Z" } \ No newline at end of file From 24cac51be38984310c831165f5cafd0459af4eb8 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 11 Jun 2018 10:08:33 +0200 Subject: [PATCH 06/39] WA-234 Adding remove owner button --- src/routes/safe/component/Layout.jsx | 6 ++++-- src/routes/safe/component/Layout.stories.js | 4 ++++ src/routes/safe/component/Safe/Owners.jsx | 15 ++++++++++++++- src/routes/safe/component/Safe/index.jsx | 5 +++-- src/routes/safe/container/index.jsx | 4 ++-- src/routes/safe/container/selector.js | 2 ++ src/wallets/ethAddresses.js | 13 +++++++++++-- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/routes/safe/component/Layout.jsx b/src/routes/safe/component/Layout.jsx index e3b7f63650..d818ec841b 100644 --- a/src/routes/safe/component/Layout.jsx +++ b/src/routes/safe/component/Layout.jsx @@ -6,10 +6,12 @@ import GnoSafe from './Safe' type Props = SelectorProps -const Layout = ({ safe, balance, provider }: Props) => ( +const Layout = ({ + safe, balance, provider, userAddress, +}: Props) => ( { safe - ? + ? : } diff --git a/src/routes/safe/component/Layout.stories.js b/src/routes/safe/component/Layout.stories.js index 30ecd637e2..97ec777ab8 100644 --- a/src/routes/safe/component/Layout.stories.js +++ b/src/routes/safe/component/Layout.stories.js @@ -16,6 +16,7 @@ storiesOf('Routes /safe:address', module) .addDecorator(FrameDecorator) .add('Safe undefined being connected', () => ( ( , + userAddress: string, onAddOwner: () => void, } export const ADD_OWNER_BUTTON_TEXT = 'Add' +export const REMOVE_OWNER_BUTTON_TEXT = 'Delete' const Owners = openHoc(({ - open, toggle, owners, classes, onAddOwner, + open, toggle, owners, classes, onAddOwner, userAddress, }: Props) => ( @@ -59,6 +63,15 @@ const Owners = openHoc(({ primary={owner.name} secondary={owner.address} /> + { !sameAddress(userAddress, owner.address) && + + } ))} diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 6d9d6c660a..87bc38932f 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -27,6 +27,7 @@ const safeIcon = require('./assets/gnosis_safe.svg') type SafeProps = { safe: Safe, balance: string, + userAddress: string, } type State = { @@ -74,7 +75,7 @@ class GnoSafe extends React.PureComponent { } render() { - const { safe, balance } = this.props + const { safe, balance, userAddress } = this.props const { component } = this.state return ( @@ -82,7 +83,7 @@ class GnoSafe extends React.PureComponent { - +
diff --git a/src/routes/safe/container/index.jsx b/src/routes/safe/container/index.jsx index d6579eaddf..6c20e0e3f0 100644 --- a/src/routes/safe/container/index.jsx +++ b/src/routes/safe/container/index.jsx @@ -30,13 +30,13 @@ class SafeView extends React.PureComponent { render() { const { - safe, provider, balance, granted, + safe, provider, balance, granted, userAddress, } = this.props return ( { granted - ? + ? : } diff --git a/src/routes/safe/container/selector.js b/src/routes/safe/container/selector.js index e345129223..1ce3d69bb2 100644 --- a/src/routes/safe/container/selector.js +++ b/src/routes/safe/container/selector.js @@ -12,6 +12,7 @@ export type SelectorProps = { safe: SafeSelectorProps, provider: string, balance: string, + userAddress: string, } export const grantedSelector: Selector = createSelector( @@ -40,4 +41,5 @@ export default createStructuredSelector({ provider: providerNameSelector, balance: balanceSelector, granted: grantedSelector, + userAddress: userAccountSelector, }) diff --git a/src/wallets/ethAddresses.js b/src/wallets/ethAddresses.js index ed301735a5..a84ebf46db 100644 --- a/src/wallets/ethAddresses.js +++ b/src/wallets/ethAddresses.js @@ -1,3 +1,12 @@ // @flow -export const sameAddress = (firstAddress: string, secondAddress: string): boolean => - firstAddress.toLowerCase() === secondAddress.toLowerCase() +export const sameAddress = (firstAddress: string, secondAddress: string): boolean => { + if (!firstAddress) { + return false + } + + if (!secondAddress) { + return false + } + + return firstAddress.toLowerCase() === secondAddress.toLowerCase() +} From 5fcf87f6352b2c42a23908eacdc64e91c101bc4c Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 11 Jun 2018 10:46:18 +0200 Subject: [PATCH 07/39] WA-234 Updating material-ui react react-dom libraries --- package.json | 12 +- src/components/List/ListItemText/index.jsx | 4 +- src/components/Loader/index.jsx | 2 +- src/components/Refresh/index.jsx | 4 +- src/components/Stepper/index.jsx | 6 +- src/components/forms/Checkbox/index.jsx | 2 +- src/components/forms/TextField/index.jsx | 2 +- src/components/layout/Button/index.jsx | 2 +- src/components/layout/Table/index.jsx | 6 +- src/index.js | 2 +- .../components/FormConfirmation/index.jsx | 2 +- .../safe/component/AddOwner/Review/index.jsx | 2 +- .../AddTransaction/ReviewTx/index.jsx | 2 +- src/routes/safe/component/Safe/Address.jsx | 6 +- src/routes/safe/component/Safe/Balance.jsx | 7 +- .../safe/component/Safe/Confirmations.jsx | 6 +- src/routes/safe/component/Safe/DailyLimit.jsx | 6 +- src/routes/safe/component/Safe/MultisigTx.jsx | 6 +- src/routes/safe/component/Safe/Owners.jsx | 29 ++- src/routes/safe/component/Safe/index.jsx | 2 +- .../safe/component/Threshold/Review/index.jsx | 2 +- .../Transactions/Collapsed/Confirmations.jsx | 18 +- .../Transactions/Collapsed/index.jsx | 9 +- .../Transactions/Transaction/index.jsx | 17 +- .../safe/component/Withdrawn/Review/index.jsx | 2 +- src/theme/mui.js | 4 +- yarn.lock | 212 +++++++++--------- 27 files changed, 197 insertions(+), 177 deletions(-) diff --git a/package.json b/package.json index 3acd02cb4f..e16aec0f31 100644 --- a/package.json +++ b/package.json @@ -75,9 +75,9 @@ "postcss-mixins": "^6.2.0", "postcss-simple-vars": "^4.1.0", "pre-commit": "^1.2.2", - "react": "^16.2.0", - "react-dev-utils": "^5.0.0", - "react-dom": "^16.2.0", + "react": "^16.4.0", + "react-dev-utils": "^5.0.1", + "react-dom": "^16.4.0", "react-redux": "^5.0.7", "react-router-redux": "^5.0.0-alpha.9", "redux": "^3.7.2", @@ -100,14 +100,14 @@ "webpack-manifest-plugin": "^2.0.0-rc.2" }, "dependencies": { + "@material-ui/core": "^1.2.1", + "@material-ui/icons": "^1.1.0", "final-form": "^4.2.1", "history": "^4.7.2", - "material-ui": "^1.0.0-beta.35", - "material-ui-icons": "^1.0.0-beta.35", "react-final-form": "^3.1.2", "react-loadable": "^5.3.1", "react-router-dom": "^4.2.2", - "recompose": "^0.27.0" + "recompose": "^0.27.1" }, "jest": { "verbose": true, diff --git a/src/components/List/ListItemText/index.jsx b/src/components/List/ListItemText/index.jsx index 0ee309ab12..74edd96282 100644 --- a/src/components/List/ListItemText/index.jsx +++ b/src/components/List/ListItemText/index.jsx @@ -1,7 +1,7 @@ // @flow import * as React from 'react' -import { ListItemText } from 'material-ui/List' -import { withStyles } from 'material-ui/styles' +import ListItemText from '@material-ui/core/ListItemText' +import { withStyles } from '@material-ui/core/styles' import { type WithStyles } from '~/theme/mui' type Props = WithStyles & { diff --git a/src/components/Loader/index.jsx b/src/components/Loader/index.jsx index 750a941914..5ae3f7b927 100644 --- a/src/components/Loader/index.jsx +++ b/src/components/Loader/index.jsx @@ -1,7 +1,7 @@ // @flow import * as React from 'react' import Page from '~/components/layout/Page' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' const centerStyle = { margin: 'auto 0', diff --git a/src/components/Refresh/index.jsx b/src/components/Refresh/index.jsx index cabccf0d7a..8ec4bd5527 100644 --- a/src/components/Refresh/index.jsx +++ b/src/components/Refresh/index.jsx @@ -1,7 +1,7 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' -import RefreshIcon from 'material-ui-icons/Refresh' +import CircularProgress from '@material-ui/core/CircularProgress' +import RefreshIcon from '@material-ui/icons/Refresh' import { sm, secondary } from '~/theme/variables' type Props = { diff --git a/src/components/Stepper/index.jsx b/src/components/Stepper/index.jsx index 5f90792a87..d712156791 100644 --- a/src/components/Stepper/index.jsx +++ b/src/components/Stepper/index.jsx @@ -1,6 +1,8 @@ // @flow -import Stepper, { Step as FormStep, StepLabel } from 'material-ui/Stepper' -import { withStyles } from 'material-ui/styles' +import Stepper from '@material-ui/core/Stepper' +import FormStep from '@material-ui/core/Step' +import StepLabel from '@material-ui/core/StepLabel' +import { withStyles } from '@material-ui/core/styles' import * as React from 'react' import type { FormApi } from 'react-final-form' import GnoForm from '~/components/forms/GnoForm' diff --git a/src/components/forms/Checkbox/index.jsx b/src/components/forms/Checkbox/index.jsx index b20e101e7a..a11e084414 100644 --- a/src/components/forms/Checkbox/index.jsx +++ b/src/components/forms/Checkbox/index.jsx @@ -1,6 +1,6 @@ // @flow import React from 'react' -import Checkbox, { type CheckoxProps } from 'material-ui/Checkbox' +import Checkbox, { type CheckoxProps } from '@material-ui/core/Checkbox' class GnoCheckbox extends React.PureComponent { render() { diff --git a/src/components/forms/TextField/index.jsx b/src/components/forms/TextField/index.jsx index cbc88c882f..77c936edf5 100644 --- a/src/components/forms/TextField/index.jsx +++ b/src/components/forms/TextField/index.jsx @@ -1,6 +1,6 @@ // @flow import React from 'react' -import MuiTextField, { TextFieldProps } from 'material-ui/TextField' +import MuiTextField, { TextFieldProps } from '@material-ui/core/TextField' // Neded for solving a fix in Windows browsers const overflowStyle = { diff --git a/src/components/layout/Button/index.jsx b/src/components/layout/Button/index.jsx index 31a62242a6..f0ee9a37fe 100644 --- a/src/components/layout/Button/index.jsx +++ b/src/components/layout/Button/index.jsx @@ -1,4 +1,4 @@ // @flow -import Button from 'material-ui/Button' +import Button from '@material-ui/core/Button' export default Button diff --git a/src/components/layout/Table/index.jsx b/src/components/layout/Table/index.jsx index 817b7c2da9..6f23f5328e 100644 --- a/src/components/layout/Table/index.jsx +++ b/src/components/layout/Table/index.jsx @@ -1,6 +1,10 @@ // @flow import * as React from 'react' -import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table' +import Table from '@material-ui/core/Table' +import TableBody from '@material-ui/core/TableBody' +import TableCell from '@material-ui/core/TableCell' +import TableHead from '@material-ui/core/TableHead' +import TableRow from '@material-ui/core/TableRow' export { TableBody, TableCell, TableHead, TableRow } diff --git a/src/index.js b/src/index.js index e57c20bb91..364987d12d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ // @flow import 'babel-polyfill' -import { MuiThemeProvider } from 'material-ui/styles' +import { MuiThemeProvider } from '@material-ui/core/styles' import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' diff --git a/src/routes/open/components/FormConfirmation/index.jsx b/src/routes/open/components/FormConfirmation/index.jsx index 647a47e0ea..1fe4c9477e 100644 --- a/src/routes/open/components/FormConfirmation/index.jsx +++ b/src/routes/open/components/FormConfirmation/index.jsx @@ -1,6 +1,6 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Col from '~/components/layout/Col' diff --git a/src/routes/safe/component/AddOwner/Review/index.jsx b/src/routes/safe/component/AddOwner/Review/index.jsx index 6bc31b7734..7c2b9ac9a2 100644 --- a/src/routes/safe/component/AddOwner/Review/index.jsx +++ b/src/routes/safe/component/AddOwner/Review/index.jsx @@ -1,6 +1,6 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Heading from '~/components/layout/Heading' diff --git a/src/routes/safe/component/AddTransaction/ReviewTx/index.jsx b/src/routes/safe/component/AddTransaction/ReviewTx/index.jsx index 86524b60c6..e37028ee0c 100644 --- a/src/routes/safe/component/AddTransaction/ReviewTx/index.jsx +++ b/src/routes/safe/component/AddTransaction/ReviewTx/index.jsx @@ -1,6 +1,6 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Heading from '~/components/layout/Heading' diff --git a/src/routes/safe/component/Safe/Address.jsx b/src/routes/safe/component/Safe/Address.jsx index 3a21532e01..52dd313532 100644 --- a/src/routes/safe/component/Safe/Address.jsx +++ b/src/routes/safe/component/Safe/Address.jsx @@ -1,8 +1,8 @@ // @flow import * as React from 'react' -import { ListItem } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import Mail from 'material-ui-icons/Mail' +import ListItem from '@material-ui/core/ListItem' +import Avatar from '@material-ui/core/Avatar' +import Mail from '@material-ui/icons/Mail' import ListItemText from '~/components/List/ListItemText' type Props = { diff --git a/src/routes/safe/component/Safe/Balance.jsx b/src/routes/safe/component/Safe/Balance.jsx index 95aeef3f24..da30168813 100644 --- a/src/routes/safe/component/Safe/Balance.jsx +++ b/src/routes/safe/component/Safe/Balance.jsx @@ -1,8 +1,9 @@ // @flow import * as React from 'react' -import { ListItem, ListItemText } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import AccountBalance from 'material-ui-icons/AccountBalance' +import ListItem from '@material-ui/core/ListItem' +import ListItemText from '@material-ui/core/ListItemText' +import Avatar from '@material-ui/core/Avatar' +import AccountBalance from '@material-ui/icons/AccountBalance' type Props = { balance: string, diff --git a/src/routes/safe/component/Safe/Confirmations.jsx b/src/routes/safe/component/Safe/Confirmations.jsx index faf23d456c..c935077155 100644 --- a/src/routes/safe/component/Safe/Confirmations.jsx +++ b/src/routes/safe/component/Safe/Confirmations.jsx @@ -1,8 +1,8 @@ // @flow import * as React from 'react' -import { ListItem } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import DoneAll from 'material-ui-icons/DoneAll' +import ListItem from '@material-ui/core/ListItem' +import Avatar from '@material-ui/core/Avatar' +import DoneAll from '@material-ui/icons/DoneAll' import ListItemText from '~/components/List/ListItemText' import Button from '~/components/layout/Button' diff --git a/src/routes/safe/component/Safe/DailyLimit.jsx b/src/routes/safe/component/Safe/DailyLimit.jsx index c44326c047..fcfc10b523 100644 --- a/src/routes/safe/component/Safe/DailyLimit.jsx +++ b/src/routes/safe/component/Safe/DailyLimit.jsx @@ -1,8 +1,8 @@ // @flow import * as React from 'react' -import { ListItem } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import NotificationsPaused from 'material-ui-icons/NotificationsPaused' +import ListItem from '@material-ui/core/ListItem' +import Avatar from '@material-ui/core/Avatar' +import NotificationsPaused from '@material-ui/icons/NotificationsPaused' import Button from '~/components/layout/Button' import ListItemText from '~/components/List/ListItemText' import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit' diff --git a/src/routes/safe/component/Safe/MultisigTx.jsx b/src/routes/safe/component/Safe/MultisigTx.jsx index a70774db8a..e41973d016 100644 --- a/src/routes/safe/component/Safe/MultisigTx.jsx +++ b/src/routes/safe/component/Safe/MultisigTx.jsx @@ -1,8 +1,8 @@ // @flow import * as React from 'react' -import { ListItem } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import AcoountBalanceWallet from 'material-ui-icons/AccountBalanceWallet' +import ListItem from '@material-ui/core/ListItem' +import Avatar from '@material-ui/core/Avatar' +import AcoountBalanceWallet from '@material-ui/icons/AccountBalanceWallet' import Button from '~/components/layout/Button' import ListItemText from '~/components/List/ListItemText' diff --git a/src/routes/safe/component/Safe/Owners.jsx b/src/routes/safe/component/Safe/Owners.jsx index 47cdc07aa9..e3a5473bf5 100644 --- a/src/routes/safe/component/Safe/Owners.jsx +++ b/src/routes/safe/component/Safe/Owners.jsx @@ -1,17 +1,20 @@ // @flow import * as React from 'react' import openHoc, { type Open } from '~/components/hoc/OpenHoc' -import { withStyles } from 'material-ui/styles' -import Collapse from 'material-ui/transitions/Collapse' +import { withStyles } from '@material-ui/core/styles' +import Collapse from '@material-ui/core/Collapse' import ListItemText from '~/components/List/ListItemText' -import List, { ListItem, ListItemIcon } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' +import List from '@material-ui/core/List' +import ListItem from '@material-ui/core/ListItem' +import ListItemIcon from '@material-ui/core/ListItemIcon' +import Avatar from '@material-ui/core/Avatar' +import IconButton from '@material-ui/core/IconButton' import Button from '~/components/layout/Button' -import Group from 'material-ui-icons/Group' -import Delete from 'material-ui-icons/Delete' -import Person from 'material-ui-icons/Person' -import ExpandLess from 'material-ui-icons/ExpandLess' -import ExpandMore from 'material-ui-icons/ExpandMore' +import Group from '@material-ui/icons/Group' +import Delete from '@material-ui/icons/Delete' +import Person from '@material-ui/icons/Person' +import ExpandLess from '@material-ui/icons/ExpandLess' +import ExpandMore from '@material-ui/icons/ExpandMore' import { type OwnerProps } from '~/routes/safe/store/model/owner' import { type WithStyles } from '~/theme/mui' import { sameAddress } from '~/wallets/ethAddresses' @@ -64,13 +67,9 @@ const Owners = openHoc(({ secondary={owner.address} /> { !sameAddress(userAddress, owner.address) && - + } ))} diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 87bc38932f..e729f4c823 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -7,7 +7,7 @@ import Img from '~/components/layout/Img' import Paragraph from '~/components/layout/Paragraph' import Row from '~/components/layout/Row' import { type Safe } from '~/routes/safe/store/model/safe' -import List from 'material-ui/List' +import List from '@material-ui/core/List' import Withdrawn from '~/routes/safe/component/Withdrawn' import Transactions from '~/routes/safe/component/Transactions' diff --git a/src/routes/safe/component/Threshold/Review/index.jsx b/src/routes/safe/component/Threshold/Review/index.jsx index 0483e8762f..93937efde4 100644 --- a/src/routes/safe/component/Threshold/Review/index.jsx +++ b/src/routes/safe/component/Threshold/Review/index.jsx @@ -1,6 +1,6 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Heading from '~/components/layout/Heading' diff --git a/src/routes/safe/component/Transactions/Collapsed/Confirmations.jsx b/src/routes/safe/component/Transactions/Collapsed/Confirmations.jsx index 0b79b3d776..d0bcb9f43a 100644 --- a/src/routes/safe/component/Transactions/Collapsed/Confirmations.jsx +++ b/src/routes/safe/component/Transactions/Collapsed/Confirmations.jsx @@ -1,15 +1,17 @@ // @flow import * as React from 'react' import openHoc, { type Open } from '~/components/hoc/OpenHoc' -import { withStyles } from 'material-ui/styles' -import Collapse from 'material-ui/transitions/Collapse' +import { withStyles } from '@material-ui/core/styles' +import Collapse from '@material-ui/core/Collapse' import ListItemText from '~/components/List/ListItemText' -import List, { ListItem, ListItemIcon } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import Group from 'material-ui-icons/Group' -import Person from 'material-ui-icons/Person' -import ExpandLess from 'material-ui-icons/ExpandLess' -import ExpandMore from 'material-ui-icons/ExpandMore' +import List from '@material-ui/core/List' +import ListItem from '@material-ui/core/ListItem' +import ListItemIcon from '@material-ui/core/ListItemIcon' +import Avatar from '@material-ui/core/Avatar' +import Group from '@material-ui/icons/Group' +import Person from '@material-ui/icons/Person' +import ExpandLess from '@material-ui/icons/ExpandLess' +import ExpandMore from '@material-ui/icons/ExpandMore' import { type WithStyles } from '~/theme/mui' import { type Confirmation, type ConfirmationProps } from '~/routes/safe/store/model/confirmation' diff --git a/src/routes/safe/component/Transactions/Collapsed/index.jsx b/src/routes/safe/component/Transactions/Collapsed/index.jsx index b92a0635a2..d57b0b0aaa 100644 --- a/src/routes/safe/component/Transactions/Collapsed/index.jsx +++ b/src/routes/safe/component/Transactions/Collapsed/index.jsx @@ -3,11 +3,12 @@ import * as React from 'react' import { List as ImmutableList } from 'immutable' import Row from '~/components/layout/Row' import Col from '~/components/layout/Col' -import List, { ListItem } from 'material-ui/List' +import List from '@material-ui/core/List' +import ListItem from '@material-ui/core/ListItem' import ListItemText from '~/components/List/ListItemText' -import Avatar from 'material-ui/Avatar' -import Group from 'material-ui-icons/Group' -import MailOutline from 'material-ui-icons/MailOutline' +import Avatar from '@material-ui/core/Avatar' +import Group from '@material-ui/icons/Group' +import MailOutline from '@material-ui/icons/MailOutline' import { type Confirmation } from '~/routes/safe/store/model/confirmation' import Confirmations from './Confirmations' diff --git a/src/routes/safe/component/Transactions/Transaction/index.jsx b/src/routes/safe/component/Transactions/Transaction/index.jsx index 7ee4883384..344b33ba97 100644 --- a/src/routes/safe/component/Transactions/Transaction/index.jsx +++ b/src/routes/safe/component/Transactions/Transaction/index.jsx @@ -3,16 +3,17 @@ import * as React from 'react' import { List } from 'immutable' import { connect } from 'react-redux' import openHoc, { type Open } from '~/components/hoc/OpenHoc' -import ExpandLess from 'material-ui-icons/ExpandLess' -import ExpandMore from 'material-ui-icons/ExpandMore' +import ExpandLess from '@material-ui/icons/ExpandLess' +import ExpandMore from '@material-ui/icons/ExpandMore' import ListItemText from '~/components/List/ListItemText' import Row from '~/components/layout/Row' -import { ListItem, ListItemIcon } from 'material-ui/List' -import Avatar from 'material-ui/Avatar' -import AttachMoney from 'material-ui-icons/AttachMoney' -import Atm from 'material-ui-icons/LocalAtm' -import DoneAll from 'material-ui-icons/DoneAll' -import CompareArrows from 'material-ui-icons/CompareArrows' +import ListItem from '@material-ui/core/ListItem' +import ListItemIcon from '@material-ui/core/ListItemIcon' +import Avatar from '@material-ui/core/Avatar' +import AttachMoney from '@material-ui/icons/AttachMoney' +import Atm from '@material-ui/icons/LocalAtm' +import DoneAll from '@material-ui/icons/DoneAll' +import CompareArrows from '@material-ui/icons/CompareArrows' import Collapsed from '~/routes/safe/component/Transactions/Collapsed' import { type Transaction } from '~/routes/safe/store/model/transaction' import Hairline from '~/components/layout/Hairline/index' diff --git a/src/routes/safe/component/Withdrawn/Review/index.jsx b/src/routes/safe/component/Withdrawn/Review/index.jsx index 303d058841..83a36444df 100644 --- a/src/routes/safe/component/Withdrawn/Review/index.jsx +++ b/src/routes/safe/component/Withdrawn/Review/index.jsx @@ -1,6 +1,6 @@ // @flow import * as React from 'react' -import { CircularProgress } from 'material-ui/Progress' +import CircularProgress from '@material-ui/core/CircularProgress' import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Heading from '~/components/layout/Heading' diff --git a/src/theme/mui.js b/src/theme/mui.js index 486d342251..325d2da911 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -1,6 +1,6 @@ // @flow -import red from 'material-ui/colors/red' -import { createMuiTheme } from 'material-ui/styles' +import red from '@material-ui/core/colors/red' +import { createMuiTheme } from '@material-ui/core/styles' import { primary, secondary } from './variables' export type WithStyles = { diff --git a/yarn.lock b/yarn.lock index d6761ce8da..17e488987f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -657,6 +657,13 @@ "@babel/plugin-syntax-dynamic-import" "7.0.0-beta.40" "@babel/plugin-syntax-import-meta" "7.0.0-beta.40" +"@babel/runtime@^7.0.0-beta.42": + version "7.0.0-beta.49" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.49.tgz#03b3bf07eb982072c8e851dd2ddd5110282e61bf" + dependencies: + core-js "^2.5.6" + regenerator-runtime "^0.11.1" + "@babel/template@7.0.0-beta.40": version "7.0.0-beta.40" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.40.tgz#034988c6424eb5c3268fe6a608626de1f4410fc8" @@ -688,6 +695,44 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +"@material-ui/core@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-1.2.1.tgz#f8c73da10b875762b37be7167ec2ac79b027499f" + dependencies: + "@babel/runtime" "^7.0.0-beta.42" + "@types/jss" "^9.5.3" + "@types/react-transition-group" "^2.0.8" + brcast "^3.0.1" + classnames "^2.2.5" + csstype "^2.5.2" + debounce "^1.1.0" + deepmerge "^2.0.1" + dom-helpers "^3.2.1" + hoist-non-react-statics "^2.5.0" + jss "^9.3.3" + jss-camel-case "^6.0.0" + jss-default-unit "^8.0.2" + jss-global "^3.0.0" + jss-nested "^6.0.1" + jss-props-sort "^6.0.0" + jss-vendor-prefixer "^7.0.0" + keycode "^2.1.9" + normalize-scroll-left "^0.1.2" + prop-types "^15.6.0" + react-event-listener "^0.6.0" + react-jss "^8.1.0" + react-popper "^0.10.0" + react-transition-group "^2.2.1" + recompose "^0.26.0 || ^0.27.0" + scroll "^2.0.3" + warning "^4.0.1" + +"@material-ui/icons@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-1.1.0.tgz#4d025df7b0ba6ace8d6710079ed76013a4d26595" + dependencies: + recompose "^0.26.0 || ^0.27.0" + "@sambego/storybook-state@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@sambego/storybook-state/-/storybook-state-1.0.7.tgz#4409793c0d34f1d351af1c8045a2764b5af574c0" @@ -898,9 +943,12 @@ react-treebeard "^2.1.0" redux "^3.7.2" -"@types/jss@^9.3.0": - version "9.3.1" - resolved "https://registry.yarnpkg.com/@types/jss/-/jss-9.3.1.tgz#9e113f5d3e6bba6d8babca6be528b5cf19d37a16" +"@types/jss@^9.5.3": + version "9.5.3" + resolved "https://registry.yarnpkg.com/@types/jss/-/jss-9.5.3.tgz#0c106de3fe0b324cd4173fac7dab26c12cda624e" + dependencies: + csstype "^2.0.0" + indefinite-observable "^1.0.1" "@types/radium@^0.18.22": version "0.18.24" @@ -912,9 +960,9 @@ version "0.25.12" resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.25.12.tgz#49f22f7611ae381473bc9b992776a1471e899a5a" -"@types/react-transition-group@^2.0.6": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.7.tgz#2847292d54c5685d982ae5a3ecb6960946689d87" +"@types/react-transition-group@^2.0.8": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.11.tgz#feb274676a39383fffaa0dff710958d2251abefb" dependencies: "@types/react" "*" @@ -3465,6 +3513,10 @@ core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.3: version "2.5.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" +core-js@^2.5.6: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3711,6 +3763,10 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": dependencies: cssom "0.3.x" +csstype@^2.0.0, csstype@^2.5.2: + version "2.5.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.5.3.tgz#2504152e6e1cc59b32098b7f5d6a63f16294c1f7" + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -3753,6 +3809,10 @@ dateformat@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" +debounce@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.1.0.tgz#6a1a4ee2a9dc4b7c24bb012558dbcdb05b37f408" + debug@2.2.0, debug@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" @@ -3930,9 +3990,9 @@ detect-node@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" -detect-port-alt@1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.5.tgz#a1aa8fc805a4a5df9b905b7ddc7eed036bcce889" +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" dependencies: address "^1.0.1" debug "^2.6.0" @@ -5890,6 +5950,12 @@ in-publish@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" +indefinite-observable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indefinite-observable/-/indefinite-observable-1.0.1.tgz#09915423cc8d6f7eb1cb7882ad134633c9a6edc3" + dependencies: + symbol-observable "1.0.4" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -7444,45 +7510,6 @@ material-colors@^1.2.1: version "1.2.5" resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.5.tgz#5292593e6754cb1bcc2b98030e4e0d6a3afc9ea1" -material-ui-icons@^1.0.0-beta.35: - version "1.0.0-beta.36" - resolved "https://registry.yarnpkg.com/material-ui-icons/-/material-ui-icons-1.0.0-beta.36.tgz#86390a61f4c83f718eaba77ccce575834f2cf2a8" - dependencies: - recompose "^0.26.0" - -material-ui@^1.0.0-beta.35: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-1.0.0-beta.37.tgz#19097dd05e61936d2d8449874aeed1c9ae9ceb8a" - dependencies: - "@types/jss" "^9.3.0" - "@types/react-transition-group" "^2.0.6" - babel-runtime "^6.26.0" - brcast "^3.0.1" - classnames "^2.2.5" - deepmerge "^2.0.1" - dom-helpers "^3.2.1" - hoist-non-react-statics "^2.5.0" - jss "^9.3.3" - jss-camel-case "^6.0.0" - jss-default-unit "^8.0.2" - jss-global "^3.0.0" - jss-nested "^6.0.1" - jss-props-sort "^6.0.0" - jss-vendor-prefixer "^7.0.0" - keycode "^2.1.9" - lodash "^4.2.0" - normalize-scroll-left "^0.1.2" - prop-types "^15.6.0" - react-event-listener "^0.5.1" - react-jss "^8.1.0" - react-lifecycles-compat "^1.0.2" - react-popper "^0.8.0" - react-scrollbar-size "^2.0.2" - react-transition-group "^2.2.1" - recompose "^0.26.0" - scroll "^2.0.3" - warning "^3.0.0" - math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" @@ -8587,9 +8614,9 @@ pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" -popper.js@^1.12.9: - version "1.12.9" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.12.9.tgz#0dfbc2dff96c451bb332edcfcfaaf566d331d5b3" +popper.js@^1.14.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.3.tgz#1438f98d046acf7b4d78cd502bf418ac64d4f095" portfinder@^1.0.9: version "1.0.13" @@ -8998,7 +9025,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0: +prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1: version "15.6.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" dependencies: @@ -9181,15 +9208,15 @@ react-datetime@^2.11.1: prop-types "^15.5.7" react-onclickoutside "^6.5.0" -react-dev-utils@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.0.tgz#425ac7c9c40c2603bc4f7ab8836c1406e96bb473" +react-dev-utils@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613" dependencies: address "1.0.3" babel-code-frame "6.26.0" chalk "1.1.3" cross-spawn "5.1.0" - detect-port-alt "1.1.5" + detect-port-alt "1.1.6" escape-string-regexp "1.0.5" filesize "3.5.11" global-modules "1.0.0" @@ -9216,9 +9243,9 @@ react-docgen@^2.20.0: node-dir "^0.1.10" recast "^0.12.6" -react-dom@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" +react-dom@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.0.tgz#099f067dd5827ce36a29eaf9a6cdc7cbf6216b1e" dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" @@ -9229,12 +9256,11 @@ react-error-overlay@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4" -react-event-listener@^0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.3.tgz#a8b492596ad601865314fcc2c18cb87b6ce3876e" +react-event-listener@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.0.tgz#f8cf2821f5ca1844e0df1dac1c7b9a3ecb686fd7" dependencies: - babel-runtime "^6.26.0" - fbjs "^0.8.16" + "@babel/runtime" "^7.0.0-beta.42" prop-types "^15.6.0" warning "^3.0.0" @@ -9284,10 +9310,6 @@ react-jss@^8.1.0: prop-types "^15.6.0" theming "^1.3.0" -react-lifecycles-compat@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-1.0.2.tgz#551d8b1d156346e5fcf30ffac9b32ce3f78b8850" - react-lifecycles-compat@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.2.tgz#7279047275bd727a912e25f734c0559527e84eff" @@ -9310,12 +9332,12 @@ react-onclickoutside@^6.5.0: version "6.7.1" resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz#6a5b5b8b4eae6b776259712c89c8a2b36b17be93" -react-popper@^0.8.0: - version "0.8.2" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.8.2.tgz#092095ff13933211d3856d9f325511ec3a42f12c" +react-popper@^0.10.0: + version "0.10.4" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.10.4.tgz#af2a415ea22291edd504678d7afda8a6ee3295aa" dependencies: - popper.js "^1.12.9" - prop-types "^15.6.0" + popper.js "^1.14.1" + prop-types "^15.6.1" react-redux@^5.0.7: version "5.0.7" @@ -9359,15 +9381,6 @@ react-router-redux@^5.0.0-alpha.9: prop-types "^15.5.4" warning "^3.0.0" -react-scrollbar-size@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz#105e797135cab92b1f9e16f00071db7f29f80754" - dependencies: - babel-runtime "^6.26.0" - prop-types "^15.6.0" - react-event-listener "^0.5.1" - stifle "^1.0.2" - react-split-pane@^0.1.74: version "0.1.77" resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.77.tgz#f0c8cd18d076bbac900248dcf6dbcec02d5340db" @@ -9430,9 +9443,9 @@ react-treebeard@^2.1.0: object-assign "^4.1.0" prop-types "^15.5.10" -react@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" +react@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" @@ -9593,18 +9606,9 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -recompose@^0.26.0: - version "0.26.0" - resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.26.0.tgz#9babff039cb72ba5bd17366d55d7232fbdfb2d30" - dependencies: - change-emitter "^0.1.2" - fbjs "^0.8.1" - hoist-non-react-statics "^2.3.1" - symbol-observable "^1.0.4" - -recompose@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.27.0.tgz#8230ebd651bf1159097006f79083fe224b1501cf" +"recompose@^0.26.0 || ^0.27.0", recompose@^0.27.1: + version "0.27.1" + resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.27.1.tgz#1a49e931f183634516633bbb4f4edbfd3f38a7ba" dependencies: babel-runtime "^6.26.0" change-emitter "^0.1.2" @@ -10650,10 +10654,6 @@ stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" -stifle@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/stifle/-/stifle-1.0.4.tgz#8b3bcdf52419b0a9c79e35adadce50123c1d8e99" - storybook-host@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/storybook-host/-/storybook-host-4.1.5.tgz#d0e71eeba05744a4a72c9c53a0cab3d9efca9a88" @@ -10930,6 +10930,10 @@ symbol-observable@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" +symbol-observable@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + symbol-observable@^0.2.2: version "0.2.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" @@ -11666,6 +11670,12 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" +warning@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.1.tgz#66ce376b7fbfe8a887c22bdf0e7349d73d397745" + dependencies: + loose-envify "^1.0.0" + watch@~0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" From 67e170a847568b12dbc8383e330e65ab9c8099e7 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 11 Jun 2018 17:28:04 +0200 Subject: [PATCH 08/39] WA-234 RemoveOwner component --- .../RemoveOwner/RemoveOwnerForm/index.jsx | 35 +++++++ .../component/RemoveOwner/Review/index.jsx | 44 +++++++++ .../safe/component/RemoveOwner/actions.js | 12 +++ .../safe/component/RemoveOwner/index.jsx | 93 +++++++++++++++++++ .../safe/component/RemoveOwner/selector.js | 11 +++ 5 files changed, 195 insertions(+) create mode 100644 src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx create mode 100644 src/routes/safe/component/RemoveOwner/Review/index.jsx create mode 100644 src/routes/safe/component/RemoveOwner/actions.js create mode 100644 src/routes/safe/component/RemoveOwner/index.jsx create mode 100644 src/routes/safe/component/RemoveOwner/selector.js diff --git a/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx new file mode 100644 index 0000000000..212309261c --- /dev/null +++ b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx @@ -0,0 +1,35 @@ +// @flow +import * as React from 'react' +import Field from '~/components/forms/Field' +import Checkbox from '~/components/forms/Checkbox' +import Block from '~/components/layout/Block' +import Heading from '~/components/layout/Heading' + +export const DECREASE_PARAM = 'decrease' + +type Props = { + numOwners: number, + threshold: number, + name: string, +} + +const RemoveOwnerForm = ({ numOwners, threshold, name }: Props) => () => ( + + + Remove Owner { !!name && name } + + + {`Actual number of owners: ${numOwners}, threhsold of safe: ${threshold}`} + + + + Decrease threshold? + + +) + +export default RemoveOwnerForm diff --git a/src/routes/safe/component/RemoveOwner/Review/index.jsx b/src/routes/safe/component/RemoveOwner/Review/index.jsx new file mode 100644 index 0000000000..3bf6f29649 --- /dev/null +++ b/src/routes/safe/component/RemoveOwner/Review/index.jsx @@ -0,0 +1,44 @@ +// @flow +import * as React from 'react' +import CircularProgress from '@material-ui/core/CircularProgress' +import Block from '~/components/layout/Block' +import Bold from '~/components/layout/Bold' +import Heading from '~/components/layout/Heading' +import Paragraph from '~/components/layout/Paragraph' +import { DECREASE_PARAM } from '~/routes/safe/component/RemoveOwner/RemoveOwnerForm' + +type Props = { + name: string, +} + +type FormProps = { + values: Object, + submitting: boolean, +} + +const spinnerStyle = { + minHeight: '50px', +} + +const Review = ({ name }: Props) => ({ values, submitting }: FormProps) => { + const text = values[DECREASE_PARAM] + ? 'This operation will decrease the threshold of the safe' + : 'This operation will not modify the threshold of the safe' + + return ( + + Review the Add Owner operation + + Owner Name: {name} + + + {text} + + + { submitting && } + + + ) +} + +export default Review diff --git a/src/routes/safe/component/RemoveOwner/actions.js b/src/routes/safe/component/RemoveOwner/actions.js new file mode 100644 index 0000000000..32f51f38aa --- /dev/null +++ b/src/routes/safe/component/RemoveOwner/actions.js @@ -0,0 +1,12 @@ +// @flow +import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' + +type FetchTransactions = typeof fetchTransactions + +export type Actions = { + fetchTransactions: FetchTransactions, +} + +export default { + fetchTransactions, +} diff --git a/src/routes/safe/component/RemoveOwner/index.jsx b/src/routes/safe/component/RemoveOwner/index.jsx new file mode 100644 index 0000000000..3369ddb078 --- /dev/null +++ b/src/routes/safe/component/RemoveOwner/index.jsx @@ -0,0 +1,93 @@ +// @flow +import * as React from 'react' +import Stepper from '~/components/Stepper' +import { connect } from 'react-redux' +import { type Safe } from '~/routes/safe/store/model/safe' +import { getSafeEthereumInstance, createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions' +import RemoveOwnerForm, { DECREASE_PARAM } from './RemoveOwnerForm' +import Review from './Review' +import selector, { type SelectorProps } from './selector' +import actions, { type Actions } from './actions' + +const getSteps = () => [ + 'Fill Owner Form', 'Review Add order operation', +] + +type Props = SelectorProps & Actions & { + safe: Safe, + threshold: number, + name: string, + userToRemove: string, +} + +type State = { + done: boolean, +} + +const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001' +export const REMOVE_OWNER_RESET_BUTTON_TEXT = 'RESET' + +class RemoveOwner extends React.Component { + state = { + done: false, + } + + onRemoveOwner = async (values: Object) => { + try { + const { + safe, threshold, executor, fetchTransactions, userToRemove, name, + } = this.props + const nonce = Date.now() + const newThreshold = values[DECREASE_PARAM] ? threshold - 1 : threshold + const safeAddress = safe.get('address') + const gnosisSafe = await getSafeEthereumInstance(safeAddress) + + const storedOwners = await gnosisSafe.getOwners() + const index = storedOwners.findIndex(ownerAddress => ownerAddress === userToRemove) + const prevAddress = index === 0 ? SENTINEL_ADDRESS : storedOwners[index - 1] + const data = gnosisSafe.contract.removeOwner.getData(prevAddress, userToRemove, newThreshold) + + const text = name || userToRemove + await createTransaction(safe, `Remove Owner ${text}`, safeAddress, 0, nonce, executor, data) + + fetchTransactions() + this.setState({ done: true }) + } catch (error) { + this.setState({ done: false }) + // eslint-disable-next-line + console.log('Error while adding owner ' + error) + } + } + + onReset = () => { + this.setState({ done: false }) + } + + render() { + const { safe, name } = this.props + const { done } = this.state + const steps = getSteps() + const finishedButton = + + return ( + + + + { RemoveOwnerForm } + + + { Review } + + + + ) + } +} + +export default connect(selector, actions)(RemoveOwner) diff --git a/src/routes/safe/component/RemoveOwner/selector.js b/src/routes/safe/component/RemoveOwner/selector.js new file mode 100644 index 0000000000..5dd370d224 --- /dev/null +++ b/src/routes/safe/component/RemoveOwner/selector.js @@ -0,0 +1,11 @@ +// @flow +import { createStructuredSelector } from 'reselect' +import { userAccountSelector } from '~/wallets/store/selectors/index' + +export type SelectorProps = { + executor: userAccountSelector, +} + +export default createStructuredSelector({ + executor: userAccountSelector, +}) From a21300706852084766fd902190f3812636a3cb2f Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 11 Jun 2018 17:28:43 +0200 Subject: [PATCH 09/39] WA-234 Adding RemoveComponent into Safe dashboard --- src/routes/safe/component/Safe/Owners.jsx | 41 +++++++++++++---------- src/routes/safe/component/Safe/index.jsx | 14 +++++++- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/routes/safe/component/Safe/Owners.jsx b/src/routes/safe/component/Safe/Owners.jsx index e3a5473bf5..794e0bff8f 100644 --- a/src/routes/safe/component/Safe/Owners.jsx +++ b/src/routes/safe/component/Safe/Owners.jsx @@ -29,13 +29,14 @@ type Props = Open & WithStyles & { owners: List, userAddress: string, onAddOwner: () => void, + onRemoveOwner: (name: string, addres: string) => void, } export const ADD_OWNER_BUTTON_TEXT = 'Add' export const REMOVE_OWNER_BUTTON_TEXT = 'Delete' const Owners = openHoc(({ - open, toggle, owners, classes, onAddOwner, userAddress, + open, toggle, owners, classes, onAddOwner, userAddress, onRemoveOwner, }: Props) => ( @@ -56,23 +57,27 @@ const Owners = openHoc(({ - {owners.map(owner => ( - - - - - - { !sameAddress(userAddress, owner.address) && - - - - } - - ))} + {owners.map((owner) => { + const onRemoveIconClick = () => onRemoveOwner(owner.name, owner.address) + + return ( + + + + + + { !sameAddress(userAddress, owner.address) && + + + + } + + ) + })} diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index e729f4c823..6e8c629b44 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -14,6 +14,7 @@ import Transactions from '~/routes/safe/component/Transactions' import AddTransaction from '~/routes/safe/component/AddTransaction' import Threshold from '~/routes/safe/component/Threshold' import AddOwner from '~/routes/safe/component/AddOwner' +import RemoveOwner from '~/routes/safe/component/RemoveOwner' import Address from './Address' import Balance from './Balance' @@ -74,6 +75,12 @@ class GnoSafe extends React.PureComponent { this.setState({ component: }) } + onRemoveOwner = (name: string, address: string) => { + const { safe } = this.props + + this.setState({ component: }) + } + render() { const { safe, balance, userAddress } = this.props const { component } = this.state @@ -83,7 +90,12 @@ class GnoSafe extends React.PureComponent { - +
From 31a0c9a5f2d875a7b5e92cfc0502edd4eb3be865 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 12 Jun 2018 08:59:40 +0200 Subject: [PATCH 10/39] WA-234 Disabling decrease on edge conditions when removing owners --- .../RemoveOwner/RemoveOwnerForm/index.jsx | 8 ++++++-- src/routes/safe/component/RemoveOwner/index.jsx | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx index 212309261c..146cc1fcc7 100644 --- a/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx +++ b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx @@ -11,9 +11,12 @@ type Props = { numOwners: number, threshold: number, name: string, + disabled: boolean, } -const RemoveOwnerForm = ({ numOwners, threshold, name }: Props) => () => ( +const RemoveOwnerForm = ({ + numOwners, threshold, name, disabled, +}: Props) => () => ( Remove Owner { !!name && name } @@ -26,8 +29,9 @@ const RemoveOwnerForm = ({ numOwners, threshold, name }: Props) => () => ( name={DECREASE_PARAM} component={Checkbox} type="checkbox" + disabled={disabled} /> - Decrease threshold? + {disabled && '(disabled) '}Decrease threshold? ) diff --git a/src/routes/safe/component/RemoveOwner/index.jsx b/src/routes/safe/component/RemoveOwner/index.jsx index 3369ddb078..aed0adb906 100644 --- a/src/routes/safe/component/RemoveOwner/index.jsx +++ b/src/routes/safe/component/RemoveOwner/index.jsx @@ -27,6 +27,12 @@ type State = { const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001' export const REMOVE_OWNER_RESET_BUTTON_TEXT = 'RESET' +const initialValuesFrom = (decreaseMandatory: boolean = false) => ({ + [DECREASE_PARAM]: decreaseMandatory, +}) + +const shouldDecrease = (numOwners: number, threshold: number) => threshold === numOwners + class RemoveOwner extends React.Component { state = { done: false, @@ -67,7 +73,12 @@ class RemoveOwner extends React.Component { const { safe, name } = this.props const { done } = this.state const steps = getSteps() + const numOwners = safe.get('owners').count() + const threshold = safe.get('threshold') const finishedButton = + const decrease = shouldDecrease(numOwners, threshold) + const initialValues = initialValuesFrom(decrease) + const disabled = decrease || threshold === 1 return ( @@ -77,8 +88,9 @@ class RemoveOwner extends React.Component { onSubmit={this.onRemoveOwner} steps={steps} onReset={this.onReset} + initialValues={initialValues} > - + { RemoveOwnerForm } From 442723cfad0a8928e61fb98f40ccc8e8e6e2e8ad Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 12 Jun 2018 10:37:39 +0200 Subject: [PATCH 11/39] WA-234 Creating the Snackbar Content component --- src/components/SnackbarContent/index.jsx | 103 +++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/components/SnackbarContent/index.jsx diff --git a/src/components/SnackbarContent/index.jsx b/src/components/SnackbarContent/index.jsx new file mode 100644 index 0000000000..cfb0915791 --- /dev/null +++ b/src/components/SnackbarContent/index.jsx @@ -0,0 +1,103 @@ +// @flow +import SnackbarContent from '@material-ui/core/SnackbarContent' +import classNames from 'classnames/bind' +import * as React from 'react' +import green from '@material-ui/core/colors/green' +import amber from '@material-ui/core/colors/amber' +import CloseIcon from '@material-ui/icons/Close' +import CheckCircleIcon from '@material-ui/icons/CheckCircle' +import ErrorIcon from '@material-ui/icons/Error' +import InfoIcon from '@material-ui/icons/Info' +import IconButton from '@material-ui/core/IconButton' +import { withStyles } from '@material-ui/core/styles' +import WarningIcon from '@material-ui/icons/Warning' +import { type WithStyles } from '~/theme/mui' + +type Variant = 'success' | 'error' | 'warning' | 'info' + +type MessageProps = WithStyles & { + variant: Variant, + message: string, +} + +type Props = MessageProps & { + onClose?: () => void, +} + +type CloseProps = WithStyles & { + onClose: () => void, +} + +const variantIcon = { + success: CheckCircleIcon, + warning: WarningIcon, + error: ErrorIcon, + info: InfoIcon, +} + +const styles = theme => ({ + success: { + backgroundColor: green[600], + }, + error: { + backgroundColor: theme.palette.error.dark, + }, + info: { + backgroundColor: theme.palette.primary.dark, + }, + warning: { + backgroundColor: amber[700], + }, + icon: { + fontSize: 20, + }, + iconVariant: { + opacity: 0.9, + marginRight: theme.spacing.unit, + }, + message: { + display: 'flex', + alignItems: 'center', + }, +}) + +const Close = ({ classes, onClose }: CloseProps) => ( + + + +) + +const Message = ({ classes, message, variant }: MessageProps) => { + const Icon = variantIcon[variant] + + return ( + + + {message} + + ) +} + +const GnoSnackbarContent = ({ + variant, classes, message, onClose, +}: Props) => { + const action = onClose ? [] : undefined + const messageComponent = + + return ( + + ) +} + +export default withStyles(styles)(GnoSnackbarContent) From 9bef7f3894bef68b37ffedf43dddbf15f69d254a Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 12 Jun 2018 10:37:59 +0200 Subject: [PATCH 12/39] WA-234 Adding pendingTransactions selector --- .../safe/component/RemoveOwner/selector.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/routes/safe/component/RemoveOwner/selector.js b/src/routes/safe/component/RemoveOwner/selector.js index 5dd370d224..76ee9f09e2 100644 --- a/src/routes/safe/component/RemoveOwner/selector.js +++ b/src/routes/safe/component/RemoveOwner/selector.js @@ -1,11 +1,26 @@ // @flow -import { createStructuredSelector } from 'reselect' +import { List } from 'immutable' +import { createStructuredSelector, createSelector } from 'reselect' import { userAccountSelector } from '~/wallets/store/selectors/index' +import { type Transaction } from '~/routes/safe/store/model/transaction' +import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index' + +const pendingTransactionsSelector = createSelector( + safeTransactionsSelector, + (transactions: List) => + transactions.findEntry((transaction: Transaction) => { + const txHash = transaction.get('tx') + + return txHash === '' || txHash === undefined + }) !== undefined, +) export type SelectorProps = { executor: userAccountSelector, + pendingTransactions: pendingTransactionsSelector, } export default createStructuredSelector({ executor: userAccountSelector, + pendingTransactions: pendingTransactionsSelector, }) From 3cccc34ea72980b5d0ca0a599fba73e889aeea85 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 12 Jun 2018 10:38:52 +0200 Subject: [PATCH 13/39] WA-234 Include warning message when removing owner if there are pending transactions --- .../component/RemoveOwner/RemoveOwnerForm/index.jsx | 10 +++++++++- src/routes/safe/component/RemoveOwner/index.jsx | 10 ++++++++-- src/routes/safe/component/Safe/index.jsx | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx index 146cc1fcc7..fc47e8db60 100644 --- a/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx +++ b/src/routes/safe/component/RemoveOwner/RemoveOwnerForm/index.jsx @@ -1,6 +1,7 @@ // @flow import * as React from 'react' import Field from '~/components/forms/Field' +import SnackbarContent from '~/components/SnackbarContent' import Checkbox from '~/components/forms/Checkbox' import Block from '~/components/layout/Block' import Heading from '~/components/layout/Heading' @@ -12,10 +13,11 @@ type Props = { threshold: number, name: string, disabled: boolean, + pendingTransactions: boolean, } const RemoveOwnerForm = ({ - numOwners, threshold, name, disabled, + numOwners, threshold, name, disabled, pendingTransactions, }: Props) => () => ( @@ -24,6 +26,12 @@ const RemoveOwnerForm = ({ {`Actual number of owners: ${numOwners}, threhsold of safe: ${threshold}`} + { pendingTransactions && + + } { } render() { - const { safe, name } = this.props + const { safe, name, pendingTransactions } = this.props const { done } = this.state const steps = getSteps() const numOwners = safe.get('owners').count() @@ -90,7 +90,13 @@ class RemoveOwner extends React.Component { onReset={this.onReset} initialValues={initialValues} > - + { RemoveOwnerForm } diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 6e8c629b44..1740da0729 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -78,7 +78,7 @@ class GnoSafe extends React.PureComponent { onRemoveOwner = (name: string, address: string) => { const { safe } = this.props - this.setState({ component: }) + this.setState({ component: }) } render() { From 161b0976baa305669ca5335ff061da687524591d Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 12 Jun 2018 12:03:52 +0200 Subject: [PATCH 14/39] WA-234 Fix tests after unpgrading material ui --- src/routes/safe/test/testMultisig.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/routes/safe/test/testMultisig.js b/src/routes/safe/test/testMultisig.js index 8e469410c3..45360b9821 100644 --- a/src/routes/safe/test/testMultisig.js +++ b/src/routes/safe/test/testMultisig.js @@ -80,12 +80,12 @@ export const expandTransactionOf = async ( ) => { const paragraphs = getTagFromTransaction(SafeDom, 'p') TestUtils.Simulate.click(paragraphs[2]) // expanded - await sleep(1000) // Time to expand + await sleep(2500) // Time to expand const paragraphsExpanded = getTagFromTransaction(SafeDom, 'p') const threshold = paragraphsExpanded[5] expect(threshold.innerHTML).toContain(`confirmation${safeThreshold === 1 ? '' : 's'} needed`) TestUtils.Simulate.click(threshold) // expanded - await sleep(1000) // Time to expand + await sleep(2500) // Time to expand expect(paragraphsExpanded.length).toBe(paragraphs.length + numOwners) } @@ -96,10 +96,11 @@ export const getTransactionFromReduxStore = (store: Store, address: } export const confirmOwners = async (SafeDom: React$Component, ...statusses: string[]) => { - const paragraphsWithOwners = getTagFromTransaction(SafeDom, 'h3') + const paragraphsWithOwners = getTagFromTransaction(SafeDom, 'span') for (let i = 0; i < statusses.length; i += 1) { const ownerIndex = i + 6 const ownerParagraph = paragraphsWithOwners[ownerIndex].innerHTML + expect(statusses[i]).toEqual(ownerParagraph) } } From 1e51a482504a28401eb5a68562dde767e887590d Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 13 Jun 2018 15:48:43 +0200 Subject: [PATCH 15/39] WA-234 Fix unnecesary re-renders when storing again just fetched safe --- src/routes/safe/container/index.jsx | 4 +++- src/routes/safe/store/reducer/safe.js | 3 ++- src/routes/safe/store/selectors/index.js | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/routes/safe/container/index.jsx b/src/routes/safe/container/index.jsx index 6c20e0e3f0..4346d852c3 100644 --- a/src/routes/safe/container/index.jsx +++ b/src/routes/safe/container/index.jsx @@ -18,7 +18,9 @@ class SafeView extends React.PureComponent { if (!safe) { return } const safeAddress: string = safe.get('address') fetchBalance(safeAddress) - fetchSafe(safe) + if (safe) { + fetchSafe(safe) + } }, 1500) } diff --git a/src/routes/safe/store/reducer/safe.js b/src/routes/safe/store/reducer/safe.js index dd94140775..41832b32e8 100644 --- a/src/routes/safe/store/reducer/safe.js +++ b/src/routes/safe/store/reducer/safe.js @@ -24,7 +24,8 @@ action: AddSafeType export default handleActions({ [UPDATE_SAFE]: (state: State, action: ActionType): State => - state.set(action.payload.get('address'), action.payload), + state.update(action.payload.get('address'), prevSafe => + (prevSafe.equals(action.payload) ? prevSafe : action.payload)), [UPDATE_SAFES]: (state: State, action: ActionType): State => action.payload, [ADD_SAFE]: (state: State, action: ActionType): State => { diff --git a/src/routes/safe/store/selectors/index.js b/src/routes/safe/store/selectors/index.js index 07d58cc155..8e18c2e63b 100644 --- a/src/routes/safe/store/selectors/index.js +++ b/src/routes/safe/store/selectors/index.js @@ -75,7 +75,9 @@ export const safeSelector: Selector return undefined } - return safes.get(address) + const safe = safes.get(address) + + return safe }, ) From 9d27d7a7a7edcfc690a8f02b9b768b6f10762960 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 14 Jun 2018 15:50:18 +0200 Subject: [PATCH 16/39] WA-234 Refactor 1 owner 1 threshold DOM safe test --- .../SafeForm/Confirmations/index.test.js | 2 +- .../components/SafeForm/Owners/index.test.js | 2 +- src/routes/safe/component/Safe/Owners.jsx | 5 +- .../Transactions/Collapsed/Confirmations.jsx | 6 +- .../Transactions/Transaction/index.jsx | 6 +- .../component/Withdrawn/withdrawn.test.js | 2 +- src/routes/safe/store/test/balance.reducer.js | 2 +- .../safe/store/test/balance.selector.js | 2 +- .../safe/store/test/granted.selector.js | 2 +- src/routes/safe/store/test/safe.selector.js | 2 +- .../Safe.multisig.1owners1threshold.test.js | 2 +- src/routes/safe/test/Safe.owners.test.js | 2 +- src/routes/safe/test/Safe.threshold.test.js | 2 +- src/routes/safe/test/Safe.withdrawn.test.js | 2 +- src/routes/safe/test/testMultisig.js | 2 +- .../open/components => test}/Layout.test.js | 0 src/test/addEtherTo.js | 10 -- src/test/builder/safe.dom.builder.js | 141 ++++++++++++++++++ src/test/builder/safe.dom.utils.js | 35 +++++ src/test/safe.dom.test.js | 34 +++++ src/test/{ => utils}/Wrapper.jsx | 0 src/test/utils/addEtherTo.js | 23 +++ src/test/{ => utils}/buildReactRouterProps.js | 0 .../utils/transactions/addOwner.helper.js | 37 +++++ .../utils/transactions/moveFunds.helper.js | 39 +++++ .../utils/transactions/removeOwner.helper.js | 36 +++++ .../utils/transactions/threshold.helper.js | 36 +++++ 27 files changed, 407 insertions(+), 25 deletions(-) rename src/{routes/open/components => test}/Layout.test.js (100%) delete mode 100644 src/test/addEtherTo.js create mode 100644 src/test/builder/safe.dom.builder.js create mode 100644 src/test/builder/safe.dom.utils.js create mode 100644 src/test/safe.dom.test.js rename src/test/{ => utils}/Wrapper.jsx (100%) create mode 100644 src/test/utils/addEtherTo.js rename src/test/{ => utils}/buildReactRouterProps.js (100%) create mode 100644 src/test/utils/transactions/addOwner.helper.js create mode 100644 src/test/utils/transactions/moveFunds.helper.js create mode 100644 src/test/utils/transactions/removeOwner.helper.js create mode 100644 src/test/utils/transactions/threshold.helper.js diff --git a/src/routes/open/components/SafeForm/Confirmations/index.test.js b/src/routes/open/components/SafeForm/Confirmations/index.test.js index 2c95c3c54c..31ee2b2e6c 100644 --- a/src/routes/open/components/SafeForm/Confirmations/index.test.js +++ b/src/routes/open/components/SafeForm/Confirmations/index.test.js @@ -5,7 +5,7 @@ import * as TestUtils from 'react-dom/test-utils' import Layout from '~/routes/open/components/Layout' import { FIELD_CONFIRMATIONS, FIELD_OWNERS } from '~/routes/open/components/fields' import { getProviderInfo } from '~/wallets/getWeb3' -import Wrapper from '~/test/Wrapper' +import Wrapper from '~/test/utils/Wrapper' import { CONFIRMATIONS_ERROR } from '~/routes/open/components/SafeForm' const obSubmitMock = () => {} diff --git a/src/routes/open/components/SafeForm/Owners/index.test.js b/src/routes/open/components/SafeForm/Owners/index.test.js index a6eab1385f..0951933392 100644 --- a/src/routes/open/components/SafeForm/Owners/index.test.js +++ b/src/routes/open/components/SafeForm/Owners/index.test.js @@ -6,7 +6,7 @@ import GnoForm from '~/components/forms/GnoForm' import { FIELD_OWNERS } from '~/routes/open/components/fields' import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor' import { getProviderInfo } from '~/wallets/getWeb3' -import Wrapper from '~/test/Wrapper' +import Wrapper from '~/test/utils/Wrapper' import { ADDRESS_REPEATED_ERROR } from '~/components/forms/validator' import Owners from './index' diff --git a/src/routes/safe/component/Safe/Owners.jsx b/src/routes/safe/component/Safe/Owners.jsx index 794e0bff8f..74a8802a29 100644 --- a/src/routes/safe/component/Safe/Owners.jsx +++ b/src/routes/safe/component/Safe/Owners.jsx @@ -45,7 +45,10 @@ const Owners = openHoc(({ - {open ? : } + {open + ? + : + } ) diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 1740da0729..6db44255f5 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -9,12 +9,13 @@ import Row from '~/components/layout/Row' import { type Safe } from '~/routes/safe/store/model/safe' import List from '@material-ui/core/List' -import Withdrawn from '~/routes/safe/component/Withdrawn' +import Withdraw from '~/routes/safe/component/Withdraw' import Transactions from '~/routes/safe/component/Transactions' import AddTransaction from '~/routes/safe/component/AddTransaction' import Threshold from '~/routes/safe/component/Threshold' import AddOwner from '~/routes/safe/component/AddOwner' import RemoveOwner from '~/routes/safe/component/RemoveOwner' +import EditDailyLimit from '~/routes/safe/component/EditDailyLimit' import Address from './Address' import Balance from './Balance' @@ -44,10 +45,17 @@ class GnoSafe extends React.PureComponent { component: undefined, } - onWithdrawn = () => { + onEditDailyLimit = () => { const { safe } = this.props - this.setState({ component: }) + const value = safe.get('dailyLimit').get('value') + this.setState({ component: }) + } + + onWithdraw = () => { + const { safe } = this.props + + this.setState({ component: }) } onAddTx = () => { @@ -98,7 +106,7 @@ class GnoSafe extends React.PureComponent { />
- + diff --git a/src/routes/safe/component/Withdrawn/Review/index.jsx b/src/routes/safe/component/Withdraw/Review/index.jsx similarity index 90% rename from src/routes/safe/component/Withdrawn/Review/index.jsx rename to src/routes/safe/component/Withdraw/Review/index.jsx index 83a36444df..6fa35221a0 100644 --- a/src/routes/safe/component/Withdrawn/Review/index.jsx +++ b/src/routes/safe/component/Withdraw/Review/index.jsx @@ -5,7 +5,7 @@ import Block from '~/components/layout/Block' import Bold from '~/components/layout/Bold' import Heading from '~/components/layout/Heading' import Paragraph from '~/components/layout/Paragraph' -import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn' +import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' type FormProps = { values: Object, @@ -18,7 +18,7 @@ const spinnerStyle = { const Review = () => ({ values, submitting }: FormProps) => ( - Review the Withdrawn Operation + Review the Withdraw Operation Destination: {values[DESTINATION_PARAM]} diff --git a/src/routes/safe/component/Withdrawn/WithdrawnForm/WithdrawnForm.stories.js b/src/routes/safe/component/Withdraw/WithdrawForm/WithdrawForm.stories.js similarity index 80% rename from src/routes/safe/component/Withdrawn/WithdrawnForm/WithdrawnForm.stories.js rename to src/routes/safe/component/Withdraw/WithdrawForm/WithdrawForm.stories.js index a914a0a3e6..98980dda25 100644 --- a/src/routes/safe/component/Withdrawn/WithdrawnForm/WithdrawnForm.stories.js +++ b/src/routes/safe/component/Withdraw/WithdrawForm/WithdrawForm.stories.js @@ -3,7 +3,7 @@ import { storiesOf } from '@storybook/react' import * as React from 'react' import Stepper from '~/components/Stepper' import styles from '~/components/layout/PageFrame/index.scss' -import WithdrawnForm from './index' +import WithdrawForm from './index' const FrameDecorator = story => ( @@ -14,16 +14,16 @@ const FrameDecorator = story => ( storiesOf('Components', module) .addDecorator(FrameDecorator) - .add('WithdrawnForm', () => ( + .add('WithdrawForm', () => ( } onSubmit={() => {}} - steps={['Fill Withdrawn Form', 'Review Withdrawn']} + steps={['Fill Withdraw Form', 'Review Withdraw']} onReset={() => {}} > - { WithdrawnForm } + { WithdrawForm } )) diff --git a/src/routes/safe/component/Withdrawn/WithdrawnForm/index.jsx b/src/routes/safe/component/Withdraw/WithdrawForm/index.jsx similarity index 91% rename from src/routes/safe/component/Withdrawn/WithdrawnForm/index.jsx rename to src/routes/safe/component/Withdraw/WithdrawForm/index.jsx index 12f0ae26b8..ac69aac435 100644 --- a/src/routes/safe/component/Withdrawn/WithdrawnForm/index.jsx +++ b/src/routes/safe/component/Withdraw/WithdrawForm/index.jsx @@ -5,7 +5,7 @@ import TextField from '~/components/forms/TextField' import { composeValidators, inLimit, mustBeFloat, required, greaterThan, mustBeEthereumAddress } from '~/components/forms/validator' import Block from '~/components/layout/Block' import Heading from '~/components/layout/Heading' -import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn' +import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners' @@ -24,10 +24,10 @@ type Props = { spentToday: number, } -const WithdrawnForm = ({ limit, spentToday }: Props) => () => ( +const WithdrawForm = ({ limit, spentToday }: Props) => () => ( - Withdrawn Funds + Withdraw Funds {`Daily limit ${limit} ETH (spent today: ${spentToday} ETH)`} @@ -55,4 +55,4 @@ const WithdrawnForm = ({ limit, spentToday }: Props) => () => ( ) -export default WithdrawnForm +export default WithdrawForm diff --git a/src/routes/safe/component/Withdrawn/index.jsx b/src/routes/safe/component/Withdraw/index.jsx similarity index 78% rename from src/routes/safe/component/Withdrawn/index.jsx rename to src/routes/safe/component/Withdraw/index.jsx index 608792be0b..850d3718e3 100644 --- a/src/routes/safe/component/Withdrawn/index.jsx +++ b/src/routes/safe/component/Withdraw/index.jsx @@ -4,12 +4,12 @@ import { connect } from 'react-redux' import Stepper from '~/components/Stepper' import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit' import selector, { type SelectorProps } from './selector' -import withdrawn from './withdrawn' -import WithdrawnForm from './WithdrawnForm' +import withdraw from './withdraw' +import WithdrawForm from './WithdrawForm' import Review from './Review' const getSteps = () => [ - 'Fill Withdrawn Form', 'Review Withdrawn', + 'Fill Withdraw Form', 'Review Withdraw', ] type Props = SelectorProps & { @@ -23,15 +23,15 @@ type State = { export const SEE_TXS_BUTTON_TEXT = 'RESET' -class Withdrawn extends React.Component { +class Withdraw extends React.Component { state = { done: false, } - onWithdrawn = async (values: Object) => { + onWithdraw = async (values: Object) => { try { const { safeAddress, userAddress } = this.props - await withdrawn(values, safeAddress, userAddress) + await withdraw(values, safeAddress, userAddress) this.setState({ done: true }) } catch (error) { this.setState({ done: false }) @@ -55,12 +55,12 @@ class Withdrawn extends React.Component { - { WithdrawnForm } + { WithdrawForm } { Review } @@ -71,5 +71,5 @@ class Withdrawn extends React.Component { } } -export default connect(selector)(Withdrawn) +export default connect(selector)(Withdraw) diff --git a/src/routes/safe/component/Withdraw/selector.js b/src/routes/safe/component/Withdraw/selector.js new file mode 100644 index 0000000000..9e7bfef11a --- /dev/null +++ b/src/routes/safe/component/Withdraw/selector.js @@ -0,0 +1,11 @@ +// @flow +import { createStructuredSelector } from 'reselect' +import { userAccountSelector } from '~/wallets/store/selectors/index' + +export type SelectorProps = { + userAddress: userAccountSelector, +} + +export default createStructuredSelector({ + userAddress: userAccountSelector, +}) diff --git a/src/routes/safe/component/Withdrawn/withdrawn.js b/src/routes/safe/component/Withdraw/withdraw.js similarity index 84% rename from src/routes/safe/component/Withdrawn/withdrawn.js rename to src/routes/safe/component/Withdraw/withdraw.js index 439b147a57..8a51156d5e 100644 --- a/src/routes/safe/component/Withdrawn/withdrawn.js +++ b/src/routes/safe/component/Withdraw/withdraw.js @@ -36,7 +36,13 @@ export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: numbe return { value: Number(limit), spentToday: Number(spentToday) } } -const withdrawn = async (values: Object, safeAddress: string, userAccount: string): Promise => { +export const getEditDailyLimitData = async (safeAddress: string, token: string, dailyLimit: number) => { + const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress) + + return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimit) +} + +const withdraw = async (values: Object, safeAddress: string, userAccount: string): Promise => { const web3 = getWeb3() const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress) @@ -51,4 +57,4 @@ const withdrawn = async (values: Object, safeAddress: string, userAccount: strin checkReceiptStatus(txHash.tx) } -export default withdrawn +export default withdraw diff --git a/src/routes/safe/component/Withdrawn/withdrawn.test.js b/src/routes/safe/component/Withdraw/withdraw.test.js similarity index 60% rename from src/routes/safe/component/Withdrawn/withdrawn.test.js rename to src/routes/safe/component/Withdraw/withdraw.test.js index 3529679af2..f6c5630824 100644 --- a/src/routes/safe/component/Withdrawn/withdrawn.test.js +++ b/src/routes/safe/component/Withdraw/withdraw.test.js @@ -1,7 +1,7 @@ // @flow import { aNewStore } from '~/store' import { addEtherTo } from '~/test/utils/etherMovements' -import { aDeployedSafe, executeWithdrawnOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' +import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' describe('Safe Blockchain Test', () => { let store @@ -17,10 +17,10 @@ describe('Safe Blockchain Test', () => { const value = 0.15 // WHEN - await executeWithdrawnOn(safeAddress, value) - await executeWithdrawnOn(safeAddress, value) + await executeWithdrawOn(safeAddress, value) + await executeWithdrawOn(safeAddress, value) // THEN - expect(executeWithdrawnOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert') + expect(executeWithdrawOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert') }) }) diff --git a/src/routes/safe/store/actions/fetchSafe.js b/src/routes/safe/store/actions/fetchSafe.js index 9102489a9d..9e9a48ff65 100644 --- a/src/routes/safe/store/actions/fetchSafe.js +++ b/src/routes/safe/store/actions/fetchSafe.js @@ -5,7 +5,7 @@ import { type GlobalState } from '~/store/index' import { makeOwner } from '~/routes/safe/store/model/owner' import { type SafeProps, type Safe, makeSafe } from '~/routes/safe/store/model/safe' import { makeDailyLimit } from '~/routes/safe/store/model/dailyLimit' -import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn' +import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw' import { getGnosisSafeInstanceAt } from '~/wallets/safeContracts' import updateSafe from '~/routes/safe/store/actions/updateSafe' import { getOwners } from '~/utils/localStorage' diff --git a/src/routes/safe/store/test/builder/deployedSafe.builder.js b/src/routes/safe/store/test/builder/deployedSafe.builder.js index 2429747f42..922f99e423 100644 --- a/src/routes/safe/store/test/builder/deployedSafe.builder.js +++ b/src/routes/safe/store/test/builder/deployedSafe.builder.js @@ -11,7 +11,7 @@ import { sleep } from '~/utils/timer' import { getProviderInfo, getWeb3 } from '~/wallets/getWeb3' import addProvider from '~/wallets/store/actions/addProvider' import { makeProvider } from '~/wallets/store/model/provider' -import withdrawn, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn' +import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' import { promisify } from '~/utils/promisify' export const renderSafe = async (localStore: Store) => { @@ -94,7 +94,7 @@ export const aDeployedSafe = async ( return deployedSafe.logs[1].args.proxy } -export const executeWithdrawnOn = async (safeAddress: string, value: number) => { +export const executeWithdrawOn = async (safeAddress: string, value: number) => { const providerInfo = await getProviderInfo() const userAddress = providerInfo.account @@ -103,5 +103,5 @@ export const executeWithdrawnOn = async (safeAddress: string, value: number) => [VALUE_PARAM]: `${value}`, } - return withdrawn(values, safeAddress, userAddress) + return withdraw(values, safeAddress, userAddress) } diff --git a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js index 803e22eec9..c8c0c08c90 100644 --- a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js +++ b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js @@ -18,7 +18,7 @@ import { sleep } from '~/utils/timer' import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index' -describe('React DOM TESTS > Withdrawn funds from safe', () => { +describe('React DOM TESTS > Withdraw funds from safe', () => { let SafeDom let store let address diff --git a/src/routes/safe/test/Safe.withdrawn.test.js b/src/routes/safe/test/Safe.withdrawn.test.js index 50c868fc6b..685c95c4e8 100644 --- a/src/routes/safe/test/Safe.withdrawn.test.js +++ b/src/routes/safe/test/Safe.withdrawn.test.js @@ -6,19 +6,19 @@ import { ConnectedRouter } from 'react-router-redux' import Button from '~/components/layout/Button' import { aNewStore, history } from '~/store' import { addEtherTo } from '~/test/utils/etherMovements' -import { aDeployedSafe, executeWithdrawnOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' +import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' import { SAFELIST_ADDRESS } from '~/routes/routes' import SafeView from '~/routes/safe/component/Safe' import AppRoutes from '~/routes' -import { WITHDRAWN_BUTTON_TEXT } from '~/routes/safe/component/Safe/DailyLimit' -import WithdrawnComponent, { SEE_TXS_BUTTON_TEXT } from '~/routes/safe/component/Withdrawn' +import { WITHDRAW_BUTTON_TEXT } from '~/routes/safe/component/Safe/DailyLimit' +import WithdrawComponent, { SEE_TXS_BUTTON_TEXT } from '~/routes/safe/component/Withdraw' import { getBalanceInEtherOf } from '~/wallets/getWeb3' import { sleep } from '~/utils/timer' -import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn' +import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw' import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit' import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' -describe('React DOM TESTS > Withdrawn funds from safe', () => { +describe('React DOM TESTS > Withdraw funds from safe', () => { let SafeDom let store let address @@ -38,7 +38,7 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { )) }) - it('should withdrawn funds under dailyLimit without needing confirmations', async () => { + it('should withdraw funds under dailyLimit without needing confirmations', async () => { // add funds to safe await addEtherTo(address, '0.1') await sleep(3000) @@ -46,21 +46,21 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { // $FlowFixMe const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const withdrawnButton = buttons[2] - expect(withdrawnButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT) - TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawnButton, 'button')[0]) + const withdrawButton = buttons[2] + expect(withdrawButton.props.children).toEqual(WITHDRAW_BUTTON_TEXT) + TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawButton, 'button')[0]) await sleep(4000) - const Withdrawn = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawnComponent) + const Withdraw = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawComponent) // $FlowFixMe - const inputs = TestUtils.scryRenderedDOMComponentsWithTag(Withdrawn, 'input') + const inputs = TestUtils.scryRenderedDOMComponentsWithTag(Withdraw, 'input') const amountInEth = inputs[0] const toAddress = inputs[1] TestUtils.Simulate.change(amountInEth, { target: { value: '0.01' } }) TestUtils.Simulate.change(toAddress, { target: { value: store.getState().providers.account } }) // $FlowFixMe - const form = TestUtils.findRenderedDOMComponentWithTag(Withdrawn, 'form') + const form = TestUtils.findRenderedDOMComponentWithTag(Withdraw, 'form') TestUtils.Simulate.submit(form) // fill the form TestUtils.Simulate.submit(form) // confirming data @@ -70,8 +70,8 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { expect(safeBalance).toBe('0.09') // $FlowFixMe - const withdrawnButtons = TestUtils.scryRenderedComponentsWithType(Withdrawn, Button) - const visitTxsButton = withdrawnButtons[0] + const withdrawButtons = TestUtils.scryRenderedComponentsWithType(Withdraw, Button) + const visitTxsButton = withdrawButtons[0] expect(visitTxsButton.props.children).toEqual(SEE_TXS_BUTTON_TEXT) }) @@ -81,8 +81,8 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { // GIVEN in beforeEach // WHEN - await executeWithdrawnOn(address, 0.01) - await executeWithdrawnOn(address, 0.01) + await executeWithdrawOn(address, 0.01) + await executeWithdrawOn(address, 0.01) const ethAddress = 0 const dailyLimit: DailyLimitProps = await getDailyLimitFrom(address, ethAddress) @@ -106,12 +106,12 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { expect(addTxButton.props.disabled).toBe(false) }) - it('Withdrawn button disabled when balance is 0', async () => { + it('Withdraw button disabled when balance is 0', async () => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) const addTxButton = buttons[2] - expect(addTxButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT) + expect(addTxButton.props.children).toEqual(WITHDRAW_BUTTON_TEXT) expect(addTxButton.props.disabled).toBe(true) await addEtherTo(address, '0.1') diff --git a/src/test/builder/safe.dom.utils.js b/src/test/builder/safe.dom.utils.js index 6c1d9c8475..8f07e5eb6e 100644 --- a/src/test/builder/safe.dom.utils.js +++ b/src/test/builder/safe.dom.utils.js @@ -8,7 +8,7 @@ import { sleep } from '~/utils/timer' export const EXPAND_OWNERS_INDEX = 0 export const ADD_OWNERS_INDEX = 1 export const EDIT_THRESHOLD_INDEX = 2 -export const WITHDRAWN_INDEX = 3 +export const WITHDRAW_INDEX = 3 export const MOVE_FUNDS_INDEX = 4 export const LIST_TXS_INDEX = 5 diff --git a/src/test/safe.dom.test.js b/src/test/safe.dom.test.js index 7e7c8962e2..dc015f7fab 100644 --- a/src/test/safe.dom.test.js +++ b/src/test/safe.dom.test.js @@ -1,13 +1,13 @@ // @flow import TestUtils from 'react-dom/test-utils' import Transaction from '~/routes/safe/component/Transactions/Transaction' -import { listTxsClickingOn, LIST_TXS_INDEX, MOVE_FUNDS_INDEX, ADD_OWNERS_INDEX, EXPAND_OWNERS_INDEX, EDIT_THRESHOLD_INDEX, WITHDRAWN_INDEX, refreshTransactions } from '~/test/builder/safe.dom.utils' +import { listTxsClickingOn, LIST_TXS_INDEX, MOVE_FUNDS_INDEX, ADD_OWNERS_INDEX, EXPAND_OWNERS_INDEX, EDIT_THRESHOLD_INDEX, WITHDRAW_INDEX, refreshTransactions } from '~/test/builder/safe.dom.utils' import { renderSafeInDom, type DomSafe } from '~/test/builder/safe.dom.builder' import { sendMoveFundsForm, checkMinedMoveFundsTx, checkPendingMoveFundsTx } from '~/test/utils/transactions/moveFunds.helper' import { sendAddOwnerForm, checkMinedAddOwnerTx, checkPendingAddOwnerTx } from '~/test/utils/transactions/addOwner.helper' import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx } from '~/test/utils/transactions/removeOwner.helper' import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper' -import { sendWithdrawnForm, checkMinedWithdrawnTx } from '~/test/utils/transactions/withdrawn.helper' +import { sendWithdrawForm, checkMinedWithdrawTx } from '~/test/utils/transactions/withdraw.helper' import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions' import { checkBalanceOf } from '~/test/utils/etherMovements' @@ -24,7 +24,7 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { // WHEN await sendMoveFundsForm(SafeDom, safeButtons[MOVE_FUNDS_INDEX], 'Move funds', '0.01', accounts[1]) - await sendWithdrawnForm(SafeDom, safeButtons[WITHDRAWN_INDEX], '0.01', accounts[3]) + await sendWithdrawForm(SafeDom, safeButtons[WITHDRAW_INDEX], '0.01', accounts[3]) await sendAddOwnerForm(SafeDom, safeButtons[ADD_OWNERS_INDEX], 'Adol Metamask 2', accounts[1]) await sendChangeThresholdForm(SafeDom, safeButtons[EDIT_THRESHOLD_INDEX], '2') @@ -33,7 +33,7 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { const transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) checkMinedMoveFundsTx(transactions[0], 'Move funds') - await checkMinedWithdrawnTx(address, '0.08') // 0.1 - 0.01 tx - 0.01 withdrawn + await checkMinedWithdrawTx(address, '0.08') // 0.1 - 0.01 tx - 0.01 withdraw checkMinedAddOwnerTx(transactions[1], 'Add Owner Adol Metamask 2') checkMinedThresholdTx(transactions[2], 'Change Safe\'s threshold') }) @@ -48,7 +48,7 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { await sendMoveFundsForm(SafeDom, safeButtons[MOVE_FUNDS_INDEX], 'Buy batteries', '0.01', accounts[1]) const increaseThreshold = true await sendAddOwnerForm(SafeDom, safeButtons[ADD_OWNERS_INDEX], 'Adol Metamask 3', accounts[2], increaseThreshold) - await sendWithdrawnForm(SafeDom, safeButtons[WITHDRAWN_INDEX], '0.01', accounts[3]) + await sendWithdrawForm(SafeDom, safeButtons[WITHDRAW_INDEX], '0.01', accounts[3]) // THEN await listTxsClickingOn(safeButtons[LIST_TXS_INDEX]) @@ -58,7 +58,7 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { await checkPendingMoveFundsTx(transactions[3], 2, 'Buy batteries', statusses) await checkPendingAddOwnerTx(transactions[4], 2, 'Add Owner Adol Metamask 3', statusses) // checkMinedThresholdTx(transactions[4], 'Add Owner Adol Metamask 3') - await checkMinedWithdrawnTx(address, '0.07') + await checkMinedWithdrawTx(address, '0.07') }) it('approves and executes pending transactions', async () => { diff --git a/src/test/utils/etherMovements.js b/src/test/utils/etherMovements.js index e3e676e4e8..1e9cfc9887 100644 --- a/src/test/utils/etherMovements.js +++ b/src/test/utils/etherMovements.js @@ -1,7 +1,7 @@ // @flow import { getProviderInfo, getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3' import { promisify } from '~/utils/promisify' -import withdrawn, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn' +import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' export const addEtherTo = async (address: string, eth: string) => { const web3 = getWeb3() @@ -10,7 +10,7 @@ export const addEtherTo = async (address: string, eth: string) => { return promisify(cb => web3.eth.sendTransaction(txData, cb)) } -export const executeWithdrawnOn = async (safeAddress: string, value: number) => { +export const executeWithdrawOn = async (safeAddress: string, value: number) => { const providerInfo = await getProviderInfo() const userAddress = providerInfo.account @@ -19,7 +19,7 @@ export const executeWithdrawnOn = async (safeAddress: string, value: number) => [VALUE_PARAM]: `${value}`, } - return withdrawn(values, safeAddress, userAddress) + return withdraw(values, safeAddress, userAddress) } export const checkBalanceOf = async (addressToTest: string, value: string) => { diff --git a/src/test/utils/transactions/withdrawn.helper.js b/src/test/utils/transactions/withdrawn.helper.js index 4951a18552..108cd3fa9d 100644 --- a/src/test/utils/transactions/withdrawn.helper.js +++ b/src/test/utils/transactions/withdrawn.helper.js @@ -3,14 +3,14 @@ import TestUtils from 'react-dom/test-utils' import { sleep } from '~/utils/timer' import { checkBalanceOf } from '~/test/utils/etherMovements' -export const sendWithdrawnForm = ( +export const sendWithdrawForm = ( SafeDom: React$Component, - withdrawnButton: React$Component, + withdrawButton: React$Component, amount: string, destination: string, ) => { // load add multisig form component - TestUtils.Simulate.click(withdrawnButton) + TestUtils.Simulate.click(withdrawButton) // give time to re-render it sleep(600) @@ -31,6 +31,6 @@ export const sendWithdrawnForm = ( return sleep(2500) } -export const checkMinedWithdrawnTx = async (address: string, funds: number) => { +export const checkMinedWithdrawTx = async (address: string, funds: number) => { await checkBalanceOf(address, funds) } From f8e7b1309547cdf8a08df44f70439830a3c92d26 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 21 Jun 2018 17:01:15 +0200 Subject: [PATCH 34/39] WA-438 Fix daily limit module address --- src/routes/safe/component/EditDailyLimit/index.jsx | 7 ++++--- src/routes/safe/component/Safe/index.jsx | 2 +- src/routes/safe/component/Withdraw/withdraw.js | 11 +++++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/routes/safe/component/EditDailyLimit/index.jsx b/src/routes/safe/component/EditDailyLimit/index.jsx index 04246d4cc4..d5e9f5870f 100644 --- a/src/routes/safe/component/EditDailyLimit/index.jsx +++ b/src/routes/safe/component/EditDailyLimit/index.jsx @@ -3,7 +3,7 @@ import * as React from 'react' import Stepper from '~/components/Stepper' import { connect } from 'react-redux' import { createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions' -import { getEditDailyLimitData } from '~/routes/safe/component/Withdraw/withdraw' +import { getEditDailyLimitData, getDailyLimitAddress } from '~/routes/safe/component/Withdraw/withdraw' import { type Safe } from '~/routes/safe/store/model/safe' import EditDailyLimitForm, { EDIT_DAILY_LIMIT_PARAM } from './EditDailyLimitForm' import selector, { type SelectorProps } from './selector' @@ -24,7 +24,7 @@ type State = { done: boolean, } -export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'START' +export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'SEE TXs' class EditDailyLimit extends React.PureComponent { state = { @@ -37,8 +37,9 @@ class EditDailyLimit extends React.PureComponent { const newDailyLimit = values[EDIT_DAILY_LIMIT_PARAM] const safeAddress = safe.get('address') const data = await getEditDailyLimitData(safeAddress, 0, Number(newDailyLimit)) + const to = await getDailyLimitAddress(safeAddress) const nonce = Date.now() - await createTransaction(safe, `Change Safe's daily limit to ${newDailyLimit} [${nonce}]`, safeAddress, 0, nonce, userAddress, data) + await createTransaction(safe, `Change Safe's daily limit to ${newDailyLimit} [${nonce}]`, to, 0, nonce, userAddress, data) await this.props.fetchTransactions() this.setState({ done: true }) } catch (error) { diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 6db44255f5..e1b3be06cb 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -49,7 +49,7 @@ class GnoSafe extends React.PureComponent { const { safe } = this.props const value = safe.get('dailyLimit').get('value') - this.setState({ component: }) + this.setState({ component: }) } onWithdraw = () => { diff --git a/src/routes/safe/component/Withdraw/withdraw.js b/src/routes/safe/component/Withdraw/withdraw.js index 8a51156d5e..eda37787a4 100644 --- a/src/routes/safe/component/Withdraw/withdraw.js +++ b/src/routes/safe/component/Withdraw/withdraw.js @@ -36,10 +36,17 @@ export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: numbe return { value: Number(limit), spentToday: Number(spentToday) } } -export const getEditDailyLimitData = async (safeAddress: string, token: string, dailyLimit: number) => { +export const getDailyLimitAddress = async (safeAddress: string) => { const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress) - return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimit) + return dailyLimitModule.address +} + +export const getEditDailyLimitData = async (safeAddress: string, token: string, dailyLimit: string) => { + const web3 = getWeb3() + const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress) + const dailyLimitInWei = web3.toWei(dailyLimit, 'ether') + return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimitInWei) } const withdraw = async (values: Object, safeAddress: string, userAccount: string): Promise => { From 63bba3ccd53c54d2b1dcbaa01747b329527e1f53 Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 22 Jun 2018 10:44:49 +0200 Subject: [PATCH 35/39] WA-438 Fix tests --- .../build/contracts/CreateAndAddModules.json | 8 ++++- .../build/contracts/DailyLimitModule.json | 8 ++++- .../contracts/GnosisSafePersonalEdition.json | 8 ++++- .../contracts/GnosisSafeTeamEdition.json | 8 ++++- .../build/contracts/Migrations.json | 8 ++++- safe-contracts/build/contracts/MultiSend.json | 8 ++++- .../build/contracts/ProxyFactory.json | 8 ++++- .../build/contracts/SocialRecoveryModule.json | 8 ++++- .../build/contracts/StateChannelModule.json | 8 ++++- .../build/contracts/WhitelistModule.json | 8 ++++- .../Safe.multisig.1owners1threshold.test.js | 11 +++---- src/routes/safe/test/Safe.withdrawn.test.js | 29 ++++++++++--------- src/routes/safe/test/testMultisig.js | 19 ++++++------ src/test/builder/safe.dom.utils.js | 7 +++-- ...withdrawn.helper.js => withdraw.helper.js} | 0 15 files changed, 105 insertions(+), 41 deletions(-) rename src/test/utils/transactions/{withdrawn.helper.js => withdraw.helper.js} (100%) diff --git a/safe-contracts/build/contracts/CreateAndAddModules.json b/safe-contracts/build/contracts/CreateAndAddModules.json index b2d752fc02..d6ae4cf48d 100644 --- a/safe-contracts/build/contracts/CreateAndAddModules.json +++ b/safe-contracts/build/contracts/CreateAndAddModules.json @@ -1270,8 +1270,14 @@ "links": {}, "address": "0xadf257fb7290315d37d6b11ccdbb648a5d3d148f", "transactionHash": "0x80d74510df045a8b9ff09a084394dfd4eae7b7db3921dd9bde780fa7edf4d076" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x8abc460ef144c8a56bee97dc35821f3adff74f3c", + "transactionHash": "0x7af1e557142bc9cc9bedcfbd550efa8d91bfabefb4cde8f29294155c9465c137" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.354Z" + "updatedAt": "2018-06-22T07:24:16.273Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/DailyLimitModule.json b/safe-contracts/build/contracts/DailyLimitModule.json index 61fca1111d..a9f44b8d24 100644 --- a/safe-contracts/build/contracts/DailyLimitModule.json +++ b/safe-contracts/build/contracts/DailyLimitModule.json @@ -6693,8 +6693,14 @@ "links": {}, "address": "0xaff94993c9e18850a990c68bbb61d4531d3e61dd", "transactionHash": "0xff53c43c6c273ba0614353b138d78042df23d7dc6bdf767fd00fe03b538fa019" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x33eccff7f17d7533b9d127d3885ea4b145ca962c", + "transactionHash": "0x95b2c0b5b1a282240281542feb7748212fb861c364007da93b6aba6ce6bc38cf" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.364Z" + "updatedAt": "2018-06-22T07:24:16.257Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json index 9d68305f21..01594b42a1 100644 --- a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json +++ b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json @@ -9122,8 +9122,14 @@ "links": {}, "address": "0x0c6b67148fe8939c20040e409fc2e5bc349cf1fd", "transactionHash": "0xa3d4ad952d11ed76260a43d543cd9e20075a9fd4e69a1001c5ca76dfc73b8ca0" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x3a153e91544b2639d1bff08ddf29cfe0b90d54c2", + "transactionHash": "0x3324c7ff6568820ed79ff9613ae1d851689b2d93a8eafa70c1a40e833f7cfe7b" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.351Z" + "updatedAt": "2018-06-22T07:24:16.246Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json index 2b95c1b4dd..ee49f5db21 100644 --- a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json +++ b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json @@ -6954,8 +6954,14 @@ "links": {}, "address": "0xd748a53c2061521b6b3b5b0d40b91461591b0dc7", "transactionHash": "0xe82ec5350517d60310a99990cfa668570eb06a1d69fa9f4b884eab0d5caa1ad1" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0xffc8d32e746202b3676a206fa5296edd43cb2cd3", + "transactionHash": "0x9ae1de406cd8d0ca8fe85c77d43349ae77fd4d9691defa15cd9380f4c49e3a98" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.347Z" + "updatedAt": "2018-06-22T07:24:16.250Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/Migrations.json b/safe-contracts/build/contracts/Migrations.json index 780756d6aa..4f1b96cda5 100644 --- a/safe-contracts/build/contracts/Migrations.json +++ b/safe-contracts/build/contracts/Migrations.json @@ -1392,8 +1392,14 @@ "links": {}, "address": "0xf1a3a15c821eb31eadcbbdb05e3a19d41e622074", "transactionHash": "0x78a7a50665062991b8931337e43ac4f21200e6cecaa102d7685d9a391119c3ce" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x8b8f0365a24b4c968b7a1ada7b116c510f2df133", + "transactionHash": "0xb6a19a7a679a1474c09c651e4151421f210afa3f47effed019d4c0206144ee5f" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.359Z" + "updatedAt": "2018-06-22T07:24:16.275Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/MultiSend.json b/safe-contracts/build/contracts/MultiSend.json index e3e52ab50e..2ff8cf2594 100644 --- a/safe-contracts/build/contracts/MultiSend.json +++ b/safe-contracts/build/contracts/MultiSend.json @@ -372,8 +372,14 @@ "links": {}, "address": "0xaba1a0da223a2a5e04158bd80b2af7671e27e2c6", "transactionHash": "0x6e7c0c3947a3a851738677ae63915781ce79fdfb0453030fc63bbcd346f2cf89" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x2013688de17569d52fc4cd4fe5f18821d8b32b2a", + "transactionHash": "0x2d7f72a94ced345c372040faa1f51a51f3e8da27a02dd04b9eefef487de3ba05" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.355Z" + "updatedAt": "2018-06-22T07:24:16.274Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/ProxyFactory.json b/safe-contracts/build/contracts/ProxyFactory.json index c8f83bc25e..a1eba234d9 100644 --- a/safe-contracts/build/contracts/ProxyFactory.json +++ b/safe-contracts/build/contracts/ProxyFactory.json @@ -1005,8 +1005,14 @@ "links": {}, "address": "0xce824fab495ef56405218cce3512b7a73df9e2ca", "transactionHash": "0x10a89cb87c96bb1becc3a78f1bfdd54f98cdc1cb7e5164e26b1cbbd09d69be8c" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0xffacf76025eda5f84659135a9d5c2d815dbe1caa", + "transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.341Z" + "updatedAt": "2018-06-22T07:24:16.243Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/SocialRecoveryModule.json b/safe-contracts/build/contracts/SocialRecoveryModule.json index e8ec5ea696..ec04402fd8 100644 --- a/safe-contracts/build/contracts/SocialRecoveryModule.json +++ b/safe-contracts/build/contracts/SocialRecoveryModule.json @@ -7304,8 +7304,14 @@ "links": {}, "address": "0x9d6575ea466550e050f4c08eff7075ab099db8f6", "transactionHash": "0x8c0dc99f8f345ac15f129ef0e98e60a7fde3975cf8b77fbb9f0b1e75eae34c30" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0xdfcdce812f5f001cdd35506bfb01cc02e31ae5a2", + "transactionHash": "0x6c40a3712932d0e03f4a6f0ad0f39be479bac35533935534577070e087245a52" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.368Z" + "updatedAt": "2018-06-22T07:24:16.270Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/StateChannelModule.json b/safe-contracts/build/contracts/StateChannelModule.json index 5e7cfdab8d..91d38e65ae 100644 --- a/safe-contracts/build/contracts/StateChannelModule.json +++ b/safe-contracts/build/contracts/StateChannelModule.json @@ -5437,8 +5437,14 @@ "links": {}, "address": "0x437ca411c1aa04e6012dbe1ac8cd0ccc87c1e6d9", "transactionHash": "0xe7066b0fd7695e7e5956681c536759a36839b507de3a4fde6509dab7c6d9b152" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0xcda1de5ecadaf89d663ed589a615e0ba8d697d3d", + "transactionHash": "0xcc681aa2ad918c4a255559fa45f9c64405ce4064db091ce1d7749bf3e6f05899" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.343Z" + "updatedAt": "2018-06-22T07:24:16.253Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/WhitelistModule.json b/safe-contracts/build/contracts/WhitelistModule.json index e11ee98c77..f989e7d6c1 100644 --- a/safe-contracts/build/contracts/WhitelistModule.json +++ b/safe-contracts/build/contracts/WhitelistModule.json @@ -4348,8 +4348,14 @@ "links": {}, "address": "0x6fafade61582e994730a7cd15480155d8017e888", "transactionHash": "0x7850b601cdea18ba050f455b4fad47c152c51ed5d2c56e88a54a336780ddcbd2" + }, + "1529652204341": { + "events": {}, + "links": {}, + "address": "0x88ed584819ee8dda7263b501af76ca07befa9ac7", + "transactionHash": "0x07909d849b2c29127266874541e7145062da0e1af6ab5d204cd91ca8d08d48d0" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-06-20T07:58:01.360Z" + "updatedAt": "2018-06-22T07:24:16.263Z" } \ No newline at end of file diff --git a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js index c8c0c08c90..8a0f3a6c7b 100644 --- a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js +++ b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js @@ -17,6 +17,7 @@ import { getBalanceInEtherOf } from '~/wallets/getWeb3' import { sleep } from '~/utils/timer' import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index' +import { MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils' describe('React DOM TESTS > Withdraw funds from safe', () => { let SafeDom @@ -44,12 +45,12 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const addTxButton = buttons[3] - expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT) - await sleep(1800) // Give time to enable Add button - TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(addTxButton, 'button')[0]) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const addTxButton = buttons[MOVE_FUNDS_INDEX] + expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT) + await sleep(1800) // Give time to enable Add button + TestUtils.Simulate.click(addTxButton) const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent) // $FlowFixMe diff --git a/src/routes/safe/test/Safe.withdrawn.test.js b/src/routes/safe/test/Safe.withdrawn.test.js index 685c95c4e8..cc681aa3cb 100644 --- a/src/routes/safe/test/Safe.withdrawn.test.js +++ b/src/routes/safe/test/Safe.withdrawn.test.js @@ -17,6 +17,7 @@ import { sleep } from '~/utils/timer' import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw' import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit' import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' +import { WITHDRAW_INDEX, MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils' describe('React DOM TESTS > Withdraw funds from safe', () => { let SafeDom @@ -45,10 +46,10 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const withdrawButton = buttons[2] - expect(withdrawButton.props.children).toEqual(WITHDRAW_BUTTON_TEXT) - TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawButton, 'button')[0]) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const addWithdrawButton = buttons[WITHDRAW_INDEX] + expect(addWithdrawButton.getElementsByTagName('span')[0].innerHTML).toEqual(WITHDRAW_BUTTON_TEXT) + TestUtils.Simulate.click(addWithdrawButton) await sleep(4000) const Withdraw = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawComponent) @@ -95,28 +96,28 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { it('add multisig txs button disabled when balance is 0', async () => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const addTxButton = buttons[3] - expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT) - expect(addTxButton.props.disabled).toBe(true) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const addTxButton = buttons[MOVE_FUNDS_INDEX] + expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT) + expect(addTxButton.hasAttribute('disabled')).toBe(true) await addEtherTo(address, '0.1') await sleep(1800) - expect(addTxButton.props.disabled).toBe(false) + expect(addTxButton.hasAttribute('disabled')).toBe(false) }) it('Withdraw button disabled when balance is 0', async () => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const addTxButton = buttons[2] - expect(addTxButton.props.children).toEqual(WITHDRAW_BUTTON_TEXT) - expect(addTxButton.props.disabled).toBe(true) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const addWithdrawButton = buttons[WITHDRAW_INDEX] + expect(addWithdrawButton.getElementsByTagName('span')[0].innerHTML).toEqual(WITHDRAW_BUTTON_TEXT) + expect(addWithdrawButton.hasAttribute('disabled')).toBe(true) await addEtherTo(address, '0.1') await sleep(1800) - expect(addTxButton.props.disabled).toBe(false) + expect(addWithdrawButton.hasAttribute('disabled')).toBe(false) }) }) diff --git a/src/routes/safe/test/testMultisig.js b/src/routes/safe/test/testMultisig.js index 54ec20d7e4..d8bf4c87ba 100644 --- a/src/routes/safe/test/testMultisig.js +++ b/src/routes/safe/test/testMultisig.js @@ -2,7 +2,6 @@ import TestUtils from 'react-dom/test-utils' import { sleep } from '~/utils/timer' import { getBalanceInEtherOf } from '~/wallets/getWeb3' -import Button from '~/components/layout/Button' import { ADD_MULTISIG_BUTTON_TEXT, SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' import { addEtherTo } from '~/test/utils/etherMovements' import SafeView from '~/routes/safe/component/Safe' @@ -11,6 +10,7 @@ import TransactionComponent from '~/routes/safe/component/Transactions/Transacti import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index' import { type GlobalState } from '~/store/index' import ListItemText from '~/components/List/ListItemText' +import { MOVE_FUNDS_INDEX, LIST_TXS_INDEX } from '~/test/builder/safe.dom.utils' export const createMultisigTxFilling = async ( SafeDom: React$Component, @@ -48,21 +48,22 @@ export const addFundsTo = async (SafeDom: React$Component, destination const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const addTxButton = buttons[3] - expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const addTxButton = buttons[MOVE_FUNDS_INDEX] + expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT) + await sleep(1800) // Give time to enable Add button - TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(addTxButton, 'button')[0]) + TestUtils.Simulate.click(addTxButton) } export const listTxsOf = (SafeDom: React$Component) => { const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe - const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) - const seeTx = buttons[4] - expect(seeTx.props.children).toEqual(SEE_MULTISIG_BUTTON_TEXT) - TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(seeTx, 'button')[0]) + const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button') + const seeTx = buttons[LIST_TXS_INDEX] + expect(seeTx.getElementsByTagName('span')[0].innerHTML).toEqual(SEE_MULTISIG_BUTTON_TEXT) + TestUtils.Simulate.click(seeTx) } export const getListItemsFrom = (SafeDom: React$Component) => { diff --git a/src/test/builder/safe.dom.utils.js b/src/test/builder/safe.dom.utils.js index 8f07e5eb6e..27aedd6de1 100644 --- a/src/test/builder/safe.dom.utils.js +++ b/src/test/builder/safe.dom.utils.js @@ -8,9 +8,10 @@ import { sleep } from '~/utils/timer' export const EXPAND_OWNERS_INDEX = 0 export const ADD_OWNERS_INDEX = 1 export const EDIT_THRESHOLD_INDEX = 2 -export const WITHDRAW_INDEX = 3 -export const MOVE_FUNDS_INDEX = 4 -export const LIST_TXS_INDEX = 5 +export const EDIT_INDEX = 3 +export const WITHDRAW_INDEX = 4 +export const MOVE_FUNDS_INDEX = 5 +export const LIST_TXS_INDEX = 6 export const listTxsClickingOn = async (seeTxsButton: Element) => { expect(seeTxsButton.getElementsByTagName('span')[0].innerHTML).toEqual(SEE_MULTISIG_BUTTON_TEXT) diff --git a/src/test/utils/transactions/withdrawn.helper.js b/src/test/utils/transactions/withdraw.helper.js similarity index 100% rename from src/test/utils/transactions/withdrawn.helper.js rename to src/test/utils/transactions/withdraw.helper.js From d58bcf9bb819d51396718d072ad6ae10438eaa85 Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 22 Jun 2018 13:13:52 +0200 Subject: [PATCH 36/39] WA-438 Add withdrawn transactions to list --- src/routes/safe/component/Safe/index.jsx | 2 +- src/routes/safe/component/Withdraw/actions.js | 12 +++++++ src/routes/safe/component/Withdraw/index.jsx | 14 +++++--- .../safe/component/Withdraw/withdraw.js | 13 +++++-- .../safe/component/Withdraw/withdraw.test.js | 8 +++-- .../test/builder/deployedSafe.builder.js | 5 +-- ...ithdrawn.test.js => Safe.withdraw.test.js} | 10 +++--- src/test/safe.dom.test.js | 34 +++++++++---------- .../utils/transactions/withdraw.helper.js | 10 +++++- 9 files changed, 74 insertions(+), 34 deletions(-) create mode 100644 src/routes/safe/component/Withdraw/actions.js rename src/routes/safe/test/{Safe.withdrawn.test.js => Safe.withdraw.test.js} (93%) diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index e1b3be06cb..6ab1fe5d79 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -55,7 +55,7 @@ class GnoSafe extends React.PureComponent { onWithdraw = () => { const { safe } = this.props - this.setState({ component: }) + this.setState({ component: }) } onAddTx = () => { diff --git a/src/routes/safe/component/Withdraw/actions.js b/src/routes/safe/component/Withdraw/actions.js new file mode 100644 index 0000000000..32f51f38aa --- /dev/null +++ b/src/routes/safe/component/Withdraw/actions.js @@ -0,0 +1,12 @@ +// @flow +import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' + +type FetchTransactions = typeof fetchTransactions + +export type Actions = { + fetchTransactions: FetchTransactions, +} + +export default { + fetchTransactions, +} diff --git a/src/routes/safe/component/Withdraw/index.jsx b/src/routes/safe/component/Withdraw/index.jsx index 850d3718e3..9368cadd58 100644 --- a/src/routes/safe/component/Withdraw/index.jsx +++ b/src/routes/safe/component/Withdraw/index.jsx @@ -3,17 +3,19 @@ import * as React from 'react' import { connect } from 'react-redux' import Stepper from '~/components/Stepper' import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit' +import { type Safe } from '~/routes/safe/store/model/safe' import selector, { type SelectorProps } from './selector' import withdraw from './withdraw' import WithdrawForm from './WithdrawForm' import Review from './Review' +import actions, { type Actions } from './actions' const getSteps = () => [ 'Fill Withdraw Form', 'Review Withdraw', ] -type Props = SelectorProps & { - safeAddress: string, +type Props = SelectorProps & Actions & { + safe: Safe, dailyLimit: DailyLimit, } @@ -30,8 +32,10 @@ class Withdraw extends React.Component { onWithdraw = async (values: Object) => { try { - const { safeAddress, userAddress } = this.props - await withdraw(values, safeAddress, userAddress) + const { safe, userAddress, fetchTransactions } = this.props + await withdraw(values, safe, userAddress) + fetchTransactions() + this.setState({ done: true }) } catch (error) { this.setState({ done: false }) @@ -71,5 +75,5 @@ class Withdraw extends React.Component { } } -export default connect(selector)(Withdraw) +export default connect(selector, actions)(Withdraw) diff --git a/src/routes/safe/component/Withdraw/withdraw.js b/src/routes/safe/component/Withdraw/withdraw.js index eda37787a4..8048649745 100644 --- a/src/routes/safe/component/Withdraw/withdraw.js +++ b/src/routes/safe/component/Withdraw/withdraw.js @@ -3,6 +3,8 @@ import { getWeb3 } from '~/wallets/getWeb3' import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts' import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit' import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions' +import { type Safe } from '~/routes/safe/store/model/safe' +import { buildExecutedConfirmationFrom, storeTransaction } from '~/routes/safe/component/AddTransaction/createTransactions' export const LIMIT_POSITION = 0 export const SPENT_TODAY_POS = 1 @@ -49,12 +51,14 @@ export const getEditDailyLimitData = async (safeAddress: string, token: string, return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimitInWei) } -const withdraw = async (values: Object, safeAddress: string, userAccount: string): Promise => { +const withdraw = async (values: Object, safe: Safe, userAccount: string): Promise => { const web3 = getWeb3() + const safeAddress = safe.get('address') const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress) const destination = values[DESTINATION_PARAM] - const value = web3.toWei(values[VALUE_PARAM], 'ether') + const valueInEth = values[VALUE_PARAM] + const value = web3.toWei(valueInEth, 'ether') const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, destination, value) const gas = await calculateGasOf(dailyLimitData, userAccount, dailyLimitModule.address) @@ -62,6 +66,11 @@ const withdraw = async (values: Object, safeAddress: string, userAccount: string const txHash = await dailyLimitModule.executeDailyLimit(0, destination, value, { from: userAccount, gas, gasPrice }) checkReceiptStatus(txHash.tx) + + const nonce = Date.now() + const executedConfirmations: List = buildExecutedConfirmationFrom(safe.get('owners'), userAccount) + + return storeTransaction(`Withdraw movement of ${valueInEth}`, nonce, destination, valueInEth, userAccount, executedConfirmations, txHash.tx, safeAddress, safe.get('threshold'), '0x') } export default withdraw diff --git a/src/routes/safe/component/Withdraw/withdraw.test.js b/src/routes/safe/component/Withdraw/withdraw.test.js index f6c5630824..c6ca86e04a 100644 --- a/src/routes/safe/component/Withdraw/withdraw.test.js +++ b/src/routes/safe/component/Withdraw/withdraw.test.js @@ -2,6 +2,8 @@ import { aNewStore } from '~/store' import { addEtherTo } from '~/test/utils/etherMovements' import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' +import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps' +import { safeSelector } from '~/routes/safe/store/selectors/index' describe('Safe Blockchain Test', () => { let store @@ -17,8 +19,10 @@ describe('Safe Blockchain Test', () => { const value = 0.15 // WHEN - await executeWithdrawOn(safeAddress, value) - await executeWithdrawOn(safeAddress, value) + const match: Match = buildMathPropsFrom(safeAddress) + const safe = safeSelector(store.getState(), { match }) + await executeWithdrawOn(safe, value) + await executeWithdrawOn(safe, value) // THEN expect(executeWithdrawOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert') diff --git a/src/routes/safe/store/test/builder/deployedSafe.builder.js b/src/routes/safe/store/test/builder/deployedSafe.builder.js index 922f99e423..bd8253d132 100644 --- a/src/routes/safe/store/test/builder/deployedSafe.builder.js +++ b/src/routes/safe/store/test/builder/deployedSafe.builder.js @@ -13,6 +13,7 @@ import addProvider from '~/wallets/store/actions/addProvider' import { makeProvider } from '~/wallets/store/model/provider' import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' import { promisify } from '~/utils/promisify' +import { type Safe } from '~/routes/safe/store/model/safe' export const renderSafe = async (localStore: Store) => { const provider = await getProviderInfo() @@ -94,7 +95,7 @@ export const aDeployedSafe = async ( return deployedSafe.logs[1].args.proxy } -export const executeWithdrawOn = async (safeAddress: string, value: number) => { +export const executeWithdrawOn = async (safe: Safe, value: number) => { const providerInfo = await getProviderInfo() const userAddress = providerInfo.account @@ -103,5 +104,5 @@ export const executeWithdrawOn = async (safeAddress: string, value: number) => { [VALUE_PARAM]: `${value}`, } - return withdraw(values, safeAddress, userAddress) + return withdraw(values, safe, userAddress) } diff --git a/src/routes/safe/test/Safe.withdrawn.test.js b/src/routes/safe/test/Safe.withdraw.test.js similarity index 93% rename from src/routes/safe/test/Safe.withdrawn.test.js rename to src/routes/safe/test/Safe.withdraw.test.js index cc681aa3cb..d708a83ef4 100644 --- a/src/routes/safe/test/Safe.withdrawn.test.js +++ b/src/routes/safe/test/Safe.withdraw.test.js @@ -18,6 +18,8 @@ import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw' import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit' import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' import { WITHDRAW_INDEX, MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils' +import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps' +import { safeSelector } from '~/routes/safe/store/selectors/index' describe('React DOM TESTS > Withdraw funds from safe', () => { let SafeDom @@ -80,10 +82,10 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { // add funds to safe await addEtherTo(address, '0.1') - // GIVEN in beforeEach - // WHEN - await executeWithdrawOn(address, 0.01) - await executeWithdrawOn(address, 0.01) + const match: Match = buildMathPropsFrom(address) + const safe = safeSelector(store.getState(), { match }) + await executeWithdrawOn(safe, 0.01) + await executeWithdrawOn(safe, 0.01) const ethAddress = 0 const dailyLimit: DailyLimitProps = await getDailyLimitFrom(address, ethAddress) diff --git a/src/test/safe.dom.test.js b/src/test/safe.dom.test.js index dc015f7fab..eb1fda3b4a 100644 --- a/src/test/safe.dom.test.js +++ b/src/test/safe.dom.test.js @@ -33,9 +33,9 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { const transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) checkMinedMoveFundsTx(transactions[0], 'Move funds') - await checkMinedWithdrawTx(address, '0.08') // 0.1 - 0.01 tx - 0.01 withdraw - checkMinedAddOwnerTx(transactions[1], 'Add Owner Adol Metamask 2') - checkMinedThresholdTx(transactions[2], 'Change Safe\'s threshold') + await checkMinedWithdrawTx(transactions[1], 'Withdraw movement of 0.01', address, '0.08') // 0.1 - 0.01 tx - 0.01 withdraw + checkMinedAddOwnerTx(transactions[2], 'Add Owner Adol Metamask 2') + checkMinedThresholdTx(transactions[3], 'Change Safe\'s threshold') }) it('mines withdraw process correctly all multisig txs in a 2 owner & 2 threshold safe', async () => { @@ -55,10 +55,10 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { const transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) const statusses = ['Adol Metamask 2 [Not confirmed]', 'Adolfo 1 Eth Account [Confirmed]'] - await checkPendingMoveFundsTx(transactions[3], 2, 'Buy batteries', statusses) - await checkPendingAddOwnerTx(transactions[4], 2, 'Add Owner Adol Metamask 3', statusses) + await checkPendingMoveFundsTx(transactions[4], 2, 'Buy batteries', statusses) + await checkPendingAddOwnerTx(transactions[5], 2, 'Add Owner Adol Metamask 3', statusses) // checkMinedThresholdTx(transactions[4], 'Add Owner Adol Metamask 3') - await checkMinedWithdrawTx(address, '0.07') + await checkMinedWithdrawTx(transactions[6], 'Withdraw movement of 0.01', address, '0.07') }) it('approves and executes pending transactions', async () => { @@ -68,17 +68,17 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { } = domSafe let transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) - expect(transactions.length).toBe(5) + expect(transactions.length).toBe(7) // WHEN... processing pending TXs - await processTransaction(address, transactions[3].props.transaction, 1, accounts[1]) await processTransaction(address, transactions[4].props.transaction, 1, accounts[1]) + await processTransaction(address, transactions[5].props.transaction, 1, accounts[1]) await refreshTransactions(store) // THEN - checkMinedMoveFundsTx(transactions[3], 'Buy batteries') + checkMinedMoveFundsTx(transactions[4], 'Buy batteries') await checkBalanceOf(address, '0.06') - checkMinedAddOwnerTx(transactions[4], 'Add Owner Adol Metamask 3') + checkMinedAddOwnerTx(transactions[5], 'Add Owner Adol Metamask 3') await checkThresholdOf(address, 3) // WHEN... reducing threshold @@ -87,22 +87,22 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { // THEN await listTxsClickingOn(safeButtons[LIST_TXS_INDEX]) transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) - expect(transactions.length).toBe(6) + expect(transactions.length).toBe(8) let statusses = ['Adol Metamask 3 [Not confirmed]', 'Adol Metamask 2 [Not confirmed]', 'Adolfo 1 Eth Account [Confirmed]'] - await checkPendingRemoveOwnerTx(transactions[5], 3, 'Remove Owner Adol Metamask 3', statusses) + await checkPendingRemoveOwnerTx(transactions[7], 3, 'Remove Owner Adol Metamask 3', statusses) - await processTransaction(address, transactions[5].props.transaction, 1, accounts[1]) + await processTransaction(address, transactions[7].props.transaction, 1, accounts[1]) await refreshTransactions(store) transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) statusses = ['Adol Metamask 3 [Not confirmed]', 'Adol Metamask 2 [Confirmed]', 'Adolfo 1 Eth Account [Confirmed]'] - await checkPendingRemoveOwnerTx(transactions[5], 2, 'Remove Owner Adol Metamask 3', statusses) + await checkPendingRemoveOwnerTx(transactions[7], 2, 'Remove Owner Adol Metamask 3', statusses) await checkThresholdOf(address, 3) - await processTransaction(address, transactions[5].props.transaction, 2, accounts[2]) + await processTransaction(address, transactions[7].props.transaction, 2, accounts[2]) await refreshTransactions(store) await checkThresholdOf(address, 2) transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) - await checkMinedRemoveOwnerTx(transactions[5], 'Remove Owner') + await checkMinedRemoveOwnerTx(transactions[7], 'Remove Owner') // WHEN... changing threshold await sendChangeThresholdForm(SafeDom, safeButtons[EDIT_THRESHOLD_INDEX], '1') @@ -110,7 +110,7 @@ describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { // THEN transactions = TestUtils.scryRenderedComponentsWithType(SafeDom, Transaction) - await processTransaction(address, transactions[6].props.transaction, 1, accounts[1]) + await processTransaction(address, transactions[8].props.transaction, 1, accounts[1]) await checkThresholdOf(address, 1) }) }) diff --git a/src/test/utils/transactions/withdraw.helper.js b/src/test/utils/transactions/withdraw.helper.js index 108cd3fa9d..8a7c33e6b3 100644 --- a/src/test/utils/transactions/withdraw.helper.js +++ b/src/test/utils/transactions/withdraw.helper.js @@ -2,6 +2,7 @@ import TestUtils from 'react-dom/test-utils' import { sleep } from '~/utils/timer' import { checkBalanceOf } from '~/test/utils/etherMovements' +import { checkMinedTx } from '~/test/builder/safe.dom.utils' export const sendWithdrawForm = ( SafeDom: React$Component, @@ -31,6 +32,13 @@ export const sendWithdrawForm = ( return sleep(2500) } -export const checkMinedWithdrawTx = async (address: string, funds: number) => { +export const checkMinedWithdrawTx = async ( + Transaction: React$Component, + name: string, + address: string, + funds: number, +) => { await checkBalanceOf(address, funds) + + checkMinedTx(Transaction, name) } From 7e76a209203d1575d03100d0f7546704168baec4 Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 22 Jun 2018 13:46:24 +0200 Subject: [PATCH 37/39] WA-438 Giving some time to render the add multisig tx form in test --- src/routes/safe/test/Safe.multisig.1owners1threshold.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js index 8a0f3a6c7b..017cebe757 100644 --- a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js +++ b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js @@ -51,6 +51,7 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { await sleep(1800) // Give time to enable Add button TestUtils.Simulate.click(addTxButton) + await sleep(1800) // Give time to render the form const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent) // $FlowFixMe From faa6c5ae23938fd1bed93473a2e57b2ae0ddf03f Mon Sep 17 00:00:00 2001 From: apanizo Date: Fri, 22 Jun 2018 13:46:24 +0200 Subject: [PATCH 38/39] WA-438 Giving some time to render the add multisig tx form in test --- src/routes/safe/test/Safe.multisig.1owners1threshold.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js index 8a0f3a6c7b..017cebe757 100644 --- a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js +++ b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js @@ -51,6 +51,7 @@ describe('React DOM TESTS > Withdraw funds from safe', () => { await sleep(1800) // Give time to enable Add button TestUtils.Simulate.click(addTxButton) + await sleep(1800) // Give time to render the form const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent) // $FlowFixMe From b2a20f2147da09a1a4895a3ce3218664220b09eb Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 26 Jun 2018 12:29:55 +0200 Subject: [PATCH 39/39] Return fixed gas price in testing environment --- src/wallets/ethTransactions.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wallets/ethTransactions.js b/src/wallets/ethTransactions.js index 72b2ce9691..6b121f77d7 100644 --- a/src/wallets/ethTransactions.js +++ b/src/wallets/ethTransactions.js @@ -35,6 +35,10 @@ export const calculateGasPrice = async () => { : 'https://safe-relay.dev.gnosisdev.com/' */ + if (process.env.NODE_ENV === 'test') { + return '20000000000' + } + const header = new Headers({ 'Access-Control-Allow-Origin': '*', })