mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Expand template variables when redirecting from dashboard panel (#19582)
* Fix redirect but adding getExploreState method to graphite * Explore: Create interpolateVariablesInQueries function for datasources * Explore: Add interpolateVariablesInQueries method to elasticsearch datasource * Add interpolateVariablesInQueries function to influx and postgres * Explore: Add interpolateVariablesInQueries to Mssql and Mysql datasources * Explore: Add datasources to queries * Explore: Code formatting * Prettier formating fix * Explore: Add rawQuery expanding of variables for influxdb * Remove console.logs * Explore: Add rawQuery expanding of multiple variables for influxdb * Explore: If no queries in Influxdb, return early [] * Explore: Refactor influxDb to follow the code structure
This commit is contained in:
parent
9904e14f8e
commit
90b0953620
@ -77,12 +77,18 @@ export async function getExploreUrl(
|
|||||||
if (exploreDatasource) {
|
if (exploreDatasource) {
|
||||||
const range = timeSrv.timeRangeForUrl();
|
const range = timeSrv.timeRangeForUrl();
|
||||||
let state: Partial<ExploreUrlState> = { range };
|
let state: Partial<ExploreUrlState> = { range };
|
||||||
if (exploreDatasource.getExploreState) {
|
if (exploreDatasource.interpolateVariablesInQueries) {
|
||||||
state = { ...state, ...exploreDatasource.getExploreState(exploreTargets) };
|
state = {
|
||||||
|
...state,
|
||||||
|
datasource: exploreDatasource.name,
|
||||||
|
context: 'explore',
|
||||||
|
queries: exploreDatasource.interpolateVariablesInQueries(exploreTargets),
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
datasource: exploreDatasource.name,
|
datasource: exploreDatasource.name,
|
||||||
|
context: 'explore',
|
||||||
queries: exploreTargets.map(t => ({ ...t, datasource: exploreDatasource.name })),
|
queries: exploreTargets.map(t => ({ ...t, datasource: exploreDatasource.name })),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,21 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: ElasticsearchQuery[]): ElasticsearchQuery[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
query: this.templateSrv.replace(query.query),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
testDatasource() {
|
testDatasource() {
|
||||||
// validate that the index exist and has date field
|
// validate that the index exist and has date field
|
||||||
return this.getFields({ type: 'date' }).then(
|
return this.getFields({ type: 'date' }).then(
|
||||||
|
@ -6,6 +6,9 @@ import { IQService } from 'angular';
|
|||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
|
//Types
|
||||||
|
import { GraphiteQuery } from './types';
|
||||||
|
|
||||||
export class GraphiteDatasource {
|
export class GraphiteDatasource {
|
||||||
basicAuth: string;
|
basicAuth: string;
|
||||||
url: string;
|
url: string;
|
||||||
@ -117,6 +120,21 @@ export class GraphiteDatasource {
|
|||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: GraphiteQuery[]): GraphiteQuery[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
target: this.templateSrv.replace(query.target),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
annotationQuery(options: { annotation: { target: string; tags: string }; rangeRaw: any }) {
|
annotationQuery(options: { annotation: { target: string; tags: string }; rangeRaw: any }) {
|
||||||
// Graphite metric as annotation
|
// Graphite metric as annotation
|
||||||
if (options.annotation.target) {
|
if (options.annotation.target) {
|
||||||
|
5
public/app/plugins/datasource/graphite/types.ts
Normal file
5
public/app/plugins/datasource/graphite/types.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { DataQuery } from '@grafana/ui';
|
||||||
|
|
||||||
|
export interface GraphiteQuery extends DataQuery {
|
||||||
|
target?: string;
|
||||||
|
}
|
@ -176,6 +176,40 @@ export default class InfluxDatasource extends DataSourceApi<InfluxQuery, InfluxO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: InfluxQuery[]): InfluxQuery[] {
|
||||||
|
if (!queries || queries.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
measurement: this.templateSrv.replace(query.measurement, null, 'regex'),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (query.rawQuery) {
|
||||||
|
expandedQuery.query = this.templateSrv.replace(query.query, null, 'regex');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.tags) {
|
||||||
|
const expandedTags = query.tags.map(tag => {
|
||||||
|
const expandedTag = {
|
||||||
|
...tag,
|
||||||
|
value: this.templateSrv.replace(tag.value, null, 'regex'),
|
||||||
|
};
|
||||||
|
return expandedTag;
|
||||||
|
});
|
||||||
|
expandedQuery.tags = expandedTags;
|
||||||
|
}
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
metricFindQuery(query: string, options?: any) {
|
metricFindQuery(query: string, options?: any) {
|
||||||
const interpolated = this.templateSrv.replace(query, null, 'regex');
|
const interpolated = this.templateSrv.replace(query, null, 'regex');
|
||||||
|
|
||||||
|
@ -225,6 +225,21 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||||||
return merge(...subQueries);
|
return merge(...subQueries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: LokiQuery[]): LokiQuery[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
expr: this.templateSrv.replace(query.expr),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
async importQueries(queries: LokiQuery[], originMeta: PluginMeta): Promise<LokiQuery[]> {
|
async importQueries(queries: LokiQuery[], originMeta: PluginMeta): Promise<LokiQuery[]> {
|
||||||
return this.languageProvider.importQueries(queries, originMeta.id);
|
return this.languageProvider.importQueries(queries, originMeta.id);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import { BackendSrv } from 'app/core/services/backend_srv';
|
|||||||
import { IQService } from 'angular';
|
import { IQService } from 'angular';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
//Types
|
||||||
|
import { MssqlQueryForInterpolation } from './types';
|
||||||
|
|
||||||
export class MssqlDatasource {
|
export class MssqlDatasource {
|
||||||
id: any;
|
id: any;
|
||||||
@ -48,6 +50,21 @@ export class MssqlDatasource {
|
|||||||
return quotedValues.join(',');
|
return quotedValues.join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: MssqlQueryForInterpolation[]): MssqlQueryForInterpolation[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
query(options: any) {
|
query(options: any) {
|
||||||
const queries = _.filter(options.targets, item => {
|
const queries = _.filter(options.targets, item => {
|
||||||
return item.hide !== true;
|
return item.hide !== true;
|
||||||
|
7
public/app/plugins/datasource/mssql/types.ts
Normal file
7
public/app/plugins/datasource/mssql/types.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface MssqlQueryForInterpolation {
|
||||||
|
alias?: any;
|
||||||
|
format?: any;
|
||||||
|
rawSql?: any;
|
||||||
|
refId?: any;
|
||||||
|
hide?: any;
|
||||||
|
}
|
@ -5,6 +5,8 @@ import { BackendSrv } from 'app/core/services/backend_srv';
|
|||||||
import { IQService } from 'angular';
|
import { IQService } from 'angular';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
//Types
|
||||||
|
import { MysqlQueryForInterpolation } from './types';
|
||||||
|
|
||||||
export class MysqlDatasource {
|
export class MysqlDatasource {
|
||||||
id: any;
|
id: any;
|
||||||
@ -47,6 +49,21 @@ export class MysqlDatasource {
|
|||||||
return quotedValues.join(',');
|
return quotedValues.join(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: MysqlQueryForInterpolation[]): MysqlQueryForInterpolation[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
query(options: any) {
|
query(options: any) {
|
||||||
const queries = _.filter(options.targets, target => {
|
const queries = _.filter(options.targets, target => {
|
||||||
return target.hide !== true;
|
return target.hide !== true;
|
||||||
|
7
public/app/plugins/datasource/mysql/types.ts
Normal file
7
public/app/plugins/datasource/mysql/types.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface MysqlQueryForInterpolation {
|
||||||
|
alias?: any;
|
||||||
|
format?: any;
|
||||||
|
rawSql?: any;
|
||||||
|
refId?: any;
|
||||||
|
hide?: any;
|
||||||
|
}
|
@ -5,6 +5,8 @@ import { IQService } from 'angular';
|
|||||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
//Types
|
||||||
|
import { PostgresQueryForInterpolation } from './types';
|
||||||
|
|
||||||
export class PostgresDatasource {
|
export class PostgresDatasource {
|
||||||
id: any;
|
id: any;
|
||||||
@ -49,6 +51,21 @@ export class PostgresDatasource {
|
|||||||
return quotedValues.join(',');
|
return quotedValues.join(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interpolateVariablesInQueries(queries: PostgresQueryForInterpolation[]): PostgresQueryForInterpolation[] {
|
||||||
|
let expandedQueries = queries;
|
||||||
|
if (queries && queries.length > 0) {
|
||||||
|
expandedQueries = queries.map(query => {
|
||||||
|
const expandedQuery = {
|
||||||
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
|
rawSql: this.templateSrv.replace(query.rawSql, {}, this.interpolateVariable),
|
||||||
|
};
|
||||||
|
return expandedQuery;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return expandedQueries;
|
||||||
|
}
|
||||||
|
|
||||||
query(options: any) {
|
query(options: any) {
|
||||||
const queries = _.filter(options.targets, target => {
|
const queries = _.filter(options.targets, target => {
|
||||||
return target.hide !== true;
|
return target.hide !== true;
|
||||||
|
7
public/app/plugins/datasource/postgres/types.ts
Normal file
7
public/app/plugins/datasource/postgres/types.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface PostgresQueryForInterpolation {
|
||||||
|
alias?: any;
|
||||||
|
format?: any;
|
||||||
|
rawSql?: any;
|
||||||
|
refId?: any;
|
||||||
|
hide?: any;
|
||||||
|
}
|
@ -27,7 +27,6 @@ import {
|
|||||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
import { ExploreUrlState } from 'app/types';
|
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
|
|
||||||
export interface PromDataQueryResponse {
|
export interface PromDataQueryResponse {
|
||||||
@ -625,25 +624,19 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getExploreState(queries: PromQuery[]): Partial<ExploreUrlState> {
|
interpolateVariablesInQueries(queries: PromQuery[]): PromQuery[] {
|
||||||
let state: Partial<ExploreUrlState> = { datasource: this.name };
|
let expandedQueries = queries;
|
||||||
if (queries && queries.length > 0) {
|
if (queries && queries.length > 0) {
|
||||||
const expandedQueries = queries.map(query => {
|
expandedQueries = queries.map(query => {
|
||||||
const expandedQuery = {
|
const expandedQuery = {
|
||||||
...query,
|
...query,
|
||||||
|
datasource: this.name,
|
||||||
expr: this.templateSrv.replace(query.expr, {}, this.interpolateQueryExpr),
|
expr: this.templateSrv.replace(query.expr, {}, this.interpolateQueryExpr),
|
||||||
context: 'explore',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return expandedQuery;
|
return expandedQuery;
|
||||||
});
|
});
|
||||||
|
|
||||||
state = {
|
|
||||||
...state,
|
|
||||||
queries: expandedQueries,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return state;
|
return expandedQueries;
|
||||||
}
|
}
|
||||||
|
|
||||||
getQueryHints(query: PromQuery, result: any[]) {
|
getQueryHints(query: PromQuery, result: any[]) {
|
||||||
|
@ -305,6 +305,7 @@ export interface ExploreUrlState {
|
|||||||
range: RawTimeRange;
|
range: RawTimeRange;
|
||||||
ui: ExploreUIState;
|
ui: ExploreUIState;
|
||||||
originPanelId?: number;
|
originPanelId?: number;
|
||||||
|
context?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HistoryItem<TQuery extends DataQuery = DataQuery> {
|
export interface HistoryItem<TQuery extends DataQuery = DataQuery> {
|
||||||
|
Loading…
Reference in New Issue
Block a user