mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 03:15:06 +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
67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
/**
|
|
* Shared constants + gating for the Storage Snapshots & Versioning prototype.
|
|
*/
|
|
|
|
// Prototype flag: force-enabled so the surfaces are visible via `pnpm dev:studio`.
|
|
// A real rollout would replace this with `useFlag('storageObjectVersioning')`.
|
|
export const STORAGE_PROTECTION_ENABLED = true
|
|
|
|
export const useIsStorageProtectionEnabled = () => STORAGE_PROTECTION_ENABLED
|
|
|
|
export type BucketVersioningState = 'enabled' | 'suspended' | 'disabled'
|
|
|
|
export interface BucketProtection {
|
|
versioning: BucketVersioningState
|
|
snapshots: boolean
|
|
snapshotOnDatabaseBackup: boolean
|
|
/** Expire noncurrent versions after N days (null = keep indefinitely). */
|
|
versionExpiryDays: number | null
|
|
/** Cap on retained newer noncurrent versions (max 100). */
|
|
maxNoncurrentVersions: number | null
|
|
/** Expire snapshots after N days (null = keep indefinitely). */
|
|
snapshotExpiryDays: number | null
|
|
}
|
|
|
|
const PROTECTED_BUCKETS: Record<string, BucketProtection> = {
|
|
'match-media': {
|
|
versioning: 'enabled',
|
|
snapshots: true,
|
|
snapshotOnDatabaseBackup: true,
|
|
versionExpiryDays: 30,
|
|
maxNoncurrentVersions: 100,
|
|
snapshotExpiryDays: 90,
|
|
},
|
|
avatars: {
|
|
versioning: 'enabled',
|
|
snapshots: false,
|
|
snapshotOnDatabaseBackup: false,
|
|
versionExpiryDays: 30,
|
|
maxNoncurrentVersions: 10,
|
|
snapshotExpiryDays: null,
|
|
},
|
|
}
|
|
|
|
const DEFAULT_PROTECTION: BucketProtection = {
|
|
versioning: 'disabled',
|
|
snapshots: false,
|
|
snapshotOnDatabaseBackup: false,
|
|
versionExpiryDays: null,
|
|
maxNoncurrentVersions: null,
|
|
snapshotExpiryDays: null,
|
|
}
|
|
|
|
/** Prototype: derive a bucket's protection config from its name. */
|
|
export const getMockBucketProtection = (bucketName: string | undefined): BucketProtection =>
|
|
(bucketName && PROTECTED_BUCKETS[bucketName]) || DEFAULT_PROTECTION
|
|
|
|
export const isBucketVersioned = (bucketName: string | undefined) =>
|
|
getMockBucketProtection(bucketName).versioning === 'enabled'
|
|
|
|
// Colours for the retention breakdown (Tailwind-independent so the chart + legend
|
|
// stay in lockstep). Live = brand green, versions = amber, snapshots = blue.
|
|
export const RETENTION_COLORS = {
|
|
live: 'hsl(var(--brand-default))',
|
|
versions: 'hsl(var(--warning-default))',
|
|
snapshots: 'hsl(217, 91%, 60%)',
|
|
} as const
|