Add owner list page to load Safe stepper
This commit is contained in:
parent
b615d20a65
commit
0a22089535
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue