mirror of
https://github.com/status-im/safe-react.git
synced 2025-02-26 00:15:23 +00:00
refactoring ownersList column, move it to separate component to decrease complexity of ExpandedTx component
This commit is contained in:
parent
7cd59d918f
commit
d768fcbdae
@ -0,0 +1,120 @@
|
|||||||
|
// @flow
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { List } from 'immutable'
|
||||||
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
|
import Tabs from '@material-ui/core/Tabs'
|
||||||
|
import Tab from '@material-ui/core/Tab'
|
||||||
|
import Col from '~/components/layout/Col'
|
||||||
|
import Row from '~/components/layout/Row'
|
||||||
|
import Hairline from '~/components/layout/Hairline'
|
||||||
|
import { type Owner } from '~/routes/safe/store/models/owner'
|
||||||
|
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||||
|
import { TX_TYPE_CONFIRMATION } from '~/logic/safe/transactions/send'
|
||||||
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
|
import OwnersList from './List'
|
||||||
|
import ButtonRow from './ButtonRow'
|
||||||
|
import { styles } from './style'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
tx: Transaction,
|
||||||
|
owners: List<Owner>,
|
||||||
|
classes: Object,
|
||||||
|
granted: boolean,
|
||||||
|
threshold: number,
|
||||||
|
userAddress: string,
|
||||||
|
thresholdReached: boolean,
|
||||||
|
safeAddress: string,
|
||||||
|
onTxConfirm: Function,
|
||||||
|
onTxCancel: Function,
|
||||||
|
onTxExecute: Function,
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCancellationTransaction = (tx: Transaction, safeAddress: string) => !tx.value && tx.data === EMPTY_DATA && tx.recipient === safeAddress
|
||||||
|
|
||||||
|
const OwnersColumn = ({
|
||||||
|
tx,
|
||||||
|
owners,
|
||||||
|
classes,
|
||||||
|
granted,
|
||||||
|
threshold,
|
||||||
|
userAddress,
|
||||||
|
thresholdReached,
|
||||||
|
safeAddress,
|
||||||
|
onTxConfirm,
|
||||||
|
onTxCancel,
|
||||||
|
onTxExecute,
|
||||||
|
}: Props) => {
|
||||||
|
const [tabIndex, setTabIndex] = useState(0)
|
||||||
|
const handleTabChange = (event, tabClicked) => {
|
||||||
|
setTabIndex(tabClicked)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancellationTx = isCancellationTransaction(tx, safeAddress)
|
||||||
|
const confirmedLabel = `Confirmed [${
|
||||||
|
tx.confirmations.filter(conf => conf.type === TX_TYPE_CONFIRMATION).size
|
||||||
|
}/${threshold}]`
|
||||||
|
const unconfirmedLabel = `Unconfirmed [${owners.size - tx.confirmations.size}]`
|
||||||
|
|
||||||
|
const ownersWhoConfirmed = []
|
||||||
|
const ownersUnconfirmed = []
|
||||||
|
|
||||||
|
let currentUserAlreadyConfirmed = false
|
||||||
|
let executionConfirmation
|
||||||
|
owners.forEach((owner) => {
|
||||||
|
const ownerConfirmation = tx.confirmations.find(conf => conf.owner.address === owner.address)
|
||||||
|
if (ownerConfirmation) {
|
||||||
|
if (ownerConfirmation.type === TX_TYPE_CONFIRMATION) {
|
||||||
|
ownersWhoConfirmed.push(owner)
|
||||||
|
} else {
|
||||||
|
executionConfirmation = owner
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner.address === userAddress) {
|
||||||
|
currentUserAlreadyConfirmed = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ownersUnconfirmed.push(owner)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let displayButtonRow = true
|
||||||
|
if (tx.isExecuted) {
|
||||||
|
// already executed, can't do any actions
|
||||||
|
displayButtonRow = false
|
||||||
|
} else if (tx.status === 'cancelled') {
|
||||||
|
// tx is cancelled (replaced) by another one
|
||||||
|
displayButtonRow = false
|
||||||
|
} else if (cancellationTx && currentUserAlreadyConfirmed && !thresholdReached) {
|
||||||
|
// the TX is the cancellation (replacement) transaction for previous TX,
|
||||||
|
// current user has already confirmed it and threshold is not reached (so he can't execute/cancel it)
|
||||||
|
displayButtonRow = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col xs={6} className={classes.rightCol} layout="block">
|
||||||
|
<Row>
|
||||||
|
<Tabs value={tabIndex} onChange={handleTabChange} indicatorColor="secondary" textColor="secondary">
|
||||||
|
<Tab label={confirmedLabel} />
|
||||||
|
<Tab label={unconfirmedLabel} />
|
||||||
|
</Tabs>
|
||||||
|
<Hairline color="#c8ced4" />
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
{tabIndex === 0 && <OwnersList owners={ownersWhoConfirmed} executionConfirmation={executionConfirmation} />}
|
||||||
|
</Row>
|
||||||
|
<Row>{tabIndex === 1 && <OwnersList owners={ownersUnconfirmed} />}</Row>
|
||||||
|
{granted && displayButtonRow && (
|
||||||
|
<ButtonRow
|
||||||
|
onTxConfirm={onTxConfirm}
|
||||||
|
onTxCancel={onTxCancel}
|
||||||
|
showConfirmBtn={!currentUserAlreadyConfirmed}
|
||||||
|
showCancelBtn={!cancellationTx}
|
||||||
|
showExecuteBtn={thresholdReached}
|
||||||
|
onTxExecute={onTxExecute}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(styles)(OwnersColumn)
|
@ -17,10 +17,8 @@ import { type Owner } from '~/routes/safe/store/models/owner'
|
|||||||
import { getEtherScanLink, openTxInEtherScan, getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getEtherScanLink, openTxInEtherScan, getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||||
import { TX_TYPE_CONFIRMATION } from '~/logic/safe/transactions'
|
import { TX_TYPE_CONFIRMATION } from '~/logic/safe/transactions'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
|
||||||
import { secondary } from '~/theme/variables'
|
import { secondary } from '~/theme/variables'
|
||||||
import OwnersList from './OwnersList'
|
import OwnersColumn from './OwnersColumn'
|
||||||
import ButtonRow from './ButtonRow'
|
|
||||||
import CancelTxModal from './CancelTxModal'
|
import CancelTxModal from './CancelTxModal'
|
||||||
import ApproveTxModal from './ApproveTxModal'
|
import ApproveTxModal from './ApproveTxModal'
|
||||||
import { styles } from './style'
|
import { styles } from './style'
|
||||||
@ -55,8 +53,6 @@ const txStatusToLabel = {
|
|||||||
awaiting_execution: 'Awaiting execution',
|
awaiting_execution: 'Awaiting execution',
|
||||||
}
|
}
|
||||||
|
|
||||||
const isCancellationTransaction = (tx: Transaction, safeAddress: string) => !tx.value && tx.data === EMPTY_DATA && tx.recipient === safeAddress
|
|
||||||
|
|
||||||
const ExpandedTx = ({
|
const ExpandedTx = ({
|
||||||
classes,
|
classes,
|
||||||
tx,
|
tx,
|
||||||
@ -68,57 +64,12 @@ const ExpandedTx = ({
|
|||||||
createTransaction,
|
createTransaction,
|
||||||
processTransaction,
|
processTransaction,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [tabIndex, setTabIndex] = useState<number>(0)
|
|
||||||
const [openModal, setOpenModal] = useState<OpenModal>(null)
|
const [openModal, setOpenModal] = useState<OpenModal>(null)
|
||||||
const openApproveModal = () => setOpenModal('approveTx')
|
const openApproveModal = () => setOpenModal('approveTx')
|
||||||
const openCancelModal = () => setOpenModal('cancelTx')
|
const openCancelModal = () => setOpenModal('cancelTx')
|
||||||
const closeModal = () => setOpenModal(null)
|
const closeModal = () => setOpenModal(null)
|
||||||
const cancellationTx = isCancellationTransaction(tx, safeAddress)
|
|
||||||
const confirmedLabel = `Confirmed [${
|
|
||||||
tx.confirmations.filter(conf => conf.type === TX_TYPE_CONFIRMATION).size
|
|
||||||
}/${threshold}]`
|
|
||||||
const unconfirmedLabel = `Unconfirmed [${owners.size - tx.confirmations.size}]`
|
|
||||||
const thresholdReached = threshold <= tx.confirmations.size
|
const thresholdReached = threshold <= tx.confirmations.size
|
||||||
|
|
||||||
const ownersWhoConfirmed = []
|
|
||||||
const ownersUnconfirmed = []
|
|
||||||
|
|
||||||
let currentUserAlreadyConfirmed = false
|
|
||||||
let executionConfirmation
|
|
||||||
owners.forEach((owner) => {
|
|
||||||
const ownerConfirmation = tx.confirmations.find(conf => conf.owner.address === owner.address)
|
|
||||||
if (ownerConfirmation) {
|
|
||||||
if (ownerConfirmation.type === TX_TYPE_CONFIRMATION) {
|
|
||||||
ownersWhoConfirmed.push(owner)
|
|
||||||
} else {
|
|
||||||
executionConfirmation = owner
|
|
||||||
}
|
|
||||||
|
|
||||||
if (owner.address === userAddress) {
|
|
||||||
currentUserAlreadyConfirmed = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ownersUnconfirmed.push(owner)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let displayButtonRow = true
|
|
||||||
if (tx.isExecuted) {
|
|
||||||
// already executed, can't do any actions
|
|
||||||
displayButtonRow = false
|
|
||||||
} else if (tx.status === 'cancelled') {
|
|
||||||
// tx is cancelled (replaced) by another one
|
|
||||||
displayButtonRow = false
|
|
||||||
} else if (cancellationTx && currentUserAlreadyConfirmed && !thresholdReached) {
|
|
||||||
// the TX is the cancellation (replacement) transaction for previous TX,
|
|
||||||
// current user has already confirmed it and threshold is not reached (so he can't execute/cancel it)
|
|
||||||
displayButtonRow = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleTabChange = (event, tabClicked) => {
|
|
||||||
setTabIndex(tabClicked)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Block>
|
<Block>
|
||||||
@ -173,31 +124,18 @@ to:
|
|||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Block>
|
</Block>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={6} className={classes.rightCol} layout="block">
|
<OwnersColumn
|
||||||
<Row>
|
tx={tx}
|
||||||
<Tabs value={tabIndex} onChange={handleTabChange} indicatorColor="secondary" textColor="secondary">
|
owners={owners}
|
||||||
<Tab label={confirmedLabel} />
|
granted={granted}
|
||||||
<Tab label={unconfirmedLabel} />
|
threshold={threshold}
|
||||||
</Tabs>
|
userAddress={userAddress}
|
||||||
<Hairline color="#c8ced4" />
|
thresholdReached={thresholdReached}
|
||||||
</Row>
|
safeAddress={safeAddress}
|
||||||
<Row>
|
onTxConfirm={openApproveModal}
|
||||||
{tabIndex === 0 && (
|
onTxCancel={openCancelModal}
|
||||||
<OwnersList owners={ownersWhoConfirmed} executionConfirmation={executionConfirmation} />
|
onTxExecute={openApproveModal}
|
||||||
)}
|
/>
|
||||||
</Row>
|
|
||||||
<Row>{tabIndex === 1 && <OwnersList owners={ownersUnconfirmed} />}</Row>
|
|
||||||
{granted && displayButtonRow && (
|
|
||||||
<ButtonRow
|
|
||||||
onTxConfirm={openApproveModal}
|
|
||||||
onTxCancel={openCancelModal}
|
|
||||||
showConfirmBtn={!currentUserAlreadyConfirmed}
|
|
||||||
showCancelBtn={!cancellationTx}
|
|
||||||
showExecuteBtn={thresholdReached}
|
|
||||||
onTxExecute={openApproveModal}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
</Row>
|
||||||
</Block>
|
</Block>
|
||||||
<CancelTxModal
|
<CancelTxModal
|
||||||
@ -215,7 +153,6 @@ to:
|
|||||||
safeAddress={safeAddress}
|
safeAddress={safeAddress}
|
||||||
threshold={threshold}
|
threshold={threshold}
|
||||||
thresholdReached={thresholdReached}
|
thresholdReached={thresholdReached}
|
||||||
currentUserAlreadyConfirmed={currentUserAlreadyConfirmed}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user