grafana/public/app/plugins/datasource/cloudwatch/components/QueryFieldsEditor.tsx
Erik Sundell a35b2ac463
CloudWatch: Annotation Editor rewrite (#20765)
* wip: react rewrite

* Cleanup

* Break out non annontations specific fields

* Cleanup. Make annontations editor a functional component

* Remove redundant classnames

* Add paneldata to props

* Cleanup

* Fix rebase merge problem

* Updates after pr feedback

* Fix conflict with master
2020-01-15 16:38:15 +01:00

145 lines
4.6 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { SelectableValue } from '@grafana/data';
import { Segment, SegmentAsync } from '@grafana/ui';
import { CloudWatchQuery, SelectableStrings } from '../types';
import CloudWatchDatasource from '../datasource';
import { Stats, Dimensions, QueryInlineField } from './';
export type Props = {
query: CloudWatchQuery;
datasource: CloudWatchDatasource;
onRunQuery?: () => void;
onChange: (value: CloudWatchQuery) => void;
hideWilcard?: boolean;
};
interface State {
regions: SelectableStrings;
namespaces: SelectableStrings;
metricNames: SelectableStrings;
variableOptionGroup: SelectableValue<string>;
showMeta: boolean;
}
export function QueryFieldsEditor({
query,
datasource,
onChange,
onRunQuery = () => {},
hideWilcard = false,
}: React.PropsWithChildren<Props>) {
const [state, setState] = useState<State>({
regions: [],
namespaces: [],
metricNames: [],
variableOptionGroup: {},
showMeta: false,
});
useEffect(() => {
const variableOptionGroup = {
label: 'Template Variables',
options: datasource.variables.map(toOption),
};
Promise.all([datasource.metricFindQuery('regions()'), datasource.metricFindQuery('namespaces()')]).then(
([regions, namespaces]) => {
setState({
...state,
regions: [...regions, variableOptionGroup],
namespaces: [...namespaces, variableOptionGroup],
variableOptionGroup,
});
}
);
}, []);
const loadMetricNames = async () => {
const { namespace, region } = query;
return datasource.metricFindQuery(`metrics(${namespace},${region})`).then(appendTemplateVariables);
};
const appendTemplateVariables = (values: SelectableValue[]) => [
...values,
{ label: 'Template Variables', options: datasource.variables.map(toOption) },
];
const toOption = (value: any) => ({ label: value, value });
const onQueryChange = (query: CloudWatchQuery) => {
onChange(query);
onRunQuery();
};
// Load dimension values based on current selected dimensions.
// Remove the new dimension key and all dimensions that has a wildcard as selected value
const loadDimensionValues = (newKey: string) => {
const { [newKey]: value, ...dim } = query.dimensions;
const newDimensions = Object.entries(dim).reduce(
(result, [key, value]) => (value === '*' ? result : { ...result, [key]: value }),
{}
);
return datasource
.getDimensionValues(query.region, query.namespace, query.metricName, newKey, newDimensions)
.then(values => (values.length ? [{ value: '*', text: '*', label: '*' }, ...values] : values))
.then(appendTemplateVariables);
};
const { regions, namespaces, variableOptionGroup } = state;
return (
<>
<QueryInlineField label="Region">
<Segment
value={query.region}
placeholder="Select region"
options={regions}
allowCustomValue
onChange={({ value: region }) => onChange({ ...query, region })}
/>
</QueryInlineField>
{query.expression.length === 0 && (
<>
<QueryInlineField label="Namespace">
<Segment
value={query.namespace}
placeholder="Select namespace"
allowCustomValue
options={namespaces}
onChange={({ value: namespace }) => onChange({ ...query, namespace })}
/>
</QueryInlineField>
<QueryInlineField label="Metric Name">
<SegmentAsync
value={query.metricName}
placeholder="Select metric name"
allowCustomValue
loadOptions={loadMetricNames}
onChange={({ value: metricName }) => onChange({ ...query, metricName })}
/>
</QueryInlineField>
<QueryInlineField label="Stats">
<Stats
stats={datasource.standardStatistics.map(toOption)}
values={query.statistics}
onChange={statistics => onQueryChange({ ...query, statistics })}
variableOptionGroup={variableOptionGroup}
/>
</QueryInlineField>
<QueryInlineField label="Dimensions">
<Dimensions
dimensions={query.dimensions}
onChange={dimensions => onQueryChange({ ...query, dimensions })}
loadKeys={() => datasource.getDimensionKeys(query.namespace, query.region).then(appendTemplateVariables)}
loadValues={loadDimensionValues}
/>
</QueryInlineField>
</>
)}
</>
);
}