import { useDebounce } from '@uidotdev/usehooks' import { useParams } from 'common' import { ArrowDownNarrowWide, RefreshCw, Search } from 'lucide-react' import { parseAsBoolean, useQueryState } from 'nuqs' import { useCallback, useMemo, useRef, useState } from 'react' import { Button, Card, DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, } from 'ui' import { Admonition } from 'ui-patterns' import { Input } from 'ui-patterns/DataInputs/Input' import { PageContainer } from 'ui-patterns/PageContainer' import { PageSection, PageSectionContent } from 'ui-patterns/PageSection' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { CreateBucketModal } from '../CreateBucketModal' import { EmptyBucketState } from '../EmptyBucketState' import { CreateBucketButton } from '../NewBucketButton' import { STORAGE_BUCKET_SORT } from '../Storage.constants' import { useStoragePreference } from '../StorageExplorer/useStoragePreference' import { BucketsTable } from './BucketsTable' import { useFilesBucketsShortcuts } from './useFilesBucketsShortcuts' import AlertError from '@/components/ui/AlertError' import { InlineLink } from '@/components/ui/InlineLink' import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip' import { useProjectStorageConfigQuery } from '@/data/config/project-storage-config-query' import { usePaginatedBucketsQuery } from '@/data/storage/buckets-query' import { IS_PLATFORM } from '@/lib/constants' import { formatBytes } from '@/lib/helpers' import { SHORTCUT_IDS } from '@/state/shortcuts/registry' import { useStorageExplorerStateSnapshot } from '@/state/storage-explorer' export const FilesBuckets = () => { const { ref } = useParams() const snap = useStorageExplorerStateSnapshot() const { sortBucket, setSortBucket } = useStoragePreference(snap.projectRef) const searchInputRef = useRef(null) const [filterString, setFilterString] = useState('') const debouncedFilterString = useDebounce(filterString, 250) const normalizedSearch = debouncedFilterString.trim() const sortColumn = sortBucket === STORAGE_BUCKET_SORT.ALPHABETICAL ? 'name' : 'created_at' const sortOrder = sortBucket === STORAGE_BUCKET_SORT.ALPHABETICAL ? 'asc' : 'desc' const [visible, setVisible] = useQueryState( 'new', parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true }) ) const { data } = useProjectStorageConfigQuery({ projectRef: ref }, { enabled: IS_PLATFORM }) const { data: bucketsData, error: bucketsError, isError: isErrorBuckets, isPending: isLoadingBuckets, isSuccess: isSuccessBuckets, isFetching: isFetchingBuckets, fetchNextPage, hasNextPage, refetch: refetchBuckets, } = usePaginatedBucketsQuery({ projectRef: ref, search: normalizedSearch.length > 0 ? normalizedSearch : undefined, sortColumn, sortOrder, }) const buckets = useMemo(() => bucketsData?.pages.flatMap((page) => page) ?? [], [bucketsData]) const fileBuckets = buckets.filter((bucket) => !('type' in bucket) || bucket.type === 'STANDARD') const hasNoBuckets = fileBuckets.length === 0 && normalizedSearch.length === 0 const formattedGlobalUploadLimit = formatBytes(data?.fileSizeLimit ?? 0) const hasNoApiKeys = isErrorBuckets && bucketsError.message.includes('Project has no active API keys') const handleLoadMoreBuckets = useCallback(() => { if (hasNextPage && !isFetchingBuckets) { fetchNextPage() } }, [hasNextPage, isFetchingBuckets, fetchNextPage]) const handleRefresh = useCallback(() => { refetchBuckets() }, [refetchBuckets]) useFilesBucketsShortcuts({ searchInputRef, setFilterString, sortBucket, setSortBucket, setCreateVisible: setVisible, onRefresh: handleRefresh, }) return ( <> {isLoadingBuckets && } {isErrorBuckets && ( <> {hasNoApiKeys ? (

The Dashboard relies on having active API keys on the project to function. If you'd like to use Storage through the Dashboard, create a set of API keys{' '} here.

) : ( )} )} {isSuccessBuckets && ( <> {hasNoBuckets ? ( setVisible(true)} /> ) : ( <>
setFilterString(e.target.value)} icon={} /> setSortBucket(value as STORAGE_BUCKET_SORT)} > Sort by name Sort by created at
setVisible(true)} />
)} )}
) }