Просмотр исходного кода

feat(cloudwatch): refactoring and editor improvements, #684

Torkel Ödegaard 10 лет назад
Родитель
Сommit
c34c3ac845

+ 4 - 5
public/app/plugins/datasource/cloudwatch/datasource.js

@@ -124,11 +124,12 @@ function (angular, _) {
       };
       };
 
 
       return this.awsRequest(request).then(function(result) {
       return this.awsRequest(request).then(function(result) {
-        console.log(result);
         return _.chain(result.Metrics).map(function(metric) {
         return _.chain(result.Metrics).map(function(metric) {
           return _.pluck(metric.Dimensions, 'Value');
           return _.pluck(metric.Dimensions, 'Value');
         }).flatten().uniq().sortBy(function(name) {
         }).flatten().uniq().sortBy(function(name) {
           return name;
           return name;
+        }).map(function(value) {
+          return {value: value, text: value};
         }).value();
         }).value();
       });
       });
     };
     };
@@ -137,10 +138,7 @@ function (angular, _) {
       return this.awsRequest({
       return this.awsRequest({
         region: region,
         region: region,
         action: 'DescribeInstances',
         action: 'DescribeInstances',
-        parameters: {
-          filter: filters,
-          instanceIds: instanceIds
-        }
+        parameters: { filter: filters, instanceIds: instanceIds }
       });
       });
     };
     };
 
 
@@ -247,6 +245,7 @@ function (angular, _) {
     function transformMetricData(md, options) {
     function transformMetricData(md, options) {
       var result = [];
       var result = [];
 
 
+      console.log(options);
       var dimensionPart = templateSrv.replace(JSON.stringify(options.dimensions));
       var dimensionPart = templateSrv.replace(JSON.stringify(options.dimensions));
       _.each(getActivatedStatistics(options.statistics), function(s) {
       _.each(getActivatedStatistics(options.statistics), function(s) {
         var originalSettings = _.templateSettings;
         var originalSettings = _.templateSettings;

+ 2 - 32
public/app/plugins/datasource/cloudwatch/partials/query.editor.html

@@ -55,40 +55,10 @@
 		<li class="tight-form-item tight-form-align" style="width: 100px">
 		<li class="tight-form-item tight-form-align" style="width: 100px">
 			Dimensions
 			Dimensions
 		</li>
 		</li>
-		<li ng-repeat="(key, value) in target.escapedDimensions track by $index" class="tight-form-item">
-			{{key}}&nbsp;=&nbsp;{{value}}
-			<a ng-click="removeDimension(key)">
-				<i class="fa fa-remove"></i>
-			</a>
-		</li>
-
-		<li class="tight-form-item" ng-hide="addDimensionMode">
-			<a ng-click="addDimension()">
-				<i class="fa fa-plus"></i>
-			</a>
-		</li>
-
-		<li ng-show="addDimensionMode">
-			<input type="text"
-			class="input-small tight-form-input"
-			spellcheck='false'
-			bs-typeahead="suggestDimensionKeys"
-			data-min-length=0 data-items=100
-			ng-model="target.currentDimensionKey"
-			placeholder="key">
-			<input type="text"
-			class="input-small tight-form-input"
-			spellcheck='false'
-			bs-typeahead="suggestDimensionValues"
-			data-min-length=0 data-items=100
-			ng-model="target.currentDimensionValue"
-			placeholder="value">
-			<a ng-click="addDimension()">
-				add dimension
-			</a>
+		<li ng-repeat="segment in dimSegments">
+			<metric-segment segment="segment" get-options="getDimSegments(segment, $index)" on-change="dimSegmentChanged(segment, $index)"></metric-segment>
 		</li>
 		</li>
 	</ul>
 	</ul>
-
 	<div class="clearfix"></div>
 	<div class="clearfix"></div>
 </div>
 </div>
 
 

+ 78 - 47
public/app/plugins/datasource/cloudwatch/query_ctrl.js

@@ -7,36 +7,106 @@ function (angular, _) {
 
 
   var module = angular.module('grafana.controllers');
   var module = angular.module('grafana.controllers');
 
 
-  module.controller('CloudWatchQueryCtrl', function($scope, templateSrv, uiSegmentSrv) {
+  module.controller('CloudWatchQueryCtrl', function($scope, templateSrv, uiSegmentSrv, $q) {
 
 
     $scope.init = function() {
     $scope.init = function() {
       $scope.target.namespace = $scope.target.namespace || '';
       $scope.target.namespace = $scope.target.namespace || '';
       $scope.target.metricName = $scope.target.metricName || '';
       $scope.target.metricName = $scope.target.metricName || '';
+      $scope.target.statistics = $scope.target.statistics || {Average: true};
       $scope.target.dimensions = $scope.target.dimensions || {};
       $scope.target.dimensions = $scope.target.dimensions || {};
-      $scope.target.escapedDimensions = this.escapeDimensions($scope.target.dimensions);
-      $scope.target.statistics = $scope.target.statistics || {};
       $scope.target.period = $scope.target.period || 60;
       $scope.target.period = $scope.target.period || 60;
       $scope.target.region = $scope.target.region || $scope.datasource.getDefaultRegion();
       $scope.target.region = $scope.target.region || $scope.datasource.getDefaultRegion();
-      $scope.target.errors = validateTarget();
 
 
       $scope.regionSegment =  uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
       $scope.regionSegment =  uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
       $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
       $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
       $scope.metricSegment = uiSegmentSrv.getSegmentForValue($scope.target.metricName, 'select metric');
       $scope.metricSegment = uiSegmentSrv.getSegmentForValue($scope.target.metricName, 'select metric');
+
+      $scope.dimSegments = _.reduce($scope.target.dimensions, function(memo, value, key) {
+        memo.push(uiSegmentSrv.newKey(key));
+        memo.push(uiSegmentSrv.newOperator("="));
+        memo.push(uiSegmentSrv.newKeyValue(value));
+        return memo;
+      }, []);
+
+      $scope.fixSegments();
+      $scope.removeDimSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove dimension --'});
+    };
+
+    $scope.fixSegments = function() {
+      var count = $scope.dimSegments.length;
+      var lastSegment = $scope.dimSegments[Math.max(count-1, 0)];
+
+      if (!lastSegment || lastSegment.type !== 'plus-button') {
+        $scope.dimSegments.push(uiSegmentSrv.newPlusButton());
+      }
+    };
+
+    $scope.getDimSegments = function(segment) {
+      if (segment.type === 'operator') { return $q.when([]); }
+
+      var target = $scope.target;
+      var query = $q.when([]);
+
+      if (segment.type === 'key' || segment.type === 'plus-button') {
+        query = $scope.datasource.getDimensionKeys($scope.target.namespace);
+      } else if (segment.type === 'value')  {
+        query = $scope.datasource.getDimensionValues(target.region, target.namespace, target.metricName, {});
+      }
+
+      return query.then($scope.transformToSegments(true)).then(function(results) {
+        if (segment.type === 'key') {
+          results.splice(0, 0, angular.copy($scope.removeDimSegment));
+        }
+        return results;
+      });
+    };
+
+    $scope.dimSegmentChanged = function(segment, index) {
+      $scope.dimSegments[index] = segment;
+
+      if (segment.value === $scope.removeDimSegment.value) {
+        $scope.dimSegments.splice(index, 3);
+      }
+      else if (segment.type === 'plus-button') {
+        $scope.dimSegments.push(uiSegmentSrv.newOperator('='));
+        $scope.dimSegments.push(uiSegmentSrv.newFake('select dimension value', 'value', 'query-segment-value'));
+        segment.type = 'key';
+        segment.cssClass = 'query-segment-key';
+      }
+
+      $scope.fixSegments();
+      $scope.syncDimSegmentsWithModel();
+      $scope.get_data();
+    };
+
+    $scope.syncDimSegmentsWithModel = function() {
+      var dims = {};
+      var length = $scope.dimSegments.length;
+
+      for (var i = 0; i < length - 2; i += 3) {
+        var keySegment = $scope.dimSegments[i];
+        var valueSegment = $scope.dimSegments[i + 2];
+        if (!valueSegment.fake) {
+          dims[keySegment.value] = valueSegment.value;
+        }
+      }
+
+      $scope.target.dimensions = dims;
     };
     };
 
 
     $scope.getRegions = function() {
     $scope.getRegions = function() {
       return $scope.datasource.metricFindQuery('regions()')
       return $scope.datasource.metricFindQuery('regions()')
-        .then($scope.transformToSegments(true));
+      .then($scope.transformToSegments(true));
     };
     };
 
 
     $scope.getNamespaces = function() {
     $scope.getNamespaces = function() {
       return $scope.datasource.metricFindQuery('namespaces()')
       return $scope.datasource.metricFindQuery('namespaces()')
-        .then($scope.transformToSegments(true));
+      .then($scope.transformToSegments(true));
     };
     };
 
 
     $scope.getMetrics = function() {
     $scope.getMetrics = function() {
       return $scope.datasource.metricFindQuery('metrics(' + $scope.target.namespace + ')')
       return $scope.datasource.metricFindQuery('metrics(' + $scope.target.namespace + ')')
-        .then($scope.transformToSegments(true));
+      .then($scope.transformToSegments(true));
     };
     };
 
 
     $scope.regionChanged = function() {
     $scope.regionChanged = function() {
@@ -71,40 +141,12 @@ function (angular, _) {
     };
     };
 
 
     $scope.refreshMetricData = function() {
     $scope.refreshMetricData = function() {
-      $scope.target.errors = validateTarget($scope.target);
-
-      // this does not work so good
-      if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
+      if (!_.isEqual($scope.oldTarget, $scope.target)) {
         $scope.oldTarget = angular.copy($scope.target);
         $scope.oldTarget = angular.copy($scope.target);
         $scope.get_data();
         $scope.get_data();
       }
       }
     };
     };
 
 
-    $scope.suggestDimensionKeys = function(query, callback) { // jshint unused:false
-      $scope.datasource.getDimensionKeys($scope.target.namespace).then(function(result) {
-        callback(_.pluck(result, 'text'));
-      });
-    };
-
-    // TODO: Removed template variables from the suggest
-    // add this feature back after improving the editor
-    $scope.suggestDimensionValues = function(query, callback) {
-      if (!$scope.target.namespace || !$scope.target.metricName) {
-        return callback([]);
-      }
-
-      return $scope.datasource.getDimensionValues(
-        $scope.target.region,
-        $scope.target.namespace,
-        $scope.target.metricName,
-        $scope.target.dimensions
-      ).then(function(result) {
-        callback(result);
-      }, function() {
-        callback([]);
-      });
-    };
-
     $scope.addDimension = function() {
     $scope.addDimension = function() {
       if (!$scope.addDimensionMode) {
       if (!$scope.addDimensionMode) {
         $scope.addDimensionMode = true;
         $scope.addDimensionMode = true;
@@ -147,17 +189,6 @@ function (angular, _) {
       $scope.refreshMetricData();
       $scope.refreshMetricData();
     };
     };
 
 
-    // TODO: validate target
-    function validateTarget() {
-      var errs = {};
-
-      if ($scope.target.period < 60 || ($scope.target.period % 60) !== 0) {
-        errs.period = 'Period must be at least 60 seconds and must be a multiple of 60';
-      }
-
-      return errs;
-    }
-
     $scope.init();
     $scope.init();
 
 
   });
   });