فهرست منبع

aliasByNode support for second node param, Closes #167

Torkel Ödegaard 11 سال پیش
والد
کامیت
b2aca66e2d
3فایلهای تغییر یافته به همراه108 افزوده شده و 16 حذف شده
  1. 41 11
      src/app/directives/graphiteFuncEditor.js
  2. 31 4
      src/app/services/graphite/gfunc.js
  3. 36 1
      src/test/specs/gfunc-specs.js

+ 41 - 11
src/app/directives/graphiteFuncEditor.js

@@ -29,6 +29,8 @@ function (angular, _, $) {
           var $funcControls = $(funcControlsTemplate);
           var $funcControls = $(funcControlsTemplate);
           var func = $scope.func;
           var func = $scope.func;
           var funcDef = func.def;
           var funcDef = func.def;
+          var scheduledRelink = false;
+          var paramCountAtLink = 0;
 
 
           function clickFuncParam(paramIndex) {
           function clickFuncParam(paramIndex) {
             /*jshint validthis:true */
             /*jshint validthis:true */
@@ -51,17 +53,33 @@ function (angular, _, $) {
             }
             }
           }
           }
 
 
+          function scheduledRelinkIfNeeded() {
+            if (paramCountAtLink === func.params.length) {
+              return;
+            }
+
+            if (!scheduledRelink) {
+              scheduledRelink = true;
+              setTimeout(function() {
+                relink();
+                scheduledRelink = false;
+              }, 200);
+            }
+          }
+
           function inputBlur(paramIndex) {
           function inputBlur(paramIndex) {
             /*jshint validthis:true */
             /*jshint validthis:true */
 
 
             var $input = $(this);
             var $input = $(this);
             var $link = $input.prev();
             var $link = $input.prev();
 
 
-            if ($input.val() !== '') {
+            if ($input.val() !== '' || func.def.params[paramIndex].optional) {
               $link.text($input.val());
               $link.text($input.val());
-
+              
               func.updateParam($input.val(), paramIndex);
               func.updateParam($input.val(), paramIndex);
-              $scope.$apply($scope.targetChanged);
+              scheduledRelinkIfNeeded();
+              
+              $scope.$apply($scope.targetChanged);              
             }
             }
 
 
             $input.hide();
             $input.hide();
@@ -129,9 +147,19 @@ function (angular, _, $) {
             $funcLink.appendTo(elem);
             $funcLink.appendTo(elem);
 
 
             _.each(funcDef.params, function(param, index) {
             _.each(funcDef.params, function(param, index) {
+              if (param.optional && !func.params[index]) {
+                return;
+              }
+
+              if (index > 0) {
+                $('<span>, </span>').appendTo(elem);
+              }
+
               var $paramLink = $('<a ng-click="" class="graphite-func-param-link">' + func.params[index] + '</a>');
               var $paramLink = $('<a ng-click="" class="graphite-func-param-link">' + func.params[index] + '</a>');
               var $input = $(paramTemplate);
               var $input = $(paramTemplate);
 
 
+              paramCountAtLink++;
+
               $paramLink.appendTo(elem);
               $paramLink.appendTo(elem);
               $input.appendTo(elem);
               $input.appendTo(elem);
 
 
@@ -140,10 +168,6 @@ function (angular, _, $) {
               $input.keypress(_.partial(inputKeyPress, index));
               $input.keypress(_.partial(inputKeyPress, index));
               $paramLink.click(_.partial(clickFuncParam, index));
               $paramLink.click(_.partial(clickFuncParam, index));
 
 
-              if (index !== funcDef.params.length - 1) {
-                $('<span>, </span>').appendTo(elem);
-              }
-
               if (funcDef.params[index].options) {
               if (funcDef.params[index].options) {
                 addTypeahead($input, index);
                 addTypeahead($input, index);
               }
               }
@@ -200,10 +224,16 @@ function (angular, _, $) {
             });
             });
           }
           }
 
 
-          addElementsAndCompile();
-          ifJustAddedFocusFistParam();
-          registerFuncControlsToggle();
-          registerFuncControlsActions();
+          function relink() {
+            elem.children().remove();
+
+            addElementsAndCompile();
+            ifJustAddedFocusFistParam();
+            registerFuncControlsToggle();
+            registerFuncControlsActions();            
+          }
+
+          relink();
         }
         }
       };
       };
 
 

+ 31 - 4
src/app/services/graphite/gfunc.js

@@ -132,7 +132,10 @@ function (_) {
   addFuncDef({
   addFuncDef({
     name: 'aliasByNode',
     name: 'aliasByNode',
     category: categories.Special,
     category: categories.Special,
-    params: [ { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] } ],
+    params: [
+      { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
+      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+    ],
     defaultParams: [3]
     defaultParams: [3]
   });
   });
 
 
@@ -340,13 +343,33 @@ function (_) {
     return str + parameters.join(',') + ')';
     return str + parameters.join(',') + ')';
   };
   };
 
 
-  FuncInstance.prototype.updateParam = function(strValue, index) {
-    if (this.def.params[index].type === 'int') {
+  FuncInstance.prototype._hasMultipleParamsInString = function(strValue, index) {
+    if (strValue.indexOf(',') === -1) {
+      return false;
+    }
+
+    return this.def.params[index + 1] && this.def.params[index + 1].optional;
+  };
+
+  FuncInstance.prototype.updateParam = function(strValue, index) {    
+    // handle optional parameters
+    // if string contains ',' and next param is optional, split and update both
+    if (this._hasMultipleParamsInString(strValue, index)) {      
+      _.each(strValue.split(','), function(partVal, idx) {
+        this.updateParam(partVal.trim(), idx);
+      }, this);      
+      return;
+    }
+
+    if (strValue === '' && this.def.params[index].optional) {                  
+      this.params.splice(index, 1);      
+    }
+    else if (this.def.params[index].type === 'int') {
       this.params[index] = parseInt(strValue, 10);
       this.params[index] = parseInt(strValue, 10);
     }
     }
     else {
     else {
       this.params[index] = strValue;
       this.params[index] = strValue;
-    }
+    }    
 
 
     this.updateText();
     this.updateText();
   };
   };
@@ -359,6 +382,10 @@ function (_) {
 
 
     var text = this.def.name + '(';
     var text = this.def.name + '(';
     _.each(this.def.params, function(param, index) {
     _.each(this.def.params, function(param, index) {
+      if (param.optional && this.params[index] === undefined) {
+        return;
+      }
+
       text += this.params[index] + ', ';
       text += this.params[index] + ', ';
     }, this);
     }, this);
     text = text.substring(0, text.length - 2);
     text = text.substring(0, text.length - 2);

+ 36 - 1
src/test/specs/gfunc-specs.js

@@ -57,12 +57,47 @@ define([
   });
   });
 
 
   describe('when requesting function categories', function() {
   describe('when requesting function categories', function() {
-
     it('should return function categories', function() {
     it('should return function categories', function() {
       var catIndex = gfunc.getCategories();
       var catIndex = gfunc.getCategories();
       expect(catIndex.Special.length).to.be.greaterThan(8);
       expect(catIndex.Special.length).to.be.greaterThan(8);
     });
     });
+  });
+
+  describe('when updating func param', function() {
+    it('should update param value and update text representation', function() {
+      var func = gfunc.createFuncInstance('summarize');
+      func.updateParam('1h', 0);
+      expect(func.params[0]).to.be('1h');
+      expect(func.text).to.be('summarize(1h, sum)');
+    });
+
+
+  });
+
+  describe('when updating func param with optional second parameter', function() {
+    it('should update value and text', function() {
+      var func = gfunc.createFuncInstance('aliasByNode');
+      func.updateParam('1', 0);
+      expect(func.params[0]).to.be(1);
+    });
 
 
+    it('should slit text and put value in second param', function() {
+      var func = gfunc.createFuncInstance('aliasByNode');
+      func.updateParam('4,-5', 0);
+      expect(func.params[0]).to.be(4);
+      expect(func.params[1]).to.be(-5);
+      expect(func.text).to.be('aliasByNode(4, -5)');
+    });
+
+    it('should remove second param when empty string is set', function() {
+      var func = gfunc.createFuncInstance('aliasByNode');
+      func.updateParam('4,-5', 0);
+      func.updateParam('', 1);
+      expect(func.params[0]).to.be(4);
+      expect(func.params[1]).to.be(undefined);
+      expect(func.text).to.be('aliasByNode(4)');
+    });    
   });
   });
 
 
 });
 });
+