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

Merge branch 'master' into updated-list-views

Nick Christus 10 лет назад
Родитель
Сommit
282aaa5cf0

+ 7 - 1
CHANGELOG.md

@@ -1,4 +1,9 @@
-# 2.6.0 (unreleased)
+# 2.6.0 (2015-12-04)
+
+### Bug Fixes
+* **metric editors**: Fix for clicking typeahead auto dropdown option, fixes [#3428](https://github.com/grafana/grafana/issues/3428)
+
+# 2.6.0-Beta1 (2015-12-04)
 
 ### New Table Panel
 * **table**:  New powerful and flexible table panel, closes [#215](https://github.com/grafana/grafana/issues/215)
@@ -6,6 +11,7 @@
 ### Enhancements
 * **CloudWatch**: Support for multiple AWS Credentials, closes [#3053](https://github.com/grafana/grafana/issues/3053), [#3080](https://github.com/grafana/grafana/issues/3080)
 * **Elasticsearch**: Support for dynamic daily indices for annotations, closes [#3061](https://github.com/grafana/grafana/issues/3061)
+* **Elasticsearch**: Support for setting min_doc_count for date histogram, closes [#3416](https://github.com/grafana/grafana/issues/3416)
 * **Graph Panel**: Option to hide series with all zeroes from legend and tooltip, closes [#1381](https://github.com/grafana/grafana/issues/1381), [#3336](https://github.com/grafana/grafana/issues/3336)
 
 ### Bug Fixes

+ 1 - 1
appveyor.yml

@@ -5,7 +5,7 @@ os: Windows Server 2012 R2
 clone_folder: c:\gopath\src\github.com\grafana\grafana
 
 environment:
-  nodejs_version: "0.12.2"
+  nodejs_version: "4"
   GOPATH: c:\gopath
 
 install:

+ 18 - 1
build.go

@@ -76,6 +76,14 @@ func main() {
 			grunt("release")
 			createLinuxPackages()
 
+		case "pkg-rpm":
+			grunt("release")
+			createRpmPackages()
+
+		case "pkg-deb":
+			grunt("release")
+			createDebPackages()
+
 		case "latest":
 			makeLatestDistCopies()
 
@@ -147,7 +155,7 @@ type linuxPackageOptions struct {
 	depends []string
 }
 
-func createLinuxPackages() {
+func createDebPackages() {
 	createPackage(linuxPackageOptions{
 		packageType:            "deb",
 		homeDir:                "/usr/share/grafana",
@@ -167,7 +175,9 @@ func createLinuxPackages() {
 
 		depends: []string{"adduser", "libfontconfig"},
 	})
+}
 
+func createRpmPackages() {
 	createPackage(linuxPackageOptions{
 		packageType:            "rpm",
 		homeDir:                "/usr/share/grafana",
@@ -189,6 +199,11 @@ func createLinuxPackages() {
 	})
 }
 
+func createLinuxPackages() {
+	createDebPackages()
+	createRpmPackages()
+}
+
 func createPackage(options linuxPackageOptions) {
 	packageRoot, _ := ioutil.TempDir("", "grafana-linux-pack")
 
@@ -315,6 +330,8 @@ func build(pkg string, tags []string) {
 	args = append(args, "-o", binary)
 	args = append(args, pkg)
 	setBuildEnv()
+
+	runPrint("go", "version")
 	runPrint("go", args...)
 
 	// Create an md5 checksum of the binary, to be included in the archive for

+ 1 - 1
package.json

@@ -4,7 +4,7 @@
     "company": "Coding Instinct AB"
   },
   "name": "grafana",
-  "version": "2.6.0-pre1",
+  "version": "2.6.0-beta1",
   "repository": {
     "type": "git",
     "url": "http://github.com/torkelo/grafana.git"

+ 6 - 0
pkg/setting/setting.go

@@ -174,6 +174,9 @@ func applyEnvVariableOverrides() {
 
 			if len(envValue) > 0 {
 				key.SetValue(envValue)
+				if strings.Contains(envKey, "PASSWORD") {
+					envValue = "*********"
+				}
 				appliedEnvOverrides = append(appliedEnvOverrides, fmt.Sprintf("%s=%s", envKey, envValue))
 			}
 		}
@@ -188,6 +191,9 @@ func applyCommandLineDefaultProperties(props map[string]string) {
 			value, exists := props[keyString]
 			if exists {
 				key.SetValue(value)
+				if strings.Contains(keyString, "password") {
+					value = "*********"
+				}
 				appliedCommandLineProperties = append(appliedCommandLineProperties, fmt.Sprintf("%s=%s", keyString, value))
 			}
 		}

+ 4 - 4
public/app/core/directives/metric_segment.js

@@ -55,8 +55,8 @@ function (_, $, coreModule) {
           });
         };
 
-        $scope.switchToLink = function() {
-          if (linkMode) { return; }
+        $scope.switchToLink = function(fromClick) {
+          if (linkMode && !fromClick) { return; }
 
           clearTimeout(cancelBlur);
           cancelBlur = null;
@@ -69,7 +69,7 @@ function (_, $, coreModule) {
         $scope.inputBlur = function() {
           // happens long before the click event on the typeahead options
           // need to have long delay because the blur
-          cancelBlur = setTimeout($scope.switchToLink, 100);
+          cancelBlur = setTimeout($scope.switchToLink, 200);
         };
 
         $scope.source = function(query, callback) {
@@ -100,7 +100,7 @@ function (_, $, coreModule) {
           }
 
           $input.val(value);
-          $scope.switchToLink();
+          $scope.switchToLink(true);
 
           return value;
         };

+ 1 - 1
public/app/core/directives/value_select_dropdown.js

@@ -156,7 +156,7 @@ function (angular, _, coreModule) {
     vm.selectionsChanged = function(commitChange) {
       vm.selectedValues = _.filter(vm.options, {selected: true});
 
-      if (vm.selectedValues.length > 1 && vm.selectedValues.length !== vm.options.length) {
+      if (vm.selectedValues.length > 1) {
         if (vm.selectedValues[0].text === 'All') {
           vm.selectedValues[0].selected = false;
           vm.selectedValues = vm.selectedValues.slice(1, vm.selectedValues.length);

+ 3 - 2
public/app/features/dashboard/timeSrv.js

@@ -47,8 +47,9 @@ define([
       if (value.length === 15) {
         return moment.utc(value, 'YYYYMMDDTHHmmss');
       }
-      var epoch = parseInt(value);
-      if (!_.isNaN(epoch)) {
+
+      if (!isNaN(value)) {
+        var epoch = parseInt(value);
         return moment(epoch);
       }
 

+ 1 - 1
public/app/panels/table/controller.ts

@@ -26,7 +26,7 @@ export class TablePanelCtrl {
 
     var panelDefaults = {
       targets: [{}],
-      transform: 'timeseries_to_rows',
+      transform: 'timeseries_to_columns',
       pageSize: null,
       showHeader: true,
       styles: [

+ 8 - 2
public/app/panels/table/editor.ts

@@ -45,11 +45,17 @@ export class TablePanelEditorCtrl {
     };
 
     $scope.addColumn = function() {
-      $scope.panel.columns.push({text: $scope.addColumnSegment.value, value: $scope.addColumnSegment.value});
-      $scope.render();
+      var columns = transformers[$scope.panel.transform].getColumns($scope.dataRaw);
+      var column = _.findWhere(columns, {text: $scope.addColumnSegment.value});
+
+      if (column) {
+        $scope.panel.columns.push(column);
+        $scope.render();
+      }
 
       var plusButton = uiSegmentSrv.newPlusButton();
       $scope.addColumnSegment.html = plusButton.html;
+      $scope.addColumnSegment.value = plusButton.value;
     };
 
     $scope.transformChanged = function() {

+ 1 - 1
public/app/panels/table/renderer.ts

@@ -112,7 +112,7 @@ export class TableRenderer {
     // this hack adds header content to cell (not visible)
     var widthHack = '';
     if (addWidthHack) {
-      widthHack = '<div class="table-panel-width-hack">' + this.table.columns[columnIndex].text + '<div>';
+      widthHack = '<div class="table-panel-width-hack">' + this.table.columns[columnIndex].text + '</div>';
     }
 
     return '<td' + style + '>' + value + widthHack + '</td>';

+ 1 - 0
public/app/panels/table/specs/table_model_specs.ts

@@ -0,0 +1 @@
+

+ 2 - 2
public/app/plugins/datasource/cloudwatch/datasource.js

@@ -25,7 +25,7 @@ function (angular, _) {
       var end = convertToCloudWatchTime(options.range.to);
 
       var queries = [];
-      options = _.clone(options);
+      options = angular.copy(options);
       _.each(options.targets, _.bind(function(target) {
         if (target.hide || !target.namespace || !target.metricName || _.isEmpty(target.statistics)) {
           return;
@@ -129,7 +129,7 @@ function (angular, _) {
         .pluck('Dimensions')
         .flatten()
         .filter(function(dimension) {
-          return dimension.Name === dimensionKey;
+          return dimension !== null && dimension.Name === dimensionKey;
         })
         .pluck('Value')
         .uniq()

+ 2 - 0
public/app/plugins/datasource/elasticsearch/bucket_agg.js

@@ -92,8 +92,10 @@ function (angular, _, queryDef) {
         }
         case 'date_histogram': {
           settings.interval = settings.interval || 'auto';
+          settings.min_doc_count = settings.min_doc_count || 0;
           $scope.agg.field = $scope.target.timeField;
           settingsLinkText = 'Interval: ' + settings.interval;
+          settingsLinkText += ', Min Doc Count: ' + settings.min_doc_count;
         }
       }
 

+ 13 - 2
public/app/plugins/datasource/elasticsearch/partials/bucketAgg.html

@@ -35,9 +35,9 @@
 
 <div class="tight-form" ng-if="showOptions">
 	<div class="tight-form-inner-box" ng-if="agg.type === 'date_histogram'">
-		<div class="tight-form last">
+		<div class="tight-form">
 			<ul class="tight-form-list">
-				<li class="tight-form-item" style="width: 60px">
+				<li class="tight-form-item" style="width: 94px">
 					Interval
 				</li>
 				<li>
@@ -46,6 +46,17 @@
 			</ul>
 			<div class="clearfix"></div>
 		</div>
+		<div class="tight-form last">
+			<ul class="tight-form-list">
+				<li class="tight-form-item" style="width: 94px">
+					Min Doc Count
+				</li>
+				<li>
+					<input type="number" class="tight-form-input" ng-model="agg.settings.min_doc_count" ng-blur="onChangeInternal()"></input>
+				</li>
+			</ul>
+			<div class="clearfix"></div>
+		</div>
 	</div>
 	<div class="tight-form-inner-box" ng-if="agg.type === 'terms'">
 		<div class="tight-form">

+ 17 - 14
public/app/plugins/datasource/elasticsearch/query_builder.js

@@ -50,12 +50,23 @@ function () {
     return queryNode;
   };
 
-  ElasticQueryBuilder.prototype.getInterval = function(agg) {
-    if (agg.settings && agg.settings.interval !== 'auto') {
-      return agg.settings.interval;
-    } else {
-      return '$interval';
+  ElasticQueryBuilder.prototype.getDateHistogramAgg = function(aggDef) {
+    var esAgg = {};
+    var settings = aggDef.settings || {};
+    esAgg.interval = settings.interval;
+    esAgg.field = this.timeField;
+    esAgg.min_doc_count = settings.min_doc_count || 0;
+    esAgg.extended_bounds = {min: "$timeFrom", max: "$timeTo"};
+
+    if (esAgg.interval === 'auto') {
+      esAgg.interval = "$interval";
     }
+
+    if (this.esVersion >= 2) {
+      esAgg.format = "epoch_millis";
+    }
+
+    return esAgg;
   };
 
   ElasticQueryBuilder.prototype.getFiltersAgg = function(aggDef) {
@@ -130,15 +141,7 @@ function () {
 
       switch(aggDef.type) {
         case 'date_histogram': {
-          esAgg["date_histogram"] = {
-            "interval": this.getInterval(aggDef),
-            "field": this.timeField,
-            "min_doc_count": 0,
-            "extended_bounds": { "min": "$timeFrom", "max": "$timeTo" }
-          };
-          if (this.esVersion >= 2) {
-            esAgg["date_histogram"]["format"] = "epoch_millis";
-          }
+          esAgg["date_histogram"] = this.getDateHistogramAgg(aggDef);
           break;
         }
         case 'filters': {

+ 3 - 3
public/app/plugins/datasource/influxdb/partials/query.editor.html

@@ -55,12 +55,12 @@
 				<metric-segment segment="segment" get-options="getTagsOrValues(segment, $index)" on-change="tagSegmentUpdated(segment, $index)"></metric-segment>
 			</li>
 		</ul>
-		<div class="clearfix"></div>
 
-		<div style="padding: 10px" ng-if="target.rawQuery">
-			<textarea ng-model="target.query" rows="8" spellcheck="false" style="width: 100%; box-sizing: border-box;" ng-blur="get_data()"></textarea>
+		<div class="tight-form-flex-wrapper" ng-show="target.rawQuery">
+			<input type="text" class="tight-form-clear-input" ng-model="target.query" spellcheck="false" style="width: 100%;" ng-blur="get_data()"></input>
 		</div>
 
+		<div class="clearfix"></div>
 	</div>
 
 	<div ng-hide="target.rawQuery">

+ 0 - 1
public/app/plugins/datasource/influxdb/query_ctrl.js

@@ -23,7 +23,6 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
       $scope.resultFormats = [
          {text: 'Time series', value: 'time_series'},
          {text: 'Table', value: 'table'},
-         {text: 'JSON field', value: 'json_field'},
       ];
 
       if (!$scope.target.measurement) {

+ 1 - 1
public/app/plugins/datasource/influxdb/specs/influx_series_specs.ts

@@ -205,7 +205,7 @@ describe('when generating timeseries from influxdb response', function() {
 
       expect(table.type).to.be('table');
       expect(table.columns.length).to.be(3);
-      expect(table.rows[0]).to.eql([1431946625000, 'America', 10]);;
+      expect(table.rows[0]).to.eql([1431946625000, 'America', 10]);
     });
   });
 

+ 4 - 2
public/less/overrides.less

@@ -61,7 +61,7 @@
 }
 
 code, pre {
-  background-color: @grayLighter;
+  background-color: @codeTagBackground;
 }
 
 div.editor-row {
@@ -587,8 +587,10 @@ div.flot-text {
 
 // pre
 code, pre {
-  background-color: @grafanaPanelBackground;
+  background-color: @codeTagBackground;
   color: @textColor;
+  border: 1px solid darken(@codeTagBackground, 15%);
+  padding: 2px;
 }
 
 .dropdown-menu {

+ 5 - 0
public/less/tightform.less

@@ -59,6 +59,11 @@
   }
 }
 
+.tight-form-flex-wrapper {
+  display: flex;
+  flex-direction: row;
+}
+
 .grafana-metric-options {
   margin-top: 25px;
 }

+ 1 - 0
public/less/variables.dark.less

@@ -48,6 +48,7 @@
 @grafanaTargetFuncHightlight: #444;
 
 @modalBackground: @black;
+@codeTagBackground: #444;
 
 // Scaffolding
 // -------------------------

+ 1 - 0
public/less/variables.light.less

@@ -61,6 +61,7 @@
 @grafanaTargetFuncHightlight: darken(@grafanaTargetBackground, 10%);
 
 @modalBackground: @bodyBackground;
+@codeTagBackground: #ddd;
 
 // Scaffolding
 // -------------------------

+ 1 - 1
public/test/mocks/dashboard-mock.js

@@ -15,7 +15,7 @@ define([],
         rows: [],
         pulldowns: [ { type: 'templating' },  { type: 'annotations' } ],
         nav: [ { type: 'timepicker' } ],
-        time: {from: '1h', to: 'now'},
+        time: {from: 'now-6h', to: 'now'},
         templating: {
           list: []
         },

+ 8 - 0
public/test/specs/time_srv_specs.js

@@ -75,6 +75,14 @@ define([
         expect(time.to.valueOf()).to.equal(1410337665699);
       });
 
+      it('should handle bad dates', function() {
+        ctx.$routeParams.from = '20151126T00010%3C%2Fp%3E%3Cspan%20class';
+        ctx.$routeParams.to = 'now';
+        _dashboard.time.from = 'now-6h';
+        ctx.service.init(_dashboard);
+        expect(ctx.service.time.from).to.equal('now-6h');
+        expect(ctx.service.time.to).to.equal('now');
+      });
     });
 
     describe('setTime', function() {