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

Merge branch 'master' into alerting_definitions

bergquist 9 лет назад
Родитель
Сommit
2e097f4af1

+ 2 - 0
CHANGELOG.md

@@ -11,6 +11,8 @@
 * **Graph**: Fixed issue with unneeded scrollbar in legend for Firefox, fixes [#4760](https://github.com/grafana/grafana/issues/4760)
 * **Graph**: Fixed issue with unneeded scrollbar in legend for Firefox, fixes [#4760](https://github.com/grafana/grafana/issues/4760)
 * **Table panel**: Fixed issue table panel formating string array properties, fixes [#4791](https://github.com/grafana/grafana/issues/4791)
 * **Table panel**: Fixed issue table panel formating string array properties, fixes [#4791](https://github.com/grafana/grafana/issues/4791)
 * **grafana-cli**: Improve error message when failing to install plugins due to corrupt response, fixes [#4651](https://github.com/grafana/grafana/issues/4651)
 * **grafana-cli**: Improve error message when failing to install plugins due to corrupt response, fixes [#4651](https://github.com/grafana/grafana/issues/4651)
+* **Singlestat**: Fixes prefix an postfix for gauges, fixes [#4812](https://github.com/grafana/grafana/issues/4812)
+* **Singlestat**: Fixes auto-refresh on change for some options, fixes [#4809](https://github.com/grafana/grafana/issues/4809)
 
 
 # 3.0.0-beta5 (2016-04-15)
 # 3.0.0-beta5 (2016-04-15)
 
 

+ 17 - 0
Makefile

@@ -0,0 +1,17 @@
+all: deps build
+
+deps:
+	go run build.go setup
+	godep restore
+	npm install
+
+build:
+	go run build.go build
+	npm run build
+
+test:
+	godep go test -v ./pkg/...
+	npm test
+
+run:
+	./bin/grafana-server

+ 1 - 3
README.md

@@ -103,8 +103,7 @@ npm (v2.5.0) and grunt (v0.4.5). Run the following:
 
 
 ```bash
 ```bash
 npm install
 npm install
-npm install -g grunt-cli
-grunt
+npm run build
 ```
 ```
 
 
 ### Recompile backend on source change
 ### Recompile backend on source change
@@ -145,4 +144,3 @@ please [sign the CLA](http://docs.grafana.org/project/cla/)
 
 
 Grafana is distributed under Apache 2.0 License.
 Grafana is distributed under Apache 2.0 License.
 Work in progress Grafana 2.0 (with included Grafana backend)
 Work in progress Grafana 2.0 (with included Grafana backend)
-

+ 1 - 1
build.go

@@ -306,7 +306,7 @@ func ChangeWorkingDir(dir string) {
 }
 }
 
 
 func grunt(params ...string) {
 func grunt(params ...string) {
-	runPrint("./node_modules/grunt-cli/bin/grunt", params...)
+	runPrint("./node_modules/.bin/grunt", params...)
 }
 }
 
 
 func setup() {
 func setup() {

+ 2 - 2
circle.yml

@@ -25,12 +25,12 @@ test:
      # Go test
      # Go test
      - godep go test -v ./pkg/...
      - godep go test -v ./pkg/...
      # js tests
      # js tests
-     - ./node_modules/grunt-cli/bin/grunt test
+     - npm test
      - npm run coveralls
      - npm run coveralls
 
 
 deployment:
 deployment:
   master:
   master:
     branch: master
     branch: master
     owner: grafana
     owner: grafana
-    commands: 
+    commands:
       - ./trigger_grafana_packer.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN}
       - ./trigger_grafana_packer.sh ${TRIGGER_GRAFANA_PACKER_CIRCLECI_TOKEN}

+ 1 - 0
package.json

@@ -62,6 +62,7 @@
     "npm": "2.14.x"
     "npm": "2.14.x"
   },
   },
   "scripts": {
   "scripts": {
+    "build": "grunt",
     "test": "grunt test",
     "test": "grunt test",
     "coveralls": "grunt karma:coveralls && rm -rf ./coverage"
     "coveralls": "grunt karma:coveralls && rm -rf ./coverage"
   },
   },

+ 1 - 1
pkg/api/dtos/plugins.go

@@ -48,6 +48,6 @@ func (slice PluginList) Swap(i, j int) {
 type ImportDashboardCommand struct {
 type ImportDashboardCommand struct {
 	PluginId  string                         `json:"pluginId"`
 	PluginId  string                         `json:"pluginId"`
 	Path      string                         `json:"path"`
 	Path      string                         `json:"path"`
-	Reinstall bool                           `json:"reinstall"`
+	Overwrite bool                           `json:"overwrite"`
 	Inputs    []plugins.ImportDashboardInput `json:"inputs"`
 	Inputs    []plugins.ImportDashboardInput `json:"inputs"`
 }
 }

+ 6 - 5
pkg/api/plugins.go

@@ -156,11 +156,12 @@ func GetPluginReadme(c *middleware.Context) Response {
 func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand) Response {
 func ImportDashboard(c *middleware.Context, apiCmd dtos.ImportDashboardCommand) Response {
 
 
 	cmd := plugins.ImportDashboardCommand{
 	cmd := plugins.ImportDashboardCommand{
-		OrgId:    c.OrgId,
-		UserId:   c.UserId,
-		PluginId: apiCmd.PluginId,
-		Path:     apiCmd.Path,
-		Inputs:   apiCmd.Inputs,
+		OrgId:     c.OrgId,
+		UserId:    c.UserId,
+		PluginId:  apiCmd.PluginId,
+		Path:      apiCmd.Path,
+		Inputs:    apiCmd.Inputs,
+		Overwrite: apiCmd.Overwrite,
 	}
 	}
 
 
 	if err := bus.Dispatch(&cmd); err != nil {
 	if err := bus.Dispatch(&cmd); err != nil {

+ 7 - 5
pkg/plugins/dashboard_importer.go

@@ -11,12 +11,13 @@ import (
 )
 )
 
 
 type ImportDashboardCommand struct {
 type ImportDashboardCommand struct {
-	Path   string                 `json:"string"`
-	Inputs []ImportDashboardInput `json:"inputs"`
+	Path      string
+	Inputs    []ImportDashboardInput
+	Overwrite bool
 
 
-	OrgId    int64  `json:"-"`
-	UserId   int64  `json:"-"`
-	PluginId string `json:"-"`
+	OrgId    int64
+	UserId   int64
+	PluginId string
 	Result   *PluginDashboardInfoDTO
 	Result   *PluginDashboardInfoDTO
 }
 }
 
 
@@ -67,6 +68,7 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
 		Dashboard: generatedDash,
 		Dashboard: generatedDash,
 		OrgId:     cmd.OrgId,
 		OrgId:     cmd.OrgId,
 		UserId:    cmd.UserId,
 		UserId:    cmd.UserId,
+		Overwrite: cmd.Overwrite,
 	}
 	}
 
 
 	if err := bus.Dispatch(&saveCmd); err != nil {
 	if err := bus.Dispatch(&saveCmd); err != nil {

+ 3 - 0
public/app/core/directives/plugin_component.ts

@@ -211,6 +211,9 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
     // let a binding digest cycle complete before adding to dom
     // let a binding digest cycle complete before adding to dom
     setTimeout(function() {
     setTimeout(function() {
       elem.append(child);
       elem.append(child);
+      scope.$apply(function() {
+        scope.$broadcast('refresh');
+      });
     });
     });
   }
   }
 
 

+ 1 - 1
public/app/core/utils/emitter.ts

@@ -23,7 +23,7 @@ export class Emitter {
     this.emitter.on(name, handler);
     this.emitter.on(name, handler);
 
 
     if (scope) {
     if (scope) {
-      scope.$on('$destroy', function() {
+      scope.$on('$destroy', () => {
         this.emitter.off(name, handler);
         this.emitter.off(name, handler);
       });
       });
     }
     }

+ 2 - 5
public/app/features/panel/panel_ctrl.ts

@@ -44,18 +44,15 @@ export class PanelCtrl {
       this.pluginName = plugin.name;
       this.pluginName = plugin.name;
     }
     }
 
 
-    $scope.$on("refresh", () => this.refresh());
-    $scope.$on("render", () => this.render());
+    $scope.$on("refresh", this.refresh.bind(this));
+    $scope.$on("render", this.render.bind(this));
     $scope.$on("$destroy", () => this.events.emit('panel-teardown'));
     $scope.$on("$destroy", () => this.events.emit('panel-teardown'));
   }
   }
 
 
   init() {
   init() {
     this.calculatePanelHeight();
     this.calculatePanelHeight();
-
     this.publishAppEvent('panel-initialized', {scope: this.$scope});
     this.publishAppEvent('panel-initialized', {scope: this.$scope});
     this.events.emit('panel-initialized');
     this.events.emit('panel-initialized');
-
-    this.refresh();
   }
   }
 
 
   renderingCompleted() {
   renderingCompleted() {

+ 4 - 4
public/app/features/plugins/ds_edit_ctrl.ts

@@ -98,9 +98,7 @@ export class DataSourceEditCtrl {
 
 
       this.datasourceSrv.get(this.current.name).then(datasource => {
       this.datasourceSrv.get(this.current.name).then(datasource => {
         if (!datasource.testDatasource) {
         if (!datasource.testDatasource) {
-          this.testing.message = 'Data source does not support test connection feature.';
-          this.testing.status = 'warning';
-          this.testing.title = 'Unknown';
+          delete this.testing;
           return;
           return;
         }
         }
 
 
@@ -118,7 +116,9 @@ export class DataSourceEditCtrl {
           }
           }
         });
         });
       }).finally(() => {
       }).finally(() => {
-        this.testing.done = true;
+        if (this.testing) {
+          this.testing.done = true;
+        }
       });
       });
     }
     }
 
 

+ 4 - 4
public/app/features/plugins/import_list/import_list.html

@@ -15,16 +15,16 @@
 				</td>
 				</td>
 				<td>
 				<td>
 					v{{dash.revision}}
 					v{{dash.revision}}
-				</td>
-				<td ng-if="dash.installed">
-					Imported v{{dash.installedRevision}}
+					<span ng-if="dash.installed">
+						&nbsp;(Imported v{{dash.installedRevision}})
+					<span>
 				</td>
 				</td>
 				<td style="text-align: right">
 				<td style="text-align: right">
 					<button class="btn btn-secondary" ng-click="ctrl.import(dash, false)" ng-show="!dash.installed">
 					<button class="btn btn-secondary" ng-click="ctrl.import(dash, false)" ng-show="!dash.installed">
 						Import
 						Import
 					</button>
 					</button>
 					<button class="btn btn-secondary" ng-click="ctrl.import(dash, true)" ng-show="dash.installed">
 					<button class="btn btn-secondary" ng-click="ctrl.import(dash, true)" ng-show="dash.installed">
-						Re-Import
+						Update
 					</button>
 					</button>
 					<button class="btn btn-danger" ng-click="ctrl.remove(dash)" ng-show="dash.installed">
 					<button class="btn btn-danger" ng-click="ctrl.remove(dash)" ng-show="dash.installed">
 						Delete
 						Delete

+ 2 - 2
public/app/features/plugins/import_list/import_list.ts

@@ -43,11 +43,11 @@ export class DashImportListCtrl {
     });
     });
   }
   }
 
 
-  import(dash, reinstall) {
+  import(dash, overwrite) {
     var installCmd = {
     var installCmd = {
       pluginId: this.plugin.id,
       pluginId: this.plugin.id,
       path: dash.path,
       path: dash.path,
-      reinstall: reinstall,
+      overwrite: overwrite,
       inputs: []
       inputs: []
     };
     };
 
 

+ 1 - 1
public/app/features/plugins/partials/ds_edit.html

@@ -53,7 +53,7 @@
 			</plugin-component>
 			</plugin-component>
 			</rebuild-on-change>
 			</rebuild-on-change>
 
 
-			<div ng-if="ctrl.testing" style="margin-top: 25px">
+			<div ng-if="ctrl.testing" class="gf-form-group">
 				<h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
 				<h5 ng-show="!ctrl.testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
 				<div class="alert-{{ctrl.testing.status}} alert">
 				<div class="alert-{{ctrl.testing.status}} alert">
 					<div class="alert-title">{{ctrl.testing.title}}</div>
 					<div class="alert-title">{{ctrl.testing.title}}</div>

+ 21 - 9
public/app/plugins/panel/singlestat/editor.html

@@ -158,7 +158,7 @@
 
 
 <div class="editor-row">
 <div class="editor-row">
 	<div class="section" style="margin-bottom: 20px">
 	<div class="section" style="margin-bottom: 20px">
-		<div class="tight-form last">
+		<div class="tight-form">
 			<ul class="tight-form-list">
 			<ul class="tight-form-list">
 				<li class="tight-form-item" style="width: 80px">
 				<li class="tight-form-item" style="width: 80px">
 					<strong>Gauge</strong>
 					<strong>Gauge</strong>
@@ -169,27 +169,39 @@
 					ng-model="ctrl.panel.gauge.show" ng-checked="ctrl.panel.gauge.show" ng-change="ctrl.render()">
 					ng-model="ctrl.panel.gauge.show" ng-checked="ctrl.panel.gauge.show" ng-change="ctrl.render()">
 					<label for="panel.gauge.show" class="cr1"></label>
 					<label for="panel.gauge.show" class="cr1"></label>
 				</li>
 				</li>
-				<li class="tight-form-item">
-					Threshold labels&nbsp;
-					<input class="cr1" id="panel.gauge.thresholdLabels" type="checkbox"
-					ng-model="ctrl.panel.gauge.thresholdLabels" ng-checked="ctrl.panel.gauge.thresholdLabels" ng-change="ctrl.render()">
-					<label for="panel.gauge.thresholdLabels" class="cr1"></label>
-				</li>
 				<li class="tight-form-item">
 				<li class="tight-form-item">
 					Min
 					Min
 				</li>
 				</li>
 				<li>
 				<li>
-					<input type="text" class="input-small tight-form-input" ng-model="ctrl.panel.gauge.minValue" ng-blur="ctrl.render()" placeholder="0"></input>
+					<input type="number" class="input-small tight-form-input" ng-model="ctrl.panel.gauge.minValue" ng-blur="ctrl.render()" placeholder="0"></input>
 				</li>
 				</li>
 				<li class="tight-form-item last">
 				<li class="tight-form-item last">
 					Max
 					Max
 				</li>
 				</li>
 				<li>
 				<li>
-					<input type="text" class="input-small tight-form-input last" ng-model="ctrl.panel.gauge.maxValue" ng-blur="ctrl.render()" placeholder="100"></input>
+					<input type="number" class="input-small tight-form-input last" ng-model="ctrl.panel.gauge.maxValue" ng-blur="ctrl.render()" placeholder="100"></input>
+					<span class="alert-state-critical" ng-show="ctrl.invalidGaugeRange">
+						&nbsp;
+						<i class="fa fa-warning"></i>
+						Min value is bigger than max.
+					</span>
 				</li>
 				</li>
 			</ul>
 			</ul>
 			<div class="clearfix"></div>
 			<div class="clearfix"></div>
 		</div>
 		</div>
+		<div class="tight-form last">
+			<li class="tight-form-item">
+				Threshold labels&nbsp;
+				<input class="cr1" id="panel.gauge.thresholdLabels" type="checkbox" ng-model="ctrl.panel.gauge.thresholdLabels" ng-checked="ctrl.panel.gauge.thresholdLabels" ng-change="ctrl.render()">
+				<label for="panel.gauge.thresholdLabels" class="cr1"></label>
+			</li>
+			<li class="tight-form-item">
+				Threshold markers&nbsp;
+				<input class="cr1" id="panel.gauge.thresholdMarkers" type="checkbox" ng-model="ctrl.panel.gauge.thresholdMarkers" ng-checked="ctrl.panel.gauge.thresholdMarkers" ng-change="ctrl.render()">
+				<label for="panel.gauge.thresholdMarkers" class="cr1"></label>
+			</li>
+			<div class="clearfix"></div>
+		</div>
 	</div>
 	</div>
 </div>
 </div>
 
 

+ 35 - 9
public/app/plugins/panel/singlestat/module.ts

@@ -18,6 +18,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
   data: any;
   data: any;
   fontSizes: any[];
   fontSizes: any[];
   unitFormats: any[];
   unitFormats: any[];
+  invalidGaugeRange: boolean;
 
 
   // Set and populate defaults
   // Set and populate defaults
   panelDefaults = {
   panelDefaults = {
@@ -53,7 +54,8 @@ class SingleStatCtrl extends MetricsPanelCtrl {
       show: false,
       show: false,
       minValue: 0,
       minValue: 0,
       maxValue: 100,
       maxValue: 100,
-      thresholdLabels: true
+      thresholdMarkers: true,
+      thresholdLabels: false
     }
     }
   };
   };
 
 
@@ -278,14 +280,30 @@ class SingleStatCtrl extends MetricsPanelCtrl {
       return body;
       return body;
     }
     }
 
 
+    function getValueText() {
+      var result = panel.prefix ? panel.prefix : '';
+      result += data.valueFormated;
+      result += panel.postfix ? panel.postfix : '';
+
+      return result;
+    }
+
     function addGauge() {
     function addGauge() {
+      ctrl.invalidGaugeRange = false;
+      if (panel.gauge.minValue > panel.gauge.maxValue) {
+        ctrl.invalidGaugeRange = true;
+        return;
+      }
+
       var plotCanvas = $('<div></div>');
       var plotCanvas = $('<div></div>');
+      var width = elem.width();
+      var height = elem.height();
       var plotCss = {
       var plotCss = {
         top: '10px',
         top: '10px',
         margin: 'auto',
         margin: 'auto',
         position: 'relative',
         position: 'relative',
-        height: (elem.height() * 0.9) + 'px',
-        width: elem.width() + 'px'
+        height: (height * 0.9) + 'px',
+        width:  width + 'px'
       };
       };
 
 
       plotCanvas.css(plotCss);
       plotCanvas.css(plotCss);
@@ -306,6 +324,12 @@ class SingleStatCtrl extends MetricsPanelCtrl {
         ? 'rgb(230,230,230)'
         ? 'rgb(230,230,230)'
         : 'rgb(38,38,38)';
         : 'rgb(38,38,38)';
 
 
+
+      var dimension = Math.min(width, height);
+      var fontSize = Math.min(dimension/4, 100);
+      var gaugeWidth = Math.min(dimension/6, 60);
+      var thresholdMarkersWidth = gaugeWidth/5;
+
       var options = {
       var options = {
         series: {
         series: {
           gauges: {
           gauges: {
@@ -315,11 +339,11 @@ class SingleStatCtrl extends MetricsPanelCtrl {
               background: { color: bgColor },
               background: { color: bgColor },
               border: { color: null },
               border: { color: null },
               shadow: { show: false },
               shadow: { show: false },
-              width: 38
+              width: gaugeWidth,
             },
             },
             frame: { show: false },
             frame: { show: false },
             label: { show: false },
             label: { show: false },
-            layout: { margin: 0 },
+            layout: { margin: 0, thresholdWidth: 0 },
             cell: { border: { width: 0 } },
             cell: { border: { width: 0 } },
             threshold: {
             threshold: {
               values: thresholds,
               values: thresholds,
@@ -328,12 +352,13 @@ class SingleStatCtrl extends MetricsPanelCtrl {
                 margin: 8,
                 margin: 8,
                 font: { size: 18 }
                 font: { size: 18 }
               },
               },
-              width: 8
+              show: panel.gauge.thresholdMarkers,
+              width: thresholdMarkersWidth,
             },
             },
             value: {
             value: {
               color: panel.colorValue ? getColorForValue(data, data.valueRounded) : null,
               color: panel.colorValue ? getColorForValue(data, data.valueRounded) : null,
-              formatter: function () { return data.valueFormated; },
-              font: { size: getGaugeFontSize() }
+              formatter: function() { return getValueText(); },
+              font: { size: fontSize, family: 'Helvetica Neue", Helvetica, Arial, sans-serif' }
             },
             },
             show: true
             show: true
           }
           }
@@ -352,7 +377,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     function getGaugeFontSize() {
     function getGaugeFontSize() {
       if (panel.valueFontSize) {
       if (panel.valueFontSize) {
         var num = parseInt(panel.valueFontSize.substring(0, panel.valueFontSize.length - 1));
         var num = parseInt(panel.valueFontSize.substring(0, panel.valueFontSize.length - 1));
-        return 30 * (num / 100);
+        return (30 * (num / 100)) + 15;
       } else {
       } else {
         return 30;
         return 30;
       }
       }
@@ -419,6 +444,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
 
 
     function render() {
     function render() {
       if (!ctrl.data) { return; }
       if (!ctrl.data) { return; }
+      ctrl.setValues(ctrl.data);
       data = ctrl.data;
       data = ctrl.data;
       setElementHeight();
       setElementHeight();
 
 

+ 4 - 0
public/sass/components/_panel_singlestat.scss

@@ -48,4 +48,8 @@
   }
   }
 }
 }
 
 
+#flotGagueValue0 {
+  font-weight: bold; //please dont hurt me for this!
+}
+