mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Moves PromContext from query level to DataQueryRequest level (#21260)
Closes #19598 Fixes bug introduced recently where the new PromQueryEditor did not preserve the PromContext.Explore set on the query model by PromQueryField which caused the table to be empty for Prometheus in explore.
This commit is contained in:
parent
545b72da33
commit
45b7de1910
@ -3,6 +3,11 @@ import { KeyValue } from './data';
|
||||
import { NavModel } from './navModel';
|
||||
import { PluginMeta, GrafanaPlugin, PluginIncludeType } from './plugin';
|
||||
|
||||
export enum CoreApp {
|
||||
Dashboard = 'dashboard',
|
||||
Explore = 'explore',
|
||||
}
|
||||
|
||||
export interface AppRootProps<T = KeyValue> {
|
||||
meta: AppPluginMeta<T>;
|
||||
|
||||
|
@ -7,6 +7,7 @@ import { AnnotationEvent, KeyValue, LoadingState, TableData, TimeSeries } from '
|
||||
import { DataFrame, DataFrameDTO } from './dataFrame';
|
||||
import { RawTimeRange, TimeRange, AbsoluteTimeRange } from './time';
|
||||
import { ScopedVars } from './ScopedVars';
|
||||
import { CoreApp } from './app';
|
||||
|
||||
export interface DataSourcePluginOptionsEditorProps<JSONData = DataSourceJsonData, SecureJSONData = {}> {
|
||||
options: DataSourceSettings<JSONData, SecureJSONData>;
|
||||
@ -449,6 +450,7 @@ export interface DataQueryRequest<TQuery extends DataQuery = DataQuery> {
|
||||
scopedVars: ScopedVars;
|
||||
targets: TQuery[];
|
||||
timezone: string;
|
||||
app: CoreApp | string;
|
||||
|
||||
cacheTimeout?: string;
|
||||
exploreMode?: 'Logs' | 'Metrics';
|
||||
|
@ -4,6 +4,7 @@ import { Unsubscribable } from 'rxjs';
|
||||
// Services & Utils
|
||||
import {
|
||||
DataQuery,
|
||||
CoreApp,
|
||||
DataQueryError,
|
||||
DataQueryRequest,
|
||||
DataSourceApi,
|
||||
@ -130,6 +131,7 @@ export function buildQueryTransaction(
|
||||
const panelId = `${key}`;
|
||||
|
||||
const request: DataQueryRequest = {
|
||||
app: CoreApp.Explore,
|
||||
dashboardId: 0,
|
||||
// TODO probably should be taken from preferences but does not seem to be used anyway.
|
||||
timezone: DefaultTimeZone,
|
||||
|
@ -15,6 +15,7 @@ import { runSharedRequest, isSharedDashboardQuery } from '../../../plugins/datas
|
||||
import {
|
||||
PanelData,
|
||||
DataQuery,
|
||||
CoreApp,
|
||||
DataQueryRequest,
|
||||
DataSourceApi,
|
||||
DataSourceJsonData,
|
||||
@ -106,6 +107,7 @@ export class PanelQueryRunner {
|
||||
}
|
||||
|
||||
const request: DataQueryRequest = {
|
||||
app: CoreApp.Dashboard,
|
||||
requestId: getNextRequestId(),
|
||||
timezone,
|
||||
panelId,
|
||||
|
@ -6,6 +6,8 @@ import { Table, Collapse } from '@grafana/ui';
|
||||
import { ExploreId, ExploreItemState } from 'app/types/explore';
|
||||
import { StoreState } from 'app/types';
|
||||
import { toggleTable } from './state/actions';
|
||||
import { config } from 'app/core/config';
|
||||
import { PANEL_BORDER } from 'app/core/constants';
|
||||
|
||||
interface TableContainerProps {
|
||||
exploreId: ExploreId;
|
||||
@ -37,8 +39,7 @@ export class TableContainer extends PureComponent<TableContainerProps> {
|
||||
const { loading, onClickCell, showingTable, tableResult, width } = this.props;
|
||||
|
||||
const height = this.getTableHeight();
|
||||
const paddingWidth = 16;
|
||||
const tableWidth = width - paddingWidth;
|
||||
const tableWidth = width - config.theme.panelPadding * 2 - PANEL_BORDER;
|
||||
|
||||
return (
|
||||
<Collapse label="Table" loading={loading} collapsible isOpen={showingTable} onToggle={this.onClickTableButton}>
|
||||
|
@ -262,7 +262,7 @@ export default class LokiLanguageProvider extends LanguageProvider {
|
||||
return Promise.all(
|
||||
queries.map(async query => {
|
||||
const expr = await this.importPrometheusQuery(query.expr);
|
||||
const { context, ...rest } = query as PromQuery;
|
||||
const { ...rest } = query as PromQuery;
|
||||
return {
|
||||
...rest,
|
||||
expr,
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
import Prism from 'prismjs';
|
||||
|
||||
// dom also includes Element polyfills
|
||||
import { PromQuery, PromContext, PromOptions, PromMetricsMetadata } from '../types';
|
||||
import { PromQuery, PromOptions, PromMetricsMetadata } from '../types';
|
||||
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
|
||||
import { ExploreQueryFieldProps, QueryHint, isDataFrame, toLegacyResponseData, HistoryItem } from '@grafana/data';
|
||||
import { DOMUtil, SuggestionsState } from '@grafana/ui';
|
||||
@ -220,7 +220,7 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
// Send text change to parent
|
||||
const { query, onChange, onRunQuery } = this.props;
|
||||
if (onChange) {
|
||||
const nextQuery: PromQuery = { ...query, expr: value, context: PromContext.Explore };
|
||||
const nextQuery: PromQuery = { ...query, expr: value };
|
||||
onChange(nextQuery);
|
||||
|
||||
if (override && onRunQuery) {
|
||||
|
@ -11,9 +11,10 @@ import {
|
||||
DataQueryResponseData,
|
||||
DataQueryRequest,
|
||||
dateTime,
|
||||
CoreApp,
|
||||
LoadingState,
|
||||
} from '@grafana/data';
|
||||
import { PromOptions, PromQuery, PromContext } from './types';
|
||||
import { PromOptions, PromQuery } from './types';
|
||||
import templateSrv from 'app/features/templating/template_srv';
|
||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { CustomVariable } from 'app/features/templating/custom_variable';
|
||||
@ -70,7 +71,7 @@ describe('PrometheusDatasource', () => {
|
||||
it('returns empty array when no queries', done => {
|
||||
expect.assertions(2);
|
||||
|
||||
ds.query(makeQuery([])).subscribe({
|
||||
ds.query(createDataRequest([])).subscribe({
|
||||
next(next) {
|
||||
expect(next.data).toEqual([]);
|
||||
expect(next.state).toBe(LoadingState.Done);
|
||||
@ -84,7 +85,7 @@ describe('PrometheusDatasource', () => {
|
||||
it('performs time series queries', done => {
|
||||
expect.assertions(2);
|
||||
|
||||
ds.query(makeQuery([{}])).subscribe({
|
||||
ds.query(createDataRequest([{}])).subscribe({
|
||||
next(next) {
|
||||
expect(next.data.length).not.toBe(0);
|
||||
expect(next.state).toBe(LoadingState.Done);
|
||||
@ -99,7 +100,7 @@ describe('PrometheusDatasource', () => {
|
||||
expect.assertions(4);
|
||||
|
||||
const responseStatus = [LoadingState.Loading, LoadingState.Done];
|
||||
ds.query(makeQuery([{ context: PromContext.Explore }, { context: PromContext.Explore }])).subscribe({
|
||||
ds.query(createDataRequest([{}, {}], { app: CoreApp.Explore })).subscribe({
|
||||
next(next) {
|
||||
expect(next.data.length).not.toBe(0);
|
||||
expect(next.state).toBe(responseStatus.shift());
|
||||
@ -112,7 +113,7 @@ describe('PrometheusDatasource', () => {
|
||||
|
||||
it('with 2 queries and used from Panel, waits for all to finish until sending Done status', done => {
|
||||
expect.assertions(2);
|
||||
ds.query(makeQuery([{ context: PromContext.Panel }, { context: PromContext.Panel }])).subscribe({
|
||||
ds.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard })).subscribe({
|
||||
next(next) {
|
||||
expect(next.data.length).not.toBe(0);
|
||||
expect(next.state).toBe(LoadingState.Done);
|
||||
@ -1552,7 +1553,7 @@ describe('PrometheusDatasource for POST', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const getPrepareTargetsContext = (target: PromQuery) => {
|
||||
const getPrepareTargetsContext = (target: PromQuery, app?: CoreApp) => {
|
||||
const instanceSettings = ({
|
||||
url: 'proxied',
|
||||
directUrl: 'direct',
|
||||
@ -1563,7 +1564,7 @@ const getPrepareTargetsContext = (target: PromQuery) => {
|
||||
const start = 0;
|
||||
const end = 1;
|
||||
const panelId = '2';
|
||||
const options = ({ targets: [target], interval: '1s', panelId } as any) as DataQueryRequest<PromQuery>;
|
||||
const options = ({ targets: [target], interval: '1s', panelId, app } as any) as DataQueryRequest<PromQuery>;
|
||||
|
||||
const ds = new PrometheusDatasource(instanceSettings);
|
||||
const { queries, activeTargets } = ds.prepareTargets(options, start, end);
|
||||
@ -1583,7 +1584,6 @@ describe('prepareTargets', () => {
|
||||
const target: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'up',
|
||||
context: PromContext.Panel,
|
||||
};
|
||||
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
|
||||
@ -1614,12 +1614,11 @@ describe('prepareTargets', () => {
|
||||
const target: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'up',
|
||||
context: PromContext.Explore,
|
||||
showingGraph: true,
|
||||
showingTable: true,
|
||||
};
|
||||
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
|
||||
|
||||
expect(queries.length).toBe(2);
|
||||
expect(activeTargets.length).toBe(2);
|
||||
@ -1672,12 +1671,11 @@ describe('prepareTargets', () => {
|
||||
const target: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'up',
|
||||
context: PromContext.Explore,
|
||||
showingGraph: false,
|
||||
showingTable: false,
|
||||
};
|
||||
|
||||
const { queries, activeTargets } = getPrepareTargetsContext(target);
|
||||
const { queries, activeTargets } = getPrepareTargetsContext(target, CoreApp.Explore);
|
||||
|
||||
expect(queries.length).toBe(0);
|
||||
expect(activeTargets.length).toBe(0);
|
||||
@ -1689,12 +1687,11 @@ describe('prepareTargets', () => {
|
||||
const target: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'up',
|
||||
context: PromContext.Explore,
|
||||
showingGraph: false,
|
||||
showingTable: true,
|
||||
};
|
||||
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
|
||||
|
||||
expect(queries.length).toBe(1);
|
||||
expect(activeTargets.length).toBe(1);
|
||||
@ -1727,12 +1724,11 @@ describe('prepareTargets', () => {
|
||||
const target: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'up',
|
||||
context: PromContext.Explore,
|
||||
showingGraph: true,
|
||||
showingTable: false,
|
||||
};
|
||||
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target);
|
||||
const { queries, activeTargets, panelId, end, start } = getPrepareTargetsContext(target, CoreApp.Explore);
|
||||
|
||||
expect(queries.length).toBe(1);
|
||||
expect(activeTargets.length).toBe(1);
|
||||
@ -1761,8 +1757,9 @@ describe('prepareTargets', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function makeQuery(targets: any[]): any {
|
||||
return {
|
||||
function createDataRequest(targets: any[], overrides?: Partial<DataQueryRequest>): DataQueryRequest<PromQuery> {
|
||||
const defaults = {
|
||||
app: CoreApp.Dashboard,
|
||||
targets: targets.map(t => {
|
||||
return {
|
||||
instant: false,
|
||||
@ -1779,4 +1776,6 @@ function makeQuery(targets: any[]): any {
|
||||
},
|
||||
interval: '15s',
|
||||
};
|
||||
|
||||
return Object.assign(defaults, overrides || {}) as DataQueryRequest<PromQuery>;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
LoadingState,
|
||||
TimeRange,
|
||||
TimeSeries,
|
||||
CoreApp,
|
||||
DataQueryError,
|
||||
DataQueryRequest,
|
||||
DataQueryResponse,
|
||||
@ -29,7 +30,7 @@ import addLabelToQuery from './add_label_to_query';
|
||||
import { getQueryHints } from './query_hints';
|
||||
import { expandRecordingRules } from './language_utils';
|
||||
// Types
|
||||
import { PromContext, PromOptions, PromQuery, PromQueryRequest } from './types';
|
||||
import { PromOptions, PromQuery, PromQueryRequest } from './types';
|
||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||
import templateSrv from 'app/features/templating/template_srv';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
@ -202,7 +203,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
|
||||
target.requestId = options.panelId + target.refId;
|
||||
|
||||
if (target.context !== PromContext.Explore) {
|
||||
if (options.app !== CoreApp.Explore) {
|
||||
activeTargets.push(target);
|
||||
queries.push(this.createQuery(target, options, start, end));
|
||||
continue;
|
||||
@ -237,11 +238,6 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
};
|
||||
};
|
||||
|
||||
calledFromExplore = (options: DataQueryRequest<PromQuery>): boolean => {
|
||||
const exploreTargets = options.targets.filter(target => target.context === PromContext.Explore).length;
|
||||
return exploreTargets === options.targets.length;
|
||||
};
|
||||
|
||||
query(options: DataQueryRequest<PromQuery>): Observable<DataQueryResponse> {
|
||||
const start = this.getPrometheusTime(options.range.from, false);
|
||||
const end = this.getPrometheusTime(options.range.to, true);
|
||||
@ -255,7 +251,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
});
|
||||
}
|
||||
|
||||
if (this.calledFromExplore(options)) {
|
||||
if (options.app === CoreApp.Explore) {
|
||||
return this.exploreQuery(queries, activeTargets, end);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,7 @@
|
||||
import { DataQuery, DataSourceJsonData } from '@grafana/data';
|
||||
|
||||
export enum PromContext {
|
||||
Explore = 'explore',
|
||||
Panel = 'panel',
|
||||
}
|
||||
|
||||
export interface PromQuery extends DataQuery {
|
||||
expr: string;
|
||||
context?: PromContext;
|
||||
format?: string;
|
||||
instant?: boolean;
|
||||
hinting?: boolean;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DataQueryRequest, DataQuery } from '@grafana/data';
|
||||
import { DataQueryRequest, DataQuery, CoreApp } from '@grafana/data';
|
||||
import { dateTime } from '@grafana/data';
|
||||
|
||||
export function getQueryOptions<TQuery extends DataQuery>(
|
||||
@ -9,6 +9,7 @@ export function getQueryOptions<TQuery extends DataQuery>(
|
||||
|
||||
const defaults: DataQueryRequest<TQuery> = {
|
||||
requestId: 'TEST',
|
||||
app: CoreApp.Dashboard,
|
||||
range: range,
|
||||
targets: [],
|
||||
scopedVars: {},
|
||||
|
Loading…
Reference in New Issue
Block a user