diff --git a/packages/app/src/systems/Transaction/components/TxOperations/TxOperations.tsx b/packages/app/src/systems/Transaction/components/TxOperations/TxOperations.tsx index 0e8d25383..28200e7d6 100644 --- a/packages/app/src/systems/Transaction/components/TxOperations/TxOperations.tsx +++ b/packages/app/src/systems/Transaction/components/TxOperations/TxOperations.tsx @@ -28,7 +28,7 @@ export function TxOperations({ } return ( - + {operations?.map((operation, index) => ( @@ -43,7 +43,7 @@ export function TxOperations({ } TxOperations.Loader = () => ( - + ); diff --git a/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsGroup.tsx b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsGroup.tsx new file mode 100644 index 000000000..f37c54422 --- /dev/null +++ b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsGroup.tsx @@ -0,0 +1,90 @@ +import { cssObj } from '@fuel-ui/css'; +import { Box, Icon, Text } from '@fuel-ui/react'; +import { useState } from 'react'; +import type { SimplifiedOperation } from '../../../types'; +import { TxOperation } from './operations/TxOperation'; + +type TxOperationsGroupProps = { + title: string; + operations: SimplifiedOperation[]; + showNesting?: boolean; +}; + +export function TxOperationsGroup({ + title, + operations, + showNesting, +}: TxOperationsGroupProps) { + const [isExpanded, setIsExpanded] = useState(false); + + if (!operations.length) return null; + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsExpanded(!isExpanded); + }; + + return ( + + + + + {title} ({operations.length}) + + + {isExpanded && ( + e.stopPropagation()} + > + {operations.map((operation, index) => ( + + ))} + + )} + + ); +} + +const styles = { + root: cssObj({ + borderTop: '1px solid $border', + marginTop: '$2', + paddingTop: '$2', + }), + header: cssObj({ + display: 'flex', + alignItems: 'center', + gap: '$2', + padding: '$2', + cursor: 'pointer', + backgroundColor: 'transparent', + border: 'none', + width: '100%', + borderRadius: '$md', + transition: 'all 0.2s ease', + '&:hover': { + backgroundColor: '$gray3', + }, + }), + icon: cssObj({ + color: '$gray8', + }), + title: cssObj({ + color: '$gray8', + fontWeight: '$medium', + }), + content: cssObj({ + paddingLeft: '$6', + }), +}; diff --git a/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsList.tsx b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsList.tsx index 7ba885b06..440c82ce8 100644 --- a/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsList.tsx +++ b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/TxOperationsList.tsx @@ -1,22 +1,86 @@ import { Box } from '@fuel-ui/react'; import { useMemo } from 'react'; import type { SimplifiedOperation } from '../../../types'; +import { TxCategory } from '../../../types'; +import { TxOperationsGroup } from './TxOperationsGroup'; import { TxOperation } from './operations/TxOperation'; type TxOperationsListProps = { operations: SimplifiedOperation[]; + currentAccount?: string; }; -export function TxOperationsList({ operations }: TxOperationsListProps) { - const renderedOperations = useMemo(() => { - return operations.map((operation, index) => { - console.log('Rendering operation:', operation); - const key = `${operation.type}-${operation.from}-${operation.to}-${index}`; - return ; - }); - }, [operations]); +export function TxOperationsList({ + operations, + currentAccount, +}: TxOperationsListProps) { + const { mainOperations, otherRootOperations, intermediateOperations } = + useMemo(() => { + const main: SimplifiedOperation[] = []; + const otherRoot: SimplifiedOperation[] = []; + const intermediate: SimplifiedOperation[] = []; - return {renderedOperations}; + for (const op of operations) { + const depth = op.metadata?.depth || 0; + const isTransfer = op.type === TxCategory.SEND; + const isFromCurrentAccount = + currentAccount && op.from === currentAccount; + const isToCurrentAccount = currentAccount && op.to === currentAccount; + + // All transfers go to main list + if (isTransfer) { + main.push(op); + continue; + } + + // Contract calls at root level (depth 0) + if (depth === 0) { + // If related to current account, show in main list + if (isFromCurrentAccount || isToCurrentAccount) { + main.push(op); + } else { + otherRoot.push(op); + } + continue; + } + + // All other operations (intermediate contract calls) + intermediate.push(op); + } + + return { + mainOperations: main, + otherRootOperations: otherRoot, + intermediateOperations: intermediate, + }; + }, [operations, currentAccount]); + + return ( + + {/* Main operations (transfers and root contract calls related to current account) */} + {mainOperations.map((operation, index) => ( + + ))} + + {/* Other root operations not related to current account */} + + + {/* Intermediate operations with nesting */} + + + ); } TxOperationsList.Loader = function TxOperationsListLoader() { diff --git a/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/operations/TxAddressDisplay.tsx b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/operations/TxAddressDisplay.tsx index 8180c466b..d63218716 100644 --- a/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/operations/TxAddressDisplay.tsx +++ b/packages/app/src/systems/Transaction/components/TxViewSimple/TxOperationsSimple/operations/TxAddressDisplay.tsx @@ -16,7 +16,6 @@ export function TxAddressDisplay({ name, image, isContract, - label, }: TxAddressDisplayProps) { const { accounts } = useAccounts(); const account = accounts?.find( @@ -27,19 +26,19 @@ export function TxAddressDisplay({ {image ? ( - + ) : ( - + )} - {label && ( - - {label}: - - )} - {account?.name || name || shortAddress(address)} + {account?.name || 'Unknown'} {isContract && ( @@ -48,6 +47,9 @@ export function TxAddressDisplay({ )} + + {shortAddress(address)} + - + {isContract && showNesting && } @@ -38,19 +48,17 @@ export function TxOperation({ operation }: TxOperationProps) { )} - - + + {isTransfer && ( + + )} + {hasAsset && amount && assetId && ( - {!isContract && } )} @@ -61,23 +69,23 @@ export function TxOperation({ operation }: TxOperationProps) { ); } -// root level rule is only for contract calls, all transfers should show as well // we also have the operations not related to the account in a group, and intermediate contract calls const styles = { root: cssObj({ - display: 'flex', - alignItems: 'flex-start', - gap: '$2', - padding: '$3', - backgroundColor: '$cardBg', - borderRadius: '$md', + padding: '$1', + backgroundColor: '#E0E0E0', + borderRadius: '12px', width: '100%', - minWidth: 0, + boxSizing: 'border-box', }), contentCol: cssObj({ display: 'flex', + backgroundColor: 'white', + boxShadow: '0px 2px 6px -1px #2020201A, 0px 0px 0px 1px #2020201F', flex: 1, + borderRadius: '8px', minWidth: 0, + padding: '$3', }), header: cssObj({ display: 'flex', @@ -99,9 +107,7 @@ const styles = { fontWeight: '$normal', }), arrow: cssObj({ - color: '$gray8', - marginTop: '$1', - marginLeft: '$2', + color: '#0D74CE', }), functionName: cssObj({ fontSize: '$sm',