@@ -7,6 +7,8 @@ import {Overview} from "@/pages/Overview.tsx";
77import { Endpoints } from "@/pages/Endpoints.tsx" ;
88import { TestResults } from "@/pages/TestResults.tsx" ;
99import { Tests } from "@/pages/Tests.tsx" ;
10+ import { Warnings } from "@/pages/Warnings.tsx" ;
11+ import { Examples } from "@/pages/Examples.tsx" ;
1012
1113import { ScrollArea , ScrollBar } from "@/components/ui/scroll-area.tsx" ;
1214import { useAppContext } from "@/AppProvider.tsx" ;
@@ -15,11 +17,26 @@ import {REVIEW_STATE} from "@/types/Review.ts";
1517
1618export interface ITestTabs {
1719 value : string ;
20+ origin : string ;
1821}
1922
23+ const MAIN_TABS = new Set ( [ "overview" , "endpoints" , "examples" , "tests" , "warnings" ] ) ;
24+
2025export const Dashboard : React . FC = ( ) => {
2126 const { data, isDirty, reviews} = useAppContext ( ) ;
2227
28+ const warningCount = data ?. warnings ?. length ?? 0 ;
29+
30+ const examplesCount = useMemo ( ( ) => {
31+ const set = new Set < string > ( ) ;
32+ for ( const tc of data ?. testCases ?? [ ] ) {
33+ for ( const ex of tc . namedExamples ?? [ ] ) {
34+ if ( ex ) set . add ( ex ) ;
35+ }
36+ }
37+ return set . size ;
38+ } , [ data ] ) ;
39+
2340 const reviewRatio = useMemo ( ( ) => {
2441 if ( ! data ) return null ;
2542 const total = data . testCases . length ;
@@ -37,9 +54,16 @@ export const Dashboard: React.FC = () => {
3754
3855 const [ testTabs , setTestTabs ] = useState < Array < ITestTabs > > ( [ ] ) ;
3956
57+ const [ openExamples , setOpenExamples ] = useState < string [ ] > ( [ ] ) ;
58+ const [ openEndpoint , setOpenEndpoint ] = useState < string > ( "" ) ;
59+ const [ openTestFiles , setOpenTestFiles ] = useState < string [ ] > ( [ ] ) ;
60+
4061 const addTestTab = ( testName : string , event : React . MouseEvent < HTMLElement > ) => {
62+ const origin = MAIN_TABS . has ( activeTab )
63+ ? activeTab
64+ : ( testTabs . find ( t => t . value === activeTab ) ?. origin ?? "endpoints" ) ;
4165 if ( ! testTabs . find ( ( t ) => t . value === testName ) ) {
42- setTestTabs ( [ { value : testName } , ...testTabs ] ) ;
66+ setTestTabs ( [ { value : testName , origin } , ...testTabs ] ) ;
4367 }
4468
4569 if ( ! event . ctrlKey ) {
@@ -48,12 +72,15 @@ export const Dashboard: React.FC = () => {
4872 }
4973
5074 const handleCloseTestsTab = ( testName : string ) => {
75+ const closing = testTabs . find ( t => t . value === testName ) ;
5176 const updatedTabs = testTabs . filter ( ( t ) => t . value !== testName ) ;
5277 setTestTabs ( updatedTabs ) ;
78+ if ( activeTab !== testName ) return ;
5379 if ( updatedTabs . length === 0 ) {
54- setActiveTab ( "endpoints" )
80+ const fallback = closing ?. origin ?? "endpoints" ;
81+ setActiveTab ( MAIN_TABS . has ( fallback ) ? fallback : "endpoints" ) ;
5582 } else {
56- setActiveTab ( updatedTabs [ 0 ] . value )
83+ setActiveTab ( updatedTabs [ 0 ] . value ) ;
5784 }
5885 }
5986
@@ -79,7 +106,7 @@ export const Dashboard: React.FC = () => {
79106 toolNameVersion = { `${ data . toolName } -${ data . toolVersion } ` } />
80107 < Tabs value = { activeTab } onValueChange = { setActiveTab } className = "w-full" >
81108 < div className = "flex justify-center mb-2 w-full" >
82- < TabsList className = { `flex gap-2 sm:gap-4 w-full max-w-[700px ] h-auto p-1 bg-transparent` } >
109+ < TabsList className = { `flex gap-2 sm:gap-4 w-full max-w-[1000px ] h-auto p-1 bg-transparent` } >
83110 < TabsTrigger
84111 value = "overview"
85112 className = "flex-1 sm:flex-none sm:min-w-[150px] py-3 text-xs sm:text-sm border border-gray-500 data-[state=active]:bg-blue-100 data-[state=active]:border-2 data-[state=active]:border-black data-[state=active]:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]"
@@ -94,6 +121,18 @@ export const Dashboard: React.FC = () => {
94121 >
95122 Endpoints
96123 </ TabsTrigger >
124+ < TabsTrigger
125+ value = "examples"
126+ className = "flex-1 sm:flex-none sm:min-w-[150px] py-3 text-xs sm:text-sm border border-gray-500 data-[state=active]:bg-blue-100 data-[state=active]:border-2 data-[state=active]:border-black data-[state=active]:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]"
127+ data-testid = "tab-examples"
128+ >
129+ Examples
130+ { examplesCount > 0 && (
131+ < span className = "ml-2 text-xs font-mono text-gray-600" data-testid = "tab-examples-count" >
132+ { examplesCount }
133+ </ span >
134+ ) }
135+ </ TabsTrigger >
97136 < TabsTrigger
98137 value = "tests"
99138 className = "flex-1 sm:flex-none sm:min-w-[150px] py-3 text-xs sm:text-sm border border-gray-500 data-[state=active]:bg-blue-100 data-[state=active]:border-2 data-[state=active]:border-black data-[state=active]:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]"
@@ -107,13 +146,25 @@ export const Dashboard: React.FC = () => {
107146 ) }
108147 { isDirty && < span className = "ml-1 text-orange-600" title = "Unsaved review changes" > •</ span > }
109148 </ TabsTrigger >
149+ < TabsTrigger
150+ value = "warnings"
151+ className = "flex-1 sm:flex-none sm:min-w-[150px] py-3 text-xs sm:text-sm border border-gray-500 data-[state=active]:bg-orange-100 data-[state=active]:border-2 data-[state=active]:border-black data-[state=active]:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]"
152+ data-testid = "tab-warnings"
153+ >
154+ Warnings
155+ { warningCount > 0 && (
156+ < span className = "ml-2 text-xs font-mono px-1.5 py-0.5 border border-orange-600 bg-orange-50 text-orange-700" data-testid = "tab-warnings-count" >
157+ { warningCount }
158+ </ span >
159+ ) }
160+ </ TabsTrigger >
110161 </ TabsList >
111162 </ div >
112163 < div className = "border-t border-black my-2" > </ div >
113164
114165 < div className = "flex justify-center w-full" >
115166 {
116- < TabsList className = { `flex gap-2 sm:gap-4 w-full max-w-[700px ] h-auto p-1 bg-transparent` } >
167+ < TabsList className = { `flex gap-2 sm:gap-4 w-full max-w-[1000px ] h-auto p-1 bg-transparent` } >
117168 < ScrollArea className = "w-[130%] whitespace-nowrap py-3" >
118169 {
119170 testTabs . map ( ( test , index ) => (
@@ -148,11 +199,19 @@ export const Dashboard: React.FC = () => {
148199 </ TabsContent >
149200
150201 < TabsContent value = "endpoints" >
151- < Endpoints addTestTab = { addTestTab } />
202+ < Endpoints addTestTab = { addTestTab } openEndpoint = { openEndpoint } setOpenEndpoint = { setOpenEndpoint } />
203+ </ TabsContent >
204+
205+ < TabsContent value = "examples" >
206+ < Examples addTestTab = { addTestTab } openExamples = { openExamples } setOpenExamples = { setOpenExamples } />
152207 </ TabsContent >
153208
154209 < TabsContent value = "tests" >
155- < Tests />
210+ < Tests openTestFiles = { openTestFiles } setOpenTestFiles = { setOpenTestFiles } />
211+ </ TabsContent >
212+
213+ < TabsContent value = "warnings" >
214+ < Warnings />
156215 </ TabsContent >
157216
158217 {
0 commit comments