useOnRowsChange() — supabase Function Reference
Architecture documentation for the useOnRowsChange() function in Grid.utils.tsx from the supabase codebase.
Entity Profile
Dependency Diagram
graph TD 13c29bbf_8511_5da2_f728_9f9db5e200c0["useOnRowsChange()"] 195c5181_2e45_3007_560a_5b290d5d2777["Grid()"] 195c5181_2e45_3007_560a_5b290d5d2777 -->|calls| 13c29bbf_8511_5da2_f728_9f9db5e200c0 style 13c29bbf_8511_5da2_f728_9f9db5e200c0 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
apps/studio/components/grid/components/grid/Grid.utils.tsx lines 22–172
export function useOnRowsChange(rows: SupaRow[]) {
const isQueueOperationsEnabled = useIsQueueOperationsEnabled()
const queryClient = useQueryClient()
const { data: project } = useSelectedProjectQuery()
const snap = useTableEditorTableStateSnapshot()
const tableEditorSnap = useTableEditorStateSnapshot()
const getImpersonatedRoleState = useGetImpersonatedRoleState()
const { mutate: mutateUpdateTableRow } = useTableRowUpdateMutation({
async onMutate({ projectRef, table, configuration, payload }) {
const primaryKeyColumns = new Set(Object.keys(configuration.identifiers))
const queryKey = tableRowKeys.tableRows(projectRef, { table: { id: table.id } })
await queryClient.cancelQueries({ queryKey })
const previousRowsQueries = queryClient.getQueriesData<TableRowsData>({ queryKey })
queryClient.setQueriesData<TableRowsData>({ queryKey }, (old) => {
return {
rows:
old?.rows.map((row) => {
// match primary keys
if (
Object.entries(row)
.filter(([key]) => primaryKeyColumns.has(key))
.every(([key, value]) => value === configuration.identifiers[key])
) {
return { ...row, ...payload }
}
return row
}) ?? [],
}
})
return { previousRowsQueries }
},
onError(error, _variables, context) {
const { previousRowsQueries } = context as {
previousRowsQueries: [
QueryKey,
(
| {
result: any[]
}
| undefined
),
][]
}
previousRowsQueries.forEach(([queryKey, previousRows]) => {
if (previousRows) {
queryClient.setQueriesData({ queryKey }, previousRows)
}
queryClient.invalidateQueries({ queryKey })
})
toast.error(error?.message ?? error)
},
})
return useCallback(
(_rows: SupaRow[], data: RowsChangeData<SupaRow, unknown>) => {
if (!project) return
const rowData = _rows[data.indexes[0]]
const previousRow = rows.find((x) => x.idx == rowData.idx)
const changedColumn = Object.keys(rowData).find(
(name) => rowData[name] !== previousRow![name]
)
if (!previousRow || !changedColumn) return
const enumArrayColumns = snap.originalTable.columns
?.filter((column) => {
return (column?.enums ?? []).length > 0 && column.data_type.toLowerCase() === 'array'
})
.map((column) => column.name)
const identifiers = {} as Dictionary<any>
isTableLike(snap.originalTable) &&
snap.originalTable.primary_keys.forEach((column) => {
const col = snap.originalTable.columns.find((c) => c.name === column.name)
identifiers[column.name] =
col?.format === 'bytea'
? convertByteaToHex(previousRow[column.name])
: previousRow[column.name]
})
if (Object.keys(identifiers).length === 0) {
return toast('Unable to update row as table has no primary keys', {
description: (
<div>
<p className="text-sm text-foreground-light">
Add a primary key column to your table first to serve as a unique identifier for
each row before updating or deleting the row.
</p>
<div className="mt-3">
<DocsButton href={`${DOCS_URL}/guides/database/tables#primary-keys`} />
</div>
</div>
),
})
}
const configuration = { identifiers }
if (isQueueOperationsEnabled) {
queueCellEditWithOptimisticUpdate({
queryClient,
queueOperation: tableEditorSnap.queueOperation,
projectRef: project.ref,
tableId: snap.table.id,
table: snap.originalTable,
row: previousRow,
rowIdentifiers: identifiers,
columnName: changedColumn,
oldValue: previousRow[changedColumn],
newValue: rowData[changedColumn],
enumArrayColumns,
})
} else {
// Default behavior: immediately save the change
const updatedData = { [changedColumn]: rowData[changedColumn] }
mutateUpdateTableRow({
projectRef: project.ref,
connectionString: project.connectionString,
table: snap.originalTable,
configuration,
payload: updatedData,
enumArrayColumns,
roleImpersonationState: getImpersonatedRoleState(),
})
}
},
[
getImpersonatedRoleState,
isQueueOperationsEnabled,
mutateUpdateTableRow,
project,
rows,
snap.originalTable,
snap.table.id,
tableEditorSnap,
queryClient,
]
)
}
Domain
Subdomains
Called By
Source
Frequently Asked Questions
What does useOnRowsChange() do?
useOnRowsChange() is a function in the supabase codebase.
What calls useOnRowsChange()?
useOnRowsChange() is called by 1 function(s): Grid.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free