Compare commits

...

3 Commits

Author SHA1 Message Date
Andrew Hackmann
6d3353f11b prettier? 2025-12-17 15:38:23 -06:00
Andrew Hackmann
5c29e4190a missed save 2025-12-16 16:21:10 -06:00
Andrew Hackmann
813e7b173c The builder query no longer runs if code mode query is empty. Remove checks for query being empty to run raw query. 2025-12-16 16:17:28 -06:00
8 changed files with 107 additions and 7 deletions

View File

@@ -24,7 +24,7 @@ func (e *elasticsearchDataQuery) processQuery(q *Query, ms *es.MultiSearchReques
filters.AddDateRangeFilter(defaultTimeField, to, from, es.DateFormatEpochMS)
filters.AddQueryStringFilter(q.RawQuery, true)
if q.EditorType != nil && *q.EditorType == "code" && q.RawDSLQuery != "" {
if q.EditorType != nil && *q.EditorType == "code" {
cfg := backend.GrafanaConfigFromContext(e.ctx)
if !cfg.FeatureToggles().IsEnabled("elasticsearchRawDSLQuery") {
return backend.DownstreamError(fmt.Errorf("raw DSL query feature is disabled. Enable the elasticsearchRawDSLQuery feature toggle to use this query type"))

View File

@@ -7,7 +7,7 @@ import (
// isQueryWithError validates the query and returns an error if invalid
func isQueryWithError(query *Query) error {
// Skip validation for raw DSL queries because no easy way to see it is valid without just running it
if query.EditorType != nil && *query.EditorType == "code" && query.RawDSLQuery != "" {
if query.EditorType != nil && *query.EditorType == "code" {
return nil
}
if len(query.BucketAggs) == 0 {

View File

@@ -7,7 +7,7 @@ import {
import { defaultBucketAgg } from '../../../../queryDef';
import { reducerTester } from '../../../reducerTester';
import { changeMetricType } from '../../MetricAggregationsEditor/state/actions';
import { initQuery } from '../../state';
import { changeEditorTypeAndResetQuery, initQuery } from '../../state';
import { bucketAggregationConfig } from '../utils';
import {
@@ -180,4 +180,27 @@ describe('Bucket Aggregations Reducer', () => {
.thenStateShouldEqual([bucketAgg]);
});
});
describe('When switching editor type', () => {
it('Should reset bucket aggregations to default when switching editor types', () => {
const defaultTimeField = '@timestamp';
const initialState: BucketAggregation[] = [
{
id: '1',
type: 'date_histogram',
field: '@timestamp',
},
{
id: '2',
type: 'terms',
field: 'status',
},
];
reducerTester<ElasticsearchDataQuery['bucketAggs']>()
.givenReducer(createReducer(defaultTimeField), initialState)
.whenActionIsDispatched(changeEditorTypeAndResetQuery('code'))
.thenStateShouldEqual([{ ...defaultBucketAgg('2'), field: defaultTimeField }]);
});
});
});

View File

@@ -6,7 +6,7 @@ import { defaultBucketAgg } from '../../../../queryDef';
import { removeEmpty } from '../../../../utils';
import { changeMetricType } from '../../MetricAggregationsEditor/state/actions';
import { metricAggregationConfig } from '../../MetricAggregationsEditor/utils';
import { initQuery } from '../../state';
import { changeEditorTypeAndResetQuery, initQuery } from '../../state';
import { bucketAggregationConfig } from '../utils';
import {
@@ -87,6 +87,11 @@ export const createReducer =
return state;
}
if (changeEditorTypeAndResetQuery.match(action)) {
// Returns the default bugcket agg. We will always want to set the default when switching types
return [{ ...defaultBucketAgg('2'), field: defaultTimeField }];
}
if (changeBucketAggregationSetting.match(action)) {
return state!.map((bucketAgg) => {
if (bucketAgg.id !== action.payload.bucketAgg.id) {

View File

@@ -7,7 +7,7 @@ import {
import { defaultMetricAgg } from '../../../../queryDef';
import { reducerTester } from '../../../reducerTester';
import { initQuery } from '../../state';
import { changeEditorTypeAndResetQuery, initQuery } from '../../state';
import { metricAggregationConfig } from '../utils';
import {
@@ -248,4 +248,26 @@ describe('Metric Aggregations Reducer', () => {
.whenActionIsDispatched(initQuery())
.thenStateShouldEqual([defaultMetricAgg('1')]);
});
describe('When switching editor type', () => {
it('Should reset to single default metric when switching to code editor', () => {
const initialState: MetricAggregation[] = [
{
id: '1',
type: 'avg',
field: 'value',
},
{
id: '2',
type: 'max',
field: 'value',
},
];
reducerTester<ElasticsearchDataQuery['metrics']>()
.givenReducer(reducer, initialState)
.whenActionIsDispatched(changeEditorTypeAndResetQuery('code'))
.thenStateShouldEqual([defaultMetricAgg('1')]);
});
});
});

View File

@@ -4,7 +4,7 @@ import { ElasticsearchDataQuery, MetricAggregation } from 'app/plugins/datasourc
import { defaultMetricAgg, queryTypeToMetricType } from '../../../../queryDef';
import { removeEmpty } from '../../../../utils';
import { initQuery } from '../../state';
import { changeEditorTypeAndResetQuery, initQuery } from '../../state';
import { isMetricAggregationWithMeta, isMetricAggregationWithSettings, isPipelineAggregation } from '../aggregations';
import { getChildren, metricAggregationConfig } from '../utils';
@@ -65,6 +65,11 @@ export const reducer = (
});
}
if (changeEditorTypeAndResetQuery.match(action)) {
// Reset to default metric when switching to editor types
return [defaultMetricAgg('1')];
}
if (changeMetricField.match(action)) {
return state!.map((metric) => {
if (metric.id !== action.payload.id) {

View File

@@ -1,7 +1,15 @@
import { ElasticsearchDataQuery } from '../../dataquery.gen';
import { reducerTester } from '../reducerTester';
import { aliasPatternReducer, changeAliasPattern, changeQuery, initQuery, queryReducer } from './state';
import {
aliasPatternReducer,
changeAliasPattern,
changeEditorTypeAndResetQuery,
changeQuery,
initQuery,
queryReducer,
rawDSLQueryReducer,
} from './state';
describe('Query Reducer', () => {
describe('On Init', () => {
@@ -42,6 +50,17 @@ describe('Query Reducer', () => {
.whenActionIsDispatched({ type: 'THIS ACTION SHOULD NOT HAVE ANY EFFECT IN THIS REDUCER' })
.thenStateShouldEqual(initialState);
});
describe('When switching editor type', () => {
it('Should clear query when switching editor types', () => {
const initialQuery: ElasticsearchDataQuery['query'] = 'Some lucene query';
reducerTester<ElasticsearchDataQuery['query']>()
.givenReducer(queryReducer, initialQuery)
.whenActionIsDispatched(changeEditorTypeAndResetQuery('code'))
.thenStateShouldEqual('');
});
});
});
describe('Alias Pattern Reducer', () => {
@@ -62,4 +81,26 @@ describe('Alias Pattern Reducer', () => {
.whenActionIsDispatched({ type: 'THIS ACTION SHOULD NOT HAVE ANY EFFECT IN THIS REDUCER' })
.thenStateShouldEqual(initialState);
});
describe('When switching editor type', () => {
it('Should clear alias when switching editor types', () => {
const initialAlias: ElasticsearchDataQuery['alias'] = 'Some alias pattern';
reducerTester<ElasticsearchDataQuery['alias']>()
.givenReducer(aliasPatternReducer, initialAlias)
.whenActionIsDispatched(changeEditorTypeAndResetQuery('code'))
.thenStateShouldEqual('');
});
});
});
describe('Raw DSL Query Reducer', () => {
it('Should clear raw DSL query when switching editor types', () => {
const initialRawQuery: ElasticsearchDataQuery['rawDSLQuery'] = '{"query": {"match_all": {}}}';
reducerTester<ElasticsearchDataQuery['rawDSLQuery']>()
.givenReducer(rawDSLQueryReducer, initialRawQuery)
.whenActionIsDispatched(changeEditorTypeAndResetQuery('builder'))
.thenStateShouldEqual('');
});
});

View File

@@ -58,6 +58,10 @@ export const aliasPatternReducer = (prevAliasPattern: ElasticsearchDataQuery['al
return action.payload;
}
if (changeEditorTypeAndResetQuery.match(action)) {
return '';
}
if (initQuery.match(action)) {
return prevAliasPattern || '';
}