mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
add experimental slo query editor (#51351)
This commit is contained in:
parent
c12d1727f0
commit
396278a6e5
@ -0,0 +1,56 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const SLO: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
const [slos, setSLOs] = useState<Array<SelectableValue<string>>>([]);
|
||||
const { projectName, serviceId } = query;
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectName || !serviceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
datasource.getServiceLevelObjectives(projectName, serviceId).then((sloIds: Array<SelectableValue<string>>) => {
|
||||
setSLOs([
|
||||
{
|
||||
label: 'Template Variables',
|
||||
options: templateVariableOptions,
|
||||
},
|
||||
...sloIds,
|
||||
]);
|
||||
});
|
||||
}, [datasource, projectName, serviceId, templateVariableOptions]);
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="SLO" htmlFor={`${refId}-slo`}>
|
||||
<Select
|
||||
inputId={`${refId}-slo`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={query?.sloId && { value: query?.sloId, label: query?.sloName || query?.sloId }}
|
||||
placeholder="Select SLO"
|
||||
options={slos}
|
||||
onChange={async ({ value: sloId = '', label: sloName = '' }) => {
|
||||
const slos = await datasource.getServiceLevelObjectives(projectName, serviceId);
|
||||
const slo = slos.find(({ value }) => value === datasource.templateSrv.replace(sloId));
|
||||
onChange({ ...query, sloId, sloName, goal: slo?.goal });
|
||||
}}
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
);
|
||||
};
|
@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { EditorField, EditorFieldGroup, EditorRow, Stack } from '@grafana/experimental';
|
||||
|
||||
import { Project } from '..';
|
||||
import { ALIGNMENT_PERIODS } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { AlignmentTypes, CustomMetaData, SLOQuery } from '../../types';
|
||||
|
||||
import { AliasBy } from './AliasBy';
|
||||
import { AlignmentPeriodLabel } from './AlignmentPeriodLabel';
|
||||
import { PeriodSelect } from './PeriodSelect';
|
||||
import { SLO } from './SLO';
|
||||
import { Selector } from './Selector';
|
||||
import { Service } from './Service';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
customMetaData: CustomMetaData;
|
||||
variableOptionGroup: SelectableValue<string>;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
onRunQuery: () => void;
|
||||
query: SLOQuery;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const defaultQuery: (dataSource: CloudMonitoringDatasource) => SLOQuery = (dataSource) => ({
|
||||
projectName: dataSource.getDefaultProject(),
|
||||
alignmentPeriod: 'cloud-monitoring-auto',
|
||||
perSeriesAligner: AlignmentTypes.ALIGN_MEAN,
|
||||
aliasBy: '',
|
||||
selectorName: 'select_slo_health',
|
||||
serviceId: '',
|
||||
serviceName: '',
|
||||
sloId: '',
|
||||
sloName: '',
|
||||
});
|
||||
|
||||
export function SLOQueryEditor({
|
||||
refId,
|
||||
query,
|
||||
datasource,
|
||||
onChange,
|
||||
variableOptionGroup,
|
||||
customMetaData,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<>
|
||||
<Project
|
||||
refId={refId}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
projectName={query.projectName}
|
||||
datasource={datasource}
|
||||
onChange={(projectName) => onChange({ ...query, projectName })}
|
||||
/>
|
||||
<Service
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<SLO
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Selector
|
||||
refId={refId}
|
||||
datasource={datasource}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
/>
|
||||
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
<EditorField label="Alignment period">
|
||||
<PeriodSelect
|
||||
inputId={`${refId}-alignment-period`}
|
||||
templateVariableOptions={variableOptionGroup.options}
|
||||
current={query.alignmentPeriod}
|
||||
onChange={(period) => onChange({ ...query, alignmentPeriod: period })}
|
||||
aligmentPeriods={ALIGNMENT_PERIODS}
|
||||
/>
|
||||
</EditorField>
|
||||
<Stack alignItems="flex-end">
|
||||
<AlignmentPeriodLabel datasource={datasource} customMetaData={customMetaData} />
|
||||
</Stack>
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
|
||||
<AliasBy refId={refId} value={query.aliasBy} onChange={(aliasBy) => onChange({ ...query, aliasBy })} />
|
||||
</>
|
||||
);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH, SELECTORS } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const Selector: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
return (
|
||||
<QueryEditorRow label="Selector" htmlFor={`${refId}-slo-selector`}>
|
||||
<Select
|
||||
inputId={`${refId}-slo-selector`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={[...SELECTORS, ...templateVariableOptions].find((s) => s.value === query?.selectorName ?? '')}
|
||||
options={[
|
||||
{
|
||||
label: 'Template Variables',
|
||||
options: templateVariableOptions,
|
||||
},
|
||||
...SELECTORS,
|
||||
]}
|
||||
onChange={({ value: selectorName }) => onChange({ ...query, selectorName: selectorName ?? '' })}
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
);
|
||||
};
|
@ -0,0 +1,54 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { QueryEditorRow } from '..';
|
||||
import { SELECT_WIDTH } from '../../constants';
|
||||
import CloudMonitoringDatasource from '../../datasource';
|
||||
import { SLOQuery } from '../../types';
|
||||
|
||||
export interface Props {
|
||||
refId: string;
|
||||
onChange: (query: SLOQuery) => void;
|
||||
query: SLOQuery;
|
||||
templateVariableOptions: Array<SelectableValue<string>>;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
}
|
||||
|
||||
export const Service: React.FC<Props> = ({ refId, query, templateVariableOptions, onChange, datasource }) => {
|
||||
const [services, setServices] = useState<Array<SelectableValue<string>>>([]);
|
||||
const { projectName } = query;
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectName) {
|
||||
return;
|
||||
}
|
||||
|
||||
datasource.getSLOServices(projectName).then((services: Array<SelectableValue<string>>) => {
|
||||
setServices([
|
||||
{
|
||||
label: 'Template Variables',
|
||||
options: templateVariableOptions,
|
||||
},
|
||||
...services,
|
||||
]);
|
||||
});
|
||||
}, [datasource, projectName, templateVariableOptions]);
|
||||
|
||||
return (
|
||||
<QueryEditorRow label="Service" htmlFor={`${refId}-slo-service`}>
|
||||
<Select
|
||||
inputId={`${refId}-slo-service`}
|
||||
width={SELECT_WIDTH}
|
||||
allowCustomValue
|
||||
value={query?.serviceId && { value: query?.serviceId, label: query?.serviceName || query?.serviceId }}
|
||||
placeholder="Select service"
|
||||
options={services}
|
||||
onChange={({ value: serviceId = '', label: serviceName = '' }) =>
|
||||
onChange({ ...query, serviceId, serviceName, sloId: '' })
|
||||
}
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
);
|
||||
};
|
@ -12,6 +12,7 @@ import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery, Clo
|
||||
|
||||
import { MetricQueryEditor as ExperimentalMetricQueryEditor } from './Experimental/MetricQueryEditor';
|
||||
import { QueryHeader } from './Experimental/QueryHeader';
|
||||
import { SLOQueryEditor as ExperimentalSLOQueryEditor } from './Experimental/SLOQueryEditor';
|
||||
import { defaultQuery } from './MetricQueryEditor';
|
||||
import { defaultQuery as defaultSLOQuery } from './SLO/SLOQueryEditor';
|
||||
|
||||
@ -82,7 +83,7 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
)}
|
||||
|
||||
{queryType === QueryType.SLO && (
|
||||
<SLOQueryEditor
|
||||
<ExperimentalSLOQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
|
Loading…
Reference in New Issue
Block a user