add a replacement tx search to the selector

This commit is contained in:
Mikhail Mikheev 2019-07-04 14:40:30 +04:00
parent ce65dccd82
commit 8565164d85
7 changed files with 55 additions and 11 deletions

View File

@ -11,12 +11,12 @@ import { styles } from './style'
type Props = {
classes: Object,
status: 'pending' | 'awaiting' | 'success' | 'failed',
status: 'awaiting' | 'success' | 'cancelled',
}
const statusToIcon = {
success: OkIcon,
failed: ErrorIcon,
cancelled: ErrorIcon,
awaiting: AwaitingIcon,
}

View File

@ -15,7 +15,7 @@ export const styles = () => ({
backgroundColor: '#d7f3f3',
color: '#346d6d',
},
failed: {
cancelled: {
backgroundColor: 'transparent',
color: '#fd7890',
},

View File

@ -30,6 +30,18 @@ export const formatDate = (date: Date): string => format(date, 'MMM D, YYYY - h:
export type TransactionRow = SortRow<TxData>
const getTxStatus = (tx: Transaction): string => {
let txStatus = 'awaiting'
if (tx.isExecuted) {
txStatus = 'success'
} else if (tx.cancelled) {
txStatus = 'cancelled'
}
return txStatus
}
export const getTxTableData = (transactions: List<Transaction>): List<TransactionRow> => {
const rows = transactions.map((tx: Transaction) => {
const txDate = tx.isExecuted ? tx.executionDate : tx.submissionDate
@ -40,7 +52,7 @@ export const getTxTableData = (transactions: List<Transaction>): List<Transactio
[TX_TABLE_DATE_ID]: formatDate(tx.isExecuted ? tx.executionDate : tx.submissionDate),
[buildOrderFieldFrom(TX_TABLE_DATE_ID)]: getTime(txDate),
[TX_TABLE_AMOUNT_ID]: Number(tx.value) > 0 ? `${fromWei(toBN(tx.value), 'ether')} ${tx.symbol}` : 'n/a',
[TX_TABLE_STATUS_ID]: tx.isExecuted ? 'success' : 'awaiting',
[TX_TABLE_STATUS_ID]: getTxStatus(tx),
[TX_TABLE_RAW_TX_ID]: tx,
}
})

View File

@ -50,8 +50,8 @@ const TxsTable = ({
}: Props) => {
const [expandedTx, setExpandedTx] = useState<string | null>(null)
const handleTxExpand = (nonce) => {
setExpandedTx(prevTx => (prevTx === nonce ? null : nonce))
const handleTxExpand = (creationTxHash) => {
setExpandedTx(prevTx => (prevTx === creationTxHash ? null : creationTxHash))
}
const columns = generateColumns()
@ -73,8 +73,8 @@ const TxsTable = ({
<React.Fragment key={index}>
<TableRow
tabIndex={-1}
className={cn(classes.row, expandedTx === row.tx.id && classes.expandedRow)}
onClick={() => handleTxExpand(row.tx.id)}
className={cn(classes.row, expandedTx === row.tx.creationTxHash && classes.expandedRow)}
onClick={() => handleTxExpand(row.tx.creationTxHash)}
>
{autoColumns.map((column: Column) => (
<TableCell
@ -103,7 +103,7 @@ const TxsTable = ({
className={classes.extendedTxContainer}
>
<Collapse
in={expandedTx === row.tx.id}
in={expandedTx === row.tx.creationTxHash}
timeout="auto"
component={ExpandedTxComponent}
unmountOnExit

View File

@ -1,6 +1,7 @@
// @flow
import { List, Map } from 'immutable'
import { createSelector, createStructuredSelector, type Selector } from 'reselect'
import { isAfter } from 'date-fns'
import {
safeSelector,
safeActiveTokensSelector,
@ -89,6 +90,31 @@ const extendedSafeTokensSelector: Selector<GlobalState, RouterProps, List<Token>
},
)
const extendedTransactionsSelector: Selector<GlobalState, RouterProps, List<Transaction>> = createSelector(
safeTransactionsSelector,
(transactions) => {
const extendedTransactions = transactions.map((tx: Transaction) => {
if (tx.isExecuted) {
return tx
}
// If transactions is not executed, but there's a transaction with the same nonce submitted later
// it means that the transaction was cancelled (Replaced) and shouldn't get executed
const replacementTransaction = transactions.findLast(
transaction => transaction.nonce === tx.nonce && isAfter(transaction.submissionDate, tx.submissionDate),
)
if (!replacementTransaction) {
return tx
}
return tx.set('cancelled', true)
})
return extendedTransactions
},
)
export default createStructuredSelector<Object, *>({
safe: safeSelector,
provider: providerNameSelector,
@ -98,5 +124,5 @@ export default createStructuredSelector<Object, *>({
userAddress: userAccountSelector,
network: networkSelector,
safeUrl: safeParamAddressSelector,
transactions: safeTransactionsSelector,
transactions: extendedTransactionsSelector,
})

View File

@ -13,7 +13,7 @@ import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { addTransactions } from './addTransactions'
import { getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
import { isAddressAToken } from '~/logic/tokens/utils/tokenHelpers'
import { TX_TYPE_EXECUTION } from '~/logic/safe/transactions/send'
import { TX_TYPE_EXECUTION, TX_TYPE_CONFIRMATION } from '~/logic/safe/transactions/send'
type ConfirmationServiceModel = {
owner: string,
@ -49,6 +49,7 @@ const buildTransactionFrom = async (safeAddress: string, tx: TxServiceModel, saf
}),
)
const isToken = await isAddressAToken(tx.to)
const creationTxHash = confirmations.find(conf => conf.type === TX_TYPE_CONFIRMATION).hash
let executionTxHash
const executionTx = confirmations.find(conf => conf.type === TX_TYPE_EXECUTION)
@ -76,6 +77,7 @@ const buildTransactionFrom = async (safeAddress: string, tx: TxServiceModel, saf
submissionDate: tx.submissionDate,
executionDate: tx.executionDate,
executionTxHash,
creationTxHash,
})
}

View File

@ -14,7 +14,9 @@ export type TransactionProps = {
submissionDate: Date,
executionDate: Date,
symbol: string,
creationTxHash: string,
executionTxHash?: string,
cancelled?: boolean,
}
export const makeTransaction: RecordFactory<TransactionProps> = Record({
@ -29,6 +31,8 @@ export const makeTransaction: RecordFactory<TransactionProps> = Record({
executionDate: '',
symbol: '',
executionTxHash: undefined,
creationTxHash: '',
cancelled: false,
})
export type Transaction = RecordOf<TransactionProps>