@@ -37,11 +37,14 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
3737 }
3838 ) ;
3939
40- const [ selectedCode , setSelectedCode ] = useState < number | string > ( sortedStatusCodes [ 0 ] ?. code || 0 ) ;
41- const [ isFault , setIsFault ] = useState ( false ) ;
40+ type Selection = { code : number | string ; isFault : boolean } ;
41+ const [ selection , setSelection ] = useState < Selection | null > ( null ) ;
4242
43- const selectedTestCases = statusCodes . find ( ( code ) => code . code === selectedCode ) ?. testCases || [ ] ;
44- const selectedFaultTestCases = faults . find ( ( code ) => code . code === selectedCode ) ?. testCases || [ ] ;
43+ const toggleSelection = ( code : number | string , fault : boolean ) => {
44+ setSelection ( prev =>
45+ prev && prev . code === code && prev . isFault === fault ? null : { code, isFault : fault }
46+ ) ;
47+ } ;
4548
4649 const sortedFaults = faults . sort ( ( a , b ) => {
4750 const codeA = Number ( a . code ) ;
@@ -51,13 +54,22 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
5154 }
5255 return codeA - codeB ;
5356 } ) ;
54- const getSelectedStyle = ( code : number | string , fault : boolean ) => {
5557
56- const isSelected = selectedCode === code && isFault === fault ;
58+ const getSelectedStyle = ( code : number | string , fault : boolean ) => {
59+ const isSelected = selection ?. code === code && selection ?. isFault === fault ;
5760 return isSelected ? "ring-2 ring-offset-2 ring-offset-white ring-blue-400 shadow-md" : "" ;
58-
5961 }
6062
63+ const selectedGroup = selection
64+ ? ( selection . isFault
65+ ? sortedFaults . find ( f => f . code === selection . code )
66+ : sortedStatusCodes . find ( s => s . code === selection . code ) )
67+ : null ;
68+
69+ const nonEmptyStatusGroups = sortedStatusCodes . filter ( c => c . testCases . length > 0 ) ;
70+ const nonEmptyFaultGroups = sortedFaults . filter ( f => f . testCases . length > 0 ) ;
71+ const hasAnyTestCases = nonEmptyStatusGroups . length > 0 || nonEmptyFaultGroups . length > 0 ;
72+
6173 const faultColors = [ "bg-red-300" , "bg-red-500" , "bg-red-700" ] ;
6274 return (
6375 < AccordionItem value = { value } className = "border-2 border-black mb-4 overflow-hidden" data-testid = { endpoint } >
@@ -82,10 +94,7 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
8294 < div className = "flex flex-wrap gap-2" >
8395 {
8496 sortedStatusCodes . map ( ( code , index ) => (
85- < Badge key = { index } onClick = { ( ) => {
86- setSelectedCode ( code . code ) ;
87- setIsFault ( false ) ;
88- } }
97+ < Badge key = { index } onClick = { ( ) => toggleSelection ( code . code , false ) }
8998 className = { `${ getColor ( code . code , true , false ) } ${ getSelectedStyle ( code . code , false ) } ${ getHoverColor ( code . code , false ) } cursor-pointer text-white font-mono text-base border-2 border-black shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]` } >
9099 { code . code == - 1 ? "NO-RESPONSE" : `H${ code . code } ` }
91100 </ Badge >
@@ -103,10 +112,7 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
103112 < div className = "flex flex-wrap gap-2" >
104113 {
105114 sortedFaults . map ( ( fault , index ) => (
106- < Badge key = { index } onClick = { ( ) => {
107- setSelectedCode ( fault . code )
108- setIsFault ( true ) ;
109- } }
115+ < Badge key = { index } onClick = { ( ) => toggleSelection ( fault . code , true ) }
110116 className = { `${ faultColors [ index % faultColors . length ] } ${ getSelectedStyle ( fault . code , true ) } hover:bg-red-400 cursor-pointer text-white text-base font-mono border-2 border-black shadow-[2px_2px_0px_0px_rgba(0,0,0,1)]` } >
111117 F{ fault . code }
112118 </ Badge >
@@ -118,15 +124,30 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
118124 }
119125 </ div >
120126 </ div >
121- < div className = "text-xs text-gray-500 mt-1" > Click to show test cases.</ div >
127+ < div className = "text-xs text-gray-500 mt-1" >
128+ { selection ? "Click the highlighted code again to clear the filter." : "Showing all test cases. Click a code to filter." }
129+ </ div >
122130
123- {
124- ( selectedTestCases . length > 0 || selectedFaultTestCases . length > 0 ) &&
131+ { hasAnyTestCases && (
125132 < div className = "mt-6" >
126- < TestCases addTestTab = { addTestTab } isFault = { isFault } code = { selectedCode }
127- testCases = { selectedTestCases . length > 0 && ! isFault ? selectedTestCases : selectedFaultTestCases } />
133+ { selection && selectedGroup && selectedGroup . testCases . length > 0 && (
134+ < TestCases addTestTab = { addTestTab } isFault = { selection . isFault } code = { selection . code }
135+ testCases = { selectedGroup . testCases } />
136+ ) }
137+ { ! selection && (
138+ < >
139+ { nonEmptyStatusGroups . map ( c => (
140+ < TestCases key = { `s-${ c . code } ` } addTestTab = { addTestTab } isFault = { false }
141+ code = { c . code } testCases = { c . testCases } />
142+ ) ) }
143+ { nonEmptyFaultGroups . map ( f => (
144+ < TestCases key = { `f-${ f . code } ` } addTestTab = { addTestTab } isFault = { true }
145+ code = { f . code } testCases = { f . testCases } />
146+ ) ) }
147+ </ >
148+ ) }
128149 </ div >
129- }
150+ ) }
130151 </ AccordionContent >
131152 </ AccordionItem >
132153 )
0 commit comments