mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 03:45:06 +03:00
refactor(storage): trim comments to one line where they earn their place
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N3euXsz25sTybsGTcxCFfn
This commit is contained in:
1 parent
39f0406192
commit
ffc1ab56e6
10 files changed
+14
-47
No files matched your search
@@ -6,11 +6,7 @@ import { useStorageExplorerNavigation } from './StorageExplorerNavigation'
|
||||
import { useObjectPurgeMutation } from '@/data/storage/versioning/object-purge-mutation'
|
||||
import { useStorageExplorerStateSnapshot } from '@/state/storage-explorer'
|
||||
|
||||
/**
|
||||
* Mounted once by the explorer. A permanent delete is the escape hatch from
|
||||
* versioning — an ordinary delete on a versioned bucket only archives — so it is
|
||||
* confirmed separately from `ConfirmDeleteModal` and always reads as destructive.
|
||||
*/
|
||||
/** Mounted once by the explorer. Confirmed separately from `ConfirmDeleteModal`, which archives. */
|
||||
export const ConfirmPurgeModal = () => {
|
||||
const {
|
||||
projectRef,
|
||||
@@ -26,8 +22,7 @@ export const ConfirmPurgeModal = () => {
|
||||
const { mutate: purgeObject, isPending: isPurging } = useObjectPurgeMutation({
|
||||
onSuccess: async () => {
|
||||
toast.success(`Permanently deleted ${itemToPurge?.name}`)
|
||||
// Only when the pane is showing the file that just went; purging from a row
|
||||
// menu shouldn't close a preview of something else.
|
||||
// Purging from a row menu shouldn't close a preview of something else.
|
||||
if (selectedFilePreview?.id === itemToPurge?.id) clearPreviewedFile()
|
||||
setItemToPurge(undefined)
|
||||
await refetchAllOpenedFolders()
|
||||
@@ -37,8 +32,7 @@ export const ConfirmPurgeModal = () => {
|
||||
const onConfirm = () => {
|
||||
if (!projectRef || !selectedBucket?.id || itemToPurge === undefined) return
|
||||
|
||||
// The delete endpoint addresses an object by its full path in the bucket, and a
|
||||
// row only knows its own leaf name.
|
||||
// The endpoint addresses an object by full path; a row only knows its leaf name.
|
||||
const folderPath = getPathAlongOpenedFolders(
|
||||
{ openedFolders: openedFolders.slice(0, itemToPurge.columnIndex), selectedBucket },
|
||||
false
|
||||
|
||||
@@ -233,8 +233,7 @@ export const FileExplorerRow = ({
|
||||
...(canUpdateFiles
|
||||
? [
|
||||
{
|
||||
// On a versioned bucket this is a soft delete, so it reads as Archive
|
||||
// here just as it does in the file preview panel.
|
||||
// On a versioned bucket this is a soft delete, so it reads as Archive.
|
||||
name: isVersionedBucket ? 'Archive' : 'Delete',
|
||||
icon: isVersionedBucket ? (
|
||||
<Archive size={12} className="text-foreground-light" />
|
||||
|
||||
@@ -14,7 +14,6 @@ vi.mock('@/state/storage-explorer', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
/** Captures the request body so the test can assert which version was asked for. */
|
||||
const mockSignEndpoint = () => {
|
||||
const bodies: Array<Record<string, unknown>> = []
|
||||
|
||||
|
||||
@@ -20,28 +20,18 @@ const FileIcon = ({ className }: { className?: string }) => (
|
||||
)
|
||||
|
||||
interface FilePreviewProps {
|
||||
/** Full path within the bucket. */
|
||||
path: string
|
||||
mimeType?: string
|
||||
/** Bytes. Anything larger than the limit renders a placeholder instead. */
|
||||
/** Bytes. Anything over the limit renders a placeholder instead. */
|
||||
size?: number
|
||||
/**
|
||||
* Renders that specific version's bytes rather than the object's current ones.
|
||||
* Without it the preview always shows the current version, which is what made
|
||||
* every entry in a version history look identical.
|
||||
*/
|
||||
/** Renders that version's bytes. Without it, the current ones. */
|
||||
versionId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a file's actual content — the same component for the current version and
|
||||
* for any older one, so a version preview can never silently fall back to showing
|
||||
* the current bytes.
|
||||
*/
|
||||
export const FilePreview = ({ path, mimeType, size, versionId }: FilePreviewProps) => {
|
||||
const { projectRef, selectedBucket } = useStorageExplorerStateSnapshot()
|
||||
|
||||
// An unknown size is treated as too large, matching the pre-versioning behavior.
|
||||
// An unknown size counts as too large, matching the pre-versioning behavior.
|
||||
const effectiveSize = size ?? PREVIEW_SIZE_LIMIT + 1
|
||||
const isSkipped = !!mimeType && effectiveSize > PREVIEW_SIZE_LIMIT
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ interface CurrentFilePreviewProps {
|
||||
onPurge: () => void
|
||||
}
|
||||
|
||||
/** The default top slot: the current file's thumbnail, metadata and actions. */
|
||||
const CurrentFilePreview = ({
|
||||
file,
|
||||
path,
|
||||
@@ -252,8 +251,7 @@ export const PreviewPane = () => {
|
||||
|
||||
const versioningState = getBucketVersioningState(selectedBucket)
|
||||
|
||||
// The version endpoints address an object by its full path in the bucket, not
|
||||
// by the leaf name the explorer renders.
|
||||
// The version endpoints address an object by full path, not the leaf name in the row.
|
||||
const folderPath = getPathAlongOpenedFolders({ openedFolders, selectedBucket }, false)
|
||||
const filePath = file ? [folderPath, file.name].filter(Boolean).join('/') : undefined
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import type { ObjectVersion } from '@/data/storage/versioning/object-versions-qu
|
||||
import { formatBytes } from '@/lib/helpers'
|
||||
|
||||
interface VersionCompareWidgetProps {
|
||||
/** Full path within the bucket. */
|
||||
path: string
|
||||
mimeType?: string
|
||||
selectedVersion: ObjectVersion
|
||||
@@ -60,8 +59,7 @@ export const VersionCompareWidget = ({
|
||||
<ArrowRight size={14} className="shrink-0 text-foreground-lighter" />
|
||||
<div className="flex-1 space-y-1.5">
|
||||
<div className="flex h-24 items-center justify-center overflow-hidden rounded-md border border-overlay bg-surface-200">
|
||||
{/* No `versionId`: without one the endpoint resolves the current version,
|
||||
which is exactly the right side of this comparison. */}
|
||||
{/* No `versionId`, so the endpoint resolves the current version. */}
|
||||
<FilePreview path={path} mimeType={mimeType} size={currentVersion?.size} />
|
||||
</div>
|
||||
<p className="truncate text-center font-mono text-[11px] text-foreground-lighter">
|
||||
|
||||
@@ -87,7 +87,6 @@ const VersionActionsMenu = ({
|
||||
const label = shortVersion(version.versionId)
|
||||
const isDeleteMarker = version.action === 'delete marker'
|
||||
|
||||
// Restoring and deleting only make sense for the versions behind the current one.
|
||||
if (version.isCurrent) return null
|
||||
|
||||
return (
|
||||
@@ -127,7 +126,6 @@ const VersionActionsMenu = ({
|
||||
interface VersionHistoryProps {
|
||||
projectRef?: string
|
||||
bucketId?: string
|
||||
/** Leaf name, for copy. */
|
||||
objectName: string
|
||||
/** Full path within the bucket, which is what the version endpoints address. */
|
||||
path: string
|
||||
|
||||
@@ -4,10 +4,7 @@ import { cn } from 'ui'
|
||||
import { useFetchFileUrlQuery } from './useFetchFileUrlQuery'
|
||||
import { useStorageExplorerStateSnapshot } from '@/state/storage-explorer'
|
||||
|
||||
/**
|
||||
* The thumbnail is 28px, so the whole object is downloaded to be drawn into
|
||||
* almost nothing. Worth it for an ordinary image, not for a large one.
|
||||
*/
|
||||
// The box is 28px, so the whole object is downloaded to draw almost nothing.
|
||||
const THUMBNAIL_SIZE_LIMIT = 5 * 1024 * 1024 // 5MB
|
||||
|
||||
const MimeTypeIcon = ({ mimeType, size }: { mimeType?: string; size: number }) => {
|
||||
@@ -58,15 +55,11 @@ interface VersionThumbnailProps {
|
||||
isCurrent: boolean
|
||||
isDeleteMarker?: boolean
|
||||
size?: number
|
||||
/**
|
||||
* Full path within the bucket. Given a path, an image version renders its own
|
||||
* bytes rather than a generic icon — which is the only thing that tells two
|
||||
* versions of the same file apart at a glance.
|
||||
*/
|
||||
/** Full path within the bucket. Given one, an image renders its own bytes. */
|
||||
path?: string
|
||||
/** Omit to render the object's current version. */
|
||||
versionId?: string
|
||||
/** Bytes, used to skip the fetch for a file too large to be worth thumbnailing. */
|
||||
/** Bytes, used to skip the fetch for a file too large to thumbnail. */
|
||||
byteSize?: number
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ export const fetchFileUrl = async (
|
||||
expiresIn?: number,
|
||||
versionId?: string
|
||||
) => {
|
||||
// Omitted entirely rather than sent as `undefined`, so a request for the current
|
||||
// version stays byte-identical to what the non-versioned callers send.
|
||||
// Omitted rather than sent as `undefined`, so current-version requests are unchanged.
|
||||
const options = versionId === undefined ? undefined : { versionId }
|
||||
|
||||
if (isBucketPublic) {
|
||||
|
||||
@@ -169,8 +169,7 @@ export function createStorageExplorerState({
|
||||
state.selectedItemsToDelete = items
|
||||
},
|
||||
|
||||
// Separate from `selectedItemsToDelete`: on a versioned bucket that one archives,
|
||||
// while this one takes the file and every retained version with it.
|
||||
// Separate from `selectedItemsToDelete`, which only archives on a versioned bucket.
|
||||
itemToPurge: undefined as StorageItemWithColumn | undefined,
|
||||
setItemToPurge: (item?: StorageItemWithColumn) => {
|
||||
state.itemToPurge = item
|
||||
|
||||
Reference in new issue
Block a user