Merge pull request #23 from gnosis/feature/WA-238-include-daily-limit
WA-238 - Include daily limit component in UI
This commit is contained in:
commit
23d4ad9a96
|
@ -8,6 +8,14 @@ export const required = (value: Field) => (value ? undefined : 'Required')
|
||||||
export const mustBeNumber = (value: number) =>
|
export const mustBeNumber = (value: number) =>
|
||||||
(Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
|
(Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
|
||||||
|
|
||||||
|
export const greaterThan = (min: number) => (value: string) => {
|
||||||
|
if (Number.isNaN(Number(value)) || Number.parseFloat(value) > Number(min)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Should be greater than ${min}`
|
||||||
|
}
|
||||||
|
|
||||||
export const minValue = (min: number) => (value: string) => {
|
export const minValue = (min: number) => (value: string) => {
|
||||||
if (Number.isNaN(Number(value)) || Number.parseInt(value, 10) >= Number(min)) {
|
if (Number.isNaN(Number(value)) || Number.parseInt(value, 10) >= Number(min)) {
|
||||||
return undefined
|
return undefined
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
// @flow
|
// @flow
|
||||||
import TestUtils from 'react-dom/test-utils'
|
import TestUtils from 'react-dom/test-utils'
|
||||||
import { store } from '~/store'
|
import { store } from '~/store'
|
||||||
import { FIELD_NAME, FIELD_OWNERS, FIELD_CONFIRMATIONS, getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
|
import {
|
||||||
|
FIELD_NAME,
|
||||||
|
FIELD_OWNERS,
|
||||||
|
FIELD_CONFIRMATIONS,
|
||||||
|
FIELD_DAILY_LIMIT,
|
||||||
|
getOwnerNameBy,
|
||||||
|
getOwnerAddressBy,
|
||||||
|
} from '~/routes/open/components/fields'
|
||||||
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
|
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
|
||||||
import { sleep } from '~/utils/timer'
|
import { sleep } from '~/utils/timer'
|
||||||
import { getProviderInfo } from '~/wallets/getWeb3'
|
import { getProviderInfo } from '~/wallets/getWeb3'
|
||||||
|
@ -26,6 +33,9 @@ describe('React DOM TESTS > Create Safe form', () => {
|
||||||
const fieldConfirmations = inputs[2]
|
const fieldConfirmations = inputs[2]
|
||||||
expect(fieldConfirmations.name).toEqual(FIELD_CONFIRMATIONS)
|
expect(fieldConfirmations.name).toEqual(FIELD_CONFIRMATIONS)
|
||||||
|
|
||||||
|
const dailyLimitConfirmations = inputs[3]
|
||||||
|
expect(dailyLimitConfirmations.name).toEqual(FIELD_DAILY_LIMIT)
|
||||||
|
|
||||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
||||||
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||||
|
|
||||||
|
@ -39,6 +49,7 @@ describe('React DOM TESTS > Create Safe form', () => {
|
||||||
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
||||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
|
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
|
||||||
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
|
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
|
||||||
|
TestUtils.Simulate.change(dailyLimitConfirmations, { target: { value: '10' } })
|
||||||
|
|
||||||
const form = TestUtils.findRenderedDOMComponentWithTag(open, 'form')
|
const form = TestUtils.findRenderedDOMComponentWithTag(open, 'form')
|
||||||
// One submit per step when creating a safe
|
// One submit per step when creating a safe
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Col from '~/components/layout/Col'
|
||||||
import Heading from '~/components/layout/Heading'
|
import Heading from '~/components/layout/Heading'
|
||||||
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 { FIELD_NAME, FIELD_CONFIRMATIONS, FIELD_DAILY_LIMIT } from '../fields'
|
||||||
|
|
||||||
type FormProps = {
|
type FormProps = {
|
||||||
values: Object,
|
values: Object,
|
||||||
|
@ -20,10 +21,13 @@ const ReviewInformation = () => ({ values }: FormProps) => {
|
||||||
<Block>
|
<Block>
|
||||||
<Heading tag="h2">Review the Safe information</Heading>
|
<Heading tag="h2">Review the Safe information</Heading>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
<Bold>Safe Name: </Bold> {values.name}
|
<Bold>Safe Name: </Bold> {values[FIELD_NAME]}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
<Bold>Required confirmations: </Bold> {values.confirmations}
|
<Bold>Required confirmations: </Bold> {values[FIELD_CONFIRMATIONS]}
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
<Bold>Daily limit: </Bold> {values[FIELD_DAILY_LIMIT]} ETH
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Heading tag="h3">Owners</Heading>
|
<Heading tag="h3">Owners</Heading>
|
||||||
{ names.map((name, index) => (
|
{ names.map((name, index) => (
|
||||||
|
|
|
@ -49,7 +49,7 @@ describe('React DOM TESTS > Create Safe form', () => {
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
||||||
expect(5).toEqual(muiFields.length)
|
expect(6).toEqual(muiFields.length)
|
||||||
const confirmationsField = muiFields[4]
|
const confirmationsField = muiFields[4]
|
||||||
|
|
||||||
expect(confirmationsField.props.meta.valid).toBe(false)
|
expect(confirmationsField.props.meta.valid).toBe(false)
|
||||||
|
@ -64,7 +64,7 @@ describe('React DOM TESTS > Create Safe form', () => {
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
||||||
expect(7).toEqual(muiFields.length)
|
expect(8).toEqual(muiFields.length)
|
||||||
const confirmationsField = muiFields[6]
|
const confirmationsField = muiFields[6]
|
||||||
|
|
||||||
expect(confirmationsField.props.meta.valid).toBe(false)
|
expect(confirmationsField.props.meta.valid).toBe(false)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react'
|
||||||
|
import Field from '~/components/forms/Field'
|
||||||
|
import TextField from '~/components/forms/TextField'
|
||||||
|
import { composeValidators, mustBeNumber, required, greaterThan } from '~/components/forms/validator'
|
||||||
|
import Block from '~/components/layout/Block'
|
||||||
|
import { FIELD_DAILY_LIMIT } from '~/routes/open/components/fields'
|
||||||
|
|
||||||
|
const DailyLimit = () => (
|
||||||
|
<Block margin="md">
|
||||||
|
<Field
|
||||||
|
name={FIELD_DAILY_LIMIT}
|
||||||
|
component={TextField}
|
||||||
|
type="text"
|
||||||
|
validate={composeValidators(required, mustBeNumber, greaterThan(0))}
|
||||||
|
placeholder="Daily Limit*"
|
||||||
|
text="Daily Limit"
|
||||||
|
/>
|
||||||
|
</Block>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default DailyLimit
|
|
@ -6,6 +6,7 @@ import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||||
import Name from './Name'
|
import Name from './Name'
|
||||||
import Owners from './Owners'
|
import Owners from './Owners'
|
||||||
import Confirmations from './Confirmations'
|
import Confirmations from './Confirmations'
|
||||||
|
import DailyLimit from './DailyLimit'
|
||||||
|
|
||||||
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
|
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
|
||||||
|
|
||||||
|
@ -25,5 +26,6 @@ export default () => ({ values }: Object) => (
|
||||||
<Name />
|
<Name />
|
||||||
<Owners numOwners={values.owners} otherAccounts={getAccountsFrom(values)} />
|
<Owners numOwners={values.owners} otherAccounts={getAccountsFrom(values)} />
|
||||||
<Confirmations />
|
<Confirmations />
|
||||||
|
<DailyLimit />
|
||||||
</Block>
|
</Block>
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
export const FIELD_NAME: string = 'name'
|
export const FIELD_NAME: string = 'name'
|
||||||
export const FIELD_CONFIRMATIONS: string = 'confirmations'
|
export const FIELD_CONFIRMATIONS: string = 'confirmations'
|
||||||
export const FIELD_OWNERS: string = 'owners'
|
export const FIELD_OWNERS: string = 'owners'
|
||||||
|
export const FIELD_DAILY_LIMIT: string = 'limit'
|
||||||
|
|
||||||
export const getOwnerNameBy = (index: number) => `owner${index}Name`
|
export const getOwnerNameBy = (index: number) => `owner${index}Name`
|
||||||
export const getOwnerAddressBy = (index: number) => `owner${index}Address`
|
export const getOwnerAddressBy = (index: number) => `owner${index}Address`
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import contract from 'truffle-contract'
|
import contract from 'truffle-contract'
|
||||||
import Page from '~/components/layout/Page'
|
import Page from '~/components/layout/Page'
|
||||||
import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom } from '~/routes/open/utils/safeDataExtractor'
|
import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom, getDailyLimitFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||||
import { getWeb3 } from '~/wallets/getWeb3'
|
import { getWeb3 } from '~/wallets/getWeb3'
|
||||||
import { promisify } from '~/utils/promisify'
|
import { promisify } from '~/utils/promisify'
|
||||||
import Safe from '#/GnosisSafe.json'
|
import Safe from '#/GnosisSafe.json'
|
||||||
|
@ -26,12 +26,13 @@ const createSafe = async (safeContract, values, userAccount, addSafe) => {
|
||||||
const numConfirmations = getThresholdFrom(values)
|
const numConfirmations = getThresholdFrom(values)
|
||||||
const name = getSafeNameFrom(values)
|
const name = getSafeNameFrom(values)
|
||||||
const owners = getNamesFrom(values)
|
const owners = getNamesFrom(values)
|
||||||
|
const dailyLimit = getDailyLimitFrom(values)
|
||||||
|
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
safeContract.setProvider(web3.currentProvider)
|
safeContract.setProvider(web3.currentProvider)
|
||||||
|
|
||||||
const safe = await safeContract.new(accounts, numConfirmations, 0, 0, { from: userAccount, gas: '5000000' })
|
const safe = await safeContract.new(accounts, numConfirmations, 0, 0, { from: userAccount, gas: '5000000' })
|
||||||
addSafe(name, safe.address, numConfirmations, owners, accounts)
|
addSafe(name, safe.address, numConfirmations, dailyLimit, owners, accounts)
|
||||||
return safe
|
return safe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
export const getDailyLimitFrom = (values: Object): number => Number(values.limit)
|
||||||
|
|
||||||
export const getAccountsFrom = (values: Object): string[] => {
|
export const getAccountsFrom = (values: Object): string[] => {
|
||||||
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Address$/.test(key))
|
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Address$/.test(key))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react'
|
||||||
|
import { ListItem } from 'material-ui/List'
|
||||||
|
import Avatar from 'material-ui/Avatar'
|
||||||
|
import NotificationsPaused from 'material-ui-icons/NotificationsPaused'
|
||||||
|
import ListItemText from '~/components/List/ListItemText'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
limit: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
const DailyLimit = ({ limit }: Props) => (
|
||||||
|
<ListItem>
|
||||||
|
<Avatar>
|
||||||
|
<NotificationsPaused />
|
||||||
|
</Avatar>
|
||||||
|
<ListItemText primary="Daily Limit" secondary={`${limit} ETH`} />
|
||||||
|
</ListItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default DailyLimit
|
|
@ -39,7 +39,7 @@ const Owners = openHoc(({
|
||||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
<List component="div" disablePadding>
|
<List component="div" disablePadding>
|
||||||
{owners.map(owner => (
|
{owners.map(owner => (
|
||||||
<ListItem key={owner.address} button className={classes.nested}>
|
<ListItem key={owner.address} className={classes.nested}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<Person />
|
<Person />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import Address from './Address'
|
||||||
import Balance from './Balance'
|
import Balance from './Balance'
|
||||||
import Owners from './Owners'
|
import Owners from './Owners'
|
||||||
import Confirmations from './Confirmations'
|
import Confirmations from './Confirmations'
|
||||||
|
import DailyLimit from './DailyLimit'
|
||||||
|
|
||||||
type SafeProps = {
|
type SafeProps = {
|
||||||
safe: Safe,
|
safe: Safe,
|
||||||
|
@ -20,6 +21,7 @@ type SafeProps = {
|
||||||
|
|
||||||
const listStyle = {
|
const listStyle = {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
minWidth: '485px',
|
||||||
}
|
}
|
||||||
|
|
||||||
class GnoSafe extends React.PureComponent<SafeProps> {
|
class GnoSafe extends React.PureComponent<SafeProps> {
|
||||||
|
@ -34,6 +36,7 @@ class GnoSafe extends React.PureComponent<SafeProps> {
|
||||||
<Owners owners={safe.owners} />
|
<Owners owners={safe.owners} />
|
||||||
<Confirmations confirmations={safe.get('confirmations')} />
|
<Confirmations confirmations={safe.get('confirmations')} />
|
||||||
<Address address={safe.get('address')} />
|
<Address address={safe.get('address')} />
|
||||||
|
<DailyLimit limit={safe.get('dailyLimit')} />
|
||||||
</List>
|
</List>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={12} center="xs" sm={8} margin="xl" layout="block">
|
<Col xs={12} center="xs" sm={8} margin="xl" layout="block">
|
||||||
|
|
|
@ -15,13 +15,14 @@ export const buildOwnersFrom = (names: string[], addresses: string[]) => {
|
||||||
const addSafe = createAction(
|
const addSafe = createAction(
|
||||||
ADD_SAFE,
|
ADD_SAFE,
|
||||||
(
|
(
|
||||||
name: string, address: string, confirmations: number,
|
name: string, address: string,
|
||||||
|
confirmations: number, dailyLimit: number,
|
||||||
ownersName: string[], ownersAddress: string[],
|
ownersName: string[], ownersAddress: string[],
|
||||||
): SafeProps => {
|
): SafeProps => {
|
||||||
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
address, name, confirmations, owners,
|
address, name, confirmations, owners, dailyLimit,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,6 +8,7 @@ export type SafeProps = {
|
||||||
address: string,
|
address: string,
|
||||||
confirmations: number,
|
confirmations: number,
|
||||||
owners: List<Owner>,
|
owners: List<Owner>,
|
||||||
|
dailyLimit: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeSafe: RecordFactory<SafeProps> = Record({
|
export const makeSafe: RecordFactory<SafeProps> = Record({
|
||||||
|
@ -15,6 +16,7 @@ export const makeSafe: RecordFactory<SafeProps> = Record({
|
||||||
address: '',
|
address: '',
|
||||||
confirmations: 0,
|
confirmations: 0,
|
||||||
owners: List([]),
|
owners: List([]),
|
||||||
|
dailyLimit: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
export type Safe = RecordOf<SafeProps>
|
export type Safe = RecordOf<SafeProps>
|
||||||
|
|
|
@ -33,6 +33,7 @@ const deploySafe = async (safe: React$Component<{}>) => {
|
||||||
const fieldName = inputs[0]
|
const fieldName = inputs[0]
|
||||||
const fieldOwners = inputs[1]
|
const fieldOwners = inputs[1]
|
||||||
const fieldConfirmations = inputs[2]
|
const fieldConfirmations = inputs[2]
|
||||||
|
const fieldDailyLimit = inputs[3]
|
||||||
|
|
||||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
||||||
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
||||||
|
@ -41,6 +42,7 @@ const deploySafe = async (safe: React$Component<{}>) => {
|
||||||
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
||||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
|
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
|
||||||
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
|
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
|
||||||
|
TestUtils.Simulate.change(fieldDailyLimit, { target: { value: '10' } })
|
||||||
|
|
||||||
const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form')
|
const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form')
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@ class SafeBuilder {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withDailyLimit(limit: number) {
|
||||||
|
this.safe = this.safe.set('dailyLimit', limit)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
withOwner(names: string[], adresses: string[]) {
|
withOwner(names: string[], adresses: string[]) {
|
||||||
const owners = buildOwnersFrom(names, adresses)
|
const owners = buildOwnersFrom(names, adresses)
|
||||||
this.safe = this.safe.set('owners', owners)
|
this.safe = this.safe.set('owners', owners)
|
||||||
|
@ -42,6 +47,7 @@ export class SafeFactory {
|
||||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0025')
|
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0025')
|
||||||
.withName('Adol ICO Safe')
|
.withName('Adol ICO Safe')
|
||||||
.withConfirmations(1)
|
.withConfirmations(1)
|
||||||
|
.withDailyLimit(10)
|
||||||
.withOwner(['Adol Metamask'], ['0x03db1a8b26d08df23337e9276a36b474510f0023'])
|
.withOwner(['Adol Metamask'], ['0x03db1a8b26d08df23337e9276a36b474510f0023'])
|
||||||
.get()
|
.get()
|
||||||
|
|
||||||
|
|
|
@ -23,27 +23,31 @@ const aStore = (initState) => {
|
||||||
const providerReducerTests = () => {
|
const providerReducerTests = () => {
|
||||||
describe('Safe Actions[addSafe]', () => {
|
describe('Safe Actions[addSafe]', () => {
|
||||||
let store
|
let store
|
||||||
|
let address
|
||||||
|
let formValues
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store = aStore()
|
store = aStore()
|
||||||
})
|
address = '0x03db1a8b26d08df23337e9276a36b474510f0025'
|
||||||
|
formValues = {
|
||||||
it('reducer should return SafeRecord from form values', () => {
|
|
||||||
// GIVEN
|
|
||||||
const address = '0x03db1a8b26d08df23337e9276a36b474510f0025'
|
|
||||||
const formValues = {
|
|
||||||
[SafeFields.FIELD_NAME]: 'Adol ICO Safe',
|
[SafeFields.FIELD_NAME]: 'Adol ICO Safe',
|
||||||
[SafeFields.FIELD_CONFIRMATIONS]: 1,
|
[SafeFields.FIELD_CONFIRMATIONS]: 1,
|
||||||
[SafeFields.FIELD_OWNERS]: 1,
|
[SafeFields.FIELD_OWNERS]: 1,
|
||||||
|
[SafeFields.FIELD_DAILY_LIMIT]: 10,
|
||||||
[SafeFields.getOwnerAddressBy(0)]: '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
[SafeFields.getOwnerAddressBy(0)]: '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
||||||
[SafeFields.getOwnerNameBy(0)]: 'Adol Metamask',
|
[SafeFields.getOwnerNameBy(0)]: 'Adol Metamask',
|
||||||
address,
|
address,
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reducer should return SafeRecord from form values', () => {
|
||||||
|
// GIVEN in beforeEach method
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
store.dispatch(addSafe(
|
store.dispatch(addSafe(
|
||||||
formValues[SafeFields.FIELD_NAME],
|
formValues[SafeFields.FIELD_NAME],
|
||||||
formValues.address,
|
formValues.address,
|
||||||
formValues[SafeFields.FIELD_CONFIRMATIONS],
|
formValues[SafeFields.FIELD_CONFIRMATIONS],
|
||||||
|
formValues[SafeFields.FIELD_DAILY_LIMIT],
|
||||||
getNamesFrom(formValues),
|
getNamesFrom(formValues),
|
||||||
getAccountsFrom(formValues),
|
getAccountsFrom(formValues),
|
||||||
))
|
))
|
||||||
|
@ -54,22 +58,14 @@ const providerReducerTests = () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('reducer loads information from localStorage', async () => {
|
it('reducer loads information from localStorage', async () => {
|
||||||
// GIVEN
|
// GIVEN in beforeEach method
|
||||||
const address = '0x03db1a8b26d08df23337e9276a36b474510f0025'
|
|
||||||
const formValues = {
|
|
||||||
[SafeFields.FIELD_NAME]: 'Adol ICO Safe',
|
|
||||||
[SafeFields.FIELD_CONFIRMATIONS]: 1,
|
|
||||||
[SafeFields.FIELD_OWNERS]: 1,
|
|
||||||
[SafeFields.getOwnerAddressBy(0)]: '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
|
||||||
[SafeFields.getOwnerNameBy(0)]: 'Adol Metamask',
|
|
||||||
address,
|
|
||||||
}
|
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
store.dispatch(addSafe(
|
store.dispatch(addSafe(
|
||||||
formValues[SafeFields.FIELD_NAME],
|
formValues[SafeFields.FIELD_NAME],
|
||||||
formValues.address,
|
formValues.address,
|
||||||
formValues[SafeFields.FIELD_CONFIRMATIONS],
|
formValues[SafeFields.FIELD_CONFIRMATIONS],
|
||||||
|
formValues[SafeFields.FIELD_DAILY_LIMIT],
|
||||||
getNamesFrom(formValues),
|
getNamesFrom(formValues),
|
||||||
getAccountsFrom(formValues),
|
getAccountsFrom(formValues),
|
||||||
))
|
))
|
||||||
|
|
|
@ -19,6 +19,7 @@ const SafeTable = ({ safes }: Props) => (
|
||||||
<TableCell>Deployed Address</TableCell>
|
<TableCell>Deployed Address</TableCell>
|
||||||
<TableCell numeric>Confirmations</TableCell>
|
<TableCell numeric>Confirmations</TableCell>
|
||||||
<TableCell numeric>Number of owners</TableCell>
|
<TableCell numeric>Number of owners</TableCell>
|
||||||
|
<TableCell numeric>Daily Limit</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -29,10 +30,11 @@ const SafeTable = ({ safes }: Props) => (
|
||||||
<Button variant="raised" size="small" color="primary">Open</Button>
|
<Button variant="raised" size="small" color="primary">Open</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell padding="none">{safe.name}</TableCell>
|
<TableCell padding="none">{safe.get('name')}</TableCell>
|
||||||
<TableCell padding="none">{safe.address}</TableCell>
|
<TableCell padding="none">{safe.get('address')}</TableCell>
|
||||||
<TableCell padding="none" numeric>{safe.confirmations}</TableCell>
|
<TableCell padding="none" numeric>{safe.get('confirmations')}</TableCell>
|
||||||
<TableCell padding="none" numeric>{safe.owners.count()}</TableCell>
|
<TableCell padding="none" numeric>{safe.get('owners').count()}</TableCell>
|
||||||
|
<TableCell padding="none" numeric>{`${safe.get('dailyLimit')} ETH`}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
|
|
Loading…
Reference in New Issue