import React, { useState, useEffect, useCallback } from 'react'; import { SelectableValue } from '@grafana/data'; import { Project, VisualMetricQueryEditor, AliasBy } from '.'; import { MetricQuery, MetricDescriptor, EditorMode, MetricKind, PreprocessorType, AlignmentTypes, CustomMetaData, ValueTypes, SLOQuery, } from '../types'; import { getAlignmentPickerData } from '../functions'; import CloudMonitoringDatasource from '../datasource'; import { MQLQueryEditor } from './MQLQueryEditor'; export interface Props { refId: string; customMetaData: CustomMetaData; variableOptionGroup: SelectableValue; onChange: (query: MetricQuery) => void; onRunQuery: () => void; query: MetricQuery; datasource: CloudMonitoringDatasource; } interface State { labels: any; [key: string]: any; } export const defaultState: State = { labels: {}, }; export const defaultQuery: (dataSource: CloudMonitoringDatasource) => MetricQuery = (dataSource) => ({ editorMode: EditorMode.Visual, projectName: dataSource.getDefaultProject(), metricType: '', metricKind: MetricKind.GAUGE, valueType: '', crossSeriesReducer: 'REDUCE_MEAN', alignmentPeriod: 'cloud-monitoring-auto', perSeriesAligner: AlignmentTypes.ALIGN_MEAN, groupBys: [], filters: [], aliasBy: '', query: '', preprocessor: PreprocessorType.None, }); function Editor({ refId, query, datasource, onChange: onQueryChange, onRunQuery, customMetaData, variableOptionGroup, }: React.PropsWithChildren) { const [state, setState] = useState(defaultState); const { projectName, metricType, groupBys, editorMode } = query; useEffect(() => { if (projectName && metricType) { datasource .getLabels(metricType, refId, projectName, groupBys) .then((labels) => setState((prevState) => ({ ...prevState, labels }))); } }, [datasource, groupBys, metricType, projectName, refId]); const onChange = useCallback( (metricQuery: MetricQuery | SLOQuery) => { onQueryChange({ ...query, ...metricQuery }); onRunQuery(); }, [onQueryChange, onRunQuery, query] ); const onMetricTypeChange = useCallback( ({ valueType, metricKind, type }: MetricDescriptor) => { const preprocessor = metricKind === MetricKind.GAUGE || valueType === ValueTypes.DISTRIBUTION ? PreprocessorType.None : PreprocessorType.Rate; const { perSeriesAligner } = getAlignmentPickerData(valueType, metricKind, state.perSeriesAligner, preprocessor); onChange({ ...query, perSeriesAligner, metricType: type, valueType, metricKind, preprocessor, }); }, [onChange, query, state] ); return ( <> { onChange({ ...query, projectName }); }} /> {editorMode === EditorMode.Visual && ( )} {editorMode === EditorMode.MQL && ( onQueryChange({ ...query, query: q })} onRunQuery={onRunQuery} query={query.query} > )} { onChange({ ...query, aliasBy }); }} /> ); } export const MetricQueryEditor = React.memo(Editor);