mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch: Display dynamic label field in case feature is enabled (#48614)
* move metrics editor related files to a separate folder * cleanup * add tests * remove snapshot test * nit * remove unsued import * remove snapshot
This commit is contained in:
parent
66d7105b34
commit
0d60b1ce0a
@ -6,9 +6,10 @@ import { Input } from '@grafana/ui';
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
onChange: (alias: any) => void;
|
onChange: (alias: any) => void;
|
||||||
value: string;
|
value: string;
|
||||||
|
id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Alias: FunctionComponent<Props> = ({ value = '', onChange }) => {
|
export const Alias: FunctionComponent<Props> = ({ value = '', onChange, id }) => {
|
||||||
const [alias, setAlias] = useState(value);
|
const [alias, setAlias] = useState(value);
|
||||||
|
|
||||||
const propagateOnChange = debounce(onChange, 1500);
|
const propagateOnChange = debounce(onChange, 1500);
|
||||||
@ -18,5 +19,5 @@ export const Alias: FunctionComponent<Props> = ({ value = '', onChange }) => {
|
|||||||
propagateOnChange(e.target.value);
|
propagateOnChange(e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Input type="text" value={alias} onChange={onChange} aria-label="Optional alias" />;
|
return <Input id={id} type="text" value={alias} onChange={onChange} aria-label="Optional alias" />;
|
||||||
};
|
};
|
@ -1,14 +1,14 @@
|
|||||||
import { render, screen, act } from '@testing-library/react';
|
import { render, screen, act } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import selectEvent from 'react-select-event';
|
import selectEvent from 'react-select-event';
|
||||||
import renderer from 'react-test-renderer';
|
|
||||||
|
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||||
|
import { config } from '@grafana/runtime';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
import { CustomVariableModel, initialVariableModelState } from '../../../../features/variables/types';
|
import { CustomVariableModel, initialVariableModelState } from '../../../../../features/variables/types';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../../datasource';
|
||||||
import { CloudWatchJsonData, MetricEditorMode, MetricQueryType } from '../types';
|
import { CloudWatchJsonData, MetricEditorMode, MetricQueryType } from '../../types';
|
||||||
|
|
||||||
import { MetricsQueryEditor, Props } from './MetricsQueryEditor';
|
import { MetricsQueryEditor, Props } from './MetricsQueryEditor';
|
||||||
|
|
||||||
@ -70,15 +70,6 @@ const setup = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('QueryEditor', () => {
|
describe('QueryEditor', () => {
|
||||||
it('should render component', async () => {
|
|
||||||
const { act } = renderer;
|
|
||||||
await act(async () => {
|
|
||||||
const props = setup();
|
|
||||||
const tree = renderer.create(<MetricsQueryEditor {...props} />).toJSON();
|
|
||||||
expect(tree).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('should handle editor modes correctly', () => {
|
describe('should handle editor modes correctly', () => {
|
||||||
it('when metric query type is metric search and editor mode is builder', async () => {
|
it('when metric query type is metric search and editor mode is builder', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@ -165,4 +156,48 @@ describe('QueryEditor', () => {
|
|||||||
expect(await screen.findByText('*')).toBeInTheDocument();
|
expect(await screen.findByText('*')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when dynamic labels feature toggle is enabled', () => {
|
||||||
|
it('shoud render label field', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
const props = setup();
|
||||||
|
const originalValue = config.featureToggles.cloudWatchDynamicLabels;
|
||||||
|
config.featureToggles.cloudWatchDynamicLabels = true;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<MetricsQueryEditor
|
||||||
|
{...props}
|
||||||
|
query={{ ...props.query, refId: 'A', alias: 'Period: {{period}} InstanceId: {{InstanceId}}' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText('Label')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Alias')).toBeNull();
|
||||||
|
expect(screen.getByLabelText('Label - optional')).toHaveValue(
|
||||||
|
"Period: ${PROP('Period')} InstanceId: ${PROP('Dim.InstanceId')}"
|
||||||
|
);
|
||||||
|
|
||||||
|
config.featureToggles.cloudWatchDynamicLabels = originalValue;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when dynamic labels feature toggle is disabled', () => {
|
||||||
|
it('shoud render alias field', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
const props = setup();
|
||||||
|
const originalValue = config.featureToggles.cloudWatchDynamicLabels;
|
||||||
|
config.featureToggles.cloudWatchDynamicLabels = false;
|
||||||
|
|
||||||
|
const expected = 'Period: {{period}} InstanceId: {{InstanceId}}';
|
||||||
|
render(<MetricsQueryEditor {...props} query={{ ...props.query, refId: 'A', alias: expected }} />);
|
||||||
|
|
||||||
|
expect(await screen.getByText('Alias')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Label')).toBeNull();
|
||||||
|
expect(screen.getByLabelText('Alias - optional')).toHaveValue(expected);
|
||||||
|
|
||||||
|
config.featureToggles.cloudWatchDynamicLabels = originalValue;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
@ -2,10 +2,12 @@ import React, { ChangeEvent, useState } from 'react';
|
|||||||
|
|
||||||
import { QueryEditorProps } from '@grafana/data';
|
import { QueryEditorProps } from '@grafana/data';
|
||||||
import { EditorField, EditorRow, Space } from '@grafana/experimental';
|
import { EditorField, EditorRow, Space } from '@grafana/experimental';
|
||||||
|
import { config } from '@grafana/runtime';
|
||||||
import { Input } from '@grafana/ui';
|
import { Input } from '@grafana/ui';
|
||||||
|
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { MathExpressionQueryField, MetricStatEditor, SQLBuilderEditor, SQLCodeEditor } from '../';
|
||||||
import { isCloudWatchMetricsQuery } from '../guards';
|
import { CloudWatchDatasource } from '../../datasource';
|
||||||
|
import { isCloudWatchMetricsQuery } from '../../guards';
|
||||||
import {
|
import {
|
||||||
CloudWatchJsonData,
|
CloudWatchJsonData,
|
||||||
CloudWatchMetricsQuery,
|
CloudWatchMetricsQuery,
|
||||||
@ -13,13 +15,12 @@ import {
|
|||||||
MetricEditorMode,
|
MetricEditorMode,
|
||||||
MetricQueryType,
|
MetricQueryType,
|
||||||
MetricStat,
|
MetricStat,
|
||||||
} from '../types';
|
} from '../../types';
|
||||||
|
import QueryHeader from '../QueryHeader';
|
||||||
|
|
||||||
import QueryHeader from './QueryHeader';
|
import { Alias } from './Alias';
|
||||||
import usePreparedMetricsQuery from './usePreparedMetricsQuery';
|
import usePreparedMetricsQuery from './usePreparedMetricsQuery';
|
||||||
|
|
||||||
import { Alias, MathExpressionQueryField, MetricStatEditor, SQLBuilderEditor, SQLCodeEditor } from './';
|
|
||||||
|
|
||||||
export interface Props extends QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData> {
|
export interface Props extends QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData> {
|
||||||
query: CloudWatchMetricsQuery;
|
query: CloudWatchMetricsQuery;
|
||||||
}
|
}
|
||||||
@ -130,6 +131,24 @@ export const MetricsQueryEditor = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
</EditorField>
|
</EditorField>
|
||||||
|
|
||||||
|
{config.featureToggles.cloudWatchDynamicLabels ? (
|
||||||
|
<EditorField
|
||||||
|
label="Label"
|
||||||
|
width={26}
|
||||||
|
optional
|
||||||
|
tooltip="Change time series legend name using Dynamic labels. See documentation for details."
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
id={`${query.refId}-cloudwatch-metric-query-editor-label`}
|
||||||
|
placeholder="auto"
|
||||||
|
onBlur={onRunQuery}
|
||||||
|
value={preparedQuery.label ?? ''}
|
||||||
|
onChange={(event: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
onChange({ ...preparedQuery, label: event.target.value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EditorField>
|
||||||
|
) : (
|
||||||
<EditorField
|
<EditorField
|
||||||
label="Alias"
|
label="Alias"
|
||||||
width={26}
|
width={26}
|
||||||
@ -137,10 +156,12 @@ export const MetricsQueryEditor = (props: Props) => {
|
|||||||
tooltip="Change time series legend name using this field. See documentation for replacement variable formats."
|
tooltip="Change time series legend name using this field. See documentation for replacement variable formats."
|
||||||
>
|
>
|
||||||
<Alias
|
<Alias
|
||||||
|
id={`${query.refId}-cloudwatch-metric-query-editor-alias`}
|
||||||
value={preparedQuery.alias ?? ''}
|
value={preparedQuery.alias ?? ''}
|
||||||
onChange={(value: string) => onChange({ ...preparedQuery, alias: value })}
|
onChange={(value: string) => onChange({ ...preparedQuery, alias: value })}
|
||||||
/>
|
/>
|
||||||
</EditorField>
|
</EditorField>
|
||||||
|
)}
|
||||||
</EditorRow>
|
</EditorRow>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
@ -2,8 +2,8 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
|
|
||||||
import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource';
|
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource';
|
||||||
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types';
|
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../../types';
|
||||||
|
|
||||||
import MetricsQueryHeader from './MetricsQueryHeader';
|
import MetricsQueryHeader from './MetricsQueryHeader';
|
||||||
|
|
@ -4,8 +4,8 @@ import { SelectableValue } from '@grafana/data';
|
|||||||
import { InlineSelect, FlexItem } from '@grafana/experimental';
|
import { InlineSelect, FlexItem } from '@grafana/experimental';
|
||||||
import { Button, ConfirmModal, RadioButtonGroup } from '@grafana/ui';
|
import { Button, ConfirmModal, RadioButtonGroup } from '@grafana/ui';
|
||||||
|
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../../datasource';
|
||||||
import { CloudWatchMetricsQuery, CloudWatchQuery, MetricEditorMode, MetricQueryType } from '../types';
|
import { CloudWatchMetricsQuery, CloudWatchQuery, MetricEditorMode, MetricQueryType } from '../../types';
|
||||||
|
|
||||||
interface MetricsQueryHeaderProps {
|
interface MetricsQueryHeaderProps {
|
||||||
query: CloudWatchMetricsQuery;
|
query: CloudWatchMetricsQuery;
|
@ -1,6 +1,6 @@
|
|||||||
import { renderHook } from '@testing-library/react-hooks';
|
import { renderHook } from '@testing-library/react-hooks';
|
||||||
|
|
||||||
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types';
|
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../../types';
|
||||||
|
|
||||||
import usePreparedMetricsQuery, { DEFAULT_QUERY } from './usePreparedMetricsQuery';
|
import usePreparedMetricsQuery, { DEFAULT_QUERY } from './usePreparedMetricsQuery';
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
import deepEqual from 'fast-deep-equal';
|
import deepEqual from 'fast-deep-equal';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
import { migrateMetricQuery } from '../migrations/metricQueryMigrations';
|
import { migrateMetricQuery } from '../../migrations/metricQueryMigrations';
|
||||||
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types';
|
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../../types';
|
||||||
|
|
||||||
export const DEFAULT_QUERY: Omit<CloudWatchMetricsQuery, 'refId'> = {
|
export const DEFAULT_QUERY: Omit<CloudWatchMetricsQuery, 'refId'> = {
|
||||||
queryMode: 'Metrics',
|
queryMode: 'Metrics',
|
@ -6,8 +6,8 @@ import { CloudWatchDatasource } from '../datasource';
|
|||||||
import { isCloudWatchMetricsQuery } from '../guards';
|
import { isCloudWatchMetricsQuery } from '../guards';
|
||||||
import { CloudWatchJsonData, CloudWatchQuery } from '../types';
|
import { CloudWatchJsonData, CloudWatchQuery } from '../types';
|
||||||
|
|
||||||
|
import { MetricsQueryEditor } from '././MetricsQueryEditor/MetricsQueryEditor';
|
||||||
import LogsQueryEditor from './LogsQueryEditor';
|
import LogsQueryEditor from './LogsQueryEditor';
|
||||||
import { MetricsQueryEditor } from './MetricsQueryEditor';
|
|
||||||
|
|
||||||
export type Props = QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData>;
|
export type Props = QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData>;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { CloudWatchDatasource } from '../datasource';
|
|||||||
import { useRegions } from '../hooks';
|
import { useRegions } from '../hooks';
|
||||||
import { CloudWatchQuery, CloudWatchQueryMode } from '../types';
|
import { CloudWatchQuery, CloudWatchQueryMode } from '../types';
|
||||||
|
|
||||||
import MetricsQueryHeader from './MetricsQueryHeader';
|
import MetricsQueryHeader from './MetricsQueryEditor/MetricsQueryHeader';
|
||||||
|
|
||||||
interface QueryHeaderProps {
|
interface QueryHeaderProps {
|
||||||
query: CloudWatchQuery;
|
query: CloudWatchQuery;
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`QueryEditor should render component 1`] = `null`;
|
|
@ -1,6 +1,5 @@
|
|||||||
export { Dimensions } from './Dimensions/Dimensions';
|
export { Dimensions } from './Dimensions/Dimensions';
|
||||||
export { QueryInlineField, QueryField } from './Forms';
|
export { QueryInlineField, QueryField } from './Forms';
|
||||||
export { Alias } from './Alias';
|
|
||||||
export { PanelQueryEditor } from './PanelQueryEditor';
|
export { PanelQueryEditor } from './PanelQueryEditor';
|
||||||
export { CloudWatchLogsQueryEditor } from './LogsQueryEditor';
|
export { CloudWatchLogsQueryEditor } from './LogsQueryEditor';
|
||||||
export { MetricStatEditor } from './MetricStatEditor';
|
export { MetricStatEditor } from './MetricStatEditor';
|
||||||
|
Loading…
Reference in New Issue
Block a user