SaveQueueActionBar() — supabase Function Reference
Architecture documentation for the SaveQueueActionBar() function in SaveQueueActionBar.tsx from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/studio/components/grid/components/footer/operations/SaveQueueActionBar.tsx lines 11–107
export const SaveQueueActionBar = () => {
const modKey = getModKeyLabel()
const snap = useTableEditorStateSnapshot()
const isQueueOperationsEnabled = useIsQueueOperationsEnabled()
const { handleSave } = useOperationQueueActions()
const [leftPosition, setLeftPosition] = useState<string>('50%')
useOperationQueueShortcuts()
const operationCount = snap.operationQueue.operations.length
const isSaving = snap.operationQueue.status === 'saving'
const isOperationQueuePanelOpen = snap.sidePanel?.type === 'operation-queue'
const isVisible =
isQueueOperationsEnabled && snap.hasPendingOperations && !isOperationQueuePanelOpen
// Center position relative to grid container (viewport alignment)
useEffect(() => {
if (!isVisible) return
const gridContainer = document.querySelector('.sb-grid')
const updatePosition = () => {
if (!gridContainer) {
setLeftPosition('50%')
return
}
const gridRect = gridContainer.getBoundingClientRect()
const gridCenter = gridRect.left + gridRect.width / 2
setLeftPosition(`${gridCenter}px`)
}
updatePosition()
if (!gridContainer) return
const resizeObserver = new ResizeObserver(updatePosition)
resizeObserver.observe(gridContainer)
window.addEventListener('resize', updatePosition)
window.addEventListener('scroll', updatePosition, true)
return () => {
resizeObserver.disconnect()
window.removeEventListener('resize', updatePosition)
window.removeEventListener('scroll', updatePosition, true)
}
}, [isVisible])
const content = (
<AnimatePresence>
{isVisible && (
<div
className="fixed bottom-12 z-50 transform-gpu will-change-transform"
style={{ left: leftPosition, transform: 'translateX(-50%)' }}
>
<motion.div
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 16 }}
transition={{
type: 'spring',
stiffness: 420,
damping: 30,
mass: 0.4,
}}
>
<div className="flex items-center gap-8 pl-4 pr-2 py-2 bg-surface-100 border rounded-lg shadow-lg">
<span className="text-xs text-foreground-light max-w-40 truncate">
{operationCount} pending change{operationCount !== 1 ? 's' : ''}
</span>
<div className="flex items-center gap-2">
<Button type="default" size="tiny" onClick={() => snap.toggleViewOperationQueue()}>
Review{' '}
<span className="text-[10px] text-foreground/40 ml-1.5">{`${modKey}.`}</span>
</Button>
<Button
size="tiny"
type="primary"
onClick={handleSave}
disabled={isSaving}
loading={isSaving}
>
Save{operationCount > 1 && ' all'}
<span className="text-[10px] text-foreground/40 ml-1.5">{`${modKey}S`}</span>
</Button>
</div>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
)
if (typeof document === 'undefined' || !document.body) return null
return createPortal(content, document.body)
}
Domain
Subdomains
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free