Files
supabase/apps/studio/components/grid/hooks/useOperationQueueActions.ts
Ali Waseem ea1b95d29b feature: batch and save operations for cell content updates (#42120)
* added initial queue operations and feature flag

* updated types

* added dirty state tracking on columns

* updated queue operations

* updated operation types and queue

* updated spacing

* removed on cancel

* updated to support saving

* updated to include eye details

* updated spacing for orders

* updated to support shortcuts

* added feature preview

* updated to unify queue methods

* added key generation

* used unique keys rather than random uuid

* updated based on code review

* operation key

* updated handle cancel

* updated remove operation button

* updated views for toast

* updated logic to support optimistic updates

* updated types

* code cleanup: remove LLM slop

* updated PR bug

* updated preview for logout

* updated based on code review

* removed use effect as it was causing problems

* fixed toast mounting away from sql editor

* removed toast for dedicated action bar

* cleaned up logic

* updated queue operations

* renamed method

* updated name for types

* updated comment

* fixed code rabbit solution

* added check for changed column

* added tests
2026-01-28 06:54:30 -07:00

84 lines
2.8 KiB
TypeScript

import { useQueryClient } from '@tanstack/react-query'
import { useCallback } from 'react'
import { toast } from 'sonner'
import { tableRowKeys } from 'data/table-rows/keys'
import { useOperationQueueSaveMutation } from 'data/table-rows/operation-queue-save-mutation'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { useGetImpersonatedRoleState } from 'state/role-impersonation-state'
import { useTableEditorStateSnapshot } from 'state/table-editor'
import { QueuedOperation } from 'state/table-editor-operation-queue.types'
interface UseOperationQueueActionsOptions {
onSaveSuccess?: () => void
onCancelSuccess?: () => void
}
/**
* Hook that provides save and cancel actions for the operation queue.
* Consolidates the logic used by both the useSaveQueueToast hook and OperationQueueSidePanel.
*/
export function useOperationQueueActions(options: UseOperationQueueActionsOptions = {}) {
const { onSaveSuccess, onCancelSuccess } = options
const queryClient = useQueryClient()
const { data: project } = useSelectedProjectQuery()
const snap = useTableEditorStateSnapshot()
const getImpersonatedRoleState = useGetImpersonatedRoleState()
const { mutate: saveOperationQueue, isPending: isMutationPending } =
useOperationQueueSaveMutation({
onSuccess: () => {
snap.clearQueue()
toast.success('Changes saved successfully')
onSaveSuccess?.()
},
onError: (error) => {
snap.setQueueStatus('idle')
toast.error(`Failed to save changes: ${error.message}`)
},
})
const isSaving = snap.operationQueue.status === 'saving' || isMutationPending
const handleSave = useCallback(() => {
if (!project) return
const operations = snap.operationQueue.operations as readonly QueuedOperation[]
if (operations.length === 0) return
snap.setQueueStatus('saving')
saveOperationQueue({
projectRef: project.ref,
connectionString: project.connectionString,
operations,
roleImpersonationState: getImpersonatedRoleState(),
})
}, [snap, project, saveOperationQueue, getImpersonatedRoleState])
const handleCancel = useCallback(() => {
// Get unique table IDs from the queue before clearing
const operations = snap.operationQueue.operations as readonly QueuedOperation[]
const tableIds = [...new Set(operations.map((op) => op.tableId))]
// Clear the queue and invalidate queries to revert optimistic updates
snap.clearQueue()
if (project) {
// Invalidate queries for each table that had pending operations
tableIds.forEach((tableId) => {
queryClient.invalidateQueries({
queryKey: tableRowKeys.tableRowsAndCount(project.ref, tableId),
})
})
}
onCancelSuccess?.()
}, [snap, project, queryClient, onCancelSuccess])
return {
handleSave,
handleCancel,
isSaving,
}
}