Add owner list page to load Safe stepper

This commit is contained in:
Germán Martínez 2019-05-20 09:57:48 +02:00
parent b615d20a65
commit 0a22089535
2 changed files with 184 additions and 2 deletions

View File

@ -7,12 +7,13 @@ import Heading from '~/components/layout/Heading'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import IconButton from '@material-ui/core/IconButton' import IconButton from '@material-ui/core/IconButton'
import ReviewInformation from '~/routes/load/components/ReviewInformation' import ReviewInformation from '~/routes/load/components/ReviewInformation'
import OwnerList from '~/routes/load/components/OwnerList'
import DetailsForm, { safeFieldsValidation } from '~/routes/load/components/DetailsForm' import DetailsForm, { safeFieldsValidation } from '~/routes/load/components/DetailsForm'
import { history } from '~/store' import { history } from '~/store'
import { secondary } from '~/theme/variables' import { secondary } from '~/theme/variables'
import { type SelectorProps } from '~/routes/load/container/selector' import { type SelectorProps } from '~/routes/load/container/selector'
const getSteps = () => ['Details', 'Review'] const getSteps = () => ['Details', 'Owners', 'Review']
type Props = SelectorProps & { type Props = SelectorProps & {
onLoadSafeSubmit: (values: Object) => Promise<void>, onLoadSafeSubmit: (values: Object) => Promise<void>,
@ -45,13 +46,14 @@ const Layout = ({
</Row> </Row>
<Stepper onSubmit={onLoadSafeSubmit} steps={steps} testId="load-safe-form"> <Stepper onSubmit={onLoadSafeSubmit} steps={steps} testId="load-safe-form">
<Stepper.Page validate={safeFieldsValidation}>{DetailsForm}</Stepper.Page> <Stepper.Page validate={safeFieldsValidation}>{DetailsForm}</Stepper.Page>
<Stepper.Page network={network}>{OwnerList}</Stepper.Page>
<Stepper.Page network={network} userAddress={userAddress}> <Stepper.Page network={network} userAddress={userAddress}>
{ReviewInformation} {ReviewInformation}
</Stepper.Page> </Stepper.Page>
</Stepper> </Stepper>
</Block> </Block>
) : ( ) : (
<div>No metamask detected</div> <div>No account detected</div>
)} )}
</React.Fragment> </React.Fragment>
) )

View File

@ -0,0 +1,180 @@
// @flow
import * as React from 'react'
import Block from '~/components/layout/Block'
import { withStyles } from '@material-ui/core/styles'
import Field from '~/components/forms/Field'
import { required } from '~/components/forms/validator'
import TextField from '~/components/forms/TextField'
import OpenInNew from '@material-ui/icons/OpenInNew'
import Identicon from '~/components/Identicon'
import OpenPaper from '~/components/Stepper/OpenPaper'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph'
import Hairline from '~/components/layout/Hairline'
import {
xs, sm, md, lg, border, secondary,
} from '~/theme/variables'
import { getOwnerNameBy } from '~/routes/open/components/fields'
import { getEtherScanLink, getWeb3 } from '~/logic/wallets/getWeb3'
import { FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields'
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
const openIconStyle = {
height: '16px',
color: secondary,
}
const styles = () => ({
details: {
padding: lg,
borderRight: `solid 1px ${border}`,
height: '100%',
},
owners: {
display: 'flex',
justifyContent: 'flex-start',
},
ownerNames: {
maxWidth: '400px',
},
ownerAddresses: {
alignItems: 'center',
marginLeft: `${sm}`,
},
address: {
paddingLeft: '6px',
},
open: {
paddingLeft: sm,
width: 'auto',
'&:hover': {
cursor: 'pointer',
},
},
title: {
padding: `${md} ${lg}`,
},
owner: {
padding: `0 ${lg}`,
marginBottom: '12px',
},
header: {
padding: `${sm} ${lg}`,
},
name: {
marginRight: `${sm}`,
},
})
type LayoutProps = {
network: string,
}
type Props = LayoutProps & {
values: Object,
classes: Object,
}
type State = {
owners: Array<string>,
}
class OwnerListComponent extends React.PureComponent<Props, State> {
state = {
owners: [],
}
mounted = false
componentDidMount = async () => {
this.mounted = true
const { values } = this.props
const safeAddress = values[FIELD_LOAD_ADDRESS]
const web3 = getWeb3()
const GnosisSafe = getGnosisSafeContract(web3)
const gnosisSafe = await GnosisSafe.at(safeAddress)
const owners = await gnosisSafe.getOwners()
if (!owners) {
return
}
if (this.mounted) {
this.setState(() => ({ owners: owners.sort() }))
}
}
componentWillUnmount() {
this.mounted = false
}
render() {
const { network, classes } = this.props
const { owners } = this.state
return (
<React.Fragment>
<Block className={classes.title}>
<Paragraph noMargin size="md" color="primary">
{`This Safe has ${owners.length} owners. Optional: Provide a name for each owner.`}
</Paragraph>
</Block>
<Hairline />
<Row className={classes.header}>
<Col xs={4}>NAME</Col>
<Col xs={8}>ADDRESS</Col>
</Row>
<Hairline />
<Block margin="md" padding="md">
{ owners.map((x, index) => (
<Row key={`owner${(index)}`} className={classes.owner}>
<Col xs={4}>
<Field
className={classes.name}
name={getOwnerNameBy(index)}
component={TextField}
type="text"
validate={required}
defaultValue={`Owner #${index + 1}`}
placeholder="Owner Name*"
text="Owner Name"
/>
</Col>
<Col xs={7}>
<Row className={classes.ownerAddresses}>
<Identicon address={owners[index]} diameter={32} />
<Paragraph size="md" color="disabled" noMargin className={classes.address}>
{owners[index]}
</Paragraph>
<Link className={classes.open} to={getEtherScanLink(owners[index], network)} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Row>
</Col>
</Row>
)) }
</Block>
</React.Fragment>
)
}
}
const OwnerListPage = withStyles(styles)(OwnerListComponent)
const OwnerList = (network: string) => (controls: React$Node, { values }: Object) => (
<React.Fragment>
<OpenPaper controls={controls} padding={false}>
<OwnerListPage
network={network}
values={values}
/>
</OpenPaper>
</React.Fragment>
)
export default OwnerList