feat: show transaction sweep status
This commit is contained in:
parent
fa0ef6b053
commit
10245bbb19
8 changed files with 61 additions and 19 deletions
|
|
@ -21,7 +21,8 @@ function transaction () {
|
||||||
SELECT 'address' AS type, to_address AS value FROM cash_in_txs UNION
|
SELECT 'address' AS type, to_address AS value FROM cash_in_txs UNION
|
||||||
SELECT 'address' AS type, to_address AS value FROM cash_out_txs UNION
|
SELECT 'address' AS type, to_address AS value FROM cash_out_txs UNION
|
||||||
SELECT 'status' AS type, ${cashInTx.TRANSACTION_STATES} AS value FROM cash_in_txs UNION
|
SELECT 'status' AS type, ${cashInTx.TRANSACTION_STATES} AS value FROM cash_in_txs UNION
|
||||||
SELECT 'status' AS type, ${CASH_OUT_TRANSACTION_STATES} AS value FROM cash_out_txs
|
SELECT 'status' AS type, ${CASH_OUT_TRANSACTION_STATES} AS value FROM cash_out_txs UNION
|
||||||
|
SELECT 'sweep status' AS type, CASE WHEN swept THEN 'Swept' WHEN NOT swept THEN 'Unswept' END AS value FROM cash_out_txs
|
||||||
) f`
|
) f`
|
||||||
|
|
||||||
return db.any(sql)
|
return db.any(sql)
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ const resolvers = {
|
||||||
isAnonymous: parent => (parent.customerId === anonymous.uuid)
|
isAnonymous: parent => (parent.customerId === anonymous.uuid)
|
||||||
},
|
},
|
||||||
Query: {
|
Query: {
|
||||||
transactions: (...[, { from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers }]) =>
|
transactions: (...[, { from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept, excludeTestingCustomers }]) =>
|
||||||
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers),
|
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept, excludeTestingCustomers),
|
||||||
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, timezone, excludeTestingCustomers, simplified }]) =>
|
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept, timezone, excludeTestingCustomers, simplified }]) =>
|
||||||
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers, simplified)
|
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept, excludeTestingCustomers, simplified)
|
||||||
.then(data => parseAsync(logDateFormat(timezone, data, ['created', 'sendTime']))),
|
.then(data => parseAsync(logDateFormat(timezone, data, ['created', 'sendTime', 'publishedAt']))),
|
||||||
transactionCsv: (...[, { id, txClass, timezone }]) =>
|
transactionCsv: (...[, { id, txClass, timezone }]) =>
|
||||||
transactions.getTx(id, txClass).then(data =>
|
transactions.getTx(id, txClass).then(data =>
|
||||||
parseAsync(logDateFormat(timezone, [data], ['created', 'sendTime']))
|
parseAsync(logDateFormat(timezone, [data], ['created', 'sendTime']))
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ const typeDef = gql`
|
||||||
batchError: String
|
batchError: String
|
||||||
walletScore: Int
|
walletScore: Int
|
||||||
profit: String
|
profit: String
|
||||||
|
swept: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type Filter {
|
type Filter {
|
||||||
|
|
@ -58,8 +59,8 @@ const typeDef = gql`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, excludeTestingCustomers: Boolean): [Transaction] @auth
|
transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, swept: Boolean, excludeTestingCustomers: Boolean): [Transaction] @auth
|
||||||
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, timezone: String, excludeTestingCustomers: Boolean, simplified: Boolean): String @auth
|
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, swept: Boolean, timezone: String, excludeTestingCustomers: Boolean, simplified: Boolean): String @auth
|
||||||
transactionCsv(id: ID, txClass: String, timezone: String): String @auth
|
transactionCsv(id: ID, txClass: String, timezone: String): String @auth
|
||||||
txAssociatedDataCsv(id: ID, txClass: String, timezone: String): String @auth
|
txAssociatedDataCsv(id: ID, txClass: String, timezone: String): String @auth
|
||||||
transactionFilters: [Filter] @auth
|
transactionFilters: [Filter] @auth
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ function batch (
|
||||||
cryptoCode = null,
|
cryptoCode = null,
|
||||||
toAddress = null,
|
toAddress = null,
|
||||||
status = null,
|
status = null,
|
||||||
|
swept = null,
|
||||||
excludeTestingCustomers = false,
|
excludeTestingCustomers = false,
|
||||||
simplified
|
simplified
|
||||||
) {
|
) {
|
||||||
|
|
@ -109,14 +110,33 @@ function batch (
|
||||||
AND ($11 is null or txs.crypto_code = $11)
|
AND ($11 is null or txs.crypto_code = $11)
|
||||||
AND ($12 is null or txs.to_address = $12)
|
AND ($12 is null or txs.to_address = $12)
|
||||||
AND ($13 is null or txs.txStatus = $13)
|
AND ($13 is null or txs.txStatus = $13)
|
||||||
|
AND ($14 is null or txs.swept = $14)
|
||||||
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
||||||
AND (fiat > 0)
|
AND (fiat > 0)
|
||||||
ORDER BY created DESC limit $4 offset $5`
|
ORDER BY created DESC limit $4 offset $5`
|
||||||
|
|
||||||
return Promise.all([
|
// The swept filter is cash-out only, so omit the cash-in query entirely
|
||||||
|
const hasCashInOnlyFilters = false
|
||||||
|
const hasCashOutOnlyFilters = !_.isNil(swept)
|
||||||
|
|
||||||
|
let promises
|
||||||
|
|
||||||
|
if (hasCashInOnlyFilters && hasCashOutOnlyFilters) {
|
||||||
|
throw new Error('Trying to filter transactions with mutually exclusive filters')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCashInOnlyFilters) {
|
||||||
|
promises = [db.any(cashInSql, [cashInTx.PENDING_INTERVAL, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status])]
|
||||||
|
} else if (hasCashOutOnlyFilters) {
|
||||||
|
promises = [db.any(cashOutSql, [REDEEMABLE_AGE, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept])]
|
||||||
|
} else {
|
||||||
|
promises = [
|
||||||
db.any(cashInSql, [cashInTx.PENDING_INTERVAL, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status]),
|
db.any(cashInSql, [cashInTx.PENDING_INTERVAL, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status]),
|
||||||
db.any(cashOutSql, [REDEEMABLE_AGE, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status])
|
db.any(cashOutSql, [REDEEMABLE_AGE, from, until, limit, offset, id, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, swept])
|
||||||
])
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises)
|
||||||
.then(packager)
|
.then(packager)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (simplified) return simplifiedBatch(res)
|
if (simplified) return simplifiedBatch(res)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { P, Label3 } from 'src/components/typography'
|
||||||
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
|
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
|
||||||
import { ReactComponent as FilterIcon } from 'src/styling/icons/button/filter/white.svg'
|
import { ReactComponent as FilterIcon } from 'src/styling/icons/button/filter/white.svg'
|
||||||
import { ReactComponent as ReverseFilterIcon } from 'src/styling/icons/button/filter/zodiac.svg'
|
import { ReactComponent as ReverseFilterIcon } from 'src/styling/icons/button/filter/zodiac.svg'
|
||||||
import { onlyFirstToUpper } from 'src/utils/string'
|
import { onlyFirstToUpper, singularOrPlural } from 'src/utils/string'
|
||||||
|
|
||||||
import { chipStyles, styles } from './SearchFilter.styles'
|
import { chipStyles, styles } from './SearchFilter.styles'
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ const SearchFilter = ({
|
||||||
filters,
|
filters,
|
||||||
onFilterDelete,
|
onFilterDelete,
|
||||||
deleteAllFilters,
|
deleteAllFilters,
|
||||||
entries
|
entries = 0
|
||||||
}) => {
|
}) => {
|
||||||
const chipClasses = useChipStyles()
|
const chipClasses = useChipStyles()
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
@ -40,8 +40,11 @@ const SearchFilter = ({
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.deleteWrapper}>
|
<div className={classes.deleteWrapper}>
|
||||||
{
|
{
|
||||||
<Label3 className={classes.entries}>{`${entries ??
|
<Label3 className={classes.entries}>{`${entries} ${singularOrPlural(
|
||||||
0} entries`}</Label3>
|
entries,
|
||||||
|
`entry`,
|
||||||
|
`entries`
|
||||||
|
)}`}</Label3>
|
||||||
}
|
}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,14 @@ const DetailsRow = ({ it: tx, timezone }) => {
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{!R.isNil(tx.swept) && (
|
||||||
|
<div className={classes.swept}>
|
||||||
|
<Label>Sweep status</Label>
|
||||||
|
<span className={classes.bold}>
|
||||||
|
{tx.swept ? `Swept` : `Unswept`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<Label>Other actions</Label>
|
<Label>Other actions</Label>
|
||||||
<div className={classes.otherActionsGroup}>
|
<div className={classes.otherActionsGroup}>
|
||||||
|
|
|
||||||
|
|
@ -131,5 +131,8 @@ export default {
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
color: tomato
|
color: tomato
|
||||||
|
},
|
||||||
|
swept: {
|
||||||
|
width: 250
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ const GET_TRANSACTIONS = gql`
|
||||||
$cryptoCode: String
|
$cryptoCode: String
|
||||||
$toAddress: String
|
$toAddress: String
|
||||||
$status: String
|
$status: String
|
||||||
|
$swept: Boolean
|
||||||
) {
|
) {
|
||||||
transactions(
|
transactions(
|
||||||
limit: $limit
|
limit: $limit
|
||||||
|
|
@ -87,6 +88,7 @@ const GET_TRANSACTIONS = gql`
|
||||||
cryptoCode: $cryptoCode
|
cryptoCode: $cryptoCode
|
||||||
toAddress: $toAddress
|
toAddress: $toAddress
|
||||||
status: $status
|
status: $status
|
||||||
|
swept: $swept
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
txClass
|
txClass
|
||||||
|
|
@ -121,6 +123,7 @@ const GET_TRANSACTIONS = gql`
|
||||||
rawTickerPrice
|
rawTickerPrice
|
||||||
batchError
|
batchError
|
||||||
walletScore
|
walletScore
|
||||||
|
swept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
@ -246,7 +249,8 @@ const Transactions = () => {
|
||||||
fiatCode: filtersObject.fiat,
|
fiatCode: filtersObject.fiat,
|
||||||
cryptoCode: filtersObject.crypto,
|
cryptoCode: filtersObject.crypto,
|
||||||
toAddress: filtersObject.address,
|
toAddress: filtersObject.address,
|
||||||
status: filtersObject.status
|
status: filtersObject.status,
|
||||||
|
swept: filtersObject.swept === 'Swept'
|
||||||
})
|
})
|
||||||
|
|
||||||
refetch && refetch()
|
refetch && refetch()
|
||||||
|
|
@ -269,7 +273,8 @@ const Transactions = () => {
|
||||||
fiatCode: filtersObject.fiat,
|
fiatCode: filtersObject.fiat,
|
||||||
cryptoCode: filtersObject.crypto,
|
cryptoCode: filtersObject.crypto,
|
||||||
toAddress: filtersObject.address,
|
toAddress: filtersObject.address,
|
||||||
status: filtersObject.status
|
status: filtersObject.status,
|
||||||
|
swept: filtersObject.swept === 'Swept'
|
||||||
})
|
})
|
||||||
|
|
||||||
refetch && refetch()
|
refetch && refetch()
|
||||||
|
|
@ -287,7 +292,8 @@ const Transactions = () => {
|
||||||
fiatCode: filtersObject.fiat,
|
fiatCode: filtersObject.fiat,
|
||||||
cryptoCode: filtersObject.crypto,
|
cryptoCode: filtersObject.crypto,
|
||||||
toAddress: filtersObject.address,
|
toAddress: filtersObject.address,
|
||||||
status: filtersObject.status
|
status: filtersObject.status,
|
||||||
|
swept: filtersObject.swept === 'Swept'
|
||||||
})
|
})
|
||||||
|
|
||||||
refetch && refetch()
|
refetch && refetch()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue