RowHeader() — supabase Function Reference
Architecture documentation for the RowHeader() function in Header.tsx from the supabase codebase.
Entity Profile
Dependency Diagram
graph TD 45a20a70_0227_f399_758d_7761ce34992b["RowHeader()"] 461e5ae4_2848_627b_8597_976e56b82b69["formatRowsForCSV()"] 45a20a70_0227_f399_758d_7761ce34992b -->|calls| 461e5ae4_2848_627b_8597_976e56b82b69 style 45a20a70_0227_f399_758d_7761ce34992b fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
apps/studio/components/grid/components/header/Header.tsx lines 224–521
const RowHeader = ({ tableQueriesEnabled = true }: RowHeaderProps) => {
const queryClient = useQueryClient()
const { data: project } = useSelectedProjectQuery()
const tableEditorSnap = useTableEditorStateSnapshot()
const snap = useTableEditorTableStateSnapshot()
const isQueueOperationsEnabled = useIsQueueOperationsEnabled()
const roleImpersonationState = useRoleImpersonationStateSnapshot()
const isImpersonatingRole = roleImpersonationState.role !== undefined
const { filters } = useTableFilter()
const { sorts } = useTableSort()
const [isExporting, setIsExporting] = useState(false)
const [showExportModal, setShowExportModal] = useState(false)
const { data } = useTableRowsQuery(
{
projectRef: project?.ref,
connectionString: project?.connectionString,
tableId: snap.table.id,
sorts,
filters,
page: snap.page,
limit: tableEditorSnap.rowsPerPage,
roleImpersonationState: roleImpersonationState as RoleImpersonationState,
},
{ enabled: tableQueriesEnabled }
)
const { data: countData } = useTableRowsCountQuery(
{
projectRef: project?.ref,
connectionString: project?.connectionString,
tableId: snap.table.id,
filters,
enforceExactCount: snap.enforceExactCount,
roleImpersonationState: roleImpersonationState as RoleImpersonationState,
},
{ placeholderData: keepPreviousData, enabled: tableQueriesEnabled }
)
const allRows = data?.rows ?? []
const totalRows = countData?.count ?? 0
const onSelectAllRows = () => {
snap.setSelectedRows(new Set(allRows.map((row) => row.idx)), true)
}
const onRowsDelete = () => {
const rowIdxs = Array.from(snap.selectedRows) as number[]
const rows = allRows.filter((x) => rowIdxs.includes(x.idx))
// Queue delete operations directly if queue mode is enabled (and not all rows selected)
if (isQueueOperationsEnabled && !snap.allRowsSelected) {
queueRowDeletesWithOptimisticUpdate({
rows,
table: snap.originalTable,
queryClient,
queueOperation: tableEditorSnap.queueOperation,
projectRef: project?.ref,
})
snap.resetSelectedRows()
return
}
// Fall back to confirmation dialog
tableEditorSnap.onDeleteRows(rows, {
allRowsSelected: snap.allRowsSelected,
numRows: snap.allRowsSelected ? totalRows : rows.length,
callback: () => {
snap.resetSelectedRows()
},
})
}
const onCopyRows = (type: 'csv' | 'json' | 'sql') => {
const rows = allRows.filter((x) => snap.selectedRows.has(x.idx))
if (type === 'csv') {
const csv = formatRowsForCSV({
rows,
columns: snap.table!.columns.map((column) => column.name),
})
copyToClipboard(csv)
} else if (type === 'sql') {
const sqlStatements = formatTableRowsToSQL(snap.table, rows)
copyToClipboard(sqlStatements)
} else if (type === 'json') {
copyToClipboard(JSON.stringify(rows))
}
toast.success('Copied rows to clipboard')
}
const exportParams = snap.allRowsSelected
? ({ type: 'fetch_all', filters, sorts } as const)
: ({
type: 'provided_rows',
table: snap.table,
rows: allRows.filter((x) => snap.selectedRows.has(x.idx)),
} as const)
const { exportCsv, confirmationModal: exportCsvConfirmationModal } = useExportAllRowsAsCsv(
project
? {
enabled: true,
projectRef: project.ref,
connectionString: project?.connectionString ?? null,
entity: snap.table,
totalRows,
...exportParams,
}
: { enabled: false }
)
const onRowsExportCSV = async () => {
setIsExporting(true)
if (!project) {
toast.error('Project is required')
return setIsExporting(false)
}
exportCsv()
setIsExporting(false)
}
const { exportSql, confirmationModal: exportSqlConfirmationModal } = useExportAllRowsAsSql(
project
? {
enabled: true,
projectRef: project.ref,
connectionString: project?.connectionString ?? null,
entity: snap.table,
...exportParams,
}
: { enabled: false }
)
const onRowsExportSQL = async () => {
setIsExporting(true)
if (!project) {
toast.error('Project is required')
return setIsExporting(false)
}
exportSql()
setIsExporting(false)
}
const { exportJson, confirmationModal: exportJsonConfirmationModal } = useExportAllRowsAsJson(
project
? {
enabled: true,
projectRef: project.ref,
connectionString: project?.connectionString ?? null,
entity: snap.table,
...exportParams,
}
: { enabled: false }
)
const onRowsExportJSON = async () => {
if (!project) {
return toast.error('Project is required')
}
setIsExporting(true)
exportJson()
setIsExporting(false)
}
useSubscribeToImpersonatedRole(() => {
if (snap.allRowsSelected || snap.selectedRows.size > 0) {
snap.resetSelectedRows()
}
})
return (
<>
<div className="flex items-center gap-x-2">
{snap.editable && (
<ButtonTooltip
type="default"
size="tiny"
icon={<Trash />}
onClick={onRowsDelete}
disabled={snap.allRowsSelected && isImpersonatingRole}
tooltip={{
content: {
side: 'bottom',
text:
snap.allRowsSelected && isImpersonatingRole
? 'Table truncation is not supported when impersonating a role'
: undefined,
},
}}
>
{snap.allRowsSelected
? `Delete all rows in table`
: snap.selectedRows.size > 1
? `Delete ${snap.selectedRows.size} rows`
: `Delete ${snap.selectedRows.size} row`}
</ButtonTooltip>
)}
{!snap.allRowsSelected ? (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="default"
size="tiny"
iconRight={<ChevronDown />}
loading={isExporting}
disabled={isExporting}
>
Copy
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-40">
<DropdownMenuItem onClick={() => onCopyRows('csv')}>Copy as CSV</DropdownMenuItem>
<DropdownMenuItem onClick={() => onCopyRows('sql')}>Copy as SQL</DropdownMenuItem>
<DropdownMenuItem onClick={() => onCopyRows('json')}>Copy as JSON</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
) : (
<ButtonTooltip
disabled
type="default"
tooltip={{
content: {
side: 'bottom',
className: 'w-64 text-center',
text: 'Copy to clipboard is not supported while all rows in the table are selected',
},
}}
>
Copy
</ButtonTooltip>
)}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="default"
size="tiny"
iconRight={<ChevronDown />}
loading={isExporting}
disabled={isExporting}
>
Export
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className={snap.allRowsSelected ? 'w-52' : 'w-40'}>
<DropdownMenuItem onClick={onRowsExportCSV}>Export as CSV</DropdownMenuItem>
<DropdownMenuItem onClick={onRowsExportSQL}>Export as SQL</DropdownMenuItem>
{snap.allRowsSelected ? (
<DropdownMenuItem className="group" onClick={() => setShowExportModal(true)}>
<div>
<p className="group-hover:text-foreground">Export via CLI</p>
<p className="text-foreground-lighter">Recommended for large tables</p>
</div>
</DropdownMenuItem>
) : (
<DropdownMenuItem onClick={onRowsExportJSON}>Export as JSON</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
{!snap.allRowsSelected && totalRows > allRows.length && (
<>
<div className="h-6 ml-0.5">
<Separator orientation="vertical" />
</div>
<Button type="text" onClick={() => onSelectAllRows()}>
Select all rows in table
</Button>
</>
)}
</div>
<ExportDialog
table={snap.table}
filters={filters}
sorts={sorts}
open={showExportModal}
onOpenChange={() => setShowExportModal(false)}
/>
{exportCsvConfirmationModal}
{exportSqlConfirmationModal}
{exportJsonConfirmationModal}
</>
)
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does RowHeader() do?
RowHeader() is a function in the supabase codebase.
What does RowHeader() call?
RowHeader() calls 1 function(s): formatRowsForCSV.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free