Merge pull request #22 from gnosis/feature/WA-238-add-daily-limit
WA-238 - Refactor Safe component
This commit is contained in:
commit
92f092c0d1
|
@ -104,7 +104,8 @@
|
|||
"material-ui-icons": "^1.0.0-beta.35",
|
||||
"react-final-form": "^3.1.2",
|
||||
"react-loadable": "^5.3.1",
|
||||
"react-router-dom": "^4.2.2"
|
||||
"react-router-dom": "^4.2.2",
|
||||
"recompose": "^0.27.0"
|
||||
},
|
||||
"jest": {
|
||||
"verbose": true,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { ListItemText } from 'material-ui/List'
|
||||
import { withStyles } from 'material-ui/styles'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
|
||||
type Props = WithStyles & {
|
||||
primary: string,
|
||||
secondary: string,
|
||||
cut?: boolean,
|
||||
}
|
||||
|
||||
const styles = {
|
||||
itemTextSecondary: {
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
}
|
||||
|
||||
const GnoListItemText = ({
|
||||
primary, secondary, classes, cut = false,
|
||||
}: Props) => {
|
||||
const cutStyle = cut ? {
|
||||
secondary: classes.itemTextSecondary,
|
||||
} : undefined
|
||||
|
||||
return (
|
||||
<ListItemText
|
||||
classes={cutStyle}
|
||||
inset
|
||||
primary={primary}
|
||||
secondary={secondary}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default withStyles(styles)(GnoListItemText)
|
|
@ -0,0 +1,12 @@
|
|||
// @flow
|
||||
import { withStateHandlers } from 'recompose'
|
||||
|
||||
export type Open = {
|
||||
open: boolean,
|
||||
toggle: () => void,
|
||||
}
|
||||
|
||||
export default withStateHandlers(
|
||||
() => ({ open: false }),
|
||||
{ toggle: ({ open }) => () => ({ open: !open }) },
|
||||
)
|
|
@ -11,7 +11,7 @@ type Size = 'sm' | 'md' | 'lg' | 'xl'
|
|||
type Props = {
|
||||
margin?: Size,
|
||||
padding?: Size,
|
||||
center?: boolean,
|
||||
align?: 'center' | 'right',
|
||||
children: React$Node,
|
||||
className?: string,
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ type Props = {
|
|||
class Block extends PureComponent<Props> {
|
||||
render() {
|
||||
const {
|
||||
margin, padding, center, children, className, ...props
|
||||
margin, padding, align, children, className, ...props
|
||||
} = this.props
|
||||
|
||||
const paddingStyle = padding ? capitalize(padding, 'padding') : undefined
|
||||
return (
|
||||
<div className={cx(className, 'block', margin, paddingStyle, { center })} {...props}>
|
||||
<div className={cx(className, 'block', margin, paddingStyle, align)} {...props}>
|
||||
{ children }
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
.block {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -41,3 +40,9 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
|
@ -16,6 +16,7 @@ type Props = {
|
|||
around?: 'xs' | 'sm' | 'md' | 'lg',
|
||||
between?: 'xs' | 'sm' | 'md' | 'lg',
|
||||
margin?: 'sm' | 'md' | 'lg' | 'xl',
|
||||
layout?: 'inherit' | 'block',
|
||||
xs?: number | boolean,
|
||||
sm?: number | boolean,
|
||||
md?: number | boolean,
|
||||
|
@ -29,7 +30,7 @@ type Props = {
|
|||
}
|
||||
|
||||
const Col = ({
|
||||
children, margin,
|
||||
children, margin, layout = 'inherit',
|
||||
xs, sm, md, lg,
|
||||
start, center, end, top, middle, bottom, around, between,
|
||||
xsOffset, smOffset, mdOffset, lgOffset,
|
||||
|
@ -54,6 +55,7 @@ const Col = ({
|
|||
smOffset ? capitalize(smOffset, 'smOffset') : undefined,
|
||||
mdOffset ? capitalize(mdOffset, 'mdOffset') : undefined,
|
||||
lgOffset ? capitalize(lgOffset, 'lgOffset') : undefined,
|
||||
layout,
|
||||
props.className,
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
.col {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.inherit {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.marginSm {
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Table, { TableBody, TableCell, TableHead, TableRow } from '~/components/layout/Table'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
|
||||
type SafeProps = {
|
||||
safe: Safe,
|
||||
balance: string,
|
||||
}
|
||||
|
||||
const GnoSafe = ({ safe, balance }: SafeProps) => (
|
||||
<React.Fragment>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<Paragraph size="lg">
|
||||
<Bold>{safe.name.toUpperCase()}</Bold>
|
||||
</Paragraph>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Paragraph size="lg">
|
||||
<Bold>Balance</Bold>
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row>
|
||||
<Block>
|
||||
<Paragraph>
|
||||
{balance} - ETH
|
||||
</Paragraph>
|
||||
</Block>
|
||||
</Row>
|
||||
<Row>
|
||||
<Paragraph size="lg">
|
||||
<Bold>Address</Bold>
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row>
|
||||
<Block>
|
||||
<Paragraph>
|
||||
{safe.address}
|
||||
</Paragraph>
|
||||
</Block>
|
||||
</Row>
|
||||
<Row>
|
||||
<Paragraph size="lg">
|
||||
<Bold>Number of required confirmations per transaction</Bold>
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row>
|
||||
<Paragraph>
|
||||
{safe.get('confirmations')}
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row>
|
||||
<Paragraph size="lg">
|
||||
<Bold>Owners</Bold>
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row margin="lg">
|
||||
<Table size={700}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Name</TableCell>
|
||||
<TableCell>Adress</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{safe.owners.map(owner => (
|
||||
<TableRow key={safe.address}>
|
||||
<TableCell>{owner.name}</TableCell>
|
||||
<TableCell>{owner.address}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div />
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
export default GnoSafe
|
|
@ -0,0 +1,21 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { ListItem } from 'material-ui/List'
|
||||
import Avatar from 'material-ui/Avatar'
|
||||
import Mail from 'material-ui-icons/Mail'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
}
|
||||
|
||||
const Address = ({ address }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<Mail />
|
||||
</Avatar>
|
||||
<ListItemText primary="Safe Address" secondary={address} cut />
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Address
|
|
@ -0,0 +1,20 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { ListItem, ListItemText } from 'material-ui/List'
|
||||
import Avatar from 'material-ui/Avatar'
|
||||
import AccountBalance from 'material-ui-icons/AccountBalance'
|
||||
|
||||
type Props = {
|
||||
balance: string,
|
||||
}
|
||||
|
||||
const Balance = ({ balance }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<AccountBalance />
|
||||
</Avatar>
|
||||
<ListItemText primary="Balance" secondary={`${balance} ETH`} />
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Balance
|
|
@ -0,0 +1,25 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { ListItem } from 'material-ui/List'
|
||||
import Avatar from 'material-ui/Avatar'
|
||||
import DoneAll from 'material-ui-icons/DoneAll'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
|
||||
type Props = {
|
||||
confirmations: number,
|
||||
}
|
||||
|
||||
const Confirmations = ({ confirmations }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<DoneAll />
|
||||
</Avatar>
|
||||
<ListItemText
|
||||
primary="Confirmations"
|
||||
secondary={`${confirmations} required confirmations per transaction`}
|
||||
cut
|
||||
/>
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Confirmations
|
|
@ -0,0 +1,58 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { withStyles } from 'material-ui/styles'
|
||||
import Collapse from 'material-ui/transitions/Collapse'
|
||||
import ListItemText from '~/components/List/ListItemText'
|
||||
import List, { ListItem, ListItemIcon } from 'material-ui/List'
|
||||
import Avatar from 'material-ui/Avatar'
|
||||
import Group from 'material-ui-icons/Group'
|
||||
import Person from 'material-ui-icons/Person'
|
||||
import ExpandLess from 'material-ui-icons/ExpandLess'
|
||||
import ExpandMore from 'material-ui-icons/ExpandMore'
|
||||
import { type OwnerProps } from '~/routes/safe/store/model/owner'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
|
||||
const styles = {
|
||||
nested: {
|
||||
paddingLeft: '40px',
|
||||
},
|
||||
}
|
||||
|
||||
type Props = Open & WithStyles & {
|
||||
owners: List<OwnerProps>,
|
||||
}
|
||||
|
||||
const Owners = openHoc(({
|
||||
open, toggle, owners, classes,
|
||||
}: Props) => (
|
||||
<React.Fragment>
|
||||
<ListItem onClick={toggle}>
|
||||
<Avatar>
|
||||
<Group />
|
||||
</Avatar>
|
||||
<ListItemText primary="Owners" secondary={`${owners.size} owners`} />
|
||||
<ListItemIcon>
|
||||
{open ? <ExpandLess /> : <ExpandMore />}
|
||||
</ListItemIcon>
|
||||
</ListItem>
|
||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||
<List component="div" disablePadding>
|
||||
{owners.map(owner => (
|
||||
<ListItem key={owner.address} button className={classes.nested}>
|
||||
<ListItemIcon>
|
||||
<Person />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
cut
|
||||
primary={owner.name}
|
||||
secondary={owner.address}
|
||||
/>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
))
|
||||
|
||||
export default withStyles(styles)(Owners)
|
|
@ -0,0 +1,58 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
import List from 'material-ui/List'
|
||||
|
||||
import Address from './Address'
|
||||
import Balance from './Balance'
|
||||
import Owners from './Owners'
|
||||
import Confirmations from './Confirmations'
|
||||
|
||||
type SafeProps = {
|
||||
safe: Safe,
|
||||
balance: string,
|
||||
}
|
||||
|
||||
const listStyle = {
|
||||
width: '100%',
|
||||
}
|
||||
|
||||
class GnoSafe extends React.PureComponent<SafeProps> {
|
||||
render() {
|
||||
const { safe, balance } = this.props
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col xs={12} top="xs" sm={4} margin="xl">
|
||||
<List style={listStyle}>
|
||||
<Balance balance={balance} />
|
||||
<Owners owners={safe.owners} />
|
||||
<Confirmations confirmations={safe.get('confirmations')} />
|
||||
<Address address={safe.get('address')} />
|
||||
</List>
|
||||
</Col>
|
||||
<Col xs={12} center="xs" sm={8} margin="xl" layout="block">
|
||||
<Block margin="xl">
|
||||
<Paragraph size="lg" noMargin align="right">
|
||||
<Bold>{safe.name.toUpperCase()}</Bold>
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Block>
|
||||
Extra info will be placed here
|
||||
</Block>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
<Paragraph size="lg">
|
||||
<Bold>{safe.name.toUpperCase()}</Bold>
|
||||
*/
|
||||
export default GnoSafe
|
|
@ -1,7 +1,12 @@
|
|||
import red from 'material-ui/colors/red';
|
||||
// @flow
|
||||
import red from 'material-ui/colors/red'
|
||||
import { createMuiTheme } from 'material-ui/styles'
|
||||
import { primary, secondary } from './variables'
|
||||
|
||||
export type WithStyles = {
|
||||
classes: Object,
|
||||
}
|
||||
|
||||
const palette = {
|
||||
primary: {
|
||||
main: primary,
|
||||
|
@ -18,7 +23,7 @@ const palette = {
|
|||
// see https://github.com/mui-org/material-ui/blob/v1-beta/src/styles/createMuiTheme.js
|
||||
export default createMuiTheme({
|
||||
typography: {
|
||||
fontFamily: 'Montserrat,sans-serif'
|
||||
fontFamily: 'Montserrat,sans-serif',
|
||||
},
|
||||
palette,
|
||||
})
|
||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -9249,6 +9249,10 @@ react-lifecycles-compat@^1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-1.0.2.tgz#551d8b1d156346e5fcf30ffac9b32ce3f78b8850"
|
||||
|
||||
react-lifecycles-compat@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.2.tgz#7279047275bd727a912e25f734c0559527e84eff"
|
||||
|
||||
react-loadable@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.3.1.tgz#9699e9a08fed49bacd69caaa282034b62a76bcdd"
|
||||
|
@ -9559,6 +9563,17 @@ recompose@^0.26.0:
|
|||
hoist-non-react-statics "^2.3.1"
|
||||
symbol-observable "^1.0.4"
|
||||
|
||||
recompose@^0.27.0:
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.27.0.tgz#8230ebd651bf1159097006f79083fe224b1501cf"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
change-emitter "^0.1.2"
|
||||
fbjs "^0.8.1"
|
||||
hoist-non-react-statics "^2.3.1"
|
||||
react-lifecycles-compat "^3.0.2"
|
||||
symbol-observable "^1.0.4"
|
||||
|
||||
recursive-readdir@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99"
|
||||
|
|
Loading…
Reference in New Issue