@@ -4,13 +4,16 @@ import {
44 useReactTable ,
55 getCoreRowModel ,
66 getFilteredRowModel ,
7+ getSortedRowModel ,
78 flexRender ,
89 type ColumnDef ,
910 type CellContext ,
1011 type ColumnResizeMode ,
1112 type ColumnFiltersState ,
1213 type FilterFn ,
1314 type Column ,
15+ type SortingState ,
16+ type SortDirection ,
1417} from "@tanstack/react-table" ;
1518import { useVirtualizer } from "@tanstack/react-virtual" ;
1619import { formatDurationMilliseconds , MachinePresetName } from "@trigger.dev/core/v3" ;
@@ -36,7 +39,12 @@ import { Paragraph } from "../primitives/Paragraph";
3639import { TextLink } from "../primitives/TextLink" ;
3740import { InfoIconTooltip , SimpleTooltip } from "../primitives/Tooltip" ;
3841import { QueueName } from "../runs/v3/QueueName" ;
39- import { FunnelIcon } from "@heroicons/react/20/solid" ;
42+ import {
43+ FunnelIcon ,
44+ ChevronUpIcon ,
45+ ChevronDownIcon ,
46+ ChevronUpDownIcon ,
47+ } from "@heroicons/react/20/solid" ;
4048
4149const MAX_STRING_DISPLAY_LENGTH = 64 ;
4250const ROW_HEIGHT = 33 ; // Estimated row height in pixels
@@ -757,13 +765,19 @@ function HeaderCellContent({
757765 onFilterClick,
758766 showFilters,
759767 hasActiveFilter,
768+ sortDirection,
769+ onSortClick,
770+ canSort,
760771} : {
761772 alignment : "left" | "right" ;
762773 tooltip ?: React . ReactNode ;
763774 children : React . ReactNode ;
764775 onFilterClick ?: ( ) => void ;
765776 showFilters ?: boolean ;
766777 hasActiveFilter ?: boolean ;
778+ sortDirection ?: SortDirection | false ;
779+ onSortClick ?: ( event : React . MouseEvent ) => void ;
780+ canSort ?: boolean ;
767781} ) {
768782 const [ isHovered , setIsHovered ] = useState ( false ) ;
769783
@@ -772,10 +786,12 @@ function HeaderCellContent({
772786 className = { cn (
773787 "flex w-full items-center gap-1 overflow-hidden bg-background-dimmed px-2 py-1.5" ,
774788 "text-sm font-medium text-text-bright" ,
775- alignment === "right" && "justify-end"
789+ alignment === "right" && "justify-end" ,
790+ canSort && "cursor-pointer select-none"
776791 ) }
777792 onMouseEnter = { ( ) => setIsHovered ( true ) }
778793 onMouseLeave = { ( ) => setIsHovered ( false ) }
794+ onClick = { onSortClick }
779795 >
780796 { tooltip ? (
781797 < div
@@ -793,6 +809,20 @@ function HeaderCellContent({
793809 ) : (
794810 < span className = "min-w-0 flex-1 truncate" > { children } </ span >
795811 ) }
812+ { /* Sort indicator */ }
813+ { canSort && (
814+ < span
815+ className = { cn ( "flex-shrink-0" , sortDirection ? "text-text-bright" : "text-text-dimmed" ) }
816+ >
817+ { sortDirection === "asc" ? (
818+ < ChevronUpIcon className = "size-4" />
819+ ) : sortDirection === "desc" ? (
820+ < ChevronDownIcon className = "size-4" />
821+ ) : (
822+ < ChevronUpDownIcon className = "size-4" />
823+ ) }
824+ </ span >
825+ ) }
796826 { onFilterClick && (
797827 < button
798828 onClick = { ( e ) => {
@@ -849,6 +879,8 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
849879 // State for column filters and filter row visibility
850880 const [ columnFilters , setColumnFilters ] = useState < ColumnFiltersState > ( [ ] ) ;
851881 const [ showFilters , setShowFilters ] = useState ( false ) ;
882+ // State for column sorting
883+ const [ sorting , setSorting ] = useState < SortingState > ( [ ] ) ;
852884
853885 // Create TanStack Table column definitions from OutputColumnMetadata
854886 // Calculate column widths based on content
@@ -885,10 +917,13 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
885917 columnResizeMode,
886918 state : {
887919 columnFilters,
920+ sorting,
888921 } ,
889922 onColumnFiltersChange : setColumnFilters ,
923+ onSortingChange : setSorting ,
890924 getCoreRowModel : getCoreRowModel ( ) ,
891925 getFilteredRowModel : getFilteredRowModel ( ) ,
926+ getSortedRowModel : getSortedRowModel ( ) ,
892927 } ) ;
893928
894929 const { rows : tableRows } = table . getRowModel ( ) ;
@@ -939,6 +974,9 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
939974 onFilterClick = { ( ) => setShowFilters ( ! showFilters ) }
940975 showFilters = { showFilters }
941976 hasActiveFilter = { ! ! header . column . getFilterValue ( ) }
977+ sortDirection = { header . column . getIsSorted ( ) }
978+ onSortClick = { header . column . getToggleSortingHandler ( ) }
979+ canSort = { header . column . getCanSort ( ) }
942980 >
943981 { flexRender ( header . column . columnDef . header , header . getContext ( ) ) }
944982 </ HeaderCellContent >
@@ -1022,6 +1060,9 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
10221060 onFilterClick = { ( ) => setShowFilters ( ! showFilters ) }
10231061 showFilters = { showFilters }
10241062 hasActiveFilter = { ! ! header . column . getFilterValue ( ) }
1063+ sortDirection = { header . column . getIsSorted ( ) }
1064+ onSortClick = { header . column . getToggleSortingHandler ( ) }
1065+ canSort = { header . column . getCanSort ( ) }
10251066 >
10261067 { flexRender ( header . column . columnDef . header , header . getContext ( ) ) }
10271068 </ HeaderCellContent >
0 commit comments