mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 21:19:28 -06:00
Tempo: Copy trace query to TraceQL tab (#79935)
* Copy trace query to TraceQL tab * Remove datasourceType * Update button position * Update test * Remove extra check * Update text
This commit is contained in:
parent
e508c83538
commit
ef6b35ad3b
@ -193,6 +193,8 @@ class TempoQueryFieldComponent extends React.PureComponent<Props, State> {
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
onBlur={this.props.onBlur}
|
||||
app={app}
|
||||
onClearResults={this.onClearResults}
|
||||
/>
|
||||
)}
|
||||
{query.queryType === 'serviceMap' && (
|
||||
|
@ -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(<TraceQLSearch datasource={datasource} query={query} onChange={onChange} />);
|
||||
const { container } = render(
|
||||
<TraceQLSearch datasource={datasource} query={query} onChange={onChange} onClearResults={onClearResults} />
|
||||
);
|
||||
|
||||
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(<TraceQLSearch datasource={datasource} query={query} onChange={onChange} />);
|
||||
const { container } = render(
|
||||
<TraceQLSearch datasource={datasource} query={query} onChange={onChange} onClearResults={onClearResults} />
|
||||
);
|
||||
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(<TraceQLSearch datasource={datasource} query={query} onChange={onChange} />);
|
||||
const { container } = render(
|
||||
<TraceQLSearch datasource={datasource} query={query} onChange={onChange} onClearResults={onClearResults} />
|
||||
);
|
||||
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(<TraceQLSearch datasource={datasource} query={query} onChange={onChange} />);
|
||||
render(
|
||||
<TraceQLSearch datasource={datasource} query={query} onChange={onChange} onClearResults={onClearResults} />
|
||||
);
|
||||
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(<TraceQLSearch datasource={datasource} query={query} onChange={onChange} />);
|
||||
render(
|
||||
<TraceQLSearch datasource={datasource} query={query} onChange={onChange} onClearResults={onClearResults} />
|
||||
);
|
||||
const groupBy = screen.queryByText('Aggregate by');
|
||||
expect(groupBy).not.toBeNull();
|
||||
expect(groupBy).toBeInTheDocument();
|
||||
|
@ -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<Error | FetchError | null>(null);
|
||||
|
||||
@ -214,9 +215,30 @@ const TraceQLSearch = ({ datasource, query, onChange }: Props) => {
|
||||
<GroupByField datasource={datasource} onChange={onChange} query={query} isTagsLoading={isTagsLoading} />
|
||||
)}
|
||||
</div>
|
||||
<EditorRow>
|
||||
<div className={styles.rawQueryContainer}>
|
||||
<RawQuery query={templateSrv.replace(traceQlQuery)} lang={{ grammar: traceqlGrammar, name: 'traceql' }} />
|
||||
</EditorRow>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
reportInteraction('grafana_traces_copy_to_traceql_clicked', {
|
||||
app: app ?? '',
|
||||
grafana_version: config.buildInfo.version,
|
||||
location: 'search_tab',
|
||||
});
|
||||
|
||||
onClearResults();
|
||||
const traceQlQuery = generateQueryFromFilters(query.filters || []);
|
||||
onChange({
|
||||
...query,
|
||||
query: traceQlQuery,
|
||||
queryType: 'traceql',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Edit in TraceQL
|
||||
</Button>
|
||||
</div>
|
||||
<TempoQueryBuilderOptions onChange={onChange} query={query} />
|
||||
</div>
|
||||
{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),
|
||||
}),
|
||||
});
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user