MERGE development into master (#648)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

* Bug: #482 - Address book Custom transactions Recipient validation (#577)

* (fix) text input bottom border

* Fix #482 input

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	src/components/forms/TextField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx
#	yarn.lock

* Fix custom tx addresses filtering

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	yarn.lock

* Remove console logs
Fixed prettier issues

* Remove unnecessary template string

* Fix `tokenAddress` string conversion

* Use `secondaryBackground` value

Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: Fernando <fernando.greco@gmail.com>

* (feature)  Adding origin for Apps Transactions (#576)

* Adding origin field when creates a TX

* refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function

* minor changes

* Allow execute if threshold is 1 for the first tx

- Related to issue #563
- `lastTx` is required due to #489

* - Normalizing logic between createTransaction and processTransaction
- Moving shared function to a new file

* Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning

* Rename function and variable names

* Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions

* Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

* Update Tests

- remove mocked `getGnosisSafeInstanceAt`
- pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

Co-authored-by: Fernando <fernando.greco@gmail.com>

* (Feature) Add checks into CI (#594)

* Repare new dev and staging enviroments to deploy (#618)

* Repare new dev and staging enviroments to deploy

  - Add to `deploy_pull_requests.sh` to the new path.
  - Replace upload-dir to deploy staging to the new path.

* add /app/ public path for the webapp, remove duplicate yarn build from travis

* add basename to app

* deploy pr to /app

* update travis

* linter error fixes

* fix travis build script

Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>

* (fix) sidebar contents' scrolling (#622)

* (add) linter sorting rules (#614)

* (add) linter sorting rules

* (fix) linting errors according to the new rules

Co-authored-by: Fernando <fernando.greco@gmail.com>

* Rebase master onto development (#624)

* v1.7.3 (#611)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* Update package.json (#612)

* Add public url to prod webpack config (#615)

* add public url to prod webpack config

* modify travis/webpack config to add public url

* add slash

* cherry pick new travis yml merge commit (#620)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

* Bug: #482 - Address book Custom transactions Recipient validation (#577)

* (fix) text input bottom border

* Fix #482 input

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	src/components/forms/TextField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx
#	yarn.lock

* Fix custom tx addresses filtering

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	yarn.lock

* Remove console logs
Fixed prettier issues

* Remove unnecessary template string

* Fix `tokenAddress` string conversion

* Use `secondaryBackground` value

Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: Fernando <fernando.greco@gmail.com>

* (feature)  Adding origin for Apps Transactions (#576)

* Adding origin field when creates a TX

* refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function

* minor changes

* Allow execute if threshold is 1 for the first tx

- Related to issue #563
- `lastTx` is required due to #489

* - Normalizing logic between createTransaction and processTransaction
- Moving shared function to a new file

* Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning

* Rename function and variable names

* Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions

* Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

* Update Tests

- remove mocked `getGnosisSafeInstanceAt`
- pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

Co-authored-by: Fernando <fernando.greco@gmail.com>

* (Feature) Add checks into CI (#594)

* Repare new dev and staging enviroments to deploy (#618)

* Repare new dev and staging enviroments to deploy

  - Add to `deploy_pull_requests.sh` to the new path.
  - Replace upload-dir to deploy staging to the new path.

* add /app/ public path for the webapp, remove duplicate yarn build from travis

* add basename to app

* deploy pr to /app

* update travis

* linter error fixes

* fix travis build script

Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>

* (fix) sidebar contents' scrolling (#622)

* (add) linter sorting rules (#614)

* (add) linter sorting rules

* (fix) linting errors according to the new rules

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>
Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: nicolas <nicosampler@users.noreply.github.com>
Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>

* (feature): [Safe Apps] App Transaction List Details (#601)

* Adding IconText component

* Get origin for TXs in Redux

* Adding Icon and name app to transaction list

* Fix customTx condition

* Fix HTML element for text

* simplify condition

* Bug: Accounts/Network are not updated in production build (#625)

* Adding Apps info to toast notification (#621)

* Adding APP_Name for APPs TXs in toast messages

* refactor: save appId instead of appName in origin field

* adding fallback icon and message to TX apps table

* review changes

* review fixes

* force build

* update Apps list info (#629)

* update Apps list info

* fix

* Feature: replace web3connect with onboardjs (#456)

* init onboard.js

* dep bump

* initial replacement of web3connect with onboard.js

* use averta font in the modal

* update onboard.js, add handlers for session murder

* update preferred wallets

* implement reconnecting to injected provider

* fix duplicate wallet disconnected notification

* update onboard dep

* onboardjs fixes

* test onboard js with hw

* add https to rpcUrl

* Added saved wallet and transactions validation

* made Transactions validation

* bnc-onboard version updated

* Fix lock/unlock problem

* bump onboardjs version

* fixed material-ui lab version

* Update onboard version

* Added hw wallets integration

* Updated preferred wallets

* Add ledger modal

* Merge with dev

* Update onboard

* BUmp new version of onboardjs

* Added some logs

* Added some logs

* Update onboardjs version fix ledger connection

* Update onboardjs version fix ledger connection

* Bump new onboardjs version

* Update new version

* Made improvements

* yarn.lock regenration

* remove https=true

* Remove comments and added some improvements

* Updated package.json dep

* Removed unused deps

* Remove web3connect dep

Co-authored-by: lukasschor <lukas.schor@gnosis.pm>
Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com>

* Passing ethBalance to Apps component (#636)

* (Fix) Update safe modal verbiage (#633)

* Fixs verbiage in update safe modal

* Fixs yarn lock

* Bump dependencies (#639)

* Use hash history (#638)

* v1.7.3 (#611)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* Update package.json (#612)

* Add public url to prod webpack config (#615)

* add public url to prod webpack config

* modify travis/webpack config to add public url

* add slash

* cherry pick new travis yml merge commit (#620)

* use hash history

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* - Updates how the transactions are ordered, now orders by nonce and then by date (#640)

* (Fix) Lowercased safes address in URL (#631)

* Return checksummed addrress from `safeParamAddressFromState` selector

* Update `yarn.lock`

* Remove redundant `toChecksumAddress` call

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>

* Rebase master into development (#647)

* v1.7.3 (#611)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* Update package.json (#612)

* Add public url to prod webpack config (#615)

* add public url to prod webpack config

* modify travis/webpack config to add public url

* add slash

* cherry pick new travis yml merge commit (#620)

* V1.7.5 release (#641)

* use hash history

* update package json

* BUG: App index.html cached on production (#642)

* remove caching for webapp index.html

* keep --delete flag

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

* Bug: #482 - Address book Custom transactions Recipient validation (#577)

* (fix) text input bottom border

* Fix #482 input

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	src/components/forms/TextField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx
#	src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx
#	yarn.lock

* Fix custom tx addresses filtering

* Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book

# Conflicts:
#	yarn.lock

* Remove console logs
Fixed prettier issues

* Remove unnecessary template string

* Fix `tokenAddress` string conversion

* Use `secondaryBackground` value

Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: Fernando <fernando.greco@gmail.com>

* (feature)  Adding origin for Apps Transactions (#576)

* Adding origin field when creates a TX

* refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function

* minor changes

* Allow execute if threshold is 1 for the first tx

- Related to issue #563
- `lastTx` is required due to #489

* - Normalizing logic between createTransaction and processTransaction
- Moving shared function to a new file

* Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning

* Rename function and variable names

* Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions

* Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

* Update Tests

- remove mocked `getGnosisSafeInstanceAt`
- pass `safeInstance` instead of `safeAddress` to `getNewTxNonce`

Co-authored-by: Fernando <fernando.greco@gmail.com>

* (Feature) Add checks into CI (#594)

* Repare new dev and staging enviroments to deploy (#618)

* Repare new dev and staging enviroments to deploy

  - Add to `deploy_pull_requests.sh` to the new path.
  - Replace upload-dir to deploy staging to the new path.

* add /app/ public path for the webapp, remove duplicate yarn build from travis

* add basename to app

* deploy pr to /app

* update travis

* linter error fixes

* fix travis build script

Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>

* (fix) sidebar contents' scrolling (#622)

* (add) linter sorting rules (#614)

* (add) linter sorting rules

* (fix) linting errors according to the new rules

Co-authored-by: Fernando <fernando.greco@gmail.com>

* (feature): [Safe Apps] App Transaction List Details (#601)

* Adding IconText component

* Get origin for TXs in Redux

* Adding Icon and name app to transaction list

* Fix customTx condition

* Fix HTML element for text

* simplify condition

* Bug: Accounts/Network are not updated in production build (#625)

* Adding Apps info to toast notification (#621)

* Adding APP_Name for APPs TXs in toast messages

* refactor: save appId instead of appName in origin field

* adding fallback icon and message to TX apps table

* review changes

* review fixes

* force build

* update Apps list info (#629)

* update Apps list info

* fix

* Feature: replace web3connect with onboardjs (#456)

* init onboard.js

* dep bump

* initial replacement of web3connect with onboard.js

* use averta font in the modal

* update onboard.js, add handlers for session murder

* update preferred wallets

* implement reconnecting to injected provider

* fix duplicate wallet disconnected notification

* update onboard dep

* onboardjs fixes

* test onboard js with hw

* add https to rpcUrl

* Added saved wallet and transactions validation

* made Transactions validation

* bnc-onboard version updated

* Fix lock/unlock problem

* bump onboardjs version

* fixed material-ui lab version

* Update onboard version

* Added hw wallets integration

* Updated preferred wallets

* Add ledger modal

* Merge with dev

* Update onboard

* BUmp new version of onboardjs

* Added some logs

* Added some logs

* Update onboardjs version fix ledger connection

* Update onboardjs version fix ledger connection

* Bump new onboardjs version

* Update new version

* Made improvements

* yarn.lock regenration

* remove https=true

* Remove comments and added some improvements

* Updated package.json dep

* Removed unused deps

* Remove web3connect dep

Co-authored-by: lukasschor <lukas.schor@gnosis.pm>
Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com>

* Passing ethBalance to Apps component (#636)

* (Fix) Update safe modal verbiage (#633)

* Fixs verbiage in update safe modal

* Fixs yarn lock

* Bump dependencies (#639)

* Use hash history (#638)

* v1.7.3 (#611)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* Update package.json (#612)

* Add public url to prod webpack config (#615)

* add public url to prod webpack config

* modify travis/webpack config to add public url

* add slash

* cherry pick new travis yml merge commit (#620)

* use hash history

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* - Updates how the transactions are ordered, now orders by nonce and then by date (#640)

* (Fix) Lowercased safes address in URL (#631)

* Return checksummed addrress from `safeParamAddressFromState` selector

* Update `yarn.lock`

* Remove redundant `toChecksumAddress` call

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>
Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: nicolas <nicosampler@users.noreply.github.com>
Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>
Co-authored-by: lukasschor <lukas.schor@gnosis.pm>
Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com>
Co-authored-by: francovenica <francovenica@gmail.com>

* Update safe relay and transaction endpoints

* Master into development (#655)

* Fix NODE_ENV development definition

  - Define develop build for development branches.
  - Use POSIX standard to call shell scripts in travis file.

* Mark travis shell scripts as executable

* Fix conditional statement at travis build.sh file

* Set development endpoints to stable staging backends

* Sync master dev (#656)

* v1.7.3 (#611)

* Fix #597: USD value not load (#609)

* Converts all the addresses to checksum values

* Fix for empty address

* fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610)

* Fix #596: Notification when safe is already updated (#599)

* Fix notification of update if the safe is already updated

* Makes the notification clickable
Displays the notification for owners only

* Identify upgrade tx

* Add red badge to Settings tab

* Fixs Padding
Removes the red dot if the user is not an owner

Co-authored-by: Fernando <fernando.greco@gmail.com>

Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

* Update package.json (#612)

* Add public url to prod webpack config (#615)

* add public url to prod webpack config

* modify travis/webpack config to add public url

* add slash

* cherry pick new travis yml merge commit (#620)

* V1.7.5 release (#641)

* use hash history

* update package json

* BUG: App index.html cached on production (#642)

* remove caching for webapp index.html

* keep --delete flag

Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
Co-authored-by: Fernando <fernando.greco@gmail.com>
Co-authored-by: Agustin Pane <agustin.pane@gmail.com>

Co-authored-by: Agustin Pane <agustin.pane@gmail.com>
Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com>
Co-authored-by: nicolas <nicosampler@users.noreply.github.com>
Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com>
Co-authored-by: lukasschor <lukas.schor@gnosis.pm>
Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com>
Co-authored-by: francovenica <francovenica@gmail.com>
Co-authored-by: Richard Meissner <rmeissner@users.noreply.github.com>
This commit is contained in:
Fernando 2020-03-11 10:11:42 -03:00 committed by GitHub
parent d3bac2f8bb
commit 3193cdc2b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
308 changed files with 5913 additions and 5125 deletions

View File

@ -8,7 +8,7 @@
"import/extensions": [".js", ".jsx"]
},
"parser": "babel-eslint",
"plugins": ["react", "flowtype", "import", "jsx-a11y", "prettier"],
"plugins": ["react", "flowtype", "import", "jsx-a11y", "sort-destructure-keys", "prettier"],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
@ -52,6 +52,12 @@
}
],
"semi": ["error", "never"],
"sort-imports": [
"error",
{
"ignoreDeclarationSort": true
}
],
"flowtype/require-valid-file-annotation": [
2,
"always",
@ -62,6 +68,16 @@
"import/extensions": 0,
"import/no-extraneous-dependencies": 0,
"import/no-unresolved": 0,
"import/order": [
"error",
{
"groups": ["builtin", "external", "parent", "sibling", "index"],
"newlines-between": "always",
"alphabetize": {
"order": "asc"
}
}
],
"import/prefer-default-export": 0,
"jsx-a11y/anchor-is-valid": [
"error",
@ -88,7 +104,9 @@
}
],
"react/jsx-props-no-spreading": 0,
"react/jsx-sort-props": 2,
"prettier/prettier": "error",
"jsx-a11y/no-autofocus": "warn"
"jsx-a11y/no-autofocus": "warn",
"sort-destructure-keys/sort-destructure-keys": 2
}
}

View File

@ -69,6 +69,6 @@ deploy:
on:
tags: true
- provider: script
script: bash config/travis/prepare_production_deployment.sh
script: ./config/travis/prepare_production_deployment.sh
on:
tags: true

0
config/travis/build.sh Normal file → Executable file
View File

0
config/travis/prepare_production_deployment.sh Normal file → Executable file
View File

View File

@ -43,24 +43,20 @@
"dependencies": {
"@gnosis.pm/safe-contracts": "1.1.1-dev.1",
"@gnosis.pm/util-contracts": "2.0.6",
"@material-ui/core": "4.8.0",
"@material-ui/icons": "4.5.1",
"@material-ui/core": "4.9.5",
"@material-ui/icons": "4.9.1",
"@material-ui/lab": "4.0.0-alpha.39",
"@portis/web3": "^2.0.0-beta.45",
"@testing-library/jest-dom": "4.2.4",
"@toruslabs/torus-embed": "0.2.10",
"@walletconnect/web3-provider": "^1.0.0-beta.37",
"@welldone-software/why-did-you-render": "3.4.1",
"authereum": "^0.0.4-beta.83",
"axios": "0.19.0",
"@testing-library/jest-dom": "5.1.1",
"@welldone-software/why-did-you-render": "4.0.5",
"axios": "0.19.2",
"bignumber.js": "9.0.0",
"connected-react-router": "6.6.1",
"bnc-onboard": "1.3.3",
"connected-react-router": "6.7.0",
"currency-flags": "^2.1.1",
"date-fns": "2.8.1",
"date-fns": "2.10.0",
"dotenv": "^8.2.0",
"ethereum-ens": "0.8.0",
"final-form": "4.18.6",
"fortmatic": "^1.0.1",
"final-form": "4.18.7",
"history": "4.10.1",
"immortal-db": "^1.0.2",
"immutable": "^4.0.0-rc.9",
@ -71,65 +67,64 @@
"optimize-css-assets-webpack-plugin": "5.0.3",
"polished": "^3.4.2",
"qrcode.react": "1.0.0",
"query-string": "6.9.0",
"react": "16.12.0",
"query-string": "6.11.1",
"react": "16.13.0",
"react-dev-utils": "^10.0.0",
"react-dom": "16.12.0",
"react-final-form": "6.3.3",
"react-dom": "16.13.0",
"react-final-form": "6.3.5",
"react-final-form-listeners": "^1.0.2",
"react-ga": "^2.7.0",
"react-hot-loader": "4.12.18",
"react-hot-loader": "4.12.19",
"react-qr-reader": "^2.2.1",
"react-redux": "7.1.3",
"react-redux": "7.2.0",
"react-router-dom": "5.1.2",
"react-window": "^1.8.5",
"recompose": "^0.30.0",
"redux": "4.0.4",
"redux": "4.0.5",
"redux-actions": "^2.6.5",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"semver": "^7.1.1",
"styled-components": "^5.0.1",
"web3": "1.2.4",
"web3connect": "1.0.0-beta.25"
"web3": "1.2.6"
},
"devDependencies": {
"@babel/cli": "7.7.5",
"@babel/core": "7.7.5",
"@babel/plugin-proposal-class-properties": "7.7.4",
"@babel/plugin-proposal-decorators": "7.7.4",
"@babel/plugin-proposal-do-expressions": "7.7.4",
"@babel/plugin-proposal-export-default-from": "7.7.4",
"@babel/plugin-proposal-export-namespace-from": "7.7.4",
"@babel/plugin-proposal-function-bind": "7.7.4",
"@babel/plugin-proposal-function-sent": "7.7.4",
"@babel/plugin-proposal-json-strings": "7.7.4",
"@babel/plugin-proposal-logical-assignment-operators": "7.7.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.7.4",
"@babel/plugin-proposal-numeric-separator": "7.7.4",
"@babel/plugin-proposal-optional-chaining": "7.7.5",
"@babel/plugin-proposal-pipeline-operator": "7.7.4",
"@babel/plugin-proposal-throw-expressions": "7.7.4",
"@babel/plugin-syntax-dynamic-import": "7.7.4",
"@babel/plugin-syntax-import-meta": "7.7.4",
"@babel/plugin-transform-member-expression-literals": "7.7.4",
"@babel/plugin-transform-property-literals": "7.7.4",
"@babel/polyfill": "7.7.0",
"@babel/preset-env": "7.7.6",
"@babel/preset-flow": "7.7.4",
"@babel/preset-react": "7.7.4",
"@testing-library/react": "9.4.0",
"autoprefixer": "9.7.3",
"@babel/cli": "7.8.4",
"@babel/core": "7.8.7",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/plugin-proposal-decorators": "7.8.3",
"@babel/plugin-proposal-do-expressions": "7.8.3",
"@babel/plugin-proposal-export-default-from": "7.8.3",
"@babel/plugin-proposal-export-namespace-from": "7.8.3",
"@babel/plugin-proposal-function-bind": "7.8.3",
"@babel/plugin-proposal-function-sent": "7.8.3",
"@babel/plugin-proposal-json-strings": "7.8.3",
"@babel/plugin-proposal-logical-assignment-operators": "7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3",
"@babel/plugin-proposal-numeric-separator": "7.8.3",
"@babel/plugin-proposal-optional-chaining": "7.8.3",
"@babel/plugin-proposal-pipeline-operator": "7.8.3",
"@babel/plugin-proposal-throw-expressions": "7.8.3",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/plugin-syntax-import-meta": "7.8.3",
"@babel/plugin-transform-member-expression-literals": "7.8.3",
"@babel/plugin-transform-property-literals": "7.8.3",
"@babel/polyfill": "7.8.7",
"@babel/preset-env": "7.8.7",
"@babel/preset-flow": "7.8.3",
"@babel/preset-react": "7.8.3",
"@testing-library/react": "9.5.0",
"autoprefixer": "9.7.4",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "10.0.3",
"babel-jest": "24.9.0",
"babel-eslint": "10.1.0",
"babel-jest": "25.1.0",
"babel-loader": "8.0.6",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.6",
"css-loader": "3.4.0",
"css-loader": "3.4.2",
"detect-port": "^1.3.0",
"dotenv-expand": "^5.1.0",
"eslint": "^6.8.0",
@ -139,33 +134,34 @@
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.18.3",
"eslint-plugin-sort-destructure-keys": "^1.3.3",
"ethereumjs-abi": "0.6.8",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "5.0.2",
"flow-bin": "0.114.0",
"file-loader": "5.1.0",
"flow-bin": "0.120.1",
"fs-extra": "8.1.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"husky": "^4.2.2",
"jest": "24.9.0",
"jest": "25.1.0",
"jest-dom": "4.0.0",
"json-loader": "^0.5.7",
"mini-css-extract-plugin": "0.8.1",
"mini-css-extract-plugin": "0.9.0",
"postcss-loader": "^3.0.0",
"postcss-mixins": "6.2.3",
"postcss-simple-vars": "^5.0.2",
"prettier": "^1.19.1",
"run-with-testrpc": "0.3.1",
"style-loader": "1.0.2",
"terser-webpack-plugin": "2.3.1",
"truffle": "5.1.4",
"style-loader": "1.1.3",
"terser-webpack-plugin": "2.3.5",
"truffle": "5.1.16",
"truffle-contract": "4.0.31",
"truffle-solidity-loader": "0.1.32",
"url-loader": "3.0.0",
"webpack": "4.41.3",
"webpack": "4.42.0",
"webpack-bundle-analyzer": "3.6.0",
"webpack-cli": "3.3.10",
"webpack-dev-server": "3.9.0",
"webpack-cli": "3.3.11",
"webpack-dev-server": "3.10.3",
"webpack-manifest-plugin": "2.2.0"
}
}

View File

@ -2,10 +2,11 @@
import React from 'react'
import styled from 'styled-components'
import Hairline from '~/components/layout/Hairline'
import { sm, md } from '~/theme/variables'
import ArrowDown from './arrow-down.svg'
import Hairline from '~/components/layout/Hairline'
import { md, sm } from '~/theme/variables'
const Wrapper = styled.div`
display: flex;
align-items: center;
@ -22,7 +23,7 @@ type Props = {
const DividerLine = ({ withArrow }: Props) => (
<Wrapper>
{withArrow && <img src={ArrowDown} alt="Arrow Down" />}
{withArrow && <img alt="Arrow Down" src={ArrowDown} />}
<Hairline />
</Wrapper>
)

View File

@ -0,0 +1,25 @@
// @flow
import React from 'react'
import styled from 'styled-components'
const Wrapper = styled.div`
display: flex;
align-items: center;
`
const Icon = styled.img`
max-width: 15px;
max-height: 15px;
margin-right: 5px;
`
const Text = styled.span`
height: 17px;
`
const IconText = ({ iconUrl, text }: { iconUrl: string, text: string }) => (
<Wrapper>
<Icon alt={text} src={iconUrl} />
<Text>{text}</Text>
</Wrapper>
)
export default IconText

View File

@ -1,3 +1,4 @@
// @flow
export { default as DividerLine } from './DividerLine'
export { default as TextBox } from './TextBox'
export { default as IconText } from './IconText'

View File

@ -1,6 +1,6 @@
// @flow
import React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import React from 'react'
import styled from 'styled-components'
const Wrapper = styled.div`

View File

@ -1,9 +1,9 @@
// @flow
import { withStyles } from '@material-ui/core/styles'
import cn from 'classnames'
import React from 'react'
import styled from 'styled-components'
import cn from 'classnames'
import { withStyles } from '@material-ui/core/styles'
// TODO: move these styles to a generic place
import styles from './style'
@ -34,17 +34,17 @@ type Props = {
classes: Object,
}
const List = ({ items, activeItem, onItemClick, classes }: Props) => {
const List = ({ activeItem, classes, items, onItemClick }: Props) => {
return (
<Wrapper>
{items.map(i => (
<Item
key={i.id}
className={cn(classes.menuOption, activeItem === i.id && classes.active)}
key={i.id}
onClick={() => onItemClick(i.id)}
>
<div className="container">
{i.iconUrl && <IconImg src={i.iconUrl} alt={i.name} />}
{i.iconUrl && <IconImg alt={i.name} src={i.iconUrl} />}
<span>{i.name}</span>
</div>
</Item>

View File

@ -1,15 +1,15 @@
// @flow
import {
xs,
sm,
md,
border,
secondary,
bolderFont,
background,
largeFontSize,
bolderFont,
border,
fontColor,
largeFontSize,
md,
screenSm,
secondary,
sm,
xs,
} from '~/theme/variables'
const styles = () => ({

View File

@ -2,13 +2,13 @@
import React from 'react'
import styled from 'styled-components'
import Paragraph from '~/components/layout/Paragraph'
import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn'
import EtherscanBtn from '~/components/EtherscanBtn'
import Identicon from '~/components/Identicon'
import Bold from '~/components/layout/Bold'
import { xs, border } from '~/theme/variables'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Paragraph from '~/components/layout/Paragraph'
import { border, xs } from '~/theme/variables'
const Wrapper = styled.div`
display: flex;
@ -43,7 +43,7 @@ type Props = {
ethBalance: string,
}
const AddressInfo = ({ safeName, safeAddress, ethBalance }: Props) => {
const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props) => {
return (
<Wrapper>
<div className="icon-section">
@ -51,12 +51,12 @@ const AddressInfo = ({ safeName, safeAddress, ethBalance }: Props) => {
</div>
<div className="data-section">
{safeName && (
<Paragraph weight="bolder" noMargin>
<Paragraph noMargin weight="bolder">
{safeName}
</Paragraph>
)}
<div className="address">
<Paragraph weight="bolder" noMargin>
<Paragraph noMargin weight="bolder">
{safeAddress}
</Paragraph>
<CopyBtn content={safeAddress} />

View File

@ -1,10 +1,10 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import CollapseMUI from '@material-ui/core/Collapse'
import IconButton from '@material-ui/core/IconButton'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import React from 'react'
import styled from 'styled-components'
const Wrapper = styled.div``
@ -21,7 +21,7 @@ type Props = {
description: React.Node,
}
const Collapse = ({ title, description, children }: Props) => {
const Collapse = ({ children, description, title }: Props) => {
const [open, setOpen] = React.useState(false)
const handleClick = () => {
@ -32,7 +32,7 @@ const Collapse = ({ title, description, children }: Props) => {
<Wrapper>
<Title>{title}</Title>
<Header>
<IconButton disableRipple size="small" onClick={handleClick}>
<IconButton disableRipple onClick={handleClick} size="small">
{open ? <ExpandLess /> : <ExpandMore />}
</IconButton>
{description}

View File

@ -1,9 +1,9 @@
// @flow
import IconButton from '@material-ui/core/IconButton'
import { createStyles, makeStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import React from 'react'
import styled from 'styled-components'
import Close from '@material-ui/icons/Close'
import { makeStyles, createStyles } from '@material-ui/core/styles'
import IconButton from '@material-ui/core/IconButton'
import Modal from '~/components/Modal'
import Hairline from '~/components/layout/Hairline'
@ -45,14 +45,14 @@ type Props = {
onClose: () => void,
}
const GenericModal = ({ title, body, footer, onClose }: Props) => {
const GenericModal = ({ body, footer, onClose, title }: Props) => {
const classes = useStyles()
return (
<Modal title="GenericModal" description="GenericModal" handleClose={onClose} paperClassName={classes.paper} open>
<Modal description="GenericModal" handleClose={onClose} open paperClassName={classes.paper} title="GenericModal">
<TitleSection>
{title}
<IconButton onClick={onClose} disableRipple>
<IconButton disableRipple onClick={onClose}>
<StyledClose />
</IconButton>
</TitleSection>

View File

@ -2,8 +2,8 @@
import React from 'react'
import styled from 'styled-components'
import Paragraph from '~/components/layout/Paragraph'
import Button from '~/components/layout/Button'
import Paragraph from '~/components/layout/Paragraph'
import { lg } from '~/theme/variables'
const StyledParagraph = styled(Paragraph)`
@ -20,11 +20,11 @@ const TitleWrapper = styled.div`
align-items: center;
`
export const ModalTitle = ({ title, iconUrl }: { title: string, iconUrl: string }) => {
export const ModalTitle = ({ iconUrl, title }: { title: string, iconUrl: string }) => {
return (
<TitleWrapper>
{iconUrl && <IconImg src={iconUrl} alt={title} />}
<StyledParagraph weight="bolder" noMargin>
{iconUrl && <IconImg alt={title} src={iconUrl} />}
<StyledParagraph noMargin weight="bolder">
{title}
</StyledParagraph>
</TitleWrapper>
@ -37,10 +37,10 @@ const FooterWrapper = styled.div`
`
export const ModalFooterConfirmation = ({
okText,
cancelText,
handleOk,
handleCancel,
handleOk,
okText,
}: {
okText: string,
cancelText: string,

View File

@ -1,68 +1,99 @@
// @flow
import Onboard from 'bnc-onboard'
import React from 'react'
import Web3Connect from 'web3connect'
import Torus from '@toruslabs/torus-embed'
import WalletConnectProvider from '@walletconnect/web3-provider'
import Fortmatic from 'fortmatic'
import Portis from '@portis/web3'
import Authereum from 'authereum'
import Button from '~/components/layout/Button'
import { fetchProvider, removeProvider } from '~/logic/wallets/store/actions'
import { getNetwork } from '~/config'
import { getNetworkId } from '~/config'
import { getWeb3, setWeb3 } from '~/logic/wallets/getWeb3'
import { fetchProvider } from '~/logic/wallets/store/actions'
import transactionDataCheck from '~/logic/wallets/transactionDataCheck'
import { store } from '~/store'
const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet'
const BLOCKNATIVE_API_KEY = isMainnet ? process.env.REACT_APP_BLOCKNATIVE_KEY : '7fbb9cee-7e97-4436-8770-8b29a9a8814c'
const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f28b-4463-80cb-846d7ec5806b'
// const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78'
const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40'
export const web3Connect = new Web3Connect.Core({
network: getNetwork().toLowerCase(),
providerOptions: {
walletconnect: {
package: WalletConnectProvider,
options: {
infuraId: process.env.REACT_APP_INFURA_TOKEN,
const wallets = [
{ walletName: 'metamask', preferred: true },
{
walletName: 'walletConnect',
preferred: true,
infuraKey: process.env.REACT_APP_INFURA_TOKEN,
},
{
walletName: 'trezor',
appUrl: 'gnosis-safe.io',
preferred: true,
email: 'safe@gnosis.io',
rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba',
},
portis: {
package: Portis,
options: {
id: PORTIS_DAPP_ID,
{
walletName: 'ledger',
preferred: true,
rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba',
},
{ walletName: 'trust', preferred: true },
{ walletName: 'dapper' },
{
walletName: 'fortmatic',
apiKey: FORTMATIC_API_KEY,
},
fortmatic: {
package: Fortmatic,
options: {
key: FORTMATIC_API_KEY,
{
walletName: 'portis',
apiKey: PORTIS_DAPP_ID,
label: 'Login with Email',
},
},
torus: {
package: Torus,
options: {
enableLogging: false,
buttonPosition: 'bottom-left',
buildEnv: process.env.NODE_ENV,
showTorusButton: true,
},
},
authereum: {
package: Authereum,
options: {},
},
},
})
{ walletName: 'authereum' },
{ walletName: 'coinbase' },
{ walletName: 'opera' },
{ walletName: 'operaTouch' },
]
web3Connect.on('connect', (provider: any) => {
if (provider) {
store.dispatch(fetchProvider(provider))
let lastUsedAddress = ''
let providerName
export const onboard = new Onboard({
dappId: BLOCKNATIVE_API_KEY,
networkId: getNetworkId(),
subscriptions: {
wallet: wallet => {
if (wallet.provider) {
// this function will intialize web3 and store it somewhere available throughout the dapp and
// can also instantiate your contracts with the web3 instance
setWeb3(wallet.provider)
providerName = wallet.name
}
},
address: address => {
if (!lastUsedAddress && address) {
lastUsedAddress = address
store.dispatch(fetchProvider(providerName))
}
// we don't have an unsubscribe event so we rely on this
if (!address && lastUsedAddress) {
lastUsedAddress = ''
providerName = undefined
}
},
},
walletSelect: {
wallets,
},
walletCheck: [{ checkName: 'connect' }, transactionDataCheck(), { checkName: 'network' }, { checkName: 'accounts' }],
})
web3Connect.on('disconnect', () => {
store.dispatch(removeProvider())
})
export const onboardUser = async () => {
// before calling walletSelect you want to check if web3 has been instantiated
// which indicates that a wallet has already been selected
// and web3 has been instantiated with that provider
const web3 = getWeb3()
const walletSelected = web3 ? true : await onboard.walletSelect()
return walletSelected && onboard.walletCheck()
}
type Props = {
enqueueSnackbar: Function,
@ -72,11 +103,12 @@ type Props = {
const ConnectButton = (props: Props) => (
<Button
color="primary"
variant="contained"
minWidth={140}
onClick={() => {
web3Connect.toggleModal()
onClick={async () => {
await onboard.walletSelect()
await onboard.walletCheck()
}}
variant="contained"
{...props}
>
Connect

View File

@ -1,20 +1,21 @@
// @flow
import Checkbox from '@material-ui/core/Checkbox'
import FormControlLabel from '@material-ui/core/FormControlLabel'
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch, useSelector } from 'react-redux'
import cn from 'classnames'
import Link from '~/components/layout/Link'
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import Button from '~/components/layout/Button'
import { primary, mainFontFamily, md, screenSm } from '~/theme/variables'
import Link from '~/components/layout/Link'
import type { CookiesProps } from '~/logic/cookies/model/cookie'
import { COOKIES_KEY } from '~/logic/cookies/model/cookie'
import { loadFromCookie, saveCookie } from '~/logic/cookies/utils'
import { cookieBannerOpen } from '~/logic/cookies/store/selectors'
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
import { loadIntercom } from '~/utils/intercom'
import { cookieBannerOpen } from '~/logic/cookies/store/selectors'
import { loadFromCookie, saveCookie } from '~/logic/cookies/utils'
import { mainFontFamily, md, primary, screenSm } from '~/theme/variables'
import { loadGoogleAnalytics } from '~/utils/googleAnalytics'
import { loadIntercom } from '~/utils/intercom'
const useStyles = makeStyles({
container: {
@ -96,7 +97,7 @@ const CookiesBanner = () => {
async function fetchCookiesFromStorage() {
const cookiesState: ?CookiesProps = await loadFromCookie(COOKIES_KEY)
if (cookiesState) {
const { acceptedNecessary, acceptedAnalytics } = cookiesState
const { acceptedAnalytics, acceptedNecessary } = cookiesState
setLocalAnalytics(acceptedAnalytics)
setLocalNecessary(acceptedNecessary)
const openBanner = acceptedNecessary === false || showBanner
@ -133,11 +134,11 @@ const CookiesBanner = () => {
const cookieBannerContent = (
<div className={classes.container}>
<span
role="button"
tabIndex="0"
className={cn(classes.acceptPreferences, classes.text)}
onClick={closeCookiesBannerHandler}
onKeyDown={closeCookiesBannerHandler}
className={cn(classes.acceptPreferences, classes.text)}
role="button"
tabIndex="0"
>
Accept preferences &gt;
</span>
@ -154,21 +155,21 @@ const CookiesBanner = () => {
<div className={classes.formItem}>
<FormControlLabel
checked={localNecessary}
control={<Checkbox disabled />}
disabled
label="Necessary"
name="Necessary"
onChange={() => setLocalNecessary(prev => !prev)}
value={localNecessary}
control={<Checkbox disabled />}
/>
</div>
<div className={classes.formItem}>
<FormControlLabel
control={<Checkbox checked={localAnalytics} />}
label="Analytics"
name="Analytics"
onChange={() => setLocalAnalytics(prev => !prev)}
value={localAnalytics}
control={<Checkbox checked={localAnalytics} />}
/>
</div>
<div className={classes.formItem}>
@ -176,8 +177,8 @@ const CookiesBanner = () => {
color="primary"
component={Link}
minWidth={180}
variant="outlined"
onClick={() => acceptCookiesHandler()}
variant="outlined"
>
Accept All
</Button>

View File

@ -1,13 +1,15 @@
// @flow
import React, { useState } from 'react'
import Tooltip from '@material-ui/core/Tooltip'
import { makeStyles } from '@material-ui/core/styles'
import cn from 'classnames'
import Img from '~/components/layout/Img'
import { copyToClipboard } from '~/utils/clipboard'
import { xs } from '~/theme/variables'
import React, { useState } from 'react'
import CopyIcon from './copy.svg'
import Img from '~/components/layout/Img'
import { xs } from '~/theme/variables'
import { copyToClipboard } from '~/utils/clipboard'
const useStyles = makeStyles({
container: {
display: 'flex',
@ -39,8 +41,7 @@ const CopyBtn = ({ className, content, increaseZindex = false }: CopyBtnProps) =
return (
<Tooltip
title={clicked ? 'Copied' : 'Copy to clipboard'}
placement="top"
classes={customClasses}
onClose={() => {
// this is fired before tooltip is closed
// added setTimeout so the user doesn't see the text changing/jumping
@ -50,17 +51,18 @@ const CopyBtn = ({ className, content, increaseZindex = false }: CopyBtnProps) =
}
}, 300)
}}
classes={customClasses}
placement="top"
title={clicked ? 'Copied' : 'Copy to clipboard'}
>
<div className={cn(classes.container, className)}>
<Img
src={CopyIcon}
height={20}
alt="Copy to clipboard"
height={20}
onClick={() => {
copyToClipboard(content)
setClicked(true)
}}
src={CopyIcon}
/>
</div>
</Tooltip>

View File

@ -1,10 +1,12 @@
// @flow
import React from 'react'
import Tooltip from '@material-ui/core/Tooltip'
import { makeStyles } from '@material-ui/core/styles'
import cn from 'classnames'
import Img from '~/components/layout/Img'
import React from 'react'
import EtherscanOpenIcon from './img/etherscan-open.svg'
import Img from '~/components/layout/Img'
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import { xs } from '~/theme/variables'
@ -33,12 +35,12 @@ type EtherscanBtnProps = {
value: string,
}
const EtherscanBtn = ({ type, value, className, increaseZindex = false }: EtherscanBtnProps) => {
const EtherscanBtn = ({ className, increaseZindex = false, type, value }: EtherscanBtnProps) => {
const classes = useStyles()
const customClasses = increaseZindex ? { popper: classes.increasedPopperZindex } : {}
return (
<Tooltip title="Show details on Etherscan" placement="top" classes={customClasses}>
<Tooltip classes={customClasses} placement="top" title="Show details on Etherscan">
<a
aria-label="Show details on Etherscan"
className={cn(classes.container, className)}
@ -46,7 +48,7 @@ const EtherscanBtn = ({ type, value, className, increaseZindex = false }: Ethers
rel="noopener noreferrer"
target="_blank"
>
<Img src={EtherscanOpenIcon} height={20} alt="Show on Etherscan" />
<Img alt="Show on Etherscan" height={20} src={EtherscanOpenIcon} />
</a>
</Tooltip>
)

View File

@ -1,14 +1,16 @@
// @flow
import React from 'react'
import { withStyles } from '@material-ui/core/styles'
import cn from 'classnames'
import Block from '~/components/layout/Block'
import React from 'react'
import { styles } from './style.js'
import CopyBtn from '~/components/CopyBtn'
import EtherscanBtn from '~/components/EtherscanBtn'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { styles } from './style.js'
import EllipsisTransactionDetails from '~/routes/safe/components/AddressBook/EllipsisTransactionDetails'
import Block from '~/components/layout/Block'
import Span from '~/components/layout/Span'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import EllipsisTransactionDetails from '~/routes/safe/components/AddressBook/EllipsisTransactionDetails'
type EtherscanLinkProps = {
classes: Object,
@ -18,14 +20,14 @@ type EtherscanLinkProps = {
value: string,
}
const EtherscanLink = ({ type, value, cut, classes, knownAddress }: EtherscanLinkProps) => (
const EtherscanLink = ({ classes, cut, knownAddress, type, value }: EtherscanLinkProps) => (
<Block className={classes.etherscanLink}>
<Span className={cn(knownAddress && classes.addressParagraph, classes.address)} size="md">
{cut ? shortVersionOf(value, cut) : value}
</Span>
<CopyBtn className={cn(classes.button, classes.firstButton)} content={value} />
<EtherscanBtn className={classes.button} type={type} value={value} />
{knownAddress !== undefined ? <EllipsisTransactionDetails knownAddress={knownAddress} address={value} /> : null}
{knownAddress !== undefined ? <EllipsisTransactionDetails address={value} knownAddress={knownAddress} /> : null}
</Block>
)

View File

@ -1,12 +1,13 @@
// @flow
import * as React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch } from 'react-redux'
import cn from 'classnames'
import Link from '~/components/layout/Link'
import { secondary, screenSm, sm } from '~/theme/variables'
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
import * as React from 'react'
import { useDispatch } from 'react-redux'
import GnoButtonLink from '~/components/layout/ButtonLink'
import Link from '~/components/layout/Link'
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
import { screenSm, secondary, sm } from '~/theme/variables'
const useStyles = makeStyles({
footer: {
@ -57,23 +58,23 @@ const Footer = () => {
<footer className={classes.footer}>
<span className={classes.item}>©{date.getFullYear()} Gnosis</span>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/terms" target="_blank">
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/terms">
Terms
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/privacy" target="_blank">
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/privacy">
Privacy
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/licenses" target="_blank">
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/licenses">
Licenses
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/imprint" target="_blank">
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/imprint">
Imprint
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/cookie" target="_blank">
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/cookie">
Cookie Policy
</Link>
<span className={classes.sep}>-</span>
@ -83,8 +84,8 @@ const Footer = () => {
<span className={classes.sep}>|</span>
<Link
className={cn(classes.item, classes.link)}
to="https://github.com/gnosis/safe-react/releases"
target="_blank"
to="https://github.com/gnosis/safe-react/releases"
>
{appVersion}
</Link>

View File

@ -1,10 +1,11 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord'
import * as React from 'react'
import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img'
import { fancy, border, warning, screenSm } from '~/theme/variables'
import { border, fancy, screenSm, warning } from '~/theme/variables'
const key = require('../assets/key.svg')
const triangle = require('../assets/triangle.svg')
@ -64,15 +65,15 @@ const buildDotStyleFrom = (size: number, top: number, right: number, mode: Mode)
})
const KeyRing = ({
classes,
center = false,
circleSize,
keySize,
classes,
dotRight,
dotSize,
dotTop,
dotRight,
mode,
center = false,
hideDot = false,
keySize,
mode,
}: Props) => {
const keyStyle = buildKeyStyleFrom(circleSize, center, dotSize)
const dotStyle = buildDotStyleFrom(dotSize, dotTop, dotRight, mode)
@ -84,11 +85,11 @@ const KeyRing = ({
<Block className={classes.root}>
<Block className={classes.key} style={keyStyle}>
<Img
src={img}
height={keySize}
width={isWarning ? keySize + 2 : keySize}
alt="Status connection"
className={isWarning ? classes.warning : undefined}
height={keySize}
src={img}
width={isWarning ? keySize + 2 : keySize}
/>
</Block>
{!hideDot && <Dot className={classes.dot} style={dotStyle} />}

View File

@ -1,21 +1,23 @@
// @flow
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Grow from '@material-ui/core/Grow'
import List from '@material-ui/core/List'
import Popper from '@material-ui/core/Popper'
import { withStyles } from '@material-ui/core/styles'
import * as React from 'react'
import { Link } from 'react-router-dom'
import { withStyles } from '@material-ui/core/styles'
import Grow from '@material-ui/core/Grow'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Popper from '@material-ui/core/Popper'
import List from '@material-ui/core/List'
import Divider from '~/components/layout/Divider'
import NetworkLabel from './NetworkLabel'
import Provider from './Provider'
import SafeListHeader from './SafeListHeader'
import Spacer from '~/components/Spacer'
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
import Col from '~/components/layout/Col'
import Divider from '~/components/layout/Divider'
import Img from '~/components/layout/Img'
import Row from '~/components/layout/Row'
import Spacer from '~/components/Spacer'
import { border, sm, md, headerHeight, screenSm } from '~/theme/variables'
import Provider from './Provider'
import NetworkLabel from './NetworkLabel'
import SafeListHeader from './SafeListHeader'
import { border, headerHeight, md, screenSm, sm } from '~/theme/variables'
const logo = require('../assets/gnosis-safe-multisig-logo.svg')
@ -62,11 +64,11 @@ const styles = () => ({
},
})
const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, providerDetails }: Props) => (
const Layout = openHoc(({ classes, clickAway, open, providerDetails, providerInfo, toggle }: Props) => (
<Row className={classes.summary}>
<Col start="xs" middle="xs" className={classes.logo}>
<Col className={classes.logo} middle="xs" start="xs">
<Link to="/">
<Img src={logo} height={32} alt="Gnosis Team Safe" />
<Img alt="Gnosis Team Safe" height={32} src={logo} />
</Link>
</Col>
<Divider />
@ -74,7 +76,7 @@ const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, provid
<Divider />
<NetworkLabel />
<Spacer />
<Provider open={open} toggle={toggle} info={providerInfo}>
<Provider info={providerInfo} open={open} toggle={toggle}>
{providerRef => (
<Popper
anchorEl={providerRef.current}
@ -86,7 +88,7 @@ const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, provid
{({ TransitionProps }) => (
<Grow {...TransitionProps}>
<>
<ClickAwayListener onClickAway={clickAway} mouseEvent="onClick" touchEvent={false}>
<ClickAwayListener mouseEvent="onClick" onClickAway={clickAway} touchEvent={false}>
<List className={classes.root} component="div">
{providerDetails}
</List>

View File

@ -1,10 +1,11 @@
// @flow
import * as React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { getNetwork } from '~/config'
import Paragraph from '~/components/layout/Paragraph'
import * as React from 'react'
import Col from '~/components/layout/Col'
import { xs, sm, md, border, screenSm } from '~/theme/variables'
import Paragraph from '~/components/layout/Paragraph'
import { getNetwork } from '~/config'
import { border, md, screenSm, sm, xs } from '~/theme/variables'
const network = getNetwork()
const formattedNetwork = network[0].toUpperCase() + network.substring(1).toLowerCase()
@ -35,8 +36,8 @@ const EarlyAccessLabel = () => {
const classes = useStyles()
return (
<Col start="xs" middle="xs" className={classes.container}>
<Paragraph size="xs" className={classes.text}>
<Col className={classes.container} middle="xs" start="xs">
<Paragraph className={classes.text} size="xs">
{formattedNetwork}
</Paragraph>
</Col>

View File

@ -1,13 +1,14 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import * as React from 'react'
import { type Open } from '~/components/hoc/OpenHoc'
import Col from '~/components/layout/Col'
import Divider from '~/components/layout/Divider'
import { type Open } from '~/components/hoc/OpenHoc'
import { sm, md, screenSm } from '~/theme/variables'
import { md, screenSm, sm } from '~/theme/variables'
type Props = Open & {
classes: Object,
@ -56,15 +57,15 @@ class Provider extends React.Component<Props> {
}
render() {
const { open, toggle, children, classes, info } = this.props
const { children, classes, info, open, toggle } = this.props
return (
<>
<div ref={this.myRef} className={classes.root}>
<div className={classes.root} ref={this.myRef}>
<Divider />
<Col end="sm" middle="xs" className={classes.provider} onClick={toggle}>
<Col className={classes.provider} end="sm" middle="xs" onClick={toggle}>
{info}
<IconButton disableRipple className={classes.expand}>
<IconButton className={classes.expand} disableRipple>
{open ? <ExpandLess /> : <ExpandMore />}
</IconButton>
</Col>

View File

@ -1,12 +1,13 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Paragraph from '~/components/layout/Paragraph'
import * as React from 'react'
import ConnectButton from '~/components/ConnectButton'
import Row from '~/components/layout/Row'
import Block from '~/components/layout/Block'
import { md, lg } from '~/theme/variables'
import CircleDot from '~/components/Header/components/CircleDot'
import Block from '~/components/layout/Block'
import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row'
import { lg, md } from '~/theme/variables'
type Props = {
classes: Object,
@ -39,14 +40,14 @@ const styles = () => ({
const ConnectDetails = ({ classes }: Props) => (
<>
<div className={classes.container}>
<Row margin="lg" align="center">
<Paragraph className={classes.text} size="lg" noMargin weight="bolder">
<Row align="center" margin="lg">
<Paragraph className={classes.text} noMargin size="lg" weight="bolder">
Connect a Wallet
</Paragraph>
</Row>
</div>
<Row className={classes.logo} margin="lg">
<CircleDot keySize={32} circleSize={75} dotSize={25} dotTop={50} dotRight={25} center mode="error" />
<CircleDot center circleSize={75} dotRight={25} dotSize={25} dotTop={50} keySize={32} mode="error" />
</Row>
<Block className={classes.connect}>
<ConnectButton />

View File

@ -1,25 +1,26 @@
// @flow
import * as React from 'react'
import classNames from 'classnames'
import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord'
import EtherscanBtn from '~/components/EtherscanBtn'
import classNames from 'classnames'
import * as React from 'react'
import CopyBtn from '~/components/CopyBtn'
import Paragraph from '~/components/layout/Paragraph'
import Button from '~/components/layout/Button'
import EtherscanBtn from '~/components/EtherscanBtn'
import CircleDot from '~/components/Header/components/CircleDot'
import Identicon from '~/components/Identicon'
import Spacer from '~/components/Spacer'
import Block from '~/components/layout/Block'
import Button from '~/components/layout/Button'
import Hairline from '~/components/layout/Hairline'
import Img from '~/components/layout/Img'
import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row'
import Block from '~/components/layout/Block'
import Spacer from '~/components/Spacer'
import { xs, sm, md, lg, background, warning, connected as connectedBg } from '~/theme/variables'
import { upperFirst } from '~/utils/css'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import CircleDot from '~/components/Header/components/CircleDot'
import { background, connected as connectedBg, lg, md, sm, warning, xs } from '~/theme/variables'
import { upperFirst } from '~/utils/css'
const walletIcon = require('../../assets/wallet.svg')
const dot = require('../../assets/dotRinkeby.svg')
const walletIcon = require('../../assets/wallet.svg')
type Props = {
provider: string,
@ -91,7 +92,7 @@ const styles = () => ({
},
})
const UserDetails = ({ provider, connected, network, userAddress, classes, onDisconnect }: Props) => {
const UserDetails = ({ classes, connected, network, onDisconnect, provider, userAddress }: Props) => {
const status = connected ? 'Connected' : 'Connection error'
const address = userAddress ? shortVersionOf(userAddress, 4) : 'Address not available'
const identiconAddress = userAddress || 'random'
@ -100,62 +101,62 @@ const UserDetails = ({ provider, connected, network, userAddress, classes, onDis
return (
<>
<Block className={classes.container}>
<Row className={classes.identicon} margin="md" align="center">
<Row align="center" className={classes.identicon} margin="md">
{connected ? (
<Identicon address={identiconAddress} diameter={60} />
) : (
<CircleDot keySize={30} circleSize={75} dotSize={25} dotTop={50} dotRight={25} mode="warning" hideDot />
<CircleDot circleSize={75} dotRight={25} dotSize={25} dotTop={50} hideDot keySize={30} mode="warning" />
)}
</Row>
<Block justify="center" className={classes.user}>
<Paragraph className={classes.address} size="sm" noMargin>
<Block className={classes.user} justify="center">
<Paragraph className={classes.address} noMargin size="sm">
{address}
</Paragraph>
{userAddress && (
<>
<CopyBtn content={userAddress} increaseZindex />
<EtherscanBtn type="address" value={userAddress} increaseZindex />
<EtherscanBtn increaseZindex type="address" value={userAddress} />
</>
)}
</Block>
</Block>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>
<Paragraph align="right" className={classes.labels} noMargin>
Status
</Paragraph>
<Spacer />
<Dot className={classNames(classes.dot, connected ? classes.connected : classes.warning)} />
<Paragraph noMargin align="right" color={color} weight="bolder" className={classes.labels}>
<Paragraph align="right" className={classes.labels} color={color} noMargin weight="bolder">
{status}
</Paragraph>
</Row>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>
<Paragraph align="right" className={classes.labels} noMargin>
Wallet
</Paragraph>
<Spacer />
<Img className={classes.logo} src={walletIcon} height={14} alt="Wallet icon" />
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
<Img alt="Wallet icon" className={classes.logo} height={14} src={walletIcon} />
<Paragraph align="right" className={classes.labels} noMargin weight="bolder">
{upperFirst(provider)}
</Paragraph>
</Row>
<Hairline margin="xs" />
<Row className={classes.details}>
<Paragraph noMargin align="right" className={classes.labels}>
<Paragraph align="right" className={classes.labels} noMargin>
Network
</Paragraph>
<Spacer />
<Img className={classes.logo} src={dot} height={14} alt="Network" />
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
<Img alt="Network" className={classes.logo} height={14} src={dot} />
<Paragraph align="right" className={classes.labels} noMargin weight="bolder">
{upperFirst(network)}
</Paragraph>
</Row>
<Hairline margin="xs" />
<Row className={classes.disconnect}>
<Button onClick={onDisconnect} size="medium" variant="contained" color="primary" fullWidth>
<Paragraph className={classes.disconnectText} size="md" color="white" noMargin>
<Button color="primary" fullWidth onClick={onDisconnect} size="medium" variant="contained">
<Paragraph className={classes.disconnectText} color="white" noMargin size="md">
Disconnect
</Paragraph>
</Button>

View File

@ -1,13 +1,14 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord'
import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col'
import { screenSm, connected as connectedBg, sm } from '~/theme/variables'
import Identicon from '~/components/Identicon'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import * as React from 'react'
import CircleDot from '~/components/Header/components/CircleDot'
import Identicon from '~/components/Identicon'
import Col from '~/components/layout/Col'
import Paragraph from '~/components/layout/Paragraph'
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { connected as connectedBg, screenSm, sm } from '~/theme/variables'
type Props = {
provider: string,
@ -54,7 +55,7 @@ const styles = () => ({
},
})
const ProviderInfo = ({ provider, network, userAddress, connected, classes }: Props) => {
const ProviderInfo = ({ classes, connected, network, provider, userAddress }: Props) => {
const providerText = `${provider} [${network}]`
const cutAddress = connected ? shortVersionOf(userAddress, 4) : 'Connection Error'
const color = connected ? 'primary' : 'warning'
@ -64,16 +65,16 @@ const ProviderInfo = ({ provider, network, userAddress, connected, classes }: Pr
<>
{connected && (
<>
<Identicon className={classes.identicon} address={identiconAddress} diameter={30} />
<Identicon address={identiconAddress} className={classes.identicon} diameter={30} />
<Dot className={classes.dot} />
</>
)}
{!connected && <CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />}
<Col start="sm" layout="column" className={classes.account}>
<Paragraph size="xs" transform="capitalize" className={classes.network} noMargin weight="bolder">
{!connected && <CircleDot circleSize={35} dotRight={11} dotSize={16} dotTop={24} keySize={14} mode="warning" />}
<Col className={classes.account} layout="column" start="sm">
<Paragraph className={classes.network} noMargin size="xs" transform="capitalize" weight="bolder">
{providerText}
</Paragraph>
<Paragraph size="xs" className={classes.address} noMargin color={color}>
<Paragraph className={classes.address} color={color} noMargin size="xs">
{cutAddress}
</Paragraph>
</Col>

View File

@ -1,11 +1,12 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col'
import { type Open } from '~/components/hoc/OpenHoc'
import { sm } from '~/theme/variables'
import * as React from 'react'
import CircleDot from '~/components/Header/components/CircleDot'
import { type Open } from '~/components/hoc/OpenHoc'
import Col from '~/components/layout/Col'
import Paragraph from '~/components/layout/Paragraph'
import { sm } from '~/theme/variables'
type Props = Open & {
classes: Object,
@ -32,12 +33,12 @@ const styles = () => ({
const ProviderDisconnected = ({ classes }: Props) => (
<>
<CircleDot keySize={17} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="error" />
<Col end="sm" middle="xs" layout="column" className={classes.account}>
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bold">
<CircleDot circleSize={35} dotRight={11} dotSize={16} dotTop={24} keySize={17} mode="error" />
<Col className={classes.account} end="sm" layout="column" middle="xs">
<Paragraph className={classes.network} noMargin size="sm" transform="capitalize" weight="bold">
Not Connected
</Paragraph>
<Paragraph size="sm" color="fancy" className={classes.connect} noMargin>
<Paragraph className={classes.connect} color="fancy" noMargin size="sm">
Connect Wallet
</Paragraph>
</Col>

View File

@ -1,15 +1,16 @@
// @flow
import IconButton from '@material-ui/core/IconButton'
import { makeStyles } from '@material-ui/core/styles'
import ExpandLessIcon from '@material-ui/icons/ExpandLess'
import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
import * as React from 'react'
import { connect } from 'react-redux'
import { makeStyles } from '@material-ui/core/styles'
import IconButton from '@material-ui/core/IconButton'
import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
import ExpandLessIcon from '@material-ui/icons/ExpandLess'
import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col'
import { xs, sm, md, border, screenSm } from '~/theme/variables'
import { safesCountSelector } from '~/routes/safe/store/selectors'
import { SidebarContext } from '~/components/Sidebar'
import Col from '~/components/layout/Col'
import Paragraph from '~/components/layout/Paragraph'
import { safesCountSelector } from '~/routes/safe/store/selectors'
import { border, md, screenSm, sm, xs } from '~/theme/variables'
export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN'
@ -42,19 +43,19 @@ const { useContext } = React
const SafeListHeader = ({ safesCount }: Props) => {
const classes = useStyles()
const { toggleSidebar, isOpen } = useContext(SidebarContext)
const { isOpen, toggleSidebar } = useContext(SidebarContext)
return (
<Col start="xs" middle="xs" className={classes.container}>
<Col className={classes.container} middle="xs" start="xs">
Safes
<Paragraph size="xs" className={classes.counter}>
<Paragraph className={classes.counter} size="xs">
{safesCount}
</Paragraph>
<IconButton
onClick={toggleSidebar}
className={classes.icon}
aria-label="Expand Safe List"
className={classes.icon}
data-testid={TOGGLE_SIDEBAR_BTN_TESTID}
onClick={toggleSidebar}
>
{isOpen ? <ExpandLessIcon /> : <ExpandMoreIcon color="secondary" />}
</IconButton>

View File

@ -1,19 +1,21 @@
// @flow
import { withSnackbar } from 'notistack'
import * as React from 'react'
import { connect } from 'react-redux'
import { withSnackbar } from 'notistack'
import { logComponentStack, type Info } from '~/utils/logBoundaries'
import actions, { type Actions } from './actions'
import Layout from './components/Layout'
import ConnectDetails from './components/ProviderDetails/ConnectDetails'
import UserDetails from './components/ProviderDetails/UserDetails'
import ProviderAccessible from './components/ProviderInfo/ProviderAccessible'
import ProviderDisconnected from './components/ProviderInfo/ProviderDisconnected'
import selector, { type SelectorProps } from './selector'
import { onboard } from '~/components/ConnectButton'
import { NOTIFICATIONS, showSnackbar } from '~/logic/notifications'
import { web3Connect } from '~/components/ConnectButton'
import { INJECTED_PROVIDERS } from '~/logic/wallets/getWeb3'
import { loadLastUsedProvider } from '~/logic/wallets/store/middlewares/providerWatcher'
import ProviderAccessible from './components/ProviderInfo/ProviderAccessible'
import UserDetails from './components/ProviderDetails/UserDetails'
import ProviderDisconnected from './components/ProviderInfo/ProviderDisconnected'
import ConnectDetails from './components/ProviderDetails/ConnectDetails'
import Layout from './components/Layout'
import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector'
import { type Info, logComponentStack } from '~/utils/logBoundaries'
type Props = Actions &
SelectorProps & {
@ -36,13 +38,16 @@ class HeaderComponent extends React.PureComponent<Props, State> {
async componentDidMount() {
const lastUsedProvider = await loadLastUsedProvider()
if (INJECTED_PROVIDERS.includes(lastUsedProvider) || process.env.NODE_ENV === 'test') {
web3Connect.connectToInjected()
if (INJECTED_PROVIDERS.includes(lastUsedProvider.toUpperCase()) || process.env.NODE_ENV === 'test') {
const hasSelectedWallet = await onboard.walletSelect(lastUsedProvider)
if (hasSelectedWallet) {
await onboard.walletCheck()
}
}
}
componentDidCatch(error: Error, info: Info) {
const { enqueueSnackbar, closeSnackbar } = this.props
const { closeSnackbar, enqueueSnackbar } = this.props
this.setState({ hasError: true })
showSnackbar(NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG, enqueueSnackbar, closeSnackbar)
@ -51,25 +56,25 @@ class HeaderComponent extends React.PureComponent<Props, State> {
}
onDisconnect = () => {
const { removeProvider, enqueueSnackbar, closeSnackbar } = this.props
const { closeSnackbar, enqueueSnackbar, removeProvider } = this.props
removeProvider(enqueueSnackbar, closeSnackbar)
}
getProviderInfoBased = () => {
const { hasError } = this.state
const { loaded, available, provider, network, userAddress } = this.props
const { available, loaded, network, provider, userAddress } = this.props
if (hasError || !loaded) {
return <ProviderDisconnected />
}
return <ProviderAccessible provider={provider} network={network} userAddress={userAddress} connected={available} />
return <ProviderAccessible connected={available} network={network} provider={provider} userAddress={userAddress} />
}
getProviderDetailsBased = () => {
const { hasError } = this.state
const { loaded, available, provider, network, userAddress } = this.props
const { available, loaded, network, provider, userAddress } = this.props
if (hasError || !loaded) {
return <ConnectDetails />
@ -90,7 +95,7 @@ class HeaderComponent extends React.PureComponent<Props, State> {
const info = this.getProviderInfoBased()
const details = this.getProviderDetailsBased()
return <Layout providerInfo={info} providerDetails={details} />
return <Layout providerDetails={details} providerInfo={info} />
}
}

View File

@ -1,11 +1,12 @@
// @flow
import { createStructuredSelector } from 'reselect'
import {
providerNameSelector,
userAccountSelector,
networkSelector,
availableSelector,
loadedSelector,
networkSelector,
providerNameSelector,
userAccountSelector,
} from '~/logic/wallets/store/selectors'
export type SelectorProps = {

View File

@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import { toDataUrl } from './blockies'
type Props = {
@ -63,9 +64,9 @@ export default class Identicon extends React.PureComponent<Props> {
}
render() {
const { diameter, className } = this.props
const { className, diameter } = this.props
const style = this.getStyleFrom(diameter)
return <div className={className} style={style} ref={this.identicon} />
return <div className={className} ref={this.identicon} style={style} />
}
}

View File

@ -1,7 +1,8 @@
// @flow
import * as React from 'react'
import MuiListItemText from '@material-ui/core/ListItemText'
import { withStyles } from '@material-ui/core/styles'
import * as React from 'react'
import { type WithStyles } from '~/theme/mui'
type Props = WithStyles & {
@ -20,7 +21,7 @@ const styles = {
class ListItemText extends React.PureComponent<Props> {
render() {
const { primary, secondary, classes, cut = false } = this.props
const { classes, cut = false, primary, secondary } = this.props
const cutStyle = cut
? {

View File

@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import * as React from 'react'
import Page from '~/components/layout/Page'
const centerStyle = {
@ -9,7 +10,7 @@ const centerStyle = {
const Loader = () => (
<Page align="center">
<CircularProgress style={centerStyle} size={60} />
<CircularProgress size={60} style={centerStyle} />
</Page>
)

View File

@ -1,8 +1,9 @@
// @flow
import * as React from 'react'
import cn from 'classnames'
import Modal from '@material-ui/core/Modal'
import { withStyles } from '@material-ui/core/styles'
import cn from 'classnames'
import * as React from 'react'
import { sm } from '~/theme/variables'
type Props = {
@ -40,21 +41,21 @@ const styles = () => ({
})
const GnoModal = ({
title,
description,
open,
children,
classes,
description,
handleClose,
modalClassName,
classes,
open,
paperClassName,
title,
}: Props) => (
<Modal
aria-labelledby={title}
aria-describedby={description}
open={open}
onClose={handleClose}
aria-labelledby={title}
className={cn(classes.root, modalClassName)}
onClose={handleClose}
open={open}
>
<div className={cn(classes.paper, paperClassName)}>{children}</div>
</Modal>

View File

@ -1,9 +1,10 @@
// @flow
import * as React from 'react'
import Bold from '~/components/layout/Bold'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import Paragraph from '~/components/layout/Paragraph/index'
import Row from '~/components/layout/Row'
import { CreateSafe } from '~/routes/welcome/components/Layout'
type Props = {
@ -11,14 +12,14 @@ type Props = {
provider: string,
}
const NoSafe = ({ text, provider }: Props) => (
const NoSafe = ({ provider, text }: Props) => (
<Row>
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
<Col center="xs" margin="md" sm={10} smOffset={2} start="sm" xs={12}>
<Paragraph size="lg">
<Bold>{text}</Bold>
</Paragraph>
</Col>
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
<Col center="xs" margin="md" sm={10} smOffset={2} start="sm" xs={12}>
<CreateSafe provider={provider} />
</Col>
</Row>

View File

@ -1,12 +1,14 @@
// @flow
import { Component } from 'react'
import { List } from 'immutable'
import { connect } from 'react-redux'
import { withSnackbar } from 'notistack'
import { type Notification } from '~/logic/notifications/store/models/notification'
import { Component } from 'react'
import { connect } from 'react-redux'
import actions, { type Actions } from './actions'
import selector from './selector'
import { type Notification } from '~/logic/notifications/store/models/notification'
type Props = Actions & {
notifications: List<Notification>,
closeSnackbar: Function,
@ -17,7 +19,7 @@ class Notifier extends Component<Props> {
displayed = []
shouldComponentUpdate({ notifications: newSnacks = List() }) {
const { notifications: currentSnacks, closeSnackbar, removeSnackbar } = this.props
const { closeSnackbar, notifications: currentSnacks, removeSnackbar } = this.props
if (!newSnacks.size) {
this.displayed = []

View File

@ -1,5 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { notificationsListSelector } from '~/logic/notifications/store/selectors'
export default createStructuredSelector<Object, *>({

View File

@ -0,0 +1,6 @@
/* Onboard.js custom styles */
:global(.bn-onboard-custom.bn-onboard-modal) {
font-family: "Averta";
z-index: 2001;
}

View File

@ -2,17 +2,20 @@
import 'babel-polyfill'
import { MuiThemeProvider } from '@material-ui/core/styles'
import React, { Suspense } from 'react'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router'
import React, { Suspense } from 'react'
import { hot } from 'react-hot-loader/root'
import PageFrame from '../layout/PageFrame'
import { Provider } from 'react-redux'
import Loader from '../Loader'
import PageFrame from '../layout/PageFrame'
import AppRoutes from '~/routes'
import { history, store } from '~/store'
import theme from '~/theme/mui'
import AppRoutes from '~/routes'
import './index.scss'
import './OnboardCustom.scss'
const Root = () => (
<Provider store={store}>

View File

@ -1,19 +1,21 @@
// @flow
import * as React from 'react'
import QrReader from 'react-qr-reader'
import CircularProgress from '@material-ui/core/CircularProgress'
import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close'
import IconButton from '@material-ui/core/IconButton'
import CircularProgress from '@material-ui/core/CircularProgress'
import Paragraph from '~/components/layout/Paragraph'
import Button from '~/components/layout/Button'
import Block from '~/components/layout/Block'
import Row from '~/components/layout/Row'
import Hairline from '~/components/layout/Hairline'
import Col from '~/components/layout/Col'
import Modal from '~/components/Modal'
import { checkWebcam } from './utils'
import * as React from 'react'
import QrReader from 'react-qr-reader'
import { styles } from './style'
import { checkWebcam } from './utils'
import Modal from '~/components/Modal'
import Block from '~/components/layout/Block'
import Button from '~/components/layout/Button'
import Col from '~/components/layout/Col'
import Hairline from '~/components/layout/Hairline'
import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row'
const { useEffect, useState } = React
@ -24,7 +26,7 @@ type Props = {
isOpen: boolean,
}
const ScanQRModal = ({ classes, onClose, isOpen, onScan }: Props) => {
const ScanQRModal = ({ classes, isOpen, onClose, onScan }: Props) => {
const [hasWebcam, setHasWebcam] = useState(null)
const scannerRef: Object = React.createRef()
const openImageDialog = () => {
@ -52,43 +54,43 @@ const ScanQRModal = ({ classes, onClose, isOpen, onScan }: Props) => {
}, [hasWebcam])
return (
<Modal title="Receive Tokens" description="Receive Tokens Form" handleClose={onClose} open={isOpen}>
<Row align="center" grow className={classes.heading}>
<Paragraph size="xl" noMargin>
<Modal description="Receive Tokens Form" handleClose={onClose} open={isOpen} title="Receive Tokens">
<Row align="center" className={classes.heading} grow>
<Paragraph noMargin size="xl">
Scan QR
</Paragraph>
<IconButton onClick={onClose} disableRipple>
<IconButton disableRipple onClick={onClose}>
<Close className={classes.close} />
</IconButton>
</Row>
<Hairline />
<Col layout="column" middle="xs" className={classes.detailsContainer}>
<Col className={classes.detailsContainer} layout="column" middle="xs">
{hasWebcam === null ? (
<Block justify="center" className={classes.loaderContainer}>
<Block className={classes.loaderContainer} justify="center">
<CircularProgress />
</Block>
) : (
<QrReader
ref={scannerRef}
legacyMode={!hasWebcam}
onScan={data => {
if (data) onScan(data)
}}
onError={err => {
console.error(err)
}}
onScan={data => {
if (data) onScan(data)
}}
ref={scannerRef}
style={{ width: '400px', height: '400px' }}
/>
)}
</Col>
<Hairline />
<Row align="center" className={classes.buttonRow}>
<Button color="secondary" className={classes.button} minWidth={154} onClick={onClose}>
<Button className={classes.button} color="secondary" minWidth={154} onClick={onClose}>
Close
</Button>
<Button
color="primary"
className={classes.button}
color="primary"
minWidth={154}
onClick={() => {
if (hasWebcam) {

View File

@ -1,5 +1,5 @@
// @flow
import { lg, sm, background, secondaryText } from '~/theme/variables'
import { background, lg, secondaryText, sm } from '~/theme/variables'
export const styles = () => ({
heading: {

View File

@ -1,11 +1,12 @@
// @flow
import * as React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import Img from '~/components/layout/Img'
import Block from '~/components/layout/Block'
import Paragraph from '~/components/layout/Paragraph'
import { primary, secondaryBackground, md } from '~/theme/variables'
import * as React from 'react'
import HomeIcon from '~/assets/icons/shape.svg'
import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img'
import Paragraph from '~/components/layout/Paragraph'
import { md, primary, secondaryBackground } from '~/theme/variables'
const useStyles = makeStyles({
container: {
@ -27,9 +28,9 @@ const DefaultBadge = () => {
const classes = useStyles()
return (
<Block justify="left" className={classes.container}>
<Img src={HomeIcon} alt="Home Icon" />
<Paragraph noMargin size="xs" className={classes.defaultText}>
<Block className={classes.container} justify="left">
<Img alt="Home Icon" src={HomeIcon} />
<Paragraph className={classes.defaultText} noMargin size="xs">
Default
</Paragraph>
</Block>

View File

@ -1,24 +1,26 @@
// @flow
import * as React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { List } from 'immutable'
import MuiList from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import ListItemText from '@material-ui/core/ListItemText'
import Link from '~/components/layout/Link'
import Hairline from '~/components/layout/Hairline'
import Paragraph from '~/components/layout/Paragraph'
import ButtonLink from '~/components/layout/ButtonLink'
import Identicon from '~/components/Identicon'
import { mediumFontSize, sm, primary, disabled, md } from '~/theme/variables'
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import { shortVersionOf, sameAddress } from '~/logic/wallets/ethAddresses'
import { type Safe } from '~/routes/safe/store/models/safe'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import { makeStyles } from '@material-ui/core/styles'
import { List } from 'immutable'
import * as React from 'react'
import DefaultBadge from './DefaultBadge'
import Img from '~/components/layout/Img'
import check from '~/assets/icons/check.svg'
import Identicon from '~/components/Identicon'
import ButtonLink from '~/components/layout/ButtonLink'
import Hairline from '~/components/layout/Hairline'
import Img from '~/components/layout/Img'
import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph'
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import { sameAddress, shortVersionOf } from '~/logic/wallets/ethAddresses'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import { type Safe } from '~/routes/safe/store/models/safe'
import { disabled, md, mediumFontSize, primary, sm } from '~/theme/variables'
export const SIDEBAR_SAFELIST_ROW_TESTID = 'SIDEBAR_SAFELIST_ROW_TESTID'
@ -38,10 +40,10 @@ const useStyles = makeStyles({
marginRight: '10px',
},
list: {
overflow: 'hidden',
overflowY: 'hidden',
padding: 0,
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
padding: 0,
},
listItemRoot: {
paddingTop: 0,
@ -72,7 +74,7 @@ const useStyles = makeStyles({
},
})
const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe }: SafeListProps) => {
const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe }: SafeListProps) => {
const classes = useStyles()
return (
@ -80,30 +82,30 @@ const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe
{safes.map(safe => (
<React.Fragment key={safe.address}>
<Link
to={`${SAFELIST_ADDRESS}/${safe.address}/balances`}
onClick={onSafeClick}
data-testid={SIDEBAR_SAFELIST_ROW_TESTID}
onClick={onSafeClick}
to={`${SAFELIST_ADDRESS}/${safe.address}/balances`}
>
<ListItem classes={{ root: classes.listItemRoot }}>
{sameAddress(currentSafe, safe.address) ? (
<ListItemIcon>
<Img src={check} alt="check" className={classes.checkIcon} />
<Img alt="check" className={classes.checkIcon} src={check} />
</ListItemIcon>
) : (
<div className={classes.noIcon}>placeholder</div>
)}
<ListItemIcon>
<Identicon address={safe.address} diameter={32} className={classes.icon} />
<Identicon address={safe.address} className={classes.icon} diameter={32} />
</ListItemIcon>
<ListItemText
primary={safe.name}
secondary={shortVersionOf(safe.address, 4)}
classes={{
primary: classes.safeName,
secondary: classes.safeAddress,
}}
primary={safe.name}
secondary={shortVersionOf(safe.address, 4)}
/>
<Paragraph size="lg" color="primary">
<Paragraph color="primary" size="lg">
{`${formatAmount(safe.ethBalance)} ETH`}
</Paragraph>
{sameAddress(defaultSafe, safe.address) ? (
@ -111,13 +113,13 @@ const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe
) : (
<ButtonLink
className={classes.makeDefaultBtn}
size="sm"
onClick={e => {
e.preventDefault()
e.stopPropagation()
setDefaultSafe(safe.address)
}}
size="sm"
>
Make default
</ButtonLink>

View File

@ -1,26 +1,28 @@
// @flow
import * as React from 'react'
import { List } from 'immutable'
import SearchBar from 'material-ui-search-bar'
import { connect } from 'react-redux'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Drawer from '@material-ui/core/Drawer'
import SearchIcon from '@material-ui/icons/Search'
import Divider from '~/components/layout/Divider'
import Button from '~/components/layout/Button'
import Link from '~/components/layout/Link'
import Spacer from '~/components/Spacer'
import Hairline from '~/components/layout/Hairline'
import Row from '~/components/layout/Row'
import { WELCOME_ADDRESS } from '~/routes/routes'
import { type Safe } from '~/routes/safe/store/models/safe'
import { defaultSafeSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
import { sortedSafeListSelector } from './selectors'
import { List } from 'immutable'
import SearchBar from 'material-ui-search-bar'
import * as React from 'react'
import { connect } from 'react-redux'
import SafeList from './SafeList'
import { sortedSafeListSelector } from './selectors'
import useSidebarStyles from './style'
const { useState, useEffect, useMemo } = React
import Spacer from '~/components/Spacer'
import Button from '~/components/layout/Button'
import Divider from '~/components/layout/Divider'
import Hairline from '~/components/layout/Hairline'
import Link from '~/components/layout/Link'
import Row from '~/components/layout/Row'
import { WELCOME_ADDRESS } from '~/routes/routes'
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
import { type Safe } from '~/routes/safe/store/models/safe'
import { defaultSafeSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
const { useEffect, useMemo, useState } = React
type TSidebarContext = {
isOpen: boolean,
@ -48,7 +50,7 @@ const filterBy = (filter: string, safes: List<Safe>): List<Safe> =>
safe.name.toLowerCase().includes(filter.toLowerCase()),
)
const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSafe }: SidebarProps) => {
const Sidebar = ({ children, currentSafe, defaultSafe, safes, setDefaultSafeAction }: SidebarProps) => {
const [isOpen, setIsOpen] = useState<boolean>(false)
const [filter, setFilter] = useState<string>('')
const classes = useSidebarStyles()
@ -90,14 +92,14 @@ const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSa
<SidebarContext.Provider value={{ isOpen, toggleSidebar }}>
<ClickAwayListener onClickAway={toggleSidebar}>
<Drawer
ModalProps={{ onBackdropClick: toggleSidebar }}
className={classes.sidebar}
classes={{ paper: classes.sidebarPaper }}
className={classes.sidebar}
ModalProps={{ onBackdropClick: toggleSidebar }}
onKeyDown={handleEsc}
open={isOpen}
>
<Row className={classes.topComponents} align="center">
<Row className={classes.searchWrapper} align="center">
<Row align="center" className={classes.topComponents}>
<Row align="center" className={classes.searchWrapper}>
<SearchIcon className={classes.searchIcon} />
<SearchBar
classes={searchClasses}
@ -125,11 +127,11 @@ const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSa
</Row>
<Hairline />
<SafeList
safes={filteredSafes}
onSafeClick={toggleSidebar}
setDefaultSafe={setDefaultSafeAction}
defaultSafe={defaultSafe}
currentSafe={currentSafe}
defaultSafe={defaultSafe}
onSafeClick={toggleSidebar}
safes={filteredSafes}
setDefaultSafe={setDefaultSafeAction}
/>
</Drawer>
</ClickAwayListener>

View File

@ -1,6 +1,7 @@
// @flow
import { List } from 'immutable'
import { createSelector, type Selector } from 'reselect'
import { type Selector, createSelector } from 'reselect'
import { type Safe } from '~/routes/safe/store/models/safe'
import { safesListSelector } from '~/routes/safe/store/selectors'
import { type GlobalState } from '~/store/index'

View File

@ -1,6 +1,7 @@
// @flow
import { makeStyles } from '@material-ui/core/styles'
import { xs, mediumFontSize, secondaryText, md, headerHeight, screenSm } from '~/theme/variables'
import { headerHeight, md, mediumFontSize, screenSm, secondaryText, xs } from '~/theme/variables'
const sidebarWidth = '400px'
const sidebarMarginLeft = '12px'

View File

@ -1,9 +1,10 @@
// @flow
import * as React from 'react'
import Button from '~/components/layout/Button'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import { sm, boldFont } from '~/theme/variables'
import { boldFont, sm } from '~/theme/variables'
const controlStyle = {
backgroundColor: 'white',
@ -30,7 +31,7 @@ type Props = {
buttonLabels?: Array<string>,
}
const Controls = ({ onPrevious, firstPage, penultimate, lastPage, disabled, currentStep, buttonLabels }: Props) => {
const Controls = ({ buttonLabels, currentStep, disabled, firstPage, lastPage, onPrevious, penultimate }: Props) => {
const back = firstPage ? 'Cancel' : 'Back'
let next
@ -43,18 +44,18 @@ const Controls = ({ onPrevious, firstPage, penultimate, lastPage, disabled, curr
}
return (
<Row style={controlStyle} align="end" grow>
<Col xs={12} end="xs">
<Button style={firstButtonStyle} type="button" onClick={onPrevious} size="small">
<Row align="end" grow style={controlStyle}>
<Col end="xs" xs={12}>
<Button onClick={onPrevious} size="small" style={firstButtonStyle} type="button">
{back}
</Button>
<Button
style={secondButtonStyle}
size="small"
variant="contained"
color="primary"
type="submit"
disabled={disabled}
size="small"
style={secondButtonStyle}
type="submit"
variant="contained"
>
{next}
</Button>

View File

@ -1,7 +1,8 @@
// @flow
import * as React from 'react'
import { withStyles } from '@material-ui/core/styles'
import Paper from '@material-ui/core/Paper'
import { withStyles } from '@material-ui/core/styles'
import * as React from 'react'
import Block from '~/components/layout/Block'
import { lg } from '~/theme/variables'
@ -23,7 +24,7 @@ type Props = {
padding?: boolean,
}
const OpenPaper = ({ classes, children, controls, padding = true }: Props) => (
const OpenPaper = ({ children, classes, controls, padding = true }: Props) => (
<Paper className={classes.root} elevation={1}>
<Block className={padding ? classes.padding : ''}>{children}</Block>
{controls}

View File

@ -1,16 +1,18 @@
// @flow
import * as React from 'react'
import Stepper from '@material-ui/core/Stepper'
import FormStep from '@material-ui/core/Step'
import StepLabel from '@material-ui/core/StepLabel'
import StepContent from '@material-ui/core/StepContent'
import StepLabel from '@material-ui/core/StepLabel'
import Stepper from '@material-ui/core/Stepper'
import { withStyles } from '@material-ui/core/styles'
import * as React from 'react'
import Controls from './Controls'
import GnoForm from '~/components/forms/GnoForm'
import Hairline from '~/components/layout/Hairline'
import { history } from '~/store'
import Controls from './Controls'
const { useState, useEffect } = React
const { useEffect, useState } = React
export { default as Step } from './Step'
@ -110,7 +112,7 @@ const GnoStepper = (props: Props) => {
return pageNumber === steps.length - 1
}
const { steps, children, classes, disabledWhenValidating = false, testId, mutators, buttonLabels } = props
const { buttonLabels, children, classes, disabledWhenValidating = false, mutators, steps, testId } = props
const activePage = getActivePageFrom(children)
const lastPage = isLastPage(page)
@ -119,11 +121,11 @@ const GnoStepper = (props: Props) => {
return (
<>
<GnoForm
onSubmit={handleSubmit}
initialValues={values}
validation={validate}
testId={testId}
formMutators={mutators}
initialValues={values}
onSubmit={handleSubmit}
testId={testId}
validation={validate}
>
{(submitting: boolean, validating: boolean, ...rest: any) => {
const disabled = disabledWhenValidating ? submitting || validating : submitting
@ -131,19 +133,19 @@ const GnoStepper = (props: Props) => {
<>
<Hairline />
<Controls
disabled={disabled}
onPrevious={previous}
firstPage={page === 0}
lastPage={lastPage}
penultimate={penultimate}
buttonLabels={buttonLabels}
currentStep={page}
disabled={disabled}
firstPage={page === 0}
lastPage={lastPage}
onPrevious={previous}
penultimate={penultimate}
/>
</>
)
return (
<Stepper classes={{ root: classes.root }} activeStep={page} orientation="vertical">
<Stepper activeStep={page} classes={{ root: classes.root }} orientation="vertical">
{steps.map((label, index) => {
const labelProps = {}
const isClickable = index < page

View File

@ -1,10 +1,11 @@
// @flow
import * as React from 'react'
import { List } from 'immutable'
import TableCell from '@material-ui/core/TableCell'
import TableHead from '@material-ui/core/TableHead'
import TableRow from '@material-ui/core/TableRow'
import TableSortLabel from '@material-ui/core/TableSortLabel'
import { List } from 'immutable'
import * as React from 'react'
import { type Order } from '~/components/Table/sorting'
export type Column = {
@ -51,8 +52,8 @@ class GnoTableHead extends React.PureComponent<Props> {
<TableRow>
{columns.map((column: Column) => (
<TableCell
key={column.id}
align={column.align}
key={column.id}
padding={column.disablePadding ? 'none' : 'default'}
sortDirection={orderBy === column.id ? order : false}
>

View File

@ -1,15 +1,16 @@
// @flow
import * as React from 'react'
import { List } from 'immutable'
import CircularProgress from '@material-ui/core/CircularProgress'
import Table from '@material-ui/core/Table'
import TableBody from '@material-ui/core/TableBody'
import { withStyles } from '@material-ui/core/styles'
import CircularProgress from '@material-ui/core/CircularProgress'
import TablePagination from '@material-ui/core/TablePagination'
import Row from '~/components/layout/Row'
import { type Order, stableSort, getSorting } from '~/components/Table/sorting'
import { withStyles } from '@material-ui/core/styles'
import { List } from 'immutable'
import * as React from 'react'
import TableHead, { type Column } from '~/components/Table/TableHead'
import { xxl, xl, sm } from '~/theme/variables'
import { type Order, getSorting, stableSort } from '~/components/Table/sorting'
import Row from '~/components/layout/Row'
import { sm, xl, xxl } from '~/theme/variables'
type Props<K> = {
label: string,
@ -87,7 +88,7 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
}
componentDidMount() {
const { defaultOrderBy, columns } = this.props
const { columns, defaultOrderBy } = this.props
if (defaultOrderBy && columns) {
const defaultOrderCol = columns.find(({ id }) => id === defaultOrderBy)
@ -143,21 +144,21 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
render() {
const {
data,
label,
columns,
classes,
children,
size,
disablePagination,
defaultOrderBy,
defaultOrder,
classes,
columns,
data,
defaultFixed,
defaultOrder,
defaultOrderBy,
defaultRowsPerPage,
noBorder,
disableLoadingOnEmptyTable,
disablePagination,
label,
noBorder,
size,
} = this.props
const { order, orderBy, page, orderProp, rowsPerPage, fixed } = this.state
const { fixed, order, orderBy, orderProp, page, rowsPerPage } = this.state
const orderByParam = orderBy || defaultOrderBy
const orderParam = order || defaultOrder
const displayRows = rowsPerPage || defaultRowsPerPage
@ -182,7 +183,7 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
<>
{!isEmpty && (
<Table aria-labelledby={label} className={noBorder ? '' : classes.root}>
<TableHead columns={columns} order={order} orderBy={orderByParam} onSort={this.onSort} />
<TableHead columns={columns} onSort={this.onSort} order={order} orderBy={orderByParam} />
<TableBody>{children(sortedData)}</TableBody>
</Table>
)}
@ -193,16 +194,16 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
)}
{!disablePagination && (
<TablePagination
backIconButtonProps={backProps}
classes={paginationClasses}
component="div"
count={size}
rowsPerPage={displayRows}
rowsPerPageOptions={[5, 10, 25, 50, 100]}
page={page}
backIconButtonProps={backProps}
nextIconButtonProps={nextProps}
onChangePage={this.handleChangePage}
onChangeRowsPerPage={this.handleChangeRowsPerPage}
classes={paginationClasses}
page={page}
rowsPerPage={displayRows}
rowsPerPageOptions={[5, 10, 25, 50, 100]}
/>
)}
</>

View File

@ -2,8 +2,9 @@
import * as React from 'react'
import { Field } from 'react-final-form'
import { OnChange } from 'react-final-form-listeners'
import TextField from '~/components/forms/TextField'
import { composeValidators, required, mustBeEthereumAddress } from '~/components/forms/validator'
import { composeValidators, mustBeEthereumAddress, required } from '~/components/forms/validator'
import { getAddressFromENS } from '~/logic/wallets/getWeb3'
type Props = {
@ -38,17 +39,17 @@ const AddressInput = ({
}: Props): React.Element<*> => (
<>
<Field
name={name}
component={TextField}
type="text"
validate={composeValidators(required, mustBeEthereumAddress, ...validators)}
inputAdornment={inputAdornment}
placeholder={placeholder}
text={text}
className={className}
testId={testId}
component={TextField}
defaultValue={defaultValue}
disabled={disabled}
inputAdornment={inputAdornment}
name={name}
placeholder={placeholder}
testId={testId}
text={text}
type="text"
validate={composeValidators(required, mustBeEthereumAddress, ...validators)}
/>
<OnChange name={name}>
{async value => {

View File

@ -1,6 +1,6 @@
// @flow
import React from 'react'
import Checkbox, { type CheckoxProps } from '@material-ui/core/Checkbox'
import React from 'react'
class GnoCheckbox extends React.PureComponent<CheckoxProps> {
render() {
@ -9,7 +9,7 @@ class GnoCheckbox extends React.PureComponent<CheckoxProps> {
...rest
} = this.props
return <Checkbox {...rest} name={name} inputProps={restInput} onChange={onChange} checked={!!checked} />
return <Checkbox {...rest} checked={!!checked} inputProps={restInput} name={name} onChange={onChange} />
}
}

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import { type FormApi } from 'final-form'
import * as React from 'react'
import { Form } from 'react-final-form'
export type OnSubmit = (
@ -25,17 +25,17 @@ const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
flex: '1 0 auto',
})
const GnoForm = ({ onSubmit, validation, initialValues, children, padding = 0, formMutators, testId = '' }: Props) => (
const GnoForm = ({ children, formMutators, initialValues, onSubmit, padding = 0, testId = '', validation }: Props) => (
<Form
validate={validation}
onSubmit={onSubmit}
initialValues={initialValues}
mutators={formMutators}
onSubmit={onSubmit}
render={({ handleSubmit, ...rest }) => (
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)} data-testid={testId}>
<form data-testid={testId} onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
{children(rest.submitting, rest.validating, rest, rest.form.mutators)}
</form>
)}
validate={validation}
/>
)

View File

@ -1,22 +1,22 @@
// @flow
import React from 'react'
import Select, { type SelectFieldProps } from '@material-ui/core/Select'
import FormControl from '@material-ui/core/FormControl'
import InputLabel from '@material-ui/core/InputLabel'
import FormHelperText from '@material-ui/core/FormHelperText'
import InputLabel from '@material-ui/core/InputLabel'
import Select, { type SelectFieldProps } from '@material-ui/core/Select'
import React from 'react'
const style = {
minWidth: '100%',
}
const SelectInput = ({
input: { name, value, onChange, ...restInput },
meta,
label,
formControlProps,
classes,
renderValue,
disableError,
formControlProps,
input: { name, onChange, value, ...restInput },
label,
meta,
renderValue,
...rest
}: SelectFieldProps) => {
const showError = ((meta.submitError && !meta.dirtySinceLastSubmit) || meta.error) && meta.touched && !disableError
@ -30,9 +30,9 @@ const SelectInput = ({
<InputLabel htmlFor={name}>{label}</InputLabel>
<Select
classes={classes}
inputProps={inputProps}
onChange={onChange}
renderValue={renderValue}
inputProps={inputProps}
value={value}
{...rest}
/>

View File

@ -1,7 +1,8 @@
// @flow
import React from 'react'
import MuiTextField, { TextFieldProps } from '@material-ui/core/TextField'
import { withStyles } from '@material-ui/core/styles'
import React from 'react'
import { lg } from '~/theme/variables'
// Neded for solving a fix in Windows browsers
@ -21,39 +22,49 @@ const styles = () => ({
class TextField extends React.PureComponent<TextFieldProps> {
render() {
const {
input: { name, onChange, value, ...restInput },
meta,
text,
inputAdornment,
classes,
testId,
rows,
input: { name, onChange, value, ...restInput },
inputAdornment,
meta,
multiline,
rows,
testId,
text,
...rest
} = this.props
const helperText = value ? text : undefined
const showError = (meta.touched || !meta.pristine) && !meta.valid
const underline = meta.active || (meta.visited && !meta.valid)
const isInactiveAndPristineOrUntouched = !meta.active && (meta.pristine || !meta.touched)
const isInvalidAndUntouched = typeof meta.error === 'undefined' ? true : !meta.touched
const inputRoot = helperText ? classes.root : undefined
const inputProps = { ...restInput, autoComplete: 'off', 'data-testid': testId }
const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot }
const disableUnderline = isInactiveAndPristineOrUntouched && isInvalidAndUntouched
const inputRoot = helperText ? classes.root : ''
const statusClasses = meta.valid ? 'isValid' : meta.error && (meta.dirty || meta.touched) ? 'isInvalid' : ''
const inputProps = {
...restInput,
autoComplete: 'off',
'data-testid': testId,
}
const inputRootProps = {
...inputAdornment,
className: `${inputRoot} ${statusClasses}`,
disableUnderline: disableUnderline,
}
return (
<MuiTextField
style={overflowStyle}
{...rest}
name={name}
helperText={showError ? meta.error : helperText || ' '} // blank in order to force to have helper text
error={meta.error && (meta.touched || !meta.pristine)}
helperText={showError ? meta.error : helperText || ' '}
inputProps={inputProps} // blank in order to force to have helper text
InputProps={inputRootProps}
// eslint-disable-next-line
inputProps={inputProps}
onChange={onChange}
value={value}
// data-testid={testId}
rows={rows}
multiline={multiline}
name={name}
onChange={onChange}
rows={rows}
style={overflowStyle}
value={value}
{...rest}
/>
)
}

View File

@ -1,7 +1,8 @@
// @flow
import React from 'react'
import { withStyles } from '@material-ui/core/styles'
import { TextFieldProps } from '@material-ui/core/TextField'
import { withStyles } from '@material-ui/core/styles'
import React from 'react'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
@ -23,7 +24,7 @@ const styles = () => ({
})
const TextareaField = ({ classes, ...props }: TextFieldProps) => (
<Field {...props} component={TextField} multiline rows="5" className={classes.textarea} />
<Field {...props} className={classes.textarea} component={TextField} multiline rows="5" />
)
export default withStyles(styles)(TextareaField)

View File

@ -1,8 +1,9 @@
// @flow
import { type FieldValidator } from 'final-form'
import { List } from 'immutable'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { getWeb3 } from '~/logic/wallets/getWeb3'
export const simpleMemoize = (fn: Function) => {
let lastArg

View File

@ -1,8 +1,8 @@
// @flow
import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import ReactDOM from 'react-dom'
import Backdrop from '@material-ui/core/Backdrop'
import { makeStyles } from '@material-ui/core/styles'
import React from 'react'
import ReactDOM from 'react-dom'
const useStyles = makeStyles({
root: {

View File

@ -1,10 +1,12 @@
// @flow
import classNames from 'classnames/bind'
import * as React from 'react'
import { capitalize } from '~/utils/css'
import { type Size } from '~/theme/size'
import styles from './index.scss'
import { type Size } from '~/theme/size'
import { capitalize } from '~/utils/css'
const { PureComponent } = React
const cx = classNames.bind(styles)
@ -19,7 +21,7 @@ type Props = {
class Block extends PureComponent<Props> {
render() {
const { margin, padding, justify, children, className, ...props } = this.props
const { children, className, justify, margin, padding, ...props } = this.props
const paddingStyle = padding ? capitalize(padding, 'padding') : undefined
return (

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import Button from '@material-ui/core/Button'
import * as React from 'react'
type Props = {
minWidth?: number,
@ -17,7 +17,7 @@ const calculateStyleBased = (minWidth, minHeight) => ({
const GnoButton = ({ minWidth, minHeight = 35, testId = '', style = {}, ...props }: Props) => {
const calculatedStyle = calculateStyleBased(minWidth, minHeight)
return <Button style={{ ...calculatedStyle, ...style }} data-testid={testId} {...props} />
return <Button data-testid={testId} style={{ ...calculatedStyle, ...style }} {...props} />
}
export default GnoButton

View File

@ -1,7 +1,8 @@
// @flow
/* eslint-disable react/button-has-type */
import * as React from 'react'
import cn from 'classnames/bind'
import * as React from 'react'
import styles from './index.scss'
const cx = cn.bind(styles)
@ -16,15 +17,15 @@ type Props = {
}
const GnoButtonLink = ({
type = 'button',
size = 'md',
weight = 'regular',
color = 'secondary',
testId = '',
className = '',
color = 'secondary',
size = 'md',
testId = '',
type = 'button',
weight = 'regular',
...props
}: Props) => (
<button type={type} className={cx(styles.btnLink, size, color, weight, className)} data-testid={testId} {...props} />
<button className={cx(styles.btnLink, size, color, weight, className)} data-testid={testId} type={type} {...props} />
)
export default GnoButtonLink

View File

@ -1,9 +1,11 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import { capitalize } from '~/utils/css'
import * as React from 'react'
import styles from './index.scss'
import { capitalize } from '~/utils/css'
const cx = classNames.bind(styles)
type Props = {
@ -31,27 +33,27 @@ type Props = {
}
const Col = ({
children,
margin,
layout = 'inherit',
overflow,
xs,
sm,
md,
lg,
start,
center,
end,
top,
middle,
bottom,
around,
between,
xsOffset,
smOffset,
mdOffset,
lgOffset,
bottom,
center,
children,
className,
end,
layout = 'inherit',
lg,
lgOffset,
margin,
md,
mdOffset,
middle,
overflow,
sm,
smOffset,
start,
top,
xs,
xsOffset,
...props
}: Props) => {
const colClassNames = cx(

View File

@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import { border } from '~/theme/variables'
type Props = {

View File

@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import { type Size, getSize } from '~/theme/size'
import { border } from '~/theme/variables'
@ -18,11 +19,11 @@ type Props = {
style?: Object,
}
const Hairline = ({ margin, color, style, className }: Props) => {
const Hairline = ({ className, color, margin, style }: Props) => {
const calculatedStyles = calculateStyleFrom(color, margin)
const mergedStyles = { ...calculatedStyles, ...(style || {}) }
return <div style={mergedStyles} className={className} />
return <div className={className} style={mergedStyles} />
}
export default Hairline

View File

@ -1,9 +1,11 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import { capitalize } from '~/utils/css'
import * as React from 'react'
import styles from './index.scss'
import { capitalize } from '~/utils/css'
const cx = classNames.bind(styles)
type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4'
@ -20,7 +22,7 @@ type Props = {
}
const Heading = (props: Props) => {
const { align, tag, truncate, margin, color, children, testId, className = '', ...rest } = props
const { align, children, className = '', color, margin, tag, testId, truncate, ...rest } = props
const classes = cx(className, 'heading', align, tag, margin ? capitalize(margin, 'margin') : undefined, color, {
truncate,

View File

@ -1,6 +1,7 @@
// @flow
import React from 'react'
import classNames from 'classnames/bind'
import React from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)
@ -14,10 +15,10 @@ type Props = {
testId?: string,
}
const Img = ({ fullwidth, alt, bordered, className, style, testId = '', ...props }: Props) => {
const Img = ({ alt, bordered, className, fullwidth, style, testId = '', ...props }: Props) => {
const classes = cx(styles.img, { fullwidth, bordered }, className)
return <img alt={alt} style={style} className={classes} data-testid={testId} {...props} />
return <img alt={alt} className={classes} data-testid={testId} style={style} {...props} />
}
export default Img

View File

@ -1,10 +1,12 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import * as React from 'react'
import { Link } from 'react-router-dom'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
import { capitalize } from '~/utils/css'
const cx = classNames.bind(styles)
type Props = {
@ -16,7 +18,7 @@ type Props = {
innerRef?: React.ElementRef<any>,
}
const GnosisLink = ({ to, children, color, className, padding, innerRef, ...props }: Props) => {
const GnosisLink = ({ children, className, color, innerRef, padding, to, ...props }: Props) => {
const internal = /^\/(?!\/)/.test(to)
const classes = cx(styles.link, color || 'regular', padding ? capitalize(padding, 'padding') : undefined, className)
const LinkElement = internal ? Link : 'a'

View File

@ -1,6 +1,7 @@
// @flow
import classNames from 'classnames/bind'
import React from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)
@ -11,7 +12,7 @@ type Props = {
overflow?: boolean,
}
const Page = ({ children, align, overflow }: Props) => (
const Page = ({ align, children, overflow }: Props) => (
<main className={cx(styles.page, align, { overflow })}>{children}</main>
)

View File

@ -1,24 +1,26 @@
// @flow
import * as React from 'react'
import { SnackbarProvider } from 'notistack'
import { connect } from 'react-redux'
import { withStyles } from '@material-ui/core/styles'
import Backdrop from '~/components/layout/Backdrop'
import CookiesBanner from '~/components/CookiesBanner'
import Header from '~/components/Header'
import Footer from '~/components/Footer'
import Img from '~/components/layout/Img'
import Notifier from '~/components/Notifier'
import SidebarProvider from '~/components/Sidebar'
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
import { getNetwork } from '~/config'
import { networkSelector } from '~/logic/wallets/store/selectors'
import { SnackbarProvider } from 'notistack'
import * as React from 'react'
import { connect } from 'react-redux'
import AlertIcon from './assets/alert.svg'
import CheckIcon from './assets/check.svg'
import ErrorIcon from './assets/error.svg'
import InfoIcon from './assets/info.svg'
import styles from './index.scss'
import CookiesBanner from '~/components/CookiesBanner'
import Footer from '~/components/Footer'
import Header from '~/components/Header'
import Notifier from '~/components/Notifier'
import SidebarProvider from '~/components/Sidebar'
import Backdrop from '~/components/layout/Backdrop'
import Img from '~/components/layout/Img'
import { getNetwork } from '~/config'
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
import { networkSelector } from '~/logic/wallets/store/selectors'
const notificationStyles = {
success: {
background: '#fff',
@ -49,7 +51,6 @@ const PageFrame = ({ children, classes, currentNetwork }: Props) => {
<div className={styles.frame}>
<Backdrop isOpen={isWrongNetwork} />
<SnackbarProvider
maxSnack={5}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
classes={{
variantSuccess: classes.success,
@ -58,11 +59,12 @@ const PageFrame = ({ children, classes, currentNetwork }: Props) => {
variantInfo: classes.info,
}}
iconVariant={{
error: <Img src={ErrorIcon} alt="Error" />,
info: <Img src={InfoIcon} alt="Info" />,
success: <Img src={CheckIcon} alt="Success" />,
warning: <Img src={AlertIcon} alt="Warning" />,
error: <Img alt="Error" src={ErrorIcon} />,
info: <Img alt="Info" src={InfoIcon} />,
success: <Img alt="Success" src={CheckIcon} />,
warning: <Img alt="Warning" src={AlertIcon} />,
}}
maxSnack={5}
>
<Notifier />
<SidebarProvider>

View File

@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import * as React from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)
@ -20,7 +21,7 @@ type Props = {
class Paragraph extends React.PureComponent<Props> {
render() {
const { weight, children, color, align, size, transform, noMargin, className, dot, ...props } = this.props
const { align, children, className, color, dot, noMargin, size, transform, weight, ...props } = this.props
return (
<p

View File

@ -1,6 +1,7 @@
// @flow
import classNames from 'classnames/bind'
import * as React from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)

View File

@ -1,9 +1,11 @@
// @flow
import classNames from 'classnames/bind'
import * as React from 'react'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
import { capitalize } from '~/utils/css'
const cx = classNames.bind(styles)
type Props = {
@ -15,7 +17,7 @@ type Props = {
testId?: string,
}
const Row = ({ children, className, margin, align, grow, testId = '', ...props }: Props) => {
const Row = ({ align, children, className, grow, margin, testId = '', ...props }: Props) => {
const rowClassNames = cx(
styles.row,
margin ? capitalize(margin, 'margin') : undefined,

View File

@ -1,10 +1,10 @@
// @flow
import * as React from 'react'
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'
import * as React from 'react'
export { TableBody, TableCell, TableHead, TableRow }
@ -22,7 +22,7 @@ const overflowStyle = {
}
// see: https://css-tricks.com/responsive-data-tables/
const GnoTable = ({ size, children }: Props) => {
const GnoTable = ({ children, size }: Props) => {
const style = size ? buildWidthFrom(size) : undefined
return (

View File

@ -5,7 +5,7 @@ import { TX_SERVICE_HOST, RELAY_API_URL } from '~/config/names'
const devMainnetConfig = {
...devConfig,
[TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.gnosis.io/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/',
}
export default devMainnetConfig

View File

@ -41,6 +41,9 @@ export const getNetwork = () =>
? ETHEREUM_NETWORK.MAINNET
: ETHEREUM_NETWORK.RINKEBY
export const getNetworkId = () =>
process.env.REACT_APP_NETWORK === "mainnet" ? 1 : 4
const getConfig = ensureOnce(configuration)
export const getTxServiceHost = () => {

View File

@ -4,7 +4,7 @@ import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL } from '~/confi
const prodConfig = {
[TX_SERVICE_HOST]: 'https://safe-transaction.rinkeby.gnosis.io/api/v1/',
[SIGNATURES_VIA_METAMASK]: false,
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.rinkeby.gnosis.io/api/v1/',
}
export default prodConfig

View File

@ -5,7 +5,7 @@ import { TX_SERVICE_HOST, RELAY_API_URL } from '~/config/names'
const stagingMainnetConfig = {
...stagingConfig,
[TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.gnosis.io/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/',
}
export default stagingMainnetConfig

View File

@ -1,13 +1,14 @@
// @flow
import 'babel-polyfill'
import { BigNumber } from 'bignumber.js'
import React from 'react'
import ReactDOM from 'react-dom'
import { BigNumber } from 'bignumber.js'
import Root from '~/components/Root'
import loadCurrentSessionFromStorage from '~/logic/currentSession/store/actions/loadCurrentSessionFromStorage'
import loadActiveTokens from '~/logic/tokens/store/actions/loadActiveTokens'
import loadDefaultSafe from '~/routes/safe/store/actions/loadDefaultSafe'
import loadSafesFromStorage from '~/routes/safe/store/actions/loadSafesFromStorage'
import loadCurrentSessionFromStorage from '~/logic/currentSession/store/actions/loadCurrentSessionFromStorage'
import { store } from '~/store'
BigNumber.set({ EXPONENTIAL_AT: [-7, 255] })

View File

@ -1,5 +1,6 @@
// @flow
import { createAction } from 'redux-actions'
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
export const ADD_ADDRESS_BOOK = 'ADD_ADDRESS_BOOK'

View File

@ -1,5 +1,6 @@
// @flow
import { createAction } from 'redux-actions'
import type { AddressBookEntryType } from '~/logic/addressBook/model/addressBook'
export const ADD_ENTRY = 'ADD_ENTRY'

View File

@ -1,5 +1,6 @@
// @flow
import { createAction } from 'redux-actions'
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
export const LOAD_ADDRESS_BOOK = 'LOAD_ADDRESS_BOOK'

View File

@ -1,11 +1,12 @@
// @flow
import { List, Map } from 'immutable'
import type { Dispatch as ReduxDispatch } from 'redux'
import { Map, List } from 'immutable'
import { type GlobalState } from '~/store/index'
import { getAddressBookFromStorage } from '~/logic/addressBook/utils'
import { loadAddressBook } from '~/logic/addressBook/store/actions/loadAddressBook'
import { safesListSelector } from '~/routes/safe/store/selectors'
import { buildAddressBook } from '~/logic/addressBook/store/reducer/addressBook'
import { getAddressBookFromStorage } from '~/logic/addressBook/utils'
import { safesListSelector } from '~/routes/safe/store/selectors'
import { type GlobalState } from '~/store/index'
const loadAddressBookFromStorage = () => async (dispatch: ReduxDispatch<GlobalState>, getState: Function) => {
try {

View File

@ -1,9 +1,10 @@
// @flow
import type { Dispatch as ReduxDispatch } from 'redux'
import { type GlobalState } from '~/store/index'
import { saveAddressBook } from '~/logic/addressBook/utils'
import { updateAddressBookEntry } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
import { updateAddressBookEntry } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
import { saveAddressBook } from '~/logic/addressBook/utils'
import { type GlobalState } from '~/store/index'
const saveAndUpdateAddressBook = (addressBook: AddressBook) => async (dispatch: ReduxDispatch<GlobalState>) => {
try {

View File

@ -1,5 +1,6 @@
// @flow
import { createAction } from 'redux-actions'
import type { AddressBookEntry } from '~/logic/addressBook/model/addressBook'
export const UPDATE_ENTRY = 'UPDATE_ENTRY'

View File

@ -1,15 +1,16 @@
// @flow
import type { AnyAction, Store } from 'redux'
import { type GlobalState } from '~/store/'
import type { AddressBookProps } from '~/logic/addressBook/model/addressBook'
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
import { addressBookMapSelector } from '~/logic/addressBook/store/selectors'
import { enhanceSnackbarForAction, getNotificationsFromTxType } from '~/logic/notifications'
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
import { saveAddressBook } from '~/logic/addressBook/utils'
import type { AddressBookProps } from '~/logic/addressBook/model/addressBook'
import { enhanceSnackbarForAction, getNotificationsFromTxType } from '~/logic/notifications'
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
import { type GlobalState } from '~/store/'
const watchedActions = [ADD_ENTRY, REMOVE_ENTRY, UPDATE_ENTRY]

View File

@ -1,14 +1,15 @@
// @flow
import { List, Map } from 'immutable'
import { handleActions, type ActionType } from 'redux-actions'
import { type ActionType, handleActions } from 'redux-actions'
import type { AddressBook, AddressBookEntry, AddressBookProps } from '~/logic/addressBook/model/addressBook'
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
import { ADD_ADDRESS_BOOK } from '~/logic/addressBook/store/actions/addAddressBook'
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
import { LOAD_ADDRESS_BOOK } from '~/logic/addressBook/store/actions/loadAddressBook'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
import { getAddressesListFromAdbk } from '~/logic/addressBook/utils'
import { sameAddress } from '~/logic/wallets/ethAddresses'
export const ADDRESS_BOOK_REDUCER_ID = 'addressBook'

View File

@ -1,12 +1,13 @@
/* eslint-disable import/named */
// @flow
import { List, Map } from 'immutable'
import { createSelector, Selector } from 'reselect'
import { useSelector } from 'react-redux'
import { ADDRESS_BOOK_REDUCER_ID } from '~/logic/addressBook/store/reducer/addressBook'
import type { GlobalState } from '~/store'
import { Selector, createSelector } from 'reselect'
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
import { ADDRESS_BOOK_REDUCER_ID } from '~/logic/addressBook/store/reducer/addressBook'
import { safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
import type { GlobalState } from '~/store'
export const addressBookMapSelector = (state: GlobalState): Map<string, AddressBook> =>
state[ADDRESS_BOOK_REDUCER_ID].get('addressBook')

View File

@ -1,9 +1,10 @@
// @flow
import { useSelector } from 'react-redux'
import type { AddressBook, AddressBookProps } from '~/logic/addressBook/model/addressBook'
import { loadFromStorage, saveToStorage } from '~/utils/storage'
import { getAddressBook } from '~/logic/addressBook/store/selectors'
import type { Owner } from '~/routes/safe/store/models/owner'
import { loadFromStorage, saveToStorage } from '~/utils/storage'
const ADDRESS_BOOK_STORAGE_KEY = 'ADDRESS_BOOK_STORAGE_KEY'

View File

@ -7,5 +7,5 @@ const proxyCodeV10 =
const oldProxyCode =
'0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600'
export const isProxyCode = codeToCheck =>
export const isProxyCode = (codeToCheck: string) =>
codeToCheck === oldProxyCode || codeToCheck === proxyCodeV10

View File

@ -1,6 +1,7 @@
// @flow
import { Map } from 'immutable'
import { handleActions, type ActionType } from 'redux-actions'
import { type ActionType, handleActions } from 'redux-actions'
import type { Cookie } from '~/logic/cookies/model/cookie'
import { OPEN_COOKIE_BANNER } from '~/logic/cookies/store/actions/openCookieBanner'

View File

@ -1,5 +1,5 @@
// @flow
import type { Provider } from '~/logic/wallets/store/model/provider'
import { COOKIES_REDUCER_ID } from '~/logic/cookies/store/reducer/cookies'
import type { Provider } from '~/logic/wallets/store/model/provider'
export const cookieBannerOpen = (state: any): Provider => state[COOKIES_REDUCER_ID].get('cookieBannerOpen')

View File

@ -1,5 +1,6 @@
// @flow
import Cookies from 'js-cookie'
import { getNetwork } from '~/config'
const PREFIX = `v1_${getNetwork()}`

View File

@ -1,5 +1,6 @@
// @flow
import axios from 'axios'
import { getExchangeRatesUrl } from '~/config'
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'

View File

@ -1,5 +1,6 @@
// @flow
import axios from 'axios'
import { getTxServiceHost } from '~/config'
const fetchTokenCurrenciesBalances = (safeAddress: string) => {

View File

@ -1,11 +1,12 @@
// @flow
import { Dispatch as ReduxDispatch } from 'redux'
import { List } from 'immutable'
import type { GlobalState } from '~/store'
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
import { Dispatch as ReduxDispatch } from 'redux'
import fetchCurrenciesRates from '~/logic/currencyValues/api/fetchCurrenciesRates'
import { currencyValuesListSelector } from '~/logic/currencyValues/store/selectors'
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
import { currencyValuesListSelector } from '~/logic/currencyValues/store/selectors'
import type { GlobalState } from '~/store'
// eslint-disable-next-line max-len
const fetchCurrencySelectedValue = (currencyValueSelected: AVAILABLE_CURRENCIES) => async (

View File

@ -1,14 +1,15 @@
// @flow
import type { Dispatch as ReduxDispatch } from 'redux'
import { List } from 'immutable'
import type { GlobalState } from '~/store'
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
import { AVAILABLE_CURRENCIES, makeBalanceCurrency } from '~/logic/currencyValues/store/model/currencyValues'
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
import type { Dispatch as ReduxDispatch } from 'redux'
import fetchTokenCurrenciesBalances from '~/logic/currencyValues/api/fetchTokenCurrenciesBalances'
import { loadFromStorage } from '~/utils/storage'
import fetchCurrencySelectedValue from '~/logic/currencyValues/store/actions/fetchCurrencySelectedValue'
import { CURRENCY_SELECTED_KEY } from '~/logic/currencyValues/store/actions/saveCurrencySelected'
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
import { AVAILABLE_CURRENCIES, makeBalanceCurrency } from '~/logic/currencyValues/store/model/currencyValues'
import type { GlobalState } from '~/store'
import { loadFromStorage } from '~/utils/storage'
export const fetchCurrencyValues = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
try {

View File

@ -1,11 +1,11 @@
// @flow
import { Dispatch as ReduxDispatch } from 'redux'
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
import type { GlobalState } from '~/store'
import { saveToStorage } from '~/utils/storage'
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
export const CURRENCY_SELECTED_KEY = 'CURRENCY_SELECTED_KEY'

Some files were not shown because too many files have changed in this diff Show More