mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 05:29:42 -06:00
CloudWatch: Fetch Dimension keys correctly from Dimension Picker (#78556)
This commit is contained in:
parent
faa29db241
commit
931c8e99b9
@ -149,7 +149,7 @@ describe('VariableEditor', () => {
|
||||
// change filter key
|
||||
const keySelect = screen.getByRole('combobox', { name: 'Dimensions filter key' });
|
||||
// confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter
|
||||
await select(keySelect, 'v4', {
|
||||
select(keySelect, 'v4', {
|
||||
container: document.body,
|
||||
});
|
||||
expect(ds.datasource.resources.getDimensionKeys).toHaveBeenCalledWith({
|
||||
@ -158,14 +158,16 @@ describe('VariableEditor', () => {
|
||||
metricName: 'i3',
|
||||
dimensionFilters: undefined,
|
||||
});
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
...defaultQuery,
|
||||
queryType: VariableQueryType.DimensionValues,
|
||||
namespace: 'z2',
|
||||
region: 'a1',
|
||||
metricName: 'i3',
|
||||
dimensionKey: 's4',
|
||||
dimensionFilters: { v4: undefined },
|
||||
await waitFor(() => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
...defaultQuery,
|
||||
queryType: VariableQueryType.DimensionValues,
|
||||
namespace: 'z2',
|
||||
region: 'a1',
|
||||
metricName: 'i3',
|
||||
dimensionKey: 's4',
|
||||
dimensionFilters: { v4: undefined },
|
||||
});
|
||||
});
|
||||
|
||||
// set filter value
|
||||
|
@ -37,12 +37,11 @@ const queryTypes: Array<{ value: string; label: string }> = [
|
||||
export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
const parsedQuery = migrateVariableQuery(query);
|
||||
|
||||
const { region, namespace, metricName, dimensionKey, dimensionFilters } = parsedQuery;
|
||||
const { region, namespace, metricName, dimensionKey } = parsedQuery;
|
||||
const [regions, regionIsLoading] = useRegions(datasource);
|
||||
const namespaces = useNamespaces(datasource);
|
||||
const metrics = useMetrics(datasource, { region, namespace });
|
||||
const dimensionKeys = useDimensionKeys(datasource, { region, namespace, metricName });
|
||||
const keysForDimensionFilter = useDimensionKeys(datasource, { region, namespace, metricName, dimensionFilters });
|
||||
const accountState = useAccountOptions(datasource.resources, query.region);
|
||||
|
||||
const newFormStylingEnabled = config.featureToggles.awsDatasourcesNewFormStyling;
|
||||
@ -188,7 +187,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
onChange={(dimensions) => {
|
||||
onChange({ ...parsedQuery, dimensionFilters: dimensions });
|
||||
}}
|
||||
dimensionKeys={keysForDimensionFilter}
|
||||
disableExpressions={true}
|
||||
datasource={datasource}
|
||||
/>
|
||||
@ -205,7 +203,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
onChange={(dimensions) => {
|
||||
onChange({ ...parsedQuery, dimensionFilters: dimensions });
|
||||
}}
|
||||
dimensionKeys={keysForDimensionFilter}
|
||||
disableExpressions={true}
|
||||
datasource={datasource}
|
||||
/>
|
||||
|
@ -43,8 +43,8 @@ describe('Dimensions', () => {
|
||||
InstanceId: '*',
|
||||
InstanceGroup: 'Group1',
|
||||
};
|
||||
render(<Dimensions {...props} metricStat={props.query} dimensionKeys={[]} />);
|
||||
const filterItems = screen.getAllByTestId('cloudwatch-dimensions-filter-item');
|
||||
render(<Dimensions {...props} metricStat={props.query} />);
|
||||
const filterItems = await screen.findAllByTestId('cloudwatch-dimensions-filter-item');
|
||||
expect(filterItems.length).toBe(2);
|
||||
|
||||
expect(within(filterItems[0]).getByText('InstanceId')).toBeInTheDocument();
|
||||
@ -61,8 +61,8 @@ describe('Dimensions', () => {
|
||||
InstanceId: ['*'],
|
||||
InstanceGroup: ['Group1'],
|
||||
};
|
||||
render(<Dimensions {...props} metricStat={props.query} dimensionKeys={[]} />);
|
||||
const filterItems = screen.getAllByTestId('cloudwatch-dimensions-filter-item');
|
||||
render(<Dimensions {...props} metricStat={props.query} />);
|
||||
const filterItems = await screen.findAllByTestId('cloudwatch-dimensions-filter-item');
|
||||
expect(filterItems.length).toBe(2);
|
||||
|
||||
expect(within(filterItems[0]).getByText('InstanceId')).toBeInTheDocument();
|
||||
@ -77,7 +77,7 @@ describe('Dimensions', () => {
|
||||
it('it should add the new item but not call onChange', async () => {
|
||||
props.query.dimensions = {};
|
||||
const onChange = jest.fn();
|
||||
render(<Dimensions {...props} metricStat={props.query} onChange={onChange} dimensionKeys={[]} />);
|
||||
render(<Dimensions {...props} metricStat={props.query} onChange={onChange} />);
|
||||
|
||||
await userEvent.click(screen.getByLabelText('Add'));
|
||||
expect(screen.getByTestId('cloudwatch-dimensions-filter-item')).toBeInTheDocument();
|
||||
@ -89,9 +89,7 @@ describe('Dimensions', () => {
|
||||
it('it should add the new item but not call onChange', async () => {
|
||||
props.query.dimensions = {};
|
||||
const onChange = jest.fn();
|
||||
const { container } = render(
|
||||
<Dimensions {...props} metricStat={props.query} onChange={onChange} dimensionKeys={[]} />
|
||||
);
|
||||
const { container } = render(<Dimensions {...props} metricStat={props.query} onChange={onChange} />);
|
||||
|
||||
await userEvent.click(screen.getByLabelText('Add'));
|
||||
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
|
||||
@ -109,9 +107,7 @@ describe('Dimensions', () => {
|
||||
it('it should add the new item and trigger onChange', async () => {
|
||||
props.query.dimensions = {};
|
||||
const onChange = jest.fn();
|
||||
const { container } = render(
|
||||
<Dimensions {...props} metricStat={props.query} onChange={onChange} dimensionKeys={[]} />
|
||||
);
|
||||
const { container } = render(<Dimensions {...props} metricStat={props.query} onChange={onChange} />);
|
||||
|
||||
const label = await screen.findByLabelText('Add');
|
||||
await userEvent.click(label);
|
||||
@ -128,11 +124,8 @@ describe('Dimensions', () => {
|
||||
expect(valueElement).toBeInTheDocument();
|
||||
await userEvent.type(valueElement!, 'my-value');
|
||||
fireEvent.keyDown(valueElement!, { keyCode: 13 });
|
||||
expect(onChange).not.toHaveBeenCalledWith({
|
||||
...props.query,
|
||||
dimensions: {
|
||||
'my-key': 'my-value',
|
||||
},
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
'my-key': 'my-value',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { EditorList } from '@grafana/experimental';
|
||||
|
||||
import { CloudWatchDatasource } from '../../../datasource';
|
||||
@ -13,7 +12,6 @@ export interface Props {
|
||||
metricStat: MetricStat;
|
||||
onChange: (dimensions: DimensionsType) => void;
|
||||
datasource: CloudWatchDatasource;
|
||||
dimensionKeys: Array<SelectableValue<string>>;
|
||||
disableExpressions: boolean;
|
||||
}
|
||||
|
||||
@ -62,7 +60,7 @@ const filterConditionsToDimensions = (filters: DimensionFilterCondition[]) => {
|
||||
}, {});
|
||||
};
|
||||
|
||||
export const Dimensions = ({ metricStat, datasource, dimensionKeys, disableExpressions, onChange }: Props) => {
|
||||
export const Dimensions = ({ metricStat, datasource, disableExpressions, onChange }: Props) => {
|
||||
const dimensionFilters = useMemo(() => dimensionsToFilterConditions(metricStat.dimensions), [metricStat.dimensions]);
|
||||
const [items, setItems] = useState<DimensionFilterCondition[]>(dimensionFilters);
|
||||
const onDimensionsChange = (newItems: Array<Partial<DimensionFilterCondition>>) => {
|
||||
@ -80,17 +78,12 @@ export const Dimensions = ({ metricStat, datasource, dimensionKeys, disableExpre
|
||||
<EditorList
|
||||
items={items}
|
||||
onChange={onDimensionsChange}
|
||||
renderItem={makeRenderFilter(datasource, metricStat, dimensionKeys, disableExpressions)}
|
||||
renderItem={makeRenderFilter(datasource, metricStat, disableExpressions)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function makeRenderFilter(
|
||||
datasource: CloudWatchDatasource,
|
||||
metricStat: MetricStat,
|
||||
dimensionKeys: Array<SelectableValue<string>>,
|
||||
disableExpressions: boolean
|
||||
) {
|
||||
function makeRenderFilter(datasource: CloudWatchDatasource, metricStat: MetricStat, disableExpressions: boolean) {
|
||||
function renderFilter(
|
||||
item: DimensionFilterCondition,
|
||||
onChange: (item: DimensionFilterCondition) => void,
|
||||
@ -103,7 +96,6 @@ function makeRenderFilter(
|
||||
datasource={datasource}
|
||||
metricStat={metricStat}
|
||||
disableExpressions={disableExpressions}
|
||||
dimensionKeys={dimensionKeys}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
);
|
||||
|
@ -0,0 +1,53 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { setupMockedDataSource } from '../../../__mocks__/CloudWatchDataSource';
|
||||
import { CloudWatchMetricsQuery } from '../../../types';
|
||||
|
||||
import { FilterItem } from './FilterItem';
|
||||
|
||||
const ds = setupMockedDataSource({
|
||||
variables: [],
|
||||
});
|
||||
|
||||
const q: CloudWatchMetricsQuery = {
|
||||
id: '',
|
||||
region: 'us-east-2',
|
||||
namespace: '',
|
||||
period: '',
|
||||
alias: '',
|
||||
metricName: '',
|
||||
dimensions: { foo: 'bar', abc: 'xyz' },
|
||||
matchExact: true,
|
||||
statistic: '',
|
||||
expression: '',
|
||||
refId: '',
|
||||
};
|
||||
|
||||
describe('Dimensions', () => {
|
||||
it('should call getDimensionKeys without the current key', async () => {
|
||||
const getDimensionKeys = jest.fn().mockResolvedValue([]);
|
||||
ds.datasource.resources.getDimensionKeys = getDimensionKeys;
|
||||
const currFilter = { key: 'foo', value: 'bar' };
|
||||
|
||||
render(
|
||||
<FilterItem
|
||||
metricStat={q}
|
||||
datasource={ds.datasource}
|
||||
filter={currFilter}
|
||||
disableExpressions={true}
|
||||
onChange={jest.fn()}
|
||||
onDelete={jest.fn()}
|
||||
/>
|
||||
);
|
||||
await userEvent.click(screen.getByLabelText('Dimensions filter key'));
|
||||
expect(getDimensionKeys).toHaveBeenCalledWith({
|
||||
namespace: q.namespace,
|
||||
region: q.region,
|
||||
metricName: q.metricName,
|
||||
accountId: q.accountId,
|
||||
dimensionFilters: { abc: ['xyz'] },
|
||||
});
|
||||
});
|
||||
});
|
@ -7,6 +7,7 @@ import { AccessoryButton, InputGroup } from '@grafana/experimental';
|
||||
import { Select, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { CloudWatchDatasource } from '../../../datasource';
|
||||
import { useDimensionKeys } from '../../../hooks';
|
||||
import { Dimensions, MetricStat } from '../../../types';
|
||||
import { appendTemplateVariables } from '../../../utils/utils';
|
||||
|
||||
@ -16,7 +17,6 @@ export interface Props {
|
||||
metricStat: MetricStat;
|
||||
datasource: CloudWatchDatasource;
|
||||
filter: DimensionFilterCondition;
|
||||
dimensionKeys: Array<SelectableValue<string>>;
|
||||
disableExpressions: boolean;
|
||||
onChange: (value: DimensionFilterCondition) => void;
|
||||
onDelete: () => void;
|
||||
@ -32,19 +32,16 @@ const excludeCurrentKey = (dimensions: Dimensions, currentKey: string | undefine
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
export const FilterItem = ({
|
||||
filter,
|
||||
metricStat: { region, namespace, metricName, dimensions, accountId },
|
||||
datasource,
|
||||
dimensionKeys,
|
||||
disableExpressions,
|
||||
onChange,
|
||||
onDelete,
|
||||
}: Props) => {
|
||||
export const FilterItem = ({ filter, metricStat, datasource, disableExpressions, onChange, onDelete }: Props) => {
|
||||
const { region, namespace, metricName, dimensions, accountId } = metricStat;
|
||||
const dimensionsExcludingCurrentKey = useMemo(
|
||||
() => excludeCurrentKey(dimensions ?? {}, filter.key),
|
||||
[dimensions, filter]
|
||||
);
|
||||
const dimensionKeys = useDimensionKeys(datasource, {
|
||||
...metricStat,
|
||||
dimensionFilters: dimensionsExcludingCurrentKey,
|
||||
});
|
||||
|
||||
const loadDimensionValues = async () => {
|
||||
if (!filter.key) {
|
||||
|
@ -6,7 +6,7 @@ import { config } from '@grafana/runtime';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { CloudWatchDatasource } from '../../../datasource';
|
||||
import { useAccountOptions, useDimensionKeys, useMetrics, useNamespaces } from '../../../hooks';
|
||||
import { useAccountOptions, useMetrics, useNamespaces } from '../../../hooks';
|
||||
import { standardStatistics } from '../../../standardStatistics';
|
||||
import { MetricStat } from '../../../types';
|
||||
import { appendTemplateVariables, toOption } from '../../../utils/utils';
|
||||
@ -35,7 +35,6 @@ export const MetricStatEditor = ({
|
||||
}: React.PropsWithChildren<Props>) => {
|
||||
const namespaces = useNamespaces(datasource);
|
||||
const metrics = useMetrics(datasource, metricStat);
|
||||
const dimensionKeys = useDimensionKeys(datasource, { ...metricStat, dimensionFilters: metricStat.dimensions });
|
||||
const accountState = useAccountOptions(datasource.resources, metricStat.region);
|
||||
|
||||
useEffect(() => {
|
||||
@ -139,7 +138,6 @@ export const MetricStatEditor = ({
|
||||
<Dimensions
|
||||
metricStat={metricStat}
|
||||
onChange={(dimensions) => onChange({ ...metricStat, dimensions })}
|
||||
dimensionKeys={dimensionKeys}
|
||||
disableExpressions={disableExpressions}
|
||||
datasource={datasource}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user