This commit is contained in:
Ivana Huckova 2022-07-06 14:00:27 +02:00
parent bc75bf4b91
commit 78da0e27e3
5 changed files with 98 additions and 8402 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,15 @@ import { EditorRow } from '@grafana/experimental';
import { LabelFilters } from 'app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters';
import { OperationList } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList';
import { OperationsEditorRow } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow';
import { QueryBuilderHints } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryBuilderHints';
import { QueryBuilderLabelFilter } from 'app/plugins/datasource/prometheus/querybuilder/shared/types';
import { LokiDatasource } from '../../datasource';
import { escapeLabelValueInSelector } from '../../language_utils';
import { lokiQueryModeller } from '../LokiQueryModeller';
import { buildVisualQueryFromString } from '../parsing';
import { LokiOperationId, LokiVisualQuery } from '../types';
import { LokiQueryBuilderHints } from './LokiQueryBuilderHints';
import { NestedQueryList } from './NestedQueryList';
export interface Props {
@ -111,7 +112,14 @@ export const LokiQueryBuilder = React.memo<Props>(({ datasource, query, onChange
onRunQuery={onRunQuery}
datasource={datasource as DataSourceApi}
/>
<LokiQueryBuilderHints datasource={datasource} query={query} onChange={onChange} data={sampleData} />
<QueryBuilderHints
datasource={datasource}
query={query}
onChange={onChange}
data={sampleData}
queryModeller={lokiQueryModeller}
buildVisualQueryFromString={buildVisualQueryFromString}
/>
</OperationsEditorRow>
{query.binaryQueries && query.binaryQueries.length > 0 && (
<NestedQueryList query={query} datasource={datasource} onChange={onChange} onRunQuery={onRunQuery} />

View File

@ -6,15 +6,17 @@ import { EditorRow } from '@grafana/experimental';
import { PrometheusDatasource } from '../../datasource';
import { getMetadataString } from '../../language_provider';
import { promQueryModeller } from '../PromQueryModeller';
import { buildVisualQueryFromString } from '../parsing';
import { LabelFilters } from '../shared/LabelFilters';
import { PromLokiVisualQuery } from '../shared/LokiAndPromQueryModellerBase';
import { OperationList } from '../shared/OperationList';
import { OperationsEditorRow } from '../shared/OperationsEditorRow';
import { QueryBuilderHints } from '../shared/QueryBuilderHints';
import { QueryBuilderLabelFilter } from '../shared/types';
import { PromVisualQuery } from '../types';
import { MetricSelect } from './MetricSelect';
import { NestedQueryList } from './NestedQueryList';
import { PromQueryBuilderHints } from './PromQueryBuilderHints';
export interface Props {
query: PromVisualQuery;
@ -108,7 +110,14 @@ export const PromQueryBuilder = React.memo<Props>(({ datasource, query, onChange
onChange={onChange}
onRunQuery={onRunQuery}
/>
<PromQueryBuilderHints datasource={datasource} query={query} onChange={onChange} data={data} />
<QueryBuilderHints
datasource={datasource}
query={query}
onChange={onChange as (query: PromLokiVisualQuery) => void}
data={data}
queryModeller={promQueryModeller}
buildVisualQueryFromString={buildVisualQueryFromString}
/>
</OperationsEditorRow>
{query.binaryQueries && query.binaryQueries.length > 0 && (
<NestedQueryList query={query} datasource={datasource} onChange={onChange} onRunQuery={onRunQuery} />

View File

@ -1,72 +0,0 @@
import { css } from '@emotion/css';
import React, { useState, useEffect } from 'react';
import { GrafanaTheme2, PanelData, QueryHint } from '@grafana/data';
import { Button, Tooltip, useStyles2 } from '@grafana/ui';
import { PrometheusDatasource } from '../../datasource';
import { promQueryModeller } from '../PromQueryModeller';
import { buildVisualQueryFromString } from '../parsing';
import { PromVisualQuery } from '../types';
export interface Props {
query: PromVisualQuery;
datasource: PrometheusDatasource;
onChange: (update: PromVisualQuery) => void;
data?: PanelData;
}
export const PromQueryBuilderHints = React.memo<Props>(({ datasource, query, onChange, data }) => {
const [hints, setHints] = useState<QueryHint[]>([]);
const styles = useStyles2(getStyles);
useEffect(() => {
const promQuery = { expr: promQueryModeller.renderQuery(query), refId: '' };
// For now show only actionable hints
const hints = datasource.getQueryHints(promQuery, data?.series || []).filter((hint) => hint.fix?.action);
setHints(hints);
}, [datasource, query, onChange, data, styles.hint]);
return (
<>
{hints.length > 0 && (
<div className={styles.container}>
{hints.map((hint) => {
return (
<Tooltip content={`${hint.label} ${hint.fix?.label}`} key={hint.type}>
<Button
onClick={() => {
const promQuery = { expr: promQueryModeller.renderQuery(query), refId: '' };
const newPromQuery = datasource.modifyQuery(promQuery, hint!.fix!.action);
const visualQuery = buildVisualQueryFromString(newPromQuery.expr);
return onChange(visualQuery.query);
}}
fill="outline"
size="sm"
className={styles.hint}
>
{'hint: ' + hint.fix?.action?.type.toLowerCase().replace('_', ' ') + '()'}
</Button>
</Tooltip>
);
})}
</div>
)}
</>
);
});
PromQueryBuilderHints.displayName = 'PromQueryBuilderHints';
const getStyles = (theme: GrafanaTheme2) => {
return {
container: css`
display: flex;
margin-bottom: ${theme.spacing(1)};
align-items: center;
`,
hint: css`
margin-right: ${theme.spacing(1)};
`,
};
};

View File

@ -0,0 +1,75 @@
import { css } from '@emotion/css';
import React, { useState, useEffect } from 'react';
import { GrafanaTheme2, PanelData, QueryHint } from '@grafana/data';
import { Button, Tooltip, useStyles2 } from '@grafana/ui';
import { LokiDatasource } from 'app/plugins/datasource/loki/datasource';
import { PrometheusDatasource } from '../../datasource';
import { LokiAndPromQueryModellerBase, PromLokiVisualQuery } from './LokiAndPromQueryModellerBase';
export interface Props {
query: PromLokiVisualQuery;
datasource: PrometheusDatasource | LokiDatasource;
queryModeller: LokiAndPromQueryModellerBase;
buildVisualQueryFromString: (expr: string) => { query: PromLokiVisualQuery };
onChange: (update: PromLokiVisualQuery) => void;
data?: PanelData;
}
export const QueryBuilderHints = React.memo<Props>(
({ datasource, query: visualQuery, onChange, data, queryModeller, buildVisualQueryFromString }) => {
const [hints, setHints] = useState<QueryHint[]>([]);
const styles = useStyles2(getStyles);
useEffect(() => {
const query = { expr: queryModeller.renderQuery(visualQuery), refId: '' };
// For now show only actionable hints
const hints = datasource.getQueryHints(query, data?.series || []).filter((hint) => hint.fix?.action);
setHints(hints);
}, [datasource, visualQuery, data, queryModeller]);
return (
<>
{hints.length > 0 && (
<div className={styles.container}>
{hints.map((hint) => {
return (
<Tooltip content={`${hint.label} ${hint.fix?.label}`} key={hint.type}>
<Button
onClick={() => {
const query = { expr: queryModeller.renderQuery(visualQuery), refId: '' };
const newQuery = datasource.modifyQuery(query, hint!.fix!.action);
const newVisualQuery = buildVisualQueryFromString(newQuery.expr);
return onChange(newVisualQuery.query);
}}
fill="outline"
size="sm"
className={styles.hint}
>
{'hint: ' + hint.fix?.action?.type.toLowerCase().replace('_', ' ') + '()'}
</Button>
</Tooltip>
);
})}
</div>
)}
</>
);
}
);
QueryBuilderHints.displayName = 'QueryBuilderHints';
const getStyles = (theme: GrafanaTheme2) => {
return {
container: css`
display: flex;
align-items: start;
`,
hint: css`
margin-right: ${theme.spacing(1)};
`,
};
};