useOperationQueueActions.ts 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // @ts-nocheck
  2. import { useQueryClient } from '@tanstack/react-query'
  3. import { useCallback } from 'react'
  4. import { toast } from 'sonner'
  5. import { tableRowKeys } from '@/data/table-rows/keys'
  6. import { useOperationQueueSaveMutation } from '@/data/table-rows/operation-queue-save-mutation'
  7. import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
  8. import { useGetImpersonatedRoleState } from '@/state/role-impersonation-state'
  9. import { useTableEditorStateSnapshot } from '@/state/table-editor'
  10. import { QueuedOperation } from '@/state/table-editor-operation-queue.types'
  11. interface UseOperationQueueActionsOptions {
  12. onSaveSuccess?: () => void
  13. onCancelSuccess?: () => void
  14. }
  15. /**
  16. * Hook that provides save and cancel actions for the operation queue.
  17. * Consolidates the logic used by both the useSaveQueueToast hook and OperationQueueSidePanel.
  18. */
  19. export function useOperationQueueActions(options: UseOperationQueueActionsOptions = {}) {
  20. const { onSaveSuccess, onCancelSuccess } = options
  21. const queryClient = useQueryClient()
  22. const { data: project } = useSelectedProjectQuery()
  23. const snap = useTableEditorStateSnapshot()
  24. const getImpersonatedRoleState = useGetImpersonatedRoleState()
  25. const { mutate: saveOperationQueue, isPending: isMutationPending } =
  26. useOperationQueueSaveMutation({
  27. onSuccess: () => {
  28. snap.clearQueue()
  29. snap.closeSidePanel()
  30. toast.success('Changes saved successfully')
  31. onSaveSuccess?.()
  32. },
  33. onError: (error) => {
  34. snap.setQueueStatus('idle')
  35. toast.error(`Failed to save changes: ${error.message}`)
  36. },
  37. })
  38. const isSaving = snap.operationQueue.status === 'saving' || isMutationPending
  39. const operations = snap.operationQueue.operations as readonly QueuedOperation[]
  40. const handleSave = useCallback(() => {
  41. if (!project || operations.length === 0) return
  42. snap.setQueueStatus('saving')
  43. saveOperationQueue({
  44. projectRef: project.ref,
  45. connectionString: project.connectionString,
  46. operations,
  47. roleImpersonationState: getImpersonatedRoleState(),
  48. })
  49. }, [snap, project, operations, saveOperationQueue, getImpersonatedRoleState])
  50. const handleCancel = useCallback(() => {
  51. // Get unique table IDs from the queue before clearing
  52. const operations = snap.operationQueue.operations as readonly QueuedOperation[]
  53. const tableIds = [...new Set(operations.map((op) => op.tableId))]
  54. // Clear the queue and invalidate queries to revert optimistic updates
  55. snap.clearQueue()
  56. if (project) {
  57. // Invalidate queries for each table that had pending operations
  58. tableIds.forEach((tableId) => {
  59. queryClient.invalidateQueries({
  60. queryKey: tableRowKeys.tableRowsAndCount(project.ref, tableId),
  61. })
  62. })
  63. }
  64. onCancelSuccess?.()
  65. }, [snap, project, queryClient, onCancelSuccess])
  66. return {
  67. handleSave,
  68. handleCancel,
  69. isSaving,
  70. }
  71. }