mirror of
https://github.com/supabase/supabase.git
synced 2026-10-16 14:49:10 +03:00
add ui to delete a sink
This commit is contained in:
1 parent
89da5468ca
commit
c192eef1ed
4 files changed
+135
-1
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { useParams } from 'common'
|
||||
import { useDeleteSinkMutation } from 'data/replication/delete-sink-mutation'
|
||||
import { toast } from 'sonner'
|
||||
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
|
||||
export type DeleteSinkModalProps = {
|
||||
visible: boolean
|
||||
title: string
|
||||
sinkId: number
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export const DeleteSinkModal = ({ visible, title, sinkId, onClose }: DeleteSinkModalProps) => {
|
||||
const { ref } = useParams()
|
||||
const { mutate: deleteSink, isLoading: isCreating } = useDeleteSinkMutation({
|
||||
onSuccess: (res) => {
|
||||
toast.success('Successfully deleted sink')
|
||||
onClose()
|
||||
},
|
||||
})
|
||||
const onConfirm = () => {
|
||||
deleteSink({
|
||||
projectRef: ref!,
|
||||
sinkId,
|
||||
})
|
||||
}
|
||||
return (
|
||||
<ConfirmationModal
|
||||
variant="destructive"
|
||||
visible={visible}
|
||||
title={title}
|
||||
confirmLabel="Delete"
|
||||
confirmLabelLoading="Deleting"
|
||||
onCancel={() => {
|
||||
onClose()
|
||||
}}
|
||||
onConfirm={onConfirm}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<p className="text-sm text-foreground-light">
|
||||
Are you sure you want to delete the selected sink? This action cannot be undone.
|
||||
</p>
|
||||
</div>
|
||||
</ConfirmationModal>
|
||||
)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import { useState } from 'react'
|
||||
import CreateSinkModal from './CreateSinkModal'
|
||||
import { Button } from 'ui'
|
||||
import { toast } from 'sonner'
|
||||
import { DeleteSinkModal } from './DeleteSinkModal'
|
||||
|
||||
export const ReplicationSinks = () => {
|
||||
const { ref } = useParams()
|
||||
@@ -16,6 +17,8 @@ export const ReplicationSinks = () => {
|
||||
projectRef: ref,
|
||||
})
|
||||
const [showCreateSinkModal, setShowCreateSinkModal] = useState(false)
|
||||
const [showDeleteSinkModal, setShowDeleteSinkModal] = useState(false)
|
||||
const [sinkIdToDelete, setSinkIdToDelete] = useState(-1)
|
||||
|
||||
const sinks = sinks_data ?? []
|
||||
|
||||
@@ -73,7 +76,8 @@ export const ReplicationSinks = () => {
|
||||
<Button
|
||||
type="danger"
|
||||
onClick={() => {
|
||||
toast.info('Deleting a sink is not yet implemented')
|
||||
setSinkIdToDelete(sink.id)
|
||||
setShowDeleteSinkModal(true)
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
@@ -93,6 +97,12 @@ export const ReplicationSinks = () => {
|
||||
visible={showCreateSinkModal}
|
||||
onClose={() => setShowCreateSinkModal(false)}
|
||||
/>
|
||||
<DeleteSinkModal
|
||||
visible={showDeleteSinkModal}
|
||||
title={`Delete sink with id ${sinkIdToDelete}?`}
|
||||
sinkId={sinkIdToDelete}
|
||||
onClose={() => setShowDeleteSinkModal(false)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import type { ResponseError } from 'types'
|
||||
import { replicationKeys } from './keys'
|
||||
import { handleError, del } from 'data/fetchers'
|
||||
|
||||
export type DeleteSinkParams = {
|
||||
projectRef: string
|
||||
sinkId: number
|
||||
}
|
||||
|
||||
async function deleteSink({ projectRef, sinkId }: DeleteSinkParams, signal?: AbortSignal) {
|
||||
if (!projectRef) throw new Error('projectRef is required')
|
||||
|
||||
const { data, error } = await del('/platform/replication/{ref}/sinks/{sink_id}', {
|
||||
params: { path: { ref: projectRef, sink_id: sinkId } },
|
||||
signal,
|
||||
})
|
||||
if (error) {
|
||||
handleError(error)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
type DeleteSinkData = Awaited<ReturnType<typeof deleteSink>>
|
||||
|
||||
export const useDeleteSinkMutation = ({
|
||||
onSuccess,
|
||||
onError,
|
||||
...options
|
||||
}: Omit<
|
||||
UseMutationOptions<DeleteSinkData, ResponseError, DeleteSinkParams>,
|
||||
'mutationFn'
|
||||
> = {}) => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation<DeleteSinkData, ResponseError, DeleteSinkParams>((vars) => deleteSink(vars), {
|
||||
async onSuccess(data, variables, context) {
|
||||
const { projectRef, sinkId } = variables
|
||||
await queryClient.invalidateQueries(replicationKeys.sinks(projectRef))
|
||||
await onSuccess?.(data, variables, context)
|
||||
},
|
||||
async onError(data, variables, context) {
|
||||
if (onError === undefined) {
|
||||
toast.error(`Failed to delete sink: ${data.message}`)
|
||||
} else {
|
||||
onError(data, variables, context)
|
||||
}
|
||||
},
|
||||
...options,
|
||||
})
|
||||
}
|
||||
Vendored
+24
@@ -3325,6 +3325,10 @@ export interface paths {
|
||||
/** Creates a sink */
|
||||
post: operations['ReplicationSinksController_createSink']
|
||||
}
|
||||
'/platform/replication/{ref}/sinks/{sink_id}': {
|
||||
/** Deletes a sink */
|
||||
delete: operations['ReplicationSinksController_deleteSink']
|
||||
}
|
||||
'/platform/replication/{ref}/sources': {
|
||||
/** Gets replication sources */
|
||||
get: operations['ReplicationSourcesController_getSources']
|
||||
@@ -21673,6 +21677,26 @@ export interface operations {
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Deletes a sink */
|
||||
ReplicationSinksController_deleteSink: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description Project ref */
|
||||
ref: string
|
||||
/** @description Sink id */
|
||||
sink_id: number
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
200: {
|
||||
content: never
|
||||
}
|
||||
/** @description Failed to delete sink */
|
||||
500: {
|
||||
content: never
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Gets replication sources */
|
||||
ReplicationSourcesController_getSources: {
|
||||
parameters: {
|
||||
|
||||
Reference in new issue
Block a user