Merge pull request #2 from gnosis/react-router

React router v4 + Aliases modules import [JEST, Webpack, VsCode]
This commit is contained in:
Adolfo Panizo 2018-03-08 15:11:37 +01:00 committed by GitHub
commit bb4906cef5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 277 additions and 128 deletions

View File

@ -10,6 +10,7 @@
"@babel/stage-0"
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"transform-es3-member-expression-literals",
"transform-es3-property-literals"
]

View File

@ -38,6 +38,7 @@ module.exports = {
appIndexJs: resolveApp('src/index.js'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appContracts: resolveApp('gnosis-safe-contracts/build/contracts'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),

View File

@ -58,12 +58,21 @@ module.exports = {
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
],
resolve: {
resolve: {
modules: [
paths.appSrc,
'node_modules',
paths.appContracts,
],
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx'],
alias: {
'~': paths.appSrc,
'#': paths.appContracts,
}
},
output: {
// Next line is not used in dev but WebpackDevServer crashes without it:

View File

@ -101,11 +101,20 @@ module.exports = {
publicPath: publicPath
},
resolve: {
modules: [
paths.appSrc,
'node_modules',
paths.appContracts,
],
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx'],
alias: {
'~': paths.appSrc,
'#': paths.appContracts,
}
},
module: {

18
jsconfig.json Normal file
View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "es2017",
"allowSyntheticDefaultImports": false,
"baseUrl": "./",
"paths": {
"~/*":["src/*"],
"@/*":["gnosis-safe-contracts/build/contracts"]
}
},
"exclude": [
"node_modules",
"build_webpack",
"config",
"public",
"scripts"
]
}

View File

@ -1,5 +0,0 @@
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};

View File

@ -1,5 +0,0 @@
var SimpleStorage = artifacts.require("./SimpleStorage.sol");
module.exports = function(deployer) {
deployer.deploy(SimpleStorage);
};

71
package-lock.json generated
View File

@ -8298,6 +8298,18 @@
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
"history": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
"integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
"requires": {
"invariant": "2.2.3",
"loose-envify": "1.3.1",
"resolve-pathname": "2.2.0",
"value-equal": "0.4.0",
"warning": "3.0.0"
}
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@ -9030,7 +9042,6 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz",
"integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==",
"dev": true,
"requires": {
"loose-envify": "1.3.1"
}
@ -9411,8 +9422,7 @@
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"isexe": {
"version": "2.0.0",
@ -15148,6 +15158,14 @@
"theming": "1.3.0"
}
},
"react-loadable": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/react-loadable/-/react-loadable-5.3.1.tgz",
"integrity": "sha1-lpnpoI/tSbrNacqqKCA0tip2vN0=",
"requires": {
"prop-types": "15.6.1"
}
},
"react-popper": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-0.8.2.tgz",
@ -15157,6 +15175,43 @@
"prop-types": "15.6.1"
}
},
"react-router": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
"integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==",
"requires": {
"history": "4.7.2",
"hoist-non-react-statics": "2.5.0",
"invariant": "2.2.3",
"loose-envify": "1.3.1",
"path-to-regexp": "1.7.0",
"prop-types": "15.6.1",
"warning": "3.0.0"
},
"dependencies": {
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"requires": {
"isarray": "0.0.1"
}
}
}
},
"react-router-dom": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz",
"integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==",
"requires": {
"history": "4.7.2",
"invariant": "2.2.3",
"loose-envify": "1.3.1",
"prop-types": "15.6.1",
"react-router": "4.2.0",
"warning": "3.0.0"
}
},
"react-scrollbar-size": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz",
@ -15675,6 +15730,11 @@
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
"dev": true
},
"resolve-pathname": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
"integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
},
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@ -19484,6 +19544,11 @@
"spdx-expression-parse": "3.0.0"
}
},
"value-equal": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
"integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@ -23,6 +23,7 @@
"devDependencies": {
"@babel/cli": "^7.0.0-beta.40",
"@babel/core": "^7.0.0-beta.40",
"@babel/plugin-syntax-dynamic-import": "^7.0.0-beta.40",
"@babel/polyfill": "^7.0.0-beta.40",
"@babel/preset-env": "^7.0.0-beta.40",
"@babel/preset-react": "^7.0.0-beta.40",
@ -62,7 +63,9 @@
"final-form": "^4.2.1",
"material-ui": "^1.0.0-beta.35",
"material-ui-icons": "^1.0.0-beta.35",
"react-final-form": "^3.1.2"
"react-final-form": "^3.1.2",
"react-loadable": "^5.3.1",
"react-router-dom": "^4.2.2"
},
"jest": {
"collectCoverageFrom": [
@ -87,6 +90,8 @@
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"
],
"moduleNameMapper": {
"~(.*)$": "<rootDir>/src/$1",
"#(.*)$": "<rootDir>/gnosis-safe-contracts/build/contracts/$1",
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [

View File

@ -1,113 +1,11 @@
import Button from 'material-ui/Button';
import React, { Component } from 'react'
import { Form, Field } from 'react-final-form'
import Safe from '../gnosis-safe-contracts/build/contracts/GnosisSafe.json'
import getWeb3, { promisify } from './utils/getWeb3'
import contract from 'truffle-contract'
import TextField from './components/forms/TextField'
import Page from './components/layout/Page'
import PageFrame from './components/layout/PageFrame'
import './App.scss'
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import AppRoutes from './routes'
class App extends Component {
constructor(props) {
super(props)
const ReactRouterApp = () => (
<BrowserRouter>
<AppRoutes />
</BrowserRouter>
)
this.state = {
storageValue: 0,
web3: undefined,
safeAddress: undefined,
funds: undefined,
}
this.safe = contract(Safe)
}
componentWillMount() {
getWeb3.then(results => {
const web3 = results.web3
this.safe.setProvider(web3.currentProvider)
this.setState({web3})
})
.catch(() => {
console.log('Error finding web3.')
})
}
onCallSafeContractSubmit = async () => {
try {
const web3 = this.state.web3
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
const safeInstance = await this.safe.new([accounts[0]], 1, 0, 0, { from: accounts[0], gas: '5000000' })
const transactionHash = safeInstance.transactionHash
// const transaction = await promisify(cb => web3.eth.getTransaction(transactionHash, cb))
// console.log("Transaction" + JSON.stringify(transaction, 2, 0))
const transactionReceipt = await promisify(cb => web3.eth.getTransactionReceipt(transactionHash, cb))
console.log("Transaction Receipt" + JSON.stringify(transactionReceipt, 2, 0))
this.setState({ safeAddress: safeInstance.address})
} catch (error) {
console.log("Error while creating the Safe")
}
}
onAddFunds = async (values) => {
const fundsToAdd = values.funds
try {
const { web3, safeAddress } = this.state
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
const txData = {from: accounts[0], to: safeAddress, value: web3.toWei(fundsToAdd, 'ether')}
await promisify(cb => web3.eth.sendTransaction(txData, cb))
const funds = await promisify( cb => web3.eth.getBalance(safeAddress, cb))
const fundsInEther = funds ? web3.fromWei(funds.toNumber(), 'ether') : 0
this.setState({funds: fundsInEther})
} catch (error) {
console.log("Errog adding funds to safe" + error)
}
}
render() {
const { safeAddress, funds } = this.state
return (
<Page>
<PageFrame>
<Form
onSubmit={this.onCallSafeContractSubmit}
render={({ handleSubmit, pristine, invalid }) => (
<form onSubmit={handleSubmit}>
<h2>Create a new Safe instance for testing purposes</h2>
<div>
<Button variant="raised" color="primary" type="submit">
Create Safe
</Button>
</div>
</form>
)}
/>
<Form
onSubmit={this.onAddFunds}
render={({ handleSubmit, pristine, invalid }) => (
<form onSubmit={handleSubmit}>
<h2>Add Funds to the safe</h2>
<div style={{ margin: '10px 0px'}}>
<label style={{ marginRight: '10px' }}>{safeAddress ? safeAddress : 'Not safe detected'}</label>
</div>
{ safeAddress && <div>
<Field name="funds" component={TextField} type="text" placeholder="ETH to add" />
<Button type="submit" disabled={ !safeAddress || pristine || invalid}>
Add funds
</Button>
</div> }
{ safeAddress && <div style={{ margin: '15px 0px'}}>
Total funds in this safe: { funds ? funds : 0 } ETH
</div> }
</form>
)}
/>
</PageFrame>
</Page>
);
}
}
export default App
export default ReactRouterApp

View File

@ -1,8 +1,8 @@
import { MuiThemeProvider } from 'material-ui/styles'
import React from 'react'
import ReactDOM from 'react-dom'
import theme from '~/theme/mui'
import App from './App'
import { MuiThemeProvider } from 'material-ui/styles';
import theme from './theme/mui'
const Root = () => (
<MuiThemeProvider theme={theme}>

23
src/routes/index.js Normal file
View File

@ -0,0 +1,23 @@
import { CircularProgress } from 'material-ui/Progress';
import React from 'react'
import Loadable from 'react-loadable';
import { Switch, Redirect, Route } from 'react-router-dom'
import Welcome from './welcome/components/Layout'
const Loading = () => <CircularProgress size={50} />
const Transactions = Loadable({
loader: () => import('./transactions/components/Layout'),
loading: Loading,
})
const Routes = () => (
<Switch>
<Redirect exact from="/" to="/welcome" />
<Route exact path='/welcome' component={Welcome} />
<Route exact path='/transactions' component={Transactions} />
</Switch>
)
export default Routes

View File

@ -0,0 +1,11 @@
import React from 'react'
class Layout extends React.Component {
render() {
return (
<div>I am transactions Layout</div>
)
}
}
export default Layout

View File

@ -0,0 +1,119 @@
import Button from 'material-ui/Button';
import React, { Component } from 'react'
import { Form, Field } from 'react-final-form'
import { Link } from 'react-router-dom'
import contract from 'truffle-contract'
import TextField from '~/components/forms/TextField'
import Page from '~/components/layout/Page'
import PageFrame from '~/components/layout/PageFrame'
import getWeb3, { promisify } from '~/utils/getWeb3'
import Safe from '#/GnosisSafe.json'
import './App.scss'
class App extends Component {
constructor(props) {
super(props)
this.state = {
storageValue: 0,
web3: undefined,
safeAddress: undefined,
funds: undefined,
}
this.safe = contract(Safe)
}
componentWillMount() {
getWeb3.then(results => {
const web3 = results.web3
this.safe.setProvider(web3.currentProvider)
this.setState({web3})
})
.catch(() => {
console.log('Error finding web3.')
})
}
onCallSafeContractSubmit = async () => {
try {
const web3 = this.state.web3
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
const safeInstance = await this.safe.new([accounts[0]], 1, 0, 0, { from: accounts[0], gas: '5000000' })
const transactionHash = safeInstance.transactionHash
// const transaction = await promisify(cb => web3.eth.getTransaction(transactionHash, cb))
// console.log("Transaction" + JSON.stringify(transaction, 2, 0))
const transactionReceipt = await promisify(cb => web3.eth.getTransactionReceipt(transactionHash, cb))
console.log("Transaction Receipt" + JSON.stringify(transactionReceipt, 2, 0))
this.setState({ safeAddress: safeInstance.address})
} catch (error) {
console.log("Error while creating the Safe")
}
}
onAddFunds = async (values) => {
const fundsToAdd = values.funds
try {
const { web3, safeAddress } = this.state
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
const txData = {from: accounts[0], to: safeAddress, value: web3.toWei(fundsToAdd, 'ether')}
await promisify(cb => web3.eth.sendTransaction(txData, cb))
const funds = await promisify( cb => web3.eth.getBalance(safeAddress, cb))
const fundsInEther = funds ? web3.fromWei(funds.toNumber(), 'ether') : 0
this.setState({funds: fundsInEther})
} catch (error) {
console.log("Errog adding funds to safe" + error)
}
}
render() {
const { safeAddress, funds } = this.state
return (
<Page>
<PageFrame>
<Form
onSubmit={this.onCallSafeContractSubmit}
render={({ handleSubmit, pristine, invalid }) => (
<form onSubmit={handleSubmit}>
<h2>Create a new Safe instance for testing purposes</h2>
<div>
<Button variant="raised" color="primary" type="submit">
Create Safe
</Button>
</div>
</form>
)}
/>
<Form
onSubmit={this.onAddFunds}
render={({ handleSubmit, pristine, invalid }) => (
<form onSubmit={handleSubmit}>
<h2>Add Funds to the safe</h2>
<div style={{ margin: '10px 0px'}}>
<label style={{ marginRight: '10px' }}>{safeAddress ? safeAddress : 'Not safe detected'}</label>
</div>
{ safeAddress && <div>
<Field name="funds" component={TextField} type="text" placeholder="ETH to add" />
<Button type="submit" disabled={ !safeAddress || pristine || invalid}>
Add funds
</Button>
</div> }
{ safeAddress && <div style={{ margin: '15px 0px'}}>
Total funds in this safe: { funds ? funds : 0 } ETH
</div> }
</form>
)}
/>
<Link to="/transactions">
<Button variant="raised" color="primary">
Go to transactions
</Button>
</Link>
</PageFrame>
</Page>
);
}
}
export default App