Skip to content

Commit 1fb741a

Browse files
authored
feat: collapsible transaction table (#80)
1 parent e4c404c commit 1fb741a

File tree

11 files changed

+62
-19
lines changed

11 files changed

+62
-19
lines changed

src/assets/icons/chevron-down.svg

Lines changed: 3 additions & 0 deletions
Loading

src/features/blocks/components/block-details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function BlockDetails({ block }: Props) {
7373
<Card className={cn('p-4')}>
7474
<CardContent className={cn('text-sm space-y-2')}>
7575
<h1 className={cn('text-2xl text-primary font-bold')}>{transactionsLabel}</h1>
76-
<TransactionsTable transactions={block.transactions} columns={transactionsTableColumnsWithoutRound} />
76+
<TransactionsTable transactions={block.transactions} columns={transactionsTableColumnsWithoutRound} subRowsExpanded={false} />
7777
</CardContent>
7878
</Card>
7979
</div>

src/features/common/components/data-table.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
1-
import { ColumnDef, flexRender, getCoreRowModel, useReactTable, getPaginationRowModel, getExpandedRowModel } from '@tanstack/react-table'
1+
import {
2+
ColumnDef,
3+
flexRender,
4+
getCoreRowModel,
5+
useReactTable,
6+
getPaginationRowModel,
7+
getExpandedRowModel,
8+
ExpandedState,
9+
} from '@tanstack/react-table'
210
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/features/common/components/table'
311
import { DataTablePagination } from './data-table-pagination'
12+
import { useEffect, useState } from 'react'
413

514
interface DataTableProps<TData, TValue> {
615
columns: ColumnDef<TData, TValue>[]
716
data: TData[]
817
getSubRows?: (row: TData) => TData[]
18+
subRowsExpanded?: boolean
919
}
1020

11-
export function DataTable<TData, TValue>({ columns, data, getSubRows }: DataTableProps<TData, TValue>) {
21+
export function DataTable<TData, TValue>({ columns, data, getSubRows, subRowsExpanded }: DataTableProps<TData, TValue>) {
22+
const [expanded, setExpanded] = useState<ExpandedState>({})
1223
const table = useReactTable({
1324
data,
1425
paginateExpandedRows: false,
1526
state: {
16-
expanded: true,
27+
expanded: expanded,
1728
},
29+
onExpandedChange: setExpanded,
1830
getSubRows: getSubRows,
1931
columns,
2032
getCoreRowModel: getCoreRowModel(),
2133
getExpandedRowModel: getExpandedRowModel(),
2234
getPaginationRowModel: getPaginationRowModel(),
2335
})
2436

37+
useEffect(() => {
38+
table.toggleAllRowsExpanded(subRowsExpanded ?? false)
39+
}, [subRowsExpanded, table])
40+
2541
return (
2642
<div>
2743
<div className="grid rounded-md border">
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { SVGProps } from 'react'
2+
const SvgChevronDown = (props: SVGProps<SVGSVGElement>) => (
3+
<svg width="1em" height="1em" viewBox="4 4 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
4+
<path d="M6 9L12 15L18 9" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />
5+
</svg>
6+
)
7+
export default SvgChevronDown

src/features/common/components/lazy-load-data-table/lazy-load-data-table.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { ColumnDef, flexRender, getCoreRowModel, getExpandedRowModel, useReactTable } from '@tanstack/react-table'
1+
import { ColumnDef, ExpandedState, flexRender, getCoreRowModel, getExpandedRowModel, useReactTable } from '@tanstack/react-table'
22
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/features/common/components/table'
3-
import { useCallback, useMemo, useState } from 'react'
3+
import { useCallback, useEffect, useMemo, useState } from 'react'
44
import { LazyLoadDataTablePagination } from './lazy-load-data-table-pagination'
55
import { Loader2 as Loader } from 'lucide-react'
66
import { Loadable } from 'jotai/vanilla/utils/loadable'
@@ -10,14 +10,15 @@ interface Props<TData, TValue> {
1010
columns: ColumnDef<TData, TValue>[]
1111
createLoadablePage: (pageSize: number) => (pageNumber: number) => Loadable<Promise<ViewModelPage<TData>>>
1212
getSubRows?: (row: TData) => TData[]
13+
subRowsExpanded?: boolean
1314
}
1415

15-
export function LazyLoadDataTable<TData, TValue>({ columns, createLoadablePage, getSubRows }: Props<TData, TValue>) {
16+
export function LazyLoadDataTable<TData, TValue>({ columns, createLoadablePage, getSubRows, subRowsExpanded }: Props<TData, TValue>) {
1617
const [pageSize, setPageSize] = useState(10)
1718
const useLoadablePage = useMemo(() => createLoadablePage(pageSize), [createLoadablePage, pageSize])
1819
const [currentPage, setCurrentPage] = useState<number>(1)
1920
const loadablePage = useLoadablePage(currentPage)
20-
21+
const [expanded, setExpanded] = useState<ExpandedState>({})
2122
const nextPage = useCallback(() => {
2223
setCurrentPage((prev) => prev + 1)
2324
}, [])
@@ -36,15 +37,20 @@ export function LazyLoadDataTable<TData, TValue>({ columns, createLoadablePage,
3637
const table = useReactTable({
3738
data: page?.items ?? [],
3839
state: {
39-
expanded: true,
40+
expanded: expanded,
4041
},
42+
onExpandedChange: setExpanded,
4143
getSubRows: getSubRows,
4244
columns,
4345
getCoreRowModel: getCoreRowModel(),
4446
getExpandedRowModel: getExpandedRowModel(),
4547
manualPagination: true,
4648
})
4749

50+
useEffect(() => {
51+
table.toggleAllRowsExpanded(subRowsExpanded ?? false)
52+
}, [subRowsExpanded, table])
53+
4854
return (
4955
<div>
5056
<div className="grid rounded-md border">

src/features/groups/components/group-transactions-view-tabs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function GroupTransactionsViewTabs({ group }: Props) {
3030
<TransactionsGraph transactions={group.transactions} />
3131
</OverflowAutoTabsContent>
3232
<OverflowAutoTabsContent value={tableTabId}>
33-
<TransactionsTable transactions={group.transactions} columns={transactionsTableColumnsWithoutRound} />
33+
<TransactionsTable transactions={group.transactions} columns={transactionsTableColumnsWithoutRound} subRowsExpanded={false} />
3434
</OverflowAutoTabsContent>
3535
</Tabs>
3636
)

src/features/groups/pages/group-page.test.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,6 @@ describe('group-page', () => {
123123
{
124124
cells: ['INDQXWQ...', '/oRSr2u...', 'AACC...EN4A', '1201559522', 'Application Call', ''],
125125
},
126-
{
127-
cells: ['Inner 1', 'aWpPwlo...', 'AACC...EN4A', '2PIF...RNMM', 'Payment', '2.770045'],
128-
},
129126
],
130127
})
131128
}

src/features/transactions/components/live-transactions-table.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { ColumnDef, flexRender, getCoreRowModel, getExpandedRowModel, useReactTable } from '@tanstack/react-table'
1+
import { ColumnDef, ExpandedState, flexRender, getCoreRowModel, getExpandedRowModel, useReactTable } from '@tanstack/react-table'
22
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/features/common/components/table'
33
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../common/components/select'
4-
import { useState } from 'react'
4+
import { useEffect, useState } from 'react'
55
import { InnerTransaction, Transaction } from '@/features/transactions/models'
66
import { TransactionResult } from '@algorandfoundation/algokit-utils/types/indexer'
77
import { useLiveTransactions } from '../data/live-transaction'
@@ -13,6 +13,7 @@ interface Props {
1313
}
1414

1515
export function LiveTransactionsTable({ filter, columns, getSubRows }: Props) {
16+
const [expanded, setExpanded] = useState<ExpandedState>({})
1617
const [maxRows, setMaxRows] = useState(10)
1718
const transactions = useLiveTransactions(filter, maxRows)
1819

@@ -24,10 +25,15 @@ export function LiveTransactionsTable({ filter, columns, getSubRows }: Props) {
2425
getSubRows: getSubRows,
2526
getExpandedRowModel: getExpandedRowModel(),
2627
state: {
27-
expanded: true,
28+
expanded: expanded,
2829
},
30+
onExpandedChange: setExpanded,
2931
})
3032

33+
useEffect(() => {
34+
table.toggleAllRowsExpanded(true)
35+
}, [table])
36+
3137
return (
3238
<div>
3339
<div className="grid rounded-md border">

src/features/transactions/components/transaction-view-tabs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function TransactionViewTabs({ transaction }: Props) {
3636
<TransactionsGraph transactions={[transaction]} />
3737
</OverflowAutoTabsContent>
3838
<OverflowAutoTabsContent value={transactionVisualTableTabId}>
39-
<TransactionsTable transactions={[transaction]} columns={transactionsTableColumnsWithoutRound} />
39+
<TransactionsTable transactions={[transaction]} columns={transactionsTableColumnsWithoutRound} subRowsExpanded={true} />
4040
</OverflowAutoTabsContent>
4141
</Tabs>
4242
)

src/features/transactions/components/transactions-table-columns.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { asTo } from '@/features/common/mappers/to'
88
import { InnerTransactionLink } from '@/features/transactions/components/inner-transaction-link'
99
import { DisplayAssetAmount } from '@/features/common/components/display-asset-amount'
1010
import { GroupLink } from '@/features/groups/components/group-link'
11+
import SvgChevronDown from '@/features/common/components/icons/chevron-down'
12+
import SvgChevronRight from '@/features/common/components/icons/chevron-right'
1113

1214
const indentationWidth = 20
1315

@@ -28,6 +30,11 @@ export const transactionsTableColumns: ColumnDef<Transaction | InnerTransaction>
2830
marginLeft: `${indentationWidth * row.depth}px`,
2931
}}
3032
>
33+
<div className={cn('inline-block min-w-6')}>
34+
{row.getCanExpand() ? (
35+
<button onClick={row.getToggleExpandedHandler()}>{row.getIsExpanded() ? <SvgChevronDown /> : <SvgChevronRight />}</button>
36+
) : null}
37+
</div>
3138
{'innerId' in transaction ? (
3239
<InnerTransactionLink transactionId={transaction.networkTransactionId} innerTransactionId={transaction.innerId} />
3340
) : (

0 commit comments

Comments
 (0)