-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: operations refactoring (#2772)
- Loading branch information
Showing
49 changed files
with
1,286 additions
and
474 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './ui'; | ||
export { operationsModel } from './model/operations-model'; | ||
export { operationsUtils } from './lib/operationsUtils'; | ||
export * as operationDetailsUtils from './lib/operationDetailsUtils'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/renderer/entities/operations/ui/OperationTitleDate.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { useStoreMap } from 'effector-react'; | ||
|
||
import { type MultisigTransaction } from '@/shared/core'; | ||
import { useI18n } from '@/shared/i18n'; | ||
import { FootnoteText } from '@/shared/ui'; | ||
import { operationsModel } from '../model/operations-model'; | ||
|
||
type Props = { | ||
operation: MultisigTransaction; | ||
}; | ||
|
||
export const OperationTitleDate = ({ operation }: Props) => { | ||
const { formatDate } = useI18n(); | ||
|
||
const events = useStoreMap({ | ||
store: operationsModel.$multisigEvents, | ||
keys: [operation], | ||
fn: (events, [operation]) => { | ||
return events.filter( | ||
(e) => | ||
e.txAccountId === operation.accountId && | ||
e.txChainId === operation.chainId && | ||
e.txCallHash === operation.callHash && | ||
e.txBlock === operation.blockCreated && | ||
e.txIndex === operation.indexCreated, | ||
); | ||
}, | ||
}); | ||
const approvals = events.filter((e) => e.status === 'SIGNED'); | ||
const initEvent = approvals.find((e) => e.accountId === operation.depositor); | ||
const date = new Date(operation.dateCreated || initEvent?.dateCreated || Date.now()); | ||
|
||
return ( | ||
<div className="w-[58px] pr-1"> | ||
<FootnoteText className="text-text-tertiary" align="right"> | ||
{formatDate(date, 'p')} | ||
</FootnoteText> | ||
</div> | ||
); | ||
}; |
38 changes: 38 additions & 0 deletions
38
src/renderer/entities/operations/ui/OperationTitleStatus.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { useStoreMap, useUnit } from 'effector-react'; | ||
|
||
import { type MultisigTransaction } from '@/shared/core'; | ||
import { accountUtils, walletModel } from '@/entities/wallet'; | ||
import { operationsModel } from '../model/operations-model'; | ||
|
||
import { Status } from './Status'; | ||
|
||
type Props = { | ||
operation: MultisigTransaction; | ||
}; | ||
|
||
export const OperationTitleStatus = ({ operation }: Props) => { | ||
const events = useStoreMap({ | ||
store: operationsModel.$multisigEvents, | ||
keys: [operation], | ||
fn: (events, [operation]) => { | ||
return events.filter( | ||
(e) => | ||
e.txAccountId === operation.accountId && | ||
e.txChainId === operation.chainId && | ||
e.txCallHash === operation.callHash && | ||
e.txBlock === operation.blockCreated && | ||
e.txIndex === operation.indexCreated, | ||
); | ||
}, | ||
}); | ||
|
||
const approvals = events.filter((e) => e.status === 'SIGNED'); | ||
const activeWallet = useUnit(walletModel.$activeWallet); | ||
const account = activeWallet?.accounts.find(accountUtils.isMultisigAccount); | ||
|
||
return ( | ||
<div className="flex w-[120px] justify-end"> | ||
<Status status={operation.status} signed={approvals.length} threshold={account?.threshold || 0} /> | ||
</div> | ||
); | ||
}; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
export { SignatorySelector } from './SignatorySelector'; | ||
export { SignButton } from './SignButton'; | ||
export { Status } from './Status'; | ||
export { OperationTitleStatus } from './OperationTitleStatus'; | ||
export { OperationTitleDate } from './OperationTitleDate'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
src/renderer/features/governance-operation-details/components/GovernanceDelegateDetails.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import { useUnit } from 'effector-react'; | ||
import { useEffect, useState } from 'react'; | ||
|
||
import { type Address, type MultisigTransaction, TransactionType } from '@/shared/core'; | ||
import { useI18n } from '@/shared/i18n'; | ||
import { toAccountId } from '@/shared/lib/utils'; | ||
import { DetailRow, FootnoteText } from '@/shared/ui'; | ||
import { Account } from '@/shared/ui-entities'; | ||
import { Skeleton } from '@/shared/ui-kit'; | ||
import { AssetBalance } from '@/entities/asset'; | ||
import { TracksDetails } from '@/entities/governance'; | ||
import { getTransactionFromMultisigTx } from '@/entities/multisig'; | ||
import { networkModel } from '@/entities/network'; | ||
import { operationDetailsUtils } from '@/entities/operations'; | ||
import { isUndelegateTransaction } from '@/entities/transaction'; | ||
|
||
type Props = { operation: MultisigTransaction }; | ||
|
||
export const GovernanceDelegateDetails = ({ operation }: Props) => { | ||
const { t } = useI18n(); | ||
const transaction = getTransactionFromMultisigTx(operation); | ||
|
||
const chains = useUnit(networkModel.$chains); | ||
const apis = useUnit(networkModel.$apis); | ||
|
||
const chain = chains[operation.chainId]; | ||
const api = apis[operation.chainId]; | ||
|
||
const defaultAsset = chain?.assets[0]; | ||
|
||
const [isUndelegationLoading, setIsUndelegationLoading] = useState(false); | ||
const [undelegationVotes, setUndelegationVotes] = useState<string>(); | ||
const [undelegationTarget, setUndelegationTarget] = useState<Address>(); | ||
|
||
const result = []; | ||
|
||
useEffect(() => { | ||
if (isUndelegateTransaction(transaction)) { | ||
setIsUndelegationLoading(true); | ||
} | ||
|
||
if (!api) return; | ||
|
||
operationDetailsUtils.getUndelegationData(api, operation).then(({ votes, target }) => { | ||
setUndelegationVotes(votes); | ||
setUndelegationTarget(target); | ||
setIsUndelegationLoading(false); | ||
}); | ||
}, [api, operation]); | ||
|
||
if ( | ||
transaction?.type && | ||
![TransactionType.DELEGATE, TransactionType.UNDELEGATE, TransactionType.EDIT_DELEGATION].includes(transaction.type) | ||
) { | ||
return null; | ||
} | ||
|
||
// TODO: Move this to domain layer | ||
const delegationTarget = operationDetailsUtils.getDelegationTarget(operation); | ||
const delegationTracks = operationDetailsUtils.getDelegationTracks(operation); | ||
const delegationVotes = operationDetailsUtils.getDelegationVotes(operation); | ||
|
||
if (isUndelegationLoading) { | ||
result.push( | ||
<> | ||
<DetailRow label={t('operation.details.delegationTarget')}> | ||
<Skeleton width={40} height={6} /> | ||
</DetailRow> | ||
|
||
<DetailRow label={t('operation.details.delegationVotes')}> | ||
<Skeleton width={20} height={5} /> | ||
</DetailRow> | ||
</>, | ||
); | ||
} | ||
|
||
if (delegationTarget) { | ||
result.push( | ||
<DetailRow label={t('operation.details.delegationTarget')} className="text-text-secondary"> | ||
<Account accountId={toAccountId(delegationTarget)} variant="short" chain={chain} /> | ||
</DetailRow>, | ||
); | ||
} | ||
|
||
if (!delegationTarget && undelegationTarget) { | ||
result.push( | ||
<DetailRow label={t('operation.details.delegationTarget')} className="text-text-secondary"> | ||
<Account accountId={toAccountId(undelegationTarget)} variant="short" chain={chain} /> | ||
</DetailRow>, | ||
); | ||
} | ||
|
||
if (delegationVotes) { | ||
result.push( | ||
<DetailRow label={t('operation.details.delegationVotes')} className="text-text-secondary"> | ||
<FootnoteText> | ||
<AssetBalance | ||
className="text-text-secondary" | ||
value={delegationVotes} | ||
asset={defaultAsset} | ||
showSymbol={false} | ||
/> | ||
</FootnoteText> | ||
</DetailRow>, | ||
); | ||
} | ||
|
||
if (!delegationVotes && undelegationVotes) { | ||
result.push( | ||
<DetailRow label={t('operation.details.delegationVotes')} className="text-text-secondary"> | ||
<FootnoteText> | ||
<AssetBalance | ||
className="text-text-secondary" | ||
value={undelegationVotes} | ||
asset={defaultAsset} | ||
showSymbol={false} | ||
/> | ||
</FootnoteText> | ||
</DetailRow>, | ||
); | ||
} | ||
|
||
if (delegationTracks) { | ||
result.push( | ||
<DetailRow label={t('operation.details.delegationTracks')} className="text-text-secondary"> | ||
<div className="-mr-2"> | ||
<TracksDetails tracks={delegationTracks.map(Number)} /> | ||
</div> | ||
</DetailRow>, | ||
); | ||
} | ||
|
||
return <>{result.map((e) => e)}</>; | ||
}; |
32 changes: 32 additions & 0 deletions
32
src/renderer/features/governance-operation-details/components/GovernanceOperationTitle.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { chainsService } from '@/shared/api/network'; | ||
import { type MultisigTransaction } from '@/shared/core'; | ||
import { getAssetById } from '@/shared/lib/utils'; | ||
import { Box } from '@/shared/ui-kit'; | ||
import { AssetBalance } from '@/entities/asset'; | ||
import { ChainTitle } from '@/entities/chain'; | ||
import { TransactionTitle, getTransactionAmount } from '@/entities/transaction'; | ||
|
||
type Props = { | ||
operation: MultisigTransaction; | ||
}; | ||
|
||
export const GovernanceOperationTitle = ({ operation }: Props) => { | ||
const asset = | ||
operation.transaction && | ||
getAssetById(operation.transaction.args.asset, chainsService.getChainById(operation.chainId)?.assets); | ||
const amount = operation.transaction && getTransactionAmount(operation.transaction); | ||
|
||
return ( | ||
<> | ||
<TransactionTitle className="flex-1 overflow-hidden" tx={operation.transaction} /> | ||
|
||
{asset && amount && ( | ||
<Box width="160px"> | ||
<AssetBalance value={amount} asset={asset} showIcon /> | ||
</Box> | ||
)} | ||
|
||
<ChainTitle chainId={operation.chainId} className="w-[114px]" /> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.