import React, { useEffect, useMemo } from 'react'; import { SelectableValue, toOption } from '@grafana/data'; import { EditorField, EditorFieldGroup, EditorSwitch } from '@grafana/experimental'; import { Select } from '@grafana/ui'; import { STATISTICS } from '../../cloudwatch-sql/language'; import { CloudWatchDatasource } from '../../datasource'; import { useDimensionKeys, useMetrics, useNamespaces } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; import { getMetricNameFromExpression, getNamespaceFromExpression, getSchemaLabelKeys as getSchemaLabels, isUsingWithSchema, removeMetricName, setAggregation, setMetricName, setNamespace, setSchemaLabels, setWithSchema, stringArrayToDimensions, } from './utils'; interface SQLBuilderSelectRowProps { query: CloudWatchMetricsQuery; datasource: CloudWatchDatasource; onQueryChange: (query: CloudWatchMetricsQuery) => void; } const AGGREGATIONS = STATISTICS.map(toOption); const SQLBuilderSelectRow: React.FC = ({ datasource, query, onQueryChange }) => { const sql = query.sql ?? {}; const aggregation = sql.select?.name; useEffect(() => { if (!aggregation) { onQueryChange(setAggregation(query, STATISTICS[0])); } }, [aggregation, onQueryChange, query]); const metricName = getMetricNameFromExpression(sql.select); const namespace = getNamespaceFromExpression(sql.from); const schemaLabels = getSchemaLabels(sql.from); const withSchemaEnabled = isUsingWithSchema(sql.from); const namespaceOptions = useNamespaces(datasource); const metricOptions = useMetrics(datasource, query.region, namespace); const existingFilters = useMemo(() => stringArrayToDimensions(schemaLabels ?? []), [schemaLabels]); const unusedDimensionKeys = useDimensionKeys(datasource, { region: query.region, namespace, metricName, dimensionFilters: existingFilters, }); const dimensionKeys = useMemo( () => (schemaLabels?.length ? [...unusedDimensionKeys, ...schemaLabels.map(toOption)] : unusedDimensionKeys), [unusedDimensionKeys, schemaLabels] ); const onNamespaceChange = async (query: CloudWatchMetricsQuery) => { const validatedQuery = await validateMetricName(query); onQueryChange(validatedQuery); }; const validateMetricName = async (query: CloudWatchMetricsQuery) => { let { region, sql } = query; await datasource.api.getMetrics(query.namespace, region).then((result: Array>) => { if (!result.some((metric) => metric.value === metricName)) { sql = removeMetricName(query).sql; } }); return { ...query, sql }; }; return ( <> item && onQueryChange(setSchemaLabels(query, item))} /> )} value && onQueryChange(setAggregation(query, value))} /> ); }; export default SQLBuilderSelectRow;