import { useEffect, useRef, useState } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; import { ObjectBrowserView } from '@/components/buckets/ObjectBrowserView'; import { useBucketObjects } from '@/hooks/useBucketObjects'; export function BucketObjects() { const { bucketName = '' } = useParams<{ bucketName: string }>(); const navigate = useNavigate(); const [searchParams, setSearchParams] = useSearchParams(); const [currentPath, setCurrentPath] = useState(searchParams.get('prefix') ?? ''); const [searchQuery, setSearchQuery] = useState(''); const [initialPageToken, setInitialPageToken] = useState( searchParams.get('page') ?? undefined, ); const [initialItemsPerPage, setInitialItemsPerPage] = useState( parseInt(searchParams.get('limit') ?? '25', 10), ); useEffect(() => { const prefix = searchParams.get('prefix') ?? ''; if (prefix !== currentPath) setCurrentPath(prefix); setInitialPageToken(searchParams.get('page') ?? undefined); setInitialItemsPerPage(parseInt(searchParams.get('limit') ?? '25', 10)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchParams]); const { objects, isLoading, isRefreshing, isNavigating, isTruncated, nextContinuationToken, itemsPerPage, setItemsPerPage, uploadFiles, uploadTasks, deleteObject, deleteMultipleObjects, createDirectory, fetchObjects, } = useBucketObjects(bucketName, currentPath); const handleNavigateToFolder = (path: string) => { setCurrentPath(path); const next = new URLSearchParams(); if (path) next.set('prefix', path); setSearchParams(next); }; const handlePageChange = (token?: string) => { fetchObjects(token); const next = new URLSearchParams(); if (currentPath) next.set('prefix', currentPath); if (token) next.set('page', token); if (itemsPerPage !== 25) next.set('limit', String(itemsPerPage)); setSearchParams(next); }; const handleItemsPerPageChange = (count: number) => { setItemsPerPage(count); const next = new URLSearchParams(); if (currentPath) next.set('prefix', currentPath); if (count !== 25) next.set('limit', String(count)); setSearchParams(next); }; const handleRefresh = async () => { await fetchObjects(undefined, true); }; const handleBackToBuckets = () => navigate('/buckets'); // CustomEvent bridge for the Upload button in BucketDetailShell hero. const uploadInputRef = useRef(null); useEffect(() => { const handler = () => uploadInputRef.current?.click(); document.addEventListener('bucket:upload', handler); return () => document.removeEventListener('bucket:upload', handler); }, []); return ( <> { const files = Array.from(e.target.files ?? []); if (files.length > 0) await uploadFiles(files); e.target.value = ''; }} /> ); }