Elasticsearch query editor: ensure unique ids on labelled fields (#74396)

This commit is contained in:
Matias Chomicki 2023-09-06 10:17:11 +02:00 committed by GitHub
parent 79b421e8c8
commit c3cbe220bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 11 deletions

View File

@ -1,12 +1,11 @@
import { uniqueId } from 'lodash'; import { uniqueId } from 'lodash';
import React, { ComponentProps, useRef, useState } from 'react'; import React, { ComponentProps, useId, useRef, useState } from 'react';
import { InlineField, Input, InlineSwitch, Select } from '@grafana/ui'; import { InlineField, Input, InlineSwitch, Select } from '@grafana/ui';
import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { useDispatch } from '../../../../hooks/useStatelessReducer';
import { extendedStats } from '../../../../queryDef'; import { extendedStats } from '../../../../queryDef';
import { MetricAggregation, ExtendedStat } from '../../../../types'; import { MetricAggregation, ExtendedStat } from '../../../../types';
import { useQuery } from '../../ElasticsearchQueryContext';
import { SettingsEditorContainer } from '../../SettingsEditorContainer'; import { SettingsEditorContainer } from '../../SettingsEditorContainer';
import { isMetricAggregationWithInlineScript, isMetricAggregationWithMissingSupport } from '../aggregations'; import { isMetricAggregationWithInlineScript, isMetricAggregationWithMissingSupport } from '../aggregations';
import { changeMetricMeta, changeMetricSetting } from '../state/actions'; import { changeMetricMeta, changeMetricSetting } from '../state/actions';
@ -33,7 +32,10 @@ export const SettingsEditor = ({ metric, previousMetrics }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const description = useDescription(metric); const description = useDescription(metric);
const query = useQuery();
const sizeFieldId = useId();
const unitFieldId = useId();
const modeFieldId = useId();
const rateAggUnitOptions = [ const rateAggUnitOptions = [
{ value: 'second', label: 'Second' }, { value: 'second', label: 'Second' },
@ -76,9 +78,9 @@ export const SettingsEditor = ({ metric, previousMetrics }: Props) => {
)} )}
{(metric.type === 'raw_data' || metric.type === 'raw_document') && ( {(metric.type === 'raw_data' || metric.type === 'raw_document') && (
<InlineField label="Size" {...inlineFieldProps}> <InlineField label="Size" {...inlineFieldProps} htmlFor={sizeFieldId}>
<Input <Input
id={`ES-query-${query.refId}_metric-${metric.id}-size`} id={sizeFieldId}
onBlur={(e) => dispatch(changeMetricSetting({ metric, settingName: 'size', newValue: e.target.value }))} onBlur={(e) => dispatch(changeMetricSetting({ metric, settingName: 'size', newValue: e.target.value }))}
defaultValue={metric.settings?.size ?? metricAggregationConfig['raw_data'].defaults.settings?.size} defaultValue={metric.settings?.size ?? metricAggregationConfig['raw_data'].defaults.settings?.size}
/> />
@ -133,18 +135,18 @@ export const SettingsEditor = ({ metric, previousMetrics }: Props) => {
{metric.type === 'rate' && ( {metric.type === 'rate' && (
<> <>
<InlineField label="Unit" {...inlineFieldProps} data-testid="unit-select"> <InlineField label="Unit" {...inlineFieldProps} data-testid="unit-select" htmlFor={unitFieldId}>
<Select <Select
id={`ES-query-${query.refId}_metric-${metric.id}-unit`} id={unitFieldId}
onChange={(e) => dispatch(changeMetricSetting({ metric, settingName: 'unit', newValue: e.value }))} onChange={(e) => dispatch(changeMetricSetting({ metric, settingName: 'unit', newValue: e.value }))}
options={rateAggUnitOptions} options={rateAggUnitOptions}
value={metric.settings?.unit} value={metric.settings?.unit}
/> />
</InlineField> </InlineField>
<InlineField label="Mode" {...inlineFieldProps} data-testid="mode-select"> <InlineField label="Mode" {...inlineFieldProps} data-testid="mode-select" htmlFor={modeFieldId}>
<Select <Select
id={`ES-query-${query.refId}_metric-${metric.id}-mode`} id={modeFieldId}
onChange={(e) => dispatch(changeMetricSetting({ metric, settingName: 'mode', newValue: e.value }))} onChange={(e) => dispatch(changeMetricSetting({ metric, settingName: 'mode', newValue: e.value }))}
options={rateAggModeOptions} options={rateAggModeOptions}
value={metric.settings?.unit} value={metric.settings?.unit}

View File

@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useId, useState } from 'react';
import { SemVer } from 'semver'; import { SemVer } from 'semver';
import { getDefaultTimeRange, GrafanaTheme2, QueryEditorProps } from '@grafana/data'; import { getDefaultTimeRange, GrafanaTheme2, QueryEditorProps } from '@grafana/data';
@ -90,6 +90,7 @@ export const ElasticSearchQueryField = ({ value, onChange }: { value?: string; o
const QueryEditorForm = ({ value }: Props) => { const QueryEditorForm = ({ value }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const nextId = useNextId(); const nextId = useNextId();
const inputId = useId();
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const isTimeSeries = isTimeSeriesQuery(value); const isTimeSeries = isTimeSeriesQuery(value);
@ -115,9 +116,10 @@ const QueryEditorForm = ({ value }: Props) => {
label="Alias" label="Alias"
labelWidth={15} labelWidth={15}
tooltip="Aliasing only works for timeseries queries (when the last group is 'Date Histogram'). For all other query types this field is ignored." tooltip="Aliasing only works for timeseries queries (when the last group is 'Date Histogram'). For all other query types this field is ignored."
htmlFor={inputId}
> >
<Input <Input
id={`ES-query-${value.refId}_alias`} id={inputId}
placeholder="Alias Pattern" placeholder="Alias Pattern"
onBlur={(e) => dispatch(changeAliasPattern(e.currentTarget.value))} onBlur={(e) => dispatch(changeAliasPattern(e.currentTarget.value))}
defaultValue={value.alias} defaultValue={value.alias}