@@ -11,7 +11,8 @@ import {
1111} from "@/components/ui/resizable" ;
1212import { useSharedAppState } from "@/state/app-state-context" ;
1313import { useCiEvalsRoute , navigateToCiEvalsRoute } from "@/lib/ci-evals-router" ;
14- import { aggregateSuite } from "./evals/helpers" ;
14+ import { aggregateSuite , groupSuitesByTag } from "./evals/helpers" ;
15+ import { TagAggregationPanel } from "./evals/tag-aggregation-panel" ;
1516import { useEvalMutations } from "./evals/use-eval-mutations" ;
1617import { useEvalQueries } from "./evals/use-eval-queries" ;
1718import { useEvalHandlers } from "./evals/use-eval-handlers" ;
@@ -33,6 +34,7 @@ export function CiEvalsTab({ convexWorkspaceId }: CiEvalsTabProps) {
3334
3435 const [ deletingSuiteId , setDeletingSuiteId ] = useState < string | null > ( null ) ;
3536 const [ deletingRunId , setDeletingRunId ] = useState < string | null > ( null ) ;
37+ const [ filterTag , setFilterTag ] = useState < string | null > ( null ) ;
3638
3739 const selectedSuiteId =
3840 route . type === "suite-overview" ||
@@ -84,6 +86,14 @@ export function CiEvalsTab({ convexWorkspaceId }: CiEvalsTabProps) {
8486 [ queries . sortedSuites ] ,
8587 ) ;
8688
89+ const tagGroups = useMemo ( ( ) => groupSuitesByTag ( sdkSuites ) , [ sdkSuites ] ) ;
90+ const hasTags = tagGroups . some ( ( g ) => g . tag !== "Untagged" ) ;
91+ const allTags = useMemo (
92+ ( ) =>
93+ Array . from ( new Set ( sdkSuites . flatMap ( ( e ) => e . suite . tags ?? [ ] ) ) ) . sort ( ) ,
94+ [ sdkSuites ] ,
95+ ) ;
96+
8797 const selectedSuiteEntry = useMemo ( ( ) => {
8898 if ( ! selectedSuiteId ) return null ;
8999 return (
@@ -127,6 +137,10 @@ export function CiEvalsTab({ convexWorkspaceId }: CiEvalsTabProps) {
127137 navigateToCiEvalsRoute ( { type : "suite-overview" , suiteId } ) ;
128138 } , [ ] ) ;
129139
140+ const handleSelectOverview = useCallback ( ( ) => {
141+ navigateToCiEvalsRoute ( { type : "list" } ) ;
142+ } , [ ] ) ;
143+
130144 const handleDeleteSuite = useCallback (
131145 async ( suite : EvalSuite ) => {
132146 if ( deletingSuiteId ) return ;
@@ -246,7 +260,11 @@ export function CiEvalsTab({ convexWorkspaceId }: CiEvalsTabProps) {
246260 suites = { sdkSuites }
247261 selectedSuiteId = { selectedSuiteId }
248262 onSelectSuite = { handleSelectSuite }
263+ onSelectOverview = { handleSelectOverview }
264+ isOverviewSelected = { ! selectedSuiteId && hasTags }
249265 isLoading = { queries . isOverviewLoading }
266+ filterTag = { filterTag }
267+ hasTags = { hasTags }
250268 />
251269 </ ResizablePanel >
252270
@@ -272,20 +290,30 @@ export function CiEvalsTab({ convexWorkspaceId }: CiEvalsTabProps) {
272290 </ div >
273291 </ div >
274292 ) : route . type === "list" || ! selectedSuite ? (
275- < div className = "flex-1 flex items-center justify-center" >
276- < div className = "text-center max-w-md mx-auto p-8" >
277- < div className = "w-20 h-20 bg-muted rounded-full flex items-center justify-center mx-auto mb-6" >
278- < GitBranch className = "h-10 w-10 text-muted-foreground" />
293+ hasTags ? (
294+ < TagAggregationPanel
295+ tagGroups = { tagGroups . filter ( ( g ) => g . tag !== "Untagged" ) }
296+ allTags = { allTags }
297+ filterTag = { filterTag }
298+ onFilterTagChange = { setFilterTag }
299+ onSelectSuite = { handleSelectSuite }
300+ />
301+ ) : (
302+ < div className = "flex-1 flex items-center justify-center" >
303+ < div className = "text-center max-w-md mx-auto p-8" >
304+ < div className = "w-20 h-20 bg-muted rounded-full flex items-center justify-center mx-auto mb-6" >
305+ < GitBranch className = "h-10 w-10 text-muted-foreground" />
306+ </ div >
307+ < h2 className = "text-2xl font-semibold text-foreground mb-2" >
308+ Select a suite
309+ </ h2 >
310+ < p className = "text-sm text-muted-foreground" >
311+ Choose a CI suite from the sidebar to inspect runs and test
312+ iterations.
313+ </ p >
279314 </ div >
280- < h2 className = "text-2xl font-semibold text-foreground mb-2" >
281- Select a suite
282- </ h2 >
283- < p className = "text-sm text-muted-foreground" >
284- Choose a CI suite from the sidebar to inspect runs and test
285- iterations.
286- </ p >
287315 </ div >
288- </ div >
316+ )
289317 ) : queries . isSuiteDetailsLoading ? (
290318 < div className = "flex h-full items-center justify-center" >
291319 < div className = "text-center" >
0 commit comments