mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: adding query editor when creating threshold rule. (#33123)
* fix viz * add datasource picker on query rows in mixed mode * add timerange, handle add/remove queryrunners * multiqueryrunner test * trying things out. * adding another test to verify running a induvidual query runner will update multirunner. * cleaned up tests a bit. * draft version working ok. * fixing so we base the refId from request targets. * reenable adding expression * layout fixes for alerting page * some cleanup * cleaning up code that we won't use * changed so we don't display the time range if params not passed. * remove unused things in querygroup * changed button to type button. * removed timerange from dataQuery and removed multiquery runner. * minor refactoring. * renamed callback function to make it more clear what it does. * renamed droppable area. * changed so we only display the query editor when selecting threshold. * removed the refresh picker. * revert * wip * extending with data query. * timerange fixes * it is now possible to add grafana queries. * removed unused type. * removed expect import. * added docs. * moved range converting methods to rangeUtil. * clean up some typings, remove file * making sure we don't blow up on component being unmounted. Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import classNames from 'classnames';
|
||||
import { has, cloneDeep } from 'lodash';
|
||||
// Utils & Services
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { AngularComponent, getAngularLoader, getTemplateSrv } from '@grafana/runtime';
|
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { ErrorBoundaryAlert, HorizontalGroup, InfoBox } from '@grafana/ui';
|
||||
import {
|
||||
@@ -36,6 +36,8 @@ interface Props {
|
||||
dsSettings: DataSourceInstanceSettings;
|
||||
id: string;
|
||||
index: number;
|
||||
timeRange?: TimeRange;
|
||||
onChangeTimeRange?: (timeRange: TimeRange) => void;
|
||||
onAddQuery: (query?: DataQuery) => void;
|
||||
onRemoveQuery: (query: DataQuery) => void;
|
||||
onChange: (query: DataQuery) => void;
|
||||
@@ -301,17 +303,18 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
renderTitle = (props: QueryOperationRowRenderProps) => {
|
||||
const { query, dsSettings, onChange, queries } = this.props;
|
||||
const dataSourceName = dsSettings.meta.mixed
|
||||
? getTemplateSrv().replace(this.getQueryDataSourceIdentifier() ?? '')
|
||||
: undefined;
|
||||
const { query, dsSettings, onChange, queries, onChangeTimeRange, timeRange } = this.props;
|
||||
const { datasource } = this.state;
|
||||
const isDisabled = query.hide;
|
||||
|
||||
return (
|
||||
<QueryEditorRowTitle
|
||||
query={query}
|
||||
queries={queries}
|
||||
dataSourceName={dataSourceName}
|
||||
onTimeRangeChange={onChangeTimeRange}
|
||||
timeRange={timeRange}
|
||||
inMixedMode={dsSettings.meta.mixed}
|
||||
dataSourceName={datasource!.name}
|
||||
disabled={isDisabled}
|
||||
onClick={(e) => this.onToggleEditMode(e, props)}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { DataQuery, GrafanaTheme } from '@grafana/data';
|
||||
import { FieldValidationMessage, Icon, Input, stylesFactory, useTheme } from '@grafana/ui';
|
||||
import { DataQuery, DataSourceInstanceSettings, GrafanaTheme, TimeRange } from '@grafana/data';
|
||||
import { DataSourcePicker } from '@grafana/runtime';
|
||||
import { Icon, Input, stylesFactory, useTheme, FieldValidationMessage, TimeRangeInput } from '@grafana/ui';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { ExpressionDatasourceID } from '../../expressions/ExpressionDatasource';
|
||||
|
||||
export interface Props {
|
||||
query: DataQuery;
|
||||
queries: DataQuery[];
|
||||
dataSourceName?: string;
|
||||
dataSourceName: string;
|
||||
inMixedMode?: boolean;
|
||||
disabled?: boolean;
|
||||
timeRange?: TimeRange;
|
||||
onTimeRangeChange?: (timeRange: TimeRange) => void;
|
||||
onChange: (query: DataQuery) => void;
|
||||
onClick: (e: React.MouseEvent) => void;
|
||||
collapsedText: string | null;
|
||||
@@ -16,11 +21,14 @@ export interface Props {
|
||||
|
||||
export const QueryEditorRowTitle: React.FC<Props> = ({
|
||||
dataSourceName,
|
||||
inMixedMode,
|
||||
disabled,
|
||||
query,
|
||||
queries,
|
||||
onClick,
|
||||
onChange,
|
||||
onTimeRangeChange,
|
||||
timeRange,
|
||||
collapsedText,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
@@ -83,6 +91,10 @@ export const QueryEditorRowTitle: React.FC<Props> = ({
|
||||
event.target.select();
|
||||
};
|
||||
|
||||
const onDataSourceChange = (dataSource: DataSourceInstanceSettings) => {
|
||||
onChange({ ...query, datasource: dataSource.name });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
{!isEditing && (
|
||||
@@ -114,7 +126,17 @@ export const QueryEditorRowTitle: React.FC<Props> = ({
|
||||
{validationError && <FieldValidationMessage horizontal>{validationError}</FieldValidationMessage>}
|
||||
</>
|
||||
)}
|
||||
{dataSourceName && <em className={styles.contextInfo}> ({dataSourceName})</em>}
|
||||
{inMixedMode && (
|
||||
<div style={{ display: 'flex', marginLeft: '8px' }}>
|
||||
{query.datasource !== ExpressionDatasourceID && (
|
||||
<>
|
||||
<DataSourcePicker current={dataSourceName} onChange={onDataSourceChange} />
|
||||
{onTimeRangeChange && timeRange && <TimeRangeInput onChange={onTimeRangeChange} value={timeRange} />}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{dataSourceName && !inMixedMode && <em className={styles.contextInfo}> ({dataSourceName})</em>}
|
||||
{disabled && <em className={styles.contextInfo}> Disabled</em>}
|
||||
|
||||
{collapsedText && (
|
||||
|
||||
@@ -28,12 +28,6 @@ export class QueryEditorRows extends PureComponent<Props> {
|
||||
onChangeQuery(query: DataQuery, index: number) {
|
||||
const { queries, onQueriesChange } = this.props;
|
||||
|
||||
const old = queries[index];
|
||||
|
||||
if (old.datasource) {
|
||||
query.datasource = old.datasource;
|
||||
}
|
||||
|
||||
// update query in array
|
||||
onQueriesChange(
|
||||
queries.map((item, itemIndex) => {
|
||||
|
||||
@@ -45,6 +45,7 @@ interface State {
|
||||
scrollTop: number;
|
||||
data: PanelData;
|
||||
isHelpOpen: boolean;
|
||||
defaultDataSource?: DataSourceApi;
|
||||
}
|
||||
|
||||
export class QueryGroup extends PureComponent<Props, State> {
|
||||
@@ -76,7 +77,8 @@ export class QueryGroup extends PureComponent<Props, State> {
|
||||
try {
|
||||
const ds = await this.dataSourceSrv.get(options.dataSource.name);
|
||||
const dsSettings = this.dataSourceSrv.getInstanceSettings(options.dataSource.name);
|
||||
this.setState({ dataSource: ds, dsSettings });
|
||||
const defaultDataSource = await this.dataSourceSrv.get();
|
||||
this.setState({ dataSource: ds, dsSettings, defaultDataSource });
|
||||
} catch (error) {
|
||||
console.log('failed to load data source', error);
|
||||
}
|
||||
@@ -140,15 +142,23 @@ export class QueryGroup extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
onAddQueryClick = () => {
|
||||
if (this.state.dsSettings?.meta.mixed) {
|
||||
this.setState({ isAddingMixed: true });
|
||||
return;
|
||||
}
|
||||
|
||||
this.onChange({ queries: addQuery(this.props.options.queries) });
|
||||
const { options } = this.props;
|
||||
this.onChange({ queries: addQuery(options.queries, this.newQuery()) });
|
||||
this.onScrollBottom();
|
||||
};
|
||||
|
||||
newQuery(): Partial<DataQuery> {
|
||||
const { dsSettings, defaultDataSource } = this.state;
|
||||
|
||||
if (!dsSettings?.meta.mixed) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
datasource: defaultDataSource?.name,
|
||||
};
|
||||
}
|
||||
|
||||
onChange(changedProps: Partial<QueryGroupOptions>) {
|
||||
this.props.onOptionsChange({
|
||||
...this.props.options,
|
||||
@@ -320,7 +330,6 @@ export class QueryGroup extends PureComponent<Props, State> {
|
||||
Query
|
||||
</Button>
|
||||
)}
|
||||
{isAddingMixed && this.renderMixedPicker()}
|
||||
{config.expressionsEnabled && this.isExpressionsSupported(dsSettings) && (
|
||||
<Tooltip content="Experimental feature: queries could stop working in next version" placement="right">
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user