({ workspaceId, tableId }: RowMutationContext)
| 1773 | } |
| 1774 | |
| 1775 | export function useDeleteColumn({ workspaceId, tableId }: RowMutationContext) { |
| 1776 | const queryClient = useQueryClient() |
| 1777 | |
| 1778 | return useMutation({ |
| 1779 | mutationFn: async (columnName: string) => { |
| 1780 | return requestJson(deleteTableColumnContract, { |
| 1781 | params: { tableId }, |
| 1782 | body: { workspaceId, columnName }, |
| 1783 | }) |
| 1784 | }, |
| 1785 | onMutate: async (columnName) => { |
| 1786 | await queryClient.cancelQueries({ queryKey: tableKeys.detail(tableId) }) |
| 1787 | |
| 1788 | const lower = columnName.toLowerCase() |
| 1789 | const previousDetail = queryClient.getQueryData<TableDefinition>(tableKeys.detail(tableId)) |
| 1790 | // The grid deletes by stable id; legacy callers may pass a name. Resolve |
| 1791 | // the column's storage id once from either form, then strip schema, |
| 1792 | // widths, and row data by that single id — all three are id-keyed, so a |
| 1793 | // name arg with a distinct id must never be used as the strip key directly. |
| 1794 | const target = previousDetail?.schema.columns.find( |
| 1795 | (c) => getColumnId(c) === columnName || c.name.toLowerCase() === lower |
| 1796 | ) |
| 1797 | const stripKey = target ? getColumnId(target) : columnName |
| 1798 | |
| 1799 | if (previousDetail) { |
| 1800 | const nextColumns = previousDetail.schema.columns.filter((c) => getColumnId(c) !== stripKey) |
| 1801 | const prevWidths = previousDetail.metadata?.columnWidths |
| 1802 | const nextMetadata = prevWidths |
| 1803 | ? { |
| 1804 | ...previousDetail.metadata, |
| 1805 | columnWidths: Object.fromEntries( |
| 1806 | Object.entries(prevWidths).filter(([k]) => k !== stripKey) |
| 1807 | ), |
| 1808 | } |
| 1809 | : previousDetail.metadata |
| 1810 | queryClient.setQueryData<TableDefinition>(tableKeys.detail(tableId), { |
| 1811 | ...previousDetail, |
| 1812 | schema: { ...previousDetail.schema, columns: nextColumns }, |
| 1813 | metadata: nextMetadata, |
| 1814 | }) |
| 1815 | } |
| 1816 | |
| 1817 | const rowSnapshots = await snapshotAndMutateRows(queryClient, tableId, (row) => { |
| 1818 | if (!(stripKey in row.data)) return null |
| 1819 | const { [stripKey]: _removed, ...rest } = row.data |
| 1820 | return { ...row, data: rest } |
| 1821 | }) |
| 1822 | |
| 1823 | return { previousDetail, rowSnapshots } |
| 1824 | }, |
| 1825 | onError: (error, _columnName, context) => { |
| 1826 | if (context?.previousDetail) { |
| 1827 | queryClient.setQueryData(tableKeys.detail(tableId), context.previousDetail) |
| 1828 | } |
| 1829 | if (context?.rowSnapshots) { |
| 1830 | for (const [key, data] of context.rowSnapshots) { |
| 1831 | queryClient.setQueryData(key, data) |
| 1832 | } |
no test coverage detected