Explore: Align Explore with Dashboards and Panels (#16823)

* Wip: Removes queryTransactions from state

* Refactor: Adds back query failures

* Refactor: Moves error parsing to datasources

* Refactor: Adds back hinting for Prometheus

* Refactor: removed commented out code

* Refactor: Adds back QueryStatus

* Refactor: Adds scanning back to Explore

* Fix: Fixes prettier error

* Fix: Makes sure there is an error

* Merge: Merges with master

* Fix: Adds safeStringifyValue to error parsing

* Fix: Fixes table result calculations

* Refactor: Adds ErrorContainer and generic error handling in Explore

* Fix: Fixes so refIds remain consistent

* Refactor: Makes it possible to return result even when there are errors

* Fix: Fixes digest issue with Angular editors

* Refactor: Adds tests for explore utils

* Refactor: Breakes current behaviour of always returning a result even if Query fails

* Fix: Fixes Prettier error

* Fix: Adds back console.log for erroneous querys

* Refactor: Changes console.log to console.error
This commit is contained in:
Hugo Häggmark
2019-05-10 14:00:39 +02:00
committed by GitHub
parent 8eb78ea931
commit 6dbaa704bc
28 changed files with 871 additions and 549 deletions

View File

@@ -16,7 +16,7 @@ import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
import { PromQuery } from '../types';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
import { ExploreDataSourceApi, ExploreQueryFieldProps, DataSourceStatus } from '@grafana/ui';
import { ExploreDataSourceApi, ExploreQueryFieldProps, DataSourceStatus, QueryHint } from '@grafana/ui';
const HISTOGRAM_GROUP = '__histograms__';
const METRIC_MARK = 'metric';
@@ -109,6 +109,7 @@ interface PromQueryFieldProps extends ExploreQueryFieldProps<ExploreDataSourceAp
interface PromQueryFieldState {
metricsOptions: any[];
syntaxLoaded: boolean;
hint: QueryHint;
}
class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryFieldState> {
@@ -125,7 +126,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
this.plugins = [
BracesPlugin(),
RunnerPlugin({ handler: props.onExecuteQuery }),
RunnerPlugin({ handler: props.onRunQuery }),
PluginPrism({
onlyIn: (node: any) => node.type === 'code_block',
getSyntax: (node: any) => 'promql',
@@ -135,6 +136,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
this.state = {
metricsOptions: [],
syntaxLoaded: false,
hint: null,
};
}
@@ -142,6 +144,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
if (this.languageProvider) {
this.refreshMetrics(makePromiseCancelable(this.languageProvider.start()));
}
this.refreshHint();
}
componentWillUnmount() {
@@ -151,6 +154,11 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
}
componentDidUpdate(prevProps: PromQueryFieldProps) {
const currentHasSeries = this.props.queryResponse.series && this.props.queryResponse.series.length > 0;
if (currentHasSeries && prevProps.queryResponse.series !== this.props.queryResponse.series) {
this.refreshHint();
}
const reconnected =
prevProps.datasourceStatus === DataSourceStatus.Disconnected &&
this.props.datasourceStatus === DataSourceStatus.Connected;
@@ -167,6 +175,17 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
}
}
refreshHint = () => {
const { datasource, query, queryResponse } = this.props;
if (queryResponse.series && queryResponse.series.length === 0) {
return;
}
const hints = datasource.getQueryHints(query, queryResponse.series);
const hint = hints && hints.length > 0 ? hints[0] : null;
this.setState({ hint });
};
refreshMetrics = (cancelablePromise: CancelablePromise<any>) => {
this.languageProviderInitializationPromise = cancelablePromise;
this.languageProviderInitializationPromise.promise
@@ -204,21 +223,22 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
onChangeQuery = (value: string, override?: boolean) => {
// Send text change to parent
const { query, onQueryChange, onExecuteQuery } = this.props;
if (onQueryChange) {
const { query, onChange, onRunQuery } = this.props;
if (onChange) {
const nextQuery: PromQuery = { ...query, expr: value };
onQueryChange(nextQuery);
onChange(nextQuery);
if (override && onExecuteQuery) {
onExecuteQuery();
if (override && onRunQuery) {
onRunQuery();
}
}
};
onClickHintFix = () => {
const { hint, onExecuteHint } = this.props;
if (onExecuteHint && hint && hint.fix) {
onExecuteHint(hint.fix.action);
const { hint } = this.state;
const { onHint } = this.props;
if (onHint && hint && hint.fix) {
onHint(hint.fix.action);
}
};
@@ -273,8 +293,8 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
};
render() {
const { error, hint, query, datasourceStatus } = this.props;
const { metricsOptions, syntaxLoaded } = this.state;
const { queryResponse, query, datasourceStatus } = this.props;
const { metricsOptions, syntaxLoaded, hint } = this.state;
const cleanText = this.languageProvider ? this.languageProvider.cleanText : undefined;
const chooserText = getChooserText(syntaxLoaded, datasourceStatus);
const buttonDisabled = !syntaxLoaded || datasourceStatus === DataSourceStatus.Disconnected;
@@ -296,15 +316,17 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
initialQuery={query.expr}
onTypeahead={this.onTypeahead}
onWillApplySuggestion={willApplySuggestion}
onQueryChange={this.onChangeQuery}
onExecuteQuery={this.props.onExecuteQuery}
onChange={this.onChangeQuery}
onRunQuery={this.props.onRunQuery}
placeholder="Enter a PromQL query"
portalOrigin="prometheus"
syntaxLoaded={syntaxLoaded}
/>
</div>
</div>
{error ? <div className="prom-query-field-info text-error">{error}</div> : null}
{queryResponse && queryResponse.error ? (
<div className="prom-query-field-info text-error">{queryResponse.error.message}</div>
) : null}
{hint ? (
<div className="prom-query-field-info text-warning">
{hint.label}{' '}