mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki Query Builder: ensure unique ids for labelled fields (#74398)
* Loki Query Builder: ensure unique ids for labelled fields * Rename refactored argument
This commit is contained in:
parent
c3cbe220bb
commit
9310bb632e
@ -63,7 +63,7 @@ const createProps = (
|
||||
onChange: jest.fn(),
|
||||
onRunQuery: jest.fn(),
|
||||
index: 1,
|
||||
operationIndex: 1,
|
||||
operationId: '1',
|
||||
query: {
|
||||
labels: [{ op: '=', label: 'foo', value: 'bar' }],
|
||||
operations: [
|
||||
|
@ -15,7 +15,7 @@ import { LokiVisualQuery } from '../types';
|
||||
export function UnwrapParamEditor({
|
||||
onChange,
|
||||
index,
|
||||
operationIndex,
|
||||
operationId,
|
||||
value,
|
||||
query,
|
||||
datasource,
|
||||
@ -27,7 +27,7 @@ export function UnwrapParamEditor({
|
||||
|
||||
return (
|
||||
<Select
|
||||
inputId={getOperationParamId(operationIndex, index)}
|
||||
inputId={getOperationParamId(operationId, index)}
|
||||
onOpenMenu={async () => {
|
||||
// This check is always true, we do it to make typescript happy
|
||||
if (datasource instanceof LokiDatasource) {
|
||||
|
@ -11,7 +11,7 @@ import { PromVisualQuery } from '../types';
|
||||
export function LabelParamEditor({
|
||||
onChange,
|
||||
index,
|
||||
operationIndex,
|
||||
operationId,
|
||||
value,
|
||||
query,
|
||||
datasource,
|
||||
@ -23,7 +23,7 @@ export function LabelParamEditor({
|
||||
|
||||
return (
|
||||
<Select
|
||||
inputId={getOperationParamId(operationIndex, index)}
|
||||
inputId={getOperationParamId(operationId, index)}
|
||||
autoFocus={value === '' ? true : undefined}
|
||||
openMenuOnFocus
|
||||
onOpenMenu={async () => {
|
||||
|
@ -30,7 +30,7 @@ describe('PromQueryBuilderContainer', () => {
|
||||
await userEvent.click(screen.getByTestId('operations.0.add-rest-param'));
|
||||
|
||||
waitFor(() => {
|
||||
expect(container.querySelector(`${getOperationParamId(0, 0)}`)).toBeInTheDocument();
|
||||
expect(container.querySelector(`${getOperationParamId('0', 0)}`)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useId, useState } from 'react';
|
||||
import { Draggable } from 'react-beautiful-dnd';
|
||||
|
||||
import { DataSourceApi, GrafanaTheme2 } from '@grafana/data';
|
||||
@ -46,6 +46,7 @@ export function OperationEditor({
|
||||
}: Props) {
|
||||
const def = queryModeller.getOperationDef(operation.id);
|
||||
const shouldFlash = useFlash(flash);
|
||||
const id = useId();
|
||||
|
||||
const isConflicting =
|
||||
operation.id === LokiOperationId.LabelFilter && isConflictingFilter(operation, query.operations);
|
||||
@ -86,7 +87,7 @@ export function OperationEditor({
|
||||
<div className={styles.paramRow} key={`${paramIndex}-1`}>
|
||||
{!paramDef.hideName && (
|
||||
<div className={styles.paramName}>
|
||||
<label htmlFor={getOperationParamId(index, paramIndex)}>{paramDef.name}</label>
|
||||
<label htmlFor={getOperationParamId(id, paramIndex)}>{paramDef.name}</label>
|
||||
{paramDef.description && (
|
||||
<Tooltip placement="top" content={paramDef.description} theme="info">
|
||||
<Icon name="info-circle" size="sm" className={styles.infoIcon} />
|
||||
@ -101,7 +102,7 @@ export function OperationEditor({
|
||||
paramDef={paramDef}
|
||||
value={operation.params[paramIndex]}
|
||||
operation={operation}
|
||||
operationIndex={index}
|
||||
operationId={id}
|
||||
onChange={onParamValueChanged}
|
||||
onRunQuery={onRunQuery}
|
||||
query={query}
|
||||
|
@ -33,7 +33,7 @@ export function getOperationParamEditor(
|
||||
function SimpleInputParamEditor(props: QueryBuilderOperationParamEditorProps) {
|
||||
return (
|
||||
<AutoSizeInput
|
||||
id={getOperationParamId(props.operationIndex, props.index)}
|
||||
id={getOperationParamId(props.operationId, props.index)}
|
||||
defaultValue={props.value?.toString()}
|
||||
minWidth={props.paramDef.minWidth}
|
||||
placeholder={props.paramDef.placeholder}
|
||||
@ -52,7 +52,7 @@ function SimpleInputParamEditor(props: QueryBuilderOperationParamEditorProps) {
|
||||
function BoolInputParamEditor(props: QueryBuilderOperationParamEditorProps) {
|
||||
return (
|
||||
<Checkbox
|
||||
id={getOperationParamId(props.operationIndex, props.index)}
|
||||
id={getOperationParamId(props.operationId, props.index)}
|
||||
value={props.value as boolean}
|
||||
onChange={(evt) => props.onChange(props.index, evt.currentTarget.checked)}
|
||||
/>
|
||||
@ -63,7 +63,7 @@ function SelectInputParamEditor({
|
||||
paramDef,
|
||||
value,
|
||||
index,
|
||||
operationIndex,
|
||||
operationId,
|
||||
onChange,
|
||||
}: QueryBuilderOperationParamEditorProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
@ -99,7 +99,7 @@ function SelectInputParamEditor({
|
||||
return (
|
||||
<Stack gap={0.5} direction="row" alignItems="center" wrap={false}>
|
||||
<Select
|
||||
id={getOperationParamId(operationIndex, index)}
|
||||
id={getOperationParamId(operationId, index)}
|
||||
value={valueOption}
|
||||
options={selectOptions}
|
||||
placeholder={paramDef.placeholder}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
createAggregationOperation,
|
||||
createAggregationOperationWithParam,
|
||||
getOperationParamId,
|
||||
isConflictingSelector,
|
||||
} from './operationUtils';
|
||||
|
||||
@ -197,3 +198,11 @@ describe('isConflictingSelector', () => {
|
||||
expect(isConflictingSelector(newLabel, labels)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOperationParamId', () => {
|
||||
it('Generates correct id for operation param', () => {
|
||||
const operationId = 'abc';
|
||||
const paramId = 0;
|
||||
expect(getOperationParamId(operationId, paramId)).toBe('operations.abc.param.0');
|
||||
});
|
||||
});
|
||||
|
@ -120,8 +120,8 @@ export function getPromAndLokiOperationDisplayName(funcName: string) {
|
||||
return capitalize(funcName.replace(/_/g, ' '));
|
||||
}
|
||||
|
||||
export function getOperationParamId(operationIndex: number, paramIndex: number) {
|
||||
return `operations.${operationIndex}.param.${paramIndex}`;
|
||||
export function getOperationParamId(operationId: string, paramIndex: number) {
|
||||
return `operations.${operationId}.param.${paramIndex}`;
|
||||
}
|
||||
|
||||
export function getRangeVectorParamDef(withRateInterval = false): QueryBuilderOperationParamDef {
|
||||
|
@ -89,7 +89,7 @@ export interface QueryBuilderOperationParamEditorProps {
|
||||
/** Parameter index */
|
||||
index: number;
|
||||
operation: QueryBuilderOperation;
|
||||
operationIndex: number;
|
||||
operationId: string;
|
||||
query: any;
|
||||
datasource: DataSourceApi;
|
||||
onChange: (index: number, value: QueryBuilderOperationParamValue) => void;
|
||||
|
Loading…
Reference in New Issue
Block a user