BucketsTable.tsx124 lines · main
1import { useRef } from 'react'
2import { Table, TableBody } from 'ui'
3
4import { LoadMoreRow } from './BucketsTable.LoadMoreRow'
5import { BucketTableHeader } from './BucketTableHeader'
6import { BucketTableEmptyState, BucketTableRow } from './BucketTableRow'
7import type { AllowedBucketType, BucketsTablePaginationProps } from './types'
8import { VirtualizedTable, VirtualizedTableBody } from '@/components/ui/VirtualizedTable'
9import { type Bucket } from '@/data/storage/buckets-query'
10
11type BucketsTableProps = {
12 buckets: Bucket[]
13 projectRef: string
14 filterString: string
15 formattedGlobalUploadLimit: string
16 onSelectBucket: (bucket: Bucket) => void
17 allowedBucketType: AllowedBucketType
18 pagination: BucketsTablePaginationProps
19}
20
21export const BucketsTable = (props: BucketsTableProps) => {
22 const isVirtualized = props.buckets.length > 50
23 return isVirtualized ? (
24 <BucketsTableVirtualized {...props} />
25 ) : (
26 <BucketsTableUnvirtualized {...props} />
27 )
28}
29
30const BucketsTableUnvirtualized = ({
31 buckets,
32 filterString,
33 formattedGlobalUploadLimit,
34 onSelectBucket,
35 allowedBucketType,
36 pagination: { hasMore = false, isLoadingMore = false, onLoadMore },
37}: BucketsTableProps) => {
38 const showSearchEmptyState = buckets.length === 0 && filterString.length > 0
39
40 return (
41 <Table
42 containerProps={{
43 containerClassName: 'h-full overflow-auto',
44 className: 'overflow-visible',
45 }}
46 >
47 <BucketTableHeader mode="standard" hasBuckets={buckets.length > 0} />
48 <TableBody>
49 {showSearchEmptyState ? (
50 <BucketTableEmptyState mode="standard" filterString={filterString} />
51 ) : (
52 buckets.map((bucket) => (
53 <BucketTableRow
54 mode="standard"
55 key={bucket.id}
56 bucket={bucket}
57 onSelectBucket={onSelectBucket}
58 allowedBucketType={allowedBucketType}
59 formattedGlobalUploadLimit={formattedGlobalUploadLimit}
60 />
61 ))
62 )}
63 <LoadMoreRow
64 mode="standard"
65 colSpan={6}
66 hasMore={hasMore}
67 isLoadingMore={isLoadingMore}
68 onLoadMore={onLoadMore}
69 />
70 </TableBody>
71 </Table>
72 )
73}
74
75const BucketsTableVirtualized = ({
76 buckets,
77 filterString,
78 formattedGlobalUploadLimit,
79 onSelectBucket,
80 allowedBucketType,
81 pagination: { hasMore = false, isLoadingMore = false, onLoadMore },
82}: BucketsTableProps) => {
83 const showSearchEmptyState = buckets.length === 0 && filterString.length > 0
84 const scrollContainerRef = useRef<HTMLDivElement>(null)
85
86 return (
87 <VirtualizedTable
88 data={buckets}
89 estimateSize={() => 59}
90 getItemKey={(bucket) => bucket.id}
91 scrollContainerRef={scrollContainerRef}
92 >
93 <BucketTableHeader mode="virtualized" hasBuckets={buckets.length > 0} />
94 <VirtualizedTableBody<Bucket>
95 paddingColSpan={5}
96 emptyContent={
97 showSearchEmptyState ? (
98 <BucketTableEmptyState mode="virtualized" filterString={filterString} />
99 ) : undefined
100 }
101 trailingContent={
102 <LoadMoreRow
103 mode="virtualized"
104 colSpan={6}
105 hasMore={hasMore}
106 isLoadingMore={isLoadingMore}
107 onLoadMore={onLoadMore}
108 />
109 }
110 >
111 {(bucket) => (
112 <BucketTableRow
113 mode="virtualized"
114 key={bucket.id}
115 bucket={bucket}
116 onSelectBucket={onSelectBucket}
117 allowedBucketType={allowedBucketType}
118 formattedGlobalUploadLimit={formattedGlobalUploadLimit}
119 />
120 )}
121 </VirtualizedTableBody>
122 </VirtualizedTable>
123 )
124}