@@ -66,7 +66,7 @@ import { RowModal } from '../row-modal'
6666import { TableFilter } from '../table-filter'
6767import { CellContent } from './cells/cell-content'
6868import { ExpandedCellPopover } from './cells/expanded-cell-popover'
69- import { COL_WIDTH , SELECTION_TINT_BG } from './constants'
69+ import { COL_WIDTH , COLUMN_SIDEBAR_WIDTH_CSS , SELECTION_TINT_BG } from './constants'
7070import { ColumnHeaderMenu } from './headers/column-header-menu'
7171import { COLUMN_TYPE_ICONS } from './headers/column-type-icon'
7272import { WorkflowGroupMetaCell } from './headers/workflow-group-meta-cell'
@@ -94,8 +94,6 @@ const COL_WIDTH_AUTO_FIT_MAX = 1000
9494// row-by-row.
9595const CHECKBOX_COL_WIDTH = 56
9696const ADD_COL_WIDTH = 120
97- /** Width of the column-config slideout (matches `column-sidebar.tsx`'s `w-[400px]`). */
98- const COLUMN_SIDEBAR_WIDTH = 400
9997const SKELETON_COL_COUNT = 4
10098const SKELETON_ROW_COUNT = 10
10199const ROW_HEIGHT_ESTIMATE = 35
@@ -1218,29 +1216,35 @@ export function Table({
12181216 return ( ) => cancelAnimationFrame ( rafId )
12191217 } , [ selectionAnchor , selectionFocus , isColumnSelection ] )
12201218
1221- const handleCellClick = useCallback ( ( rowId : string , columnName : string ) => {
1222- const column = columnsRef . current . find ( ( c ) => c . name === columnName )
1223- if ( column ?. type === 'boolean' ) {
1224- if ( ! canEditRef . current ) return
1225- const row = rowsRef . current . find ( ( r ) => r . id === rowId )
1226- if ( row ) {
1227- toggleBooleanCell ( rowId , columnName , row . data [ columnName ] )
1219+ const handleCellClick = useCallback (
1220+ ( rowId : string , columnName : string , options ?: { toggleBoolean ?: boolean } ) => {
1221+ const column = columnsRef . current . find ( ( c ) => c . name === columnName )
1222+ if ( column ?. type === 'boolean' ) {
1223+ if ( ! options ?. toggleBoolean || ! canEditRef . current ) return
1224+ const row = rowsRef . current . find ( ( r ) => r . id === rowId )
1225+ if ( row ) {
1226+ toggleBooleanCell ( rowId , columnName , row . data [ columnName ] )
1227+ }
1228+ return
12281229 }
1229- return
1230- }
12311230
1232- const current = editingCellRef . current
1233- if ( current && current . rowId === rowId && current . columnName === columnName ) return
1234- setEditingCell ( null )
1235- setInitialCharacter ( null )
1236- } , [ ] )
1231+ const current = editingCellRef . current
1232+ if ( current && current . rowId === rowId && current . columnName === columnName ) return
1233+ setEditingCell ( null )
1234+ setInitialCharacter ( null )
1235+ } ,
1236+ [ ]
1237+ )
12371238
12381239 // The cell has `select-none` which suppresses programmatic selection, so we
12391240 // override `user-select` on the inner element until the next click. The popover
12401241 // only opens when the leaf's scroll dimensions exceed its client dimensions
12411242 // (workflow cells nest text inside a span with its own `overflow-clip`).
12421243 const handleCellDoubleClick = useCallback (
12431244 ( rowId : string , columnName : string , columnKey : string ) => {
1245+ const column = columnsRef . current . find ( ( c ) => c . key === columnKey )
1246+ if ( column ?. type === 'boolean' ) return
1247+
12441248 setSelectionFocus ( null )
12451249 setIsColumnSelection ( false )
12461250
@@ -2080,11 +2084,11 @@ export function Table({
20802084 * The two panels are mutually exclusive (each opener closes the other).
20812085 */
20822086 const logPanelWidth = useLogDetailsUIStore ( ( state ) => state . panelWidth )
2083- const sidebarReservedPx = configState
2084- ? COLUMN_SIDEBAR_WIDTH
2087+ const sidebarReservedWidth = configState
2088+ ? COLUMN_SIDEBAR_WIDTH_CSS
20852089 : executionDetailsId
2086- ? logPanelWidth
2087- : 0
2090+ ? ` ${ logPanelWidth } px`
2091+ : '0px'
20882092
20892093 const handleConfigureColumn = useCallback ( ( columnName : string ) => {
20902094 setExecutionDetailsId ( null )
@@ -2578,8 +2582,8 @@ export function Table({
25782582 < div
25792583 className = 'relative h-fit'
25802584 style = { {
2581- width : `${ tableWidth + sidebarReservedPx } px ` ,
2582- paddingRight : sidebarReservedPx ,
2585+ width : `calc( ${ tableWidth } px + ${ sidebarReservedWidth } ) ` ,
2586+ paddingRight : sidebarReservedWidth ,
25832587 } }
25842588 >
25852589 < table
@@ -2989,7 +2993,7 @@ interface DataRowProps {
29892993 initialCharacter : string | null
29902994 pendingCellValue : Record < string , unknown > | null
29912995 normalizedSelection : NormalizedSelection | null
2992- onClick : ( rowId : string , columnName : string ) => void
2996+ onClick : ( rowId : string , columnName : string , options ?: { toggleBoolean ?: boolean } ) => void
29932997 onDoubleClick : ( rowId : string , columnName : string , columnKey : string ) => void
29942998 onSave : ( rowId : string , columnName : string , value : unknown , reason : SaveReason ) => void
29952999 onCancel : ( ) => void
@@ -3115,15 +3119,15 @@ const DataRow = React.memo(function DataRow({
31153119
31163120 return (
31173121 < tr onContextMenu = { ( e ) => onContextMenu ( e , row ) } >
3118- < td className = { cn ( CELL_CHECKBOX , 'cursor-pointer' ) } >
3122+ < td
3123+ className = { cn ( CELL_CHECKBOX , 'cursor-pointer' ) }
3124+ onMouseDown = { ( e ) => {
3125+ if ( e . button !== 0 ) return
3126+ onRowToggle ( rowIndex , e . shiftKey )
3127+ } }
3128+ >
31193129 < div className = 'flex items-center justify-center gap-1' >
3120- < div
3121- className = 'group/checkbox flex h-[20px] w-[24px] shrink-0 items-center justify-center'
3122- onMouseDown = { ( e ) => {
3123- if ( e . button !== 0 ) return
3124- onRowToggle ( rowIndex , e . shiftKey )
3125- } }
3126- >
3130+ < div className = 'group/checkbox flex h-[20px] w-[24px] shrink-0 items-center justify-center' >
31273131 < span
31283132 className = { cn (
31293133 'text-[var(--text-tertiary)] text-xs tabular-nums' ,
@@ -3147,6 +3151,9 @@ const DataRow = React.memo(function DataRow({
31473151 aria-label = { runningCount > 0 ? `Stop ${ runningCount } running` : 'Run row' }
31483152 title = { runningCount > 0 ? `Stop ${ runningCount } running` : 'Run row' }
31493153 className = 'ml-auto flex h-[20px] w-[20px] shrink-0 items-center justify-center rounded text-[var(--text-primary)] transition-colors hover-hover:bg-[var(--surface-2)]'
3154+ onMouseDown = { ( e ) => {
3155+ e . stopPropagation ( )
3156+ } }
31503157 onClick = { ( ) => {
31513158 if ( runningCount > 0 ) {
31523159 onStopRow ( row . id )
@@ -3192,7 +3199,13 @@ const DataRow = React.memo(function DataRow({
31923199 onCellMouseDown ( rowIndex , colIndex , e . shiftKey )
31933200 } }
31943201 onMouseEnter = { ( ) => onCellMouseEnter ( rowIndex , colIndex ) }
3195- onClick = { ( ) => onClick ( row . id , column . name ) }
3202+ onClick = { ( e ) =>
3203+ onClick ( row . id , column . name , {
3204+ toggleBoolean : Boolean (
3205+ ( e . target as HTMLElement ) . closest ( '[data-boolean-cell-toggle]' )
3206+ ) ,
3207+ } )
3208+ }
31963209 onDoubleClick = { ( ) => onDoubleClick ( row . id , column . name , column . key ) }
31973210 >
31983211 { isHighlighted && ( isMultiCell || isRowChecked ) && (
@@ -3307,9 +3320,23 @@ const SelectAllCheckbox = React.memo(function SelectAllCheckbox({
33073320 onCheckedChange : ( ) => void
33083321} ) {
33093322 return (
3310- < th className = { CELL_HEADER_CHECKBOX } >
3323+ < th
3324+ className = { cn ( CELL_HEADER_CHECKBOX , 'cursor-pointer' ) }
3325+ role = 'checkbox'
3326+ aria-checked = { checked }
3327+ tabIndex = { 0 }
3328+ onMouseDown = { ( e ) => {
3329+ if ( e . button !== 0 ) return
3330+ onCheckedChange ( )
3331+ } }
3332+ onKeyDown = { ( e ) => {
3333+ if ( e . key !== ' ' && e . key !== 'Enter' ) return
3334+ e . preventDefault ( )
3335+ onCheckedChange ( )
3336+ } }
3337+ >
33113338 < div className = 'flex items-center justify-center' >
3312- < Checkbox size = 'sm' checked = { checked } onCheckedChange = { onCheckedChange } />
3339+ < Checkbox size = 'sm' checked = { checked } className = 'pointer-events-none' />
33133340 </ div >
33143341 </ th >
33153342 )
0 commit comments