DeleteCronJob.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { parseAsString, useQueryState } from 'nuqs'
  2. import { useEffect } from 'react'
  3. import { toast } from 'sonner'
  4. import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'
  5. import { parseCronJobCommand } from './CronJobs.utils'
  6. import { useCronJobsData } from './CronJobsTab.useCronJobsData'
  7. import { TextConfirmModal } from '@/components/ui/TextConfirmModalWrapper'
  8. import { useDatabaseCronJobDeleteMutation } from '@/data/database-cron-jobs/database-cron-jobs-delete-mutation'
  9. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  10. import { cleanPointerEventsNoneOnBody } from '@/lib/helpers'
  11. import { useTrack } from '@/lib/telemetry/track'
  12. export const DeleteCronJob = () => {
  13. const { data: project } = useSelectedProjectQuery()
  14. const [searchQuery] = useQueryState('search', parseAsString.withDefault(''))
  15. const [cronJobIdForDeletion, setCronJobForDeletion] = useQueryState('delete', parseAsString)
  16. const { grid } = useCronJobsData({
  17. projectRef: project?.ref,
  18. connectionString: project?.connectionString,
  19. searchQuery,
  20. })
  21. const cronJob = grid.rows.find((j) => j.jobid.toString() === cronJobIdForDeletion)
  22. const track = useTrack()
  23. const {
  24. mutate: deleteDatabaseCronJob,
  25. isPending,
  26. isSuccess: isSuccessDelete,
  27. } = useDatabaseCronJobDeleteMutation({
  28. onSuccess: () => {
  29. if (cronJob && project) {
  30. const { type } = parseCronJobCommand(cronJob.command, project.ref)
  31. track('cron_job_removed', { type })
  32. }
  33. toast.success(`Successfully removed cron job`)
  34. setCronJobForDeletion(null)
  35. },
  36. })
  37. async function handleDelete() {
  38. if (!project) return console.error('Project is required')
  39. if (!cronJob) return console.error('Cron job is missing')
  40. deleteDatabaseCronJob({
  41. jobId: cronJob.jobid,
  42. projectRef: project.ref,
  43. connectionString: project.connectionString,
  44. searchTerm: searchQuery,
  45. })
  46. }
  47. useEffect(() => {
  48. if (grid.isSuccess && !!cronJobIdForDeletion && !cronJob && !isSuccessDelete) {
  49. toast('Cron job not found')
  50. setCronJobForDeletion(null)
  51. }
  52. }, [cronJob, cronJobIdForDeletion, grid.isSuccess, isSuccessDelete, setCronJobForDeletion])
  53. if (!cronJob) {
  54. return null
  55. }
  56. // Cron job name is optional. If the cron job has no name, show a simplified modal which doesn't require the user to input the name.
  57. if (!cronJob.jobname) {
  58. return (
  59. <ConfirmationModal
  60. variant="destructive"
  61. visible={!!cronJob}
  62. onCancel={() => {
  63. setCronJobForDeletion(null)
  64. cleanPointerEventsNoneOnBody()
  65. }}
  66. onConfirm={handleDelete}
  67. title={`Delete the cron job`}
  68. loading={isPending}
  69. confirmLabel={`Delete`}
  70. alert={{ title: 'You cannot recover this cron job once deleted.' }}
  71. />
  72. )
  73. }
  74. return (
  75. <TextConfirmModal
  76. variant="destructive"
  77. visible={!!cronJob}
  78. onConfirm={handleDelete}
  79. onCancel={() => {
  80. setCronJobForDeletion(null)
  81. cleanPointerEventsNoneOnBody()
  82. }}
  83. title="Delete this cron job"
  84. loading={isPending}
  85. confirmLabel={`Delete cron job ${cronJob.jobname}`}
  86. confirmPlaceholder="Type in name of cron job"
  87. confirmString={cronJob.jobname ?? 'Unknown'}
  88. text={
  89. <>
  90. <span>This will delete the cron job</span>{' '}
  91. <span className="text-bold text-foreground">{cronJob.jobname}</span>
  92. </>
  93. }
  94. alert={{ title: 'You cannot recover this cron job once deleted.' }}
  95. />
  96. )
  97. }