diff --git a/public/app/plugins/datasource/tempo/QueryField.tsx b/public/app/plugins/datasource/tempo/QueryField.tsx index 252975076f3..80c15d8f5ce 100644 --- a/public/app/plugins/datasource/tempo/QueryField.tsx +++ b/public/app/plugins/datasource/tempo/QueryField.tsx @@ -193,6 +193,8 @@ class TempoQueryFieldComponent extends React.PureComponent { query={query} onChange={onChange} onBlur={this.props.onBlur} + app={app} + onClearResults={this.onClearResults} /> )} {query.queryType === 'serviceMap' && ( diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.test.tsx b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.test.tsx index 97405e906d5..3d43dcf2725 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.test.tsx +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.test.tsx @@ -70,6 +70,7 @@ describe('TraceQLSearch', () => { const onChange = (q: TempoQuery) => { query = q; }; + const onClearResults = jest.fn(); beforeEach(() => { jest.useFakeTimers(); @@ -83,7 +84,9 @@ describe('TraceQLSearch', () => { }); it('should update operator when new value is selected in operator input', async () => { - const { container } = render(); + const { container } = render( + + ); const minDurationOperator = container.querySelector(`input[aria-label="select min-duration operator"]`); expect(minDurationOperator).not.toBeNull(); @@ -101,7 +104,9 @@ describe('TraceQLSearch', () => { }); it('should add new filter when new value is selected in the service name section', async () => { - const { container } = render(); + const { container } = render( + + ); const serviceNameValue = container.querySelector(`input[aria-label="select service-name value"]`); expect(serviceNameValue).not.toBeNull(); expect(serviceNameValue).toBeInTheDocument(); @@ -136,7 +141,9 @@ describe('TraceQLSearch', () => { } as TempoDatasource; datasource.languageProvider = new TempoLanguageProvider(datasource); await act(async () => { - const { container } = render(); + const { container } = render( + + ); const serviceNameValue = container.querySelector(`input[aria-label="select service-name value"]`); expect(serviceNameValue).toBeNull(); expect(serviceNameValue).not.toBeInTheDocument(); @@ -145,7 +152,9 @@ describe('TraceQLSearch', () => { it('should not render group by when feature toggle is not enabled', async () => { await waitFor(() => { - render(); + render( + + ); const groupBy = screen.queryByText('Aggregate by'); expect(groupBy).toBeNull(); expect(groupBy).not.toBeInTheDocument(); @@ -155,7 +164,9 @@ describe('TraceQLSearch', () => { it('should render group by when feature toggle enabled', async () => { config.featureToggles.metricsSummary = true; await waitFor(() => { - render(); + render( + + ); const groupBy = screen.queryByText('Aggregate by'); expect(groupBy).not.toBeNull(); expect(groupBy).toBeInTheDocument(); diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.tsx b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.tsx index 1b3ed2e3f37..ee14233f34b 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.tsx +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/TraceQLSearch.tsx @@ -1,10 +1,9 @@ import { css } from '@emotion/css'; import React, { useCallback, useEffect, useState } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; -import { EditorRow } from '@grafana/experimental'; -import { config, FetchError, getTemplateSrv } from '@grafana/runtime'; -import { Alert, HorizontalGroup, Select, useStyles2 } from '@grafana/ui'; +import { CoreApp, GrafanaTheme2 } from '@grafana/data'; +import { config, FetchError, getTemplateSrv, reportInteraction } from '@grafana/runtime'; +import { Alert, Button, HorizontalGroup, Select, useStyles2 } from '@grafana/ui'; import { createErrorNotification } from '../../../../core/copy/appNotification'; import { notifyApp } from '../../../../core/reducers/appNotification'; @@ -28,11 +27,13 @@ interface Props { query: TempoQuery; onChange: (value: TempoQuery) => void; onBlur?: () => void; + onClearResults: () => void; + app?: CoreApp; } const hardCodedFilterIds = ['min-duration', 'max-duration', 'status']; -const TraceQLSearch = ({ datasource, query, onChange }: Props) => { +const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app }: Props) => { const styles = useStyles2(getStyles); const [error, setError] = useState(null); @@ -214,9 +215,30 @@ const TraceQLSearch = ({ datasource, query, onChange }: Props) => { )} - +
- + +
{error ? ( @@ -242,4 +264,11 @@ const getStyles = (theme: GrafanaTheme2) => ({ flex-wrap: wrap; flex-direction: column; `, + rawQueryContainer: css({ + alignItems: 'center', + backgroundColor: theme.colors.background.secondary, + display: 'flex', + justifyContent: 'space-between', + padding: theme.spacing(1), + }), }); diff --git a/public/app/plugins/datasource/tempo/traceql/QueryEditor.tsx b/public/app/plugins/datasource/tempo/traceql/QueryEditor.tsx index 2a75c84a33b..130ec34b193 100644 --- a/public/app/plugins/datasource/tempo/traceql/QueryEditor.tsx +++ b/public/app/plugins/datasource/tempo/traceql/QueryEditor.tsx @@ -48,9 +48,9 @@ export function QueryEditor(props: Props) { size="sm" onClick={() => { reportInteraction('grafana_traces_copy_to_traceql_clicked', { - datasourceType: 'tempo', app: props.app ?? '', grafana_version: config.buildInfo.version, + location: 'traceql_tab', }); props.onClearResults();