Browse Source

feature for issue #9911

Brian Gann 8 years ago
parent
commit
b316dfea98

+ 78 - 2
public/app/features/templating/specs/template_srv.jest.ts

@@ -31,12 +31,40 @@ describe('templateSrv', function() {
       expect(target).toBe('this.mupp.filters');
       expect(target).toBe('this.mupp.filters');
     });
     });
 
 
+    it('should replace ${test} with scoped value', function() {
+      var target = _templateSrv.replace('this.${test}.filters', {
+        test: { value: 'mupp', text: 'asd' },
+      });
+      expect(target).toBe('this.mupp.filters');
+    });
+
+    it('should replace ${test:glob} with scoped value', function() {
+      var target = _templateSrv.replace('this.${test:glob}.filters', {
+        test: { value: 'mupp', text: 'asd' },
+      });
+      expect(target).toBe('this.mupp.filters');
+    });
+
     it('should replace $test with scoped text', function() {
     it('should replace $test with scoped text', function() {
       var target = _templateSrv.replaceWithText('this.$test.filters', {
       var target = _templateSrv.replaceWithText('this.$test.filters', {
         test: { value: 'mupp', text: 'asd' },
         test: { value: 'mupp', text: 'asd' },
       });
       });
       expect(target).toBe('this.asd.filters');
       expect(target).toBe('this.asd.filters');
     });
     });
+
+    it('should replace ${test} with scoped text', function() {
+      var target = _templateSrv.replaceWithText('this.${test}.filters', {
+        test: { value: 'mupp', text: 'asd' },
+      });
+      expect(target).toBe('this.asd.filters');
+    });
+
+    it('should replace ${test:glob} with scoped text', function() {
+      var target = _templateSrv.replaceWithText('this.${test:glob}.filters', {
+        test: { value: 'mupp', text: 'asd' },
+      });
+      expect(target).toBe('this.asd.filters');
+    });
   });
   });
 
 
   describe('getAdhocFilters', function() {
   describe('getAdhocFilters', function() {
@@ -79,18 +107,34 @@ describe('templateSrv', function() {
       ]);
       ]);
     });
     });
 
 
+
     it('should replace $test with globbed value', function() {
     it('should replace $test with globbed value', function() {
       var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
       var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
       expect(target).toBe('this.{value1,value2}.filters');
       expect(target).toBe('this.{value1,value2}.filters');
     });
     });
 
 
+    it('should replace ${test} with globbed value', function() {
+      var target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
+      expect(target).toBe('this.{value1,value2}.filters');
+    });
+
+    it('should replace ${test:glob} with globbed value', function() {
+      var target = _templateSrv.replace('this.${test:glob}.filters', {});
+      expect(target).toBe('this.{value1,value2}.filters');
+    });
+
     it('should replace $test with piped value', function() {
     it('should replace $test with piped value', function() {
       var target = _templateSrv.replace('this=$test', {}, 'pipe');
       var target = _templateSrv.replace('this=$test', {}, 'pipe');
       expect(target).toBe('this=value1|value2');
       expect(target).toBe('this=value1|value2');
     });
     });
 
 
-    it('should replace $test with piped value', function() {
-      var target = _templateSrv.replace('this=$test', {}, 'pipe');
+    it('should replace ${test} with piped value', function() {
+      var target = _templateSrv.replace('this=${test}', {}, 'pipe');
+      expect(target).toBe('this=value1|value2');
+    });
+
+    it('should replace ${test:pipe} with piped value', function() {
+      var target = _templateSrv.replace('this=${test:pipe}', {});
       expect(target).toBe('this=value1|value2');
       expect(target).toBe('this=value1|value2');
     });
     });
   });
   });
@@ -111,6 +155,16 @@ describe('templateSrv', function() {
       var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
       var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
       expect(target).toBe('this.{value1,value2}.filters');
       expect(target).toBe('this.{value1,value2}.filters');
     });
     });
+
+    it('should replace ${test} with formatted all value', function() {
+      var target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
+      expect(target).toBe('this.{value1,value2}.filters');
+    });
+
+    it('should replace ${test:glob} with formatted all value', function() {
+      var target = _templateSrv.replace('this.${test:glob}.filters', {});
+      expect(target).toBe('this.{value1,value2}.filters');
+    });
   });
   });
 
 
   describe('variable with all option and custom value', function() {
   describe('variable with all option and custom value', function() {
@@ -131,6 +185,16 @@ describe('templateSrv', function() {
       expect(target).toBe('this.*.filters');
       expect(target).toBe('this.*.filters');
     });
     });
 
 
+    it('should replace ${test} with formatted all value', function() {
+      var target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
+      expect(target).toBe('this.*.filters');
+    });
+
+    it('should replace ${test:glob} with formatted all value', function() {
+      var target = _templateSrv.replace('this.${test:glob}.filters', {});
+      expect(target).toBe('this.*.filters');
+    });
+
     it('should not escape custom all value', function() {
     it('should not escape custom all value', function() {
       var target = _templateSrv.replace('this.$test', {}, 'regex');
       var target = _templateSrv.replace('this.$test', {}, 'regex');
       expect(target).toBe('this.*');
       expect(target).toBe('this.*');
@@ -143,6 +207,18 @@ describe('templateSrv', function() {
       var target = _templateSrv.replace('this:$test', {}, 'lucene');
       var target = _templateSrv.replace('this:$test', {}, 'lucene');
       expect(target).toBe('this:value\\/4');
       expect(target).toBe('this:value\\/4');
     });
     });
+
+    it('should properly escape ${test} with lucene escape sequences', function() {
+      initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'value/4' } }]);
+      var target = _templateSrv.replace('this:${test}', {}, 'lucene');
+      expect(target).toBe('this:value\\/4');
+    });
+
+    it('should properly escape ${test:lucene} with lucene escape sequences', function() {
+      initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'value/4' } }]);
+      var target = _templateSrv.replace('this:${test:lucene}', {});
+      expect(target).toBe('this:value\\/4');
+    });
   });
   });
 
 
   describe('format variable to string values', function() {
   describe('format variable to string values', function() {

+ 13 - 10
public/app/features/templating/template_srv.ts

@@ -8,7 +8,7 @@ function luceneEscape(value) {
 export class TemplateSrv {
 export class TemplateSrv {
   variables: any[];
   variables: any[];
 
 
-  private regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
+  private regex = /\$(\w+)|\[\[([\s\S]+?)\]\]|\${(\w+):?(\w+)?}/g;
   private index = {};
   private index = {};
   private grafanaVariables = {};
   private grafanaVariables = {};
   private builtIns = {};
   private builtIns = {};
@@ -89,6 +89,9 @@ export class TemplateSrv {
         }
         }
 
 
         var escapedValues = _.map(value, kbn.regexEscape);
         var escapedValues = _.map(value, kbn.regexEscape);
+        if (escapedValues.length === 1) {
+          return escapedValues[0];
+        }
         return '(' + escapedValues.join('|') + ')';
         return '(' + escapedValues.join('|') + ')';
       }
       }
       case 'lucene': {
       case 'lucene': {
@@ -140,8 +143,8 @@ export class TemplateSrv {
 
 
     str = _.escape(str);
     str = _.escape(str);
     this.regex.lastIndex = 0;
     this.regex.lastIndex = 0;
-    return str.replace(this.regex, (match, g1, g2) => {
-      if (this.index[g1 || g2] || this.builtIns[g1 || g2]) {
+    return str.replace(this.regex, (match, g1, g2, g3) => {
+      if (this.index[g1 || g2 || g3] || this.builtIns[g1 || g2 || g3]) {
         return '<span class="template-variable">' + match + '</span>';
         return '<span class="template-variable">' + match + '</span>';
       }
       }
       return match;
       return match;
@@ -167,11 +170,11 @@ export class TemplateSrv {
     var variable, systemValue, value;
     var variable, systemValue, value;
     this.regex.lastIndex = 0;
     this.regex.lastIndex = 0;
 
 
-    return target.replace(this.regex, (match, g1, g2) => {
-      variable = this.index[g1 || g2];
-
+    return target.replace(this.regex, (match, g1, g2, g3, g4) => {
+      variable = this.index[g1 || g2 || g3];
+      format = g4 || format;
       if (scopedVars) {
       if (scopedVars) {
-        value = scopedVars[g1 || g2];
+        value = scopedVars[g1 || g2 || g3];
         if (value) {
         if (value) {
           return this.formatValue(value.value, format, variable);
           return this.formatValue(value.value, format, variable);
         }
         }
@@ -212,15 +215,15 @@ export class TemplateSrv {
     var variable;
     var variable;
     this.regex.lastIndex = 0;
     this.regex.lastIndex = 0;
 
 
-    return target.replace(this.regex, (match, g1, g2) => {
+    return target.replace(this.regex, (match, g1, g2, g3) => {
       if (scopedVars) {
       if (scopedVars) {
-        var option = scopedVars[g1 || g2];
+        var option = scopedVars[g1 || g2 || g3];
         if (option) {
         if (option) {
           return option.text;
           return option.text;
         }
         }
       }
       }
 
 
-      variable = this.index[g1 || g2];
+      variable = this.index[g1 || g2 || g3];
       if (!variable) {
       if (!variable) {
         return match;
         return match;
       }
       }