({ workspaceId, tableId }: RowMutationContext)
| 1235 | * Uses optimistic update for instant visual feedback. |
| 1236 | */ |
| 1237 | export function useUpdateTableMetadata({ workspaceId, tableId }: RowMutationContext) { |
| 1238 | const queryClient = useQueryClient() |
| 1239 | |
| 1240 | return useMutation({ |
| 1241 | mutationFn: async (metadata: TableMetadata) => { |
| 1242 | return requestJson(updateTableMetadataContract, { |
| 1243 | params: { tableId }, |
| 1244 | body: { workspaceId, metadata }, |
| 1245 | }) |
| 1246 | }, |
| 1247 | onMutate: async (metadata) => { |
| 1248 | await queryClient.cancelQueries({ queryKey: tableKeys.detail(tableId) }) |
| 1249 | |
| 1250 | const previous = queryClient.getQueryData<TableDefinition>(tableKeys.detail(tableId)) |
| 1251 | |
| 1252 | if (previous) { |
| 1253 | queryClient.setQueryData<TableDefinition>(tableKeys.detail(tableId), { |
| 1254 | ...previous, |
| 1255 | metadata: { ...(previous.metadata ?? {}), ...metadata }, |
| 1256 | }) |
| 1257 | } |
| 1258 | |
| 1259 | return { previous } |
| 1260 | }, |
| 1261 | onError: (_err, _vars, context) => { |
| 1262 | if (context?.previous) { |
| 1263 | queryClient.setQueryData(tableKeys.detail(tableId), context.previous) |
| 1264 | } |
| 1265 | }, |
| 1266 | onSettled: () => { |
| 1267 | // exact: rowsRoot nests under detail, so a prefix match would needlessly refetch all rows |
| 1268 | queryClient.invalidateQueries({ queryKey: tableKeys.detail(tableId), exact: true }) |
| 1269 | }, |
| 1270 | }) |
| 1271 | } |
| 1272 | |
| 1273 | interface CancelRunsParams { |
| 1274 | scope: 'all' | 'row' |
no test coverage detected