mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 10:50:37 -06:00
Explore: adds PrometheusExploreQueryEditor (#20195)
* Explore: updates prom query field styles with flex-grow * Explore: adds prometheus explore query editor * Explore: updates step input width in prom explore query editor * Explore: updates prom explore query editor step field input placeholder to auto * Explore: updates prom explore query editor to include history * Explore: updates prom explore query editor, removes unused lodash import * Explore: updates step spacing in prom explore query editor * Explore: updates prom explore query editor - moves logic to query field * Explore: updates prom query field - adds step field with conditional rendering * Explore: updates promql cheat sheet with step description * Explore: updates prom cheat sheet step description * Explore: updates styles - adds query row break class * Explore: moves back step markup to PromExploreQueryEditor
This commit is contained in:
parent
7e8f4d0b0e
commit
1de24cc929
@ -18,20 +18,27 @@ const CHEAT_SHEET_ITEMS = [
|
||||
expression: 'sort_desc(sum(sum_over_time(ALERTS{alertstate="firing"}[24h])) by (alertname))',
|
||||
label: 'Sums up the alerts that have been firing over the last 24 hours.',
|
||||
},
|
||||
{
|
||||
title: 'Step',
|
||||
label:
|
||||
'Defines the graph resolution using a duration format (15s, 1m, 3h, ...). Small steps create high-resolution graphs but can be slow over larger time ranges. Using a longer step lowers the resolution and smooths the graph by producing fewer datapoints. If no step is given the resolution is calculated automatically.',
|
||||
},
|
||||
];
|
||||
|
||||
export default (props: ExploreStartPageProps) => (
|
||||
<div>
|
||||
<h2>PromQL Cheat Sheet</h2>
|
||||
{CHEAT_SHEET_ITEMS.map(item => (
|
||||
<div className="cheat-sheet-item" key={item.expression}>
|
||||
{CHEAT_SHEET_ITEMS.map((item, index) => (
|
||||
<div className="cheat-sheet-item" key={index}>
|
||||
<div className="cheat-sheet-item__title">{item.title}</div>
|
||||
{item.expression ? (
|
||||
<div
|
||||
className="cheat-sheet-item__example"
|
||||
onClick={e => props.onClickExample({ refId: 'A', expr: item.expression } as DataQuery)}
|
||||
>
|
||||
<code>{item.expression}</code>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="cheat-sheet-item__label">{item.label}</div>
|
||||
</div>
|
||||
))}
|
||||
|
@ -0,0 +1,85 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
// Types
|
||||
import { ExploreQueryFieldProps } from '@grafana/data';
|
||||
import { FormLabel } from '@grafana/ui';
|
||||
|
||||
import { PrometheusDatasource } from '../datasource';
|
||||
import { PromQuery, PromOptions } from '../types';
|
||||
|
||||
import PromQueryField from './PromQueryField';
|
||||
export type Props = ExploreQueryFieldProps<PrometheusDatasource, PromQuery, PromOptions>;
|
||||
|
||||
interface State {
|
||||
interval: string;
|
||||
}
|
||||
|
||||
export class PromExploreQueryEditor extends PureComponent<Props, State> {
|
||||
// Query target to be modified and used for queries
|
||||
query: PromQuery;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
const { query } = props;
|
||||
this.query = query;
|
||||
// Query target properties that are fully controlled inputs
|
||||
this.state = {
|
||||
// Fully controlled text inputs
|
||||
interval: query.interval,
|
||||
};
|
||||
}
|
||||
|
||||
onFieldChange = (query: PromQuery, override?: any) => {
|
||||
this.query.expr = query.expr;
|
||||
};
|
||||
|
||||
onIntervalChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const interval = e.currentTarget.value;
|
||||
this.query.interval = interval;
|
||||
this.setState({ interval });
|
||||
};
|
||||
|
||||
onRunQuery = () => {
|
||||
const { query } = this;
|
||||
this.props.onChange(query);
|
||||
this.props.onRunQuery();
|
||||
};
|
||||
|
||||
onReturnKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.onRunQuery();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { datasource, query, data, history } = this.props;
|
||||
const { interval } = this.state;
|
||||
|
||||
return (
|
||||
<div className="gf-form-inline">
|
||||
<PromQueryField
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
onRunQuery={this.onRunQuery}
|
||||
onChange={this.onFieldChange}
|
||||
history={history}
|
||||
data={data}
|
||||
>
|
||||
<div className="gf-form-inline explore-input--ml">
|
||||
<div className="gf-form">
|
||||
<FormLabel width={4}>Step</FormLabel>
|
||||
<input
|
||||
type="text"
|
||||
className="gf-form-input width-6"
|
||||
placeholder={'auto'}
|
||||
onChange={this.onIntervalChange}
|
||||
onKeyDown={this.onReturnKeyDown}
|
||||
value={interval}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</PromQueryField>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -291,7 +291,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, query } = this.props;
|
||||
const { data, query, children } = this.props;
|
||||
const { metricsOptions, syntaxLoaded, hint } = this.state;
|
||||
const cleanText = this.languageProvider ? this.languageProvider.cleanText : undefined;
|
||||
const chooserText = getChooserText(syntaxLoaded, metricsOptions);
|
||||
@ -300,7 +300,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline gf-form-inline--nowrap">
|
||||
<div className="gf-form-inline gf-form-inline--nowrap flex-grow-1">
|
||||
<div className="gf-form flex-shrink-0">
|
||||
<Cascader
|
||||
options={metricsOptions}
|
||||
@ -325,9 +325,15 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
syntaxLoaded={syntaxLoaded}
|
||||
/>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
{showError ? <div className="prom-query-field-info text-error">{data.error.message}</div> : null}
|
||||
{showError ? (
|
||||
<div className="query-row-break">
|
||||
<div className="prom-query-field-info text-error">{data.error.message}</div>
|
||||
</div>
|
||||
) : null}
|
||||
{hint ? (
|
||||
<div className="query-row-break">
|
||||
<div className="prom-query-field-info text-warning">
|
||||
{hint.label}{' '}
|
||||
{hint.fix ? (
|
||||
@ -336,6 +342,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ import { PrometheusDatasource } from './datasource';
|
||||
|
||||
import { PromQueryEditor } from './components/PromQueryEditor';
|
||||
import PromCheatSheet from './components/PromCheatSheet';
|
||||
import PromQueryField from './components/PromQueryField';
|
||||
import { PromExploreQueryEditor } from './components/PromExploreQueryEditor';
|
||||
|
||||
import { ConfigEditor } from './configuration/ConfigEditor';
|
||||
|
||||
@ -14,6 +14,6 @@ class PrometheusAnnotationsQueryCtrl {
|
||||
export const plugin = new DataSourcePlugin(PrometheusDatasource)
|
||||
.setQueryEditor(PromQueryEditor)
|
||||
.setConfigEditor(ConfigEditor)
|
||||
.setExploreMetricsQueryField(PromQueryField)
|
||||
.setExploreMetricsQueryField(PromExploreQueryEditor)
|
||||
.setAnnotationQueryCtrl(PrometheusAnnotationsQueryCtrl)
|
||||
.setExploreStartPage(PromCheatSheet);
|
||||
|
@ -229,6 +229,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.explore-input--ml {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.navbar .elapsed-time {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -273,6 +277,11 @@
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.query-row-break {
|
||||
height: 0;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.query-transactions {
|
||||
display: table;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user