Files

159 lines
4.2 KiB
TypeScript

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<string>;
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<Props>) {
const [state, setState] = useState<State>(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 (
<>
<Project
refId={refId}
templateVariableOptions={variableOptionGroup.options}
projectName={projectName}
datasource={datasource}
onChange={(projectName) => {
onChange({ ...query, projectName });
}}
/>
{editorMode === EditorMode.Visual && (
<VisualMetricQueryEditor
refId={refId}
labels={state.labels}
variableOptionGroup={variableOptionGroup}
customMetaData={customMetaData}
onMetricTypeChange={onMetricTypeChange}
onChange={onChange}
datasource={datasource}
query={query}
/>
)}
{editorMode === EditorMode.MQL && (
<>
<MQLQueryEditor
onChange={(q: string) => onQueryChange({ ...query, query: q })}
onRunQuery={onRunQuery}
query={query.query}
></MQLQueryEditor>
<GraphPeriod
onChange={(graphPeriod: string) => onQueryChange({ ...query, graphPeriod })}
graphPeriod={query.graphPeriod}
refId={refId}
variableOptionGroup={variableOptionGroup}
/>
</>
)}
<AliasBy
refId={refId}
value={query.aliasBy}
onChange={(aliasBy) => {
onChange({ ...query, aliasBy });
}}
/>
</>
);
}
export const MetricQueryEditor = React.memo(Editor);