Przeglądaj źródła

Merge remote-tracking branch 'origin/master' into pro

Torkel Ödegaard 11 lat temu
rodzic
commit
37b3b1fc3a
49 zmienionych plików z 415 dodań i 117 usunięć
  1. 1 0
      .gitignore
  2. 2 0
      .travis.yml
  3. 20 2
      CHANGELOG.md
  4. 1 1
      README.md
  5. 3 3
      latest.json
  6. 2 1
      package.json
  7. 1 1
      src/app/app.js
  8. 1 0
      src/app/controllers/all.js
  9. 121 0
      src/app/controllers/console-ctrl.js
  10. 7 0
      src/app/controllers/grafanaCtrl.js
  11. 14 3
      src/app/controllers/inspectCtrl.js
  12. 2 5
      src/app/controllers/row.js
  13. 5 9
      src/app/directives/grafanaPanel.js
  14. 5 10
      src/app/panels/graph/legend.html
  15. 6 4
      src/app/panels/text/module.js
  16. 1 1
      src/app/panels/timepicker/module.html
  17. 19 0
      src/app/partials/console.html
  18. 14 7
      src/app/partials/dashboard.html
  19. 2 1
      src/app/partials/dasheditor.html
  20. 2 1
      src/app/partials/inspector.html
  21. 2 2
      src/app/partials/roweditor.html
  22. 3 3
      src/app/services/alertSrv.js
  23. 2 1
      src/app/services/elasticsearch/es-datasource.js
  24. 1 0
      src/app/services/graphite/graphiteDatasource.js
  25. 4 2
      src/app/services/influxdb/influxdbDatasource.js
  26. 1 1
      src/app/services/opentsdb/opentsdbDatasource.js
  27. 0 8
      src/css/bootstrap-responsive.min.css
  28. 0 0
      src/css/bootstrap.dark.min.css
  29. 0 0
      src/css/bootstrap.light.min.css
  30. 0 0
      src/css/default.min.css
  31. 0 21
      src/css/less/bootswatch.light.less
  32. 71 0
      src/css/less/console.less
  33. 9 0
      src/css/less/grafana.less
  34. 15 0
      src/css/less/graph.less
  35. 28 11
      src/css/less/overrides.less
  36. 1 1
      src/css/less/variables.dark.less
  37. 2 4
      src/index.html
  38. 3 2
      src/vendor/angular/angular-strap.js
  39. 0 0
      src/vendor/css/animate.min.css
  40. 0 0
      src/vendor/css/font-awesome.min.css
  41. 0 0
      src/vendor/css/normalize.min.css
  42. 0 0
      src/vendor/css/spectrum.css
  43. 0 0
      src/vendor/css/timepicker.css
  44. 2 1
      tasks/build_task.js
  45. 2 1
      tasks/default_task.js
  46. 22 7
      tasks/options/concat.js
  47. 6 2
      tasks/options/filerev.js
  48. 1 1
      tasks/options/requirejs.js
  49. 11 0
      tasks/options/watch.js

+ 1 - 0
.gitignore

@@ -6,6 +6,7 @@ dist
 # locally required config files
 web.config
 config.js
+src/css/*.min.css
 
 # Editor junk
 *.sublime-workspace

+ 2 - 0
.travis.yml

@@ -1,6 +1,8 @@
 language: node_js
 node_js:
   - "0.10"
+git:
+  depth: 1
 before_script:
   - npm install -g grunt-cli
 after_script:

+ 20 - 2
CHANGELOG.md

@@ -1,9 +1,27 @@
-# 1.7.0 (unreleased)
+# 1.8.0 (unreleased)
+
+**New features and improvements**
+
+- [Issue #578](https://github.com/grafana/grafana/issues/578). Dashboard: Row option to display row title even when the row is visible
+
+**Tech**
+- Upgraded from angularjs 1.1.5 to 1.3 beta 17;
+- Switch from underscore to lodash
+- helpers to easily unit test angularjs controllers and services
+- Test coverage through coveralls
+
+# 1.7.0 (2014-08-11)
 
 **Fixes**
-- [Issue #655](https://github.com/grafana/grafana/issues/655). General: Auto refresh not initiated / started after dashboard loading
 - [Issue #652](https://github.com/grafana/grafana/issues/652). Timepicker: Entering custom date range impossible when refresh is low (now is constantly reset)
 - [Issue #450](https://github.com/grafana/grafana/issues/450). Graph: Tooltip does not disappear sometimes and would get stuck
+- [Issue #655](https://github.com/grafana/grafana/issues/655). General: Auto refresh not initiated / started after dashboard loading
+- [Issue #657](https://github.com/grafana/grafana/issues/657). General: Fix for refresh icon in IE browsers
+- [Issue #661](https://github.com/grafana/grafana/issues/661). Annotations: Elasticsearch querystring with filter template replacements was not interpolated
+- [Issue #660](https://github.com/grafana/grafana/issues/660). OpenTSDB: fix opentsdb queries that returned more than one series
+
+**Change**
+- [Issue #681](https://github.com/grafana/grafana/issues/681). Dashboard: The panel error bar has been replaced with a small error indicator, this indicator does not change panel height and is a lot less intrusive. Hover over it for short details, click on it for more details.
 
 # 1.7.0-rc1 (2014-08-05)
 

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
-[Grafana](http://grafana.org) [![Build Status](https://api.travis-ci.org/grafana/grafana.png)](https://travis-ci.org/grafana/grafana) [![Gittip](http://img.shields.io/gittip/torkelo.svg)](https://www.gittip.com/torkelo)
+[Grafana](http://grafana.org) [![Build Status](https://api.travis-ci.org/grafana/grafana.svg)](https://travis-ci.org/grafana/grafana) [![Coverage Status](https://coveralls.io/repos/grafana/grafana/badge.png?branch=develop)](https://coveralls.io/r/grafana/grafana?branch=develop)
 ================
 [Website](http://grafana.org) |
 [Twitter](http://twitter.com/grafana) |

+ 3 - 3
latest.json

@@ -1,4 +1,4 @@
 {
-	"version": "1.7.0-rc1",
-	"url": "http://grafanarel.s3.amazonaws.com/grafana-1.7.0-rc1.tar.gz"
-}
+	"version": "1.7.0",
+	"url": "http://grafanarel.s3.amazonaws.com/grafana-1.7.0"
+}

+ 2 - 1
package.json

@@ -4,7 +4,7 @@
     "company": "Coding Instinct AB"
   },
   "name": "grafana",
-  "version": "1.7.0-rc1",
+  "version": "1.7.0",
   "repository": {
     "type": "git",
     "url": "http://github.com/torkelo/grafana.git"
@@ -26,6 +26,7 @@
     "grunt-contrib-less": "~0.7.0",
     "grunt-contrib-requirejs": "~0.4.1",
     "grunt-contrib-uglify": "~0.2.4",
+    "grunt-contrib-watch": "^0.6.1",
     "grunt-filerev": "^0.2.1",
     "grunt-git-describe": "~2.3.2",
     "grunt-karma": "~0.8.3",

+ 1 - 1
src/app/app.js

@@ -51,13 +51,13 @@ function (angular, $, _, appLevelRequire, config) {
   app.config(function ($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
 
     $routeProvider.otherwise({ redirectTo: config.default_route });
-
     // this is how the internet told me to dynamically add modules :/
     register_fns.controller = $controllerProvider.register;
     register_fns.directive  = $compileProvider.directive;
     register_fns.factory    = $provide.factory;
     register_fns.service    = $provide.service;
     register_fns.filter     = $filterProvider.register;
+
   });
 
   var apps_deps = [

+ 1 - 0
src/app/controllers/all.js

@@ -13,4 +13,5 @@ define([
   './playlistCtrl',
   './inspectCtrl',
   './opentsdbTargetCtrl',
+  './console-ctrl',
 ], function () {});

+ 121 - 0
src/app/controllers/console-ctrl.js

@@ -0,0 +1,121 @@
+define([
+  'angular',
+  'lodash',
+  'moment',
+],
+function (angular, _, moment) {
+  'use strict';
+
+  var module = angular.module('grafana.controllers');
+  var consoleEnabled = window.localStorage && window.localStorage.grafanaConsole === 'true';
+
+  if (!consoleEnabled) {
+    return;
+  }
+
+  var events = [];
+
+  var oldLog = console.log;
+  console.log = function (message) {
+    try {
+      if (_.isObject(message)) {
+        message = angular.toJson(message);
+        if (message.length > 50) {
+          message = message.substring(0, 50);
+        }
+      }
+      events.push(new ConsoleEvent('log', message, {}));
+      oldLog.apply(console, arguments);
+    } catch (e) { }
+  };
+
+  function ConsoleEvent(type, title, data) {
+    this.type = type;
+    this.title = title;
+    this.data = data;
+    this.time = moment().format('hh:mm:ss');
+
+    if (data.config) {
+      this.method = data.config.method;
+      this.elapsed = (new Date().getTime() - data.config.$grafana_timestamp) + ' ms';
+      if (data.config.params && data.config.params.q) {
+        this.field2 = data.config.params.q;
+      }
+      if (_.isString(data.config.data)) {
+        this.field2 = data.config.data;
+      }
+      if (data.status !== 200) {
+        this.error = true;
+        this.field3 = data.data;
+      }
+
+      if (_.isArray(data.data)) {
+        this.extractTimeseriesInfo(data.data);
+      }
+    }
+  }
+
+  ConsoleEvent.prototype.extractTimeseriesInfo = function(series) {
+    if (series.length === 0) {
+      return;
+    }
+
+    var points = 0;
+    var ok = false;
+
+    if (series[0].datapoints) {
+      points = _.reduce(series, function(memo, val) {
+        return memo + val.datapoints.length;
+      }, 0);
+      ok = true;
+    }
+    if (series[0].columns) {
+      points = _.reduce(series, function(memo, val) {
+        return memo + val.points.length;
+      }, 0);
+      ok = true;
+    }
+
+    if (ok) {
+      this.field1 = '(' + series.length + ' series';
+      this.field1 += ', ' + points + ' points)';
+    }
+  };
+
+  module.config(function($provide, $httpProvider) {
+    $provide.factory('mupp', function($q) {
+      return {
+        'request': function(config) {
+          if (config.inspect) {
+            config.$grafana_timestamp = new Date().getTime();
+          }
+          return config;
+        },
+        'response': function(response) {
+          if (response.config.inspect) {
+            events.push(new ConsoleEvent(response.config.inspect.type, response.config.url, response));
+          }
+          return response;
+        },
+        'requestError': function(rejection) {
+          console.log('requestError', rejection);
+          return $q.reject(rejection);
+        },
+        'responseError': function (rejection) {
+          var inspect = rejection.config.inspect || { type: 'error' };
+          events.push(new ConsoleEvent(inspect.type, rejection.config.url, rejection));
+          return $q.reject(rejection);
+        }
+      };
+    });
+
+    $httpProvider.interceptors.push('mupp');
+  });
+
+  module.controller('ConsoleCtrl', function($scope) {
+
+    $scope.events = events;
+
+  });
+
+});

+ 7 - 0
src/app/controllers/grafanaCtrl.js

@@ -18,6 +18,13 @@ function (angular, config, _) {
       $scope.grafana = {
         style: 'dark'
       };
+
+      $scope.consoleEnabled = (window.localStorage && window.localStorage.grafanaConsole === 'true');
+    };
+
+    $scope.toggleConsole = function() {
+      $scope.consoleEnabled = !$scope.consoleEnabled;
+      window.localStorage.grafanaConsole = $scope.consoleEnabled ? 'true' : 'false';
     };
 
     $rootScope.onAppEvent = function(name, callback) {

+ 14 - 3
src/app/controllers/inspectCtrl.js

@@ -1,7 +1,8 @@
 define([
-  'angular'
+  'angular',
+  'lodash'
 ],
-function (angular) {
+function (angular, _) {
   'use strict';
 
   var module = angular.module('grafana.controllers');
@@ -28,6 +29,16 @@ function (angular) {
         return;
       }
 
+      if (_.isString(model.error.data)) {
+        $scope.response = model.error.data;
+      }
+
+      if (model.error.config && model.error.config.params) {
+        $scope.request_parameters = _.map(model.error.config.params, function(value, key) {
+          return { key: key, value: value};
+        });
+      }
+
       if (model.error.stack) {
         $scope.editor.index = 2;
         $scope.stack_trace = model.error.stack;
@@ -72,4 +83,4 @@ function (angular) {
       };
     });
 
-});
+});

+ 2 - 5
src/app/controllers/row.js

@@ -33,11 +33,8 @@ function (angular, app, _) {
     };
 
     $scope.rowSpan = function(row) {
-      var panels = _.filter(row.panels, function(p) {
-        return $scope.isPanel(p);
-      });
-      return _.reduce(_.pluck(panels,'span'), function(p,v) {
-        return p+v;
+      return _.reduce(row.panels, function(p,v) {
+        return p + v.span;
       },0);
     };
 

+ 5 - 9
src/app/directives/grafanaPanel.js

@@ -15,16 +15,12 @@ function (angular, $) {
 
       var panelHeader =
       '<div class="panel-header">'+
-        '<div class="row-fluid">' +
-          '<div class="span12 alert-error panel-error small" ng-show="panel.error">' +
-            '<a class="close" ng-click="panel.error=false">&times;</a>' +
-            '<span><i class="icon-exclamation-sign"></i> <strong>Oops!</strong> {{panel.error}} </span>' +
-            '<span class="pointer panel-error-inspector-link" config-modal="app/partials/inspector.html">View details</span>' +
-          '</div>' +
-        '</div>\n' +
-
-        '<div class="row-fluid panel-extra">' +
+       '<div class="row-fluid panel-extra">' +
           '<div class="panel-extra-container">' +
+            '<span class="alert-error panel-error small pointer"' +
+                  'config-modal="app/partials/inspector.html" ng-show="panel.error" data-placement="right" bs-tooltip="panel.error">' +
+              '<i class="icon-exclamation-sign"></i><span class="panel-error-arrow"></span>' +
+            '</span>' +
 
             '<span class="panel-loading" ng-show="panelMeta.loading == true">' +
               '<i class="icon-spinner icon-spin icon-large"></i>' +

+ 5 - 10
src/app/panels/graph/legend.html

@@ -13,20 +13,15 @@
         {{series.alias}}
       </a>
     </div>
-    <div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.current">
-      Current: {{series.current}}
+    <div class="graph-legend-value current small" ng-show="panel.legend.values && panel.legend.current" ng-bind="series.current">
     </div>
-    <div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.min">
-      Min: {{series.min}}
+    <div class="graph-legend-value min small" ng-show="panel.legend.values && panel.legend.min" ng-bind="series.min">
     </div>
-    <div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.max">
-      Max: {{series.max}}
+    <div class="graph-legend-value max small" ng-show="panel.legend.values && panel.legend.max" ng-bind="series.max">
     </div>
-    <div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.total">
-      Total: {{series.total}}
+    <div class="graph-legend-value total small" ng-show="panel.legend.values && panel.legend.total" ng-bind="series.total">
     </div>
-    <div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.avg">
-      Avg: {{series.avg}}
+    <div class="graph-legend-value avg small" ng-show="panel.legend.values && panel.legend.avg" ng-bind="series.avg">
     </div>
   </div>
 

+ 6 - 4
src/app/panels/text/module.js

@@ -82,11 +82,13 @@ function (angular, app, _, require) {
     $scope.updateContent = function(html) {
       try {
         $scope.content = $sce.trustAsHtml(filterSrv.applyTemplateToTarget(html));
-
-        if(!$scope.$$phase) {
-          $scope.$apply();
-        }
       } catch(e) {
+        console.log('Text panel error: ', e);
+        $scope.content = $sce.trustAsHtml(html);
+      }
+
+      if(!$scope.$$phase) {
+        $scope.$apply();
       }
     };
 

+ 1 - 1
src/app/panels/timepicker/module.html

@@ -52,7 +52,7 @@
 
       </li>
       <li ng-show="!dashboard.refresh" class="grafana-menu-refresh">
-        <a class="icon-refresh" ng-click="dashboard.emit_refresh()"></a>
+        <a ng-click="dashboard.emit_refresh()"><i class="icon-refresh"></i></a>
       </li>
     </ul>
 

+ 19 - 0
src/app/partials/console.html

@@ -0,0 +1,19 @@
+<div class="grafana-console" ng-controller="ConsoleCtrl">
+	<div class="grafana-console-header">
+		<span class="grafana-console-title large"><i class="icon-terminal"></i></span>
+	</div>
+	<div class="grafana-console-body">
+		<div class="grafana-console-item" ng-repeat="item in events" ng-class="{'grafana-console-error': item.error}">
+			<span class="grafana-console-time gfc-col" ng-bind="item.time"></span>
+			<span class="grafana-console-type gfc-col">
+				<span class="label label-info" ng-bind="item.type"></span>
+			</span>
+			<span class="gfc-col grafana-console-method" ng-bind="item.method"></span>
+			<span class="gfc-col grafana-console-title" ng-bind="item.title"></span>
+			<span class="gfc-col grafana-console-elapsed" ng-bind="item.elapsed"></span>
+			<span class="gfc-col grafana-console-field1" ng-bind="item.field1"></span>
+			<span class="gfc-col grafana-console-field2" ng-bind="item.field2"></span>
+			<span class="gfc-col grafana-console-field3" ng-bind="item.field3"></span>
+		</div>
+	</div>
+</div>

+ 14 - 7
src/app/partials/dashboard.html

@@ -31,13 +31,15 @@
           <div class="row-control">
             <div class="row-control-inner" style="padding:0px;margin:0px;position:relative;">
               <div class="row-close" ng-show="row.collapse" data-placement="bottom" >
-                <span class="row-button bgWarning" config-modal="app/partials/roweditor.html" class="pointer">
-                  <i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
-                </span>
-                <span class="row-button bgPrimary" ng-click="toggle_row(row)">
-                  <i bs-tooltip="'Expand row'" data-placement="right" class="icon-caret-left pointer" ></i>
-                </span>
-                <span class="row-button row-text" ng-click="toggle_row(row)">{{row.title || 'Row '+$index}}</span>
+								<div class="row-close-buttons">
+									<span class="row-button bgWarning" config-modal="app/partials/roweditor.html" class="pointer">
+										<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
+									</span>
+									<span class="row-button bgPrimary" ng-click="toggle_row(row)">
+										<i bs-tooltip="'Expand row'" data-placement="right" class="icon-caret-left pointer" ></i>
+									</span>
+								</div>
+                <span class="row-text pointer" ng-click="toggle_row(row)" ng-bind="row.title"></span>
               </div>
               <div class="row-open" ng-show="!row.collapse">
                 <div class='row-tab bgPrimary' ng-click="toggle_row(row)">
@@ -92,6 +94,8 @@
             </div>
 
             <div style="padding-top:0px" ng-if="!row.collapse">
+							<div class="row-text pointer" ng-click="toggle_row(row)" ng-if="row.showTitle" ng-bind="row.title">
+							</div>
 
               <!-- Panels -->
               <div ng-repeat="(name, panel) in row.panels|filter:isPanel" ng-hide="panel.hide" class="panel nospace" ng-style="{'width':(panel.span/1.2)*10+'%'}" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:$index,mutate:false,onDrop:'panelMoveDrop',onOver:'panelMoveOver(true)',onOut:'panelMoveOut'}" ng-class="{'dragInProgress':dashboard.$$panelDragging}">
@@ -121,4 +125,7 @@
     </div>
   </div>
 
+	<div ng-include="'app/partials/console.html'" ng-if="consoleEnabled">
+	</div>
+
 </div>

+ 2 - 1
src/app/partials/dasheditor.html

@@ -25,7 +25,7 @@
           <label class="small">Hide controls (CTRL+H)</label>
           <input type="checkbox" ng-model="dashboard.hideControls" ng-checked="dashboard.hideControls">
         </div>
-      </div>
+     </div>
     </div>
      <div class="editor-row">
       <div class="section">
@@ -98,6 +98,7 @@
     <span class="editor-option small">
       Grafana version: {{grafanaVersion}}
     </span>
+		<span> | <a ng-click="toggleConsole()" ng-show="!consoleEnabled">enable console</a> <a ng-click="toggleConsole()" ng-show="consoleEnabled">disable console</a></span>
     <div class="small" grafana-version-check>
     </div>
   </div>

+ 2 - 1
src/app/partials/inspector.html

@@ -41,6 +41,7 @@
   </div>
 
   <div ng-if="editor.index == 1">
+		<h5 ng-if="response" ng-bind="response"></h5>
 
     <div ng-if="response_html">
       <div iframe-content="response_html"></div>
@@ -65,4 +66,4 @@
 </div>
 <div class="modal-footer">
   <button type="button" class="btn btn-info" ng-click="dismiss()">Close</button>
-</div>
+</div>

+ 2 - 2
src/app/partials/roweditor.html

@@ -17,9 +17,9 @@
       <label class="small"> Editable </label><input type="checkbox" ng-model="row.editable" ng-checked="row.editable" />
     </div>
     <div class="editor-option">
-      <label class="small"> Collapsable </label><input type="checkbox" ng-model="row.collapsable" ng-checked="row.collapsable" />
+      <label class="small"> Show title </label><input type="checkbox" ng-model="row.showTitle" ng-checked="row.showTitle" />
     </div>
-  </div>
+	</div>
   <div class="row-fluid" ng-if="editor.index == 1">
     <div class="span12">
       <h4>Panels</h4>

+ 3 - 3
src/app/services/alertSrv.js

@@ -7,7 +7,7 @@ function (angular, _) {
 
   var module = angular.module('grafana.services');
 
-  module.service('alertSrv', function($timeout) {
+  module.service('alertSrv', function($timeout, $sce) {
     var self = this;
 
     // List of all alert objects
@@ -17,7 +17,7 @@ function (angular, _) {
       var
         _a = {
           title: title || '',
-          text: text || '',
+          text: $sce.trustAsHtml(text || ''),
           severity: severity || 'info',
         },
         _ca = angular.toJson(_a),
@@ -46,4 +46,4 @@ function (angular, _) {
       self.list = [];
     };
   });
-});
+});

+ 2 - 1
src/app/services/elasticsearch/es-datasource.js

@@ -73,8 +73,9 @@ function (angular, _, $, config, kbn, moment) {
         to: rangeUnparsed.to,
       };
 
+      var queryInterpolated = filterSrv.applyTemplateToTarget(queryString);
       var filter = { "bool": { "must": [{ "range": range }] } };
-      var query = { "bool": { "should": [{ "query_string": { "query": queryString } }] } };
+      var query = { "bool": { "should": [{ "query_string": { "query": queryInterpolated } }] } };
       var data = { "query" : { "filtered": { "query" : query, "filter": filter } }, "size": 100 };
 
       return this._request('POST', '/_search', annotation.index, data).then(function(results) {

+ 1 - 0
src/app/services/graphite/graphiteDatasource.js

@@ -205,6 +205,7 @@ function (angular, _, $, config, kbn, moment) {
       }
 
       options.url = this.url + options.url;
+      options.inspect = { type: 'graphite' };
 
       return $http(options);
     };

+ 4 - 2
src/app/services/influxdb/influxdbDatasource.js

@@ -132,8 +132,8 @@ function (angular, _, kbn, InfluxSeries) {
         return new InfluxSeries({ seriesList: results, annotation: annotation }).getAnnotations();
       });
     };
-
     InfluxDatasource.prototype.listColumns = function(seriesName) {
+
       return this._seriesQuery('select * from /' + seriesName + '/ limit 1').then(function(data) {
         if (!data) {
           return [];
@@ -184,6 +184,7 @@ function (angular, _, kbn, InfluxSeries) {
     function retry(deferred, callback, delay) {
       return callback().then(undefined, function(reason) {
         if (reason.status !== 0 || reason.status >= 300) {
+          reason.message = 'InfluxDB Error: <br/>' + reason.data;
           deferred.reject(reason);
         }
         else {
@@ -223,7 +224,8 @@ function (angular, _, kbn, InfluxSeries) {
           method: method,
           url:    currentUrl + url,
           params: params,
-          data:   data
+          data:   data,
+          inspect: { type: 'influxdb' },
         };
 
         return $http(options).success(function (data) {

+ 1 - 1
src/app/services/opentsdb/opentsdbDatasource.js

@@ -106,7 +106,7 @@ function (angular, _, kbn) {
     }
 
     function createMetricLabel(metric, tagData, options) {
-      if (options.alias) {
+      if (!_.isUndefined(options) && options.alias) {
         return options.alias;
       }
 

Plik diff jest za duży
+ 0 - 8
src/css/bootstrap-responsive.min.css


Plik diff jest za duży
+ 0 - 0
src/css/bootstrap.dark.min.css


Plik diff jest za duży
+ 0 - 0
src/css/bootstrap.light.min.css


Plik diff jest za duży
+ 0 - 0
src/css/default.min.css


+ 0 - 21
src/css/less/bootswatch.light.less

@@ -12,22 +12,6 @@ body {
 	//url('../img/light.png') repeat right top;
 }
 
-h1 {
-	font-size: 50px;
-}
-
-h2, h3 {
-	font-size: 26px;
-}
-
-h4 {
-	font-size: 14px;
-}
-
-h5, h6 {
-	font-size: 11px;
-}
-
 blockquote {
 
 	padding: 10px 15px;
@@ -527,11 +511,6 @@ a:hover {
 	.box-shadow(none);
 }
 
-[class^="icon-"], [class*=" icon-"] {
-	margin: 0 2px;
-	vertical-align: -2px;
-}
-
 a.thumbnail {
 	background-color: @grayLight;
 

+ 71 - 0
src/css/less/console.less

@@ -0,0 +1,71 @@
+.grafana-console {
+  position: fixed;
+  width: 100%;
+  bottom: 0px;
+  height: 300px;
+  background: @grafanaPanelBackground;
+  border-top: 1px solid @fullEditBorder;
+}
+
+.grafana-console-header {
+  background: @fullEditTabsBackground;
+  border-top: @fullEditTabsBorder;
+  padding: 2px 5px;
+}
+
+.grafana-console-item {
+  .icon-caret-right {
+    font-size: 14px;
+    color: @blue;
+  }
+  margin: 2px 0;
+  display: table-row;
+}
+
+.grafana-console-body {
+  overflow-y: auto;
+  display: table;
+  width: 100%;
+}
+
+.gfc-col {
+  display: table-cell;
+  padding: 2px 4px;
+  white-space: nowrap;
+  overflow: hidden;
+  vertical-align: middle;
+}
+
+.grafana-console-method {
+  text-align: center;
+}
+
+.grafana-console-error {
+  .grafana-console-method {
+    color: red;
+  }
+}
+
+.grafana-console-field2 {
+  width: 90%;
+}
+
+.grafana-console-time:before {
+  content: '(';
+  color: rgb(106, 253, 81);
+}
+
+.grafana-console-time:after {
+  content: ')';
+  color: rgb(106, 253, 81);
+}
+
+.grafana-console-time {
+  color: rgb(162, 196, 253);
+}
+
+.grafana-console-elapsed {
+  text-align: right;
+  color: rgb(162, 196, 253);
+}
+

+ 9 - 0
src/css/less/grafana.less

@@ -1,5 +1,6 @@
 @import "submenu.less";
 @import "graph.less";
+@import "console.less";
 @import "bootstrap-tagsinput.less";
 
 .hide-controls {
@@ -494,3 +495,11 @@ select.grafana-target-segment-input {
   border-radius: 5px;
   z-index: 9999;
 }
+
+.tooltip.in {
+  .opacity(100);
+}
+.tooltip-inner {
+  max-width: 400px;
+}
+

+ 15 - 0
src/css/less/graph.less

@@ -25,6 +25,21 @@
 .graph-legend-value {
   float: left;
   white-space: nowrap;
+  &.current:before {
+    content: "Current: "
+  }
+  &.max:before {
+    content: "Max: "
+  }
+  &.min:before {
+    content: "Min: "
+  }
+  &.total:before {
+    content: "Total: "
+  }
+  &.avg:before {
+    content: "Avg: "
+  }
 }
 
 .graph-legend-series {

+ 28 - 11
src/css/less/overrides.less

@@ -112,15 +112,27 @@ code, pre {
 
 .panel-error {
   color: @white;
-  padding: 5px 10px 0px 10px;
+  //padding: 5px 10px 0px 10px;
+  position: absolute;
+  left: 5px;
+  padding: 0px 17px 6px 5px;
+  top: 0;
+  i {
+    position: relative;
+    top: -2px;
+  }
 }
-
-.panel-error-inspector-link {
-  float: right;
-  margin-right: 10px;
+.panel-error-arrow {
+  width: 0;
+  height: 0;
+  position: absolute;
+  border-left: 31px solid transparent;
+  border-right: 30px solid transparent;
+  border-bottom: 27px solid @grafanaPanelBackground;
+  left: 0;
+  bottom: 0;
 }
 
-
 div.editor-row {
   vertical-align: top;
 }
@@ -223,9 +235,9 @@ form input.ng-invalid {
 
 .row-button {
   width: 30px;
-  text-align: center;
   float: left;
   cursor: pointer;
+  line-height: 31px;
 }
 
 .row-text {
@@ -233,15 +245,20 @@ form input.ng-invalid {
   text-transform: uppercase;
   font-weight: bold;
   font-size: 0.9em;
-  margin: 0px 10px;
+  text-align: center;
+  line-height: 31px;
 }
 
 .row-close {
   padding: 0px;
   margin: 0px;
-  min-height: 30px !important;
-  line-height: 30px;
   background: @grafanaPanelBackground;
+  text-align: center;
+}
+
+.row-close-buttons {
+  position: absolute;
+  left: 0;
 }
 
 .row-open {
@@ -614,4 +631,4 @@ div.flot-text {
 code, pre {
   background-color: @grafanaPanelBackground;
   color: @textColor;
-}
+}

+ 1 - 1
src/css/less/variables.dark.less

@@ -19,7 +19,7 @@
 @blue:                  #33B5E5;
 @blueDark:              #0099CC;
 @green:                 #669900;
-@red:                   #CC0000;
+@red:                   #CC3900;
 @yellow:                #ECBB13;
 @orange:                #FF8800;
 @pink:                  #FF4444;

+ 2 - 4
src/index.html

@@ -7,7 +7,7 @@
     <meta name="viewport" content="width=device-width">
 
     <title>Grafana</title>
-    <link rel="stylesheet" href="css/default.min.css" title="Dark">
+    <link rel="stylesheet" href="css/grafana.dark.min.css" title="Dark">
 
     <!-- build:js app/app.js -->
     <script src="vendor/require/require.js"></script>
@@ -20,9 +20,7 @@
 
   <body ng-cloak ng-controller="GrafanaCtrl">
 
-    <link rel="stylesheet" href="css/bootstrap.light.min.css" ng-if="grafana.style === 'light'">
-    <link rel="stylesheet" href="css/bootstrap-responsive.min.css">
-    <link rel="stylesheet" href="css/font-awesome.min.css">
+    <link rel="stylesheet" href="css/grafana.light.min.css" ng-if="grafana.style === 'light'">
 
     <div ng-repeat='alert in dashAlerts.list' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
       <button type="button" class="close" ng-click="dashAlerts.clear(alert)" style="padding-right:50px">&times;</button>

+ 3 - 2
src/vendor/angular/angular-strap.js

@@ -797,7 +797,8 @@ angular.module('$strap.directives').directive('bsTooltip', [
           title: function () {
             return angular.isFunction(value) ? value.apply(null, arguments) : value;
           },
-          html: true
+          html: true,
+          container: 'body', // Grafana change
         });
         var tooltip = element.data('tooltip');
         tooltip.show = function () {
@@ -875,4 +876,4 @@ angular.module('$strap.directives').directive('bsTypeahead', [
       }
     };
   }
-]);
+]);

+ 0 - 0
src/css/animate.min.css → src/vendor/css/animate.min.css


+ 0 - 0
src/css/font-awesome.min.css → src/vendor/css/font-awesome.min.css


+ 0 - 0
src/css/normalize.min.css → src/vendor/css/normalize.min.css


+ 0 - 0
src/css/spectrum.css → src/vendor/css/spectrum.css


+ 0 - 0
src/css/timepicker.css → src/vendor/css/timepicker.css


+ 2 - 1
tasks/build_task.js

@@ -6,7 +6,8 @@ module.exports = function(grunt) {
     'jshint:tests',
     'clean:on_start',
     'less:src',
-    'concat:css',
+    'concat:cssDark',
+    'concat:cssLight',
     'copy:everything_but_less_to_temp',
     'htmlmin:build',
     'ngtemplates',

+ 2 - 1
tasks/default_task.js

@@ -1,5 +1,6 @@
 // Lint and build CSS
 module.exports = function(grunt) {
-  grunt.registerTask('default', ['jscs', 'jshint', 'less:src', 'concat:css']);
+  grunt.registerTask('css', ['less:src', 'concat:cssDark', 'concat:cssLight']);
+  grunt.registerTask('default', ['jscs', 'jshint', 'css']);
   grunt.registerTask('test', ['default', 'karma:test']);
 };

+ 22 - 7
tasks/options/concat.js

@@ -1,15 +1,30 @@
 module.exports = function(config) {
   return {
-    css: {
+    cssDark: {
       src: [
-        '<%= srcDir %>/css/normalize.min.css',
-        '<%= srcDir %>/css/timepicker.css',
-        '<%= srcDir %>/css/spectrum.css',
-        '<%= srcDir %>/css/animate.min.css',
-        '<%= srcDir %>/css/bootstrap.dark.min.css'
+        '<%= srcDir %>/vendor/css/normalize.min.css',
+        '<%= srcDir %>/vendor/css/timepicker.css',
+        '<%= srcDir %>/vendor/css/spectrum.css',
+        '<%= srcDir %>/vendor/css/animate.min.css',
+        '<%= srcDir %>/css/bootstrap.dark.min.css',
+        '<%= srcDir %>/css/bootstrap-responsive.min.css',
+        '<%= srcDir %>/vendor/css/font-awesome.min.css'
       ],
-      dest: '<%= srcDir %>/css/default.min.css'
+      dest: '<%= srcDir %>/css/grafana.dark.min.css'
     },
+    cssLight: {
+      src: [
+        '<%= srcDir %>/vendor/css/normalize.min.css',
+        '<%= srcDir %>/vendor/css/timepicker.css',
+        '<%= srcDir %>/vendor/css/spectrum.css',
+        '<%= srcDir %>/vendor/css/animate.min.css',
+        '<%= srcDir %>/css/bootstrap.light.min.css',
+        '<%= srcDir %>/css/bootstrap-responsive.min.css',
+        '<%= srcDir %>/vendor/css/font-awesome.min.css'
+      ],
+      dest: '<%= srcDir %>/css/grafana.light.min.css'
+    },
+
     js: {
       src: [
         '<%= destDir %>/vendor/require/require.js',

+ 6 - 2
tasks/options/filerev.js

@@ -5,8 +5,12 @@ module.exports = function(config) {
       algorithm: 'md5',
       length: 8,
     },
-    css: {
-      src: '<%= destDir %>/css/default.min.css',
+    cssDark: {
+      src: '<%= destDir %>/css/grafana.dark.min.css',
+      dest: '<%= destDir %>/css'
+    },
+    cssLight: {
+      src: '<%= destDir %>/css/grafana.light.min.css',
       dest: '<%= destDir %>/css'
     },
     js: {

+ 1 - 1
tasks/options/requirejs.js

@@ -51,7 +51,7 @@ module.exports = function(config,grunt) {
         'modernizr',
         'timepicker',
         'datepicker',
-        'underscore',
+        'lodash',
         'filters/all',
         'jquery.flot',
         'services/all',

+ 11 - 0
tasks/options/watch.js

@@ -0,0 +1,11 @@
+module.exports = function(config) {
+  return {
+    css: {
+      files: [ '<%= srcDir %>/css/**/*.less' ],
+      tasks: ['css'],
+      options: {
+        spawn: false
+      }
+    }
+  };
+};

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików