import React, { useCallback, useEffect, useState } from 'react'; import { SelectableValue } from '@grafana/data'; import CloudMonitoringDatasource from '../datasource'; import { getAlignmentPickerData } from '../functions'; import { AlignmentTypes, CustomMetaData, EditorMode, MetricDescriptor, MetricKind, MetricQuery, PreprocessorType, SLOQuery, ValueTypes, } from '../types'; import { GraphPeriod } from './GraphPeriod'; import { MQLQueryEditor } from './MQLQueryEditor'; import { AliasBy, Project, VisualMetricQueryEditor } from '.'; 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, crossSeriesReducer } = query; useEffect(() => { if (projectName && metricType) { datasource .getLabels(metricType, refId, projectName) .then((labels) => setState((prevState) => ({ ...prevState, labels }))); } }, [datasource, groupBys, metricType, projectName, refId, crossSeriesReducer]); 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} > onQueryChange({ ...query, graphPeriod })} graphPeriod={query.graphPeriod} refId={refId} variableOptionGroup={variableOptionGroup} /> )} { onChange({ ...query, aliasBy }); }} /> ); } export const MetricQueryEditor = React.memo(Editor);