import React, { useMemo, useState } from 'react'; import { SelectableValue, toOption } from '@grafana/data'; import { AccessoryButton, EditorList, InputGroup } from '@grafana/experimental'; import { Select } from '@grafana/ui'; import { CloudWatchDatasource } from '../../datasource'; import { QueryEditorExpressionType, QueryEditorGroupByExpression, QueryEditorPropertyType } from '../../expressions'; import { useDimensionKeys } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; import { getFlattenedGroupBys, getMetricNameFromExpression, getNamespaceFromExpression, setGroupByField, setSql, } from './utils'; interface SQLGroupByProps { query: CloudWatchMetricsQuery; datasource: CloudWatchDatasource; onQueryChange: (query: CloudWatchMetricsQuery) => void; } const SQLGroupBy: React.FC = ({ query, datasource, onQueryChange }) => { const sql = query.sql ?? {}; const groupBysFromQuery = useMemo(() => getFlattenedGroupBys(query.sql ?? {}), [query.sql]); const [items, setItems] = useState(groupBysFromQuery); const namespace = getNamespaceFromExpression(sql.from); const metricName = getMetricNameFromExpression(sql.select); const baseOptions = useDimensionKeys(datasource, query.region, namespace, metricName); const options = useMemo( // Exclude options we've already selected () => baseOptions.filter((option) => !groupBysFromQuery.some((v) => v.property.name === option.value)), [baseOptions, groupBysFromQuery] ); const onChange = (newItems: Array>) => { // As new (empty object) items come in, with need to make sure they have the correct type const cleaned = newItems.map( (v): QueryEditorGroupByExpression => ({ type: QueryEditorExpressionType.GroupBy, property: { type: QueryEditorPropertyType.String, name: v.property?.name, }, }) ); setItems(cleaned); // Only save complete expressions into the query state; const completeExpressions = cleaned.filter((v) => v.property?.name); const groupBy = completeExpressions.length ? { type: QueryEditorExpressionType.And as const, expressions: completeExpressions, } : undefined; onQueryChange(setSql(query, { groupBy })); }; return ; }; function makeRenderItem(options: Array>) { function renderItem( item: Partial, onChange: (item: QueryEditorGroupByExpression) => void, onDelete: () => void ) { return ; } return renderItem; } interface GroupByItemProps { options: Array>; item: Partial; onChange: (item: QueryEditorGroupByExpression) => void; onDelete: () => void; } const GroupByItem: React.FC = (props) => { const { options, item, onChange, onDelete } = props; const fieldName = item.property?.name; return (