Calculating isOwner property in ReviewInfo component #75

This commit is contained in:
apanizo 2018-11-14 12:45:10 +01:00
parent 936b2bc51c
commit cafbfb38d9
4 changed files with 107 additions and 56 deletions

View File

@ -1,5 +1,6 @@
// @flow // @flow
import * as React from 'react' import * as React from 'react'
import ChevronLeft from '@material-ui/icons/ChevronLeft'
import Stepper from '~/components/Stepper' import Stepper from '~/components/Stepper'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Heading from '~/components/layout/Heading' import Heading from '~/components/layout/Heading'
@ -7,17 +8,15 @@ 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 DetailsForm, { safeFieldsValidation } from '~/routes/load/components/DetailsForm' import DetailsForm, { safeFieldsValidation } from '~/routes/load/components/DetailsForm'
import ChevronLeft from '@material-ui/icons/ChevronLeft'
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'
const getSteps = () => [ const getSteps = () => [
'Details', 'Review', 'Details', 'Review',
] ]
type Props = { type Props = SelectorProps & {
provider: string,
network: string,
onLoadSafeSubmit: (values: Object) => Promise<void>, onLoadSafeSubmit: (values: Object) => Promise<void>,
} }
@ -32,7 +31,7 @@ const back = () => {
} }
const Layout = ({ const Layout = ({
provider, onLoadSafeSubmit, network, provider, onLoadSafeSubmit, network, userAddress,
}: Props) => { }: Props) => {
const steps = getSteps() const steps = getSteps()
@ -54,7 +53,7 @@ const Layout = ({
<Stepper.Page validate={safeFieldsValidation}> <Stepper.Page validate={safeFieldsValidation}>
{ DetailsForm } { DetailsForm }
</Stepper.Page> </Stepper.Page>
<Stepper.Page network={network}> <Stepper.Page network={network} userAddress={userAddress}>
{ ReviewInformation } { ReviewInformation }
</Stepper.Page> </Stepper.Page>
</Stepper> </Stepper>

View File

@ -8,8 +8,10 @@ import OpenPaper from '~/components/Stepper/OpenPaper'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import { xs, sm, lg, border, secondary } from '~/theme/variables' import { xs, sm, lg, border, secondary } from '~/theme/variables'
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3' import { openAddressInEtherScan, getWeb3 } from '~/logic/wallets/getWeb3'
import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields' import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
const openIconStyle = { const openIconStyle = {
height: '16px', height: '16px',
@ -43,6 +45,7 @@ const styles = () => ({
type LayoutProps = { type LayoutProps = {
network: string, network: string,
userAddress: string,
} }
type Props = LayoutProps & { type Props = LayoutProps & {
@ -50,53 +53,92 @@ type Props = LayoutProps & {
classes: Object, classes: Object,
} }
const ReviewComponent = ({ values, classes, network }: Props) => { type State = {
const safeAddress = values[FIELD_LOAD_ADDRESS] isOwner: boolean,
}
return ( class ReviewComponent extends React.PureComponent<Props, State> {
<React.Fragment> state = {
<Block className={classes.details}> isOwner: false,
<Block margin="lg"> }
<Paragraph size="sm" color="disabled" noMargin>
Name of the Safe componentDidMount = async () => {
</Paragraph> this.mounted = true
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
{values[FIELD_LOAD_NAME]} const { values, userAddress } = this.props
</Paragraph> const safeAddress = values[FIELD_LOAD_ADDRESS]
const web3 = getWeb3()
const GnosisSafe = getGnosisSafeContract(web3)
const gnosisSafe = GnosisSafe.at(safeAddress)
const owners = await gnosisSafe.getOwners()
if (!owners) {
return
}
const isOwner = owners.find((owner: string) => sameAddress(owner, userAddress)) !== undefined
if (this.mounted) {
this.setState(() => ({ isOwner }))
}
}
componentWillUnmount() {
this.mounted = false
}
mounted = false
render() {
const { values, classes, network } = this.props
const { isOwner } = this.state
const safeAddress = values[FIELD_LOAD_ADDRESS]
return (
<React.Fragment>
<Block className={classes.details}>
<Block margin="lg">
<Paragraph size="sm" color="disabled" noMargin>
Name of the Safe
</Paragraph>
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
{values[FIELD_LOAD_NAME]}
</Paragraph>
</Block>
<Block margin="lg">
<Paragraph size="sm" color="disabled" noMargin>
Safe address
</Paragraph>
<Row className={classes.container}>
<Identicon address={safeAddress} diameter={32} />
<Paragraph size="md" color="disabled" noMargin className={classes.address}>{safeAddress}</Paragraph>
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(safeAddress, network)}
/>
</Row>
</Block>
<Block margin="lg">
<Paragraph size="sm" color="disabled" noMargin>
Connected wallet client is owner?
</Paragraph>
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
{ isOwner ? 'Yes' : 'No (read-only)' }
</Paragraph>
</Block>
</Block> </Block>
<Block margin="lg"> </React.Fragment>
<Paragraph size="sm" color="disabled" noMargin> )
Safe address }
</Paragraph>
<Row className={classes.container}>
<Identicon address={safeAddress} diameter={32} />
<Paragraph size="md" color="disabled" noMargin className={classes.address}>{safeAddress}</Paragraph>
<OpenInNew
className={classes.open}
style={openIconStyle}
onClick={openAddressInEtherScan(safeAddress, network)}
/>
</Row>
</Block>
<Block margin="lg">
<Paragraph size="sm" color="disabled" noMargin>
Connected wallet client is owner?
</Paragraph>
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
No (read-only)
</Paragraph>
</Block>
</Block>
</React.Fragment>
)
} }
const ReviewPage = withStyles(styles)(ReviewComponent) const ReviewPage = withStyles(styles)(ReviewComponent)
const Review = ({ network }: LayoutProps) => (controls: React$Node, { values }: Object) => ( const Review = ({ network, userAddress }: LayoutProps) => (controls: React$Node, { values }: Object) => (
<React.Fragment> <React.Fragment>
<OpenPaper controls={controls} padding={false}> <OpenPaper controls={controls} padding={false}>
<ReviewPage network={network} values={values} /> <ReviewPage network={network} values={values} userAddress={userAddress} />
</OpenPaper> </OpenPaper>
</React.Fragment> </React.Fragment>
) )

View File

@ -6,16 +6,12 @@ import { buildSafe } from '~/routes/safe/store/actions/fetchSafe'
import { SAFES_KEY, load, saveSafes } from '~/utils/localStorage' import { SAFES_KEY, load, saveSafes } from '~/utils/localStorage'
import { SAFELIST_ADDRESS } from '~/routes/routes' import { SAFELIST_ADDRESS } from '~/routes/routes'
import { history } from '~/store' import { history } from '~/store'
import selector from './selector' import selector, { type SelectorProps } from './selector'
import actions, { type Actions, type UpdateSafe } from './actions' import actions, { type Actions, type UpdateSafe } from './actions'
import Layout from '../components/Layout' import Layout from '../components/Layout'
import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '../components/fields' import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '../components/fields'
type Props = Actions & { type Props = SelectorProps & Actions
provider: string,
userAccount: string,
network: string,
}
export const loadSafe = async (safeName: string, safeAddress: string, updateSafe: UpdateSafe) => { export const loadSafe = async (safeName: string, safeAddress: string, updateSafe: UpdateSafe) => {
const safeRecord = await buildSafe(safeAddress, safeName) const safeRecord = await buildSafe(safeAddress, safeName)
@ -45,7 +41,9 @@ class Open extends React.Component<Props> {
} }
render() { render() {
const { provider, network } = this.props const {
provider, network, userAddress,
} = this.props
return ( return (
<Page> <Page>
@ -53,6 +51,7 @@ class Open extends React.Component<Props> {
network={network} network={network}
provider={provider} provider={provider}
onLoadSafeSubmit={this.onLoadSafeSubmit} onLoadSafeSubmit={this.onLoadSafeSubmit}
userAddress={userAddress}
/> />
</Page> </Page>
) )

View File

@ -1,8 +1,19 @@
// @flow // @flow
import { createStructuredSelector } from 'reselect' import { createStructuredSelector, type Selector } from 'reselect'
import { providerNameSelector, networkSelector } from '~/logic/wallets/store/selectors' import { providerNameSelector, networkSelector, userAccountSelector } from '~/logic/wallets/store/selectors'
import { type GlobalState } from '~/store'
export default createStructuredSelector({ export type SelectorProps = {
provider: string,
network: string,
userAddress: string,
}
const structuredSelector: Selector<GlobalState, any, any> = createStructuredSelector({
provider: providerNameSelector, provider: providerNameSelector,
network: networkSelector, network: networkSelector,
userAddress: userAccountSelector,
}) })
export default structuredSelector