@@ -18,7 +18,7 @@ import {
1818import { useVirtualizer } from "@tanstack/react-virtual" ;
1919import { formatDurationMilliseconds , MachinePresetName } from "@trigger.dev/core/v3" ;
2020import { ClipboardCheckIcon , ClipboardIcon } from "lucide-react" ;
21- import { memo , useEffect , useMemo , useRef , useState } from "react" ;
21+ import { forwardRef , memo , useEffect , useMemo , useRef , useState } from "react" ;
2222import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel" ;
2323import { MachineLabelCombo } from "~/components/MachineLabelCombo" ;
2424import { DateTimeAccurate } from "~/components/primitives/DateTime" ;
@@ -188,16 +188,14 @@ const fuzzyFilter: FilterFn<RowData> = (row, columnId, value, addMeta) => {
188188/**
189189 * Debounced input component for filter inputs
190190 */
191- function DebouncedInput ( {
192- value : initialValue ,
193- onChange,
194- debounce = 300 ,
195- ...props
196- } : {
197- value : string ;
198- onChange : ( value : string ) => void ;
199- debounce ?: number ;
200- } & Omit < React . InputHTMLAttributes < HTMLInputElement > , "onChange" > ) {
191+ const DebouncedInput = forwardRef <
192+ HTMLInputElement ,
193+ {
194+ value : string ;
195+ onChange : ( value : string ) => void ;
196+ debounce ?: number ;
197+ } & Omit < React . InputHTMLAttributes < HTMLInputElement > , "onChange" >
198+ > ( function DebouncedInput ( { value : initialValue , onChange, debounce = 300 , ...props } , ref ) {
201199 const [ value , setValue ] = useState ( initialValue ) ;
202200
203201 useEffect ( ( ) => {
@@ -212,8 +210,8 @@ function DebouncedInput({
212210 return ( ) => clearTimeout ( timeout ) ;
213211 } , [ value , debounce , onChange ] ) ;
214212
215- return < input { ...props } value = { value } onChange = { ( e ) => setValue ( e . target . value ) } /> ;
216- }
213+ return < input ref = { ref } { ...props } value = { value } onChange = { ( e ) => setValue ( e . target . value ) } /> ;
214+ } ) ;
217215
218216// Extended column meta to store OutputColumnMetadata
219217interface ColumnMeta {
@@ -785,7 +783,7 @@ function HeaderCellContent({
785783 < div
786784 className = { cn (
787785 "flex w-full items-center gap-1 overflow-hidden bg-background-dimmed px-2 py-1.5" ,
788- "text-sm font-medium text-text-bright" ,
786+ "font-mono text-xs font-medium text-text-bright" ,
789787 alignment === "right" && "justify-end" ,
790788 canSort && "cursor-pointer select-none"
791789 ) }
@@ -846,12 +844,31 @@ function HeaderCellContent({
846844/**
847845 * Filter input cell for the filter row
848846 */
849- function FilterCell ( { column, width } : { column : Column < RowData , unknown > ; width : number } ) {
847+ function FilterCell ( {
848+ column,
849+ width,
850+ shouldFocus,
851+ onFocused,
852+ } : {
853+ column : Column < RowData , unknown > ;
854+ width : number ;
855+ shouldFocus ?: boolean ;
856+ onFocused ?: ( ) => void ;
857+ } ) {
850858 const columnFilterValue = column . getFilterValue ( ) as string ;
859+ const inputRef = useRef < HTMLInputElement > ( null ) ;
860+
861+ useEffect ( ( ) => {
862+ if ( shouldFocus && inputRef . current ) {
863+ inputRef . current . focus ( ) ;
864+ onFocused ?.( ) ;
865+ }
866+ } , [ shouldFocus , onFocused ] ) ;
851867
852868 return (
853869 < div className = "flex items-center bg-background-dimmed px-1.5 pb-1" style = { { width } } >
854870 < DebouncedInput
871+ ref = { inputRef }
855872 value = { columnFilterValue ?? "" }
856873 onChange = { ( value ) => column . setFilterValue ( value ) }
857874 placeholder = "Filter..."
@@ -879,6 +896,8 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
879896 // State for column filters and filter row visibility
880897 const [ columnFilters , setColumnFilters ] = useState < ColumnFiltersState > ( [ ] ) ;
881898 const [ showFilters , setShowFilters ] = useState ( false ) ;
899+ // Track which column's filter should be focused
900+ const [ focusFilterColumn , setFocusFilterColumn ] = useState < string | null > ( null ) ;
882901 // State for column sorting
883902 const [ sorting , setSorting ] = useState < SortingState > ( [ ] ) ;
884903
@@ -971,7 +990,14 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
971990 < HeaderCellContent
972991 alignment = { meta ?. alignment ?? "left" }
973992 tooltip = { meta ?. outputColumn . description }
974- onFilterClick = { ( ) => setShowFilters ( ! showFilters ) }
993+ onFilterClick = { ( ) => {
994+ if ( ! showFilters ) {
995+ setFocusFilterColumn ( header . id ) ;
996+ } else {
997+ setColumnFilters ( [ ] ) ;
998+ }
999+ setShowFilters ( ! showFilters ) ;
1000+ } }
9751001 showFilters = { showFilters }
9761002 hasActiveFilter = { ! ! header . column . getFilterValue ( ) }
9771003 sortDirection = { header . column . getIsSorted ( ) }
@@ -1005,6 +1031,8 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
10051031 key = { `filter-${ header . id } ` }
10061032 column = { header . column }
10071033 width = { header . getSize ( ) }
1034+ shouldFocus = { focusFilterColumn === header . id }
1035+ onFocused = { ( ) => setFocusFilterColumn ( null ) }
10081036 />
10091037 ) ) }
10101038 </ tr >
@@ -1057,7 +1085,14 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
10571085 < HeaderCellContent
10581086 alignment = { meta ?. alignment ?? "left" }
10591087 tooltip = { meta ?. outputColumn . description }
1060- onFilterClick = { ( ) => setShowFilters ( ! showFilters ) }
1088+ onFilterClick = { ( ) => {
1089+ if ( ! showFilters ) {
1090+ setFocusFilterColumn ( header . id ) ;
1091+ } else {
1092+ setColumnFilters ( [ ] ) ;
1093+ }
1094+ setShowFilters ( ! showFilters ) ;
1095+ } }
10611096 showFilters = { showFilters }
10621097 hasActiveFilter = { ! ! header . column . getFilterValue ( ) }
10631098 sortDirection = { header . column . getIsSorted ( ) }
@@ -1091,6 +1126,8 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
10911126 key = { `filter-${ header . id } ` }
10921127 column = { header . column }
10931128 width = { header . getSize ( ) }
1129+ shouldFocus = { focusFilterColumn === header . id }
1130+ onFocused = { ( ) => setFocusFilterColumn ( null ) }
10941131 />
10951132 ) ) }
10961133 </ tr >
0 commit comments