@@ -25,11 +25,20 @@ import { TFunction, useTranslation } from 'react-i18next';
2525import { useDispatch , useSelector } from 'react-redux' ;
2626import { useLocationQuery } from '../hooks/useLocationQuery' ;
2727import { usePluginAvailable } from '../hooks/usePluginAvailable' ;
28- import { getGoalsGraph , getNeighborsGraph } from '../korrel8r-client' ;
28+ import { getGoalsGraph , getNeighborsGraph , replaceTraceStore } from '../korrel8r-client' ;
2929import * as api from '../korrel8r/client' ;
3030import * as korrel8r from '../korrel8r/types' ;
31- import { defaultSearch , Result , Search , SearchType , setResult , setSearch } from '../redux-actions' ;
31+ import {
32+ defaultSearch ,
33+ Result ,
34+ Search ,
35+ SearchType ,
36+ setResult ,
37+ setSearch ,
38+ setTraceContext ,
39+ } from '../redux-actions' ;
3240import { State } from '../redux-reducers' ;
41+ import { buildTraceStoreConfig , extractTraceContext , TraceContext } from '../utils/traceStoreUtils' ;
3342import * as time from '../time' ;
3443import { AdvancedSearchForm } from './AdvancedSearchForm' ;
3544import './korrel8rpanel.css' ;
@@ -43,6 +52,9 @@ export default function Korrel8rPanel() {
4352
4453 const search : Search = useSelector ( ( state : State ) => state . plugins ?. tp ?. get ( 'search' ) ) ;
4554 const result : Result | null = useSelector ( ( state : State ) => state . plugins ?. tp ?. get ( 'result' ) ) ;
55+ const storedTraceContext : TraceContext | null = useSelector ( ( state : State ) =>
56+ state . plugins ?. tp ?. get ( 'traceContext' ) ,
57+ ) ;
4658
4759 // Disable focus button if the panel is already focused on the current location,
4860 // or the current result is an error.
@@ -92,6 +104,13 @@ export default function Korrel8rPanel() {
92104 // Skip the first fetch if we already have a stored result.
93105 const useStoredResult = React . useRef ( result != null ) ;
94106
107+ // Helper function to check if two TraceContexts are different
108+ const traceContextsDiffer = ( a : TraceContext | null , b : TraceContext | null ) : boolean => {
109+ if ( ! a && ! b ) return false ;
110+ if ( ! a || ! b ) return true ;
111+ return a . namespace !== b . namespace || a . name !== b . name || a . tenant !== b . tenant ;
112+ } ;
113+
95114 // Fetch a new result from the korrel8r service when the search changes.
96115 React . useEffect ( ( ) => {
97116 if ( useStoredResult . current ) {
@@ -102,37 +121,77 @@ export default function Korrel8rPanel() {
102121 if ( ! queryStr ) return ;
103122
104123 let cancelled = false ;
105- const start : api . Start = {
106- queries : [ queryStr ] ,
107- constraint : constraint ?. toAPI ( ) ,
124+
125+ // Check if we need to update the trace store based on current URL
126+ const currentTraceContext = extractTraceContext ( ) ;
127+ const needsTraceStoreUpdate = traceContextsDiffer ( currentTraceContext , storedTraceContext ) ;
128+
129+ // Helper to perform the korrel8r fetch
130+ const performFetch = ( ) => {
131+ const start : api . Start = {
132+ queries : [ queryStr ] ,
133+ constraint : constraint ?. toAPI ( ) ,
134+ } ;
135+
136+ const fetch =
137+ search . searchType === SearchType . Goal
138+ ? getGoalsGraph ( { start, goals : [ search . goal ] } )
139+ : getNeighborsGraph ( { start, depth : search . depth } ) ;
140+ fetch
141+ . then ( ( response : api . Graph ) => {
142+ if ( cancelled ) return ;
143+ dispatchResult (
144+ Array . isArray ( response ?. nodes ) && response . nodes . length > 0
145+ ? { graph : new korrel8r . Graph ( response ) }
146+ : { title : t ( 'Empty Result' ) , message : t ( 'No correlated data found' ) } ,
147+ ) ;
148+ } )
149+ . catch ( ( e : api . ApiError ) => {
150+ if ( cancelled ) return ;
151+ dispatchResult ( {
152+ title : e ?. body ?. error ? t ( 'Search Error' ) : t ( 'Search Failed' ) ,
153+ message : e ?. body ?. error || e . message || 'Unknown Error' ,
154+ isError : true ,
155+ } ) ;
156+ } ) ;
157+ return fetch ;
108158 } ;
109159
110- const fetch =
111- search . searchType === SearchType . Goal
112- ? getGoalsGraph ( { start, goals : [ search . goal ] } )
113- : getNeighborsGraph ( { start, depth : search . depth } ) ;
114- fetch
115- . then ( ( response : api . Graph ) => {
116- if ( cancelled ) return ;
117- dispatchResult (
118- Array . isArray ( response ?. nodes ) && response . nodes . length > 0
119- ? { graph : new korrel8r . Graph ( response ) }
120- : { title : t ( 'Empty Result' ) , message : t ( 'No correlated data found' ) } ,
121- ) ;
122- } )
123- . catch ( ( e : api . ApiError ) => {
124- if ( cancelled ) return ;
125- dispatchResult ( {
126- title : e ?. body ?. error ? t ( 'Search Error' ) : t ( 'Search Failed' ) ,
127- message : e ?. body ?. error || e . message || 'Unknown Error' ,
128- isError : true ,
160+ // If trace context changed, update the backend trace store first
161+ if ( needsTraceStoreUpdate && currentTraceContext ) {
162+ const storeConfig = buildTraceStoreConfig ( currentTraceContext ) ;
163+ const timeoutMs = 3000 ;
164+
165+ Promise . race ( [
166+ replaceTraceStore ( storeConfig ) ,
167+ new Promise ( ( _ , reject ) =>
168+ setTimeout ( ( ) => reject ( new Error ( 'Trace store update timed out' ) ) , timeoutMs ) ,
169+ ) ,
170+ ] )
171+ . then ( ( ) => {
172+ if ( cancelled ) return ;
173+ // eslint-disable-next-line no-console
174+ console . log ( 'Trace store updated for tenant:' , currentTraceContext . tenant ) ;
175+ dispatch ( setTraceContext ( currentTraceContext ) ) ;
176+ performFetch ( ) ;
177+ } )
178+ . catch ( ( error ) => {
179+ if ( cancelled ) return ;
180+ // Log error but continue with fetch - panel will work with other domains
181+ // eslint-disable-next-line no-console
182+ console . error ( 'Failed to update trace store:' , error ) ;
183+ dispatch ( setTraceContext ( currentTraceContext ) ) ;
184+ performFetch ( ) ;
129185 } ) ;
130- } ) ;
186+ } else {
187+ // No trace context change, just perform the fetch
188+ performFetch ( ) ;
189+ }
190+
131191 return ( ) => {
132192 cancelled = true ;
133- fetch . cancel ( ) ;
134193 } ;
135- } , [ search , constraint , dispatchResult , t ] ) ;
194+ } , [ search , constraint , dispatchResult , dispatch , storedTraceContext , t ] ) ;
136195
137196 const advancedToggleID = 'query-toggle' ;
138197 const advancedContentID = 'query-content' ;
0 commit comments