diff --git a/public/app/features/plugins/VariableQueryComponentLoader.tsx b/public/app/features/plugins/VariableQueryComponentLoader.tsx index c7bb826d302..631161b4e9b 100644 --- a/public/app/features/plugins/VariableQueryComponentLoader.tsx +++ b/public/app/features/plugins/VariableQueryComponentLoader.tsx @@ -14,7 +14,7 @@ async function loadComponent(module) { } /** @ngInject */ -function variableQueryEditorLoader() { +function variableQueryEditorLoader(templateSrv) { return { restrict: 'E', link: async (scope, elem) => { @@ -23,6 +23,7 @@ function variableQueryEditorLoader() { datasource: scope.currentDatasource, query: scope.current.query, onChange: scope.onQueryChange, + templateSrv, }; ReactDOM.render(, elem[0]); scope.$on('$destroy', () => { diff --git a/public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts b/public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts index 2dea8c0405a..8920fed989e 100644 --- a/public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts +++ b/public/app/plugins/datasource/stackdriver/StackdriverMetricFindQuery.ts @@ -1,7 +1,12 @@ import isString from 'lodash/isString'; import { alignmentPeriods } from './constants'; import { MetricFindQueryTypes } from './types'; -import { getMetricTypesByService, getAlignmentOptionsByMetric, getAggregationOptionsByMetric } from './functions'; +import { + getMetricTypesByService, + getAlignmentOptionsByMetric, + getAggregationOptionsByMetric, + getLabelKeys, +} from './functions'; export default class StackdriverMetricFindQuery { constructor(private datasource) {} @@ -37,37 +42,34 @@ export default class StackdriverMetricFindQuery { return []; } const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName); - return getMetricTypesByService(metricDescriptors, selectedService).map(s => ({ + return getMetricTypesByService(metricDescriptors, this.datasource.templateSrv.replace(selectedService)).map(s => ({ text: s.displayName, value: s.type, expandable: true, })); } - async handleLabelKeysQuery({ selectedQueryType, selectedMetricType, labelKey }) { + async handleLabelKeysQuery({ selectedMetricType }) { if (!selectedMetricType) { return []; } - const refId = 'handleLabelKeysQuery'; - const response = await this.datasource.getLabels(selectedMetricType, refId); - const labelKeys = response.meta - ? [...Object.keys(response.meta.resourceLabels), ...Object.keys(response.meta.metricLabels)] - : []; + const labelKeys = await getLabelKeys(this.datasource, selectedMetricType); return labelKeys.map(this.toFindQueryResult); } - async handleLabelValuesQuery({ selectedQueryType, selectedMetricType, labelKey }) { + async handleLabelValuesQuery({ selectedMetricType, labelKey }) { if (!selectedMetricType) { return []; } const refId = 'handleLabelValuesQuery'; const response = await this.datasource.getLabels(selectedMetricType, refId); - + const interpolatedKey = this.datasource.templateSrv.replace(labelKey); + const [name] = interpolatedKey.split('.').reverse(); let values = []; - if (response.meta && response.meta.metricLabels && response.meta.metricLabels.hasOwnProperty(labelKey)) { - values = response.meta.metricLabels[labelKey]; - } else if (response.meta && response.meta.resourceLabels && response.meta.resourceLabels.hasOwnProperty(labelKey)) { - values = response.meta.resourceLabels[labelKey]; + if (response.meta && response.meta.metricLabels && response.meta.metricLabels.hasOwnProperty(name)) { + values = response.meta.metricLabels[name]; + } else if (response.meta && response.meta.resourceLabels && response.meta.resourceLabels.hasOwnProperty(name)) { + values = response.meta.resourceLabels[name]; } return values.map(this.toFindQueryResult); @@ -87,7 +89,9 @@ export default class StackdriverMetricFindQuery { return []; } const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName); - const { valueType, metricKind } = metricDescriptors.find(m => m.type === selectedMetricType); + const { valueType, metricKind } = metricDescriptors.find( + m => m.type === this.datasource.templateSrv.replace(selectedMetricType) + ); return getAlignmentOptionsByMetric(valueType, metricKind).map(this.toFindQueryResult); } @@ -96,7 +100,9 @@ export default class StackdriverMetricFindQuery { return []; } const metricDescriptors = await this.datasource.getMetricTypes(this.datasource.projectName); - const { valueType, metricKind } = metricDescriptors.find(m => m.type === selectedMetricType); + const { valueType, metricKind } = metricDescriptors.find( + m => m.type === this.datasource.templateSrv.replace(selectedMetricType) + ); return getAggregationOptionsByMetric(valueType, metricKind).map(this.toFindQueryResult); } diff --git a/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx b/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx index 5143348f0fe..d1fc3d87288 100644 --- a/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx +++ b/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx @@ -14,6 +14,7 @@ const props: VariableQueryProps = { datasource: { getMetricTypes: async p => [], }, + templateSrv: { replace: s => s }, }; describe('VariableQueryEditor', () => { diff --git a/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx b/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx index 4ce5910e191..20eb451ce4b 100644 --- a/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import uniqBy from 'lodash/uniqBy'; import { VariableQueryProps } from 'app/types/plugins'; import SimpleSelect from './SimpleSelect'; -import { getMetricTypes } from '../functions'; +import { getMetricTypes, getLabelKeys } from '../functions'; import { MetricFindQueryTypes, VariableQueryData } from '../types'; export class StackdriverVariableQueryEditor extends PureComponent { @@ -40,7 +40,7 @@ export class StackdriverVariableQueryEditor extends PureComponent s.value === this.state.selectedService)) { + if (services.some(s => s.value === this.props.templateSrv.replace(this.state.selectedService))) { selectedService = this.state.selectedService; } else if (services && services.length > 0) { selectedService = services[0].value; @@ -49,6 +49,7 @@ export class StackdriverVariableQueryEditor extends PureComponent l === this.state.labelKey) ? this.state.labelKey : labels[0]; + const labels = await getLabelKeys(this.props.datasource, selectedMetricType); + const labelKey = labels.some(l => l === this.props.templateSrv.replace(this.state.labelKey)) + ? this.state.labelKey + : labels[0]; result = { labels, labelKey }; } return result; } + insertTemplateVariables(options) { + const templateVariables = this.props.templateSrv.variables.map(v => ({ name: `$${v.name}`, value: `$${v.name}` })); + return [...templateVariables, ...options]; + } + renderQueryTypeSwitch(queryType) { switch (queryType) { case MetricFindQueryTypes.MetricTypes: @@ -136,14 +143,14 @@ export class StackdriverVariableQueryEditor extends PureComponent this.onMetricTypeChange(e)} label="Metric Types" /> {queryType === MetricFindQueryTypes.LabelValues && ( ({ value: l, name: l }))} + options={this.insertTemplateVariables(this.state.labels.map(l => ({ value: l, name: l })))} onValueChange={e => this.onLabelKeyChange(e)} label="Label Keys" /> @@ -162,7 +169,7 @@ export class StackdriverVariableQueryEditor extends PureComponent this.onMetricTypeChange(e)} label="Metric Types" /> diff --git a/public/app/plugins/datasource/stackdriver/functions.ts b/public/app/plugins/datasource/stackdriver/functions.ts index 79e8aa30325..0b1a37aa933 100644 --- a/public/app/plugins/datasource/stackdriver/functions.ts +++ b/public/app/plugins/datasource/stackdriver/functions.ts @@ -3,12 +3,12 @@ import { alignOptions, aggOptions } from './constants'; export const getMetricTypesByService = (metricDescriptors, service) => metricDescriptors.filter(m => m.service === service); -export const getMetricTypes = (metricDescriptors, metricType, selectedService) => { +export const getMetricTypes = (metricDescriptors, metricType, interpolatedMetricType, selectedService) => { const metricTypes = getMetricTypesByService(metricDescriptors, selectedService).map(m => ({ value: m.type, name: m.displayName, })); - const metricTypeExistInArray = metricTypes.some(m => m.value === metricType); + const metricTypeExistInArray = metricTypes.some(m => m.value === interpolatedMetricType); const selectedMetricType = metricTypeExistInArray ? metricType : metricTypes[0].value; return { metricTypes, @@ -31,3 +31,15 @@ export const getAggregationOptionsByMetric = (valueType, metricKind) => { return i.valueTypes.indexOf(valueType) !== -1 && i.metricKinds.indexOf(metricKind) !== -1; }); }; + +export const getLabelKeys = async (datasource, selectedMetricType) => { + const refId = 'handleLabelKeysQuery'; + const response = await datasource.getLabels(selectedMetricType, refId); + const labelKeys = response.meta + ? [ + ...Object.keys(response.meta.resourceLabels).map(l => `resource.label.${l}`), + ...Object.keys(response.meta.metricLabels).map(l => `metric.label.${l}`), + ] + : []; + return labelKeys; +}; diff --git a/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts b/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts index 03fa3b6cecb..628cc494242 100644 --- a/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts +++ b/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts @@ -65,7 +65,9 @@ export class StackdriverAggregationCtrl { const selectedAlignment = this.alignOptions.find( ap => ap.value === this.templateSrv.replace(this.target.aggregation.perSeriesAligner) ); - return `${kbn.secondsToHms(this.$scope.alignmentPeriod)} interval (${selectedAlignment.text})`; + return `${kbn.secondsToHms(this.$scope.alignmentPeriod)} interval (${ + selectedAlignment ? selectedAlignment.text : '' + })`; } deselectAggregationOption(notValidOptionValue: string) { diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 95d27afd496..9e3264be70c 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -104,4 +104,5 @@ export interface VariableQueryProps { query: any; onChange: (query: any, definition: string) => void; datasource: any; + templateSrv: any; }