mirror of
https://github.com/grafana/grafana.git
synced 2025-02-09 23:16:16 -06:00
add query header (#51072)
This commit is contained in:
parent
3273588cc0
commit
d8d1ca8151
@ -1,4 +1,4 @@
|
||||
import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType } from '../types';
|
||||
import { AlignmentTypes, CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery } from '../types';
|
||||
|
||||
export const createMockMetricQuery: (overrides?: Partial<MetricQuery>) => MetricQuery = (
|
||||
overrides?: Partial<MetricQuery>
|
||||
@ -13,12 +13,29 @@ export const createMockMetricQuery: (overrides?: Partial<MetricQuery>) => Metric
|
||||
};
|
||||
};
|
||||
|
||||
export const createMockQuery: () => CloudMonitoringQuery = () => {
|
||||
export const createMockSLOQuery: (overrides?: Partial<SLOQuery>) => SLOQuery = (overrides) => {
|
||||
return {
|
||||
projectName: 'projectName',
|
||||
alignmentPeriod: 'cloud-monitoring-auto',
|
||||
perSeriesAligner: AlignmentTypes.ALIGN_MEAN,
|
||||
aliasBy: '',
|
||||
selectorName: 'select_slo_health',
|
||||
serviceId: '',
|
||||
serviceName: '',
|
||||
sloId: '',
|
||||
sloName: '',
|
||||
...overrides,
|
||||
};
|
||||
};
|
||||
|
||||
export const createMockQuery: (overrides?: Partial<CloudMonitoringQuery>) => CloudMonitoringQuery = (overrides) => {
|
||||
return {
|
||||
refId: 'cloudMonitoringRefId',
|
||||
queryType: QueryType.METRICS,
|
||||
intervalMs: 0,
|
||||
type: 'timeSeriesQuery',
|
||||
metricQuery: createMockMetricQuery(),
|
||||
...overrides,
|
||||
metricQuery: createMockMetricQuery(overrides?.metricQuery),
|
||||
sloQuery: createMockSLOQuery(overrides?.sloQuery),
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,107 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { openMenu, select } from 'react-select-event';
|
||||
|
||||
import { createMockQuery, createMockSLOQuery } from '../../__mocks__/cloudMonitoringQuery';
|
||||
import { EditorMode, QueryType } from '../../types';
|
||||
|
||||
import { QueryHeader } from './QueryHeader';
|
||||
|
||||
describe('QueryHeader', () => {
|
||||
it('renders an editor mode radio group if query type is a metric query', () => {
|
||||
const query = createMockQuery();
|
||||
const { metricQuery } = query;
|
||||
const sloQuery = createMockSLOQuery();
|
||||
const onChange = jest.fn();
|
||||
const onRunQuery = jest.fn();
|
||||
|
||||
render(
|
||||
<QueryHeader
|
||||
query={query}
|
||||
metricQuery={metricQuery}
|
||||
sloQuery={sloQuery}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(/Query type/)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('Builder')).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('MQL')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render an editor mode radio group if query type is a SLO query', () => {
|
||||
const query = createMockQuery({ queryType: QueryType.SLO });
|
||||
const { metricQuery } = query;
|
||||
const sloQuery = createMockSLOQuery();
|
||||
const onChange = jest.fn();
|
||||
const onRunQuery = jest.fn();
|
||||
|
||||
render(
|
||||
<QueryHeader
|
||||
query={query}
|
||||
metricQuery={metricQuery}
|
||||
sloQuery={sloQuery}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(/Query type/)).toBeInTheDocument();
|
||||
expect(screen.queryByLabelText('Builder')).not.toBeInTheDocument();
|
||||
expect(screen.queryByLabelText('MQL')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('can change query types', async () => {
|
||||
const query = createMockQuery();
|
||||
const { metricQuery } = query;
|
||||
const sloQuery = createMockSLOQuery();
|
||||
const onChange = jest.fn();
|
||||
const onRunQuery = jest.fn();
|
||||
|
||||
render(
|
||||
<QueryHeader
|
||||
query={query}
|
||||
metricQuery={metricQuery}
|
||||
sloQuery={sloQuery}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
);
|
||||
|
||||
const queryType = screen.getByLabelText(/Query type/);
|
||||
await openMenu(queryType);
|
||||
await select(screen.getByLabelText('Select options menu'), 'Service Level Objectives (SLO)');
|
||||
expect(onChange).toBeCalledWith(expect.objectContaining({ queryType: QueryType.SLO }));
|
||||
});
|
||||
|
||||
it('can change editor modes when query is a metric query type', async () => {
|
||||
const query = createMockQuery();
|
||||
const { metricQuery } = query;
|
||||
const sloQuery = createMockSLOQuery();
|
||||
const onChange = jest.fn();
|
||||
const onRunQuery = jest.fn();
|
||||
|
||||
render(
|
||||
<QueryHeader
|
||||
query={query}
|
||||
metricQuery={metricQuery}
|
||||
sloQuery={sloQuery}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
);
|
||||
|
||||
const builder = screen.getByLabelText('Builder');
|
||||
const MQL = screen.getByLabelText('MQL');
|
||||
expect(builder).toBeChecked();
|
||||
expect(MQL).not.toBeChecked();
|
||||
|
||||
await userEvent.click(MQL);
|
||||
|
||||
expect(onChange).toBeCalledWith(
|
||||
expect.objectContaining({ metricQuery: expect.objectContaining({ editorMode: EditorMode.MQL }) })
|
||||
);
|
||||
});
|
||||
});
|
@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
|
||||
import { EditorHeader, FlexItem, InlineSelect } from '@grafana/experimental';
|
||||
import { RadioButtonGroup } from '@grafana/ui';
|
||||
|
||||
import { QUERY_TYPES } from '../../constants';
|
||||
import { EditorMode, CloudMonitoringQuery, QueryType, SLOQuery, MetricQuery } from '../../types';
|
||||
|
||||
export interface QueryEditorHeaderProps {
|
||||
query: CloudMonitoringQuery;
|
||||
metricQuery: MetricQuery;
|
||||
sloQuery: SLOQuery;
|
||||
onChange: (value: CloudMonitoringQuery) => void;
|
||||
onRunQuery: () => void;
|
||||
}
|
||||
|
||||
const EDITOR_MODES = [
|
||||
{ label: 'Builder', value: EditorMode.Visual },
|
||||
{ label: 'MQL', value: EditorMode.MQL },
|
||||
];
|
||||
|
||||
export const QueryHeader = (props: QueryEditorHeaderProps) => {
|
||||
const { query, metricQuery, sloQuery, onChange, onRunQuery } = props;
|
||||
const { queryType } = query;
|
||||
const { editorMode } = metricQuery;
|
||||
|
||||
return (
|
||||
<EditorHeader>
|
||||
<InlineSelect
|
||||
label="Query type"
|
||||
options={QUERY_TYPES}
|
||||
value={queryType}
|
||||
onChange={({ value }) => {
|
||||
onChange({ ...query, sloQuery, queryType: value! });
|
||||
onRunQuery();
|
||||
}}
|
||||
/>
|
||||
<FlexItem grow={1} />
|
||||
{queryType !== QueryType.SLO && (
|
||||
<RadioButtonGroup
|
||||
size="sm"
|
||||
options={EDITOR_MODES}
|
||||
value={editorMode || EditorMode.Visual}
|
||||
onChange={(value) => {
|
||||
onChange({
|
||||
...query,
|
||||
metricQuery: {
|
||||
...metricQuery,
|
||||
editorMode: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</EditorHeader>
|
||||
);
|
||||
};
|
@ -11,6 +11,7 @@ import CloudMonitoringDatasource from '../datasource';
|
||||
import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery, CloudMonitoringOptions } from '../types';
|
||||
|
||||
import { MetricQueryEditor as ExperimentalMetricQueryEditor } from './Experimental/MetricQueryEditor';
|
||||
import { QueryHeader } from './Experimental/QueryHeader';
|
||||
import { defaultQuery } from './MetricQueryEditor';
|
||||
import { defaultQuery as defaultSLOQuery } from './SLO/SLOQueryEditor';
|
||||
|
||||
@ -57,7 +58,42 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
options: datasource.getVariables().map(toOption),
|
||||
};
|
||||
|
||||
return (
|
||||
return config.featureToggles.cloudMonitoringExperimentalUI ? (
|
||||
<EditorRows>
|
||||
<QueryHeader
|
||||
query={query}
|
||||
metricQuery={metricQuery}
|
||||
sloQuery={sloQuery}
|
||||
onChange={onChange}
|
||||
onRunQuery={onRunQuery}
|
||||
/>
|
||||
{queryType === QueryType.METRICS && (
|
||||
<ExperimentalMetricQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(metricQuery: MetricQuery) => {
|
||||
this.props.onChange({ ...this.props.query, metricQuery });
|
||||
}}
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={metricQuery}
|
||||
/>
|
||||
)}
|
||||
|
||||
{queryType === QueryType.SLO && (
|
||||
<SLOQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(query: SLOQuery) => this.onQueryChange('sloQuery', query)}
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={sloQuery}
|
||||
/>
|
||||
)}
|
||||
</EditorRows>
|
||||
) : (
|
||||
<EditorRows>
|
||||
<QueryEditorRow
|
||||
label="Query type"
|
||||
@ -94,32 +130,19 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
/>
|
||||
</QueryEditorRow>
|
||||
|
||||
{queryType === QueryType.METRICS &&
|
||||
(config.featureToggles.cloudMonitoringExperimentalUI ? (
|
||||
<ExperimentalMetricQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(metricQuery: MetricQuery) => {
|
||||
this.props.onChange({ ...this.props.query, metricQuery });
|
||||
}}
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={metricQuery}
|
||||
/>
|
||||
) : (
|
||||
<MetricQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(metricQuery: MetricQuery) => {
|
||||
this.props.onChange({ ...this.props.query, metricQuery });
|
||||
}}
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={metricQuery}
|
||||
/>
|
||||
))}
|
||||
{queryType === QueryType.METRICS && (
|
||||
<MetricQueryEditor
|
||||
refId={query.refId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
customMetaData={customMetaData}
|
||||
onChange={(metricQuery: MetricQuery) => {
|
||||
this.props.onChange({ ...this.props.query, metricQuery });
|
||||
}}
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={metricQuery}
|
||||
/>
|
||||
)}
|
||||
|
||||
{queryType === QueryType.SLO && (
|
||||
<SLOQueryEditor
|
||||
@ -130,7 +153,7 @@ export class QueryEditor extends PureComponent<Props> {
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={sloQuery}
|
||||
></SLOQueryEditor>
|
||||
/>
|
||||
)}
|
||||
</EditorRows>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user