import { css } from '@emotion/css'; import { PureComponent } from 'react'; import { QueryEditorProps, SelectableValue } from '@grafana/data'; import { config, reportInteraction } from '@grafana/runtime'; import { Button, FileDropzone, HorizontalGroup, InlineField, InlineFieldRow, Modal, RadioButtonGroup, Themeable2, withTheme2, } from '@grafana/ui'; import TraceQLSearch from './SearchTraceQLEditor/TraceQLSearch'; import { ServiceGraphSection } from './ServiceGraphSection'; import { TempoQueryType } from './dataquery.gen'; import { TempoDatasource } from './datasource'; import { QueryEditor } from './traceql/QueryEditor'; import { TempoQuery } from './types'; import { migrateFromSearchToTraceQLSearch } from './utils'; interface Props extends QueryEditorProps, Themeable2 { // should template variables be added to tag options. default true addVariablesToOptions?: boolean; } interface State { uploadModalOpen: boolean; } // This needs to default to traceql for data sources like Splunk, where clicking on a // data link should open the traceql tab and run a search based on the configured query. const DEFAULT_QUERY_TYPE: TempoQueryType = 'traceql'; class TempoQueryFieldComponent extends PureComponent { constructor(props: Props) { super(props); this.state = { uploadModalOpen: false, }; } // Set the default query type when the component mounts. // Also do this if queryType is 'clear' (which is the case when the user changes the query type) // otherwise if the user changes the query type and refreshes the page, no query type will be selected // which is inconsistent with how the UI was originally when they selected the Tempo data source. async componentDidMount() { if (!this.props.query.queryType || this.props.query.queryType === 'clear') { this.props.onChange({ ...this.props.query, queryType: DEFAULT_QUERY_TYPE, }); } } onClearResults = () => { // Run clear query to clear results const { onChange, query, onRunQuery } = this.props; onChange({ ...query, queryType: 'clear', }); onRunQuery(); }; render() { const { query, onChange, datasource, app } = this.props; const graphDatasourceUid = datasource.serviceMap?.datasourceUid; let queryTypeOptions: Array> = [ { value: 'traceqlSearch', label: 'Search' }, { value: 'traceql', label: 'TraceQL' }, { value: 'serviceMap', label: 'Service Graph' }, ]; // Migrate user to new query type if they are using the old search query type if ( query.spanName || query.serviceName || query.search || query.maxDuration || query.minDuration || query.queryType === 'nativeSearch' ) { onChange(migrateFromSearchToTraceQLSearch(query)); } return ( <> this.setState({ uploadModalOpen: false })} >
{ if (typeof result !== 'string' && result !== null) { throw Error(`Unexpected result type: ${typeof result}`); } this.props.datasource.uploadedJson = result; onChange({ ...query, queryType: 'upload', }); this.setState({ uploadModalOpen: false }); this.props.onRunQuery(); }} />
options={queryTypeOptions} value={query.queryType} onChange={(v) => { reportInteraction('grafana_traces_query_type_changed', { datasourceType: 'tempo', app: app ?? '', grafana_version: config.buildInfo.version, newQueryType: v, previousQueryType: query.queryType ?? '', }); this.onClearResults(); onChange({ ...query, queryType: v, }); }} size="md" /> {query.queryType === 'traceqlSearch' && ( )} {query.queryType === 'serviceMap' && ( )} {query.queryType === 'traceql' && ( )} ); } } const TempoQueryField = withTheme2(TempoQueryFieldComponent); export default TempoQueryField;