@@ -15,12 +15,12 @@ import { BucketNewForm } from "@/components/buckets/new-form"
1515import { Spinner } from "@/components/ui/spinner"
1616import { useBucket } from "@/hooks/use-bucket"
1717import { useObject } from "@/hooks/use-object"
18- import { useSystem } from "@/hooks/use-system"
1918import { usePermissions } from "@/hooks/use-permissions"
2019import { useDialog } from "@/lib/feedback/dialog"
2120import { useMessage } from "@/lib/feedback/message"
2221import { formatDateTime , formatInteger , niceBytes } from "@/lib/functions"
2322import { normalizeDateToIso } from "@/lib/safe-date"
23+ import { getAccountBucketUsage } from "@/lib/account-bucket-usage"
2424import { BrowserContent } from "./content"
2525import type { ColumnDef } from "@tanstack/react-table"
2626
@@ -33,70 +33,23 @@ interface BucketRow {
3333 IsPublic ?: boolean
3434}
3535
36- type BucketUsageMap = Record < string , { objects_count ?: number ; size ?: number } | undefined >
37-
3836function BrowserBucketsPage ( ) {
3937 const { t } = useTranslation ( )
4038 const router = useRouter ( )
4139 const message = useMessage ( )
4240 const dialog = useDialog ( )
43- const { canCapability } = usePermissions ( )
41+ const { canCapability, userInfo , isLoading : accountInfoLoading , hasFetchedPolicy , fetchUserPolicy } = usePermissions ( )
4442 const { listBuckets, deleteBucket, getBucketPolicyStatus } = useBucket ( )
45- const { getDataUsageInfo } = useSystem ( )
4643
4744 const [ formVisible , setFormVisible ] = useState ( false )
4845 const [ searchTerm , setSearchTerm ] = useState ( "" )
4946 const [ data , setData ] = useState < BucketRow [ ] > ( [ ] )
5047 const [ pending , setPending ] = useState ( true )
51- const [ usageLoading , setUsageLoading ] = useState ( false )
5248 const [ policyLoading , setPolicyLoading ] = useState ( false )
5349 const fetchIdRef = useRef ( 0 )
5450
5551 const canCreateBucket = canCapability ( "bucket.create" )
5652
57- const loadBucketUsage = useCallback (
58- async ( fetchId : number , bucketNames : string [ ] ) => {
59- if ( bucketNames . length === 0 ) {
60- setUsageLoading ( false )
61- return
62- }
63-
64- try {
65- const usage = ( await getDataUsageInfo ( ) ) as { buckets_usage ?: BucketUsageMap } | undefined
66- if ( fetchId !== fetchIdRef . current ) return
67-
68- // getDataUsageInfo returns undefined on 403; don't update data so table shows "--"
69- if ( ! usage ) {
70- return
71- }
72-
73- const bucketUsage = usage ?. buckets_usage ?? { }
74-
75- setData ( ( prev ) =>
76- prev . map ( ( row ) => {
77- const stats = bucketUsage [ row . Name ]
78- const objectsCount = typeof stats ?. objects_count === "number" ? stats . objects_count : 0
79- const totalSize = typeof stats ?. size === "number" ? stats . size : 0
80- return {
81- ...row ,
82- Count : objectsCount ,
83- Size : niceBytes ( String ( totalSize ) ) ,
84- SizeBytes : totalSize ,
85- }
86- } ) ,
87- )
88- } catch {
89- if ( fetchId !== fetchIdRef . current ) return
90- // On error, don't update the data - keep showing "--"
91- } finally {
92- if ( fetchId === fetchIdRef . current ) {
93- setUsageLoading ( false )
94- }
95- }
96- } ,
97- [ getDataUsageInfo ] ,
98- )
99-
10053 const loadPolicyStatus = useCallback (
10154 async ( fetchId : number , bucketNames : string [ ] ) => {
10255 if ( bucketNames . length === 0 ) {
@@ -165,11 +118,9 @@ function BrowserBucketsPage() {
165118 setData ( buckets )
166119 setPending ( false )
167120
168- setUsageLoading ( true )
169- void loadBucketUsage (
170- fetchId ,
171- buckets . map ( ( bucket ) => bucket . Name ) ,
172- )
121+ if ( options ?. force ) {
122+ void fetchUserPolicy ( )
123+ }
173124
174125 setPolicyLoading ( true )
175126 void loadPolicyStatus (
@@ -186,16 +137,36 @@ function BrowserBucketsPage() {
186137 }
187138 }
188139 } ,
189- [ listBuckets , loadBucketUsage , loadPolicyStatus ] ,
140+ [ fetchUserPolicy , listBuckets , loadPolicyStatus ] ,
190141 )
191142
192143 useEffect ( ( ) => {
193144 fetchBuckets ( )
194145 } , [ fetchBuckets ] )
195146
147+ const usageLoading = accountInfoLoading || ! hasFetchedPolicy
148+ const bucketUsage = useMemo ( ( ) => getAccountBucketUsage ( userInfo ) , [ userInfo ] )
149+ const rowsWithUsage = useMemo (
150+ ( ) =>
151+ data . map ( ( row ) => {
152+ const usage = bucketUsage . get ( row . Name )
153+ if ( ! usage ) return row
154+
155+ return {
156+ ...row ,
157+ Count : usage . objectsCount ,
158+ Size : niceBytes ( String ( usage . sizeBytes ) ) ,
159+ SizeBytes : usage . sizeBytes ,
160+ }
161+ } ) ,
162+ [ bucketUsage , data ] ,
163+ )
196164 const filteredData = useMemo (
197- ( ) => ( searchTerm ? data . filter ( ( bucket ) => bucket . Name . toLowerCase ( ) . includes ( searchTerm . toLowerCase ( ) ) ) : data ) ,
198- [ data , searchTerm ] ,
165+ ( ) =>
166+ searchTerm
167+ ? rowsWithUsage . filter ( ( bucket ) => bucket . Name . toLowerCase ( ) . includes ( searchTerm . toLowerCase ( ) ) )
168+ : rowsWithUsage ,
169+ [ rowsWithUsage , searchTerm ] ,
199170 )
200171
201172 const objectApi = useObject ( "" )
0 commit comments