diff --git a/pkg/ui/react-app/src/pages/graph/Panel.test.tsx b/pkg/ui/react-app/src/pages/graph/Panel.test.tsx index 993c60b1a4..4e8d262aa6 100644 --- a/pkg/ui/react-app/src/pages/graph/Panel.test.tsx +++ b/pkg/ui/react-app/src/pages/graph/Panel.test.tsx @@ -20,7 +20,7 @@ const defaultProps: PanelProps = { maxSourceResolution: 'auto', useDeduplication: true, forceTracing: false, - usePartialResponse: false, + usePartialResponse: true, storeMatches: [], engine: 'prometheus', analyze: false, @@ -96,7 +96,7 @@ describe('Panel', () => { maxSourceResolution: 'auto', useDeduplication: true, forceTracing: false, - usePartialResponse: false, + usePartialResponse: true, storeMatches: [], engine: 'prometheus', analyze: false, diff --git a/pkg/ui/react-app/src/pages/graph/Panel.tsx b/pkg/ui/react-app/src/pages/graph/Panel.tsx index fb2bd59b75..104f8db7f2 100644 --- a/pkg/ui/react-app/src/pages/graph/Panel.tsx +++ b/pkg/ui/react-app/src/pages/graph/Panel.tsx @@ -58,6 +58,9 @@ interface PanelState { exprInputValue: string; analysis: QueryTree | null; explainOutput: ExplainTree | null; + traceId: string | null; //Include traceId in the state. + queryStatus: boolean; + hoverMessage: string | null; isHovered: boolean; } @@ -93,7 +96,7 @@ export const PanelDefaultOptions: PanelOptions = { maxSourceResolution: '0s', useDeduplication: true, forceTracing: false, - usePartialResponse: false, + usePartialResponse: true, storeMatches: [], engine: '', analyze: false, @@ -116,6 +119,9 @@ class Panel extends Component { exprInputValue: props.options.expr, explainOutput: null, analysis: null, + traceId: null, // Initialize traceId to null. + queryStatus: false, + hoverMessage: null, isHovered: false, }; @@ -238,7 +244,12 @@ class Panel extends Component { credentials: 'same-origin', signal: abortController.signal, }) - .then((resp) => resp.json()) + .then((resp) => { + const traceIdHeader = resp.headers.get('X-Thanos-Trace-Id'); + this.setState({ traceId: traceIdHeader }); + return resp.json(); + }) + .then((json) => { if (json.status !== 'success') { throw new Error(json.error || 'invalid response JSON'); @@ -333,6 +344,14 @@ class Panel extends Component { }; handleChangeForceTracing = (event: React.ChangeEvent): void => { this.setOptions({ forceTracing: event.target.checked }); + + if (this.state.queryStatus && this.state.traceId) { + this.setState({ hoverMessage: `TraceID: ${this.state.traceId}` }); + } else if (this.state.queryStatus) { + this.setState({ hoverMessage: 'TraceID is not available' }); + } else { + this.setState({ hoverMessage: '' }); + } }; handleChangePartialResponse = (event: React.ChangeEvent): void => { @@ -430,6 +449,7 @@ class Panel extends Component { let result = null; if (json.data) { result = json.data; + this.setState({ queryStatus: true }); } this.setState({ explainOutput: result }); }) @@ -511,9 +531,20 @@ class Panel extends Component { id={`force-tracing-checkbox-${id}`} onChange={this.handleChangeForceTracing} defaultchecked={options.forceTracing} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} > Force Tracing +
+ this.state.isHovered && this.setState({ hoverMessage: this.state.hoverMessage })} + onMouseLeave={() => this.setState({ hoverMessage: '' })} + > + {this.state.hoverMessage} + +