Files
supabase/apps/studio/components/interfaces/Storage/FilesBuckets/EditBucketModal.utils.ts
T
6ef729cb5c feat(storage): versioning bucket modals (FE-4161) (#49205)
| # | Branch | Base |
| - | ------ | ---- |
| 1 | `feat/storage-versioning-private-alpha` — merged | `master` |
| 2 | `feat/storage-versioning/002-bucket-form-fields` | `master` |
| 3 | `feat/storage-versioning/003-bucket-modals` ◀ | 2 |
| 4 | `feat/storage-versioning/004-object-versions-data` | 3 |
| 5 | `feat/storage-versioning/005-file-preview-versions` | 4 |
| 6 | `feat/storage-versioning/006-billing-storage-retention` | 5 |
| 7 | `feat/storage-versioning/007-archived-objects-data` | 6 |
| 8 | `feat/storage-versioning/008-archived-rows` | 7 |
| 9 | `feat/storage-versioning/009-archived-preview-pane` | 8 |
| 10 | `feat/storage-versioning/010-replace-file` | 9 |

## [3/10] Storage object versioning: wire into the bucket modals

**Base:** `feat/storage-versioning/002-bucket-form-fields` (PR 2)

### This PR

Mounts the object-versioning form section in the create and edit bucket
modals behind the feature preview, and saves it.

- create and edit bucket modals spread `bucketVersioningFormFields` into
their existing form schema
- lifecycle defaults  to 30 days / 10 versions
- edit adds a confirmation before suspending an actively versioned
bucket

## Enabling object versioning on a new bucket and setting lifecycle
policies


https://github.com/user-attachments/assets/194f8319-4929-432e-8a50-206f180a77a8

## Edit and suspend object-versioning


https://github.com/user-attachments/assets/f31e1d34-9840-4f5a-a269-6a911214742d

## To reproduce

1. Make sure storage versioning is enabled under feature previews >
Storage Versioning
2. Open Storage Bucket File explorer
3. create new bucket and enable Object Versioning
4. set lifecycle policy
- Noncurrent version expiration: can be either empty or >1
- Retained noncurrent versions: can be either empty or between 1 and 100
and can't exist without "Noncurrent version expiration"
5. Open new bucket with object versioning and test changing lifecycle
policies
6. Disabling object-versioning shows proper warning and updates
`versioning_status` to SUSPENDED (it can never go back to DISABLED once
it has been enabled on a bucket)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-10-07 16:38:35 +02:00

66 lines
2.2 KiB
TypeScript

import type { BucketVersioningFormValues } from './FilesBucket.schema'
import {
PROJECT_VERSIONING_DEFAULTS,
type BucketVersioningState,
type ExpirationMode,
} from '@/components/interfaces/Storage/StorageVersioning.constants'
export interface BucketVersioningSettings {
versioning: BucketVersioningState
versionExpiryDays: number | null
maxNoncurrentVersions: number | null
expirationMode: ExpirationMode
}
/** A never-versioned bucket prefills the project defaults; an unset condition stays unset. */
export const getVersioningFormDefaults = (
settings: BucketVersioningSettings
): BucketVersioningFormValues => {
const hasEverBeenVersioned = settings.versioning !== 'disabled'
if (!hasEverBeenVersioned) {
return {
enable_versioning: false,
version_expiry_days: PROJECT_VERSIONING_DEFAULTS.versionExpiryDays,
max_noncurrent_versions: PROJECT_VERSIONING_DEFAULTS.maxNoncurrentVersions,
expiration_mode: 'and',
}
}
return {
enable_versioning: settings.versioning === 'enabled',
version_expiry_days: settings.versionExpiryDays ?? '',
max_noncurrent_versions: settings.maxNoncurrentVersions ?? '',
expiration_mode: settings.expirationMode,
}
}
/** Turning versioning off suspends rather than disables. */
export const getNextVersioningState = (
currentState: BucketVersioningState,
isVersioningEnabled: boolean
): BucketVersioningState => {
if (isVersioningEnabled) return 'enabled'
return currentState === 'disabled' ? 'disabled' : 'suspended'
}
/** `DISABLED` is not an accepted update, so both cases send no versioning field at all. */
export const toVersioningStatusUpdate = (
nextState: BucketVersioningState
): 'ENABLED' | 'SUSPENDED' | undefined => {
if (nextState === 'enabled') return 'ENABLED'
if (nextState === 'suspended') return 'SUSPENDED'
return undefined
}
export const isSuspendingVersioning = (
currentState: BucketVersioningState,
isVersioningEnabled: boolean
) => currentState === 'enabled' && !isVersioningEnabled
/** Re-enabling a suspended bucket doesn't count — the user already opted in once. */
export const isEnablingVersioning = (
currentState: BucketVersioningState,
isVersioningEnabled: boolean
) => currentState === 'disabled' && isVersioningEnabled