diff --git a/CHANGELOG.md b/CHANGELOG.md index 60445de8b35..07c1e5bbf5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Filter editing has gotten its own edit pane with much improved UI and options - [Issue #296](https://github.com/grafana/grafana/issues/296). Templating: Can now retrieve variable values from a non-default data source - [Issue #219](https://github.com/grafana/grafana/issues/219). Templating: Template variable value selection is now a typeahead autocomplete dropdown +- [Issue #760](https://github.com/grafana/grafana/issues/760). Templating: Extend template variable syntax to include $variable syntax replacement **InfluxDB Breaking changes** - To better support templating, fill(0) and group by time low limit some changes has been made to the editor and query model schema diff --git a/src/app/controllers/graphiteTarget.js b/src/app/controllers/graphiteTarget.js index 23f7cd5b598..5cd1353988c 100644 --- a/src/app/controllers/graphiteTarget.js +++ b/src/app/controllers/graphiteTarget.js @@ -165,7 +165,7 @@ function (angular, _, config, gfunc, Parser) { _.each(templateSrv.variables, function(variable) { $scope.altSegments.unshift(new MetricSegment({ type: 'template', - value: '$' + variable.name + ']]', + value: '$' + variable.name, expandable: true, })); }); @@ -297,13 +297,7 @@ function (angular, _, config, gfunc, Parser) { this.value = options.value; this.type = options.type; this.expandable = options.expandable; - - if (options.type === 'template') { - this.html = $sce.trustAsHtml(options.value); - } - else { - this.html = $sce.trustAsHtml(this.value); - } + this.html = $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value)); } }); diff --git a/src/app/directives/graphiteFuncEditor.js b/src/app/directives/graphiteFuncEditor.js index db92240bb40..dff8003f54f 100644 --- a/src/app/directives/graphiteFuncEditor.js +++ b/src/app/directives/graphiteFuncEditor.js @@ -8,7 +8,7 @@ function (angular, _, $) { angular .module('grafana.directives') - .directive('graphiteFuncEditor', function($compile) { + .directive('graphiteFuncEditor', function($compile, templateSrv) { var funcSpanTemplate = '{{func.def.name}}('; var paramTemplate = ', ').appendTo(elem); } - var $paramLink = $('' + func.params[index] + ''); + var paramValue = templateSrv.highlightVariablesAsHtml(func.params[index]); + var $paramLink = $('' + paramValue + ''); var $input = $(paramTemplate); paramCountAtLink++; diff --git a/src/app/partials/panelgeneral.html b/src/app/partials/panelgeneral.html index 40b46ca0618..c038c807519 100644 --- a/src/app/partials/panelgeneral.html +++ b/src/app/partials/panelgeneral.html @@ -10,6 +10,5 @@
- diff --git a/src/app/services/templateSrv.js b/src/app/services/templateSrv.js index 9e9dafe2c95..cf76dd5bfaa 100644 --- a/src/app/services/templateSrv.js +++ b/src/app/services/templateSrv.js @@ -40,9 +40,27 @@ function (angular, _) { this._templateData[name] = value; }; + this.variableExists = function(expression) { + this.regex.lastIndex = 0; + var match = this.regex.exec(expression); + return match && (self._templateData[match[1] || match[2]] !== void 0); + }; + + this.highlightVariablesAsHtml = function(str) { + if (!str) { return str; } + + this.regex.lastIndex = 0; + return str.replace(this.regex, function(match, g1, g2) { + if (self._templateData[g1 || g2]) { + return '' + match + ''; + } + }); + }; + this.replace = function(target) { if (!target) { return; } + this.regex.lastIndex = 0; return target.replace(this.regex, function(match, g1, g2) { return self._templateData[g1 || g2] || match; }); diff --git a/src/css/less/grafana.less b/src/css/less/grafana.less index d6c4d38f618..01b2004fe11 100644 --- a/src/css/less/grafana.less +++ b/src/css/less/grafana.less @@ -479,3 +479,8 @@ select.grafana-target-segment-input { color: darken(@gray, 25%); a { color: darken(@gray, 25%); } } + +.template-variable { + color: @variable; +} + diff --git a/src/css/less/variables.dark.less b/src/css/less/variables.dark.less index 605a1672c47..608dfb609b0 100644 --- a/src/css/less/variables.dark.less +++ b/src/css/less/variables.dark.less @@ -24,6 +24,7 @@ @orange: #FF8800; @pink: #FF4444; @purple: #9933CC; +@variable: #32D1DF; // grafana Variables // ------------------------- diff --git a/src/css/less/variables.light.less b/src/css/less/variables.light.less index b7cdc5a6271..c3453fdd92b 100644 --- a/src/css/less/variables.light.less +++ b/src/css/less/variables.light.less @@ -28,6 +28,7 @@ @orange: #FF7518; @pink: #E671B8; @purple: #9954BB; +@variable: #32D1DF; // grafana Variables // ------------------------- diff --git a/src/test/specs/helpers.js b/src/test/specs/helpers.js index 7293678b6a2..e973058da96 100644 --- a/src/test/specs/helpers.js +++ b/src/test/specs/helpers.js @@ -95,6 +95,8 @@ define([ this.replace = function(text) { return _.template(text, this.data, this.templateSettings); }; + this.variableExists = function() { return false; }; + this.highlightVariablesAsHtml = function(str) { return str; }; this.setGrafanaVariable = function(name, value) { this.data[name] = value; }; diff --git a/src/test/specs/templateSrv-specs.js b/src/test/specs/templateSrv-specs.js index c97f2e2caf4..ecd046ac8fe 100644 --- a/src/test/specs/templateSrv-specs.js +++ b/src/test/specs/templateSrv-specs.js @@ -29,6 +29,34 @@ define([ }); }); + describe('can check if variable exists', function() { + beforeEach(function() { + _templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]); + }); + + it('should return true if exists', function() { + var result = _templateSrv.variableExists('$test'); + expect(result).to.be(true); + }); + }); + + describe('can hightlight variables in string', function() { + beforeEach(function() { + _templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]); + }); + + it('should insert html', function() { + var result = _templateSrv.highlightVariablesAsHtml('$test'); + expect(result).to.be('$test'); + }); + + it('should insert html anywhere in string', function() { + var result = _templateSrv.highlightVariablesAsHtml('this $test ok'); + expect(result).to.be('this $test ok'); + }); + + }); + describe('updateTemplateData with simple value', function() { beforeEach(function() { _templateSrv.init([{ name: 'test', current: { value: 'muuuu' } }]);