mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 04:45:08 +03:00
Implements the five Claude Design mockups as real Studio components behind a single prototype flag (STORAGE_PROTECTION_ENABLED), wired to an in-memory mock data layer since no platform API exists yet: - Data protection section in create/edit bucket modals (versioning + snapshots toggles + lifecycle policies) - Snapshots: new bucket-scoped nav page with Pre-backup/Manual triggers, take snapshot, and restore-with-diff - Versions tab in the storage explorer preview pane (restore an older version) - Storage size retention breakdown on the org usage page (live / versions / snapshots, retained-data callout, per-bucket table) - Trash: new bucket-scoped nav page for soft-deletes with held-by-snapshot state Adds mock query/mutation hooks under data/storage/protection, Snapshots + Trash nav items, and new pages/routes (+ TANSTACK_MIGRATION entries). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p
47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import { useMemo } from 'react'
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from 'ui'
|
|
|
|
import { usePaginatedBucketsQuery } from '@/data/storage/buckets-query'
|
|
|
|
interface StorageBucketSelectorProps {
|
|
projectRef?: string
|
|
value?: string
|
|
onChange: (bucketId: string) => void
|
|
}
|
|
|
|
/**
|
|
* Compact bucket picker shared by the Snapshots and Trash pages, both of which
|
|
* are scoped to a single bucket at a time.
|
|
*/
|
|
export const StorageBucketSelector = ({
|
|
projectRef,
|
|
value,
|
|
onChange,
|
|
}: StorageBucketSelectorProps) => {
|
|
const { data } = usePaginatedBucketsQuery({ projectRef })
|
|
|
|
const bucketNames = useMemo(() => {
|
|
const buckets = data?.pages.flatMap((page) => page) ?? []
|
|
return buckets
|
|
.filter((bucket) => !('type' in bucket) || bucket.type === 'STANDARD')
|
|
.map((bucket) => bucket.name)
|
|
}, [data])
|
|
|
|
if (bucketNames.length === 0) return null
|
|
|
|
return (
|
|
<Select value={value} onValueChange={onChange}>
|
|
<SelectTrigger className="w-44" aria-label="Select a bucket">
|
|
<SelectValue placeholder="Select a bucket" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{bucketNames.map((name) => (
|
|
<SelectItem key={name} value={name}>
|
|
{name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
)
|
|
}
|