11import { ChevronDownIcon , ChevronUpDownIcon , ChevronUpIcon } from "@heroicons/react/20/solid" ;
22import type { OutputColumnMetadata } from "@internal/clickhouse" ;
33import { IconFilter2 , IconFilter2X , IconTable } from "@tabler/icons-react" ;
4- import { ChartBlankState } from "../primitives/charts/ChartBlankState" ;
54import { rankItem } from "@tanstack/match-sorter-utils" ;
65import {
76 flexRender ,
@@ -20,7 +19,7 @@ import {
2019} from "@tanstack/react-table" ;
2120import { useVirtualizer } from "@tanstack/react-virtual" ;
2221import { formatDurationMilliseconds , MachinePresetName } from "@trigger.dev/core/v3" ;
23- import { ClipboardCheckIcon , ClipboardIcon } from "lucide-react" ;
22+ import { AlertCircle , ClipboardCheckIcon , ClipboardIcon } from "lucide-react" ;
2423import { forwardRef , memo , useEffect , useMemo , useRef , useState } from "react" ;
2524import { EnvironmentLabel , EnvironmentSlug } from "~/components/environments/EnvironmentLabel" ;
2625import { MachineLabelCombo } from "~/components/MachineLabelCombo" ;
@@ -38,6 +37,8 @@ import { useProject } from "~/hooks/useProject";
3837import { cn } from "~/utils/cn" ;
3938import { formatCurrencyAccurate , formatNumber } from "~/utils/numberFormatter" ;
4039import { v3ProjectPath , v3RunPathFromFriendlyId } from "~/utils/pathBuilder" ;
40+ import { ChartBlankState } from "../primitives/charts/ChartBlankState" ;
41+ import { Paragraph } from "../primitives/Paragraph" ;
4142
4243import { TextLink } from "../primitives/TextLink" ;
4344import { InfoIconTooltip , SimpleTooltip } from "../primitives/Tooltip" ;
@@ -905,11 +906,14 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
905906 columns,
906907 prettyFormatting = true ,
907908 sorting : defaultSorting = [ ] ,
909+ showHeaderOnEmpty = false ,
908910} : {
909911 rows : Record < string , unknown > [ ] ;
910912 columns : OutputColumnMetadata [ ] ;
911913 prettyFormatting ?: boolean ;
912914 sorting ?: SortingState ;
915+ /** When true, show column headers + "No results" on empty data. When false, show a blank state icon. */
916+ showHeaderOnEmpty ?: boolean ;
913917} ) {
914918 const tableContainerRef = useRef < HTMLDivElement > ( null ) ;
915919
@@ -979,7 +983,62 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
979983
980984 // Empty state
981985 if ( rows . length === 0 ) {
982- return < ChartBlankState icon = { IconTable } message = "No data to display" /> ;
986+ if ( ! showHeaderOnEmpty ) {
987+ return < ChartBlankState icon = { IconTable } message = "No data to display" /> ;
988+ }
989+
990+ return (
991+ < div
992+ className = "h-full min-h-0 w-full overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
993+ style = { { position : "relative" } }
994+ >
995+ < table style = { { display : "grid" } } >
996+ < thead
997+ className = "border-t border-grid-bright bg-background-bright after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-grid-bright"
998+ style = { {
999+ display : "grid" ,
1000+ position : "sticky" ,
1001+ top : 0 ,
1002+ zIndex : 1 ,
1003+ } }
1004+ >
1005+ { table . getHeaderGroups ( ) . map ( ( headerGroup ) => (
1006+ < tr key = { headerGroup . id } style = { { display : "flex" , width : "100%" } } >
1007+ { headerGroup . headers . map ( ( header ) => {
1008+ const meta = header . column . columnDef . meta as ColumnMeta | undefined ;
1009+ return (
1010+ < th
1011+ key = { header . id }
1012+ className = "group/header relative"
1013+ style = { {
1014+ display : "flex" ,
1015+ width : header . getSize ( ) ,
1016+ } }
1017+ >
1018+ < HeaderCellContent alignment = { meta ?. alignment ?? "left" } >
1019+ { flexRender ( header . column . columnDef . header , header . getContext ( ) ) }
1020+ </ HeaderCellContent >
1021+ </ th >
1022+ ) ;
1023+ } ) }
1024+ </ tr >
1025+ ) ) }
1026+ </ thead >
1027+ < tbody style = { { display : "grid" } } >
1028+ < tr style = { { display : "flex" , width : "100%" } } >
1029+ < td className = "w-full px-3 py-6" colSpan = { columns . length } >
1030+ < div className = "flex items-center justify-center gap-1.5" >
1031+ < AlertCircle className = "size-5 text-text-dimmed/50" />
1032+ < Paragraph variant = "small" className = "text-text-dimmed" >
1033+ This query returned no results
1034+ </ Paragraph >
1035+ </ div >
1036+ </ td >
1037+ </ tr >
1038+ </ tbody >
1039+ </ table >
1040+ </ div >
1041+ ) ;
9831042 }
9841043
9851044 return (
0 commit comments