diff --git a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx index 6660bea5a89..c1b7f86d8d8 100644 --- a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx @@ -23,12 +23,16 @@ interface Props { value?: string; } -export const MetricPicker: FunctionComponent = ({ options, onChange, className, value }) => ( - option.id === value)!) : null} - /> -); +export const MetricPicker: FunctionComponent = ({ options, onChange, className, value }) => { + const selectedOption = options.find((option) => option.id === value); + + return ( + + ); +}; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx index ff5bc5438ca..01a9370ccaa 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx @@ -4,8 +4,9 @@ import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { changeMetricSetting } from '../state/actions'; import { ChangeMetricSettingAction } from '../state/types'; import { SettingKeyOf } from '../../../types'; -import { MetricAggregationWithSettings } from '../aggregations'; +import { MetricAggregationWithInlineScript, MetricAggregationWithSettings } from '../aggregations'; import { uniqueId } from 'lodash'; +import { getScriptValue } from 'app/plugins/datasource/elasticsearch/utils'; interface Props> { label: string; @@ -26,13 +27,19 @@ export function SettingField dispatch(changeMetricSetting(metric, settingName, e.target.value as any))} - defaultValue={settings?.[settingName as keyof typeof settings]} + defaultValue={defaultValue} /> ); 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 b56fedd6480..e833fdf5c56 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts @@ -43,9 +43,10 @@ export interface MetricAggregationWithMissingSupport extends BaseMetricAggregati }; } +type InlineScript = string | { inline?: string }; export interface MetricAggregationWithInlineScript extends BaseMetricAggregation { settings?: { - script?: string; + script?: InlineScript; }; } @@ -59,7 +60,7 @@ export interface Average MetricAggregationWithInlineScript { type: 'avg'; settings?: { - script?: string; + script?: InlineScript; missing?: string; }; } @@ -67,7 +68,7 @@ export interface Average export interface Sum extends MetricAggregationWithField, MetricAggregationWithInlineScript { type: 'sum'; settings?: { - script?: string; + script?: InlineScript; missing?: string; }; } @@ -75,7 +76,7 @@ export interface Sum extends MetricAggregationWithField, MetricAggregationWithIn export interface Max extends MetricAggregationWithField, MetricAggregationWithInlineScript { type: 'max'; settings?: { - script?: string; + script?: InlineScript; missing?: string; }; } @@ -83,7 +84,7 @@ export interface Max extends MetricAggregationWithField, MetricAggregationWithIn export interface Min extends MetricAggregationWithField, MetricAggregationWithInlineScript { type: 'min'; settings?: { - script?: string; + script?: InlineScript; missing?: string; }; } @@ -105,7 +106,7 @@ export interface ExtendedStat { export interface ExtendedStats extends MetricAggregationWithField, MetricAggregationWithInlineScript { type: 'extended_stats'; settings?: { - script?: string; + script?: InlineScript; missing?: string; sigma?: string; }; @@ -118,7 +119,7 @@ export interface Percentiles extends MetricAggregationWithField, MetricAggregati type: 'percentiles'; settings?: { percents?: string[]; - script?: string; + script?: InlineScript; missing?: string; }; } @@ -238,7 +239,7 @@ export interface MovingFunction extends BasePipelineMetricAggregation { type: 'moving_fn'; settings?: { window?: string; - script?: string; + script?: InlineScript; shift?: string; }; } @@ -267,7 +268,7 @@ export interface CumulativeSum extends BasePipelineMetricAggregation { export interface BucketScript extends PipelineMetricAggregationWithMultipleBucketPaths { type: 'bucket_script'; settings?: { - script?: string; + script?: InlineScript; }; } diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 08ce0e6331a..19fccfaf4ed 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -36,6 +36,7 @@ import { bucketAggregationConfig } from './components/QueryEditor/BucketAggregat import { isBucketAggregationWithField } from './components/QueryEditor/BucketAggregationsEditor/aggregations'; import { generate, Observable, of, throwError } from 'rxjs'; import { catchError, first, map, mergeMap, skipWhile, throwIfEmpty } from 'rxjs/operators'; +import { getScriptValue } from './utils'; // Those are metadata fields as defined in https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-fields.html#_identity_metadata_fields. // custom fields can start with underscores, therefore is not safe to exclude anything that starts with one. @@ -425,7 +426,7 @@ export class ElasticDatasource extends DataSourceApi v !== null) - .forEach(([k, v]) => (metricAgg[k] = v)); + .forEach(([k, v]) => { + metricAgg[k] = k === 'script' ? getScriptValue(metric as MetricAggregationWithInlineScript) : v; + }); } aggField[metric.type] = metricAgg; diff --git a/public/app/plugins/datasource/elasticsearch/utils.ts b/public/app/plugins/datasource/elasticsearch/utils.ts index f74195c2c30..ad6de6a7249 100644 --- a/public/app/plugins/datasource/elasticsearch/utils.ts +++ b/public/app/plugins/datasource/elasticsearch/utils.ts @@ -1,6 +1,7 @@ import { isMetricAggregationWithField, MetricAggregation, + MetricAggregationWithInlineScript, } from './components/QueryEditor/MetricAggregationsEditor/aggregations'; import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils'; @@ -62,3 +63,31 @@ export const convertOrderByToMetricId = (orderBy: string): string | undefined => const metricIdMatches = orderBy.match(/^(\d+)/); return metricIdMatches ? metricIdMatches[1] : void 0; }; + +/** Gets the actual script value for metrics that support inline scripts. + * + * This is needed because the `script` is a bit polymorphic. + * when creating a query with Grafana < 7.4 it was stored as: + * ```json + * { + * "settings": { + * "script": { + * "inline": "value" + * } + * } + * } + * ``` + * + * while from 7.4 it's stored as + * ```json + * { + * "settings": { + * "script": "value" + * } + * } + * ``` + * + * This allows us to access both formats and support both queries created before 7.4 and after. + */ +export const getScriptValue = (metric: MetricAggregationWithInlineScript) => + (typeof metric.settings?.script === 'object' ? metric.settings?.script?.inline : metric.settings?.script) || '';