@@ -20,7 +20,7 @@ import { AlertTableHeader } from "./AlertTableHeader";
2020import { AlertTableNoResults } from "./AlertTableNoResults" ;
2121import { AlertTableTruncatedMessage } from "./AlertTableTruncatedMessage" ;
2222import { AlertTableResultRow } from "./AlertTableResultRow" ;
23- import { useEffect , useRef , useState } from "react" ;
23+ import { useCallback , useEffect , useRef , useState } from "react" ;
2424
2525type AlertTableProps = ResultTableProps & {
2626 resultSet : InterpretedResultSet < SarifInterpretationData > ;
@@ -108,70 +108,73 @@ export function AlertTable(props: AlertTableProps) {
108108 }
109109 } ;
110110
111- const handleNavigationEvent = ( event : NavigateMsg ) => {
112- const key = getNewSelection ( selectedItem , event . direction ) ;
113- const data = resultSet . interpretation . data ;
111+ const handleNavigationEvent = useCallback (
112+ ( event : NavigateMsg ) => {
113+ const key = getNewSelection ( selectedItem , event . direction ) ;
114+ const data = resultSet . interpretation . data ;
114115
115- // Check if the selected node actually exists (bounds check) and get its location if relevant
116- let jumpLocation : Sarif . Location | undefined ;
117- if ( key . pathNodeIndex !== undefined ) {
118- jumpLocation = Keys . getPathNode ( data , key ) ;
119- if ( jumpLocation === undefined ) {
120- return ; // Result does not exist
121- }
122- } else if ( key . pathIndex !== undefined ) {
123- if ( Keys . getPath ( data , key ) === undefined ) {
124- return ; // Path does not exist
125- }
126- jumpLocation = undefined ; // When selecting a 'path', don't jump anywhere.
127- } else {
128- jumpLocation = Keys . getResult ( data , key ) ?. locations ?. [ 0 ] ;
129- if ( jumpLocation === undefined ) {
130- return ; // Path step does not exist.
131- }
132- }
133- if ( jumpLocation !== undefined ) {
134- const parsedLocation = parseSarifLocation (
135- jumpLocation ,
136- resultSet . interpretation . sourceLocationPrefix ,
137- ) ;
138- if ( ! isNoLocation ( parsedLocation ) ) {
139- jumpToLocation ( parsedLocation , databaseUri ) ;
116+ // Check if the selected node actually exists (bounds check) and get its location if relevant
117+ let jumpLocation : Sarif . Location | undefined ;
118+ if ( key . pathNodeIndex !== undefined ) {
119+ jumpLocation = Keys . getPathNode ( data , key ) ;
120+ if ( jumpLocation === undefined ) {
121+ return ; // Result does not exist
122+ }
123+ } else if ( key . pathIndex !== undefined ) {
124+ if ( Keys . getPath ( data , key ) === undefined ) {
125+ return ; // Path does not exist
126+ }
127+ jumpLocation = undefined ; // When selecting a 'path', don't jump anywhere.
128+ } else {
129+ jumpLocation = Keys . getResult ( data , key ) ?. locations ?. [ 0 ] ;
130+ if ( jumpLocation === undefined ) {
131+ return ; // Path step does not exist.
132+ }
140133 }
141- }
142-
143- const newExpanded = new Set ( expanded ) ;
144- if ( event . direction === NavigationDirection . right ) {
145- // When stepping right, expand to ensure the selected node is visible
146- newExpanded . add ( Keys . keyToString ( { resultIndex : key . resultIndex } ) ) ;
147- if ( key . pathIndex !== undefined ) {
148- newExpanded . add (
149- Keys . keyToString ( {
150- resultIndex : key . resultIndex ,
151- pathIndex : key . pathIndex ,
152- } ) ,
134+ if ( jumpLocation !== undefined ) {
135+ const parsedLocation = parseSarifLocation (
136+ jumpLocation ,
137+ resultSet . interpretation . sourceLocationPrefix ,
153138 ) ;
139+ if ( ! isNoLocation ( parsedLocation ) ) {
140+ jumpToLocation ( parsedLocation , databaseUri ) ;
141+ }
154142 }
155- } else if ( event . direction === NavigationDirection . left ) {
156- // When stepping left, collapse immediately
157- newExpanded . delete ( Keys . keyToString ( key ) ) ;
158- } else {
159- // When stepping up or down, collapse the previous node
160- if ( selectedItem !== undefined ) {
161- newExpanded . delete ( Keys . keyToString ( selectedItem ) ) ;
143+
144+ const newExpanded = new Set ( expanded ) ;
145+ if ( event . direction === NavigationDirection . right ) {
146+ // When stepping right, expand to ensure the selected node is visible
147+ newExpanded . add ( Keys . keyToString ( { resultIndex : key . resultIndex } ) ) ;
148+ if ( key . pathIndex !== undefined ) {
149+ newExpanded . add (
150+ Keys . keyToString ( {
151+ resultIndex : key . resultIndex ,
152+ pathIndex : key . pathIndex ,
153+ } ) ,
154+ ) ;
155+ }
156+ } else if ( event . direction === NavigationDirection . left ) {
157+ // When stepping left, collapse immediately
158+ newExpanded . delete ( Keys . keyToString ( key ) ) ;
159+ } else {
160+ // When stepping up or down, collapse the previous node
161+ if ( selectedItem !== undefined ) {
162+ newExpanded . delete ( Keys . keyToString ( selectedItem ) ) ;
163+ }
162164 }
163- }
164- scroller . current ?. scrollIntoViewOnNextUpdate ( ) ;
165- setExpanded ( newExpanded ) ;
166- setSelectedItem ( key ) ;
167- } ;
165+ scroller . current ?. scrollIntoViewOnNextUpdate ( ) ;
166+ setExpanded ( newExpanded ) ;
167+ setSelectedItem ( key ) ;
168+ } ,
169+ [ databaseUri , expanded , resultSet , selectedItem ] ,
170+ ) ;
168171
169172 useEffect ( ( ) => {
170173 onNavigation . addListener ( handleNavigationEvent ) ;
171174 return ( ) => {
172175 onNavigation . removeListener ( handleNavigationEvent ) ;
173176 } ;
174- } , [ ] ) ;
177+ } , [ handleNavigationEvent ] ) ;
175178
176179 const { numTruncatedResults, sourceLocationPrefix } =
177180 resultSet . interpretation ;
0 commit comments