diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx
index 5f04a1e7ead..d40bdf7d2c9 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx
@@ -12,11 +12,19 @@ const query: ElasticsearchQuery = {
};
describe('ElasticsearchQueryContext', () => {
- it('Should call onChange with the default query when the query is empty', () => {
+ it('Should call onChange and onRunQuery with the default query when the query is empty', () => {
const datasource = { timeField: 'TIMEFIELD' } as ElasticDatasource;
const onChange = jest.fn();
+ const onRunQuery = jest.fn();
- render();
+ render(
+
+ );
const changedQuery: ElasticsearchQuery = onChange.mock.calls[0][0];
expect(changedQuery.query).toBeDefined();
@@ -26,6 +34,8 @@ describe('ElasticsearchQueryContext', () => {
// Should also set timeField to the configured `timeField` option in datasource configuration
expect(changedQuery.timeField).toBe(datasource.timeField);
+
+ expect(onRunQuery).toHaveBeenCalled();
});
describe('useQuery Hook', () => {
@@ -37,7 +47,12 @@ describe('ElasticsearchQueryContext', () => {
it('Should return the current query object', () => {
const wrapper: FunctionComponent = ({ children }) => (
- {}}>
+ {}}
+ onRunQuery={() => {}}
+ >
{children}
);
@@ -61,7 +76,7 @@ describe('ElasticsearchQueryContext', () => {
const datasource = {} as ElasticDatasource;
const wrapper: FunctionComponent = ({ children }) => (
- {}}>
+ {}} onRunQuery={() => {}}>
{children}
);
diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx
index 8fb94b487ff..d28cf8a9675 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx
@@ -1,4 +1,4 @@
-import React, { createContext, FunctionComponent, useContext } from 'react';
+import React, { createContext, FunctionComponent, useCallback, useContext } from 'react';
import { ElasticDatasource } from '../../datasource';
import { combineReducers, useStatelessReducer, DispatchContext } from '../../hooks/useStatelessReducer';
import { ElasticsearchQuery } from '../../types';
@@ -13,10 +13,25 @@ const QueryContext = createContext(undefined);
interface Props {
query: ElasticsearchQuery;
onChange: (query: ElasticsearchQuery) => void;
+ onRunQuery: () => void;
datasource: ElasticDatasource;
}
-export const ElasticsearchProvider: FunctionComponent = ({ children, onChange, query, datasource }) => {
+export const ElasticsearchProvider: FunctionComponent = ({
+ children,
+ onChange,
+ onRunQuery,
+ query,
+ datasource,
+}) => {
+ const onStateChange = useCallback(
+ (query: ElasticsearchQuery) => {
+ onChange(query);
+ onRunQuery();
+ },
+ [onChange, onRunQuery]
+ );
+
const reducer = combineReducers({
query: queryReducer,
alias: aliasPatternReducer,
@@ -26,7 +41,7 @@ export const ElasticsearchProvider: FunctionComponent = ({ children, onCh
const dispatch = useStatelessReducer(
// timeField is part of the query model, but its value is always set to be the one from datasource settings.
- newState => onChange({ ...query, ...newState, timeField: datasource.timeField }),
+ newState => onStateChange({ ...query, ...newState, timeField: datasource.timeField }),
query,
reducer
);
diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts
index fe6e645d2a3..032696b2828 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts
@@ -150,6 +150,7 @@ interface Logs extends BaseMetricAggregation {
export interface BasePipelineMetricAggregation extends MetricAggregationWithField {
type: PipelineMetricAggregationType;
+ pipelineAgg?: string;
}
interface PipelineMetricAggregationWithMultipleBucketPaths extends BaseMetricAggregation {
diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts
index 70872c96808..293c03efb87 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts
@@ -106,7 +106,7 @@ describe('Metric Aggregations Reducer', () => {
it("Should correctly change aggregation's field", () => {
const firstAggregation: MetricAggregation = {
id: '1',
- type: 'count',
+ type: 'min',
};
const secondAggregation: MetricAggregation = {
id: '2',
@@ -116,12 +116,22 @@ describe('Metric Aggregations Reducer', () => {
const expectedSecondAggregation = {
...secondAggregation,
field: 'new field',
+ pipelineAgg: 'new field',
+ };
+
+ const expectedFirstAggregation = {
+ ...firstAggregation,
+ field: 'new field',
};
reducerTester()
.givenReducer(reducer, [firstAggregation, secondAggregation])
+ // When changing a a pipelineAggregation field we set both pipelineAgg and field
.whenActionIsDispatched(changeMetricField(secondAggregation.id, expectedSecondAggregation.field))
- .thenStateShouldEqual([firstAggregation, expectedSecondAggregation]);
+ .thenStateShouldEqual([firstAggregation, expectedSecondAggregation])
+ // otherwhise only field
+ .whenActionIsDispatched(changeMetricField(firstAggregation.id, expectedFirstAggregation.field))
+ .thenStateShouldEqual([expectedFirstAggregation, expectedSecondAggregation]);
});
it('Should correctly toggle `hide` field', () => {
diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts
index 760bb171cab..e89e586f565 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts
@@ -2,7 +2,12 @@ import { defaultMetricAgg } from '../../../../query_def';
import { ElasticsearchQuery } from '../../../../types';
import { removeEmpty } from '../../../../utils';
import { INIT, InitAction } from '../../state';
-import { isMetricAggregationWithMeta, isMetricAggregationWithSettings, MetricAggregation } from '../aggregations';
+import {
+ isMetricAggregationWithMeta,
+ isMetricAggregationWithSettings,
+ isPipelineAggregation,
+ MetricAggregation,
+} from '../aggregations';
import { getChildren, metricAggregationConfig } from '../utils';
import {
ADD_METRIC,
@@ -64,10 +69,16 @@ export const reducer = (
return metric;
}
- return {
+ const newMetric = {
...metric,
field: action.payload.field,
};
+
+ if (isPipelineAggregation(metric)) {
+ return { ...newMetric, pipelineAgg: action.payload.field };
+ }
+
+ return newMetric;
});
case TOGGLE_METRIC_VISIBILITY:
diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx
index 7ba7551cdd6..917ce74a74e 100644
--- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx
+++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx
@@ -12,8 +12,13 @@ import { useNextId } from '../../hooks/useNextId';
export type ElasticQueryEditorProps = QueryEditorProps;
-export const QueryEditor: FunctionComponent = ({ query, onChange, datasource }) => (
-
+export const QueryEditor: FunctionComponent = ({
+ query,
+ onChange,
+ onRunQuery,
+ datasource,
+}) => (
+
);
diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx
index 8854edbc3c1..2d52a869312 100644
--- a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx
+++ b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx
@@ -13,7 +13,7 @@ describe('useNextId', () => {
};
const wrapper: FunctionComponent = ({ children }) => {
return (
- {}}>
+ {}} onRunQuery={() => {}}>
{children}
);