Skip to content

Commit 1551f96

Browse files
committed
fix(chat): carry the selection chip on a column-header copy
Cursor: a column-header Cmd+C always took the async paged clipboard path, which replaces the whole clipboard with text/plain only and can't carry a custom MIME - so pasting a column copy into Chat couldn't rebuild the table_selection chip that Add-to-chat produces for the same selection. When every row is loaded and within the chat-selection cap, the column copy now does a synchronous event write so the scoped table_selection rides alongside text/plain (mirroring the row-'some' and cell-range paths); oversized/partially-loaded columns keep the async plain-text path.
1 parent 3dac5a8 commit 1551f96

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-grid.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,6 +2932,50 @@ export function TableGrid({
29322932
if (name) colNames.push(name)
29332933
}
29342934
const colByKey = new Map(cols.map((c) => [c.key, c]))
2935+
2936+
// When every row is loaded and within the chat-selection cap, do a
2937+
// SYNCHRONOUS event write so the table_selection chip rides alongside
2938+
// text/plain — the async paged path below replaces the whole clipboard
2939+
// and can't carry a custom MIME. Add-to-chat materializes the same
2940+
// scoped selection, so Cmd+C must be able to rebuild that chip.
2941+
const allLoaded = currentRows.length >= selectAllTotalRef.current
2942+
if (
2943+
tableNameRef.current &&
2944+
allLoaded &&
2945+
currentRows.length > 0 &&
2946+
currentRows.length <= MAX_TABLE_SELECTION_ROWS
2947+
) {
2948+
const text = currentRows
2949+
.map((row) =>
2950+
colNames.map((name) => cellToText(row.data[name], colByKey.get(name))).join('\t')
2951+
)
2952+
.join('\n')
2953+
e.clipboardData?.setData('text/plain', text)
2954+
const rowIds = currentRows.map((row) => row.id)
2955+
const columnIds: string[] = []
2956+
for (let c = sel.startCol; c <= sel.endCol && c < cols.length; c++) {
2957+
columnIds.push(getColumnId(cols[c]))
2958+
}
2959+
const scopedColumnIds =
2960+
columnIds.length > 0 && columnIds.length < cols.length
2961+
? columnIds.slice(0, MAX_TABLE_SELECTION_COLUMNS)
2962+
: undefined
2963+
attachSelectionContextToClipboard(e.clipboardData, {
2964+
kind: 'table_selection',
2965+
tableId,
2966+
label: buildTableSelectionLabel(
2967+
tableNameRef.current,
2968+
rowIds.length,
2969+
scopedColumnIds?.length,
2970+
selectionKey([...rowIds, ...(scopedColumnIds ?? [])])
2971+
),
2972+
rowIds,
2973+
...(scopedColumnIds ? { columnIds: scopedColumnIds } : {}),
2974+
})
2975+
toast.success(`Copied ${rowIds.length} ${rowIds.length === 1 ? 'row' : 'rows'}`)
2976+
return
2977+
}
2978+
29352979
writeSelectionToClipboard({
29362980
loadRows: () => ensureRowsLoadedUpToRef.current(TABLE_LIMITS.MAX_COPY_ROWS),
29372981
selectRow: () => true,

0 commit comments

Comments
 (0)