TxsTable wip
This commit is contained in:
parent
1a5beb16a4
commit
c66c59c326
|
@ -0,0 +1,60 @@
|
||||||
|
// @flow
|
||||||
|
import { List } from 'immutable'
|
||||||
|
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||||
|
import { buildOrderFieldFrom, FIXED, type SortRow } from '~/components/Table/sorting'
|
||||||
|
import { type Column } from '~/components/Table/TableHead'
|
||||||
|
|
||||||
|
export const TX_TABLE_NONCE_ID = 'nonce'
|
||||||
|
export const TX_TABLE_TYPE_ID = 'type'
|
||||||
|
export const TX_TABLE_DATE_ID = 'date'
|
||||||
|
export const TX_TABLE_AMOUNT_ID = 'amount'
|
||||||
|
export const TX_TABLE_STATUS_ID = 'status'
|
||||||
|
|
||||||
|
type BalanceData = {
|
||||||
|
asset: Object,
|
||||||
|
balance: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BalanceRow = SortRow<BalanceData>
|
||||||
|
|
||||||
|
export const getBalanceData = (activeTokens: List<Token>): List<BalanceRow> => {
|
||||||
|
const rows = activeTokens.map((token: Token) => ({
|
||||||
|
[BALANCE_TABLE_ASSET_ID]: { name: token.name, logoUri: token.logoUri },
|
||||||
|
[buildOrderFieldFrom(BALANCE_TABLE_ASSET_ID)]: token.name,
|
||||||
|
[BALANCE_TABLE_BALANCE_ID]: `${token.balance} ${token.symbol}`,
|
||||||
|
[buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: Number(token.balance),
|
||||||
|
[FIXED]: token.get('symbol') === 'ETH',
|
||||||
|
}))
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateColumns = () => {
|
||||||
|
const assetColumn: Column = {
|
||||||
|
id: BALANCE_TABLE_ASSET_ID,
|
||||||
|
order: true,
|
||||||
|
disablePadding: false,
|
||||||
|
label: 'Asset',
|
||||||
|
custom: false,
|
||||||
|
width: 250,
|
||||||
|
}
|
||||||
|
|
||||||
|
const balanceColumn: Column = {
|
||||||
|
id: BALANCE_TABLE_BALANCE_ID,
|
||||||
|
align: 'right',
|
||||||
|
order: true,
|
||||||
|
disablePadding: false,
|
||||||
|
label: 'Balance',
|
||||||
|
custom: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions: Column = {
|
||||||
|
id: 'actions',
|
||||||
|
order: false,
|
||||||
|
disablePadding: false,
|
||||||
|
label: '',
|
||||||
|
custom: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return List([assetColumn, balanceColumn, actions])
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react'
|
||||||
|
import { List } from 'immutable'
|
||||||
|
import classNames from 'classnames/bind'
|
||||||
|
import { type Token } from '~/logic/tokens/store/model/token'
|
||||||
|
import CallMade from '@material-ui/icons/CallMade'
|
||||||
|
import CallReceived from '@material-ui/icons/CallReceived'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import Checkbox from '@material-ui/core/Checkbox'
|
||||||
|
import TableRow from '@material-ui/core/TableRow'
|
||||||
|
import TableCell from '@material-ui/core/TableCell'
|
||||||
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
|
import Col from '~/components/layout/Col'
|
||||||
|
import Row from '~/components/layout/Row'
|
||||||
|
import Paragraph from '~/components/layout/Paragraph'
|
||||||
|
import Modal from '~/components/Modal'
|
||||||
|
import { type Column, cellWidth } from '~/components/Table/TableHead'
|
||||||
|
import Table from '~/components/Table'
|
||||||
|
import {
|
||||||
|
getBalanceData, generateColumns, BALANCE_TABLE_ASSET_ID, type BalanceRow, filterByZero,
|
||||||
|
} from './dataFetcher'
|
||||||
|
import { styles } from './style'
|
||||||
|
|
||||||
|
export const MANAGE_TOKENS_BUTTON_TEST_ID = 'manage-tokens-btn'
|
||||||
|
export const BALANCE_ROW_TEST_ID = 'balance-row'
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
hideZero: boolean,
|
||||||
|
showToken: boolean,
|
||||||
|
showReceive: boolean,
|
||||||
|
sendFunds: Object,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
classes: Object,
|
||||||
|
granted: boolean,
|
||||||
|
tokens: List<Token>,
|
||||||
|
activeTokens: List<Token>,
|
||||||
|
safeAddress: string,
|
||||||
|
safeName: string,
|
||||||
|
etherScanLink: string,
|
||||||
|
ethBalance: string,
|
||||||
|
createTransaction: Function,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Action = 'Token' | 'Send' | 'Receive'
|
||||||
|
|
||||||
|
class Balances extends React.Component<Props, State> {
|
||||||
|
state = {
|
||||||
|
hideZero: false,
|
||||||
|
showToken: false,
|
||||||
|
sendFunds: {
|
||||||
|
isOpen: false,
|
||||||
|
selectedToken: undefined,
|
||||||
|
},
|
||||||
|
showReceive: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
onShow = (action: Action) => () => {
|
||||||
|
this.setState(() => ({ [`show${action}`]: true }))
|
||||||
|
}
|
||||||
|
|
||||||
|
onHide = (action: Action) => () => {
|
||||||
|
this.setState(() => ({ [`show${action}`]: false }))
|
||||||
|
}
|
||||||
|
|
||||||
|
showSendFunds = (token: Token) => {
|
||||||
|
this.setState({
|
||||||
|
sendFunds: {
|
||||||
|
isOpen: true,
|
||||||
|
selectedToken: token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
hideSendFunds = () => {
|
||||||
|
this.setState({
|
||||||
|
sendFunds: {
|
||||||
|
isOpen: false,
|
||||||
|
selectedToken: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = (e: SyntheticInputEvent<HTMLInputElement>) => {
|
||||||
|
const { checked } = e.target
|
||||||
|
|
||||||
|
this.setState(() => ({ hideZero: checked }))
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
hideZero, showToken, showReceive, sendFunds,
|
||||||
|
} = this.state
|
||||||
|
const {
|
||||||
|
classes,
|
||||||
|
granted,
|
||||||
|
tokens,
|
||||||
|
safeAddress,
|
||||||
|
activeTokens,
|
||||||
|
safeName,
|
||||||
|
etherScanLink,
|
||||||
|
ethBalance,
|
||||||
|
createTransaction,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const columns = generateColumns()
|
||||||
|
const autoColumns = columns.filter(c => !c.custom)
|
||||||
|
const checkboxClasses = {
|
||||||
|
root: classes.root,
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredData = filterByZero(getBalanceData(activeTokens), hideZero)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Table
|
||||||
|
label="Balances"
|
||||||
|
defaultOrderBy={BALANCE_TABLE_ASSET_ID}
|
||||||
|
columns={columns}
|
||||||
|
data={filteredData}
|
||||||
|
size={filteredData.size}
|
||||||
|
defaultFixed
|
||||||
|
>
|
||||||
|
{(sortedData: Array<BalanceRow>) => sortedData.map((row: any, index: number) => (
|
||||||
|
<TableRow tabIndex={-1} key={index} className={classes.hide} data-testid={BALANCE_ROW_TEST_ID}>
|
||||||
|
{autoColumns.map((column: Column) => (
|
||||||
|
<TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td">
|
||||||
|
{column.id === BALANCE_TABLE_ASSET_ID ? <AssetTableCell asset={row[column.id]} /> : row[column.id]}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
<TableCell component="td">
|
||||||
|
<Row align="end" className={classes.actions}>
|
||||||
|
{granted && (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
className={classes.send}
|
||||||
|
onClick={() => this.showSendFunds(row.asset.name)}
|
||||||
|
data-testid="balance-send-btn"
|
||||||
|
>
|
||||||
|
<CallMade className={classNames(classes.leftIcon, classes.iconSmall)} />
|
||||||
|
Send
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
className={classes.receive}
|
||||||
|
onClick={this.onShow('Receive')}
|
||||||
|
>
|
||||||
|
<CallReceived className={classNames(classes.leftIcon, classes.iconSmall)} />
|
||||||
|
Receive
|
||||||
|
</Button>
|
||||||
|
</Row>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Table>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(styles)(Balances)
|
|
@ -6,6 +6,7 @@ import NoTransactions from '~/routes/safe/components/Transactions/NoTransactions
|
||||||
type Props = {
|
type Props = {
|
||||||
safeAddress: string,
|
safeAddress: string,
|
||||||
threshold: number,
|
threshold: number,
|
||||||
|
fetchTransactions: Function
|
||||||
}
|
}
|
||||||
|
|
||||||
class Transactions extends React.Component<Props, {}> {
|
class Transactions extends React.Component<Props, {}> {
|
||||||
|
@ -16,11 +17,15 @@ class Transactions extends React.Component<Props, {}> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { transactions = List(), safeName, threshold } = this.props
|
const { transactions, safeName, threshold } = this.props
|
||||||
const hasTransactions = false
|
const hasTransactions = false
|
||||||
|
|
||||||
return <React.Fragment>{hasTransactions ? <div /> : <NoTransactions />}</React.Fragment>
|
return <React.Fragment>{hasTransactions ? <div /> : <NoTransactions />}</React.Fragment>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transactions.defaultProps = {
|
||||||
|
transactions: List(),
|
||||||
|
}
|
||||||
|
|
||||||
export default Transactions
|
export default Transactions
|
||||||
|
|
|
@ -62,8 +62,8 @@ export const loadSafeTransactions = async (safeAddress: string) => {
|
||||||
const response = await axios.get(url)
|
const response = await axios.get(url)
|
||||||
const transactions: TxServiceModel[] = response.data.results
|
const transactions: TxServiceModel[] = response.data.results
|
||||||
const safeSubjects = loadSafeSubjects(safeAddress)
|
const safeSubjects = loadSafeSubjects(safeAddress)
|
||||||
const txsRecord = transactions.map(
|
const txsRecord = await Promise.all(
|
||||||
async (tx: TxServiceModel) => await buildTransactionFrom(safeAddress, tx, safeSubjects),
|
transactions.map((tx: TxServiceModel) => buildTransactionFrom(safeAddress, tx, safeSubjects)),
|
||||||
)
|
)
|
||||||
|
|
||||||
return Map().set(safeAddress, List(txsRecord))
|
return Map().set(safeAddress, List(txsRecord))
|
||||||
|
|
Loading…
Reference in New Issue