StorageSearchResults() — supabase Function Reference
Architecture documentation for the StorageSearchResults() function in StorageSearchResults.tsx from the supabase codebase.
Entity Profile
Dependency Diagram
graph TD 2e5a9f0d_3900_3512_443f_21afb4f3aa24["StorageSearchResults()"] 1b3540b5_43c3_883a_ac7f_95e3ee5e9da6["filterBuckets()"] 2e5a9f0d_3900_3512_443f_21afb4f3aa24 -->|calls| 1b3540b5_43c3_883a_ac7f_95e3ee5e9da6 style 2e5a9f0d_3900_3512_443f_21afb4f3aa24 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
apps/studio/components/interfaces/App/CommandMenu/StorageSearchResults.tsx lines 55–325
export function StorageSearchResults({ query }: StorageSearchResultsProps) {
const { ref: projectRef } = useParams()
const isAnalyticsBucketsEnabled = useIsAnalyticsBucketsEnabled({ projectRef })
const isVectorBucketsEnabled = useIsVectorBucketsEnabled({ projectRef })
// Debounce the search query to avoid excessive API calls
const debouncedQuery = useDebounce(query.trim(), 300)
const {
data: fileBucketsData,
isLoading: isLoadingFileBuckets,
isError: isErrorFileBuckets,
} = usePaginatedBucketsQuery(
{
projectRef: projectRef ?? undefined,
limit: 10,
search: debouncedQuery.length > 0 ? debouncedQuery : undefined,
},
{
enabled: !!projectRef,
}
)
const fileBuckets = useMemo(
() => fileBucketsData?.pages.flatMap((page) => page) ?? [],
[fileBucketsData]
)
const {
data: analyticsBuckets,
isLoading: isLoadingAnalyticsBuckets,
isError: isErrorAnalyticsBuckets,
} = useAnalyticsBucketsQuery(
{
projectRef: projectRef ?? undefined,
},
{
enabled: !!projectRef && isAnalyticsBucketsEnabled,
}
)
const {
data: vectorBucketsData,
isLoading: isLoadingVectorBuckets,
isError: isErrorVectorBuckets,
} = useVectorBucketsQuery(
{
projectRef: projectRef ?? undefined,
},
{
enabled: !!projectRef && isVectorBucketsEnabled,
}
)
const vectorBuckets = useMemo(() => vectorBucketsData?.vectorBuckets ?? [], [vectorBucketsData])
const { data: fileBucketsEstimate } = useBucketNumberEstimateQuery({
projectRef,
})
const isLoading =
isLoadingFileBuckets ||
(isAnalyticsBucketsEnabled && isLoadingAnalyticsBuckets) ||
(isVectorBucketsEnabled && isLoadingVectorBuckets)
const isError =
isErrorFileBuckets ||
(isAnalyticsBucketsEnabled && isErrorAnalyticsBuckets) ||
(isVectorBucketsEnabled && isErrorVectorBuckets)
const fileBucketResults: ExtendedSearchResult[] = useMemo(() => {
// Server-side search is already applied, no need for client-side filtering
if (!fileBuckets) return []
return fileBuckets.map((bucket) => {
const displayName = bucket.name || bucket.id || 'Untitled Bucket'
const visibility = bucket.public ? 'Public' : 'Private'
const description = `File bucket • ${visibility}`
return {
id: `file-bucket-${bucket.id || bucket.name}`,
name: displayName,
description,
bucketType: 'file' as const,
bucket,
}
})
}, [fileBuckets])
const analyticsBucketResults: ExtendedSearchResult[] = useMemo(() => {
return filterBuckets(
analyticsBuckets,
debouncedQuery, // Use debounced query for consistency
(bucket, searchLower) => {
const bucketName = bucket.name?.toLowerCase() || ''
return bucketName.includes(searchLower)
},
(bucket) => {
const displayName = bucket.name || 'Untitled Bucket'
const description = 'Analytics bucket'
return {
id: `analytics-bucket-${bucket.name}`,
name: displayName,
description,
bucketType: 'analytics' as const,
bucket,
}
}
)
}, [analyticsBuckets, debouncedQuery])
const vectorBucketResults: ExtendedSearchResult[] = useMemo(() => {
return filterBuckets(
vectorBuckets,
debouncedQuery, // Use debounced query for consistency
(bucket, searchLower) => {
const bucketName = bucket.vectorBucketName?.toLowerCase() || ''
return bucketName.includes(searchLower)
},
(bucket) => {
const displayName = bucket.vectorBucketName || 'Untitled Bucket'
const description = 'Vector bucket'
return {
id: `vector-bucket-${bucket.vectorBucketName}`,
name: displayName,
description,
bucketType: 'vector' as const,
bucket,
}
}
)
}, [vectorBuckets, debouncedQuery])
const allResults: ExtendedSearchResult[] = useMemo(() => {
const results = [fileBucketResults]
if (isAnalyticsBucketsEnabled) {
results.push(analyticsBucketResults)
}
if (isVectorBucketsEnabled) {
results.push(vectorBucketResults)
}
return results.flat().slice(0, 20)
}, [
fileBucketResults,
analyticsBucketResults,
vectorBucketResults,
isAnalyticsBucketsEnabled,
isVectorBucketsEnabled,
])
const getRoute = useCallback(
(result: SearchResult) => {
if (!projectRef) return '/storage/files' as `/${string}`
const extendedResult = result as ExtendedSearchResult
if (extendedResult.bucketType && extendedResult.bucket) {
const bucketType = extendedResult.bucketType
if (bucketType === 'file') {
const fileBucket = extendedResult.bucket as Bucket
return `/project/${projectRef}/storage/files/buckets/${encodeURIComponent(fileBucket.name)}` as `/${string}`
}
if (bucketType === 'analytics') {
const analyticsBucket = extendedResult.bucket as AnalyticsBucket
return `/project/${projectRef}/storage/analytics/buckets/${encodeURIComponent(analyticsBucket.name)}` as `/${string}`
}
if (bucketType === 'vector') {
const vectorBucket = extendedResult.bucket as { vectorBucketName: string }
return `/project/${projectRef}/storage/vectors/buckets/${encodeURIComponent(vectorBucket.vectorBucketName)}` as `/${string}`
}
}
return `/project/${projectRef}/storage/files` as `/${string}`
},
[projectRef]
)
const totalBucketsEstimate = useMemo(() => {
const fileBucketCount = fileBucketsEstimate ?? 0
const analyticsBucketCount = isAnalyticsBucketsEnabled ? analyticsBuckets?.length ?? 0 : 0
const vectorBucketCount = isVectorBucketsEnabled ? vectorBuckets?.length ?? 0 : 0
return fileBucketCount + analyticsBucketCount + vectorBucketCount
}, [
fileBucketsEstimate,
analyticsBuckets?.length,
vectorBuckets?.length,
isAnalyticsBucketsEnabled,
isVectorBucketsEnabled,
])
const getIcon = useCallback((result: SearchResult) => {
const extendedResult = result as ExtendedSearchResult
if (extendedResult.bucketType === 'file') return FilesBucket
if (extendedResult.bucketType === 'analytics') return AnalyticsBucketIcon
if (extendedResult.bucketType === 'vector') return VectorBucket
return Storage
}, [])
const renderFooter = () => (
<div className="absolute bottom-0 left-0 right-0 flex items-center justify-between min-h-9 h-9 px-4 border-t bg-surface-200 text-xs text-foreground-light z-10">
<div className="flex items-center gap-x-2">
{isLoading ? (
<span className="flex items-center gap-2">
<Loader2 size={14} className="animate-spin" /> Loading...
</span>
) : (
<span>
Total: {totalBucketsEstimate.toLocaleString()} bucket
{totalBucketsEstimate !== 1 ? 's' : ''} (estimate)
</span>
)}
</div>
</div>
)
if (isLoading) {
return (
<div className="relative h-full flex flex-col">
<div className="flex-1 min-h-0 overflow-hidden">
<SkeletonResults />
</div>
{renderFooter()}
</div>
)
}
if (isError) {
return (
<div className="relative h-full flex flex-col">
<div className="flex-1 min-h-0 overflow-hidden">
<div className="h-full flex flex-col items-center justify-center py-12 px-4 gap-4 text-center text-foreground-lighter">
<Storage className="h-6 w-6" strokeWidth={1.5} />
<p className="text-sm">Failed to load storage buckets</p>
</div>
</div>
{renderFooter()}
</div>
)
}
if (allResults.length === 0) {
return (
<div className="relative h-full flex flex-col">
<div className="flex-1 min-h-0 overflow-hidden">
<EmptyState icon={Storage} label="Storage" query={debouncedQuery} />
</div>
{renderFooter()}
</div>
)
}
return (
<div className="relative h-full flex flex-col">
<div className="flex-1 min-h-0 overflow-hidden">
<ResultsList
results={allResults}
icon={Storage}
getIcon={getIcon}
getRoute={getRoute}
className="pb-9"
/>
</div>
{renderFooter()}
</div>
)
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does StorageSearchResults() do?
StorageSearchResults() is a function in the supabase codebase.
What does StorageSearchResults() call?
StorageSearchResults() calls 1 function(s): filterBuckets.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free