Prometheus: Show initial hint on builder mode when metric lookup disabled (#65827)

* Show initial hint on builder mode when metric lookup disabled

* Disable MetricEncyclopedia and label request when metric lookup is disabled
This commit is contained in:
ismail simsek 2023-04-12 17:22:35 +02:00 committed by GitHub
parent e0385d08a8
commit 08727b7d6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 12 deletions

View File

@ -1,8 +1,6 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"version": "10.0.0-pre"
}

View File

@ -6,8 +6,8 @@ import (
context "context"
dashboards "github.com/grafana/grafana/pkg/services/dashboards"
mock "github.com/stretchr/testify/mock"
models "github.com/grafana/grafana/pkg/services/publicdashboards/models"
mock "github.com/stretchr/testify/mock"
)
// FakePublicDashboardStore is an autogenerated mock type for the Store type

View File

@ -7,7 +7,7 @@ import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data/src';
import { PrometheusDatasource } from '../../datasource';
import { PromOptions } from '../../types';
import { MetricSelect } from './MetricSelect';
import { MetricSelect, Props } from './MetricSelect';
const instanceSettings = {
url: 'proxied',
@ -44,7 +44,7 @@ dataSourceMock.metricFindQuery = jest.fn((query: string) => {
);
});
const props = {
const props: Props = {
labelsFilters: [],
datasource: dataSourceMock,
query: {
@ -54,6 +54,7 @@ const props = {
},
onChange: jest.fn(),
onGetMetrics: jest.fn().mockResolvedValue(mockValues),
metricLookupDisabled: false,
};
describe('MetricSelect', () => {

View File

@ -3,7 +3,7 @@ import debounce from 'debounce-promise';
import React, { useCallback, useState } from 'react';
import Highlighter from 'react-highlight-words';
import { SelectableValue, toOption, GrafanaTheme2 } from '@grafana/data';
import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data';
import { EditorField, EditorFieldGroup } from '@grafana/experimental';
import { AsyncSelect, FormatOptionLabelMeta, useStyles2 } from '@grafana/ui';
@ -16,6 +16,7 @@ import { PromVisualQuery } from '../types';
const splitSeparator = ' ';
export interface Props {
metricLookupDisabled: boolean;
query: PromVisualQuery;
onChange: (query: PromVisualQuery) => void;
onGetMetrics: () => Promise<SelectableValue[]>;
@ -25,7 +26,14 @@ export interface Props {
export const PROMETHEUS_QUERY_BUILDER_MAX_RESULTS = 1000;
export function MetricSelect({ datasource, query, onChange, onGetMetrics, labelsFilters }: Props) {
export function MetricSelect({
datasource,
query,
onChange,
onGetMetrics,
labelsFilters,
metricLookupDisabled,
}: Props) {
const styles = useStyles2(getStyles);
const [state, setState] = useState<{
metrics?: Array<SelectableValue<any>>;
@ -114,6 +122,9 @@ export function MetricSelect({ datasource, query, onChange, onGetMetrics, labels
});
};
// When metric and label lookup is disabled we won't request labels
const metricLookupDisabledSearch = () => Promise.resolve([]);
const debouncedSearch = debounce(
(query: string) => getMetricLabels(query),
datasource.getDebounceTimeInMilliseconds()
@ -126,11 +137,14 @@ export function MetricSelect({ datasource, query, onChange, onGetMetrics, labels
inputId="prometheus-metric-select"
className={styles.select}
value={query.metric ? toOption(query.metric) : undefined}
placeholder="Select metric"
placeholder={'Select metric'}
allowCustomValue
formatOptionLabel={formatOptionLabel}
filterOption={customFilterOption}
onOpenMenu={async () => {
if (metricLookupDisabled) {
return;
}
setState({ isLoading: true });
const metrics = await onGetMetrics();
if (metrics.length > PROMETHEUS_QUERY_BUILDER_MAX_RESULTS) {
@ -138,7 +152,7 @@ export function MetricSelect({ datasource, query, onChange, onGetMetrics, labels
}
setState({ metrics, isLoading: undefined });
}}
loadOptions={debouncedSearch}
loadOptions={metricLookupDisabled ? metricLookupDisabledSearch : debouncedSearch}
isLoading={state.isLoading}
defaultOptions={state.metrics}
onChange={({ value }) => {

View File

@ -8,6 +8,7 @@ import {
LoadingState,
MutableDataFrame,
PanelData,
QueryHint,
TimeRange,
} from '@grafana/data';
@ -229,6 +230,45 @@ describe('PromQueryBuilder', () => {
expect(await screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument();
});
it('renders hint if initial hint provided', async () => {
const { datasource } = createDatasource();
datasource.getInitHints = (): QueryHint[] => [
{
label: 'Initial hint',
type: 'warning',
},
];
const props = createProps(datasource);
render(
<PromQueryBuilder
{...props}
query={{
metric: 'histogram_metric_sum',
labels: [],
operations: [],
}}
/>
);
expect(await screen.queryByText('Initial hint')).toBeInTheDocument();
});
it('renders no hint if no initial hint provided', async () => {
const { datasource } = createDatasource();
datasource.getInitHints = (): QueryHint[] => [];
const props = createProps(datasource);
render(
<PromQueryBuilder
{...props}
query={{
metric: 'histogram_metric_sum',
labels: [],
operations: [],
}}
/>
);
expect(await screen.queryByText('Initial hint')).not.toBeInTheDocument();
});
// <ModernPrometheus>
it('tries to load labels when metric selected modern prom', async () => {
const { languageProvider } = setup(undefined, undefined, {

View File

@ -208,12 +208,14 @@ export const PromQueryBuilder = React.memo<Props>((props) => {
}, [datasource, query, withTemplateVariableOptions]);
const lang = { grammar: promqlGrammar, name: 'promql' };
const MetricEncyclopedia = config.featureToggles.prometheusMetricEncyclopedia;
const isMetricEncyclopediaEnabled = config.featureToggles.prometheusMetricEncyclopedia;
const initHints = datasource.getInitHints();
return (
<>
<EditorRow>
{MetricEncyclopedia ? (
{isMetricEncyclopediaEnabled && !datasource.lookupsDisabled ? (
<>
<Button
className={styles.button}
@ -252,6 +254,7 @@ export const PromQueryBuilder = React.memo<Props>((props) => {
onGetMetrics={onGetMetrics}
datasource={datasource}
labelsFilters={query.labels}
metricLookupDisabled={datasource.lookupsDisabled}
/>
)}
<LabelFilters
@ -264,6 +267,18 @@ export const PromQueryBuilder = React.memo<Props>((props) => {
onGetLabelValues={(forLabel) => withTemplateVariableOptions(onGetLabelValues(forLabel))}
/>
</EditorRow>
{initHints.length ? (
<div className="query-row-break">
<div className="prom-query-field-info text-warning">
{initHints[0].label}{' '}
{initHints[0].fix ? (
<button type="button" className={'text-warning'}>
{initHints[0].fix.label}
</button>
) : null}
</div>
</div>
) : null}
{showExplain && (
<OperationExplainedBox
stepNumber={1}