(Fix) Basic mobile responsiveness (#532)

* (fix) header mobile version

* (fix) send / receive responsive

* (fix) footer overflowing

* (fix) responsive settings menu

* (fix) scrolling menu tabs

* (fix) responsive tables

* (fix) a few modal windows' responsive issues

* (remove) unused files

* (fix) sidebar responsive

* (fix) load safe responsive

* (fix) create safe responsiveness

* (fix) text wrap

* (fix) remove modal responsiveness

* (fix) name wrap

* (update) yarn.lock
This commit is contained in:
Gabriel Rodríguez Alsina 2020-02-06 12:40:29 -03:00 committed by GitHub
parent 16b3dc0f2a
commit 165a088b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 972 additions and 1369 deletions

View File

@ -8,6 +8,6 @@
<title>Gnosis Safe Multisig</title> <title>Gnosis Safe Multisig</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root" style="overflow: hidden;"></div>
</body> </body>
</html> </html>

View File

@ -51,7 +51,6 @@ const useStyles = makeStyles({
gridTemplateColumns: '1fr', gridTemplateColumns: '1fr',
paddingBottom: '30px', paddingBottom: '30px',
rowGap: '10px', rowGap: '10px',
[`@media (min-width: ${screenSm}px)`]: { [`@media (min-width: ${screenSm}px)`]: {
gridTemplateColumns: '1fr 1fr 1fr', gridTemplateColumns: '1fr 1fr 1fr',
paddingBottom: '0', paddingBottom: '0',

View File

@ -10,8 +10,10 @@ import GnoButtonLink from '~/components/layout/ButtonLink'
const useStyles = makeStyles({ const useStyles = makeStyles({
footer: { footer: {
boxSizing: 'border-box',
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
flexShrink: '1',
flexWrap: 'wrap', flexWrap: 'wrap',
justifyContent: 'center', justifyContent: 'center',
margin: '0 auto', margin: '0 auto',
@ -54,11 +56,10 @@ const Footer = () => {
return ( return (
<footer className={classes.footer}> <footer className={classes.footer}>
<span className={classes.item}> <span className={classes.item}>
© ©
{' '}
{date.getFullYear()} {date.getFullYear()}
{' '} {' '}
Gnosis Gnosis
</span> </span>
<span className={classes.sep}>|</span> <span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/terms" target="_blank"> <Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/terms" target="_blank">
@ -85,7 +86,11 @@ const Footer = () => {
Preferences Preferences
</GnoButtonLink> </GnoButtonLink>
<span className={classes.sep}>|</span> <span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://github.com/gnosis/safe-react/releases" target="_blank"> <Link
className={cn(classes.item, classes.link)}
to="https://github.com/gnosis/safe-react/releases"
target="_blank"
>
{appVersion} {appVersion}
</Link> </Link>
</footer> </footer>

View File

@ -4,14 +4,19 @@ import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord' import Dot from '@material-ui/icons/FiberManualRecord'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Img from '~/components/layout/Img' import Img from '~/components/layout/Img'
import { fancy, border, warning } from '~/theme/variables' import {
fancy, border, warning, screenSm,
} from '~/theme/variables'
const key = require('../assets/key.svg') const key = require('../assets/key.svg')
const triangle = require('../assets/triangle.svg') const triangle = require('../assets/triangle.svg')
const styles = () => ({ const styles = () => ({
root: { root: {
display: 'flex', display: 'none',
[`@media (min-width: ${screenSm}px)`]: {
display: 'flex',
},
}, },
dot: { dot: {
position: 'relative', position: 'relative',

View File

@ -13,7 +13,7 @@ import Img from '~/components/layout/Img'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import Spacer from '~/components/Spacer' import Spacer from '~/components/Spacer'
import { import {
border, sm, md, headerHeight, border, sm, md, headerHeight, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import Provider from './Provider' import Provider from './Provider'
import NetworkLabel from './NetworkLabel' import NetworkLabel from './NetworkLabel'
@ -30,26 +30,34 @@ type Props = Open & {
const styles = () => ({ const styles = () => ({
root: { root: {
backgroundColor: 'white', backgroundColor: 'white',
padding: 0,
boxShadow: '0 0 10px 0 rgba(33, 48, 77, 0.1)',
minWidth: '280px',
borderRadius: sm, borderRadius: sm,
boxShadow: '0 0 10px 0 rgba(33, 48, 77, 0.1)',
marginTop: '11px', marginTop: '11px',
minWidth: '280px',
padding: 0,
}, },
summary: { summary: {
borderBottom: `solid 2px ${border}`,
alignItems: 'center', alignItems: 'center',
height: headerHeight,
boxShadow: '0 2px 4px 0 rgba(212, 212, 211, 0.59)',
backgroundColor: 'white', backgroundColor: 'white',
zIndex: 1301, borderBottom: `solid 2px ${border}`,
boxShadow: '0 2px 4px 0 rgba(212, 212, 211, 0.59)',
flexWrap: 'nowrap',
height: headerHeight,
position: 'fixed', position: 'fixed',
width: '100%', width: '100%',
zIndex: 1301,
}, },
logo: { logo: {
padding: `${sm} ${md}`,
flexBasis: '95px', flexBasis: '95px',
flexGrow: 0, flexShrink: '0',
flexGrow: '0',
maxWidth: '55px',
padding: sm,
[`@media (min-width: ${screenSm}px)`]: {
maxWidth: 'none',
paddingLeft: md,
paddingRight: md,
},
}, },
popper: { popper: {
zIndex: 2000, zIndex: 2000,
@ -65,46 +73,46 @@ const Layout = openHoc(
providerInfo, providerInfo,
providerDetails, providerDetails,
}: Props) => ( }: Props) => (
<Row className={classes.summary}> <Row className={classes.summary}>
<Col start="xs" middle="xs" className={classes.logo}> <Col start="xs" middle="xs" className={classes.logo}>
<Link to="/"> <Link to="/">
<Img src={logo} height={32} alt="Gnosis Team Safe" /> <Img src={logo} height={32} alt="Gnosis Team Safe" />
</Link> </Link>
</Col> </Col>
<Divider /> <Divider />
<SafeListHeader /> <SafeListHeader />
<Divider /> <Divider />
<NetworkLabel /> <NetworkLabel />
<Spacer /> <Spacer />
<Provider open={open} toggle={toggle} info={providerInfo}> <Provider open={open} toggle={toggle} info={providerInfo}>
{(providerRef) => ( {(providerRef) => (
<Popper <Popper
open={open} anchorEl={providerRef.current}
anchorEl={providerRef.current} className={classes.popper}
placement="bottom" open={open}
className={classes.popper} placement="bottom"
popperOptions={{ positionFixed: true }} popperOptions={{ positionFixed: true }}
> >
{({ TransitionProps }) => ( {({ TransitionProps }) => (
<Grow {...TransitionProps}> <Grow {...TransitionProps}>
<> <>
<ClickAwayListener <ClickAwayListener
onClickAway={clickAway} onClickAway={clickAway}
mouseEvent="onClick" mouseEvent="onClick"
touchEvent={false} touchEvent={false}
> >
<List className={classes.root} component="div"> <List className={classes.root} component="div">
{providerDetails} {providerDetails}
</List> </List>
</ClickAwayListener> </ClickAwayListener>
</> </>
</Grow> </Grow>
)} )}
</Popper> </Popper>
)} )}
</Provider> </Provider>
</Row> </Row>
), ),
) )
export default withStyles(styles)(Layout) export default withStyles(styles)(Layout)

View File

@ -5,7 +5,7 @@ import { getNetwork } from '~/config'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import { import {
xs, sm, md, border, xs, sm, md, border, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
const network = getNetwork() const network = getNetwork()
@ -14,14 +14,22 @@ const formattedNetwork = network[0].toUpperCase() + network.substring(1).toLower
const useStyles = makeStyles({ const useStyles = makeStyles({
container: { container: {
flexGrow: 0, flexGrow: 0,
padding: `0 ${md}`, padding: `0 ${sm}`,
[`@media (min-width: ${screenSm}px)`]: {
paddingLeft: md,
paddingRight: md,
},
}, },
text: { text: {
background: border, background: border,
padding: `${xs} ${sm}`,
borderRadius: '3px', borderRadius: '3px',
marginLeft: sm,
lineHeight: 'normal', lineHeight: 'normal',
margin: '0',
padding: `${xs} ${sm}`,
[`@media (min-width: ${screenSm}px)`]: {
marginLeft: '8px',
},
}, },
}) })

View File

@ -7,7 +7,7 @@ import ExpandMore from '@material-ui/icons/ExpandMore'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import Divider from '~/components/layout/Divider' import Divider from '~/components/layout/Divider'
import { type Open } from '~/components/hoc/OpenHoc' import { type Open } from '~/components/hoc/OpenHoc'
import { sm, md } from '~/theme/variables' import { sm, md, screenSm } from '~/theme/variables'
type Props = Open & { type Props = Open & {
classes: Object, classes: Object,
@ -18,22 +18,29 @@ type Props = Open & {
const styles = () => ({ const styles = () => ({
root: { root: {
height: '100%',
display: 'flex',
alignItems: 'center', alignItems: 'center',
flexBasis: '284px', display: 'flex',
marginRight: '20px', height: '100%',
[`@media (min-width: ${screenSm}px)`]: {
flexBasis: '284px',
marginRight: '20px',
},
}, },
provider: { provider: {
padding: `${sm} ${md}`,
alignItems: 'center', alignItems: 'center',
flex: '1 1 auto',
display: 'flex',
cursor: 'pointer', cursor: 'pointer',
display: 'flex',
flex: '1 1 auto',
padding: sm,
[`@media (min-width: ${screenSm}px)`]: {
paddingLeft: md,
paddingRight: md,
},
}, },
expand: { expand: {
width: '30px',
height: '30px', height: '30px',
width: '30px',
}, },
}) })

View File

@ -4,7 +4,7 @@ import { withStyles } from '@material-ui/core/styles'
import Dot from '@material-ui/icons/FiberManualRecord' import Dot from '@material-ui/icons/FiberManualRecord'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import { connected as connectedBg, sm } from '~/theme/variables' import { screenSm, connected as connectedBg, sm } from '~/theme/variables'
import Identicon from '~/components/Identicon' import Identicon from '~/components/Identicon'
import { shortVersionOf } from '~/logic/wallets/ethAddresses' import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import CircleDot from '~/components/Header/components/CircleDot' import CircleDot from '~/components/Header/components/CircleDot'
@ -21,23 +21,33 @@ const styles = () => ({
network: { network: {
fontFamily: 'Averta, sans-serif', fontFamily: 'Averta, sans-serif',
}, },
logo: { identicon: {
height: '15px', display: 'none',
width: '15px', [`@media (min-width: ${screenSm}px)`]: {
top: '12px', display: 'block',
position: 'relative', },
right: '10px', },
backgroundColor: '#ffffff', dot: {
backgroundColor: '#fff',
borderRadius: '15px', borderRadius: '15px',
color: connectedBg, color: connectedBg,
display: 'none',
height: '15px',
position: 'relative',
right: '10px',
top: '12px',
width: '15px',
[`@media (min-width: ${screenSm}px)`]: {
display: 'block',
},
}, },
account: { account: {
paddingRight: sm, alignItems: 'start',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'left',
alignItems: 'start',
flexGrow: 1, flexGrow: 1,
justifyContent: 'left',
paddingRight: sm,
}, },
address: { address: {
letterSpacing: '-0.5px', letterSpacing: '-0.5px',
@ -56,8 +66,8 @@ const ProviderInfo = ({
<> <>
{connected && ( {connected && (
<> <>
<Identicon address={identiconAddress} diameter={30} /> <Identicon className={classes.identicon} address={identiconAddress} diameter={30} />
<Dot className={classes.logo} /> <Dot className={classes.dot} />
</> </>
)} )}
{!connected && <CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />} {!connected && <CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />}

View File

@ -17,15 +17,16 @@ const styles = () => ({
fontFamily: 'Averta, sans-serif', fontFamily: 'Averta, sans-serif',
}, },
account: { account: {
paddingRight: sm, alignItems: 'start',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'center',
alignItems: 'start',
flexGrow: 1, flexGrow: 1,
justifyContent: 'center',
paddingRight: sm,
}, },
connect: { connect: {
letterSpacing: '-0.5px', letterSpacing: '-0.5px',
whiteSpace: 'nowrap',
}, },
}) })

View File

@ -8,7 +8,7 @@ import ExpandLessIcon from '@material-ui/icons/ExpandLess'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import { import {
xs, sm, md, border, xs, sm, md, border, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import { safesCountSelector } from '~/routes/safe/store/selectors' import { safesCountSelector } from '~/routes/safe/store/selectors'
import { SidebarContext } from '~/components/Sidebar' import { SidebarContext } from '~/components/Sidebar'
@ -18,7 +18,11 @@ export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN'
const useStyles = makeStyles({ const useStyles = makeStyles({
container: { container: {
flexGrow: 0, flexGrow: 0,
padding: `0 ${md}`, padding: `0 ${sm}`,
[`@media (min-width: ${screenSm}px)`]: {
paddingLeft: md,
paddingRight: md,
},
}, },
counter: { counter: {
background: border, background: border,
@ -60,7 +64,7 @@ const SafeListHeader = ({ safesCount }: Props) => {
) )
} }
export default connect<Object, Object, ?Function, ?Object>( export default connect<Object, Object,?Function,?Object>(
// $FlowFixMe // $FlowFixMe
(state) => ({ safesCount: safesCountSelector(state) }), (state) => ({ safesCount: safesCountSelector(state) }),
null, null,

View File

@ -81,11 +81,11 @@ class HeaderComponent extends React.PureComponent<Props, State> {
return ( return (
<UserDetails <UserDetails
provider={provider}
network={network}
userAddress={userAddress}
connected={available} connected={available}
network={network}
onDisconnect={this.onDisconnect} onDisconnect={this.onDisconnect}
provider={provider}
userAddress={userAddress}
/> />
) )
} }

View File

@ -57,6 +57,7 @@ const useStyles = makeStyles({
}, },
safeName: { safeName: {
color: primary, color: primary,
overflowWrap: 'break-word',
}, },
safeAddress: { safeAddress: {
color: disabled, color: disabled,

View File

@ -97,32 +97,34 @@ const Sidebar = ({
<SidebarContext.Provider value={{ isOpen, toggleSidebar }}> <SidebarContext.Provider value={{ isOpen, toggleSidebar }}>
<ClickAwayListener onClickAway={toggleSidebar}> <ClickAwayListener onClickAway={toggleSidebar}>
<Drawer <Drawer
className={classes.sidebar}
open={isOpen}
onKeyDown={handleEsc}
classes={{ paper: classes.sidebarPaper }}
ModalProps={{ onBackdropClick: toggleSidebar }} ModalProps={{ onBackdropClick: toggleSidebar }}
className={classes.sidebar}
classes={{ paper: classes.sidebarPaper }}
onKeyDown={handleEsc}
open={isOpen}
> >
<Row align="center"> <Row className={classes.topComponents} align="center">
<SearchIcon className={classes.searchIcon} /> <Row className={classes.searchWrapper} align="center">
<SearchBar <SearchIcon className={classes.searchIcon} />
classes={searchClasses} <SearchBar
placeholder="Search by name or address" classes={searchClasses}
searchIcon={<div />} onCancelSearch={handleFilterCancel}
onChange={handleFilterChange} onChange={handleFilterChange}
onCancelSearch={handleFilterCancel} placeholder="Search by name or address"
value={filter} searchIcon={<div />}
/> value={filter}
<Divider /> />
<Spacer /> </Row>
<Divider className={classes.divider} />
<Spacer className={classes.spacer} />
<Button <Button
component={Link}
to={WELCOME_ADDRESS}
className={classes.addSafeBtn} className={classes.addSafeBtn}
variant="contained"
size="small"
color="primary" color="primary"
component={Link}
onClick={toggleSidebar} onClick={toggleSidebar}
size="small"
to={WELCOME_ADDRESS}
variant="contained"
> >
+ Add Safe + Add Safe
</Button> </Button>

View File

@ -1,7 +1,7 @@
// @flow // @flow
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import { import {
xs, mediumFontSize, secondaryText, md, headerHeight, xs, mediumFontSize, secondaryText, md, headerHeight, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
const sidebarWidth = '400px' const sidebarWidth = '400px'
@ -12,17 +12,50 @@ const sidebarBorderRadius = '8px'
const useSidebarStyles = makeStyles({ const useSidebarStyles = makeStyles({
sidebar: { sidebar: {
width: sidebarWidth,
marginLeft: sidebarMarginLeft,
borderRadius: sidebarBorderRadius, borderRadius: sidebarBorderRadius,
marginLeft: sidebarMarginLeft,
top: sidebarMarginTop, top: sidebarMarginTop,
width: sidebarWidth,
}, },
sidebarPaper: { sidebarPaper: {
width: sidebarWidth,
marginLeft: sidebarMarginLeft,
top: `calc(${headerHeight} + ${sidebarMarginTop})`,
maxHeight: `calc(100vh - ${headerHeight} - ${sidebarMarginTop} - ${sidebarMarginBottom})`,
borderRadius: sidebarBorderRadius, borderRadius: sidebarBorderRadius,
marginLeft: sidebarMarginLeft,
maxHeight: `calc(100vh - ${headerHeight} - ${sidebarMarginTop} - ${sidebarMarginBottom})`,
top: `calc(${headerHeight} + ${sidebarMarginTop})`,
width: sidebarWidth,
maxWidth: `calc(100% - ${sidebarMarginLeft} - ${sidebarMarginLeft})`,
[`@media (min-width: ${screenSm}px)`]: {
maxWidth: 'none',
},
},
topComponents: {
alignItems: 'center',
flexFlow: 'column',
paddingBottom: '30px',
[`@media (min-width: ${screenSm}px)`]: {
flexFlow: 'row',
paddingBottom: '0',
},
},
searchWrapper: {
width: '100%',
[`@media (min-width: ${screenSm}px)`]: {
width: 'auto',
},
},
divider: {
display: 'none',
[`@media (min-width: ${screenSm}px)`]: {
display: 'block',
},
},
spacer: {
display: 'none',
[`@media (min-width: ${screenSm}px)`]: {
display: 'block',
},
}, },
headerPlaceholder: { headerPlaceholder: {
minHeight: headerHeight, minHeight: headerHeight,
@ -48,14 +81,16 @@ const useSidebarStyles = makeStyles({
}, },
}, },
searchContainer: { searchContainer: {
width: '190px', flexGrow: '1',
marginLeft: xs, marginLeft: xs,
marginRight: xs, marginRight: xs,
minWidth: '190px',
}, },
searchRoot: { searchRoot: {
letterSpacing: '-0.5px', letterSpacing: '-0.5px',
border: 'none', border: 'none',
boxShadow: 'none', boxShadow: 'none',
flexGrow: '1',
'& > button': { '& > button': {
display: 'none', display: 'none',
}, },

View File

@ -1,8 +1,12 @@
// @flow // @flow
import * as React from 'react' import * as React from 'react'
type Props = {
className?: string,
}
const style = { const style = {
flexGrow: 1, flexGrow: 1,
} }
export default () => <div style={style} /> export default ({ className }: Props) => <div className={className} style={style} />

View File

@ -2,11 +2,15 @@
import * as React from 'react' import * as React from 'react'
import { border } from '~/theme/variables' import { border } from '~/theme/variables'
const style = { type Props = {
height: '100%', className?: string,
borderRight: `solid 2px ${border}`,
} }
const Divider = () => <div style={style} /> const style = {
borderRight: `solid 2px ${border}`,
height: '100%',
}
const Divider = ({ className }: Props) => <div className={className} style={style} />
export default Divider export default Divider

View File

@ -12,16 +12,19 @@ const calculateStyleFrom = (color?: string, margin?: Size) => ({
}) })
type Props = { type Props = {
margin?: Size, className?: string,
color?: string, color?: string,
margin?: Size,
style?: Object, style?: Object,
} }
const Hairline = ({ margin, color, style }: Props) => { const Hairline = ({
margin, color, style, className,
}: Props) => {
const calculatedStyles = calculateStyleFrom(color, margin) const calculatedStyles = calculateStyleFrom(color, margin)
const mergedStyles = { ...calculatedStyles, ...(style || {}) } const mergedStyles = { ...calculatedStyles, ...(style || {}) }
return <div style={mergedStyles} /> return <div style={mergedStyles} className={className} />
} }
export default Hairline export default Hairline

View File

@ -1,6 +1,7 @@
// @flow // @flow
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import TableContainer from '@material-ui/core/TableContainer'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Field from '~/components/forms/Field' import Field from '~/components/forms/Field'
import { required } from '~/components/forms/validator' import { required } from '~/components/forms/validator'
@ -14,7 +15,7 @@ import Hairline from '~/components/layout/Hairline'
import EtherscanBtn from '~/components/EtherscanBtn' import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn' import CopyBtn from '~/components/CopyBtn'
import { import {
sm, md, lg, border, disabled, extraSmallFontSize, sm, md, lg, border, disabled, extraSmallFontSize, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import { getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields' import { getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
import { FIELD_LOAD_ADDRESS, THRESHOLD } from '~/routes/load/components/fields' import { FIELD_LOAD_ADDRESS, THRESHOLD } from '~/routes/load/components/fields'
@ -30,8 +31,13 @@ const styles = () => ({
display: 'flex', display: 'flex',
justifyContent: 'flex-start', justifyContent: 'flex-start',
}, },
ownerNames: { ownerName: {
maxWidth: '400px', marginBottom: '15px',
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
marginBottom: '0',
minWidth: '0',
},
}, },
ownerAddresses: { ownerAddresses: {
alignItems: 'center', alignItems: 'center',
@ -118,39 +124,41 @@ const OwnerListComponent = (props: Props) => {
</Paragraph> </Paragraph>
</Block> </Block>
<Hairline /> <Hairline />
<Row className={classes.header}> <TableContainer>
<Col xs={4}>NAME</Col> <Row className={classes.header}>
<Col xs={8}>ADDRESS</Col> <Col xs={4}>NAME</Col>
</Row> <Col xs={8}>ADDRESS</Col>
<Hairline /> </Row>
<Block margin="md" padding="md"> <Hairline />
{owners.map((address, index) => ( <Block margin="md" padding="md">
<Row key={address} className={classes.owner}> {owners.map((address, index) => (
<Col xs={4}> <Row key={address} className={classes.owner}>
<Field <Col className={classes.ownerName} xs={4}>
className={classes.name} <Field
name={getOwnerNameBy(index)} className={classes.name}
component={TextField} component={TextField}
type="text" initialValue={`Owner #${index + 1}`}
validate={required} name={getOwnerNameBy(index)}
initialValue={`Owner #${index + 1}`} placeholder="Owner Name*"
placeholder="Owner Name*" text="Owner Name"
text="Owner Name" type="text"
/> validate={required}
</Col> />
<Col xs={8}> </Col>
<Row className={classes.ownerAddresses}> <Col xs={8}>
<Identicon address={address} diameter={32} /> <Row className={classes.ownerAddresses}>
<Paragraph size="md" color="disabled" noMargin className={classes.address}> <Identicon address={address} diameter={32} />
{address} <Paragraph size="md" color="disabled" noMargin className={classes.address}>
</Paragraph> {address}
<CopyBtn content={address} /> </Paragraph>
<EtherscanBtn type="address" value={address} /> <CopyBtn content={address} />
</Row> <EtherscanBtn type="address" value={address} />
</Col> </Row>
</Row> </Col>
))} </Row>
</Block> ))}
</Block>
</TableContainer>
</> </>
) )
} }

View File

@ -2,6 +2,7 @@
import * as React from 'react' import * as React from 'react'
import classNames from 'classnames' import classNames from 'classnames'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import TableContainer from '@material-ui/core/TableContainer'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Identicon from '~/components/Identicon' import Identicon from '~/components/Identicon'
import OpenPaper from '~/components/Stepper/OpenPaper' import OpenPaper from '~/components/Stepper/OpenPaper'
@ -12,7 +13,7 @@ import Paragraph from '~/components/layout/Paragraph'
import CopyBtn from '~/components/CopyBtn' import CopyBtn from '~/components/CopyBtn'
import Hairline from '~/components/layout/Hairline' import Hairline from '~/components/layout/Hairline'
import { import {
xs, sm, lg, border, xs, sm, lg, border, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import { shortVersionOf } from '~/logic/wallets/ethAddresses' import { shortVersionOf } from '~/logic/wallets/ethAddresses'
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor' import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
@ -22,7 +23,23 @@ import type { LayoutProps } from '../Layout'
const styles = () => ({ const styles = () => ({
root: { root: {
flexDirection: 'column',
minHeight: '300px', minHeight: '300px',
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
},
detailsColumn: {
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '0',
},
},
ownersColumn: {
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '0',
},
}, },
details: { details: {
padding: lg, padding: lg,
@ -40,9 +57,10 @@ const styles = () => ({
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
}, },
owner: { owner: {
alignItems: 'center',
minWidth: 'fit-content',
padding: sm, padding: sm,
paddingLeft: lg, paddingLeft: lg,
alignItems: 'center',
}, },
user: { user: {
justifyContent: 'left', justifyContent: 'left',
@ -101,7 +119,7 @@ class ReviewComponent extends React.PureComponent<Props, State> {
return ( return (
<> <>
<Row className={classes.root}> <Row className={classes.root}>
<Col xs={4} layout="column"> <Col className={classes.detailsColumn} xs={4} layout="column">
<Block className={classes.details}> <Block className={classes.details}>
<Block margin="lg"> <Block margin="lg">
<Paragraph size="lg" color="primary" noMargin> <Paragraph size="lg" color="primary" noMargin>
@ -147,37 +165,39 @@ class ReviewComponent extends React.PureComponent<Props, State> {
</Block> </Block>
</Block> </Block>
</Col> </Col>
<Col xs={8} layout="column"> <Col className={classes.ownersColumn} xs={8} layout="column">
<Block className={classes.owners}> <TableContainer>
<Paragraph size="lg" color="primary" noMargin> <Block className={classes.owners}>
{`${getNumOwnersFrom(values)} Safe owners`} <Paragraph size="lg" color="primary" noMargin>
</Paragraph> {`${getNumOwnersFrom(values)} Safe owners`}
</Block> </Paragraph>
<Hairline /> </Block>
{owners.map((address, index) => ( <Hairline />
<React.Fragment key={address}> {owners.map((address, index) => (
<Row className={classes.owner}> <>
<Col xs={1} align="center"> <Row className={classes.owner}>
<Identicon address={address} diameter={32} /> <Col xs={1} align="center">
</Col> <Identicon address={address} diameter={32} />
<Col xs={11}> </Col>
<Block className={classNames(classes.name, classes.userName)}> <Col xs={11}>
<Paragraph size="lg" noMargin> <Block className={classNames(classes.name, classes.userName)}>
{values[getOwnerNameBy(index)]} <Paragraph size="lg" noMargin>
</Paragraph> {values[getOwnerNameBy(index)]}
<Block justify="center" className={classes.user}>
<Paragraph size="md" color="disabled" noMargin>
{address}
</Paragraph> </Paragraph>
<CopyBtn content={address} /> <Block justify="center" className={classes.user}>
<EtherscanBtn type="address" value={address} /> <Paragraph size="md" color="disabled" noMargin>
{address}
</Paragraph>
<CopyBtn content={address} />
<EtherscanBtn type="address" value={address} />
</Block>
</Block> </Block>
</Block> </Col>
</Col> </Row>
</Row> {index !== owners.length - 1 && <Hairline />}
{index !== owners.length - 1 && <Hairline />} </>
</React.Fragment> ))}
))} </TableContainer>
</Col> </Col>
</Row> </Row>
</> </>

View File

@ -2,6 +2,7 @@
import * as React from 'react' import * as React from 'react'
import classNames from 'classnames' import classNames from 'classnames'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import TableContainer from '@material-ui/core/TableContainer'
import { estimateGasForDeployingSafe } from '~/logic/contracts/safeContracts' import { estimateGasForDeployingSafe } from '~/logic/contracts/safeContracts'
import { getNamesFrom, getAccountsFrom } from '~/routes/open/utils/safeDataExtractor' import { getNamesFrom, getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
@ -14,7 +15,7 @@ import Row from '~/components/layout/Row'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import { formatAmount } from '~/logic/tokens/utils/formatAmount' import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import { import {
sm, md, lg, border, background, sm, md, lg, border, background, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import Hairline from '~/components/layout/Hairline' import Hairline from '~/components/layout/Hairline'
import { getWeb3 } from '~/logic/wallets/getWeb3' import { getWeb3 } from '~/logic/wallets/getWeb3'
@ -25,6 +26,21 @@ const { useEffect, useState } = React
const styles = () => ({ const styles = () => ({
root: { root: {
minHeight: '300px', minHeight: '300px',
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
},
detailsColumn: {
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '0',
},
},
ownersColumn: {
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '0',
},
}, },
details: { details: {
padding: lg, padding: lg,
@ -33,10 +49,10 @@ const styles = () => ({
}, },
info: { info: {
backgroundColor: background, backgroundColor: background,
padding: lg,
justifyContent: 'center',
textAlign: 'center',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'center',
padding: lg,
textAlign: 'center',
}, },
owners: { owners: {
padding: lg, padding: lg,
@ -49,8 +65,10 @@ const styles = () => ({
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
}, },
owner: { owner: {
padding: md,
alignItems: 'center', alignItems: 'center',
minWidth: 'fit-content',
padding: sm,
paddingLeft: lg,
}, },
user: { user: {
justifyContent: 'left', justifyContent: 'left',
@ -102,7 +120,7 @@ const ReviewComponent = ({ values, classes, userAccount }: Props) => {
return ( return (
<> <>
<Row className={classes.root}> <Row className={classes.root}>
<Col xs={4} layout="column"> <Col className={classes.detailsColumn} xs={4} layout="column">
<Block className={classes.details}> <Block className={classes.details}>
<Block margin="lg"> <Block margin="lg">
<Paragraph size="lg" color="primary" noMargin> <Paragraph size="lg" color="primary" noMargin>
@ -127,37 +145,39 @@ const ReviewComponent = ({ values, classes, userAccount }: Props) => {
</Block> </Block>
</Block> </Block>
</Col> </Col>
<Col xs={8} layout="column"> <Col className={classes.ownersColumn} xs={8} layout="column">
<Block className={classes.owners}> <TableContainer>
<Paragraph size="lg" color="primary" noMargin> <Block className={classes.owners}>
{`${numOwners} Safe owners`} <Paragraph size="lg" color="primary" noMargin>
</Paragraph> {`${numOwners} Safe owners`}
</Block> </Paragraph>
<Hairline /> </Block>
{names.map((name, index) => ( <Hairline />
<React.Fragment key={`name${index}`}> {names.map((name, index) => (
<Row className={classes.owner}> <React.Fragment key={`name${index}`}>
<Col xs={1} align="center"> <Row className={classes.owner}>
<Identicon address={addresses[index]} diameter={32} /> <Col xs={1} align="center">
</Col> <Identicon address={addresses[index]} diameter={32} />
<Col xs={11}> </Col>
<Block className={classNames(classes.name, classes.userName)}> <Col xs={11}>
<Paragraph size="lg" noMargin> <Block className={classNames(classes.name, classes.userName)}>
{name} <Paragraph size="lg" noMargin>
</Paragraph> {name}
<Block justify="center" className={classes.user}>
<Paragraph size="md" color="disabled" noMargin>
{addresses[index]}
</Paragraph> </Paragraph>
<CopyBtn content={addresses[index]} /> <Block justify="center" className={classes.user}>
<EtherscanBtn type="address" value={addresses[index]} /> <Paragraph size="md" color="disabled" noMargin>
{addresses[index]}
</Paragraph>
<CopyBtn content={addresses[index]} />
<EtherscanBtn type="address" value={addresses[index]} />
</Block>
</Block> </Block>
</Block> </Col>
</Col> </Row>
</Row> <Hairline />
<Hairline /> </React.Fragment>
</React.Fragment> ))}
))} </TableContainer>
</Col> </Col>
</Row> </Row>
<Row className={classes.info} align="center"> <Row className={classes.info} align="center">

View File

@ -132,7 +132,7 @@ const SafeOwners = (props: Props) => {
return ( return (
<Row key={`owner${index}`} className={classes.owner}> <Row key={`owner${index}`} className={classes.owner}>
<Col xs={4}> <Col className={classes.ownerName} xs={4}>
<Field <Field
className={classes.name} className={classes.name}
name={getOwnerNameBy(index)} name={getOwnerNameBy(index)}
@ -143,7 +143,7 @@ const SafeOwners = (props: Props) => {
text="Owner Name" text="Owner Name"
/> />
</Col> </Col>
<Col xs={6}> <Col className={classes.ownerAddress} xs={6}>
<AddressInput <AddressInput
name={addressName} name={addressName}
component={TextField} component={TextField}
@ -193,8 +193,8 @@ const SafeOwners = (props: Props) => {
<Paragraph size="md" color="primary"> <Paragraph size="md" color="primary">
Any transaction requires the confirmation of: Any transaction requires the confirmation of:
</Paragraph> </Paragraph>
<Row margin="xl" align="center"> <Row className={classes.ownersAmount} margin="xl" align="center">
<Col xs={2}> <Col className={classes.ownersAmountItem} xs={2}>
<Field <Field
name={FIELD_CONFIRMATIONS} name={FIELD_CONFIRMATIONS}
component={SelectField} component={SelectField}
@ -208,7 +208,7 @@ const SafeOwners = (props: Props) => {
))} ))}
</Field> </Field>
</Col> </Col>
<Col xs={10}> <Col className={classes.ownersAmountItem} xs={10}>
<Paragraph size="lg" color="primary" noMargin className={classes.owners}> <Paragraph size="lg" color="primary" noMargin className={classes.owners}>
out of out of
{' '} {' '}

View File

@ -1,6 +1,6 @@
// @flow // @flow
import { import {
md, lg, sm, disabled, extraSmallFontSize, md, lg, sm, disabled, extraSmallFontSize, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
export const styles = () => ({ export const styles = () => ({
@ -11,11 +11,32 @@ export const styles = () => ({
padding: `${md} ${lg}`, padding: `${md} ${lg}`,
}, },
owner: { owner: {
padding: `0 ${lg}`, flexDirection: 'column',
marginTop: '12px', marginTop: '12px',
padding: `0 ${lg}`,
'&:first-child': { '&:first-child': {
marginTop: 0, marginTop: 0,
}, },
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
},
ownerName: {
marginBottom: '5px',
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
marginBottom: '0',
minWidth: '0',
},
},
ownerAddress: {
marginBottom: '15px',
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
marginBottom: '0',
minWidth: '0',
},
}, },
header: { header: {
padding: `${sm} ${lg}`, padding: `${sm} ${lg}`,
@ -45,4 +66,16 @@ export const styles = () => ({
owners: { owners: {
paddingLeft: md, paddingLeft: md,
}, },
ownersAmount: {
flexDirection: 'column',
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
},
ownersAmountItem: {
minWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '0',
},
},
}) })

View File

@ -9,6 +9,7 @@ import { withStyles } from '@material-ui/core/styles'
import classNames from 'classnames/bind' import classNames from 'classnames/bind'
import CallMade from '@material-ui/icons/CallMade' import CallMade from '@material-ui/icons/CallMade'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import TableContainer from '@material-ui/core/TableContainer'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import { type Column, cellWidth } from '~/components/Table/TableHead' import { type Column, cellWidth } from '~/components/Table/TableHead'
@ -123,97 +124,99 @@ const AddressBookTable = ({ classes }: Props) => {
</Col> </Col>
</Row> </Row>
<Block className={classes.formContainer}> <Block className={classes.formContainer}>
<Table <TableContainer>
label="Owners" <Table
columns={columns} label="Owners"
data={addressBook} columns={columns}
size={addressBook.size} data={addressBook}
defaultFixed size={addressBook.size}
disableLoadingOnEmptyTable defaultFixed
defaultRowsPerPage={25} disableLoadingOnEmptyTable
> defaultRowsPerPage={25}
{(sortedData: List<OwnerRow>) => sortedData.map((row: AddressBookEntry, index: number) => { >
const userOwner = isUserOwnerOnAnySafe(safesList, row.address) {(sortedData: List<OwnerRow>) => sortedData.map((row: AddressBookEntry, index: number) => {
const hideBorderBottom = index >= 3 const userOwner = isUserOwnerOnAnySafe(safesList, row.address)
const hideBorderBottom = index >= 3
&& index === sortedData.size - 1 && index === sortedData.size - 1
&& classes.noBorderBottom && classes.noBorderBottom
return ( return (
<TableRow <TableRow
tabIndex={-1} tabIndex={-1}
key={index} key={index}
className={cn( className={cn(
classes.hide, classes.hide,
hideBorderBottom, hideBorderBottom,
)} )}
data-testid={ADDRESS_BOOK_ROW_ID} data-testid={ADDRESS_BOOK_ROW_ID}
> >
{autoColumns.map((column: Column) => ( {autoColumns.map((column: Column) => (
<TableCell <TableCell
key={column.id} key={column.id}
style={cellWidth(column.width)} style={cellWidth(column.width)}
align={column.align} align={column.align}
component="td" component="td"
>
{column.id === AB_ADDRESS_ID ? (
<OwnerAddressTableCell
address={row[column.id]}
showLinks
/>
) : (
row[column.id]
)}
</TableCell>
))}
<TableCell component="td">
<Row align="end" className={classes.actions}>
<Img
alt="Edit entry"
className={classes.editEntryButton}
src={RenameOwnerIcon}
onClick={() => {
setSelectedEntry({ entry: { ...row, isOwnerAddress: userOwner } })
setEditCreateEntryModalOpen(true)
}}
testId={EDIT_ENTRY_BUTTON}
/>
<Img
alt="Remove entry"
className={userOwner ? classes.removeEntryButtonDisabled : classes.removeEntryButton}
src={userOwner ? RemoveOwnerIconDisabled : RemoveOwnerIcon}
onClick={() => {
if (!userOwner) {
setSelectedEntry({ entry: row })
setDeleteEntryModalOpen(true)
}
}}
testId={REMOVE_ENTRY_BUTTON}
/>
<Button
variant="contained"
size="small"
color="primary"
className={classes.send}
testId={SEND_ENTRY_BUTTON}
onClick={() => {
setSelectedEntry({ entry: row })
setSendFundsModalOpen(true)
}}
> >
<CallMade {column.id === AB_ADDRESS_ID ? (
alt="Send Transaction" <OwnerAddressTableCell
className={classNames( address={row[column.id]}
classes.leftIcon, showLinks
classes.iconSmall, />
)} ) : (
row[column.id]
)}
</TableCell>
))}
<TableCell component="td">
<Row align="end" className={classes.actions}>
<Img
alt="Edit entry"
className={classes.editEntryButton}
src={RenameOwnerIcon}
onClick={() => {
setSelectedEntry({ entry: { ...row, isOwnerAddress: userOwner } })
setEditCreateEntryModalOpen(true)
}}
testId={EDIT_ENTRY_BUTTON}
/> />
<Img
alt="Remove entry"
className={userOwner ? classes.removeEntryButtonDisabled : classes.removeEntryButton}
src={userOwner ? RemoveOwnerIconDisabled : RemoveOwnerIcon}
onClick={() => {
if (!userOwner) {
setSelectedEntry({ entry: row })
setDeleteEntryModalOpen(true)
}
}}
testId={REMOVE_ENTRY_BUTTON}
/>
<Button
variant="contained"
size="small"
color="primary"
className={classes.send}
testId={SEND_ENTRY_BUTTON}
onClick={() => {
setSelectedEntry({ entry: row })
setSendFundsModalOpen(true)
}}
>
<CallMade
alt="Send Transaction"
className={classNames(
classes.leftIcon,
classes.iconSmall,
)}
/>
Send Send
</Button> </Button>
</Row> </Row>
</TableCell> </TableCell>
</TableRow> </TableRow>
) )
})} })}
</Table> </Table>
</TableContainer>
</Block> </Block>
<CreateEditEntryModal <CreateEditEntryModal
onClose={() => setEditCreateEntryModalOpen(false)} onClose={() => setEditCreateEntryModalOpen(false)}

View File

@ -14,7 +14,7 @@ import Col from '~/components/layout/Col'
import EtherscanBtn from '~/components/EtherscanBtn' import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn' import CopyBtn from '~/components/CopyBtn'
import { import {
sm, lg, md, secondaryText, sm, lg, md, secondaryText, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
import { copyToClipboard } from '~/utils/clipboard' import { copyToClipboard } from '~/utils/clipboard'
@ -53,11 +53,23 @@ const styles = () => ({
}, },
}, },
addressContainer: { addressContainer: {
flexDirection: 'column',
justifyContent: 'center',
margin: `${lg} 0`, margin: `${lg} 0`,
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
}, },
address: { address: {
marginLeft: sm, marginLeft: sm,
marginRight: sm, marginRight: sm,
maxWidth: '70%',
overflowWrap: 'break-word',
[`@media (min-width: ${screenSm}px)`]: {
maxWidth: 'none',
},
}, },
}) })

View File

@ -4,6 +4,7 @@ import { List } from 'immutable'
import classNames from 'classnames/bind' import classNames from 'classnames/bind'
import TableRow from '@material-ui/core/TableRow' import TableRow from '@material-ui/core/TableRow'
import TableCell from '@material-ui/core/TableCell' import TableCell from '@material-ui/core/TableCell'
import TableContainer from '@material-ui/core/TableContainer'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import CallMade from '@material-ui/icons/CallMade' import CallMade from '@material-ui/icons/CallMade'
import CallReceived from '@material-ui/icons/CallReceived' import CallReceived from '@material-ui/icons/CallReceived'
@ -148,93 +149,95 @@ class Balances extends React.Component<Props, State> {
</Modal> </Modal>
</Col> </Col>
</Row> </Row>
<Table <TableContainer>
label="Balances" <Table
defaultOrderBy={BALANCE_TABLE_ASSET_ID} columns={columns}
defaultRowsPerPage={10} data={filteredData}
columns={columns} defaultFixed
data={filteredData} defaultOrderBy={BALANCE_TABLE_ASSET_ID}
size={filteredData.size} defaultRowsPerPage={10}
defaultFixed label="Balances"
> size={filteredData.size}
{(sortedData: Array<BalanceRow>) => sortedData.map((row: any, index: number) => ( >
<TableRow tabIndex={-1} key={index} className={classes.hide} data-testid={BALANCE_ROW_TEST_ID}> {(sortedData: Array<BalanceRow>) => sortedData.map((row: any, index: number) => (
{autoColumns.map((column: Column) => { <TableRow tabIndex={-1} key={index} className={classes.hide} data-testid={BALANCE_ROW_TEST_ID}>
const { id, width, align } = column {autoColumns.map((column: Column) => {
let cellItem const { id, width, align } = column
switch (id) { let cellItem
case BALANCE_TABLE_ASSET_ID: { switch (id) {
cellItem = <AssetTableCell asset={row[id]} /> case BALANCE_TABLE_ASSET_ID: {
break cellItem = <AssetTableCell asset={row[id]} />
break
}
case BALANCE_TABLE_BALANCE_ID: {
cellItem = (
<div>
{row[id]}
</div>
)
break
}
case BALANCE_TABLE_VALUE_ID: {
cellItem = <div className={classes.currencyValueRow}>{row[id]}</div>
break
}
default: {
cellItem = null
break
}
} }
case BALANCE_TABLE_BALANCE_ID: { return (
cellItem = ( <TableCell
<div> key={id}
{row[id]} style={cellWidth(width)}
</div> align={align}
) component="td"
break >
} {cellItem}
case BALANCE_TABLE_VALUE_ID: { </TableCell>
cellItem = <div className={classes.currencyValueRow}>{row[id]}</div> )
break })}
} <TableCell component="td">
default: { <Row align="end" className={classes.actions}>
cellItem = null {granted && (
break <Button
} variant="contained"
} size="small"
return ( color="primary"
<TableCell className={classes.send}
key={id} onClick={() => this.showSendFunds(row.asset.address)}
style={cellWidth(width)} testId="balance-send-btn"
align={align} >
component="td" <CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
> Send
{cellItem} </Button>
</TableCell> )}
)
})}
<TableCell component="td">
<Row align="end" className={classes.actions}>
{granted && (
<Button <Button
variant="contained" variant="contained"
size="small" size="small"
color="primary" color="primary"
className={classes.send} className={classes.receive}
onClick={() => this.showSendFunds(row.asset.address)} onClick={this.onShow('Receive')}
testId="balance-send-btn"
> >
<CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> <CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Send
</Button>
)}
<Button
variant="contained"
size="small"
color="primary"
className={classes.receive}
onClick={this.onShow('Receive')}
>
<CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Receive Receive
</Button> </Button>
</Row> </Row>
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))}
</Table> </Table>
</TableContainer>
<SendModal <SendModal
onClose={this.hideSendFunds} activeScreenType="sendFunds"
createTransaction={createTransaction}
ethBalance={ethBalance}
isOpen={sendFunds.isOpen} isOpen={sendFunds.isOpen}
onClose={this.hideSendFunds}
safeAddress={safeAddress} safeAddress={safeAddress}
safeName={safeName} safeName={safeName}
ethBalance={ethBalance}
tokens={activeTokens}
selectedToken={sendFunds.selectedToken} selectedToken={sendFunds.selectedToken}
createTransaction={createTransaction} tokens={activeTokens}
activeScreenType="sendFunds"
/> />
<Modal <Modal
title="Receive Tokens" title="Receive Tokens"

View File

@ -20,7 +20,10 @@ export const styles = (theme: Object) => ({
fontSize: 16, fontSize: 16,
}, },
receiveModal: { receiveModal: {
height: '544px', height: 'auto',
maxWidth: 'calc(100% - 30px)',
minHeight: '544px',
overflow: 'hidden',
}, },
hide: { hide: {
'&:hover': { '&:hover': {

View File

@ -133,93 +133,86 @@ const Layout = (props: Props) => {
return ( return (
<> <>
<Block className={classes.container} margin="xl"> <Block className={classes.container} margin="xl">
<Identicon address={address} diameter={50} /> <Row className={classes.userInfo}>
<Block className={classes.name}> <Identicon address={address} diameter={50} />
<Row> <Block className={classes.name}>
<Heading tag="h2" color="primary" testId={SAFE_VIEW_NAME_HEADING_TEST_ID}> <Row>
{name} <Heading className={classes.nameText} tag="h2" color="primary" testId={SAFE_VIEW_NAME_HEADING_TEST_ID}>
</Heading> {name}
{!granted && <Block className={classes.readonly}>Read Only</Block>} </Heading>
</Row> {!granted && <Block className={classes.readonly}>Read Only</Block>}
<Block justify="center" className={classes.user}> </Row>
<Paragraph size="md" className={classes.address} color="disabled" noMargin> <Block justify="center" className={classes.user}>
{address} <Paragraph size="md" className={classes.address} color="disabled" noMargin>
</Paragraph> {address}
<CopyBtn content={address} /> </Paragraph>
<EtherscanBtn type="address" value={address} /> <CopyBtn content={address} />
<EtherscanBtn type="address" value={address} />
</Block>
</Block> </Block>
</Block> </Row>
<Block className={classes.balance}> <Block className={classes.balance}>
<Row align="end" className={classes.actions}> <Button
<Button className={classes.send}
variant="contained" color="primary"
size="small" disabled={!granted}
color="primary" onClick={() => showSendFunds('Ether')}
className={classes.send} size="small"
onClick={() => showSendFunds('Ether')} variant="contained"
disabled={!granted} >
> <CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
<CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> Send
Send </Button>
</Button> <Button
<Button className={classes.receive}
variant="contained" color="primary"
size="small" onClick={onShow('Receive')}
color="primary" size="small"
className={classes.receive} variant="contained"
onClick={onShow('Receive')} >
> <CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
<CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> Receive
Receive </Button>
</Button>
</Row>
</Block> </Block>
</Block> </Block>
<Row> <Tabs variant="scrollable" value={location.pathname} onChange={handleCallToRouter} indicatorColor="secondary" textColor="secondary">
<Tabs <Tab
value={location.pathname} classes={{
onChange={handleCallToRouter} selected: classes.tabWrapperSelected,
indicatorColor="secondary" wrapper: classes.tabWrapper,
textColor="secondary" }}
> data-testid={BALANCES_TAB_BTN_TEST_ID}
<Tab label={labelBalances}
classes={{ value={`${match.url}/balances`}
selected: classes.tabWrapperSelected, />
wrapper: classes.tabWrapper, <Tab
}} classes={{
label={labelBalances} selected: classes.tabWrapperSelected,
value={`${match.url}/balances`} wrapper: classes.tabWrapper,
data-testid={BALANCES_TAB_BTN_TEST_ID} }}
/> data-testid={TRANSACTIONS_TAB_BTN_TEST_ID}
<Tab label={labelTransactions}
classes={{ value={`${match.url}/transactions`}
selected: classes.tabWrapperSelected, />
wrapper: classes.tabWrapper, <Tab
}} classes={{
label={labelTransactions} selected: classes.tabWrapperSelected,
value={`${match.url}/transactions`} wrapper: classes.tabWrapper,
data-testid={TRANSACTIONS_TAB_BTN_TEST_ID} }}
/> data-testid={ADDRESS_BOOK_TAB_BTN_TEST_ID}
<Tab label={labelAddressBook}
classes={{ value={`${match.url}/address-book`}
selected: classes.tabWrapperSelected, />
wrapper: classes.tabWrapper, <Tab
}} classes={{
label={labelAddressBook} selected: classes.tabWrapperSelected,
value={`${match.url}/address-book`} wrapper: classes.tabWrapper,
data-testid={ADDRESS_BOOK_TAB_BTN_TEST_ID} }}
/> data-testid={SETTINGS_TAB_BTN_TEST_ID}
<Tab label={labelSettings}
classes={{ value={`${match.url}/settings`}
selected: classes.tabWrapperSelected, />
wrapper: classes.tabWrapper, </Tabs>
}}
label={labelSettings}
value={`${match.url}/settings`}
data-testid={SETTINGS_TAB_BTN_TEST_ID}
/>
</Tabs>
</Row>
<Hairline color={border} style={{ marginTop: '-2px' }} /> <Hairline color={border} style={{ marginTop: '-2px' }} />
<Switch> <Switch>
<Route <Route
@ -283,13 +276,7 @@ const Layout = (props: Props) => {
/> />
)} )}
/> />
<Route <Route exact path={`${match.path}/address-book`} render={() => <AddressBookTable />} />
exact
path={`${match.path}/address-book`}
render={() => (
<AddressBookTable />
)}
/>
<Redirect to={`${match.path}/balances`} /> <Redirect to={`${match.path}/balances`} />
</Switch> </Switch>
<SendModal <SendModal
@ -304,11 +291,11 @@ const Layout = (props: Props) => {
activeScreenType="chooseTxType" activeScreenType="chooseTxType"
/> />
<Modal <Modal
title="Receive Tokens"
description="Receive Tokens Form" description="Receive Tokens Form"
handleClose={onHide('Receive')} handleClose={onHide('Receive')}
open={showReceive} open={showReceive}
paperClassName={classes.receiveModal} paperClassName={classes.receiveModal}
title="Receive Tokens"
> >
<Receive safeName={name} safeAddress={address} onClose={onHide('Receive')} /> <Receive safeName={name} safeAddress={address} onClose={onHide('Receive')} />
</Modal> </Modal>

View File

@ -5,6 +5,7 @@ import { List } from 'immutable'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import TableRow from '@material-ui/core/TableRow' import TableRow from '@material-ui/core/TableRow'
import TableCell from '@material-ui/core/TableCell' import TableCell from '@material-ui/core/TableCell'
import TableContainer from '@material-ui/core/TableContainer'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import Table from '~/components/Table' import Table from '~/components/Table'
@ -145,66 +146,68 @@ class ManageOwners extends React.Component<Props, State> {
Add, remove and replace owners or rename existing owners. Owner names are only stored locally and never Add, remove and replace owners or rename existing owners. Owner names are only stored locally and never
shared with Gnosis or any third parties. shared with Gnosis or any third parties.
</Paragraph> </Paragraph>
<Table <TableContainer>
label="Owners" <Table
defaultOrderBy={OWNERS_TABLE_NAME_ID} label="Owners"
columns={columns} defaultOrderBy={OWNERS_TABLE_NAME_ID}
data={ownerData} columns={columns}
size={ownerData.size} data={ownerData}
disablePagination size={ownerData.size}
defaultFixed disablePagination
noBorder defaultFixed
> noBorder
{(sortedData: List<OwnerRow>) => sortedData.map((row: any, index: number) => ( >
<TableRow {(sortedData: List<OwnerRow>) => sortedData.map((row: any, index: number) => (
tabIndex={-1} <TableRow
key={index} tabIndex={-1}
className={cn(classes.hide, index >= 3 && index === sortedData.size - 1 && classes.noBorderBottom)} key={index}
data-testid={OWNERS_ROW_TEST_ID} className={cn(classes.hide, index >= 3 && index === sortedData.size - 1 && classes.noBorderBottom)}
> data-testid={OWNERS_ROW_TEST_ID}
{autoColumns.map((column: Column) => ( >
<TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td"> {autoColumns.map((column: Column) => (
{column.id === OWNERS_TABLE_ADDRESS_ID ? ( <TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td">
<OwnerAddressTableCell address={row[column.id]} /> {column.id === OWNERS_TABLE_ADDRESS_ID ? (
) : ( <OwnerAddressTableCell address={row[column.id]} />
row[column.id] ) : (
)} row[column.id]
</TableCell> )}
))} </TableCell>
<TableCell component="td"> ))}
<Row align="end" className={classes.actions}> <TableCell component="td">
<Img <Row align="end" className={classes.actions}>
alt="Edit owner" <Img
className={classes.editOwnerIcon} alt="Edit owner"
src={RenameOwnerIcon} className={classes.editOwnerIcon}
onClick={this.onShow('EditOwner', row)} src={RenameOwnerIcon}
testId={RENAME_OWNER_BTN_TEST_ID} onClick={this.onShow('EditOwner', row)}
/> testId={RENAME_OWNER_BTN_TEST_ID}
{granted && ( />
<> {granted && (
<Img <>
alt="Replace owner"
className={classes.replaceOwnerIcon}
src={ReplaceOwnerIcon}
onClick={this.onShow('ReplaceOwner', row)}
testId={REPLACE_OWNER_BTN_TEST_ID}
/>
{ownerData.size > 1 && (
<Img <Img
alt="Remove owner" alt="Replace owner"
className={classes.removeOwnerIcon} className={classes.replaceOwnerIcon}
src={RemoveOwnerIcon} src={ReplaceOwnerIcon}
onClick={this.onShow('RemoveOwner', row)} onClick={this.onShow('ReplaceOwner', row)}
testId={REMOVE_OWNER_BTN_TEST_ID} testId={REPLACE_OWNER_BTN_TEST_ID}
/> />
)} {ownerData.size > 1 && (
</> <Img
) } alt="Remove owner"
</Row> className={classes.removeOwnerIcon}
</TableCell> src={RemoveOwnerIcon}
</TableRow> onClick={this.onShow('RemoveOwner', row)}
))} testId={REMOVE_OWNER_BTN_TEST_ID}
</Table> />
)}
</>
) }
</Row>
</TableCell>
</TableRow>
))}
</Table>
</TableContainer>
</Block> </Block>
{granted && ( {granted && (
<> <>

View File

@ -38,7 +38,7 @@ type Props = Actions & {
const RemoveSafeComponent = ({ const RemoveSafeComponent = ({
onClose, isOpen, classes, safeAddress, etherScanLink, safeName, removeSafe, onClose, isOpen, classes, safeAddress, etherScanLink, safeName, removeSafe,
}: Props) => ( }: Props) => (
<Modal title="Remove Safe" description="Remove the selected Safe" handleClose={onClose} open={isOpen}> <Modal paperClassName={classes.modal} title="Remove Safe" description="Remove the selected Safe" handleClose={onClose} open={isOpen}>
<Row align="center" grow className={classes.heading}> <Row align="center" grow className={classes.heading}>
<Paragraph className={classes.manage} noMargin weight="bolder"> <Paragraph className={classes.manage} noMargin weight="bolder">
Remove Safe Remove Safe

View File

@ -5,10 +5,10 @@ import {
export const styles = () => ({ export const styles = () => ({
heading: { heading: {
padding: `${sm} ${lg}`, boxSizing: 'border-box',
justifyContent: 'space-between', justifyContent: 'space-between',
maxHeight: '75px', maxHeight: '75px',
boxSizing: 'border-box', padding: `${sm} ${lg}`,
}, },
container: { container: {
minHeight: '369px', minHeight: '369px',
@ -54,4 +54,9 @@ export const styles = () => ({
cursor: 'pointer', cursor: 'pointer',
}, },
}, },
modal: {
height: 'auto',
maxWidth: 'calc(100% - 30px)',
overflow: 'hidden',
},
}) })

View File

@ -12,16 +12,16 @@ export const styles = () => ({
maxWidth: '460px', maxWidth: '460px',
}, },
saveBtn: { saveBtn: {
marginRight: sm,
fontWeight: boldFont, fontWeight: boldFont,
marginRight: sm,
}, },
controlsRow: { controlsRow: {
padding: lg, borderTop: `2px solid ${border}`,
position: 'absolute',
bottom: 0, bottom: 0,
boxSizing: 'border-box', boxSizing: 'border-box',
padding: lg,
position: 'absolute',
width: '100%', width: '100%',
borderTop: `2px solid ${border}`,
}, },
versionNumber: { versionNumber: {
height: '21px', height: '21px',

View File

@ -117,7 +117,7 @@ class Settings extends React.Component<Props, State> {
/> />
</Row> </Row>
<Block className={classes.root}> <Block className={classes.root}>
<Col xs={3} layout="column"> <Col className={classes.menuWrapper} layout="column">
<Block className={classes.menu}> <Block className={classes.menu}>
<Row <Row
className={cn(classes.menuOption, menuOptionIndex === 1 && classes.active)} className={cn(classes.menuOption, menuOptionIndex === 1 && classes.active)}
@ -126,7 +126,7 @@ class Settings extends React.Component<Props, State> {
<SafeDetailsIcon /> <SafeDetailsIcon />
Safe details Safe details
</Row> </Row>
<Hairline /> <Hairline className={classes.hairline} />
<Row <Row
className={cn(classes.menuOption, menuOptionIndex === 2 && classes.active)} className={cn(classes.menuOption, menuOptionIndex === 2 && classes.active)}
onClick={this.handleChange(2)} onClick={this.handleChange(2)}
@ -138,7 +138,7 @@ class Settings extends React.Component<Props, State> {
{owners.size} {owners.size}
</Paragraph> </Paragraph>
</Row> </Row>
<Hairline /> <Hairline className={classes.hairline} />
<Row <Row
className={cn(classes.menuOption, menuOptionIndex === 3 && classes.active)} className={cn(classes.menuOption, menuOptionIndex === 3 && classes.active)}
onClick={this.handleChange(3)} onClick={this.handleChange(3)}
@ -146,10 +146,10 @@ class Settings extends React.Component<Props, State> {
<RequiredConfirmationsIcon /> <RequiredConfirmationsIcon />
Policies Policies
</Row> </Row>
<Hairline /> <Hairline className={classes.hairline} />
</Block> </Block>
</Col> </Col>
<Col xs={9} layout="column"> <Col className={classes.contents} layout="column">
<Block className={classes.container}> <Block className={classes.container}>
{menuOptionIndex === 1 && ( {menuOptionIndex === 1 && (
<SafeDetails safeAddress={safeAddress} safeName={safeName} updateSafe={updateSafe} /> <SafeDetails safeAddress={safeAddress} safeName={safeName} updateSafe={updateSafe} />

View File

@ -1,36 +1,85 @@
// @flow // @flow
import { import {
xs, sm, md, border, secondary, bolderFont, background, largeFontSize, fontColor, xs, sm, md, border, secondary, bolderFont, background, largeFontSize, fontColor, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
export const styles = () => ({ export const styles = () => ({
root: { root: {
backgroundColor: 'white', backgroundColor: 'white',
boxShadow: '1px 2px 10px 0 rgba(212, 212, 211, 0.59)',
minHeight: '505px',
marginBottom: '54px',
display: 'flex',
borderRadius: sm, borderRadius: sm,
boxShadow: '1px 2px 10px 0 rgba(212, 212, 211, 0.59)',
display: 'flex',
flexDirection: 'column',
marginBottom: '54px',
minHeight: '505px',
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
},
}, },
settings: { settings: {
letterSpacing: '-0.5px', letterSpacing: '-0.5px',
}, },
menuWrapper: {
display: 'flex',
flexDirection: 'row',
flexGrow: '0',
maxWidth: '100%',
[`@media (min-width: ${screenSm}px)`]: {
flexDirection: 'row',
maxWidth: 'unset',
},
},
menu: { menu: {
borderRight: `solid 2px ${border}`, borderBottom: `solid 2px ${border}`,
display: 'flex',
flexDirection: 'row',
flexGrow: '1',
height: '100%', height: '100%',
width: '100%',
[`@media (min-width: ${screenSm}px)`]: {
borderBottom: 'none',
borderRight: `solid 2px ${border}`,
flexDirection: 'column',
width: '250px',
},
}, },
menuOption: { menuOption: {
alignItems: 'center', alignItems: 'center',
borderRight: `solid 1px ${border}`,
boxSizing: 'border-box',
cursor: 'pointer', cursor: 'pointer',
fontSize: largeFontSize, flexGrow: '1',
flexShrink: '1',
fontSize: '13px',
justifyContent: 'center',
lineHeight: '1.2', lineHeight: '1.2',
padding: `${md} 0 ${md} ${md}`, minWidth: '0',
padding: `${md} ${sm}`,
width: '100%',
[`@media (min-width: ${screenSm}px)`]: {
borderRight: 'none',
flexGrow: '0',
fontSize: largeFontSize,
justifyContent: 'flex-start',
padding: `${md} 0 ${md} ${md}`,
},
'&:last-of-type': {
borderRight: 'none',
},
'&:first-child': { '&:first-child': {
borderTopLeftRadius: sm, borderTopLeftRadius: sm,
}, },
'& svg': { '& svg': {
display: 'block', display: 'block',
marginRight: sm, marginRight: xs,
maxWidth: '16px',
[`@media (min-width: ${screenSm}px)`]: {
marginRight: sm,
},
}, },
'& .fill': { '& .fill': {
fill: fontColor, fill: fontColor,
@ -44,7 +93,18 @@ export const styles = () => ({
fill: secondary, fill: secondary,
}, },
}, },
contents: {
width: '100%',
},
hairline: {
display: 'none',
[`@media (min-width: ${screenSm}px)`]: {
display: 'block',
},
},
container: { container: {
flexGrow: '1',
height: '100%', height: '100%',
position: 'relative', position: 'relative',
}, },

View File

@ -8,6 +8,7 @@ import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore' import ExpandMore from '@material-ui/icons/ExpandMore'
import TableRow from '@material-ui/core/TableRow' import TableRow from '@material-ui/core/TableRow'
import TableCell from '@material-ui/core/TableCell' import TableCell from '@material-ui/core/TableCell'
import TableContainer from '@material-ui/core/TableContainer'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
@ -81,77 +82,79 @@ const TxsTable = ({
return ( return (
<Block className={classes.container}> <Block className={classes.container}>
<Table <TableContainer>
label="Transactions" <Table
defaultOrderBy={TX_TABLE_ID} label="Transactions"
defaultOrder="desc" defaultOrderBy={TX_TABLE_ID}
defaultRowsPerPage={25} defaultOrder="desc"
columns={columns} defaultRowsPerPage={25}
data={filteredData} columns={columns}
size={filteredData.size} data={filteredData}
defaultFixed size={filteredData.size}
> defaultFixed
{(sortedData: Array<TransactionRow>) => sortedData.map((row: any, index: number) => ( >
<React.Fragment key={index}> {(sortedData: Array<TransactionRow>) => sortedData.map((row: any, index: number) => (
<TableRow <React.Fragment key={index}>
tabIndex={-1} <TableRow
className={cn(classes.row, expandedTx === row.tx.safeTxHash && classes.expandedRow)} tabIndex={-1}
onClick={() => handleTxExpand(row.tx.safeTxHash)} className={cn(classes.row, expandedTx === row.tx.safeTxHash && classes.expandedRow)}
data-testid={TRANSACTION_ROW_TEST_ID} onClick={() => handleTxExpand(row.tx.safeTxHash)}
> data-testid={TRANSACTION_ROW_TEST_ID}
{autoColumns.map((column: Column) => ( >
<TableCell {autoColumns.map((column: Column) => (
key={column.id} <TableCell
className={cn(classes.cell, row.status === 'cancelled' && classes.cancelledRow)} key={column.id}
style={cellWidth(column.width)} className={cn(classes.cell, row.status === 'cancelled' && classes.cancelledRow)}
align={column.align} style={cellWidth(column.width)}
component="td" align={column.align}
> component="td"
{row[column.id]} >
{row[column.id]}
</TableCell>
))}
<TableCell component="td">
<Row align="end" className={classes.actions}>
<Status status={row.status} />
</Row>
</TableCell> </TableCell>
))} <TableCell style={expandCellStyle}>
<TableCell component="td"> {!row.tx.creationTx && (
<Row align="end" className={classes.actions}> <IconButton disableRipple>
<Status status={row.status} /> {expandedTx === row.safeTxHash ? <ExpandLess /> : <ExpandMore />}
</Row> </IconButton>
</TableCell> )}
<TableCell style={expandCellStyle}>
{!row.tx.creationTx && (
<IconButton disableRipple>
{expandedTx === row.safeTxHash ? <ExpandLess /> : <ExpandMore />}
</IconButton>
)}
</TableCell>
</TableRow>
{!row.tx.creationTx && (
<TableRow>
<TableCell
style={{ paddingBottom: 0, paddingTop: 0 }}
colSpan={6}
className={classes.extendedTxContainer}
>
<Collapse
in={expandedTx === row.tx.safeTxHash}
timeout="auto"
component={ExpandedTxComponent}
unmountOnExit
tx={row[TX_TABLE_RAW_TX_ID]}
cancelTx={row[TX_TABLE_RAW_CANCEL_TX_ID]}
threshold={threshold}
owners={owners}
granted={granted}
userAddress={userAddress}
createTransaction={createTransaction}
processTransaction={processTransaction}
safeAddress={safeAddress}
nonce={nonce}
/>
</TableCell> </TableCell>
</TableRow> </TableRow>
)} {!row.tx.creationTx && (
</React.Fragment> <TableRow>
))} <TableCell
</Table> style={{ paddingBottom: 0, paddingTop: 0 }}
colSpan={6}
className={classes.extendedTxContainer}
>
<Collapse
in={expandedTx === row.tx.safeTxHash}
timeout="auto"
component={ExpandedTxComponent}
unmountOnExit
tx={row[TX_TABLE_RAW_TX_ID]}
cancelTx={row[TX_TABLE_RAW_CANCEL_TX_ID]}
threshold={threshold}
owners={owners}
granted={granted}
userAddress={userAddress}
createTransaction={createTransaction}
processTransaction={processTransaction}
safeAddress={safeAddress}
nonce={nonce}
/>
</TableCell>
</TableRow>
)}
</React.Fragment>
))}
</Table>
</TableContainer>
</Block> </Block>
) )
} }

View File

@ -1,12 +1,21 @@
// @flow // @flow
import { import {
sm, xs, smallFontSize, secondaryText, secondary, sm, xs, smallFontSize, secondaryText, secondary, screenSm,
} from '~/theme/variables' } from '~/theme/variables'
export const styles = () => ({ export const styles = () => ({
container: { container: {
display: 'flex',
alignItems: 'center', alignItems: 'center',
display: 'flex',
flexWrap: 'wrap',
},
userInfo: {
flexWrap: 'nowrap',
marginBottom: sm,
[`@media (min-width: ${screenSm}px)`]: {
marginBottom: '0',
},
}, },
name: { name: {
marginLeft: sm, marginLeft: sm,
@ -16,12 +25,22 @@ export const styles = () => ({
}, },
address: { address: {
marginRight: sm, marginRight: sm,
overflow: 'hidden',
maxWidth: '50%',
[`@media (min-width: ${screenSm}px)`]: {
overflow: 'visible',
maxWidth: 'none',
},
}, },
user: { user: {
justifyContent: 'left', justifyContent: 'left',
}, },
receiveModal: { receiveModal: {
height: '544px', height: 'auto',
maxWidth: 'calc(100% - 30px)',
minHeight: '544px',
overflow: 'hidden',
}, },
open: { open: {
paddingLeft: sm, paddingLeft: sm,
@ -31,39 +50,53 @@ export const styles = () => ({
}, },
}, },
readonly: { readonly: {
backgroundColor: secondaryText,
borderRadius: xs,
color: '#ffffff',
fontSize: smallFontSize, fontSize: smallFontSize,
letterSpacing: '0.5px', letterSpacing: '0.5px',
color: '#ffffff',
backgroundColor: secondaryText,
textTransform: 'uppercase',
padding: `0 ${sm}`,
marginLeft: sm,
borderRadius: xs,
lineHeight: '28px', lineHeight: '28px',
marginLeft: sm,
padding: `0 ${sm}`,
textTransform: 'uppercase',
}, },
iconSmall: { iconSmall: {
fontSize: 16, fontSize: 16,
}, },
balance: { balance: {
marginLeft: 'auto', display: 'flex',
overflow: 'hidden', overflow: 'hidden',
width: '100%',
[`@media (min-width: ${screenSm}px)`]: {
marginLeft: 'auto',
width: 'auto',
},
}, },
receive: { receive: {
width: '95px',
minWidth: '95px',
marginLeft: sm,
borderRadius: '4px', borderRadius: '4px',
marginLeft: sm,
width: '50%',
'& > span': { '& > span': {
fontSize: '14px', fontSize: '14px',
}, },
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '95px',
width: 'auto',
},
}, },
send: { send: {
width: '75px',
minWidth: '75px',
borderRadius: '4px', borderRadius: '4px',
width: '50%',
'& > span': { '& > span': {
fontSize: '14px', fontSize: '14px',
}, },
[`@media (min-width: ${screenSm}px)`]: {
minWidth: '75px',
width: 'auto',
},
}, },
leftIcon: { leftIcon: {
marginRight: sm, marginRight: sm,
@ -84,4 +117,9 @@ export const styles = () => ({
fill: secondary, fill: secondary,
}, },
}, },
nameText: {
overflowWrap: 'break-word',
wordBreak: 'break-word',
whiteSpace: 'normal',
},
}) })

737
yarn.lock

File diff suppressed because it is too large Load Diff