mirror of
https://github.com/status-im/safe-react.git
synced 2025-01-24 08:39:09 +00:00
[Address Book v2] Allow empty owner names when loading a safe (#2390)
* Allow to load new safe with empty owner names * Avoid adding owners to addressbook if name is empty * Remove unnecessary initialization
This commit is contained in:
parent
548d6d26ed
commit
e66040d32f
@ -100,8 +100,12 @@ export const mustBeEthereumContractAddress = memoize(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export const minMaxLength = (minLen: number, maxLen: number) => (value: string): ValidatorReturnType =>
|
export const minMaxLength = (minLen: number, maxLen: number) => (value: string): ValidatorReturnType => {
|
||||||
value.length >= +minLen && value.length <= +maxLen ? undefined : `Should be ${minLen} to ${maxLen} symbols`
|
const testValue = value || ''
|
||||||
|
return testValue.length >= +minLen && testValue.length <= +maxLen
|
||||||
|
? undefined
|
||||||
|
: `Should be ${minLen} to ${maxLen} symbols`
|
||||||
|
}
|
||||||
|
|
||||||
export const minMaxDecimalsLength = (minLen: number, maxLen: number) => (value: string): ValidatorReturnType => {
|
export const minMaxDecimalsLength = (minLen: number, maxLen: number) => (value: string): ValidatorReturnType => {
|
||||||
const decimals = value.split('.')[1] || '0'
|
const decimals = value.split('.')[1] || '0'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import InputAdornment from '@material-ui/core/InputAdornment'
|
import InputAdornment from '@material-ui/core/InputAdornment'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import CheckCircle from '@material-ui/icons/CheckCircle'
|
import CheckCircle from '@material-ui/icons/CheckCircle'
|
||||||
import * as React from 'react'
|
import React, { ReactElement, ReactNode } from 'react'
|
||||||
import { FormApi } from 'final-form'
|
import { FormApi } from 'final-form'
|
||||||
|
|
||||||
import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper'
|
import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper'
|
||||||
@ -68,7 +68,7 @@ interface DetailsFormProps {
|
|||||||
form: FormApi
|
form: FormApi
|
||||||
}
|
}
|
||||||
|
|
||||||
const DetailsForm = ({ errors, form }: DetailsFormProps): React.ReactElement => {
|
const DetailsForm = ({ errors, form }: DetailsFormProps): ReactElement => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
const handleScan = (value: string, closeQrModal: () => void): void => {
|
const handleScan = (value: string, closeQrModal: () => void): void => {
|
||||||
@ -145,13 +145,11 @@ const DetailsForm = ({ errors, form }: DetailsFormProps): React.ReactElement =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DetailsPage = () =>
|
const DetailsPage = () =>
|
||||||
function LoadSafeDetails(controls: React.ReactNode, { errors, form }: StepperPageFormProps): React.ReactElement {
|
function LoadSafeDetails(controls: ReactNode, { errors, form }: StepperPageFormProps): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<OpenPaper controls={controls}>
|
||||||
<OpenPaper controls={controls}>
|
<DetailsForm errors={errors} form={form} />
|
||||||
<DetailsForm errors={errors} form={form} />
|
</OpenPaper>
|
||||||
</OpenPaper>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import IconButton from '@material-ui/core/IconButton'
|
import IconButton from '@material-ui/core/IconButton'
|
||||||
import ChevronLeft from '@material-ui/icons/ChevronLeft'
|
import ChevronLeft from '@material-ui/icons/ChevronLeft'
|
||||||
import * as React from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
|
|
||||||
import Stepper, { StepperPage } from 'src/components/Stepper'
|
import Stepper, { StepperPage } from 'src/components/Stepper'
|
||||||
import Block from 'src/components/layout/Block'
|
import Block from 'src/components/layout/Block'
|
||||||
@ -34,13 +34,12 @@ const formMutators = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface LayoutProps {
|
interface LayoutProps {
|
||||||
network: string
|
|
||||||
provider?: string
|
provider?: string
|
||||||
userAddress: string
|
userAddress: string
|
||||||
onLoadSafeSubmit: (values: LoadFormValues) => void
|
onLoadSafeSubmit: (values: LoadFormValues) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layout = ({ network, onLoadSafeSubmit, provider, userAddress }: LayoutProps): React.ReactElement => (
|
const Layout = ({ onLoadSafeSubmit, provider, userAddress }: LayoutProps): ReactElement => (
|
||||||
<>
|
<>
|
||||||
{provider ? (
|
{provider ? (
|
||||||
<Block>
|
<Block>
|
||||||
@ -58,8 +57,8 @@ const Layout = ({ network, onLoadSafeSubmit, provider, userAddress }: LayoutProp
|
|||||||
testId="load-safe-form"
|
testId="load-safe-form"
|
||||||
>
|
>
|
||||||
<StepperPage validate={safeFieldsValidation} component={DetailsForm} />
|
<StepperPage validate={safeFieldsValidation} component={DetailsForm} />
|
||||||
<StepperPage network={network} component={OwnerList} />
|
<StepperPage component={OwnerList} />
|
||||||
<StepperPage network={network} userAddress={userAddress} component={ReviewInformation} />
|
<StepperPage userAddress={userAddress} component={ReviewInformation} />
|
||||||
</Stepper>
|
</Stepper>
|
||||||
</Block>
|
</Block>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
|
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import TableContainer from '@material-ui/core/TableContainer'
|
import TableContainer from '@material-ui/core/TableContainer'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { ReactElement, ReactNode, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
|
import { getExplorerInfo } from 'src/config'
|
||||||
import Field from 'src/components/forms/Field'
|
import Field from 'src/components/forms/Field'
|
||||||
import TextField from 'src/components/forms/TextField'
|
import TextField from 'src/components/forms/TextField'
|
||||||
import { composeValidators, minMaxLength, required } from 'src/components/forms/validator'
|
import { minMaxLength } from 'src/components/forms/validator'
|
||||||
import Block from 'src/components/layout/Block'
|
import Block from 'src/components/layout/Block'
|
||||||
import Col from 'src/components/layout/Col'
|
import Col from 'src/components/layout/Col'
|
||||||
import Hairline from 'src/components/layout/Hairline'
|
import Hairline from 'src/components/layout/Hairline'
|
||||||
@ -21,8 +22,7 @@ import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
|||||||
import { FIELD_LOAD_ADDRESS, THRESHOLD } from 'src/routes/load/components/fields'
|
import { FIELD_LOAD_ADDRESS, THRESHOLD } from 'src/routes/load/components/fields'
|
||||||
import { getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields'
|
import { getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields'
|
||||||
import { styles } from './styles'
|
import { styles } from './styles'
|
||||||
import { getExplorerInfo } from 'src/config'
|
import { LoadFormValues } from 'src/routes/load/container/Load'
|
||||||
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
|
||||||
|
|
||||||
const calculateSafeValues = (owners, threshold, values) => {
|
const calculateSafeValues = (owners, threshold, values) => {
|
||||||
const initialValues = { ...values }
|
const initialValues = { ...values }
|
||||||
@ -41,10 +41,14 @@ const useAddressBookForOwnersNames = (ownersList: string[]): AddressBookEntry[]
|
|||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const OwnerListComponent = (props) => {
|
interface OwnerListComponentProps {
|
||||||
|
values: LoadFormValues
|
||||||
|
updateInitialProps: (initialValues) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const OwnerListComponent = ({ values, updateInitialProps }: OwnerListComponentProps): ReactElement => {
|
||||||
const [owners, setOwners] = useState<string[]>([])
|
const [owners, setOwners] = useState<string[]>([])
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { updateInitialProps, values } = props
|
|
||||||
|
|
||||||
const ownersWithNames = useAddressBookForOwnersNames(owners)
|
const ownersWithNames = useAddressBookForOwnersNames(owners)
|
||||||
|
|
||||||
@ -88,19 +92,18 @@ const OwnerListComponent = (props) => {
|
|||||||
<Hairline />
|
<Hairline />
|
||||||
<Block margin="md" padding="md">
|
<Block margin="md" padding="md">
|
||||||
{ownersWithNames.map(({ address, name }, index) => {
|
{ownersWithNames.map(({ address, name }, index) => {
|
||||||
const ownerName = name || `Owner #${index + 1}`
|
|
||||||
return (
|
return (
|
||||||
<Row className={classes.owner} key={address} data-testid="owner-row">
|
<Row className={classes.owner} key={address} data-testid="owner-row">
|
||||||
<Col className={classes.ownerName} xs={4}>
|
<Col className={classes.ownerName} xs={4}>
|
||||||
<Field
|
<Field
|
||||||
className={classes.name}
|
className={classes.name}
|
||||||
component={TextField}
|
component={TextField}
|
||||||
initialValue={ownerName}
|
initialValue={name}
|
||||||
name={getOwnerNameBy(index)}
|
name={getOwnerNameBy(index)}
|
||||||
placeholder="Owner Name*"
|
placeholder="Owner Name"
|
||||||
text="Owner Name"
|
text="Owner Name"
|
||||||
type="text"
|
type="text"
|
||||||
validate={composeValidators(required, minMaxLength(1, 50))}
|
validate={minMaxLength(0, 50)}
|
||||||
testId={`load-safe-owner-name-${index}`}
|
testId={`load-safe-owner-name-${index}`}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
@ -118,14 +121,12 @@ const OwnerListComponent = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const OwnerList = ({ updateInitialProps }, network) =>
|
const OwnerList = ({ updateInitialProps }) =>
|
||||||
function LoadSafeOwnerList(controls, { values }): React.ReactElement {
|
function LoadSafeOwnerList(controls: ReactNode, { values }: { values: LoadFormValues }): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<OpenPaper controls={controls} padding={false}>
|
||||||
<OpenPaper controls={controls} padding={false}>
|
<OwnerListComponent updateInitialProps={updateInitialProps} values={values} />
|
||||||
<OwnerListComponent network={network} updateInitialProps={updateInitialProps} values={values} />
|
</OpenPaper>
|
||||||
</OpenPaper>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
||||||
import TableContainer from '@material-ui/core/TableContainer'
|
import TableContainer from '@material-ui/core/TableContainer'
|
||||||
import React from 'react'
|
import React, { ReactElement, ReactNode } from 'react'
|
||||||
|
|
||||||
|
import { getExplorerInfo } from 'src/config'
|
||||||
import Block from 'src/components/layout/Block'
|
import Block from 'src/components/layout/Block'
|
||||||
import Col from 'src/components/layout/Col'
|
import Col from 'src/components/layout/Col'
|
||||||
import Hairline from 'src/components/layout/Hairline'
|
import Hairline from 'src/components/layout/Hairline'
|
||||||
@ -11,8 +13,6 @@ import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME, THRESHOLD } from 'src/routes/load/
|
|||||||
import { getNumOwnersFrom, getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields'
|
import { getNumOwnersFrom, getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields'
|
||||||
import { getAccountsFrom } from 'src/routes/open/utils/safeDataExtractor'
|
import { getAccountsFrom } from 'src/routes/open/utils/safeDataExtractor'
|
||||||
import { useStyles } from './styles'
|
import { useStyles } from './styles'
|
||||||
import { getExplorerInfo } from 'src/config'
|
|
||||||
import { EthHashInfo } from '@gnosis.pm/safe-react-components'
|
|
||||||
import { LoadFormValues } from 'src/routes/load/container/Load'
|
import { LoadFormValues } from 'src/routes/load/container/Load'
|
||||||
|
|
||||||
const checkIfUserAddressIsAnOwner = (values: LoadFormValues, userAddress: string): boolean => {
|
const checkIfUserAddressIsAnOwner = (values: LoadFormValues, userAddress: string): boolean => {
|
||||||
@ -33,108 +33,104 @@ interface Props {
|
|||||||
values: LoadFormValues
|
values: LoadFormValues
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => {
|
const ReviewComponent = ({ userAddress, values }: Props): ReactElement => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const isOwner = checkIfUserAddressIsAnOwner(values, userAddress)
|
const isOwner = checkIfUserAddressIsAnOwner(values, userAddress)
|
||||||
const owners = getAccountsFrom(values)
|
const owners = getAccountsFrom(values)
|
||||||
const safeAddress = values[FIELD_LOAD_ADDRESS]
|
const safeAddress = values[FIELD_LOAD_ADDRESS]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Row className={classes.root}>
|
||||||
<Row className={classes.root}>
|
<Col className={classes.detailsColumn} layout="column" xs={4}>
|
||||||
<Col className={classes.detailsColumn} layout="column" xs={4}>
|
<Block className={classes.details}>
|
||||||
<Block className={classes.details}>
|
<Block margin="lg">
|
||||||
<Block margin="lg">
|
<Paragraph color="primary" noMargin size="lg" data-testid="load-safe-step-three">
|
||||||
<Paragraph color="primary" noMargin size="lg" data-testid="load-safe-step-three">
|
Review details
|
||||||
Review details
|
</Paragraph>
|
||||||
</Paragraph>
|
|
||||||
</Block>
|
|
||||||
<Block margin="lg">
|
|
||||||
<Paragraph color="disabled" noMargin size="sm">
|
|
||||||
Name of the Safe
|
|
||||||
</Paragraph>
|
|
||||||
<Paragraph
|
|
||||||
className={classes.name}
|
|
||||||
color="primary"
|
|
||||||
noMargin
|
|
||||||
size="lg"
|
|
||||||
weight="bolder"
|
|
||||||
data-testid="load-form-review-safe-name"
|
|
||||||
>
|
|
||||||
{values[FIELD_LOAD_NAME]}
|
|
||||||
</Paragraph>
|
|
||||||
</Block>
|
|
||||||
<Block margin="lg">
|
|
||||||
<Paragraph color="disabled" noMargin size="sm">
|
|
||||||
Safe address
|
|
||||||
</Paragraph>
|
|
||||||
<Row className={classes.container}>
|
|
||||||
<EthHashInfo
|
|
||||||
hash={safeAddress}
|
|
||||||
shortenHash={4}
|
|
||||||
showAvatar
|
|
||||||
showCopyBtn
|
|
||||||
explorerUrl={getExplorerInfo(safeAddress)}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
</Block>
|
|
||||||
<Block margin="lg">
|
|
||||||
<Paragraph color="disabled" noMargin size="sm">
|
|
||||||
Connected wallet client is owner?
|
|
||||||
</Paragraph>
|
|
||||||
<Paragraph className={classes.name} color="primary" noMargin size="lg" weight="bolder">
|
|
||||||
{isOwner ? 'Yes' : 'No (read-only)'}
|
|
||||||
</Paragraph>
|
|
||||||
</Block>
|
|
||||||
<Block margin="lg">
|
|
||||||
<Paragraph color="disabled" noMargin size="sm">
|
|
||||||
Any transaction requires the confirmation of:
|
|
||||||
</Paragraph>
|
|
||||||
<Paragraph className={classes.name} color="primary" noMargin size="lg" weight="bolder">
|
|
||||||
{`${values[THRESHOLD]} out of ${getNumOwnersFrom(values)} owners`}
|
|
||||||
</Paragraph>
|
|
||||||
</Block>
|
|
||||||
</Block>
|
</Block>
|
||||||
</Col>
|
<Block margin="lg">
|
||||||
<Col className={classes.ownersColumn} layout="column" xs={8}>
|
<Paragraph color="disabled" noMargin size="sm">
|
||||||
<TableContainer>
|
Name of the Safe
|
||||||
<Block className={classes.owners}>
|
</Paragraph>
|
||||||
<Paragraph color="primary" noMargin size="lg">
|
<Paragraph
|
||||||
{`${getNumOwnersFrom(values)} Safe owners`}
|
className={classes.name}
|
||||||
</Paragraph>
|
color="primary"
|
||||||
</Block>
|
noMargin
|
||||||
<Hairline />
|
size="lg"
|
||||||
{owners.map((address, index) => (
|
weight="bolder"
|
||||||
<>
|
data-testid="load-form-review-safe-name"
|
||||||
<Row className={classes.owner} testId={'load-safe-review-owner-name-' + index}>
|
>
|
||||||
<Col align="center" xs={12}>
|
{values[FIELD_LOAD_NAME]}
|
||||||
<EthHashInfo
|
</Paragraph>
|
||||||
hash={address}
|
</Block>
|
||||||
name={values[getOwnerNameBy(index)]}
|
<Block margin="lg">
|
||||||
showAvatar
|
<Paragraph color="disabled" noMargin size="sm">
|
||||||
showCopyBtn
|
Safe address
|
||||||
explorerUrl={getExplorerInfo(address)}
|
</Paragraph>
|
||||||
/>
|
<Row className={classes.container}>
|
||||||
</Col>
|
<EthHashInfo
|
||||||
</Row>
|
hash={safeAddress}
|
||||||
{index !== owners.length - 1 && <Hairline />}
|
shortenHash={4}
|
||||||
</>
|
showAvatar
|
||||||
))}
|
showCopyBtn
|
||||||
</TableContainer>
|
explorerUrl={getExplorerInfo(safeAddress)}
|
||||||
</Col>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</Block>
|
||||||
|
<Block margin="lg">
|
||||||
|
<Paragraph color="disabled" noMargin size="sm">
|
||||||
|
Connected wallet client is owner?
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph className={classes.name} color="primary" noMargin size="lg" weight="bolder">
|
||||||
|
{isOwner ? 'Yes' : 'No (read-only)'}
|
||||||
|
</Paragraph>
|
||||||
|
</Block>
|
||||||
|
<Block margin="lg">
|
||||||
|
<Paragraph color="disabled" noMargin size="sm">
|
||||||
|
Any transaction requires the confirmation of:
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph className={classes.name} color="primary" noMargin size="lg" weight="bolder">
|
||||||
|
{`${values[THRESHOLD]} out of ${getNumOwnersFrom(values)} owners`}
|
||||||
|
</Paragraph>
|
||||||
|
</Block>
|
||||||
|
</Block>
|
||||||
|
</Col>
|
||||||
|
<Col className={classes.ownersColumn} layout="column" xs={8}>
|
||||||
|
<TableContainer>
|
||||||
|
<Block className={classes.owners}>
|
||||||
|
<Paragraph color="primary" noMargin size="lg">
|
||||||
|
{`${getNumOwnersFrom(values)} Safe owners`}
|
||||||
|
</Paragraph>
|
||||||
|
</Block>
|
||||||
|
<Hairline />
|
||||||
|
{owners.map((address, index) => (
|
||||||
|
<>
|
||||||
|
<Row className={classes.owner} testId={'load-safe-review-owner-name-' + index}>
|
||||||
|
<Col align="center" xs={12}>
|
||||||
|
<EthHashInfo
|
||||||
|
hash={address}
|
||||||
|
name={values[getOwnerNameBy(index)]}
|
||||||
|
showAvatar
|
||||||
|
showCopyBtn
|
||||||
|
explorerUrl={getExplorerInfo(address)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
{index !== owners.length - 1 && <Hairline />}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</TableContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Review = ({ userAddress }: { userAddress: string }) =>
|
const Review = ({ userAddress }: { userAddress: string }) =>
|
||||||
function ReviewPage(controls: React.ReactNode, { values }: { values: LoadFormValues }): React.ReactElement {
|
function ReviewPage(controls: ReactNode, { values }: { values: LoadFormValues }): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<OpenPaper controls={controls} padding={false}>
|
||||||
<OpenPaper controls={controls} padding={false}>
|
<ReviewComponent userAddress={userAddress} values={values} />
|
||||||
<ReviewComponent userAddress={userAddress} values={values} />
|
</OpenPaper>
|
||||||
</OpenPaper>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { ETHEREUM_NETWORK } from 'src/config/networks/network.d'
|
|
||||||
|
|
||||||
import Layout from 'src/routes/load/components/Layout'
|
import Layout from 'src/routes/load/components/Layout'
|
||||||
import { makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook'
|
import { AddressBookEntry, makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook'
|
||||||
import { addressBookSafeLoad } from 'src/logic/addressBook/store/actions'
|
import { addressBookSafeLoad } from 'src/logic/addressBook/store/actions'
|
||||||
import { FIELD_LOAD_ADDRESS } from 'src/routes/load/components/fields'
|
import { FIELD_LOAD_ADDRESS } from 'src/routes/load/components/fields'
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ import { history } from 'src/store'
|
|||||||
import { SafeRecordProps } from 'src/logic/safe/store/models/safe'
|
import { SafeRecordProps } from 'src/logic/safe/store/models/safe'
|
||||||
import { checksumAddress } from 'src/utils/checksumAddress'
|
import { checksumAddress } from 'src/utils/checksumAddress'
|
||||||
import { isValidAddress } from 'src/utils/isValidAddress'
|
import { isValidAddress } from 'src/utils/isValidAddress'
|
||||||
import { networkSelector, providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors'
|
import { providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors'
|
||||||
import { addOrUpdateSafe } from 'src/logic/safe/store/actions/addOrUpdateSafe'
|
import { addOrUpdateSafe } from 'src/logic/safe/store/actions/addOrUpdateSafe'
|
||||||
|
|
||||||
export const loadSafe = async (safeAddress: string, addSafe: (safe: SafeRecordProps) => void): Promise<void> => {
|
export const loadSafe = async (safeAddress: string, addSafe: (safe: SafeRecordProps) => void): Promise<void> => {
|
||||||
@ -51,7 +50,6 @@ export type LoadFormValues = ReviewSafeCreationValues | LoadForm
|
|||||||
const Load = (): ReactElement => {
|
const Load = (): ReactElement => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const provider = useSelector(providerNameSelector)
|
const provider = useSelector(providerNameSelector)
|
||||||
const network = useSelector(networkSelector)
|
|
||||||
const userAddress = useSelector(userAccountSelector)
|
const userAddress = useSelector(userAccountSelector)
|
||||||
|
|
||||||
const addSafeHandler = async (safe: SafeRecordProps) => {
|
const addSafeHandler = async (safe: SafeRecordProps) => {
|
||||||
@ -68,12 +66,17 @@ const Load = (): ReactElement => {
|
|||||||
const ownersNames = getNamesFrom(values)
|
const ownersNames = getNamesFrom(values)
|
||||||
const ownersAddresses = getAccountsFrom(values)
|
const ownersAddresses = getAccountsFrom(values)
|
||||||
|
|
||||||
const owners = ownersAddresses.map((address, index) =>
|
const owners = ownersAddresses.reduce((acc, address, index) => {
|
||||||
makeAddressBookEntry({
|
if (ownersNames[index]) {
|
||||||
address,
|
// Do not add owners to addressbook if names are empty
|
||||||
name: ownersNames[index],
|
const newAddressBookEntry = makeAddressBookEntry({
|
||||||
}),
|
address,
|
||||||
)
|
name: ownersNames[index],
|
||||||
|
})
|
||||||
|
acc.push(newAddressBookEntry)
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [] as AddressBookEntry[])
|
||||||
const safe = makeAddressBookEntry({ address: safeAddress, name: values.name })
|
const safe = makeAddressBookEntry({ address: safeAddress, name: values.name })
|
||||||
await dispatch(addressBookSafeLoad([...owners, safe]))
|
await dispatch(addressBookSafeLoad([...owners, safe]))
|
||||||
|
|
||||||
@ -90,12 +93,7 @@ const Load = (): ReactElement => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<Layout
|
<Layout onLoadSafeSubmit={onLoadSafeSubmit} userAddress={userAddress} provider={provider} />
|
||||||
onLoadSafeSubmit={onLoadSafeSubmit}
|
|
||||||
network={ETHEREUM_NETWORK[network]}
|
|
||||||
userAddress={userAddress}
|
|
||||||
provider={provider}
|
|
||||||
/>
|
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user