Refactor UI

This commit is contained in:
Germán Martínez 2019-09-02 09:55:28 +02:00
parent e0544241ae
commit b471a5e056
8 changed files with 158 additions and 138 deletions

View File

@ -36,7 +36,7 @@ type TxStateType =
| Object | Object
const styles = () => ({ const styles = () => ({
smallerModalWindow: { scalableModalWindow: {
height: 'auto', height: 'auto',
position: 'static', position: 'static',
}, },
@ -57,30 +57,33 @@ const Send = ({
}: Props) => { }: Props) => {
const [activeScreen, setActiveScreen] = useState<ActiveScreen>(activeScreenType || 'chooseTxType') const [activeScreen, setActiveScreen] = useState<ActiveScreen>(activeScreenType || 'chooseTxType')
const [tx, setTx] = useState<TxStateType>({}) const [tx, setTx] = useState<TxStateType>({})
const smallerModalSize = activeScreen === 'chooseTxType'
const handleTxCreation = (txInfo) => {
setActiveScreen('reviewTx')
setTx(txInfo)
}
const handleCustomTxCreation = (customTxInfo) => {
setActiveScreen('reviewCustomTx')
setTx(customTxInfo)
}
useEffect(() => { useEffect(() => {
setActiveScreen(activeScreenType || 'chooseTxType') setActiveScreen(activeScreenType || 'chooseTxType')
setTx({}) setTx({})
}, [isOpen]) }, [isOpen])
const scalableModalSize = activeScreen === 'chooseTxType' || activeScreen === 'sendCustomTx'
const handleTxCreation = (txInfo) => {
setActiveScreen('reviewTx')
setTx(txInfo)
}
const handleCustomTxCreation = (customTxInfo) => {
setActiveScreen('reviewCustomTx')
setTx(customTxInfo)
}
return ( return (
<Modal <Modal
title="Send Tokens" title="Send Tokens"
description="Send Tokens Form" description="Send Tokens Form"
handleClose={onClose} handleClose={onClose}
open={isOpen} open={isOpen}
paperClassName={cn(smallerModalSize && classes.smallerModalWindow)} paperClassName={cn(scalableModalSize && classes.scalableModalWindow)}
> >
<React.Fragment> <>
{activeScreen === 'chooseTxType' && <ChooseTxType onClose={onClose} setActiveScreen={setActiveScreen} />} {activeScreen === 'chooseTxType' && <ChooseTxType onClose={onClose} setActiveScreen={setActiveScreen} />}
{activeScreen === 'sendFunds' && ( {activeScreen === 'sendFunds' && (
<SendFunds <SendFunds
@ -118,7 +121,7 @@ const Send = ({
initialValues={tx} initialValues={tx}
/> />
)} )}
</React.Fragment> </>
</Modal> </Modal>
) )
} }

View File

@ -2,6 +2,7 @@
import React from 'react' import React from 'react'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close' import Close from '@material-ui/icons/Close'
import InputAdornment from '@material-ui/core/InputAdornment'
import IconButton from '@material-ui/core/IconButton' import IconButton from '@material-ui/core/IconButton'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
@ -10,6 +11,7 @@ import Col from '~/components/layout/Col'
import Button from '~/components/layout/Button' import Button from '~/components/layout/Button'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Hairline from '~/components/layout/Hairline' import Hairline from '~/components/layout/Hairline'
import ButtonLink from '~/components/layout/ButtonLink'
import Field from '~/components/forms/Field' import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField' import TextField from '~/components/forms/TextField'
import TextareaField from '~/components/forms/TextareaField' import TextareaField from '~/components/forms/TextareaField'
@ -17,6 +19,9 @@ import {
composeValidators, composeValidators,
required, required,
mustBeEthereumAddress, mustBeEthereumAddress,
mustBeFloat,
maxValue,
greaterThan,
} from '~/components/forms/validator' } from '~/components/forms/validator'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo' import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
import ArrowDown from '../assets/arrow-down.svg' import ArrowDown from '../assets/arrow-down.svg'
@ -47,10 +52,14 @@ const SendCustomTx = ({
onSubmit(values) onSubmit(values)
} }
const formMutators = {} const formMutators = {
setMax: (args, state, utils) => {
utils.changeValue(state, 'amount', () => ethBalance)
},
}
return ( return (
<React.Fragment> <>
<Row align="center" grow className={classes.heading}> <Row align="center" grow className={classes.heading}>
<Paragraph weight="bolder" className={classes.manage} noMargin> <Paragraph weight="bolder" className={classes.manage} noMargin>
Send custom transactions Send custom transactions
@ -72,52 +81,86 @@ const SendCustomTx = ({
</Col> </Col>
</Row> </Row>
<GnoForm onSubmit={handleSubmit} formMutators={formMutators} initialValues={initialValues}> <GnoForm onSubmit={handleSubmit} formMutators={formMutators} initialValues={initialValues}>
{() => ( {(...args) => {
<React.Fragment> const mutators = args[3]
<Row margin="md">
<Col xs={12}> return (
<Field <>
name="recipientAddress" <Row margin="md">
component={TextField} <Col xs={12}>
type="text" <Field
validate={composeValidators(required, mustBeEthereumAddress)} name="recipientAddress"
placeholder="Recipient*" component={TextField}
text="Recipient*" type="text"
className={classes.addressInput} validate={composeValidators(required, mustBeEthereumAddress)}
/> placeholder="Recipient*"
</Col> text="Recipient*"
</Row> className={classes.addressInput}
<Row margin="sm"> />
<Col> </Col>
<TextareaField </Row>
name="data" <Row margin="xs">
type="text" <Col between="lg">
placeholder="Data interface (ABI / JSON)*" <Paragraph size="md" color="disabled" style={{ letterSpacing: '-0.5px' }} noMargin>
text="Data interface (ABI / JSON)*" Amount
/> </Paragraph>
</Col> <ButtonLink weight="bold" onClick={mutators.setMax}>
</Row> Send max
<Hairline /> </ButtonLink>
<Row align="center" className={classes.buttonRow}> </Col>
<Button minWidth={140} minHeight={42} onClick={onClose}> </Row>
Cancel <Row margin="md">
</Button> <Col>
<Button <Field
type="submit" name="amount"
variant="contained" component={TextField}
minHeight={42} type="text"
minWidth={140} validate={composeValidators(
color="primary" mustBeFloat,
data-testid="review-tx-btn" greaterThan(0),
> maxValue(ethBalance),
Review )}
</Button> placeholder="Value*"
</Row> text="Value*"
</React.Fragment> className={classes.addressInput}
)} inputAdornment={{
endAdornment: <InputAdornment position="end">ETH</InputAdornment>,
}}
/>
</Col>
</Row>
<Row margin="sm">
<Col>
<TextareaField
name="data"
type="text"
placeholder="Data interface (ABI / JSON)*"
text="Data interface (ABI / JSON)*"
/>
</Col>
</Row>
<Hairline />
<Row align="center" className={classes.buttonRow}>
<Button minWidth={140} minHeight={42} onClick={onClose}>
Cancel
</Button>
<Button
type="submit"
variant="contained"
minHeight={42}
minWidth={140}
color="primary"
data-testid="review-tx-btn"
>
Review
</Button>
</Row>
</>
)
}}
</GnoForm> </GnoForm>
</Block> </Block>
</React.Fragment> </>
) )
} }

View File

@ -6,13 +6,14 @@ import Checkbox from '@material-ui/core/Checkbox'
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 { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import CallMade from '@material-ui/icons/CallMade'
import CallReceived from '@material-ui/icons/CallReceived'
import { type Token } from '~/logic/tokens/store/model/token' import { type Token } from '~/logic/tokens/store/model/token'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import Button from '~/components/layout/Button' import Button from '~/components/layout/Button'
import ButtonLink from '~/components/layout/ButtonLink' import ButtonLink from '~/components/layout/ButtonLink'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Img from '~/components/layout/Img'
import Modal from '~/components/Modal' import Modal from '~/components/Modal'
import { type Column, cellWidth } from '~/components/Table/TableHead' import { type Column, cellWidth } from '~/components/Table/TableHead'
import Table from '~/components/Table' import Table from '~/components/Table'
@ -25,9 +26,6 @@ import SendModal from './SendModal'
import Receive from './Receive' import Receive from './Receive'
import { styles } from './style' import { styles } from './style'
const ReceiveTx = require('../assets/tx-receive.svg')
const SendTx = require('../assets/tx-send.svg')
export const MANAGE_TOKENS_BUTTON_TEST_ID = 'manage-tokens-btn' export const MANAGE_TOKENS_BUTTON_TEST_ID = 'manage-tokens-btn'
export const BALANCE_ROW_TEST_ID = 'balance-row' export const BALANCE_ROW_TEST_ID = 'balance-row'
@ -171,17 +169,6 @@ class Balances extends React.Component<Props, State> {
))} ))}
<TableCell component="td"> <TableCell component="td">
<Row align="end" className={classes.actions}> <Row align="end" className={classes.actions}>
<Button
variant="contained"
size="small"
color="primary"
className={classes.receive}
onClick={this.onShow('Receive')}
rounded
>
<Img src={ReceiveTx} alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Receive
</Button>
{granted && ( {granted && (
<Button <Button
variant="contained" variant="contained"
@ -191,7 +178,7 @@ class Balances extends React.Component<Props, State> {
onClick={() => this.showSendFunds(row.asset.name)} onClick={() => this.showSendFunds(row.asset.name)}
testId="balance-send-btn" testId="balance-send-btn"
> >
<Img src={SendTx} alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> <CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Send Send
</Button> </Button>
)} )}
@ -202,7 +189,7 @@ class Balances extends React.Component<Props, State> {
className={classes.receive} className={classes.receive}
onClick={this.onShow('Receive')} onClick={this.onShow('Receive')}
> >
<CallReceived className={classNames(classes.leftIcon, classes.iconSmall)} /> <CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Receive Receive
</Button> </Button>
</Row> </Row>

View File

@ -33,11 +33,11 @@ export const styles = (theme: Object) => ({
receive: { receive: {
width: '95px', width: '95px',
minWidth: '95px', minWidth: '95px',
marginLeft: sm,
}, },
send: { send: {
width: '75px', width: '75px',
minWidth: '75px', minWidth: '75px',
marginLeft: sm,
}, },
leftIcon: { leftIcon: {
marginRight: sm, marginRight: sm,

View File

@ -4,6 +4,8 @@ import classNames from 'classnames/bind'
import OpenInNew from '@material-ui/icons/OpenInNew' import OpenInNew from '@material-ui/icons/OpenInNew'
import Tabs from '@material-ui/core/Tabs' import Tabs from '@material-ui/core/Tabs'
import Tab from '@material-ui/core/Tab' import Tab from '@material-ui/core/Tab'
import CallMade from '@material-ui/icons/CallMade'
import CallReceived from '@material-ui/icons/CallReceived'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Hairline from '~/components/layout/Hairline' import Hairline from '~/components/layout/Hairline'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
@ -13,7 +15,6 @@ import Row from '~/components/layout/Row'
import Button from '~/components/layout/Button' import Button from '~/components/layout/Button'
import Link from '~/components/layout/Link' import Link from '~/components/layout/Link'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Img from '~/components/layout/Img'
import Modal from '~/components/Modal' import Modal from '~/components/Modal'
import SendModal from './Balances/SendModal' import SendModal from './Balances/SendModal'
import Receive from './Balances/Receive' import Receive from './Balances/Receive'
@ -21,7 +22,7 @@ import NoSafe from '~/components/NoSafe'
import { type SelectorProps } from '~/routes/safe/container/selector' import { type SelectorProps } from '~/routes/safe/container/selector'
import { getEtherScanLink } from '~/logic/wallets/getWeb3' import { getEtherScanLink } from '~/logic/wallets/getWeb3'
import { import {
sm, xs, secondary, smallFontSize, border, secondaryText, secondary, border,
} from '~/theme/variables' } from '~/theme/variables'
import { copyToClipboard } from '~/utils/clipboard' import { copyToClipboard } from '~/utils/clipboard'
import { type Actions } from '../container/actions' import { type Actions } from '../container/actions'
@ -30,9 +31,6 @@ import Transactions from './Transactions'
import Settings from './Settings' import Settings from './Settings'
import { styles } from './style' import { styles } from './style'
const ReceiveTx = require('./assets/tx-receive.svg')
const SendTx = require('./assets/tx-send.svg')
export const BALANCES_TAB_BTN_TEST_ID = 'balances-tab-btn' export const BALANCES_TAB_BTN_TEST_ID = 'balances-tab-btn'
export const SETTINGS_TAB_BTN_TEST_ID = 'settings-tab-btn' export const SETTINGS_TAB_BTN_TEST_ID = 'settings-tab-btn'
export const TRANSACTIONS_TAB_BTN_TEST_ID = 'transactions-tab-btn' export const TRANSACTIONS_TAB_BTN_TEST_ID = 'transactions-tab-btn'
@ -59,40 +57,6 @@ const openIconStyle = {
color: secondary, color: secondary,
} }
const styles = () => ({
container: {
display: 'flex',
alignItems: 'center',
},
name: {
marginLeft: sm,
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap',
},
user: {
justifyContent: 'left',
},
open: {
paddingLeft: sm,
width: 'auto',
'&:hover': {
cursor: 'pointer',
},
},
readonly: {
fontSize: smallFontSize,
letterSpacing: '0.5px',
color: '#ffffff',
backgroundColor: secondaryText,
textTransform: 'uppercase',
padding: `0 ${sm}`,
marginLeft: sm,
borderRadius: xs,
lineHeight: '28px',
},
})
class Layout extends React.Component<Props, State> { class Layout extends React.Component<Props, State> {
constructor(props) { constructor(props) {
super(props) super(props)
@ -166,17 +130,6 @@ class Layout extends React.Component<Props, State> {
</Block> </Block>
<Block className={classes.balance}> <Block className={classes.balance}>
<Row align="end" className={classes.actions}> <Row align="end" className={classes.actions}>
<Button
variant="contained"
size="small"
color="primary"
className={classes.receive}
onClick={onShow('Receive')}
rounded
>
<Img src={ReceiveTx} alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Receive
</Button>
{granted && ( {granted && (
<Button <Button
variant="contained" variant="contained"
@ -187,10 +140,21 @@ class Layout extends React.Component<Props, State> {
rounded rounded
testId="balance-send-btn" testId="balance-send-btn"
> >
<Img src={SendTx} alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} /> <CallMade alt="Send Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Send Send
</Button> </Button>
)} )}
<Button
variant="contained"
size="small"
color="primary"
className={classes.receive}
onClick={onShow('Receive')}
rounded
>
<CallReceived alt="Receive Transaction" className={classNames(classes.leftIcon, classes.iconSmall)} />
Receive
</Button>
</Row> </Row>
</Block> </Block>
</Block> </Block>
@ -241,6 +205,31 @@ class Layout extends React.Component<Props, State> {
createTransaction={createTransaction} createTransaction={createTransaction}
/> />
)} )}
<SendModal
onClose={hideSendFunds}
isOpen={sendFunds.isOpen}
etherScanLink={etherScanLink}
safeAddress={address}
safeName={name}
ethBalance={ethBalance}
tokens={activeTokens}
selectedToken={sendFunds.selectedToken}
createTransaction={createTransaction}
activeScreenType="chooseTxType"
/>
<Modal
title="Receive Tokens"
description="Receive Tokens Form"
handleClose={onHide('Receive')}
open={showReceive}
>
<Receive
safeName={name}
safeAddress={address}
etherScanLink={etherScanLink}
onClose={onHide('Receive')}
/>
</Modal>
</> </>
) )
} }

View File

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#FFF" fill-rule="nonzero" d="M1.778 0h12.444C15.204 0 16 .796 16 1.778v12.444c0 .982-.796 1.778-1.778 1.778H1.778A1.778 1.778 0 0 1 0 14.222V1.778C0 .796.796 0 1.778 0zM8.5 12L13 7.556h-2.7V4H6.7v3.556H4L8.5 12z"/>
</svg>

Before

Width:  |  Height:  |  Size: 322 B

View File

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#FFF" fill-rule="nonzero" d="M1.778 16h12.444c.982 0 1.778-.796 1.778-1.778V1.778C16 .796 15.204 0 14.222 0H1.778C.796 0 0 .796 0 1.778v12.444C0 15.204.796 16 1.778 16zM8 3.556L12.444 8H9.778v3.556H6.222V8H3.556L8 3.556z"/>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

View File

@ -1,5 +1,7 @@
// @flow // @flow
import { sm, xs, smallFontSize } from '~/theme/variables' import {
sm, xs, smallFontSize, secondaryText,
} from '~/theme/variables'
export const styles = () => ({ export const styles = () => ({
container: { container: {
@ -26,14 +28,16 @@ export const styles = () => ({
fontSize: smallFontSize, fontSize: smallFontSize,
letterSpacing: '0.5px', letterSpacing: '0.5px',
color: '#ffffff', color: '#ffffff',
backgroundColor: '#a2a8ba', backgroundColor: secondaryText,
fontFamily: 'Roboto Mono, monospace',
textTransform: 'uppercase', textTransform: 'uppercase',
padding: `0 ${sm}`, padding: `0 ${sm}`,
marginLeft: sm, marginLeft: sm,
borderRadius: xs, borderRadius: xs,
lineHeight: '28px', lineHeight: '28px',
}, },
iconSmall: {
fontSize: 16,
},
balance: { balance: {
marginLeft: 'auto', marginLeft: 'auto',
overflow: 'hidden', overflow: 'hidden',
@ -44,11 +48,11 @@ export const styles = () => ({
receive: { receive: {
width: '95px', width: '95px',
minWidth: '95px', minWidth: '95px',
marginLeft: sm,
}, },
send: { send: {
width: '75px', width: '75px',
minWidth: '75px', minWidth: '75px',
marginLeft: sm,
}, },
leftIcon: { leftIcon: {
marginRight: sm, marginRight: sm,