mirror of
https://github.com/supabase/supabase.git
synced 2026-09-09 03:19:36 +08:00
## Context Migrates the remaining API requests to the pg-meta endpoint to use the query endpoint directly with the SQL from the pg-meta package. This touches the following: - policies - publications - triggers - views - materialized views - types ## To test Just need to verify that we're still fetching the data correctly on these pages - Database policies - Database publications - Database triggers - Database tables (views + materialized views) - Database types <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved and stabilized loading of database metadata (views, triggers, RLS policies, publications, materialized views, and enum types), including more reliable schema-scoped filtering. * Updated policy loading behavior and related UI queries to consistently use schema arrays, improving cache correctness and consistency. * **Tests** * Updated end-to-end test synchronization to wait for the correct metadata responses using more specific request identifiers. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
101 lines
3.6 KiB
TypeScript
101 lines
3.6 KiB
TypeScript
import { useParams } from 'common'
|
|
import { useRouter } from 'next/router'
|
|
import { toast } from 'sonner'
|
|
|
|
import { extractBucketNameFromDefinition } from './Storage.utils'
|
|
import { TextConfirmModal } from '@/components/ui/TextConfirmModalWrapper'
|
|
import { useDatabasePoliciesQuery } from '@/data/database-policies/database-policies-query'
|
|
import { useDatabasePolicyDeleteMutation } from '@/data/database-policies/database-policy-delete-mutation'
|
|
import { useBucketDeleteMutation } from '@/data/storage/bucket-delete-mutation'
|
|
import { Bucket } from '@/data/storage/buckets-query'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
|
|
export interface DeleteBucketModalProps {
|
|
visible: boolean
|
|
bucket: Bucket
|
|
onClose: () => void
|
|
}
|
|
|
|
export const DeleteBucketModal = ({ visible, bucket, onClose }: DeleteBucketModalProps) => {
|
|
const router = useRouter()
|
|
const { ref: projectRef, bucketId } = useParams()
|
|
const { data: project } = useSelectedProjectQuery()
|
|
|
|
const { data: policies } = useDatabasePoliciesQuery({
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
schemas: ['storage'],
|
|
})
|
|
|
|
const { mutateAsync: deletePolicy } = useDatabasePolicyDeleteMutation()
|
|
|
|
const { mutate: deleteBucket, isPending: isDeletingBucket } = useBucketDeleteMutation({
|
|
onSuccess: async () => {
|
|
// Close the modal and navigate away as soon as the bucket itself is deleted, so
|
|
// policy cleanup below (which can be slow) doesn't hold the loading state or block
|
|
// the success feedback.
|
|
toast.success(`Successfully deleted bucket ${bucket.id}`)
|
|
onClose()
|
|
if (bucketId) router.push(`/project/${projectRef}/storage/files`)
|
|
|
|
if (!project) return console.error('Project is required')
|
|
|
|
// Clean up policies from the corresponding bucket that was deleted
|
|
const bucketPolicies = (policies ?? []).filter((policy) => {
|
|
if (policy.table !== 'objects') return false
|
|
|
|
const policyBucket = extractBucketNameFromDefinition(policy.definition ?? policy.check)
|
|
return policyBucket === bucket.name
|
|
})
|
|
|
|
if (bucketPolicies.length === 0) return
|
|
|
|
try {
|
|
await Promise.all(
|
|
bucketPolicies.map((policy) =>
|
|
deletePolicy({
|
|
projectRef: project.ref,
|
|
connectionString: project.connectionString,
|
|
originalPolicy: policy,
|
|
})
|
|
)
|
|
)
|
|
} catch (error) {
|
|
toast.success(
|
|
`Successfully deleted bucket ${bucket.id}. However, there was a problem deleting the policies tied to the bucket. Please review them in the storage policies section`
|
|
)
|
|
}
|
|
},
|
|
})
|
|
|
|
const onConfirmDelete = async () => {
|
|
if (!projectRef) return console.error('Project ref is required')
|
|
if (!bucket) return console.error('No bucket is selected')
|
|
deleteBucket({ projectRef, id: bucket.id })
|
|
}
|
|
|
|
return (
|
|
<TextConfirmModal
|
|
visible={visible}
|
|
size="medium"
|
|
variant="destructive"
|
|
title={`Delete bucket “${bucket.id}”`}
|
|
loading={isDeletingBucket}
|
|
confirmPlaceholder="Type bucket name"
|
|
confirmString={bucket.id}
|
|
confirmLabel="Delete bucket"
|
|
onCancel={onClose}
|
|
onConfirm={onConfirmDelete}
|
|
alert={{
|
|
title: 'You cannot recover this bucket once deleted',
|
|
description: 'This action cannot be undone',
|
|
}}
|
|
>
|
|
<p className="text-sm">
|
|
Your bucket <span className="font-bold text-foreground">{bucket.id}</span> and all of its
|
|
contents will be permanently deleted.
|
|
</p>
|
|
</TextConfirmModal>
|
|
)
|
|
}
|