소스 검색

Merge branch 'master' into postgres-query-builder

Sven Klemm 7 년 전
부모
커밋
70daa56a31
100개의 변경된 파일829개의 추가작업 그리고 729개의 파일을 삭제
  1. 13 0
      CHANGELOG.md
  2. 1 1
      docs/sources/administration/provisioning.md
  3. 29 1
      docs/sources/guides/getting_started.md
  4. 2 1
      docs/sources/installation/configuration.md
  5. 5 0
      docs/sources/installation/debian.md
  6. 5 0
      docs/sources/installation/docker.md
  7. 4 0
      docs/sources/installation/mac.md
  8. 4 0
      docs/sources/installation/rpm.md
  9. 5 0
      docs/sources/installation/windows.md
  10. 5 0
      docs/sources/project/building_from_source.md
  11. 2 2
      latest.json
  12. 1 1
      public/app/core/app_events.ts
  13. 2 2
      public/app/core/components/code_editor/code_editor.ts
  14. 1 1
      public/app/core/components/dashboard_selector.ts
  15. 7 7
      public/app/core/components/grafana_app.ts
  16. 2 2
      public/app/core/components/json_explorer/helpers.ts
  17. 1 1
      public/app/core/components/json_explorer/json_explorer.ts
  18. 1 1
      public/app/core/components/jsontree/jsontree.ts
  19. 2 2
      public/app/core/components/layout_selector/layout_selector.ts
  20. 3 3
      public/app/core/components/query_part/query_part.ts
  21. 19 19
      public/app/core/components/query_part/query_part_editor.ts
  22. 2 2
      public/app/core/components/search/search.ts
  23. 2 2
      public/app/core/components/sidemenu/sidemenu.ts
  24. 1 1
      public/app/core/components/switch.ts
  25. 18 10
      public/app/core/controllers/login_ctrl.ts
  26. 2 2
      public/app/core/directives/give_focus.ts
  27. 14 14
      public/app/core/directives/misc.ts
  28. 1 1
      public/app/core/directives/ng_model_on_blur.ts
  29. 1 1
      public/app/core/directives/rebuild_on_change.ts
  30. 3 3
      public/app/core/directives/tags.ts
  31. 5 6
      public/app/core/jquery_extended.ts
  32. 3 3
      public/app/core/live/live_srv.ts
  33. 2 2
      public/app/core/nav_model_srv.ts
  34. 5 5
      public/app/core/profiler.ts
  35. 8 7
      public/app/core/services/backend_srv.ts
  36. 1 1
      public/app/core/services/context_srv.ts
  37. 1 1
      public/app/core/services/impression_srv.ts
  38. 25 25
      public/app/core/services/ng_react.ts
  39. 1 1
      public/app/core/services/search_srv.ts
  40. 9 9
      public/app/core/time_series2.ts
  41. 6 6
      public/app/core/utils/datemath.ts
  42. 1 1
      public/app/core/utils/emitter.ts
  43. 1 1
      public/app/core/utils/model_utils.ts
  44. 4 4
      public/app/core/utils/outline.ts
  45. 1 1
      public/app/core/utils/sort_by_keys.ts
  46. 12 12
      public/app/core/utils/ticks.ts
  47. 9 9
      public/app/features/alerting/alert_def.ts
  48. 15 15
      public/app/features/alerting/alert_tab_ctrl.ts
  49. 4 4
      public/app/features/alerting/threshold_mapper.ts
  50. 5 5
      public/app/features/annotations/annotation_tooltip.ts
  51. 5 5
      public/app/features/annotations/annotations_srv.ts
  52. 1 1
      public/app/features/annotations/editor_ctrl.ts
  53. 2 2
      public/app/features/annotations/event_manager.ts
  54. 8 8
      public/app/features/dashboard/dashboard_migration.ts
  55. 7 7
      public/app/features/dashboard/dashboard_model.ts
  56. 2 2
      public/app/features/dashboard/panel_model.ts
  57. 11 11
      public/app/features/panel/metrics_panel_ctrl.ts
  58. 1 1
      public/app/features/panel/metrics_tab.ts
  59. 14 14
      public/app/features/panel/panel_ctrl.ts
  60. 10 10
      public/app/features/panellinks/link_srv.ts
  61. 59 40
      public/app/features/playlist/partials/playlists.html
  62. 3 3
      public/app/features/plugins/datasource_srv.ts
  63. 2 2
      public/app/features/templating/variable.ts
  64. 4 1
      public/app/partials/login.html
  65. 38 38
      public/app/plugins/datasource/cloudwatch/datasource.ts
  66. 10 10
      public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts
  67. 5 5
      public/app/plugins/datasource/elasticsearch/bucket_agg.ts
  68. 1 1
      public/app/plugins/datasource/elasticsearch/config_ctrl.ts
  69. 45 45
      public/app/plugins/datasource/elasticsearch/datasource.ts
  70. 30 30
      public/app/plugins/datasource/elasticsearch/elastic_response.ts
  71. 4 4
      public/app/plugins/datasource/elasticsearch/index_pattern.ts
  72. 12 12
      public/app/plugins/datasource/elasticsearch/metric_agg.ts
  73. 14 14
      public/app/plugins/datasource/elasticsearch/query_builder.ts
  74. 8 8
      public/app/plugins/datasource/elasticsearch/query_ctrl.ts
  75. 8 8
      public/app/plugins/datasource/elasticsearch/query_def.ts
  76. 1 1
      public/app/plugins/datasource/grafana/datasource.ts
  77. 7 7
      public/app/plugins/datasource/graphite/add_graphite_func.ts
  78. 17 17
      public/app/plugins/datasource/graphite/datasource.ts
  79. 22 22
      public/app/plugins/datasource/graphite/func_editor.ts
  80. 8 8
      public/app/plugins/datasource/graphite/gfunc.ts
  81. 10 10
      public/app/plugins/datasource/graphite/graphite_query.ts
  82. 20 20
      public/app/plugins/datasource/graphite/lexer.ts
  83. 13 13
      public/app/plugins/datasource/graphite/parser.ts
  84. 5 5
      public/app/plugins/datasource/graphite/query_ctrl.ts
  85. 24 24
      public/app/plugins/datasource/influxdb/datasource.ts
  86. 15 15
      public/app/plugins/datasource/influxdb/influx_query.ts
  87. 17 17
      public/app/plugins/datasource/influxdb/influx_series.ts
  88. 1 1
      public/app/plugins/datasource/influxdb/query_builder.ts
  89. 15 15
      public/app/plugins/datasource/influxdb/query_ctrl.ts
  90. 11 11
      public/app/plugins/datasource/influxdb/query_part.ts
  91. 4 4
      public/app/plugins/datasource/influxdb/response_parser.ts
  92. 4 4
      public/app/plugins/datasource/mixed/datasource.ts
  93. 2 2
      public/app/plugins/datasource/mssql/datasource.ts
  94. 1 1
      public/app/plugins/datasource/mssql/response_parser.ts
  95. 3 3
      public/app/plugins/datasource/mysql/datasource.ts
  96. 1 1
      public/app/plugins/datasource/mysql/response_parser.ts
  97. 42 42
      public/app/plugins/datasource/opentsdb/datasource.ts
  98. 2 2
      public/app/plugins/datasource/opentsdb/query_ctrl.ts
  99. 3 3
      public/app/plugins/datasource/postgres/datasource.ts
  100. 1 1
      public/app/plugins/datasource/postgres/response_parser.ts

+ 13 - 0
CHANGELOG.md

@@ -57,6 +57,7 @@ om/grafana/grafana/issues/12668)
 * **InfluxDB**: Support timeFilter in query templating for InfluxDB [#12598](https://github.com/grafana/grafana/pull/12598), thx [kichristensen](https://github.com/kichristensen)
 * **Provisioning**: Should allow one default datasource per organisation [#12229](https://github.com/grafana/grafana/issues/12229)
 * **Heatmap**: Fix broken tooltip and crosshair on Firefox [#12486](https://github.com/grafana/grafana/issues/12486)
+* **Login**: Show loading animation while waiting for authentication response on login [#12865](https://github.com/grafana/grafana/issues/12865)
 
 ### Breaking changes
 
@@ -72,6 +73,12 @@ These are new features that's still being worked on and are in an experimental p
 
 * **Frontend**: Convert all Frontend Karma tests to Jest tests [#12224](https://github.com/grafana/grafana/issues/12224)
 
+# 5.2.3 (2018-08-29)
+
+### Important fix for LDAP & OAuth login vulnerability
+
+See [security announcement](https://community.grafana.com/t/grafana-5-2-3-and-4-6-4-security-update/10050) for details.
+
 # 5.2.2 (2018-07-25)
 
 ### Minor
@@ -440,6 +447,12 @@ The following properties have been deprecated and will be removed in a future re
   - `uri` property in `GET /api/search` -> Use new `url` or `uid` property instead
   - `meta.slug` property in `GET /api/dashboards/uid/:uid` and `GET /api/dashboards/db/:slug` -> Use new `meta.url` or `dashboard.uid` property instead
 
+# 4.6.4 (2018-08-29)
+
+### Important fix for LDAP & OAuth login vulnerability
+
+See [security announcement](https://community.grafana.com/t/grafana-5-2-3-and-4-6-4-security-update/10050) for details.
+
 # 4.6.3 (2017-12-14)
 
 ## Fixes

+ 1 - 1
docs/sources/administration/provisioning.md

@@ -155,7 +155,7 @@ Since not all datasources have the same configuration settings we only have the
 | tlsSkipVerify | boolean | *All* | Controls whether a client verifies the server's certificate chain and host name. |
 | graphiteVersion | string | Graphite |  Graphite version  |
 | timeInterval | string | Elastic, InfluxDB & Prometheus | Lowest interval/step value that should be used for this data source |
-| esVersion | string | Elastic | Elasticsearch version as an number (2/5/56) |
+| esVersion | number | Elastic | Elasticsearch version as an number (2/5/56) |
 | timeField | string | Elastic | Which field that should be used as timestamp |
 | interval | string | Elastic | Index date time format |
 | authType | string | Cloudwatch | Auth provider. keys/credentials/arn |

+ 29 - 1
docs/sources/guides/getting_started.md

@@ -13,7 +13,35 @@ weight = 1
 
 # Getting started
 
-This guide will help you get started and acquainted with Grafana. It assumes you have a working Grafana server up and running and have added at least one [Data Source](/features/datasources/).
+This guide will help you get started and acquainted with Grafana. It assumes you have a working Grafana server up and running. If not please read the [installation guide](/installation/).
+
+## Logging in for the first time
+
+To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default http port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port).
+
+There you will see the login page. Default username is admin and default password is admin. When you log in for the first time you will be asked to change your password. We strongly encourage you to
+follow Grafana’s best practices and change the default administrator password. You can later go to user preferences and change your user name.
+
+
+## How to add a data source
+
+{{< docs-imagebox img="/img/docs/v52/sidemenu-datasource.png" max-width="250px" class="docs-image--right docs-image--no-shadow">}}
+
+Before you create your first dashboard you need to add your data source.
+
+First move your cursor to the cog on the side menu which will show you the configuration menu. If the side menu is not visible click the Grafana icon in the upper left corner. The first item on the configuration menu is data sources, click on that and you'll be taken to the data sources page where you can add and edit data sources. You can also simply click the cog.
+
+
+Click Add data source and you will come to the settings page of your new data source.
+
+{{< docs-imagebox img="/img/docs/v52/add-datasource.png" max-width="700px" class="docs-image--no-shadow">}}
+
+First, give the data source a Name and then select which Type of data source you'll want to create, see [Supported data sources](/features/datasources/#supported-data-sources/) for more information and how to configure your data source.
+
+
+{{< docs-imagebox img="/img/docs/v52/datasource-settings.png" max-width="700px" class="docs-image--no-shadow">}}
+
+After you have configuered your data source you are ready to save and test.
 
 ## Beginner guides
 

+ 2 - 1
docs/sources/installation/configuration.md

@@ -266,7 +266,8 @@ The number of days the keep me logged in / remember me cookie lasts.
 
 ### secret_key
 
-Used for signing keep me logged in / remember me cookies.
+Used for signing some datasource settings like secrets and passwords. Cannot be changed without requiring an update
+to datasource settings to re-encode them.
 
 ### disable_gravatar
 

+ 5 - 0
docs/sources/installation/debian.md

@@ -166,3 +166,8 @@ To configure Grafana add a configuration file named `custom.ini` to the
 Start Grafana by executing `./bin/grafana-server web`. The `grafana-server`
 binary needs the working directory to be the root install directory (where the
 binary and the `public` folder is located).
+
+## Logging in for the first time
+
+To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default http port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port).
+Then follow the instructions [here](/guides/getting_started/).

+ 5 - 0
docs/sources/installation/docker.md

@@ -217,3 +217,8 @@ chown -R root:root /etc/grafana && \
   chown -R grafana:grafana /var/lib/grafana && \
   chown -R grafana:grafana /usr/share/grafana
 ```
+
+## Logging in for the first time
+
+To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default http port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port).
+Then follow the instructions [here](/guides/getting_started/).

+ 4 - 0
docs/sources/installation/mac.md

@@ -92,3 +92,7 @@ Start Grafana by executing `./bin/grafana-server web`. The `grafana-server`
 binary needs the working directory to be the root install directory (where the
 binary and the `public` folder is located).
 
+## Logging in for the first time
+
+To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default http port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port).
+Then follow the instructions [here](/guides/getting_started/).

+ 4 - 0
docs/sources/installation/rpm.md

@@ -193,3 +193,7 @@ Start Grafana by executing `./bin/grafana-server web`. The `grafana-server`
 binary needs the working directory to be the root install directory (where the
 binary and the `public` folder is located).
 
+## Logging in for the first time
+
+To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default http port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port).
+Then follow the instructions [here](/guides/getting_started/).

+ 5 - 0
docs/sources/installation/windows.md

@@ -38,6 +38,11 @@ service using that tool.
 
 Read more about the [configuration options]({{< relref "configuration.md" >}}).
 
+## Logging in for the first time
+
+To run Grafana open your browser and go to the port you configured above, e.g. http://localhost:8080/.
+Then follow the instructions [here](/guides/getting_started/).
+
 ## Building on Windows
 
 The Grafana backend includes Sqlite3 which requires GCC to compile. So

+ 5 - 0
docs/sources/project/building_from_source.md

@@ -141,3 +141,8 @@ Please contribute to the Grafana project and submit a pull request! Build new fe
 **Problem**: On Windows, getting errors about a tool not being installed even though you just installed that tool.
 
 **Solution**: It is usually because it got added to the path and you have to restart your command prompt to use it.
+
+## Logging in for the first time
+
+To run Grafana open your browser and go to the default port http://localhost:3000 or the port you have configured.
+Then follow the instructions [here](/guides/getting_started/).

+ 2 - 2
latest.json

@@ -1,4 +1,4 @@
 {
-  "stable": "5.2.0",
-  "testing": "5.2.0"
+  "stable": "5.2.3",
+  "testing": "5.2.3"
 }

+ 1 - 1
public/app/core/app_events.ts

@@ -1,4 +1,4 @@
 import { Emitter } from './utils/emitter';
 
-var appEvents = new Emitter();
+const appEvents = new Emitter();
 export default appEvents;

+ 2 - 2
public/app/core/components/code_editor/code_editor.ts

@@ -99,9 +99,9 @@ function link(scope, elem, attrs) {
   if (scope.codeEditorFocus) {
     setTimeout(function() {
       textarea.focus();
-      var domEl = textarea[0];
+      const domEl = textarea[0];
       if (domEl.setSelectionRange) {
-        var pos = textarea.val().length * 2;
+        const pos = textarea.val().length * 2;
         domEl.setSelectionRange(pos, pos);
       }
     }, 100);

+ 1 - 1
public/app/core/components/dashboard_selector.ts

@@ -1,6 +1,6 @@
 import coreModule from 'app/core/core_module';
 
-var template = `
+const template = `
 <select class="gf-form-input" ng-model="ctrl.model" ng-options="f.value as f.text for f in ctrl.options"></select>
 `;
 

+ 7 - 7
public/app/core/components/grafana_app.ts

@@ -49,7 +49,7 @@ export class GrafanaCtrl {
     };
 
     $rootScope.onAppEvent = function(name, callback, localScope) {
-      var unbind = $rootScope.$on(name, callback);
+      const unbind = $rootScope.$on(name, callback);
       var callerScope = this;
       if (callerScope.$id === 1 && !localScope) {
         console.log('warning rootScope onAppEvent called without localscope');
@@ -76,7 +76,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
     controller: GrafanaCtrl,
     link: (scope, elem) => {
       var sidemenuOpen;
-      var body = $('body');
+      const body = $('body');
 
       // see https://github.com/zenorocha/clipboard.js/issues/155
       $.fn.modal.Constructor.prototype.enforceFocus = function() {};
@@ -153,7 +153,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
       // handle in active view state class
       var lastActivity = new Date().getTime();
       var activeUser = true;
-      var inActiveTimeLimit = 60 * 1000;
+      const inActiveTimeLimit = 60 * 1000;
       var sidemenuHidden = false;
 
       function checkForInActiveUser() {
@@ -215,16 +215,16 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
 
       // handle document clicks that should hide things
       body.click(function(evt) {
-        var target = $(evt.target);
+        const target = $(evt.target);
         if (target.parents().length === 0) {
           return;
         }
 
         // for stuff that animates, slides out etc, clicking it needs to
         // hide it right away
-        var clickAutoHide = target.closest('[data-click-hide]');
+        const clickAutoHide = target.closest('[data-click-hide]');
         if (clickAutoHide.length) {
-          var clickAutoHideParent = clickAutoHide.parent();
+          const clickAutoHideParent = clickAutoHide.parent();
           clickAutoHide.detach();
           setTimeout(function() {
             clickAutoHideParent.append(clickAutoHide);
@@ -245,7 +245,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
         }
 
         // hide popovers
-        var popover = elem.find('.popover');
+        const popover = elem.find('.popover');
         if (popover.length > 0 && target.parents('.graph-legend').length === 0) {
           popover.hide();
         }

+ 2 - 2
public/app/core/components/json_explorer/helpers.ts

@@ -12,7 +12,7 @@ function escapeString(str: string): string {
  * Determines if a value is an object
 */
 export function isObject(value: any): boolean {
-  var type = typeof value;
+  const type = typeof value;
   return !!value && type === 'object';
 }
 
@@ -55,7 +55,7 @@ export function getType(object: Object): string {
  * Generates inline preview for a JavaScript object based on a value
 */
 export function getValuePreview(object: Object, value: string): string {
-  var type = getType(object);
+  const type = getType(object);
 
   if (type === 'null' || type === 'undefined') {
     return type;

+ 1 - 1
public/app/core/components/json_explorer/json_explorer.ts

@@ -279,7 +279,7 @@ export class JsonExplorer {
       const objectWrapperSpan = createElement('span');
 
       // get constructor name and append it to wrapper span
-      var constructorName = createElement('span', 'constructor-name', this.constructorName);
+      const constructorName = createElement('span', 'constructor-name', this.constructorName);
       objectWrapperSpan.appendChild(constructorName);
 
       // if it's an array append the array specific elements like brackets and length

+ 1 - 1
public/app/core/components/jsontree/jsontree.ts

@@ -11,7 +11,7 @@ coreModule.directive('jsonTree', [
         rootName: '@',
       },
       link: function(scope, elem) {
-        var jsonExp = new JsonExplorer(scope.object, 3, {
+        const jsonExp = new JsonExplorer(scope.object, 3, {
           animateOpen: true,
         });
 

+ 2 - 2
public/app/core/components/layout_selector/layout_selector.ts

@@ -1,7 +1,7 @@
 import store from 'app/core/store';
 import coreModule from 'app/core/core_module';
 
-var template = `
+const template = `
 <div class="layout-selector">
   <button ng-click="ctrl.listView()" ng-class="{active: ctrl.mode === 'list'}">
     <i class="fa fa-list"></i>
@@ -51,7 +51,7 @@ export function layoutMode($rootScope) {
     restrict: 'A',
     scope: {},
     link: function(scope, elem) {
-      var layout = store.get('grafana.list.layout.mode') || 'grid';
+      const layout = store.get('grafana.list.layout.mode') || 'grid';
       var className = 'card-list-layout-' + layout;
       elem.addClass(className);
 

+ 3 - 3
public/app/core/components/query_part/query_part.ts

@@ -82,9 +82,9 @@ export class QueryPart {
 }
 
 export function functionRenderer(part, innerExpr) {
-  var str = part.def.type + '(';
-  var parameters = _.map(part.params, (value, index) => {
-    var paramType = part.def.params[index];
+  const str = part.def.type + '(';
+  const parameters = _.map(part.params, (value, index) => {
+    const paramType = part.def.params[index];
     if (paramType.type === 'time') {
       if (value === 'auto') {
         value = '$__interval';

+ 19 - 19
public/app/core/components/query_part/query_part_editor.ts

@@ -2,7 +2,7 @@ import _ from 'lodash';
 import $ from 'jquery';
 import coreModule from 'app/core/core_module';
 
-var template = `
+const template = `
 <div class="dropdown cascade-open">
 <a ng-click="showActionsMenu()" class="query-part-name pointer dropdown-toggle" data-toggle="dropdown">{{part.def.type}}</a>
 <span>(</span><span class="query-part-parameters"></span><span>)</span>
@@ -15,7 +15,7 @@ var template = `
 
 /** @ngInject */
 export function queryPartEditorDirective($compile, templateSrv) {
-  var paramTemplate = '<input type="text" class="hide input-mini tight-form-func-param"></input>';
+  const paramTemplate = '<input type="text" class="hide input-mini tight-form-func-param"></input>';
 
   return {
     restrict: 'E',
@@ -26,17 +26,17 @@ export function queryPartEditorDirective($compile, templateSrv) {
       debounce: '@',
     },
     link: function postLink($scope, elem) {
-      var part = $scope.part;
-      var partDef = part.def;
-      var $paramsContainer = elem.find('.query-part-parameters');
-      var debounceLookup = $scope.debounce;
+      const part = $scope.part;
+      const partDef = part.def;
+      const $paramsContainer = elem.find('.query-part-parameters');
+      const debounceLookup = $scope.debounce;
 
       $scope.partActions = [];
 
       function clickFuncParam(paramIndex) {
         /*jshint validthis:true */
-        var $link = $(this);
-        var $input = $link.next();
+        const $link = $(this);
+        const $input = $link.next();
 
         $input.val(part.params[paramIndex]);
         $input.css('width', $link.width() + 16 + 'px');
@@ -46,7 +46,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
         $input.focus();
         $input.select();
 
-        var typeahead = $input.data('typeahead');
+        const typeahead = $input.data('typeahead');
         if (typeahead) {
           $input.val('');
           typeahead.lookup();
@@ -55,9 +55,9 @@ export function queryPartEditorDirective($compile, templateSrv) {
 
       function inputBlur(paramIndex) {
         /*jshint validthis:true */
-        var $input = $(this);
-        var $link = $input.prev();
-        var newValue = $input.val();
+        const $input = $(this);
+        const $link = $input.prev();
+        const newValue = $input.val();
 
         if (newValue !== '' || part.def.params[paramIndex].optional) {
           $link.html(templateSrv.highlightVariablesAsHtml(newValue));
@@ -89,7 +89,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
           return;
         }
 
-        var typeaheadSource = function(query, callback) {
+        const typeaheadSource = function(query, callback) {
           if (param.options) {
             var options = param.options;
             if (param.type === 'int') {
@@ -102,7 +102,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
 
           $scope.$apply(function() {
             $scope.handleEvent({ $event: { name: 'get-param-options' } }).then(function(result) {
-              var dynamicOptions = _.map(result, function(op) {
+              const dynamicOptions = _.map(result, function(op) {
                 return op.value;
               });
               callback(dynamicOptions);
@@ -124,10 +124,10 @@ export function queryPartEditorDirective($compile, templateSrv) {
           },
         });
 
-        var typeahead = $input.data('typeahead');
+        const typeahead = $input.data('typeahead');
         typeahead.lookup = function() {
           this.query = this.$element.val() || '';
-          var items = this.source(this.query, $.proxy(this.process, this));
+          const items = this.source(this.query, $.proxy(this.process, this));
           return items ? this.process(items) : items;
         };
 
@@ -156,9 +156,9 @@ export function queryPartEditorDirective($compile, templateSrv) {
             $('<span>, </span>').appendTo($paramsContainer);
           }
 
-          var paramValue = templateSrv.highlightVariablesAsHtml(part.params[index]);
-          var $paramLink = $('<a class="graphite-func-param-link pointer">' + paramValue + '</a>');
-          var $input = $(paramTemplate);
+          const paramValue = templateSrv.highlightVariablesAsHtml(part.params[index]);
+          const $paramLink = $('<a class="graphite-func-param-link pointer">' + paramValue + '</a>');
+          const $input = $(paramTemplate);
 
           $paramLink.appendTo($paramsContainer);
           $input.appendTo($paramsContainer);

+ 2 - 2
public/app/core/components/search/search.ts

@@ -159,7 +159,7 @@ export class SearchCtrl {
 
   searchDashboards() {
     this.currentSearchId = this.currentSearchId + 1;
-    var localSearchId = this.currentSearchId;
+    const localSearchId = this.currentSearchId;
 
     return this.searchSrv.search(this.query).then(results => {
       if (localSearchId < this.currentSearchId) {
@@ -172,7 +172,7 @@ export class SearchCtrl {
   }
 
   queryHasNoFilters() {
-    var query = this.query;
+    const query = this.query;
     return query.query === '' && query.starred === false && query.tag.length === 0;
   }
 

+ 2 - 2
public/app/core/components/sidemenu/sidemenu.ts

@@ -74,8 +74,8 @@ export function sideMenuDirective() {
     link: function(scope, elem) {
       // hack to hide dropdown menu
       elem.on('click.dropdown', '.dropdown-menu a', function(evt) {
-        var menu = $(evt.target).parents('.dropdown-menu');
-        var parent = menu.parent();
+        const menu = $(evt.target).parents('.dropdown-menu');
+        const parent = menu.parent();
         menu.detach();
 
         setTimeout(function() {

+ 1 - 1
public/app/core/components/switch.ts

@@ -1,6 +1,6 @@
 import coreModule from 'app/core/core_module';
 
-var template = `
+const template = `
 <label for="check-{{ctrl.id}}" class="gf-form-label {{ctrl.labelClass}} pointer" ng-show="ctrl.label">
   {{ctrl.label}}
   <info-popover mode="right-normal" ng-if="ctrl.tooltip" position="top center">

+ 18 - 10
public/app/core/controllers/login_ctrl.ts

@@ -13,6 +13,7 @@ export class LoginCtrl {
 
     $scope.command = {};
     $scope.result = '';
+    $scope.loggingIn = false;
 
     contextSrv.sidemenu = false;
 
@@ -105,16 +106,23 @@ export class LoginCtrl {
       if (!$scope.loginForm.$valid) {
         return;
       }
-
-      backendSrv.post('/login', $scope.formModel).then(function(result) {
-        $scope.result = result;
-
-        if ($scope.formModel.password !== 'admin' || $scope.ldapEnabled || $scope.authProxyEnabled) {
-          $scope.toGrafana();
-          return;
-        }
-        $scope.changeView();
-      });
+      $scope.loggingIn = true;
+
+      backendSrv
+        .post('/login', $scope.formModel)
+        .then(function(result) {
+          $scope.result = result;
+
+          if ($scope.formModel.password !== 'admin' || $scope.ldapEnabled || $scope.authProxyEnabled) {
+            $scope.toGrafana();
+            return;
+          } else {
+            $scope.changeView();
+          }
+        })
+        .catch(() => {
+          $scope.loggingIn = false;
+        });
     };
 
     $scope.toGrafana = function() {

+ 2 - 2
public/app/core/directives/give_focus.ts

@@ -14,9 +14,9 @@ coreModule.directive('giveFocus', function() {
         }
         setTimeout(function() {
           element.focus();
-          var domEl = element[0];
+          const domEl = element[0];
           if (domEl.setSelectionRange) {
-            var pos = element.val().length * 2;
+            const pos = element.val().length * 2;
             domEl.setSelectionRange(pos, pos);
           }
         }, 200);

+ 14 - 14
public/app/core/directives/misc.ts

@@ -82,11 +82,11 @@ function editorOptBool($compile) {
   return {
     restrict: 'E',
     link: function(scope, elem, attrs) {
-      var ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
-      var tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
-      var showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : '';
+      const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
+      const tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
+      const showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : '';
 
-      var template =
+      const template =
         '<div class="editor-option gf-form-checkbox text-center"' +
         showIf +
         '>' +
@@ -119,11 +119,11 @@ function editorCheckbox($compile, $interpolate) {
   return {
     restrict: 'E',
     link: function(scope, elem, attrs) {
-      var text = $interpolate(attrs.text)(scope);
-      var model = $interpolate(attrs.model)(scope);
-      var ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
-      var tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
-      var label = '<label for="' + scope.$id + model + '" class="checkbox-label">' + text + tip + '</label>';
+      const text = $interpolate(attrs.text)(scope);
+      const model = $interpolate(attrs.model)(scope);
+      const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
+      const tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
+      const label = '<label for="' + scope.$id + model + '" class="checkbox-label">' + text + tip + '</label>';
 
       var template =
         '<input class="cr1" id="' +
@@ -152,8 +152,8 @@ function editorCheckbox($compile, $interpolate) {
 /** @ngInject */
 function gfDropdown($parse, $compile, $timeout) {
   function buildTemplate(items, placement?) {
-    var upclass = placement === 'top' ? 'dropup' : '';
-    var ul = ['<ul class="dropdown-menu ' + upclass + '" role="menu" aria-labelledby="drop1">', '</ul>'];
+    const upclass = placement === 'top' ? 'dropup' : '';
+    const ul = ['<ul class="dropdown-menu ' + upclass + '" role="menu" aria-labelledby="drop1">', '</ul>'];
 
     for (let index = 0; index < items.length; index++) {
       const item = items[index];
@@ -192,11 +192,11 @@ function gfDropdown($parse, $compile, $timeout) {
     restrict: 'EA',
     scope: true,
     link: function postLink(scope, iElement, iAttrs) {
-      var getter = $parse(iAttrs.gfDropdown),
+      const getter = $parse(iAttrs.gfDropdown),
         items = getter(scope);
       $timeout(function() {
-        var placement = iElement.data('placement');
-        var dropdown = angular.element(buildTemplate(items, placement).join(''));
+        const placement = iElement.data('placement');
+        const dropdown = angular.element(buildTemplate(items, placement).join(''));
         dropdown.insertAfter(iElement);
         $compile(iElement.next('ul.dropdown-menu'))(scope);
       });

+ 1 - 1
public/app/core/directives/ng_model_on_blur.ts

@@ -47,7 +47,7 @@ function validTimeSpan() {
         if (viewValue.indexOf('$') === 0 || viewValue.indexOf('+$') === 0) {
           return true; // allow template variable
         }
-        var info = rangeUtil.describeTextRange(viewValue);
+        const info = rangeUtil.describeTextRange(viewValue);
         return info.invalid !== true;
       };
     },

+ 1 - 1
public/app/core/directives/rebuild_on_change.ts

@@ -3,7 +3,7 @@ import coreModule from '../core_module';
 
 function getBlockNodes(nodes) {
   var node = nodes[0];
-  var endNode = nodes[nodes.length - 1];
+  const endNode = nodes[nodes.length - 1];
   var blockNodes;
 
   for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {

+ 3 - 3
public/app/core/directives/tags.ts

@@ -47,7 +47,7 @@ function bootstrapTagsinput() {
         scope.model = [];
       }
 
-      var select = $('select', element);
+      const select = $('select', element);
 
       if (attrs.placeholder) {
         select.attr('placeholder', attrs.placeholder);
@@ -76,7 +76,7 @@ function bootstrapTagsinput() {
             scope.onTagsUpdated();
           }
         }
-        var tagElement = select
+        const tagElement = select
           .next()
           .children('span')
           .filter(function() {
@@ -86,7 +86,7 @@ function bootstrapTagsinput() {
       });
 
       select.on('itemRemoved', function(event) {
-        var idx = scope.model.indexOf(event.item);
+        const idx = scope.model.indexOf(event.item);
         if (idx !== -1) {
           scope.model.splice(idx, 1);
           if (scope.onTagsUpdated) {

+ 5 - 6
public/app/core/jquery_extended.ts

@@ -2,10 +2,10 @@ import $ from 'jquery';
 import angular from 'angular';
 import _ from 'lodash';
 
-var $win = $(window);
+const $win = $(window);
 
 $.fn.place_tt = (function() {
-  var defaults = {
+  const defaults = {
     offset: 5,
   };
 
@@ -13,9 +13,8 @@ $.fn.place_tt = (function() {
     opts = $.extend(true, {}, defaults, opts);
 
     return this.each(function() {
-      var $tooltip = $(this),
-        width,
-        height;
+      const $tooltip = $(this);
+      let width, height;
 
       $tooltip.addClass('grafana-tooltip');
 
@@ -30,7 +29,7 @@ $.fn.place_tt = (function() {
             '$compile',
             '$rootScope',
             function($compile, $rootScope) {
-              var tmpScope = $rootScope.$new(true);
+              const tmpScope = $rootScope.$new(true);
               _.extend(tmpScope, opts.scopeData);
 
               $compile($tooltip)(tmpScope);

+ 3 - 3
public/app/core/live/live_srv.ts

@@ -13,7 +13,7 @@ export class LiveSrv {
   }
 
   getWebSocketUrl() {
-    var l = window.location;
+    const l = window.location;
     return (l.protocol === 'https:' ? 'wss://' : 'ws://') + l.host + config.appSubUrl + '/ws';
   }
 
@@ -66,7 +66,7 @@ export class LiveSrv {
       return;
     }
 
-    var observer = this.observers[message.stream];
+    const observer = this.observers[message.stream];
     if (!observer) {
       this.removeObserver(message.stream, null);
       return;
@@ -128,5 +128,5 @@ export class LiveSrv {
   }
 }
 
-var instance = new LiveSrv();
+const instance = new LiveSrv();
 export { instance as liveSrv };

+ 2 - 2
public/app/core/nav_model_srv.ts

@@ -39,7 +39,7 @@ export class NavModelSrv {
 
   getNav(...args) {
     var children = this.navItems;
-    var nav = new NavModel();
+    const nav = new NavModel();
 
     for (const id of args) {
       // if its a number then it's the index to use for main
@@ -69,7 +69,7 @@ export class NavModelSrv {
   }
 
   getNotFoundNav() {
-    var node = {
+    const node = {
       text: 'Page not found',
       icon: 'fa fa-fw fa-warning',
       subTitle: '404 Error',

+ 5 - 5
public/app/core/profiler.ts

@@ -64,11 +64,11 @@ export class Profiler {
       console.log('Dashboard::Performance Total Watchers: ' + this.getTotalWatcherCount());
       console.log('Dashboard::Performance Total ScopeCount: ' + this.scopeCount);
 
-      var timeTaken = this.timings.lastPanelInitializedAt - this.timings.dashboardLoadStart;
+      const timeTaken = this.timings.lastPanelInitializedAt - this.timings.dashboardLoadStart;
       console.log('Dashboard::Performance All panels initialized in ' + timeTaken + ' ms');
 
       // measure digest performance
-      var rootDigestStart = window.performance.now();
+      const rootDigestStart = window.performance.now();
       for (var i = 0; i < 30; i++) {
         this.$rootScope.$apply();
       }
@@ -80,9 +80,9 @@ export class Profiler {
   getTotalWatcherCount() {
     var count = 0;
     var scopes = 0;
-    var root = $(document.getElementsByTagName('body'));
+    const root = $(document.getElementsByTagName('body'));
 
-    var f = function(element) {
+    const f = function(element) {
       if (element.data().hasOwnProperty('$scope')) {
         scopes++;
         angular.forEach(element.data().$scope.$$watchers, function() {
@@ -126,5 +126,5 @@ export class Profiler {
   }
 }
 
-var profiler = new Profiler();
+const profiler = new Profiler();
 export { profiler };

+ 8 - 7
public/app/core/services/backend_srv.ts

@@ -74,8 +74,8 @@ export class BackendSrv {
 
   request(options) {
     options.retry = options.retry || 0;
-    var requestIsLocal = !options.url.match(/^http/);
-    var firstAttempt = options.retry === 0;
+    const requestIsLocal = !options.url.match(/^http/);
+    const firstAttempt = options.retry === 0;
 
     if (requestIsLocal) {
       if (this.contextSrv.user && this.contextSrv.user.orgId) {
@@ -123,30 +123,31 @@ export class BackendSrv {
   }
 
   resolveCancelerIfExists(requestId) {
-    var cancelers = this.inFlightRequests[requestId];
+    const cancelers = this.inFlightRequests[requestId];
     if (!_.isUndefined(cancelers) && cancelers.length) {
       cancelers[0].resolve();
     }
   }
 
   datasourceRequest(options) {
+    let canceler = null;
     options.retry = options.retry || 0;
 
     // A requestID is provided by the datasource as a unique identifier for a
     // particular query. If the requestID exists, the promise it is keyed to
     // is canceled, canceling the previous datasource request if it is still
     // in-flight.
-    var requestId = options.requestId;
+    const requestId = options.requestId;
     if (requestId) {
       this.resolveCancelerIfExists(requestId);
       // create new canceler
-      var canceler = this.$q.defer();
+      canceler = this.$q.defer();
       options.timeout = canceler.promise;
       this.addCanceler(requestId, canceler);
     }
 
-    var requestIsLocal = !options.url.match(/^http/);
-    var firstAttempt = options.retry === 0;
+    const requestIsLocal = !options.url.match(/^http/);
+    const firstAttempt = options.retry === 0;
 
     if (requestIsLocal) {
       if (this.contextSrv.user && this.contextSrv.user.orgId) {

+ 1 - 1
public/app/core/services/context_srv.ts

@@ -59,7 +59,7 @@ export class ContextSrv {
   }
 }
 
-var contextSrv = new ContextSrv();
+const contextSrv = new ContextSrv();
 export { contextSrv };
 
 coreModule.factory('contextSrv', function() {

+ 1 - 1
public/app/core/services/impression_srv.ts

@@ -6,7 +6,7 @@ export class ImpressionSrv {
   constructor() {}
 
   addDashboardImpression(dashboardId) {
-    var impressionsKey = this.impressionKey(config);
+    const impressionsKey = this.impressionKey(config);
     var impressions = [];
     if (store.exists(impressionsKey)) {
       impressions = JSON.parse(store.get(impressionsKey));

+ 25 - 25
public/app/core/services/ng_react.ts

@@ -52,9 +52,9 @@ function applied(fn, scope) {
   if (fn.wrappedInApply) {
     return fn;
   }
-  var wrapped: any = function() {
-    var args = arguments;
-    var phase = scope.$root.$$phase;
+  const wrapped: any = function() {
+    const args = arguments;
+    const phase = scope.$root.$$phase;
     if (phase === '$apply' || phase === '$digest') {
       return fn.apply(null, args);
     } else {
@@ -81,8 +81,8 @@ function applied(fn, scope) {
  */
 function applyFunctions(obj, scope, propsConfig?) {
   return Object.keys(obj || {}).reduce(function(prev, key) {
-    var value = obj[key];
-    var config = (propsConfig || {})[key] || {};
+    const value = obj[key];
+    const config = (propsConfig || {})[key] || {};
     /**
      * wrap functions in a function that ensures they are scope.$applied
      * ensures that when function is called from a React component
@@ -103,14 +103,14 @@ function applyFunctions(obj, scope, propsConfig?) {
  * If watchDepth attribute is NOT reference or collection, watchDepth defaults to deep watching by value
  */
 function watchProps(watchDepth, scope, watchExpressions, listener) {
-  var supportsWatchCollection = angular.isFunction(scope.$watchCollection);
-  var supportsWatchGroup = angular.isFunction(scope.$watchGroup);
+  const supportsWatchCollection = angular.isFunction(scope.$watchCollection);
+  const supportsWatchGroup = angular.isFunction(scope.$watchGroup);
 
-  var watchGroupExpressions = [];
+  const watchGroupExpressions = [];
 
   watchExpressions.forEach(function(expr) {
-    var actualExpr = getPropExpression(expr);
-    var exprWatchDepth = getPropWatchDepth(watchDepth, expr);
+    const actualExpr = getPropExpression(expr);
+    const exprWatchDepth = getPropWatchDepth(watchDepth, expr);
 
     if (exprWatchDepth === 'collection' && supportsWatchCollection) {
       scope.$watchCollection(actualExpr, listener);
@@ -156,7 +156,7 @@ function getPropExpression(prop) {
 
 // find the normalized attribute knowing that React props accept any type of capitalization
 function findAttribute(attrs, propName) {
-  var index = Object.keys(attrs).filter(function(attr) {
+  const index = Object.keys(attrs).filter(function(attr) {
     return attr.toLowerCase() === propName.toLowerCase();
   })[0];
   return attrs[index];
@@ -164,7 +164,7 @@ function findAttribute(attrs, propName) {
 
 // get watch depth of prop (string or array)
 function getPropWatchDepth(defaultWatch, prop) {
-  var customWatchDepth = Array.isArray(prop) && angular.isObject(prop[1]) && prop[1].watchDepth;
+  const customWatchDepth = Array.isArray(prop) && angular.isObject(prop[1]) && prop[1].watchDepth;
   return customWatchDepth || defaultWatch;
 }
 
@@ -186,16 +186,16 @@ function getPropWatchDepth(defaultWatch, prop) {
 //         }
 //     }));
 //
-var reactComponent = function($injector) {
+const reactComponent = function($injector) {
   return {
     restrict: 'E',
     replace: true,
     link: function(scope, elem, attrs) {
-      var reactComponent = getReactComponent(attrs.name, $injector);
+      const reactComponent = getReactComponent(attrs.name, $injector);
 
-      var renderMyComponent = function() {
-        var scopeProps = scope.$eval(attrs.props);
-        var props = applyFunctions(scopeProps, scope);
+      const renderMyComponent = function() {
+        const scopeProps = scope.$eval(attrs.props);
+        const props = applyFunctions(scopeProps, scope);
 
         renderComponent(reactComponent, props, scope, elem);
       };
@@ -243,24 +243,24 @@ var reactComponent = function($injector) {
 //
 //     <hello name="name"/>
 //
-var reactDirective = function($injector) {
+const reactDirective = function($injector) {
   return function(reactComponentName, props, conf, injectableProps) {
-    var directive = {
+    const directive = {
       restrict: 'E',
       replace: true,
       link: function(scope, elem, attrs) {
-        var reactComponent = getReactComponent(reactComponentName, $injector);
+        const reactComponent = getReactComponent(reactComponentName, $injector);
 
         // if props is not defined, fall back to use the React component's propTypes if present
         props = props || Object.keys(reactComponent.propTypes || {});
 
         // for each of the properties, get their scope value and set it to scope.props
-        var renderMyComponent = function() {
-          var scopeProps = {},
-            config = {};
+        const renderMyComponent = function() {
+          var scopeProps = {};
+          const config = {};
 
           props.forEach(function(prop) {
-            var propName = getPropName(prop);
+            const propName = getPropName(prop);
             scopeProps[propName] = scope.$eval(findAttribute(attrs, propName));
             config[propName] = getPropConfig(prop);
           });
@@ -272,7 +272,7 @@ var reactDirective = function($injector) {
 
         // watch each property name and trigger an update whenever something changes,
         // to update scope.props with new values
-        var propExpressions = props.map(function(prop) {
+        const propExpressions = props.map(function(prop) {
           return Array.isArray(prop) ? [attrs[getPropName(prop)], getPropConfig(prop)] : attrs[prop];
         });
 

+ 1 - 1
public/app/core/services/search_srv.ts

@@ -31,7 +31,7 @@ export class SearchSrv {
   }
 
   private queryForRecentDashboards() {
-    var dashIds = _.take(impressionSrv.getDashboardOpened(), 5);
+    const dashIds = _.take(impressionSrv.getDashboardOpened(), 5);
     if (dashIds.length === 0) {
       return Promise.resolve([]);
     }

+ 9 - 9
public/app/core/time_series2.ts

@@ -8,7 +8,7 @@ function matchSeriesOverride(aliasOrRegex, seriesAlias) {
   }
 
   if (aliasOrRegex[0] === '/') {
-    var regex = kbn.stringToJsRegex(aliasOrRegex);
+    const regex = kbn.stringToJsRegex(aliasOrRegex);
     return seriesAlias.match(regex) != null;
   }
 
@@ -43,9 +43,9 @@ export function updateLegendValues(data: TimeSeries[], panel, height) {
       // legend and tooltip gets one more decimal precision
       // than graph legend ticks
       const { datamin, datamax } = getDataMinMax(data);
-      let { tickDecimals, scaledDecimals } = getFlotTickDecimals(datamin, datamax, axis, height);
-      tickDecimals = (tickDecimals || -1) + 1;
-      series.updateLegendValues(formater, tickDecimals, scaledDecimals + 2);
+      const { tickDecimals, scaledDecimals } = getFlotTickDecimals(datamin, datamax, axis, height);
+      const tickDecimalsPlusOne = (tickDecimals || -1) + 1;
+      series.updateLegendValues(formater, tickDecimalsPlusOne, scaledDecimals + 2);
     }
   }
 }
@@ -125,7 +125,7 @@ export default class TimeSeries {
     delete this.bars.show;
 
     for (var i = 0; i < overrides.length; i++) {
-      var override = overrides[i];
+      const override = overrides[i];
       if (!matchSeriesOverride(override.alias, this.alias)) {
         continue;
       }
@@ -193,7 +193,7 @@ export default class TimeSeries {
   }
 
   getFlotPairs(fillStyle) {
-    var result = [];
+    const result = [];
 
     this.stats.total = 0;
     this.stats.max = -Number.MAX_VALUE;
@@ -209,8 +209,8 @@ export default class TimeSeries {
     this.allIsNull = true;
     this.allIsZero = true;
 
-    var ignoreNulls = fillStyle === 'connected';
-    var nullAsZero = fillStyle === 'null as zero';
+    const ignoreNulls = fillStyle === 'connected';
+    const nullAsZero = fillStyle === 'null as zero';
     var currentTime;
     var currentValue;
     var nonNulls = 0;
@@ -330,7 +330,7 @@ export default class TimeSeries {
   isMsResolutionNeeded() {
     for (var i = 0; i < this.datapoints.length; i++) {
       if (this.datapoints[i][1] !== null) {
-        var timestamp = this.datapoints[i][1].toString();
+        const timestamp = this.datapoints[i][1].toString();
         if (timestamp.length === 13 && timestamp % 1000 !== 0) {
           return true;
         }

+ 6 - 6
public/app/core/utils/datemath.ts

@@ -1,7 +1,7 @@
 import _ from 'lodash';
 import moment from 'moment';
 
-var units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
+const units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
 
 export function parse(text, roundUp?, timezone?) {
   if (!text) {
@@ -47,7 +47,7 @@ export function parse(text, roundUp?, timezone?) {
 }
 
 export function isValid(text) {
-  var date = parse(text);
+  const date = parse(text);
   if (!date) {
     return false;
   }
@@ -60,12 +60,12 @@ export function isValid(text) {
 }
 
 export function parseDateMath(mathString, time, roundUp?) {
-  var dateTime = time;
+  const dateTime = time;
   var i = 0;
-  var len = mathString.length;
+  const len = mathString.length;
 
   while (i < len) {
-    var c = mathString.charAt(i++);
+    const c = mathString.charAt(i++);
     var type;
     var num;
     var unit;
@@ -85,7 +85,7 @@ export function parseDateMath(mathString, time, roundUp?) {
     } else if (mathString.length === 2) {
       num = mathString.charAt(i);
     } else {
-      var numFrom = i;
+      const numFrom = i;
       while (!isNaN(mathString.charAt(i))) {
         i++;
         if (i > 10) {

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

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

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

@@ -1,5 +1,5 @@
 export function assignModelProperties(target, source, defaults, removeDefaults?) {
-  for (var key in defaults) {
+  for (const key in defaults) {
     if (!defaults.hasOwnProperty(key)) {
       continue;
     }

+ 4 - 4
public/app/core/utils/outline.ts

@@ -2,10 +2,10 @@
 function outlineFixer() {
   const d: any = document;
 
-  var style_element = d.createElement('STYLE');
-  var dom_events = 'addEventListener' in d;
+  const style_element = d.createElement('STYLE');
+  const dom_events = 'addEventListener' in d;
 
-  var add_event_listener = function(type, callback) {
+  const add_event_listener = function(type, callback) {
     // Basic cross-browser event handling
     if (dom_events) {
       d.addEventListener(type, callback);
@@ -14,7 +14,7 @@ function outlineFixer() {
     }
   };
 
-  var set_css = function(css_text) {
+  const set_css = function(css_text) {
     // Handle setting of <style> element contents in IE8
     !!style_element.styleSheet ? (style_element.styleSheet.cssText = css_text) : (style_element.innerHTML = css_text);
   };

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

@@ -6,7 +6,7 @@ export default function sortByKeys(input) {
   }
 
   if (_.isPlainObject(input)) {
-    var sortedObject = {};
+    const sortedObject = {};
     for (const key of _.keys(input).sort()) {
       sortedObject[key] = sortByKeys(input[key]);
     }

+ 12 - 12
public/app/core/utils/ticks.ts

@@ -11,9 +11,9 @@ export function tickStep(start: number, stop: number, count: number): number {
     e5 = Math.sqrt(10),
     e2 = Math.sqrt(2);
 
-  let step0 = Math.abs(stop - start) / Math.max(0, count),
-    step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
-    error = step0 / step1;
+  const step0 = Math.abs(stop - start) / Math.max(0, count);
+  let step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10));
+  const error = step0 / step1;
 
   if (error >= e10) {
     step1 *= 10;
@@ -39,13 +39,13 @@ export function getScaledDecimals(decimals, tick_size) {
  * @param tickDecimals  Tick decimal precision
  */
 export function getFlotTickSize(min: number, max: number, noTicks: number, tickDecimals: number) {
-  var delta = (max - min) / noTicks,
-    dec = -Math.floor(Math.log(delta) / Math.LN10),
-    maxDec = tickDecimals;
+  const delta = (max - min) / noTicks;
+  let dec = -Math.floor(Math.log(delta) / Math.LN10);
+  const maxDec = tickDecimals;
 
-  var magn = Math.pow(10, -dec),
-    norm = delta / magn, // norm is between 1.0 and 10.0
-    size;
+  const magn = Math.pow(10, -dec);
+  const norm = delta / magn; // norm is between 1.0 and 10.0
+  let size;
 
   if (norm < 1.5) {
     size = 1;
@@ -81,8 +81,8 @@ export function getFlotRange(panelMin, panelMax, datamin, datamax) {
   if (delta === 0.0) {
     // Grafana fix: wide Y min and max using increased wideFactor
     // when all series values are the same
-    var wideFactor = 0.25;
-    var widen = Math.abs(max === 0 ? 1 : max * wideFactor);
+    const wideFactor = 0.25;
+    const widen = Math.abs(max === 0 ? 1 : max * wideFactor);
 
     if (panelMin === null) {
       min -= widen;
@@ -94,7 +94,7 @@ export function getFlotRange(panelMin, panelMax, datamin, datamax) {
     }
   } else {
     // consider autoscaling
-    var margin = autoscaleMargin;
+    const margin = autoscaleMargin;
     if (margin != null) {
       if (panelMin == null) {
         min -= delta * margin;

+ 9 - 9
public/app/features/alerting/alert_def.ts

@@ -1,7 +1,7 @@
 import _ from 'lodash';
 import { QueryPartDef, QueryPart } from 'app/core/components/query_part/query_part';
 
-var alertQueryDef = new QueryPartDef({
+const alertQueryDef = new QueryPartDef({
   type: 'query',
   params: [
     { name: 'queryRefId', type: 'string', dynamicLookup: true },
@@ -15,9 +15,9 @@ var alertQueryDef = new QueryPartDef({
   defaultParams: ['#A', '15m', 'now', 'avg'],
 });
 
-var conditionTypes = [{ text: 'Query', value: 'query' }];
+const conditionTypes = [{ text: 'Query', value: 'query' }];
 
-var alertStateSortScore = {
+const alertStateSortScore = {
   alerting: 1,
   no_data: 2,
   pending: 3,
@@ -25,7 +25,7 @@ var alertStateSortScore = {
   paused: 5,
 };
 
-var evalFunctions = [
+const evalFunctions = [
   { text: 'IS ABOVE', value: 'gt' },
   { text: 'IS BELOW', value: 'lt' },
   { text: 'IS OUTSIDE RANGE', value: 'outside_range' },
@@ -33,9 +33,9 @@ var evalFunctions = [
   { text: 'HAS NO VALUE', value: 'no_value' },
 ];
 
-var evalOperators = [{ text: 'OR', value: 'or' }, { text: 'AND', value: 'and' }];
+const evalOperators = [{ text: 'OR', value: 'or' }, { text: 'AND', value: 'and' }];
 
-var reducerTypes = [
+const reducerTypes = [
   { text: 'avg()', value: 'avg' },
   { text: 'min()', value: 'min' },
   { text: 'max()', value: 'max' },
@@ -48,17 +48,17 @@ var reducerTypes = [
   { text: 'count_non_null()', value: 'count_non_null' },
 ];
 
-var noDataModes = [
+const noDataModes = [
   { text: 'Alerting', value: 'alerting' },
   { text: 'No Data', value: 'no_data' },
   { text: 'Keep Last State', value: 'keep_state' },
   { text: 'Ok', value: 'ok' },
 ];
 
-var executionErrorModes = [{ text: 'Alerting', value: 'alerting' }, { text: 'Keep Last State', value: 'keep_state' }];
+const executionErrorModes = [{ text: 'Alerting', value: 'alerting' }, { text: 'Keep Last State', value: 'keep_state' }];
 
 function createReducerPart(model) {
-  var def = new QueryPartDef({ type: model.type, defaultParams: [] });
+  const def = new QueryPartDef({ type: model.type, defaultParams: [] });
   return new QueryPart(model, def);
 }
 

+ 15 - 15
public/app/features/alerting/alert_tab_ctrl.ts

@@ -50,7 +50,7 @@ export class AlertTabCtrl {
     this.addNotificationSegment = this.uiSegmentSrv.newPlusButton();
 
     // subscribe to graph threshold handle changes
-    var thresholdChangedEventHandler = this.graphThresholdChanged.bind(this);
+    const thresholdChangedEventHandler = this.graphThresholdChanged.bind(this);
     this.panelCtrl.events.on('threshold-changed', thresholdChangedEventHandler);
 
     // set panel alert edit mode
@@ -129,7 +129,7 @@ export class AlertTabCtrl {
   }
 
   notificationAdded() {
-    var model = _.find(this.notifications, {
+    const model = _.find(this.notifications, {
       name: this.addNotificationSegment.value,
     });
     if (!model) {
@@ -154,7 +154,7 @@ export class AlertTabCtrl {
   }
 
   initModel() {
-    var alert = (this.alert = this.panel.alert);
+    const alert = (this.alert = this.panel.alert);
     if (!alert) {
       return;
     }
@@ -170,7 +170,7 @@ export class AlertTabCtrl {
     alert.handler = alert.handler || 1;
     alert.notifications = alert.notifications || [];
 
-    var defaultName = this.panel.title + ' alert';
+    const defaultName = this.panel.title + ' alert';
     alert.name = alert.name || defaultName;
 
     this.conditionModels = _.reduce(
@@ -185,7 +185,7 @@ export class AlertTabCtrl {
     ThresholdMapper.alertToGraphThresholds(this.panel);
 
     for (const addedNotification of alert.notifications) {
-      var model = _.find(this.notifications, { id: addedNotification.id });
+      const model = _.find(this.notifications, { id: addedNotification.id });
       if (model && model.isDefault === false) {
         model.iconClass = this.getNotificationIcon(model.type);
         this.alertNotifications.push(model);
@@ -205,7 +205,7 @@ export class AlertTabCtrl {
   }
 
   graphThresholdChanged(evt) {
-    for (var condition of this.alert.conditions) {
+    for (const condition of this.alert.conditions) {
       if (condition.type === 'query') {
         condition.evaluator.params[evt.handleIndex] = evt.threshold.value;
         this.evaluatorParamsChanged();
@@ -232,12 +232,12 @@ export class AlertTabCtrl {
     let firstTarget;
     let foundTarget = null;
 
-    for (var condition of this.alert.conditions) {
+    for (const condition of this.alert.conditions) {
       if (condition.type !== 'query') {
         continue;
       }
 
-      for (var target of this.panel.targets) {
+      for (const target of this.panel.targets) {
         if (!firstTarget) {
           firstTarget = target;
         }
@@ -256,7 +256,7 @@ export class AlertTabCtrl {
         }
       }
 
-      var datasourceName = foundTarget.datasource || this.panel.datasource;
+      const datasourceName = foundTarget.datasource || this.panel.datasource;
       this.datasourceSrv.get(datasourceName).then(ds => {
         if (!ds.meta.alerting) {
           this.error = 'The datasource does not support alerting queries';
@@ -270,7 +270,7 @@ export class AlertTabCtrl {
   }
 
   buildConditionModel(source) {
-    var cm: any = { source: source, type: source.type };
+    const cm: any = { source: source, type: source.type };
 
     cm.queryPart = new QueryPart(source.query, alertDef.alertQueryDef);
     cm.reducerPart = alertDef.createReducerPart(source.reducer);
@@ -292,7 +292,7 @@ export class AlertTabCtrl {
         this.validateModel();
       }
       case 'get-param-options': {
-        var result = this.panel.targets.map(target => {
+        const result = this.panel.targets.map(target => {
           return this.uiSegmentSrv.newSegment({ value: target.refId });
         });
 
@@ -309,8 +309,8 @@ export class AlertTabCtrl {
         break;
       }
       case 'get-part-actions': {
-        var result = [];
-        for (var type of alertDef.reducerTypes) {
+        const result = [];
+        for (const type of alertDef.reducerTypes) {
           if (type.value !== conditionModel.source.reducer.type) {
             result.push(type);
           }
@@ -321,7 +321,7 @@ export class AlertTabCtrl {
   }
 
   addCondition(type) {
-    var condition = this.buildDefaultCondition();
+    const condition = this.buildDefaultCondition();
     // add to persited model
     this.alert.conditions.push(condition);
     // add to view model
@@ -406,7 +406,7 @@ export class AlertTabCtrl {
     this.testing = true;
     this.testResult = false;
 
-    var payload = {
+    const payload = {
       dashboard: this.dashboardSrv.getCurrent().getSaveModelClone(),
       panelId: this.panelCtrl.panel.id,
     };

+ 4 - 4
public/app/features/alerting/threshold_mapper.ts

@@ -6,8 +6,8 @@ export class ThresholdMapper {
         continue;
       }
 
-      var evaluator = condition.evaluator;
-      var thresholds = (panel.thresholds = []);
+      const evaluator = condition.evaluator;
+      const thresholds = (panel.thresholds = []);
 
       switch (evaluator.type) {
         case 'gt': {
@@ -51,13 +51,13 @@ export class ThresholdMapper {
       break;
     }
 
-    for (var t of panel.thresholds) {
+    for (const t of panel.thresholds) {
       t.fill = true;
       t.line = true;
       t.colorMode = 'critical';
     }
 
-    var updated = true;
+    const updated = true;
     return updated;
   }
 }

+ 5 - 5
public/app/features/annotations/annotation_tooltip.ts

@@ -21,16 +21,16 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
       onEdit: '&',
     },
     link: function(scope, element) {
-      var event = scope.event;
+      const event = scope.event;
       var title = event.title;
       var text = event.text;
-      var dashboard = dashboardSrv.getCurrent();
+      const dashboard = dashboardSrv.getCurrent();
 
       var tooltip = '<div class="graph-annotation">';
       var titleStateClass = '';
 
       if (event.alertId) {
-        var stateModel = alertDef.getStateDisplayModel(event.newState);
+        const stateModel = alertDef.getStateDisplayModel(event.newState);
         titleStateClass = stateModel.stateClass;
         title = `<i class="icon-gf ${stateModel.iconClass}"></i> ${stateModel.text}`;
         text = alertDef.getAlertAnnotationInfo(event);
@@ -70,7 +70,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
         tooltip += '<div>' + sanitizeString(text.replace(/\n/g, '<br>')) + '</div>';
       }
 
-      var tags = event.tags;
+      const tags = event.tags;
 
       if (tags && tags.length) {
         scope.tags = tags;
@@ -81,7 +81,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
       tooltip += '</div>';
       tooltip += '</div>';
 
-      var $tooltip = $(tooltip);
+      const $tooltip = $(tooltip);
       $tooltip.appendTo(element);
 
       $compile(element.contents())(scope);

+ 5 - 5
public/app/features/annotations/annotations_srv.ts

@@ -40,7 +40,7 @@ export class AnnotationsSrv {
         annotations = makeRegions(annotations, options);
 
         // look for alert state for this panel
-        var alertState = _.find(results[1], { panelId: options.panel.id });
+        const alertState = _.find(results[1], { panelId: options.panel.id });
 
         return {
           annotations: annotations,
@@ -82,14 +82,14 @@ export class AnnotationsSrv {
   }
 
   getGlobalAnnotations(options) {
-    var dashboard = options.dashboard;
+    const dashboard = options.dashboard;
 
     if (this.globalAnnotationsPromise) {
       return this.globalAnnotationsPromise;
     }
 
-    var range = this.timeSrv.timeRange();
-    var promises = [];
+    const range = this.timeSrv.timeRange();
+    const promises = [];
 
     for (const annotation of dashboard.annotations.list) {
       if (!annotation.enable) {
@@ -155,7 +155,7 @@ export class AnnotationsSrv {
       delete annotation.snapshotData;
     }
 
-    for (var item of results) {
+    for (const item of results) {
       item.source = annotation;
     }
     return results;

+ 1 - 1
public/app/features/annotations/editor_ctrl.ts

@@ -81,7 +81,7 @@ export class AnnotationsEditorCtrl {
   }
 
   removeAnnotation(annotation) {
-    var index = _.indexOf(this.annotations, annotation);
+    const index = _.indexOf(this.annotations, annotation);
     this.annotations.splice(index, 1);
   }
 

+ 2 - 2
public/app/features/annotations/event_manager.ts

@@ -55,7 +55,7 @@ export class EventManager {
       return;
     }
 
-    var types = {
+    const types = {
       $__alerting: {
         color: ALERTING_COLOR,
         position: 'BOTTOM',
@@ -103,7 +103,7 @@ export class EventManager {
     } else {
       // annotations from query
       for (var i = 0; i < annotations.length; i++) {
-        var item = annotations[i];
+        const item = annotations[i];
 
         // add properties used by jquery flot events
         item.min = item.time;

+ 8 - 8
public/app/features/dashboard/dashboard_migration.ts

@@ -19,8 +19,8 @@ export class DashboardMigrator {
 
   updateSchema(old) {
     var i, j, k, n;
-    var oldVersion = this.dashboard.schemaVersion;
-    var panelUpgrades = [];
+    const oldVersion = this.dashboard.schemaVersion;
+    const panelUpgrades = [];
     this.dashboard.schemaVersion = 16;
 
     if (oldVersion === this.dashboard.schemaVersion) {
@@ -108,7 +108,7 @@ export class DashboardMigrator {
 
     if (oldVersion < 6) {
       // move pulldowns to new schema
-      var annotations = _.find(old.pulldowns, { type: 'annotations' });
+      const annotations = _.find(old.pulldowns, { type: 'annotations' });
 
       if (annotations) {
         this.dashboard.annotations = {
@@ -118,7 +118,7 @@ export class DashboardMigrator {
 
       // update template variables
       for (i = 0; i < this.dashboard.templating.list.length; i++) {
-        var variable = this.dashboard.templating.list[i];
+        const variable = this.dashboard.templating.list[i];
         if (variable.datasource === void 0) {
           variable.datasource = null;
         }
@@ -162,7 +162,7 @@ export class DashboardMigrator {
               delete target.fill;
             } else {
               target.select = _.map(target.fields, function(field) {
-                var parts = [];
+                const parts = [];
                 parts.push({ type: 'field', params: [field.name] });
                 parts.push({ type: field.func, params: [] });
                 if (field.mathExpr) {
@@ -204,7 +204,7 @@ export class DashboardMigrator {
         }
 
         if (panel.thresholds) {
-          var k = panel.thresholds.split(',');
+          const k = panel.thresholds.split(',');
 
           if (k.length >= 3) {
             k.shift();
@@ -224,7 +224,7 @@ export class DashboardMigrator {
 
         _.each(panel.styles, function(style) {
           if (style.thresholds && style.thresholds.length >= 3) {
-            var k = style.thresholds;
+            const k = style.thresholds;
             k.shift();
             style.thresholds = k;
           }
@@ -309,7 +309,7 @@ export class DashboardMigrator {
         }
 
         panel.thresholds = [];
-        var t1: any = {},
+        const t1: any = {},
           t2: any = {};
 
         if (panel.grid.threshold1 !== null) {

+ 7 - 7
public/app/features/dashboard/dashboard_model.ts

@@ -145,7 +145,7 @@ export class DashboardModel {
 
     // make clone
     var copy: any = {};
-    for (var property in this) {
+    for (const property in this) {
       if (DashboardModel.nonPersistedProperties[property] || !this.hasOwnProperty(property)) {
         continue;
       }
@@ -542,7 +542,7 @@ export class DashboardModel {
   }
 
   removePanel(panel: PanelModel) {
-    var index = _.indexOf(this.panels, panel);
+    const index = _.indexOf(this.panels, panel);
     this.panels.splice(index, 1);
     this.events.emit('panel-removed', panel);
   }
@@ -559,7 +559,7 @@ export class DashboardModel {
 
   expandRows() {
     for (let i = 0; i < this.panels.length; i++) {
-      var panel = this.panels[i];
+      const panel = this.panels[i];
 
       if (panel.type !== 'row') {
         continue;
@@ -573,7 +573,7 @@ export class DashboardModel {
 
   collapseRows() {
     for (let i = 0; i < this.panels.length; i++) {
-      var panel = this.panels[i];
+      const panel = this.panels[i];
 
       if (panel.type !== 'row') {
         continue;
@@ -595,12 +595,12 @@ export class DashboardModel {
         return true;
       }
 
-      var visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
+      const visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
       if (visibleVars.length > 0) {
         return true;
       }
 
-      var visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
+      const visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
       if (visibleAnnotations.length > 0) {
         return true;
       }
@@ -773,7 +773,7 @@ export class DashboardModel {
   }
 
   getNextQueryLetter(panel) {
-    var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+    const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 
     return _.find(letters, function(refId) {
       return _.every(panel.targets, function(other) {

+ 2 - 2
public/app/features/dashboard/panel_model.ts

@@ -41,7 +41,7 @@ export class PanelModel {
     this.events = new Emitter();
 
     // copy properties from persisted model
-    for (var property in model) {
+    for (const property in model) {
       this[property] = model[property];
     }
 
@@ -52,7 +52,7 @@ export class PanelModel {
 
   getSaveModel() {
     const model: any = {};
-    for (var property in this) {
+    for (const property in this) {
       if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
         continue;
       }

+ 11 - 11
public/app/features/panel/metrics_panel_ctrl.ts

@@ -164,7 +164,7 @@ class MetricsPanelCtrl extends PanelCtrl {
       intervalOverride = this.datasource.interval;
     }
 
-    var res = kbn.calculateInterval(this.range, this.resolution, intervalOverride);
+    const res = kbn.calculateInterval(this.range, this.resolution, intervalOverride);
     this.interval = res.interval;
     this.intervalMs = res.intervalMs;
   }
@@ -174,15 +174,15 @@ class MetricsPanelCtrl extends PanelCtrl {
 
     // check panel time overrrides
     if (this.panel.timeFrom) {
-      var timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
-      var timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
+      const timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
+      const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
       if (timeFromInfo.invalid) {
         this.timeInfo = 'invalid time override';
         return;
       }
 
       if (_.isString(this.range.raw.from)) {
-        var timeFromDate = dateMath.parse(timeFromInfo.from);
+        const timeFromDate = dateMath.parse(timeFromInfo.from);
         this.timeInfo = timeFromInfo.display;
         this.range.from = timeFromDate;
         this.range.to = dateMath.parse(timeFromInfo.to);
@@ -192,14 +192,14 @@ class MetricsPanelCtrl extends PanelCtrl {
     }
 
     if (this.panel.timeShift) {
-      var timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
-      var timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
+      const timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
+      const timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
       if (timeShiftInfo.invalid) {
         this.timeInfo = 'invalid timeshift';
         return;
       }
 
-      var timeShift = '-' + timeShiftInterpolated;
+      const timeShift = '-' + timeShiftInterpolated;
       this.timeInfo += ' timeshift ' + timeShift;
       this.range.from = dateMath.parseDateMath(timeShift, this.range.from, false);
       this.range.to = dateMath.parseDateMath(timeShift, this.range.to, true);
@@ -220,12 +220,12 @@ class MetricsPanelCtrl extends PanelCtrl {
 
     // make shallow copy of scoped vars,
     // and add built in variables interval and interval_ms
-    var scopedVars = Object.assign({}, this.panel.scopedVars, {
+    const scopedVars = Object.assign({}, this.panel.scopedVars, {
       __interval: { text: this.interval, value: this.interval },
       __interval_ms: { text: this.intervalMs, value: this.intervalMs },
     });
 
-    var metricsQuery = {
+    const metricsQuery = {
       timezone: this.dashboard.getTimezone(),
       panelId: this.panel.id,
       dashboardId: this.dashboard.id,
@@ -343,14 +343,14 @@ class MetricsPanelCtrl extends PanelCtrl {
   }
 
   removeQuery(target) {
-    var index = _.indexOf(this.panel.targets, target);
+    const index = _.indexOf(this.panel.targets, target);
     this.panel.targets.splice(index, 1);
     this.nextRefId = this.dashboard.getNextQueryLetter(this.panel);
     this.refresh();
   }
 
   moveQuery(target, direction) {
-    var index = _.indexOf(this.panel.targets, target);
+    const index = _.indexOf(this.panel.targets, target);
     _.move(this.panel.targets, index, index + direction);
   }
 }

+ 1 - 1
public/app/features/panel/metrics_tab.ts

@@ -92,7 +92,7 @@ export class MetricsTabCtrl {
     this.helpOpen = !this.helpOpen;
 
     this.backendSrv.get(`/api/plugins/${this.datasourceInstance.meta.id}/markdown/query_help`).then(res => {
-      var md = new Remarkable();
+      const md = new Remarkable();
       this.helpHtml = this.$sce.trustAsHtml(md.render(res));
     });
   }

+ 14 - 14
public/app/features/panel/panel_ctrl.ts

@@ -43,7 +43,7 @@ export class PanelCtrl {
     this.events = this.panel.events;
     this.timing = {};
 
-    var plugin = config.panels[this.panel.type];
+    const plugin = config.panels[this.panel.type];
     if (plugin) {
       this.pluginId = plugin.id;
       this.pluginName = plugin.name;
@@ -105,7 +105,7 @@ export class PanelCtrl {
     this.editModeInitiated = true;
     this.events.emit('init-edit-mode', null);
 
-    var urlTab = (this.$injector.get('$routeParams').tab || '').toLowerCase();
+    const urlTab = (this.$injector.get('$routeParams').tab || '').toLowerCase();
     if (urlTab) {
       this.editorTabs.forEach((tab, i) => {
         if (tab.title.toLowerCase() === urlTab) {
@@ -117,13 +117,13 @@ export class PanelCtrl {
 
   changeTab(newIndex) {
     this.editorTabIndex = newIndex;
-    var route = this.$injector.get('$route');
+    const route = this.$injector.get('$route');
     route.current.params.tab = this.editorTabs[newIndex].title.toLowerCase();
     route.updateParams();
   }
 
   addEditorTab(title, directiveFn, index?) {
-    var editorTab = { title, directiveFn };
+    const editorTab = { title, directiveFn };
 
     if (_.isString(directiveFn)) {
       editorTab.directiveFn = function() {
@@ -225,9 +225,9 @@ export class PanelCtrl {
 
   calculatePanelHeight() {
     if (this.fullscreen) {
-      var docHeight = $(window).height();
-      var editHeight = Math.floor(docHeight * 0.4);
-      var fullscreenHeight = Math.floor(docHeight * 0.8);
+      const docHeight = $(window).height();
+      const editHeight = Math.floor(docHeight * 0.4);
+      const fullscreenHeight = Math.floor(docHeight * 0.8);
       this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
     } else {
       this.containerHeight = this.panel.gridPos.h * GRID_CELL_HEIGHT + (this.panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
@@ -293,7 +293,7 @@ export class PanelCtrl {
   }
 
   sharePanel() {
-    var shareScope = this.$scope.$new();
+    const shareScope = this.$scope.$new();
     shareScope.panel = this.panel;
     shareScope.dashboard = this.dashboard;
 
@@ -323,10 +323,10 @@ export class PanelCtrl {
       markdown = this.error || this.panel.description;
     }
 
-    var linkSrv = this.$injector.get('linkSrv');
-    var sanitize = this.$injector.get('$sanitize');
-    var templateSrv = this.$injector.get('templateSrv');
-    var interpolatedMarkdown = templateSrv.replace(markdown, this.panel.scopedVars);
+    const linkSrv = this.$injector.get('linkSrv');
+    const sanitize = this.$injector.get('$sanitize');
+    const templateSrv = this.$injector.get('templateSrv');
+    const interpolatedMarkdown = templateSrv.replace(markdown, this.panel.scopedVars);
     var html = '<div class="markdown-html">';
 
     html += new Remarkable().render(interpolatedMarkdown);
@@ -334,7 +334,7 @@ export class PanelCtrl {
     if (this.panel.links && this.panel.links.length > 0) {
       html += '<ul>';
       for (const link of this.panel.links) {
-        var info = linkSrv.getPanelLinkAnchorInfo(link, this.panel.scopedVars);
+        const info = linkSrv.getPanelLinkAnchorInfo(link, this.panel.scopedVars);
         html +=
           '<li><a class="panel-menu-link" href="' +
           info.href +
@@ -352,7 +352,7 @@ export class PanelCtrl {
   }
 
   openInspector() {
-    var modalScope = this.$scope.$new();
+    const modalScope = this.$scope.$new();
     modalScope.panel = this.panel;
     modalScope.dashboard = this.dashboard;
     modalScope.panelInfoHtml = this.getInfoContent({ mode: 'inspector' });

+ 10 - 10
public/app/features/panellinks/link_srv.ts

@@ -7,11 +7,11 @@ export class LinkSrv {
   constructor(private templateSrv, private timeSrv) {}
 
   getLinkUrl(link) {
-    var url = this.templateSrv.replace(link.url || '');
-    var params = {};
+    const url = this.templateSrv.replace(link.url || '');
+    const params = {};
 
     if (link.keepTime) {
-      var range = this.timeSrv.timeRangeForUrl();
+      const range = this.timeSrv.timeRangeForUrl();
       params['from'] = range.from;
       params['to'] = range.to;
     }
@@ -24,7 +24,7 @@ export class LinkSrv {
   }
 
   addParamsToUrl(url, params) {
-    var paramsArray = [];
+    const paramsArray = [];
 
     _.each(params, function(value, key) {
       if (value === null) {
@@ -50,7 +50,7 @@ export class LinkSrv {
 
   appendToQueryString(url, stringToAppend) {
     if (!_.isUndefined(stringToAppend) && stringToAppend !== null && stringToAppend !== '') {
-      var pos = url.indexOf('?');
+      const pos = url.indexOf('?');
       if (pos !== -1) {
         if (url.length - pos > 1) {
           url += '&';
@@ -65,14 +65,14 @@ export class LinkSrv {
   }
 
   getAnchorInfo(link) {
-    var info: any = {};
+    const info: any = {};
     info.href = this.getLinkUrl(link);
     info.title = this.templateSrv.replace(link.title || '');
     return info;
   }
 
   getPanelLinkAnchorInfo(link, scopedVars) {
-    var info: any = {};
+    const info: any = {};
     if (link.type === 'absolute') {
       info.target = link.targetBlank ? '_blank' : '_self';
       info.href = this.templateSrv.replace(link.url || '', scopedVars);
@@ -87,14 +87,14 @@ export class LinkSrv {
       info.target = link.targetBlank ? '_blank' : '';
     } else {
       info.title = this.templateSrv.replace(link.title || '', scopedVars);
-      var slug = kbn.slugifyForUrl(link.dashboard || '');
+      const slug = kbn.slugifyForUrl(link.dashboard || '');
       info.href = 'dashboard/db/' + slug + '?';
     }
 
-    var params = {};
+    const params = {};
 
     if (link.keepTime) {
-      var range = this.timeSrv.timeRangeForUrl();
+      const range = this.timeSrv.timeRangeForUrl();
       params['from'] = range.from;
       params['to'] = range.to;
     }

+ 59 - 40
public/app/features/playlist/partials/playlists.html

@@ -1,47 +1,66 @@
 <page-header model="ctrl.navModel"></page-header>
 
 <div class="page-container page-body">
-  <div class="page-action-bar">
-    <div class="page-action-bar__spacer"></div>
-    <a class="btn btn-success pull-right" href="playlists/create">
-      <i class="fa fa-plus"></i>
-      New Playlist
-    </a>
+  <div ng-if="ctrl.playlists.length > 0">
+    <div class="page-action-bar">
+      <div class="page-action-bar__spacer"></div>
+      <a class="btn btn-success pull-right" href="playlists/create">
+        <i class="fa fa-plus"></i>
+        New Playlist
+      </a>
+    </div>
+
+    <table class="filter-table">
+      <thead>
+        <th>
+          <strong>Name</strong>
+        </th>
+        <th>
+          <strong>Start url</strong>
+        </th>
+        <th style="width: 78px"></th>
+        <th style="width: 78px"></th>
+        <th style="width: 25px"></th>
+      </thead>
+      <tr ng-repeat="playlist in ctrl.playlists">
+        <td>
+          <a href="playlists/edit/{{playlist.id}}">{{playlist.name}}</a>
+        </td>
+        <td>
+          <a href="playlists/play/{{playlist.id}}">playlists/play/{{playlist.id}}</a>
+        </td>
+        <td class="text-center">
+          <a href="playlists/play/{{playlist.id}}" class="btn btn-inverse btn-small">
+            <i class="fa fa-play"></i>
+            Play
+          </a>
+        </td>
+        <td class="text-right">
+          <a href="playlists/edit/{{playlist.id}}" class="btn btn-inverse btn-small">
+            <i class="fa fa-edit"></i>
+            Edit
+          </a>
+        </td>
+        <td class="text-right">
+          <a ng-click="ctrl.removePlaylist(playlist)" class="btn btn-danger btn-small">
+            <i class="fa fa-remove"></i>
+          </a>
+        </td>
+      </tr>
+    </table>
   </div>
 
-  <table class="filter-table">
-    <thead>
-      <th><strong>Name</strong></th>
-      <th><strong>Start url</strong></th>
-      <th style="width: 78px"></th>
-      <th style="width: 78px"></th>
-      <th style="width: 25px"></th>
-    </thead>
-    <tr ng-repeat="playlist in ctrl.playlists">
-      <td>
-				<a href="playlists/edit/{{playlist.id}}">{{playlist.name}}</a>
-      </td>
-      <td >
-				<a href="playlists/play/{{playlist.id}}">playlists/play/{{playlist.id}}</a>
-      </td>
-      <td class="text-center">
-        <a href="playlists/play/{{playlist.id}}" class="btn btn-inverse btn-small">
-          <i class="fa fa-play"></i>
-          Play
-        </a>
-      </td>
-      <td  class="text-right">
-        <a href="playlists/edit/{{playlist.id}}" class="btn btn-inverse btn-small">
-          <i class="fa fa-edit"></i>
-          Edit
-        </a>
-      </td>
-      <td  class="text-right">
-        <a ng-click="ctrl.removePlaylist(playlist)" class="btn btn-danger btn-small">
-          <i class="fa fa-remove"></i>
-        </a>
-      </td>
-    </tr>
-  </table>
+  <div ng-if="ctrl.playlists.length === 0">
+    <empty-list-cta model="{
+      title: 'There are no playlists created yet',
+      buttonIcon: 'fa fa-plus',
+      buttonLink: 'playlists/create',
+      buttonTitle: ' Create Playlist',
+      proTip: 'You can run the playlist in Kiosk Mode.',
+      proTipLink: 'http://docs.grafana.org/reference/playlist/',
+      proTipLinkTitle: 'Learn more',
+      proTipTarget: '_blank'
+    }" />
+  </div>
 
 </div>

+ 3 - 3
public/app/features/plugins/datasource_srv.ts

@@ -95,7 +95,7 @@ export class DatasourceSrv {
   }
 
   getMetricSources(options) {
-    var metricSources = [];
+    const metricSources = [];
 
     _.each(config.datasources, function(value, key) {
       if (value.meta && value.meta.metrics) {
@@ -137,7 +137,7 @@ export class DatasourceSrv {
   addDataSourceVariables(list) {
     // look for data source variables
     for (var i = 0; i < this.templateSrv.variables.length; i++) {
-      var variable = this.templateSrv.variables[i];
+      const variable = this.templateSrv.variables[i];
       if (variable.type !== 'datasource') {
         continue;
       }
@@ -147,7 +147,7 @@ export class DatasourceSrv {
         first = config.defaultDatasource;
       }
 
-      var ds = config.datasources[first];
+      const ds = config.datasources[first];
 
       if (ds) {
         const key = `$${variable.name}`;

+ 2 - 2
public/app/features/templating/variable.ts

@@ -22,7 +22,7 @@ export function containsVariable(...args: any[]) {
   }
 
   variableName = kbn.regexEscape(variableName);
-  var findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
-  var match = findVarRegex.exec(str);
+  const findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
+  const match = findVarRegex.exec(str);
   return match !== null;
 }

+ 4 - 1
public/app/partials/login.html

@@ -16,9 +16,12 @@
               placeholder="password">
           </div>
           <div class="login-button-group">
-            <button type="submit" class="btn btn-large p-x-2" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
+            <button type="submit" class="btn btn-large p-x-2" ng-if="!loggingIn" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
               Log In
             </button>
+            <button type="submit" class="btn btn-large p-x-2 btn-inverse btn-loading" ng-if="loggingIn">
+              Logging In<span>.</span><span>.</span><span>.</span>
+            </button>
             <div class="small login-button-forgot-password">
               <a href="user/password/send-reset-email">
                 Forgot your password?

+ 38 - 38
public/app/plugins/datasource/cloudwatch/datasource.ts

@@ -28,7 +28,7 @@ export default class CloudWatchDatasource {
     options = angular.copy(options);
     options.targets = this.expandTemplateVariable(options.targets, options.scopedVars, this.templateSrv);
 
-    var queries = _.filter(options.targets, item => {
+    const queries = _.filter(options.targets, item => {
       return (
         (item.id !== '' || item.hide !== true) &&
         ((!!item.region && !!item.namespace && !!item.metricName && !_.isEmpty(item.statistics)) ||
@@ -66,12 +66,12 @@ export default class CloudWatchDatasource {
 
     // No valid targets, return the empty result to save a round trip.
     if (_.isEmpty(queries)) {
-      var d = this.$q.defer();
+      const d = this.$q.defer();
       d.resolve({ data: [] });
       return d.promise;
     }
 
-    var request = {
+    const request = {
       from: options.range.from.valueOf().toString(),
       to: options.range.to.valueOf().toString(),
       queries: queries,
@@ -81,15 +81,15 @@ export default class CloudWatchDatasource {
   }
 
   getPeriod(target, options, now?) {
-    var start = this.convertToCloudWatchTime(options.range.from, false);
-    var end = this.convertToCloudWatchTime(options.range.to, true);
+    const start = this.convertToCloudWatchTime(options.range.from, false);
+    const end = this.convertToCloudWatchTime(options.range.to, true);
     now = Math.round((now || Date.now()) / 1000);
 
     var period;
-    var range = end - start;
+    const range = end - start;
 
-    var hourSec = 60 * 60;
-    var daySec = hourSec * 24;
+    const hourSec = 60 * 60;
+    const daySec = hourSec * 24;
     var periodUnit = 60;
     if (!target.period) {
       if (now - start <= daySec * 15) {
@@ -128,7 +128,7 @@ export default class CloudWatchDatasource {
 
   performTimeSeriesQuery(request) {
     return this.awsRequest('/api/tsdb/query', request).then(res => {
-      var data = [];
+      const data = [];
 
       if (res.results) {
         _.forEach(res.results, queryRes => {
@@ -152,7 +152,7 @@ export default class CloudWatchDatasource {
   }
 
   doMetricQueryRequest(subtype, parameters) {
-    var range = this.timeSrv.timeRange();
+    const range = this.timeSrv.timeRange();
     return this.awsRequest('/api/tsdb/query', {
       from: range.from.valueOf().toString(),
       to: range.to.valueOf().toString(),
@@ -227,38 +227,38 @@ export default class CloudWatchDatasource {
     var metricName;
     var filterJson;
 
-    var regionQuery = query.match(/^regions\(\)/);
+    const regionQuery = query.match(/^regions\(\)/);
     if (regionQuery) {
       return this.getRegions();
     }
 
-    var namespaceQuery = query.match(/^namespaces\(\)/);
+    const namespaceQuery = query.match(/^namespaces\(\)/);
     if (namespaceQuery) {
       return this.getNamespaces();
     }
 
-    var metricNameQuery = query.match(/^metrics\(([^\)]+?)(,\s?([^,]+?))?\)/);
+    const metricNameQuery = query.match(/^metrics\(([^\)]+?)(,\s?([^,]+?))?\)/);
     if (metricNameQuery) {
       namespace = metricNameQuery[1];
       region = metricNameQuery[3];
       return this.getMetrics(namespace, region);
     }
 
-    var dimensionKeysQuery = query.match(/^dimension_keys\(([^\)]+?)(,\s?([^,]+?))?\)/);
+    const dimensionKeysQuery = query.match(/^dimension_keys\(([^\)]+?)(,\s?([^,]+?))?\)/);
     if (dimensionKeysQuery) {
       namespace = dimensionKeysQuery[1];
       region = dimensionKeysQuery[3];
       return this.getDimensionKeys(namespace, region);
     }
 
-    var dimensionValuesQuery = query.match(
+    const dimensionValuesQuery = query.match(
       /^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?(.+))?\)/
     );
     if (dimensionValuesQuery) {
       region = dimensionValuesQuery[1];
       namespace = dimensionValuesQuery[2];
       metricName = dimensionValuesQuery[3];
-      var dimensionKey = dimensionValuesQuery[4];
+      const dimensionKey = dimensionValuesQuery[4];
       filterJson = {};
       if (dimensionValuesQuery[6]) {
         filterJson = JSON.parse(this.templateSrv.replace(dimensionValuesQuery[6]));
@@ -267,17 +267,17 @@ export default class CloudWatchDatasource {
       return this.getDimensionValues(region, namespace, metricName, dimensionKey, filterJson);
     }
 
-    var ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/);
+    const ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/);
     if (ebsVolumeIdsQuery) {
       region = ebsVolumeIdsQuery[1];
-      var instanceId = ebsVolumeIdsQuery[2];
+      const instanceId = ebsVolumeIdsQuery[2];
       return this.getEbsVolumeIds(region, instanceId);
     }
 
-    var ec2InstanceAttributeQuery = query.match(/^ec2_instance_attribute\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/);
+    const ec2InstanceAttributeQuery = query.match(/^ec2_instance_attribute\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/);
     if (ec2InstanceAttributeQuery) {
       region = ec2InstanceAttributeQuery[1];
-      var targetAttributeName = ec2InstanceAttributeQuery[2];
+      const targetAttributeName = ec2InstanceAttributeQuery[2];
       filterJson = JSON.parse(this.templateSrv.replace(ec2InstanceAttributeQuery[3]));
       return this.getEc2InstanceAttribute(region, targetAttributeName, filterJson);
     }
@@ -286,14 +286,14 @@ export default class CloudWatchDatasource {
   }
 
   annotationQuery(options) {
-    var annotation = options.annotation;
-    var statistics = _.map(annotation.statistics, s => {
+    const annotation = options.annotation;
+    const statistics = _.map(annotation.statistics, s => {
       return this.templateSrv.replace(s);
     });
-    var defaultPeriod = annotation.prefixMatching ? '' : '300';
+    const defaultPeriod = annotation.prefixMatching ? '' : '300';
     var period = annotation.period || defaultPeriod;
     period = parseInt(period, 10);
-    var parameters = {
+    const parameters = {
       prefixMatching: annotation.prefixMatching,
       region: this.templateSrv.replace(this.getActualRegion(annotation.region)),
       namespace: this.templateSrv.replace(annotation.namespace),
@@ -346,10 +346,10 @@ export default class CloudWatchDatasource {
 
   testDatasource() {
     /* use billing metrics for test */
-    var region = this.defaultRegion;
-    var namespace = 'AWS/Billing';
-    var metricName = 'EstimatedCharges';
-    var dimensions = {};
+    const region = this.defaultRegion;
+    const namespace = 'AWS/Billing';
+    const metricName = 'EstimatedCharges';
+    const dimensions = {};
 
     return this.getDimensionValues(region, namespace, metricName, 'ServiceName', dimensions).then(
       () => {
@@ -362,7 +362,7 @@ export default class CloudWatchDatasource {
   }
 
   awsRequest(url, data) {
-    var options = {
+    const options = {
       method: 'POST',
       url: url,
       data: data,
@@ -386,15 +386,15 @@ export default class CloudWatchDatasource {
 
   getExpandedVariables(target, dimensionKey, variable, templateSrv) {
     /* if the all checkbox is marked we should add all values to the targets */
-    var allSelected = _.find(variable.options, { selected: true, text: 'All' });
-    var selectedVariables = _.filter(variable.options, v => {
+    const allSelected = _.find(variable.options, { selected: true, text: 'All' });
+    const selectedVariables = _.filter(variable.options, v => {
       if (allSelected) {
         return v.text !== 'All';
       } else {
         return v.selected;
       }
     });
-    var currentVariables = !_.isArray(variable.current.value)
+    const currentVariables = !_.isArray(variable.current.value)
       ? [variable.current]
       : variable.current.value.map(v => {
           return {
@@ -407,8 +407,8 @@ export default class CloudWatchDatasource {
         return s.value === currentVariables[0].value;
       }) || currentVariables[0].value === '$__all';
     return (useSelectedVariables ? selectedVariables : currentVariables).map(v => {
-      var t = angular.copy(target);
-      var scopedVar = {};
+      const t = angular.copy(target);
+      const scopedVar = {};
       scopedVar[variable.name] = v;
       t.refId = target.refId + '_' + v.value;
       t.dimensions[dimensionKey] = templateSrv.replace(t.dimensions[dimensionKey], scopedVar);
@@ -425,17 +425,17 @@ export default class CloudWatchDatasource {
     // Datasource and template srv logic uber-complected. This should be cleaned up.
     return _.chain(targets)
       .map(target => {
-        var dimensionKey = _.findKey(target.dimensions, v => {
+        const dimensionKey = _.findKey(target.dimensions, v => {
           return templateSrv.variableExists(v) && !_.has(scopedVars, templateSrv.getVariableName(v));
         });
 
         if (dimensionKey) {
-          var multiVariable = _.find(templateSrv.variables, variable => {
+          const multiVariable = _.find(templateSrv.variables, variable => {
             return (
               templatingVariable.containsVariable(target.dimensions[dimensionKey], variable.name) && variable.multi
             );
           });
-          var variable = _.find(templateSrv.variables, variable => {
+          const variable = _.find(templateSrv.variables, variable => {
             return templatingVariable.containsVariable(target.dimensions[dimensionKey], variable.name);
           });
           return this.getExpandedVariables(target, dimensionKey, multiVariable || variable, templateSrv);
@@ -455,7 +455,7 @@ export default class CloudWatchDatasource {
   }
 
   convertDimensionFormat(dimensions, scopedVars) {
-    var convertedDimensions = {};
+    const convertedDimensions = {};
     _.each(dimensions, (value, key) => {
       convertedDimensions[this.templateSrv.replace(key, scopedVars)] = this.templateSrv.replace(value, scopedVars);
     });

+ 10 - 10
public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts

@@ -20,7 +20,7 @@ export class CloudWatchQueryParameterCtrl {
   /** @ngInject */
   constructor($scope, templateSrv, uiSegmentSrv, datasourceSrv, $q) {
     $scope.init = function() {
-      var target = $scope.target;
+      const target = $scope.target;
       target.namespace = target.namespace || '';
       target.metricName = target.metricName || '';
       target.statistics = target.statistics || ['Average'];
@@ -106,8 +106,8 @@ export class CloudWatchQueryParameterCtrl {
     };
 
     $scope.ensurePlusButton = function(segments) {
-      var count = segments.length;
-      var lastSegment = segments[Math.max(count - 1, 0)];
+      const count = segments.length;
+      const lastSegment = segments[Math.max(count - 1, 0)];
 
       if (!lastSegment || lastSegment.type !== 'plus-button') {
         segments.push(uiSegmentSrv.newPlusButton());
@@ -119,13 +119,13 @@ export class CloudWatchQueryParameterCtrl {
         return $q.when([]);
       }
 
-      var target = $scope.target;
+      const target = $scope.target;
       var query = $q.when([]);
 
       if (segment.type === 'key' || segment.type === 'plus-button') {
         query = $scope.datasource.getDimensionKeys($scope.target.namespace, $scope.target.region);
       } else if (segment.type === 'value') {
-        var dimensionKey = $scope.dimSegments[$index - 2].value;
+        const dimensionKey = $scope.dimSegments[$index - 2].value;
         query = $scope.datasource.getDimensionValues(
           target.region,
           target.namespace,
@@ -161,12 +161,12 @@ export class CloudWatchQueryParameterCtrl {
     };
 
     $scope.syncDimSegmentsWithModel = function() {
-      var dims = {};
-      var length = $scope.dimSegments.length;
+      const dims = {};
+      const length = $scope.dimSegments.length;
 
       for (var i = 0; i < length - 2; i += 3) {
-        var keySegment = $scope.dimSegments[i];
-        var valueSegment = $scope.dimSegments[i + 2];
+        const keySegment = $scope.dimSegments[i];
+        const valueSegment = $scope.dimSegments[i + 2];
         if (!valueSegment.fake) {
           dims[keySegment.value] = valueSegment.value;
         }
@@ -212,7 +212,7 @@ export class CloudWatchQueryParameterCtrl {
 
     $scope.transformToSegments = function(addTemplateVars) {
       return function(results) {
-        var segments = _.map(results, function(segment) {
+        const segments = _.map(results, function(segment) {
           return uiSegmentSrv.newSegment({
             value: segment.text,
             expandable: segment.expandable,

+ 5 - 5
public/app/plugins/datasource/elasticsearch/bucket_agg.ts

@@ -19,7 +19,7 @@ export function elasticBucketAgg() {
 export class ElasticBucketAggCtrl {
   /** @nginject */
   constructor($scope, uiSegmentSrv, $q, $rootScope) {
-    var bucketAggs = $scope.target.bucketAggs;
+    const bucketAggs = $scope.target.bucketAggs;
 
     $scope.orderByOptions = [];
 
@@ -85,7 +85,7 @@ export class ElasticBucketAggCtrl {
       $scope.bucketAggCount = bucketAggs.length;
 
       var settingsLinkText = '';
-      var settings = $scope.agg.settings || {};
+      const settings = $scope.agg.settings || {};
 
       switch ($scope.agg.type) {
         case 'terms': {
@@ -198,14 +198,14 @@ export class ElasticBucketAggCtrl {
 
     $scope.addBucketAgg = function() {
       // if last is date histogram add it before
-      var lastBucket = bucketAggs[bucketAggs.length - 1];
+      const lastBucket = bucketAggs[bucketAggs.length - 1];
       var addIndex = bucketAggs.length - 1;
 
       if (lastBucket && lastBucket.type === 'date_histogram') {
         addIndex -= 1;
       }
 
-      var id = _.reduce(
+      const id = _.reduce(
         $scope.target.bucketAggs.concat($scope.target.metrics),
         function(max, val) {
           return parseInt(val.id) > max ? parseInt(val.id) : max;
@@ -226,6 +226,6 @@ export class ElasticBucketAggCtrl {
   }
 }
 
-var module = angular.module('grafana.directives');
+const module = angular.module('grafana.directives');
 module.directive('elasticBucketAgg', elasticBucketAgg);
 module.controller('ElasticBucketAggCtrl', ElasticBucketAggCtrl);

+ 1 - 1
public/app/plugins/datasource/elasticsearch/config_ctrl.ts

@@ -23,7 +23,7 @@ export class ElasticConfigCtrl {
   esVersions = [{ name: '2.x', value: 2 }, { name: '5.x', value: 5 }, { name: '5.6+', value: 56 }];
 
   indexPatternTypeChanged() {
-    var def = _.find(this.indexPatternTypes, {
+    const def = _.find(this.indexPatternTypes, {
       value: this.current.jsonData.interval,
     });
     this.current.database = def.example || 'es-index-name';

+ 45 - 45
public/app/plugins/datasource/elasticsearch/datasource.ts

@@ -37,7 +37,7 @@ export class ElasticDatasource {
   }
 
   private request(method, url, data?) {
-    var options: any = {
+    const options: any = {
       url: this.url + '/' + url,
       method: method,
       data: data,
@@ -56,8 +56,8 @@ export class ElasticDatasource {
   }
 
   private get(url) {
-    var range = this.timeSrv.timeRange();
-    var index_list = this.indexPattern.getIndexList(range.from.valueOf(), range.to.valueOf());
+    const range = this.timeSrv.timeRange();
+    const index_list = this.indexPattern.getIndexList(range.from.valueOf(), range.to.valueOf());
     if (_.isArray(index_list) && index_list.length) {
       return this.request('GET', index_list[0] + url).then(function(results) {
         results.data.$$config = results.config;
@@ -90,21 +90,21 @@ export class ElasticDatasource {
   }
 
   annotationQuery(options) {
-    var annotation = options.annotation;
-    var timeField = annotation.timeField || '@timestamp';
-    var queryString = annotation.query || '*';
-    var tagsField = annotation.tagsField || 'tags';
-    var textField = annotation.textField || null;
+    const annotation = options.annotation;
+    const timeField = annotation.timeField || '@timestamp';
+    const queryString = annotation.query || '*';
+    const tagsField = annotation.tagsField || 'tags';
+    const textField = annotation.textField || null;
 
-    var range = {};
+    const range = {};
     range[timeField] = {
       from: options.range.from.valueOf(),
       to: options.range.to.valueOf(),
       format: 'epoch_millis',
     };
 
-    var queryInterpolated = this.templateSrv.replace(queryString, {}, 'lucene');
-    var query = {
+    const queryInterpolated = this.templateSrv.replace(queryString, {}, 'lucene');
+    const query = {
       bool: {
         filter: [
           { range: range },
@@ -117,7 +117,7 @@ export class ElasticDatasource {
       },
     };
 
-    var data = {
+    const data = {
       query: query,
       size: 10000,
     };
@@ -127,7 +127,7 @@ export class ElasticDatasource {
       data['fields'] = [timeField, '_source'];
     }
 
-    var header: any = {
+    const header: any = {
       search_type: 'query_then_fetch',
       ignore_unavailable: true,
     };
@@ -139,18 +139,18 @@ export class ElasticDatasource {
       header.index = this.indexPattern.getIndexList(options.range.from, options.range.to);
     }
 
-    var payload = angular.toJson(header) + '\n' + angular.toJson(data) + '\n';
+    const payload = angular.toJson(header) + '\n' + angular.toJson(data) + '\n';
 
     return this.post('_msearch', payload).then(res => {
-      var list = [];
-      var hits = res.responses[0].hits.hits;
+      const list = [];
+      const hits = res.responses[0].hits.hits;
 
-      var getFieldFromSource = function(source, fieldName) {
+      const getFieldFromSource = function(source, fieldName) {
         if (!fieldName) {
           return;
         }
 
-        var fieldNames = fieldName.split('.');
+        const fieldNames = fieldName.split('.');
         var fieldValue = source;
 
         for (var i = 0; i < fieldNames.length; i++) {
@@ -165,16 +165,16 @@ export class ElasticDatasource {
       };
 
       for (var i = 0; i < hits.length; i++) {
-        var source = hits[i]._source;
+        const source = hits[i]._source;
         var time = getFieldFromSource(source, timeField);
         if (typeof hits[i].fields !== 'undefined') {
-          var fields = hits[i].fields;
+          const fields = hits[i].fields;
           if (_.isString(fields[timeField]) || _.isNumber(fields[timeField])) {
             time = fields[timeField];
           }
         }
 
-        var event = {
+        const event = {
           annotation: annotation,
           time: moment.utc(time).valueOf(),
           text: getFieldFromSource(source, textField),
@@ -204,7 +204,7 @@ export class ElasticDatasource {
     // validate that the index exist and has date field
     return this.getFields({ type: 'date' }).then(
       function(dateFields) {
-        var timeField = _.find(dateFields, { text: this.timeField });
+        const timeField = _.find(dateFields, { text: this.timeField });
         if (!timeField) {
           return {
             status: 'error',
@@ -229,7 +229,7 @@ export class ElasticDatasource {
   }
 
   getQueryHeader(searchType, timeFrom, timeTo) {
-    var query_header: any = {
+    const query_header: any = {
       search_type: searchType,
       ignore_unavailable: true,
       index: this.indexPattern.getIndexList(timeFrom, timeTo),
@@ -243,10 +243,10 @@ export class ElasticDatasource {
   query(options) {
     var payload = '';
     var target;
-    var sentTargets = [];
+    const sentTargets = [];
 
     // add global adhoc filters to timeFilter
-    var adhocFilters = this.templateSrv.getAdhocFilters(this.name);
+    const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
 
     for (var i = 0; i < options.targets.length; i++) {
       target = options.targets[i];
@@ -254,12 +254,12 @@ export class ElasticDatasource {
         continue;
       }
 
-      var queryString = this.templateSrv.replace(target.query || '*', options.scopedVars, 'lucene');
-      var queryObj = this.queryBuilder.build(target, adhocFilters, queryString);
-      var esQuery = angular.toJson(queryObj);
+      const queryString = this.templateSrv.replace(target.query || '*', options.scopedVars, 'lucene');
+      const queryObj = this.queryBuilder.build(target, adhocFilters, queryString);
+      const esQuery = angular.toJson(queryObj);
 
-      var searchType = queryObj.size === 0 && this.esVersion < 5 ? 'count' : 'query_then_fetch';
-      var header = this.getQueryHeader(searchType, options.range.from, options.range.to);
+      const searchType = queryObj.size === 0 && this.esVersion < 5 ? 'count' : 'query_then_fetch';
+      const header = this.getQueryHeader(searchType, options.range.from, options.range.to);
       payload += header + '\n';
 
       payload += esQuery + '\n';
@@ -281,7 +281,7 @@ export class ElasticDatasource {
 
   getFields(query) {
     return this.get('/_mapping').then(function(result) {
-      var typeMap = {
+      const typeMap = {
         float: 'number',
         double: 'number',
         integer: 'number',
@@ -307,12 +307,12 @@ export class ElasticDatasource {
       }
 
       // Store subfield names: [system, process, cpu, total] -> system.process.cpu.total
-      var fieldNameParts = [];
-      var fields = {};
+      const fieldNameParts = [];
+      const fields = {};
 
       function getFieldsRecursively(obj) {
-        for (var key in obj) {
-          var subObj = obj[key];
+        for (const key in obj) {
+          const subObj = obj[key];
 
           // Check mapping field for nested fields
           if (_.isObject(subObj.properties)) {
@@ -326,7 +326,7 @@ export class ElasticDatasource {
           }
 
           if (_.isString(subObj.type)) {
-            var fieldName = fieldNameParts.concat(key).join('.');
+            const fieldName = fieldNameParts.concat(key).join('.');
 
             // Hide meta-fields and check field type
             if (shouldAddField(subObj, key, query)) {
@@ -340,12 +340,12 @@ export class ElasticDatasource {
         fieldNameParts.pop();
       }
 
-      for (var indexName in result) {
-        var index = result[indexName];
+      for (const indexName in result) {
+        const index = result[indexName];
         if (index && index.mappings) {
-          var mappings = index.mappings;
-          for (var typeName in mappings) {
-            var properties = mappings[typeName].properties;
+          const mappings = index.mappings;
+          for (const typeName in mappings) {
+            const properties = mappings[typeName].properties;
             getFieldsRecursively(properties);
           }
         }
@@ -359,9 +359,9 @@ export class ElasticDatasource {
   }
 
   getTerms(queryDef) {
-    var range = this.timeSrv.timeRange();
-    var searchType = this.esVersion >= 5 ? 'query_then_fetch' : 'count';
-    var header = this.getQueryHeader(searchType, range.from, range.to);
+    const range = this.timeSrv.timeRange();
+    const searchType = this.esVersion >= 5 ? 'query_then_fetch' : 'count';
+    const header = this.getQueryHeader(searchType, range.from, range.to);
     var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
 
     esQuery = esQuery.replace(/\$timeFrom/g, range.from.valueOf());
@@ -373,7 +373,7 @@ export class ElasticDatasource {
         return [];
       }
 
-      var buckets = res.responses[0].aggregations['1'].buckets;
+      const buckets = res.responses[0].aggregations['1'].buckets;
       return _.map(buckets, function(bucket) {
         return {
           text: bucket.key_as_string || bucket.key,

+ 30 - 30
public/app/plugins/datasource/elasticsearch/elastic_response.ts

@@ -33,10 +33,10 @@ export class ElasticResponse {
             break;
           }
 
-          var firstBucket = esAgg.buckets[0];
-          var percentiles = firstBucket[metric.id].values;
+          const firstBucket = esAgg.buckets[0];
+          const percentiles = firstBucket[metric.id].values;
 
-          for (var percentileName in percentiles) {
+          for (const percentileName in percentiles) {
             newSeries = {
               datapoints: [],
               metric: 'p' + percentileName,
@@ -46,7 +46,7 @@ export class ElasticResponse {
 
             for (i = 0; i < esAgg.buckets.length; i++) {
               bucket = esAgg.buckets[i];
-              var values = bucket[metric.id].values;
+              const values = bucket[metric.id].values;
               newSeries.datapoints.push([values[percentileName], bucket.key]);
             }
             seriesList.push(newSeries);
@@ -55,7 +55,7 @@ export class ElasticResponse {
           break;
         }
         case 'extended_stats': {
-          for (var statName in metric.meta) {
+          for (const statName in metric.meta) {
             if (!metric.meta[statName]) {
               continue;
             }
@@ -69,7 +69,7 @@ export class ElasticResponse {
 
             for (i = 0; i < esAgg.buckets.length; i++) {
               bucket = esAgg.buckets[i];
-              var stats = bucket[metric.id];
+              const stats = bucket[metric.id];
 
               // add stats that are in nested obj to top level obj
               stats.std_deviation_bounds_upper = stats.std_deviation_bounds.upper;
@@ -141,12 +141,12 @@ export class ElasticResponse {
             break;
           }
           case 'extended_stats': {
-            for (var statName in metric.meta) {
+            for (const statName in metric.meta) {
               if (!metric.meta[statName]) {
                 continue;
               }
 
-              var stats = bucket[metric.id];
+              const stats = bucket[metric.id];
               // add stats that are in nested obj to top level obj
               stats.std_deviation_bounds_upper = stats.std_deviation_bounds.upper;
               stats.std_deviation_bounds_lower = stats.std_deviation_bounds.lower;
@@ -178,7 +178,7 @@ export class ElasticResponse {
   // need to recurise down the nested buckets to build series
   processBuckets(aggs, target, seriesList, table, props, depth) {
     var bucket, aggDef, esAgg, aggId;
-    var maxDepth = target.bucketAggs.length - 1;
+    const maxDepth = target.bucketAggs.length - 1;
 
     for (aggId in aggs) {
       aggDef = _.find(target.bucketAggs, { id: aggId });
@@ -195,7 +195,7 @@ export class ElasticResponse {
           this.processAggregationDocs(esAgg, aggDef, target, table, props);
         }
       } else {
-        for (var nameIndex in esAgg.buckets) {
+        for (const nameIndex in esAgg.buckets) {
           bucket = esAgg.buckets[nameIndex];
           props = _.clone(props);
           if (bucket.key !== void 0) {
@@ -225,10 +225,10 @@ export class ElasticResponse {
     var metricName = this.getMetricName(series.metric);
 
     if (target.alias) {
-      var regex = /\{\{([\s\S]+?)\}\}/g;
+      const regex = /\{\{([\s\S]+?)\}\}/g;
 
       return target.alias.replace(regex, function(match, g1, g2) {
-        var group = g1 || g2;
+        const group = g1 || g2;
 
         if (group.indexOf('term ') === 0) {
           return series.props[group.substring(5)];
@@ -248,7 +248,7 @@ export class ElasticResponse {
     }
 
     if (series.field && queryDef.isPipelineAgg(series.metric)) {
-      var appliedAgg = _.find(target.metrics, { id: series.field });
+      const appliedAgg = _.find(target.metrics, { id: series.field });
       if (appliedAgg) {
         metricName += ' ' + queryDef.describeMetric(appliedAgg);
       } else {
@@ -258,13 +258,13 @@ export class ElasticResponse {
       metricName += ' ' + series.field;
     }
 
-    var propKeys = _.keys(series.props);
+    const propKeys = _.keys(series.props);
     if (propKeys.length === 0) {
       return metricName;
     }
 
     var name = '';
-    for (var propName in series.props) {
+    for (const propName in series.props) {
       name += series.props[propName] + ' ';
     }
 
@@ -276,16 +276,16 @@ export class ElasticResponse {
   }
 
   nameSeries(seriesList, target) {
-    var metricTypeCount = _.uniq(_.map(seriesList, 'metric')).length;
+    const metricTypeCount = _.uniq(_.map(seriesList, 'metric')).length;
 
     for (var i = 0; i < seriesList.length; i++) {
-      var series = seriesList[i];
+      const series = seriesList[i];
       series.target = this.getSeriesName(series, target, metricTypeCount);
     }
   }
 
   processHits(hits, seriesList) {
-    var series = {
+    const series = {
       target: 'docs',
       type: 'docs',
       datapoints: [],
@@ -318,13 +318,13 @@ export class ElasticResponse {
   }
 
   trimDatapoints(aggregations, target) {
-    var histogram = _.find(target.bucketAggs, { type: 'date_histogram' });
+    const histogram = _.find(target.bucketAggs, { type: 'date_histogram' });
 
-    var shouldDropFirstAndLast = histogram && histogram.settings && histogram.settings.trimEdges;
+    const shouldDropFirstAndLast = histogram && histogram.settings && histogram.settings.trimEdges;
     if (shouldDropFirstAndLast) {
-      var trim = histogram.settings.trimEdges;
-      for (var prop in aggregations) {
-        var points = aggregations[prop];
+      const trim = histogram.settings.trimEdges;
+      for (const prop in aggregations) {
+        const points = aggregations[prop];
         if (points.datapoints.length > trim * 2) {
           points.datapoints = points.datapoints.slice(trim, points.datapoints.length - trim);
         }
@@ -333,7 +333,7 @@ export class ElasticResponse {
   }
 
   getErrorFromElasticResponse(response, err) {
-    var result: any = {};
+    const result: any = {};
     result.data = JSON.stringify(err, null, 4);
     if (err.root_cause && err.root_cause.length > 0 && err.root_cause[0].reason) {
       result.message = err.root_cause[0].reason;
@@ -349,10 +349,10 @@ export class ElasticResponse {
   }
 
   getTimeSeries() {
-    var seriesList = [];
+    const seriesList = [];
 
     for (var i = 0; i < this.response.responses.length; i++) {
-      var response = this.response.responses[i];
+      const response = this.response.responses[i];
       if (response.error) {
         throw this.getErrorFromElasticResponse(this.response, response.error);
       }
@@ -362,10 +362,10 @@ export class ElasticResponse {
       }
 
       if (response.aggregations) {
-        var aggregations = response.aggregations;
-        var target = this.targets[i];
-        var tmpSeriesList = [];
-        var table = new TableModel();
+        const aggregations = response.aggregations;
+        const target = this.targets[i];
+        const tmpSeriesList = [];
+        const table = new TableModel();
 
         this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0);
         this.trimDatapoints(tmpSeriesList, target);

+ 4 - 4
public/app/plugins/datasource/elasticsearch/index_pattern.ts

@@ -24,15 +24,15 @@ export class IndexPattern {
       return this.pattern;
     }
 
-    var intervalInfo = intervalMap[this.interval];
-    var start = moment(from)
+    const intervalInfo = intervalMap[this.interval];
+    const start = moment(from)
       .utc()
       .startOf(intervalInfo.startOf);
-    var endEpoch = moment(to)
+    const endEpoch = moment(to)
       .utc()
       .startOf(intervalInfo.startOf)
       .valueOf();
-    var indexList = [];
+    const indexList = [];
 
     while (start.valueOf() <= endEpoch) {
       indexList.push(start.format(this.pattern));

+ 12 - 12
public/app/plugins/datasource/elasticsearch/metric_agg.ts

@@ -19,7 +19,7 @@ export function elasticMetricAgg() {
 
 export class ElasticMetricAggCtrl {
   constructor($scope, uiSegmentSrv, $q, $rootScope) {
-    var metricAggs = $scope.target.metrics;
+    const metricAggs = $scope.target.metrics;
     $scope.metricAggTypes = queryDef.getMetricAggTypes($scope.esVersion);
     $scope.extendedStats = queryDef.extendedStats;
     $scope.pipelineAggOptions = [];
@@ -55,7 +55,7 @@ export class ElasticMetricAggCtrl {
         $scope.agg.pipelineAgg = $scope.agg.pipelineAgg || 'select metric';
         $scope.agg.field = $scope.agg.pipelineAgg;
 
-        var pipelineOptions = queryDef.getPipelineOptions($scope.agg);
+        const pipelineOptions = queryDef.getPipelineOptions($scope.agg);
         if (pipelineOptions.length > 0) {
           _.each(pipelineOptions, function(opt) {
             $scope.agg.settings[opt.text] = $scope.agg.settings[opt.text] || opt.default;
@@ -67,7 +67,7 @@ export class ElasticMetricAggCtrl {
       }
       switch ($scope.agg.type) {
         case 'cardinality': {
-          var precision_threshold = $scope.agg.settings.precision_threshold || '';
+          const precision_threshold = $scope.agg.settings.precision_threshold || '';
           $scope.settingsLinkText = 'Precision threshold: ' + precision_threshold;
           break;
         }
@@ -82,11 +82,11 @@ export class ElasticMetricAggCtrl {
             $scope.agg.meta.std_deviation_bounds_upper = true;
           }
 
-          var stats = _.reduce(
+          const stats = _.reduce(
             $scope.agg.meta,
             function(memo, val, key) {
               if (val) {
-                var def = _.find($scope.extendedStats, { value: key });
+                const def = _.find($scope.extendedStats, { value: key });
                 memo.push(def.text);
               }
               return memo;
@@ -115,7 +115,7 @@ export class ElasticMetricAggCtrl {
       if ($scope.aggDef.supportsInlineScript) {
         // I know this stores the inline script twice
         // but having it like this simplifes the query_builder
-        var inlineScript = $scope.agg.inlineScript;
+        const inlineScript = $scope.agg.inlineScript;
         if (inlineScript) {
           $scope.agg.settings.script = { inline: inlineScript };
         } else {
@@ -138,13 +138,13 @@ export class ElasticMetricAggCtrl {
     };
 
     $scope.updateMovingAvgModelSettings = function() {
-      var modelSettingsKeys = [];
-      var modelSettings = queryDef.getMovingAvgSettings($scope.agg.settings.model, false);
+      const modelSettingsKeys = [];
+      const modelSettings = queryDef.getMovingAvgSettings($scope.agg.settings.model, false);
       for (var i = 0; i < modelSettings.length; i++) {
         modelSettingsKeys.push(modelSettings[i].value);
       }
 
-      for (var key in $scope.agg.settings.settings) {
+      for (const key in $scope.agg.settings.settings) {
         if ($scope.agg.settings.settings[key] === null || modelSettingsKeys.indexOf(key) === -1) {
           delete $scope.agg.settings.settings[key];
         }
@@ -172,9 +172,9 @@ export class ElasticMetricAggCtrl {
     };
 
     $scope.addMetricAgg = function() {
-      var addIndex = metricAggs.length;
+      const addIndex = metricAggs.length;
 
-      var id = _.reduce(
+      const id = _.reduce(
         $scope.target.bucketAggs.concat($scope.target.metrics),
         function(max, val) {
           return parseInt(val.id) > max ? parseInt(val.id) : max;
@@ -203,6 +203,6 @@ export class ElasticMetricAggCtrl {
   }
 }
 
-var module = angular.module('grafana.directives');
+const module = angular.module('grafana.directives');
 module.directive('elasticMetricAgg', elasticMetricAgg);
 module.controller('ElasticMetricAggCtrl', ElasticMetricAggCtrl);

+ 14 - 14
public/app/plugins/datasource/elasticsearch/query_builder.ts

@@ -10,7 +10,7 @@ export class ElasticQueryBuilder {
   }
 
   getRangeFilter() {
-    var filter = {};
+    const filter = {};
     filter[this.timeField] = {
       gte: '$timeFrom',
       lte: '$timeTo',
@@ -60,8 +60,8 @@ export class ElasticQueryBuilder {
   }
 
   getDateHistogramAgg(aggDef) {
-    var esAgg: any = {};
-    var settings = aggDef.settings || {};
+    const esAgg: any = {};
+    const settings = aggDef.settings || {};
     esAgg.interval = settings.interval;
     esAgg.field = this.timeField;
     esAgg.min_doc_count = settings.min_doc_count || 0;
@@ -80,8 +80,8 @@ export class ElasticQueryBuilder {
   }
 
   getHistogramAgg(aggDef) {
-    var esAgg: any = {};
-    var settings = aggDef.settings || {};
+    const esAgg: any = {};
+    const settings = aggDef.settings || {};
     esAgg.interval = settings.interval;
     esAgg.field = aggDef.field;
     esAgg.min_doc_count = settings.min_doc_count || 0;
@@ -93,9 +93,9 @@ export class ElasticQueryBuilder {
   }
 
   getFiltersAgg(aggDef) {
-    var filterObj = {};
+    const filterObj = {};
     for (var i = 0; i < aggDef.settings.filters.length; i++) {
-      var query = aggDef.settings.filters[i].query;
+      const query = aggDef.settings.filters[i].query;
       var label = aggDef.settings.filters[i].label;
       label = label === '' || label === undefined ? query : label;
       filterObj[label] = {
@@ -182,7 +182,7 @@ export class ElasticQueryBuilder {
     target.timeField = this.timeField;
 
     var i, nestedAggs, metric;
-    var query = {
+    const query = {
       size: 0,
       query: {
         bool: {
@@ -208,15 +208,15 @@ export class ElasticQueryBuilder {
         throw { message: 'Invalid query' };
       }
 
-      var size = (metric.settings && metric.settings.size) || 500;
+      const size = (metric.settings && metric.settings.size) || 500;
       return this.documentQuery(query, size);
     }
 
     nestedAggs = query;
 
     for (i = 0; i < target.bucketAggs.length; i++) {
-      var aggDef = target.bucketAggs[i];
-      var esAgg = {};
+      const aggDef = target.bucketAggs[i];
+      const esAgg = {};
 
       switch (aggDef.type) {
         case 'date_histogram': {
@@ -257,7 +257,7 @@ export class ElasticQueryBuilder {
         continue;
       }
 
-      var aggField = {};
+      const aggField = {};
       var metricAgg = null;
 
       if (queryDef.isPipelineAgg(metric.type)) {
@@ -270,7 +270,7 @@ export class ElasticQueryBuilder {
         metricAgg = { field: metric.field };
       }
 
-      for (var prop in metric.settings) {
+      for (const prop in metric.settings) {
         if (metric.settings.hasOwnProperty(prop) && metric.settings[prop] !== null) {
           metricAgg[prop] = metric.settings[prop];
         }
@@ -284,7 +284,7 @@ export class ElasticQueryBuilder {
   }
 
   getTermsQuery(queryDef) {
-    var query: any = {
+    const query: any = {
       size: 0,
       query: {
         bool: {

+ 8 - 8
public/app/plugins/datasource/elasticsearch/query_ctrl.ts

@@ -21,7 +21,7 @@ export class ElasticQueryCtrl extends QueryCtrl {
   }
 
   getFields(type) {
-    var jsonStr = angular.toJson({ find: 'fields', type: type });
+    const jsonStr = angular.toJson({ find: 'fields', type: type });
     return this.datasource
       .metricFindQuery(jsonStr)
       .then(this.uiSegmentSrv.transformToSegments(false))
@@ -29,7 +29,7 @@ export class ElasticQueryCtrl extends QueryCtrl {
   }
 
   queryUpdated() {
-    var newJson = angular.toJson(this.datasource.queryBuilder.build(this.target), true);
+    const newJson = angular.toJson(this.datasource.queryBuilder.build(this.target), true);
     if (this.rawQueryOld && newJson !== this.rawQueryOld) {
       this.refresh();
     }
@@ -39,10 +39,10 @@ export class ElasticQueryCtrl extends QueryCtrl {
   }
 
   getCollapsedText() {
-    var metricAggs = this.target.metrics;
-    var bucketAggs = this.target.bucketAggs;
-    var metricAggTypes = queryDef.getMetricAggTypes(this.esVersion);
-    var bucketAggTypes = queryDef.bucketAggTypes;
+    const metricAggs = this.target.metrics;
+    const bucketAggs = this.target.bucketAggs;
+    const metricAggTypes = queryDef.getMetricAggTypes(this.esVersion);
+    const bucketAggTypes = queryDef.bucketAggTypes;
     var text = '';
 
     if (this.target.query) {
@@ -52,7 +52,7 @@ export class ElasticQueryCtrl extends QueryCtrl {
     text += 'Metrics: ';
 
     _.each(metricAggs, (metric, index) => {
-      var aggDef = _.find(metricAggTypes, { value: metric.type });
+      const aggDef = _.find(metricAggTypes, { value: metric.type });
       text += aggDef.text + '(';
       if (aggDef.requiresField) {
         text += metric.field;
@@ -65,7 +65,7 @@ export class ElasticQueryCtrl extends QueryCtrl {
         text += ' Group by: ';
       }
 
-      var aggDef = _.find(bucketAggTypes, { value: bucketAgg.type });
+      const aggDef = _.find(bucketAggTypes, { value: bucketAgg.type });
       text += aggDef.text + '(';
       if (aggDef.requiresField) {
         text += bucketAgg.field;

+ 8 - 8
public/app/plugins/datasource/elasticsearch/query_def.ts

@@ -164,7 +164,7 @@ export function getPipelineOptions(metric) {
 
 export function isPipelineAgg(metricType) {
   if (metricType) {
-    var po = pipelineOptions[metricType];
+    const po = pipelineOptions[metricType];
     return po !== null && po !== undefined;
   }
 
@@ -172,7 +172,7 @@ export function isPipelineAgg(metricType) {
 }
 
 export function getPipelineAggOptions(targets) {
-  var result = [];
+  const result = [];
   _.each(targets.metrics, function(metric) {
     if (!isPipelineAgg(metric.type)) {
       result.push({ text: describeMetric(metric), value: metric.id });
@@ -183,7 +183,7 @@ export function getPipelineAggOptions(targets) {
 }
 
 export function getMovingAvgSettings(model, filtered) {
-  var filteredResult = [];
+  const filteredResult = [];
   if (filtered) {
     _.each(movingAvgModelSettings[model], function(setting) {
       if (!setting.isCheckbox) {
@@ -196,7 +196,7 @@ export function getMovingAvgSettings(model, filtered) {
 }
 
 export function getOrderByOptions(target) {
-  var metricRefs = [];
+  const metricRefs = [];
   _.each(target.metrics, function(metric) {
     if (metric.type !== 'count') {
       metricRefs.push({ text: describeMetric(metric), value: metric.id });
@@ -207,21 +207,21 @@ export function getOrderByOptions(target) {
 }
 
 export function describeOrder(order) {
-  var def = _.find(orderOptions, { value: order });
+  const def = _.find(orderOptions, { value: order });
   return def.text;
 }
 
 export function describeMetric(metric) {
-  var def = _.find(metricAggTypes, { value: metric.type });
+  const def = _.find(metricAggTypes, { value: metric.type });
   return def.text + ' ' + metric.field;
 }
 
 export function describeOrderBy(orderBy, target) {
-  var def = _.find(orderByOptions, { value: orderBy });
+  const def = _.find(orderByOptions, { value: orderBy });
   if (def) {
     return def.text;
   }
-  var metric = _.find(target.metrics, { id: orderBy });
+  const metric = _.find(target.metrics, { id: orderBy });
   if (metric) {
     return describeMetric(metric);
   } else {

+ 1 - 1
public/app/plugins/datasource/grafana/datasource.ts

@@ -13,7 +13,7 @@ class GrafanaDatasource {
         maxDataPoints: options.maxDataPoints,
       })
       .then(res => {
-        var data = [];
+        const data = [];
 
         if (res.results) {
           _.forEach(res.results, queryRes => {

+ 7 - 7
public/app/plugins/datasource/graphite/add_graphite_func.ts

@@ -16,16 +16,16 @@ export function graphiteAddFunc($compile) {
 
   return {
     link: function($scope, elem) {
-      var ctrl = $scope.ctrl;
+      const ctrl = $scope.ctrl;
 
-      var $input = $(inputTemplate);
-      var $button = $(buttonTemplate);
+      const $input = $(inputTemplate);
+      const $button = $(buttonTemplate);
 
       $input.appendTo(elem);
       $button.appendTo(elem);
 
       ctrl.datasource.getFuncDefs().then(function(funcDefs) {
-        var allFunctions = _.map(funcDefs, 'name').sort();
+        const allFunctions = _.map(funcDefs, 'name').sort();
 
         $scope.functionMenu = createFunctionDropDownMenu(funcDefs);
 
@@ -82,7 +82,7 @@ export function graphiteAddFunc($compile) {
       });
 
       var drop;
-      var cleanUpDrop = function() {
+      const cleanUpDrop = function() {
         if (drop) {
           drop.destroy();
           drop = null;
@@ -106,7 +106,7 @@ export function graphiteAddFunc($compile) {
               shortDesc = shortDesc.substring(0, 497) + '...';
             }
 
-            var contentElement = document.createElement('div');
+            const contentElement = document.createElement('div');
             contentElement.innerHTML = '<h4>' + funcDef.name + '</h4>' + rst2html(shortDesc);
 
             drop = new Drop({
@@ -133,7 +133,7 @@ export function graphiteAddFunc($compile) {
 angular.module('grafana.directives').directive('graphiteAddFunc', graphiteAddFunc);
 
 function createFunctionDropDownMenu(funcDefs) {
-  var categories = {};
+  const categories = {};
 
   _.forEach(funcDefs, function(funcDef) {
     if (!funcDef.category) {

+ 17 - 17
public/app/plugins/datasource/graphite/datasource.ts

@@ -30,7 +30,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   };
 
   this.query = function(options) {
-    var graphOptions = {
+    const graphOptions = {
       from: this.translateTime(options.rangeRaw.from, false),
       until: this.translateTime(options.rangeRaw.to, true),
       targets: options.targets,
@@ -39,12 +39,12 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
       maxDataPoints: options.maxDataPoints,
     };
 
-    var params = this.buildGraphiteParams(graphOptions, options.scopedVars);
+    const params = this.buildGraphiteParams(graphOptions, options.scopedVars);
     if (params.length === 0) {
       return $q.when({ data: [] });
     }
 
-    var httpOptions: any = {
+    const httpOptions: any = {
       method: 'POST',
       url: '/render',
       data: params.join('&'),
@@ -63,7 +63,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   };
 
   this.addTracingHeaders = function(httpOptions, options) {
-    var proxyMode = !this.url.match(/^http/);
+    const proxyMode = !this.url.match(/^http/);
     if (proxyMode) {
       httpOptions.headers['X-Dashboard-Id'] = options.dashboardId;
       httpOptions.headers['X-Panel-Id'] = options.panelId;
@@ -75,7 +75,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
       return [];
     }
     for (var i = 0; i < result.data.length; i++) {
-      var series = result.data[i];
+      const series = result.data[i];
       for (var y = 0; y < series.datapoints.length; y++) {
         series.datapoints[y][1] *= 1000;
       }
@@ -98,8 +98,8 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   this.annotationQuery = function(options) {
     // Graphite metric as annotation
     if (options.annotation.target) {
-      var target = templateSrv.replace(options.annotation.target, {}, 'glob');
-      var graphiteQuery = {
+      const target = templateSrv.replace(options.annotation.target, {}, 'glob');
+      const graphiteQuery = {
         rangeRaw: options.rangeRaw,
         targets: [{ target: target }],
         format: 'json',
@@ -107,13 +107,13 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
       };
 
       return this.query(graphiteQuery).then(function(result) {
-        var list = [];
+        const list = [];
 
         for (var i = 0; i < result.data.length; i++) {
-          var target = result.data[i];
+          const target = result.data[i];
 
           for (var y = 0; y < target.datapoints.length; y++) {
-            var datapoint = target.datapoints[y];
+            const datapoint = target.datapoints[y];
             if (!datapoint[0]) {
               continue;
             }
@@ -130,11 +130,11 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
       });
     } else {
       // Graphite event as annotation
-      var tags = templateSrv.replace(options.annotation.tags);
+      const tags = templateSrv.replace(options.annotation.tags);
       return this.events({ range: options.rangeRaw, tags: tags }).then(results => {
-        var list = [];
+        const list = [];
         for (var i = 0; i < results.data.length; i++) {
-          var e = results.data[i];
+          const e = results.data[i];
 
           var tags = e.tags;
           if (_.isString(e.tags)) {
@@ -490,12 +490,12 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   this._seriesRefLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 
   this.buildGraphiteParams = function(options, scopedVars) {
-    var graphite_options = ['from', 'until', 'rawData', 'format', 'maxDataPoints', 'cacheTimeout'];
-    var clean_options = [],
+    const graphite_options = ['from', 'until', 'rawData', 'format', 'maxDataPoints', 'cacheTimeout'];
+    const clean_options = [],
       targets = {};
     var target, targetValue, i;
-    var regex = /\#([A-Z])/g;
-    var intervalFormatFixRegex = /'(\d+)m'/gi;
+    const regex = /\#([A-Z])/g;
+    const intervalFormatFixRegex = /'(\d+)m'/gi;
     var hasTargets = false;
 
     options['format'] = 'json';

+ 22 - 22
public/app/plugins/datasource/graphite/func_editor.ts

@@ -20,10 +20,10 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
   return {
     restrict: 'A',
     link: function postLink($scope, elem) {
-      var $funcLink = $(funcSpanTemplate);
-      var $funcControls = $(funcControlsTemplate);
-      var ctrl = $scope.ctrl;
-      var func = $scope.func;
+      const $funcLink = $(funcSpanTemplate);
+      const $funcControls = $(funcControlsTemplate);
+      const ctrl = $scope.ctrl;
+      const func = $scope.func;
       var scheduledRelink = false;
       var paramCountAtLink = 0;
       var cancelBlur = null;
@@ -31,9 +31,9 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
       function clickFuncParam(paramIndex) {
         /*jshint validthis:true */
 
-        var $link = $(this);
-        var $comma = $link.prev('.comma');
-        var $input = $link.next();
+        const $link = $(this);
+        const $comma = $link.prev('.comma');
+        const $input = $link.next();
 
         $input.val(func.params[paramIndex]);
 
@@ -43,7 +43,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
         $input.focus();
         $input.select();
 
-        var typeahead = $input.data('typeahead');
+        const typeahead = $input.data('typeahead');
         if (typeahead) {
           $input.val('');
           typeahead.lookup();
@@ -76,14 +76,14 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
 
       function switchToLink(inputElem, paramIndex) {
         /*jshint validthis:true */
-        var $input = $(inputElem);
+        const $input = $(inputElem);
 
         clearTimeout(cancelBlur);
         cancelBlur = null;
 
-        var $link = $input.prev();
-        var $comma = $link.prev('.comma');
-        var newValue = $input.val();
+        const $link = $input.prev();
+        const $comma = $link.prev('.comma');
+        const newValue = $input.val();
 
         // remove optional empty params
         if (newValue !== '' || paramDef(paramIndex).optional) {
@@ -110,7 +110,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
       // this = input element
       function inputBlur(paramIndex) {
         /*jshint validthis:true */
-        var inputElem = this;
+        const inputElem = this;
         // happens long before the click event on the typeahead options
         // need to have long delay because the blur
         cancelBlur = setTimeout(function() {
@@ -151,7 +151,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
           },
         });
 
-        var typeahead = $input.data('typeahead');
+        const typeahead = $input.data('typeahead');
         typeahead.lookup = function() {
           this.query = this.$element.val() || '';
           return this.process(this.source);
@@ -159,7 +159,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
       }
 
       function toggleFuncControls() {
-        var targetDiv = elem.closest('.tight-form');
+        const targetDiv = elem.closest('.tight-form');
 
         if (elem.hasClass('show-function-controls')) {
           elem.removeClass('show-function-controls');
@@ -178,8 +178,8 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
         $funcControls.appendTo(elem);
         $funcLink.appendTo(elem);
 
-        var defParams = _.clone(func.def.params);
-        var lastParam = _.last(func.def.params);
+        const defParams = _.clone(func.def.params);
+        const lastParam = _.last(func.def.params);
 
         while (func.params.length >= defParams.length && lastParam && lastParam.multiple) {
           defParams.push(_.assign({}, lastParam, { optional: true }));
@@ -192,7 +192,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
 
           var paramValue = templateSrv.highlightVariablesAsHtml(func.params[index]);
 
-          var last = index >= func.params.length - 1 && param.optional && !paramValue;
+          const last = index >= func.params.length - 1 && param.optional && !paramValue;
           if (last && param.multiple) {
             paramValue = '+';
           }
@@ -201,14 +201,14 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
             $('<span class="comma' + (last ? ' query-part__last' : '') + '">, </span>').appendTo(elem);
           }
 
-          var $paramLink = $(
+          const $paramLink = $(
             '<a ng-click="" class="graphite-func-param-link' +
               (last ? ' query-part__last' : '') +
               '">' +
               (paramValue || '&nbsp;') +
               '</a>'
           );
-          var $input = $(paramTemplate);
+          const $input = $(paramTemplate);
           $input.attr('placeholder', param.name);
 
           paramCountAtLink++;
@@ -251,7 +251,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
 
       function registerFuncControlsActions() {
         $funcControls.click(function(e) {
-          var $target = $(e.target);
+          const $target = $(e.target);
           if ($target.hasClass('fa-remove')) {
             toggleFuncControls();
             $scope.$apply(function() {
@@ -277,7 +277,7 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
           }
 
           if ($target.hasClass('fa-question-circle')) {
-            var funcDef = ctrl.datasource.getFuncDef(func.def.name);
+            const funcDef = ctrl.datasource.getFuncDef(func.def.name);
             if (funcDef && funcDef.description) {
               popoverSrv.show({
                 element: e.target,

+ 8 - 8
public/app/plugins/datasource/graphite/gfunc.ts

@@ -1,7 +1,7 @@
 import _ from 'lodash';
 import { isVersionGtOrEq } from 'app/core/utils/version';
 
-var index = {};
+const index = {};
 
 function addFuncDef(funcDef) {
   funcDef.params = funcDef.params || [];
@@ -13,7 +13,7 @@ function addFuncDef(funcDef) {
   }
 }
 
-var optionalSeriesRefArgs = [{ name: 'other', type: 'value_or_series', optional: true, multiple: true }];
+const optionalSeriesRefArgs = [{ name: 'other', type: 'value_or_series', optional: true, multiple: true }];
 
 addFuncDef({
   name: 'scaleToSeconds',
@@ -962,9 +962,9 @@ export class FuncInstance {
   }
 
   render(metricExp) {
-    var str = this.def.name + '(';
+    const str = this.def.name + '(';
 
-    var parameters = _.map(
+    const parameters = _.map(
       this.params,
       function(value, index) {
         var paramType;
@@ -1063,7 +1063,7 @@ function getFuncDef(name, idx?) {
 }
 
 function getFuncDefs(graphiteVersion, idx?) {
-  var funcs = {};
+  const funcs = {};
   _.forEach(idx || index, function(funcDef) {
     if (isVersionRelatedFunction(funcDef, graphiteVersion)) {
       funcs[funcDef.name] = _.assign({}, funcDef, {
@@ -1078,7 +1078,7 @@ function getFuncDefs(graphiteVersion, idx?) {
 
 // parse response from graphite /functions endpoint into internal format
 function parseFuncDefs(rawDefs) {
-  var funcDefs = {};
+  const funcDefs = {};
 
   _.forEach(rawDefs || {}, (funcDef, funcName) => {
     // skip graphite graph functions
@@ -1095,7 +1095,7 @@ function parseFuncDefs(rawDefs) {
         .replace(/.. code-block *:: *none/g, '.. code-block::');
     }
 
-    var func = {
+    const func = {
       name: funcDef.name,
       description: description,
       category: funcDef.group,
@@ -1120,7 +1120,7 @@ function parseFuncDefs(rawDefs) {
     }
 
     _.forEach(funcDef.params, rawParam => {
-      var param = {
+      const param = {
         name: rawParam.name,
         type: 'string',
         optional: !rawParam.required,

+ 10 - 10
public/app/plugins/datasource/graphite/graphite_query.ts

@@ -33,8 +33,8 @@ export default class GraphiteQuery {
       return;
     }
 
-    var parser = new Parser(this.target.target);
-    var astNode = parser.getAst();
+    const parser = new Parser(this.target.target);
+    const astNode = parser.getAst();
     if (astNode === null) {
       this.checkOtherSegmentsIndex = 0;
       return;
@@ -69,7 +69,7 @@ export default class GraphiteQuery {
   }
 
   getSegmentPathUpTo(index) {
-    var arr = this.segments.slice(0, index);
+    const arr = this.segments.slice(0, index);
 
     return _.reduce(
       arr,
@@ -87,7 +87,7 @@ export default class GraphiteQuery {
 
     switch (astNode.type) {
       case 'function':
-        var innerFunc = this.datasource.createFuncInstance(astNode.name, {
+        const innerFunc = this.datasource.createFuncInstance(astNode.name, {
           withDefaultParams: false,
         });
         _.each(astNode.params, param => {
@@ -133,7 +133,7 @@ export default class GraphiteQuery {
   }
 
   moveAliasFuncLast() {
-    var aliasFunc = _.find(this.functions, function(func) {
+    const aliasFunc = _.find(this.functions, function(func) {
       return func.def.name.startsWith('alias');
     });
 
@@ -157,7 +157,7 @@ export default class GraphiteQuery {
   updateModelTarget(targets) {
     // render query
     if (!this.target.textEditor) {
-      var metricPath = this.getSegmentPathUpTo(this.segments.length).replace(/\.select metric$/, '');
+      const metricPath = this.getSegmentPathUpTo(this.segments.length).replace(/\.select metric$/, '');
       this.target.target = _.reduce(this.functions, wrapFunction, metricPath);
     }
 
@@ -173,12 +173,12 @@ export default class GraphiteQuery {
 
   updateRenderedTarget(target, targets) {
     // render nested query
-    var targetsByRefId = _.keyBy(targets, 'refId');
+    const targetsByRefId = _.keyBy(targets, 'refId');
 
     // no references to self
     delete targetsByRefId[target.refId];
 
-    var nestedSeriesRefRegex = /\#([A-Z])/g;
+    const nestedSeriesRefRegex = /\#([A-Z])/g;
     var targetWithNestedQueries = target.target;
 
     // Use ref count to track circular references
@@ -200,8 +200,8 @@ export default class GraphiteQuery {
     // Keep interpolating until there are no query references
     // The reason for the loop is that the referenced query might contain another reference to another query
     while (targetWithNestedQueries.match(nestedSeriesRefRegex)) {
-      var updated = targetWithNestedQueries.replace(nestedSeriesRefRegex, (match, g1) => {
-        var t = targetsByRefId[g1];
+      const updated = targetWithNestedQueries.replace(nestedSeriesRefRegex, (match, g1) => {
+        const t = targetsByRefId[g1];
         if (!t) {
           return match;
         }

+ 20 - 20
public/app/plugins/datasource/graphite/lexer.ts

@@ -9,7 +9,7 @@ import _ from 'lodash';
 // http://www.fileformat.info/info/unicode/category/Lo/list.htm
 // http://www.fileformat.info/info/unicode/category/Nl/list.htm
 
-var unicodeLetterTable = [
+const unicodeLetterTable = [
   170,
   170,
   181,
@@ -898,7 +898,7 @@ var unicodeLetterTable = [
   195101,
 ];
 
-var identifierStartTable = [];
+const identifierStartTable = [];
 
 for (var i = 0; i < 128; i++) {
   identifierStartTable[i] =
@@ -920,7 +920,7 @@ for (var i = 0; i < 128; i++) {
     (i >= 97 && i <= 122); // a-z
 }
 
-var identifierPartTable = identifierStartTable;
+const identifierPartTable = identifierStartTable;
 
 export function Lexer(expression) {
   this.input = expression;
@@ -940,7 +940,7 @@ Lexer.prototype = {
   },
 
   tokenize: function() {
-    var list = [];
+    const list = [];
     var token;
     while ((token = this.next())) {
       list.push(token);
@@ -1037,7 +1037,7 @@ Lexer.prototype = {
       return /^[0-9a-fA-F]$/.test(str);
     }
 
-    var readUnicodeEscapeSequence = _.bind(function() {
+    const readUnicodeEscapeSequence = _.bind(function() {
       /*jshint validthis:true */
       index += 1;
 
@@ -1045,10 +1045,10 @@ Lexer.prototype = {
         return null;
       }
 
-      var ch1 = this.peek(index + 1);
-      var ch2 = this.peek(index + 2);
-      var ch3 = this.peek(index + 3);
-      var ch4 = this.peek(index + 4);
+      const ch1 = this.peek(index + 1);
+      const ch2 = this.peek(index + 2);
+      const ch3 = this.peek(index + 3);
+      const ch4 = this.peek(index + 4);
       var code;
 
       if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
@@ -1065,10 +1065,10 @@ Lexer.prototype = {
       return null;
     }, this);
 
-    var getIdentifierStart = _.bind(function() {
+    const getIdentifierStart = _.bind(function() {
       /*jshint validthis:true */
-      var chr = this.peek(index);
-      var code = chr.charCodeAt(0);
+      const chr = this.peek(index);
+      const code = chr.charCodeAt(0);
 
       if (chr === '*') {
         index += 1;
@@ -1096,10 +1096,10 @@ Lexer.prototype = {
       return null;
     }, this);
 
-    var getIdentifierPart = _.bind(function() {
+    const getIdentifierPart = _.bind(function() {
       /*jshint validthis:true */
-      var chr = this.peek(index);
-      var code = chr.charCodeAt(0);
+      const chr = this.peek(index);
+      const code = chr.charCodeAt(0);
 
       if (code === 92) {
         return readUnicodeEscapeSequence();
@@ -1170,7 +1170,7 @@ Lexer.prototype = {
   scanNumericLiteral: function(): any {
     var index = 0;
     var value = '';
-    var length = this.input.length;
+    const length = this.input.length;
     var char = this.peek(index);
     var bad;
 
@@ -1385,7 +1385,7 @@ Lexer.prototype = {
   },
 
   scanPunctuator: function() {
-    var ch1 = this.peek();
+    const ch1 = this.peek();
 
     if (this.isPunctuator(ch1)) {
       return {
@@ -1411,7 +1411,7 @@ Lexer.prototype = {
    */
   scanStringLiteral: function() {
     /*jshint loopfunc:true */
-    var quote = this.peek();
+    const quote = this.peek();
 
     // String must start with a quote.
     if (quote !== '"' && quote !== "'") {
@@ -1434,8 +1434,8 @@ Lexer.prototype = {
         };
       }
 
-      var char = this.peek();
-      var jump = 1; // A length of a jump, after we're done
+      const char = this.peek();
+      const jump = 1; // A length of a jump, after we're done
       // parsing this character.
 
       value += char;

+ 13 - 13
public/app/plugins/datasource/graphite/parser.ts

@@ -54,14 +54,14 @@ Parser.prototype = {
   },
 
   metricSegment: function() {
-    var curly = this.curlyBraceSegment();
+    const curly = this.curlyBraceSegment();
     if (curly) {
       return curly;
     }
 
     if (this.match('identifier') || this.match('number')) {
       // hack to handle float numbers in metric segments
-      var parts = this.consumeToken().value.split('.');
+      const parts = this.consumeToken().value.split('.');
       if (parts.length === 2) {
         this.tokens.splice(this.index, 0, { type: '.' });
         this.tokens.splice(this.index + 1, 0, {
@@ -86,7 +86,7 @@ Parser.prototype = {
       this.errorMark('Expected identifier after templateStart');
     }
 
-    var node = {
+    const node = {
       type: 'template',
       value: this.consumeToken().value,
     };
@@ -104,7 +104,7 @@ Parser.prototype = {
       return null;
     }
 
-    var node = {
+    const node = {
       type: 'metric',
       segments: [],
     };
@@ -114,7 +114,7 @@ Parser.prototype = {
     while (this.match('.')) {
       this.consumeToken();
 
-      var segment = this.metricSegment();
+      const segment = this.metricSegment();
       if (!segment) {
         this.errorMark('Expected metric identifier');
       }
@@ -130,7 +130,7 @@ Parser.prototype = {
       return null;
     }
 
-    var node: any = {
+    const node: any = {
       type: 'function',
       name: this.consumeToken().value,
     };
@@ -165,7 +165,7 @@ Parser.prototype = {
       return [];
     }
 
-    var param =
+    const param =
       this.functionCall() ||
       this.numericLiteral() ||
       this.seriesRefExpression() ||
@@ -186,12 +186,12 @@ Parser.prototype = {
       return null;
     }
 
-    var value = this.tokens[this.index].value;
+    const value = this.tokens[this.index].value;
     if (!value.match(/\#[A-Z]/)) {
       return null;
     }
 
-    var token = this.consumeToken();
+    const token = this.consumeToken();
 
     return {
       type: 'series-ref',
@@ -215,7 +215,7 @@ Parser.prototype = {
       return null;
     }
 
-    var token = this.consumeToken();
+    const token = this.consumeToken();
     if (token.isUnclosed) {
       throw { message: 'Unclosed string parameter', pos: token.pos };
     }
@@ -227,8 +227,8 @@ Parser.prototype = {
   },
 
   errorMark: function(text) {
-    var currentToken = this.tokens[this.index];
-    var type = currentToken ? currentToken.type : 'end of string';
+    const currentToken = this.tokens[this.index];
+    const type = currentToken ? currentToken.type : 'end of string';
     throw {
       message: text + ' instead found ' + type,
       pos: currentToken ? currentToken.pos : this.lexer.char,
@@ -242,7 +242,7 @@ Parser.prototype = {
   },
 
   matchToken: function(type, index) {
-    var token = this.tokens[this.index + index];
+    const token = this.tokens[this.index + index];
     return (token === undefined && type === '') || (token && token.type === type);
   },
 

+ 5 - 5
public/app/plugins/datasource/graphite/query_ctrl.ts

@@ -72,7 +72,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
       return;
     }
 
-    var path = this.queryModel.getSegmentPathUpTo(fromIndex + 1);
+    const path = this.queryModel.getSegmentPathUpTo(fromIndex + 1);
     if (path === '') {
       return Promise.resolve();
     }
@@ -110,7 +110,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
     if (index > 0) {
       query = this.queryModel.getSegmentPathUpTo(index) + '.' + query;
     }
-    var options = {
+    const options = {
       range: this.panelCtrl.range,
       requestId: 'get-alt-segments',
     };
@@ -118,7 +118,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
     return this.datasource
       .metricFindQuery(query, options)
       .then(segments => {
-        var altSegments = _.map(segments, segment => {
+        const altSegments = _.map(segments, segment => {
           return this.uiSegmentSrv.newSegment({
             value: segment.text,
             expandable: segment.expandable,
@@ -238,7 +238,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
       return;
     }
 
-    var oldTarget = this.queryModel.target.target;
+    const oldTarget = this.queryModel.target.target;
     this.updateModelTarget();
 
     if (this.queryModel.target !== oldTarget && !this.paused) {
@@ -247,7 +247,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
   }
 
   addFunction(funcDef) {
-    var newFunc = this.datasource.createFuncInstance(funcDef, {
+    const newFunc = this.datasource.createFuncInstance(funcDef, {
       withDefaultParams: true,
     });
     newFunc.added = true;

+ 24 - 24
public/app/plugins/datasource/influxdb/datasource.ts

@@ -41,9 +41,9 @@ export default class InfluxDatasource {
 
   query(options) {
     var timeFilter = this.getTimeFilter(options);
-    var scopedVars = options.scopedVars;
-    var targets = _.cloneDeep(options.targets);
-    var queryTargets = [];
+    const scopedVars = options.scopedVars;
+    const targets = _.cloneDeep(options.targets);
+    const queryTargets = [];
     var queryModel;
     var i, y;
 
@@ -71,7 +71,7 @@ export default class InfluxDatasource {
     }
 
     // add global adhoc filters to timeFilter
-    var adhocFilters = this.templateSrv.getAdhocFilters(this.name);
+    const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
     if (adhocFilters.length > 0) {
       timeFilter += ' AND ' + queryModel.renderAdhocFilters(adhocFilters);
     }
@@ -87,20 +87,20 @@ export default class InfluxDatasource {
         return [];
       }
 
-      var seriesList = [];
+      const seriesList = [];
       for (i = 0; i < data.results.length; i++) {
-        var result = data.results[i];
+        const result = data.results[i];
         if (!result || !result.series) {
           continue;
         }
 
-        var target = queryTargets[i];
+        const target = queryTargets[i];
         var alias = target.alias;
         if (alias) {
           alias = this.templateSrv.replace(target.alias, options.scopedVars);
         }
 
-        var influxSeries = new InfluxSeries({
+        const influxSeries = new InfluxSeries({
           series: data.results[i].series,
           alias: alias,
         });
@@ -111,7 +111,7 @@ export default class InfluxDatasource {
             break;
           }
           default: {
-            var timeSeries = influxSeries.getTimeSeries();
+            const timeSeries = influxSeries.getTimeSeries();
             for (y = 0; y < timeSeries.length; y++) {
               seriesList.push(timeSeries[y]);
             }
@@ -131,7 +131,7 @@ export default class InfluxDatasource {
       });
     }
 
-    var timeFilter = this.getTimeFilter({ rangeRaw: options.rangeRaw });
+    const timeFilter = this.getTimeFilter({ rangeRaw: options.rangeRaw });
     var query = options.annotation.query.replace('$timeFilter', timeFilter);
     query = this.templateSrv.replace(query, null, 'regex');
 
@@ -165,20 +165,20 @@ export default class InfluxDatasource {
   }
 
   metricFindQuery(query: string, options?: any) {
-    var interpolated = this.templateSrv.replace(query, null, 'regex');
+    const interpolated = this.templateSrv.replace(query, null, 'regex');
 
     return this._seriesQuery(interpolated, options).then(_.curry(this.responseParser.parse)(query));
   }
 
   getTagKeys(options) {
-    var queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
-    var query = queryBuilder.buildExploreQuery('TAG_KEYS');
+    const queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
+    const query = queryBuilder.buildExploreQuery('TAG_KEYS');
     return this.metricFindQuery(query, options);
   }
 
   getTagValues(options) {
-    var queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
-    var query = queryBuilder.buildExploreQuery('TAG_VALUES', options.key);
+    const queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
+    const query = queryBuilder.buildExploreQuery('TAG_VALUES', options.key);
     return this.metricFindQuery(query, options);
   }
 
@@ -188,7 +188,7 @@ export default class InfluxDatasource {
     }
 
     if (options && options.range) {
-      var timeFilter = this.getTimeFilter({ rangeRaw: options.range });
+      const timeFilter = this.getTimeFilter({ rangeRaw: options.range });
       query = query.replace('$timeFilter', timeFilter);
     }
 
@@ -214,8 +214,8 @@ export default class InfluxDatasource {
   }
 
   testDatasource() {
-    var queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
-    var query = queryBuilder.buildExploreQuery('RETENTION POLICIES');
+    const queryBuilder = new InfluxQueryBuilder({ measurement: '', tags: [] }, this.database);
+    const query = queryBuilder.buildExploreQuery('RETENTION POLICIES');
 
     return this._seriesQuery(query)
       .then(res => {
@@ -295,9 +295,9 @@ export default class InfluxDatasource {
   }
 
   getTimeFilter(options) {
-    var from = this.getInfluxTime(options.rangeRaw.from, false);
-    var until = this.getInfluxTime(options.rangeRaw.to, true);
-    var fromIsAbsolute = from[from.length - 1] === 'ms';
+    const from = this.getInfluxTime(options.rangeRaw.from, false);
+    const until = this.getInfluxTime(options.rangeRaw.to, true);
+    const fromIsAbsolute = from[from.length - 1] === 'ms';
 
     if (until === 'now()' && !fromIsAbsolute) {
       return 'time >= ' + from;
@@ -312,10 +312,10 @@ export default class InfluxDatasource {
         return 'now()';
       }
 
-      var parts = /^now-(\d+)([d|h|m|s])$/.exec(date);
+      const parts = /^now-(\d+)([d|h|m|s])$/.exec(date);
       if (parts) {
-        var amount = parseInt(parts[1]);
-        var unit = parts[2];
+        const amount = parseInt(parts[1]);
+        const unit = parts[2];
         return 'now() - ' + amount + unit;
       }
       date = dateMath.parse(date, roundUp);

+ 15 - 15
public/app/plugins/datasource/influxdb/influx_query.ts

@@ -50,11 +50,11 @@ export default class InfluxQuery {
   }
 
   addGroupBy(value) {
-    var stringParts = value.match(/^(\w+)\((.*)\)$/);
-    var typePart = stringParts[1];
-    var arg = stringParts[2];
-    var partModel = queryPart.create({ type: typePart, params: [arg] });
-    var partCount = this.target.groupBy.length;
+    const stringParts = value.match(/^(\w+)\((.*)\)$/);
+    const typePart = stringParts[1];
+    const arg = stringParts[2];
+    const partModel = queryPart.create({ type: typePart, params: [arg] });
+    const partCount = this.target.groupBy.length;
 
     if (partCount === 0) {
       this.target.groupBy.push(partModel.part);
@@ -74,7 +74,7 @@ export default class InfluxQuery {
   }
 
   removeGroupByPart(part, index) {
-    var categories = queryPart.getCategories();
+    const categories = queryPart.getCategories();
 
     if (part.def.type === 'time') {
       // remove fill
@@ -82,7 +82,7 @@ export default class InfluxQuery {
       // remove aggregations
       this.target.select = _.map(this.target.select, (s: any) => {
         return _.filter(s, (part: any) => {
-          var partModel = queryPart.create(part);
+          const partModel = queryPart.create(part);
           if (partModel.def.category === categories.Aggregations) {
             return false;
           }
@@ -107,11 +107,11 @@ export default class InfluxQuery {
     // if we remove the field remove the whole statement
     if (part.def.type === 'field') {
       if (this.selectModels.length > 1) {
-        var modelsIndex = _.indexOf(this.selectModels, selectParts);
+        const modelsIndex = _.indexOf(this.selectModels, selectParts);
         this.selectModels.splice(modelsIndex, 1);
       }
     } else {
-      var partIndex = _.indexOf(selectParts, part);
+      const partIndex = _.indexOf(selectParts, part);
       selectParts.splice(partIndex, 1);
     }
 
@@ -119,7 +119,7 @@ export default class InfluxQuery {
   }
 
   addSelectPart(selectParts, type) {
-    var partModel = queryPart.create({ type: type });
+    const partModel = queryPart.create({ type: type });
     partModel.def.addStrategy(selectParts, partModel, this);
     this.updatePersistedParts();
   }
@@ -184,12 +184,12 @@ export default class InfluxQuery {
       return kbn.regexEscape(value);
     }
 
-    var escapedValues = _.map(value, kbn.regexEscape);
+    const escapedValues = _.map(value, kbn.regexEscape);
     return '(' + escapedValues.join('|') + ')';
   }
 
   render(interpolate?) {
-    var target = this.target;
+    const target = this.target;
 
     if (target.rawQuery) {
       if (interpolate) {
@@ -216,7 +216,7 @@ export default class InfluxQuery {
     }
 
     query += ' FROM ' + this.getMeasurementAndPolicy(interpolate) + ' WHERE ';
-    var conditions = _.map(target.tags, (tag, index) => {
+    const conditions = _.map(target.tags, (tag, index) => {
       return this.renderTagCondition(tag, index, interpolate);
     });
 
@@ -228,7 +228,7 @@ export default class InfluxQuery {
 
     var groupBySection = '';
     for (i = 0; i < this.groupByParts.length; i++) {
-      var part = this.groupByParts[i];
+      const part = this.groupByParts[i];
       if (i > 0) {
         // for some reason fill has no separator
         groupBySection += part.def.type === 'fill' ? ' ' : ', ';
@@ -260,7 +260,7 @@ export default class InfluxQuery {
   }
 
   renderAdhocFilters(filters) {
-    var conditions = _.map(filters, (tag, index) => {
+    const conditions = _.map(filters, (tag, index) => {
       return this.renderTagCondition(tag, index, false);
     });
     return conditions.join(' ');

+ 17 - 17
public/app/plugins/datasource/influxdb/influx_series.ts

@@ -13,7 +13,7 @@ export default class InfluxSeries {
   }
 
   getTimeSeries() {
-    var output = [];
+    const output = [];
     var i, j;
 
     if (this.series.length === 0) {
@@ -21,14 +21,14 @@ export default class InfluxSeries {
     }
 
     _.each(this.series, series => {
-      var columns = series.columns.length;
-      var tags = _.map(series.tags, function(value, key) {
+      const columns = series.columns.length;
+      const tags = _.map(series.tags, function(value, key) {
         return key + ': ' + value;
       });
 
       for (j = 1; j < columns; j++) {
         var seriesName = series.name;
-        var columnName = series.columns[j];
+        const columnName = series.columns[j];
         if (columnName !== 'value') {
           seriesName = seriesName + '.' + columnName;
         }
@@ -39,7 +39,7 @@ export default class InfluxSeries {
           seriesName = seriesName + ' {' + tags.join(', ') + '}';
         }
 
-        var datapoints = [];
+        const datapoints = [];
         if (series.values) {
           for (i = 0; i < series.values.length; i++) {
             datapoints[i] = [series.values[i][j], series.values[i][0]];
@@ -54,12 +54,12 @@ export default class InfluxSeries {
   }
 
   _getSeriesName(series, index) {
-    var regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
-    var segments = series.name.split('.');
+    const regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
+    const segments = series.name.split('.');
 
     return this.alias.replace(regex, function(match, g1, g2) {
-      var group = g1 || g2;
-      var segIndex = parseInt(group, 10);
+      const group = g1 || g2;
+      const segIndex = parseInt(group, 10);
 
       if (group === 'm' || group === 'measurement') {
         return series.name;
@@ -74,7 +74,7 @@ export default class InfluxSeries {
         return match;
       }
 
-      var tag = group.replace('tag_', '');
+      const tag = group.replace('tag_', '');
       if (!series.tags) {
         return match;
       }
@@ -83,12 +83,12 @@ export default class InfluxSeries {
   }
 
   getAnnotations() {
-    var list = [];
+    const list = [];
 
     _.each(this.series, series => {
       var titleCol = null;
       var timeCol = null;
-      var tagsCol = [];
+      const tagsCol = [];
       var textCol = null;
 
       _.each(series.columns, (column, index) => {
@@ -117,7 +117,7 @@ export default class InfluxSeries {
       });
 
       _.each(series.values, value => {
-        var data = {
+        const data = {
           annotation: this.annotation,
           time: +new Date(value[timeCol]),
           title: value[titleCol],
@@ -142,7 +142,7 @@ export default class InfluxSeries {
   }
 
   getTable() {
-    var table = new TableModel();
+    const table = new TableModel();
     var i, j;
 
     if (this.series.length === 0) {
@@ -168,10 +168,10 @@ export default class InfluxSeries {
 
       if (series.values) {
         for (i = 0; i < series.values.length; i++) {
-          var values = series.values[i];
-          var reordered = [values[0]];
+          const values = series.values[i];
+          const reordered = [values[0]];
           if (series.tags) {
-            for (var key in series.tags) {
+            for (const key in series.tags) {
               if (series.tags.hasOwnProperty(key)) {
                 reordered.push(series.tags[key]);
               }

+ 1 - 1
public/app/plugins/datasource/influxdb/query_builder.ts

@@ -82,7 +82,7 @@ export class InfluxQueryBuilder {
     }
 
     if (this.target.tags && this.target.tags.length > 0) {
-      var whereConditions = _.reduce(
+      const whereConditions = _.reduce(
         this.target.tags,
         function(memo, tag) {
           // do not add a condition for the key we want to explore for

+ 15 - 15
public/app/plugins/datasource/influxdb/query_ctrl.ts

@@ -67,11 +67,11 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   buildSelectMenu() {
-    var categories = queryPart.getCategories();
+    const categories = queryPart.getCategories();
     this.selectMenu = _.reduce(
       categories,
       function(memo, cat, key) {
-        var menu = {
+        const menu = {
           text: key,
           submenu: cat.map(item => {
             return { text: item.type, value: item.type };
@@ -85,12 +85,12 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   getGroupByOptions() {
-    var query = this.queryBuilder.buildExploreQuery('TAG_KEYS');
+    const query = this.queryBuilder.buildExploreQuery('TAG_KEYS');
 
     return this.datasource
       .metricFindQuery(query)
       .then(tags => {
-        var options = [];
+        const options = [];
         if (!this.queryModel.hasFill()) {
           options.push(this.uiSegmentSrv.newSegment({ value: 'fill(null)' }));
         }
@@ -133,7 +133,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
       }
     }
 
-    var plusButton = this.uiSegmentSrv.newPlusButton();
+    const plusButton = this.uiSegmentSrv.newPlusButton();
     this.groupBySegment.value = plusButton.value;
     this.groupBySegment.html = plusButton.html;
     this.panelCtrl.refresh();
@@ -147,7 +147,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   handleSelectPartEvent(selectParts, part, evt) {
     switch (evt.name) {
       case 'get-param-options': {
-        var fieldsQuery = this.queryBuilder.buildExploreQuery('FIELDS');
+        const fieldsQuery = this.queryBuilder.buildExploreQuery('FIELDS');
         return this.datasource
           .metricFindQuery(fieldsQuery)
           .then(this.transformToSegments(true))
@@ -171,7 +171,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   handleGroupByPartEvent(part, index, evt) {
     switch (evt.name) {
       case 'get-param-options': {
-        var tagsQuery = this.queryBuilder.buildExploreQuery('TAG_KEYS');
+        const tagsQuery = this.queryBuilder.buildExploreQuery('TAG_KEYS');
         return this.datasource
           .metricFindQuery(tagsQuery)
           .then(this.transformToSegments(true))
@@ -193,8 +193,8 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   fixTagSegments() {
-    var count = this.tagSegments.length;
-    var lastSegment = this.tagSegments[Math.max(count - 1, 0)];
+    const count = this.tagSegments.length;
+    const lastSegment = this.tagSegments[Math.max(count - 1, 0)];
 
     if (!lastSegment || lastSegment.type !== 'plus-button') {
       this.tagSegments.push(this.uiSegmentSrv.newPlusButton());
@@ -207,7 +207,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   getPolicySegments() {
-    var policiesQuery = this.queryBuilder.buildExploreQuery('RETENTION POLICIES');
+    const policiesQuery = this.queryBuilder.buildExploreQuery('RETENTION POLICIES');
     return this.datasource
       .metricFindQuery(policiesQuery)
       .then(this.transformToSegments(false))
@@ -229,7 +229,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   getMeasurements(measurementFilter) {
-    var query = this.queryBuilder.buildExploreQuery('MEASUREMENTS', undefined, measurementFilter);
+    const query = this.queryBuilder.buildExploreQuery('MEASUREMENTS', undefined, measurementFilter);
     return this.datasource
       .metricFindQuery(query)
       .then(this.transformToSegments(true))
@@ -243,7 +243,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
 
   transformToSegments(addTemplateVars) {
     return results => {
-      var segments = _.map(results, segment => {
+      const segments = _.map(results, segment => {
         return this.uiSegmentSrv.newSegment({
           value: segment.text,
           expandable: segment.expandable,
@@ -271,7 +271,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
       return this.$q.when([this.uiSegmentSrv.newSegment('AND'), this.uiSegmentSrv.newSegment('OR')]);
     }
     if (segment.type === 'operator') {
-      var nextValue = this.tagSegments[index + 1].value;
+      const nextValue = this.tagSegments[index + 1].value;
       if (/^\/.*\/$/.test(nextValue)) {
         return this.$q.when(this.uiSegmentSrv.newOperators(['=~', '!~']));
       } else {
@@ -301,7 +301,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   getFieldSegments() {
-    var fieldsQuery = this.queryBuilder.buildExploreQuery('FIELDS');
+    const fieldsQuery = this.queryBuilder.buildExploreQuery('FIELDS');
     return this.datasource
       .metricFindQuery(fieldsQuery)
       .then(this.transformToSegments(false))
@@ -342,7 +342,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
   }
 
   rebuildTargetTagConditions() {
-    var tags = [];
+    const tags = [];
     var tagIndex = 0;
     var tagOperator = '';
 

+ 11 - 11
public/app/plugins/datasource/influxdb/query_part.ts

@@ -1,8 +1,8 @@
 import _ from 'lodash';
 import { QueryPartDef, QueryPart, functionRenderer, suffixRenderer } from 'app/core/components/query_part/query_part';
 
-var index = [];
-var categories = {
+const index = [];
+const categories = {
   Aggregations: [],
   Selectors: [],
   Transformations: [],
@@ -13,7 +13,7 @@ var categories = {
 };
 
 function createPart(part): any {
-  var def = index[part.type];
+  const def = index[part.type];
   if (!def) {
     throw { message: 'Could not find query part ' + part.type };
   }
@@ -26,7 +26,7 @@ function register(options: any) {
   options.category.push(index[options.type]);
 }
 
-var groupByTimeFunctions = [];
+const groupByTimeFunctions = [];
 
 function aliasRenderer(part, innerExpr) {
   return innerExpr + ' AS ' + '"' + part.params[0] + '"';
@@ -42,7 +42,7 @@ function fieldRenderer(part, innerExpr) {
 function replaceAggregationAddStrategy(selectParts, partModel) {
   // look for existing aggregation
   for (var i = 0; i < selectParts.length; i++) {
-    var part = selectParts[i];
+    const part = selectParts[i];
     if (part.def.category === categories.Aggregations) {
       if (part.def.type === partModel.def.type) {
         return;
@@ -53,9 +53,9 @@ function replaceAggregationAddStrategy(selectParts, partModel) {
       }
       // remove next aggregation if distinct was replaced
       if (part.def.type === 'distinct') {
-        var morePartsAvailable = selectParts.length >= i + 2;
+        const morePartsAvailable = selectParts.length >= i + 2;
         if (partModel.def.type !== 'count' && morePartsAvailable) {
-          var nextPart = selectParts[i + 1];
+          const nextPart = selectParts[i + 1];
           if (nextPart.def.category === categories.Aggregations) {
             selectParts.splice(i + 1, 1);
           }
@@ -82,7 +82,7 @@ function addTransformationStrategy(selectParts, partModel) {
   var i;
   // look for index to add transformation
   for (i = 0; i < selectParts.length; i++) {
-    var part = selectParts[i];
+    const part = selectParts[i];
     if (part.def.category === categories.Math || part.def.category === categories.Aliasing) {
       break;
     }
@@ -92,7 +92,7 @@ function addTransformationStrategy(selectParts, partModel) {
 }
 
 function addMathStrategy(selectParts, partModel) {
-  var partCount = selectParts.length;
+  const partCount = selectParts.length;
   if (partCount > 0) {
     // if last is math, replace it
     if (selectParts[partCount - 1].def.type === 'math') {
@@ -113,7 +113,7 @@ function addMathStrategy(selectParts, partModel) {
 }
 
 function addAliasStrategy(selectParts, partModel) {
-  var partCount = selectParts.length;
+  const partCount = selectParts.length;
   if (partCount > 0) {
     // if last is alias, replace it
     if (selectParts[partCount - 1].def.type === 'alias') {
@@ -126,7 +126,7 @@ function addAliasStrategy(selectParts, partModel) {
 
 function addFieldStrategy(selectParts, partModel, query) {
   // copy all parts
-  var parts = _.map(selectParts, function(part: any) {
+  const parts = _.map(selectParts, function(part: any) {
     return createPart({ type: part.def.type, params: _.clone(part.params) });
   });
 

+ 4 - 4
public/app/plugins/datasource/influxdb/response_parser.ts

@@ -6,16 +6,16 @@ export default class ResponseParser {
       return [];
     }
 
-    var influxResults = results.results[0];
+    const influxResults = results.results[0];
     if (!influxResults.series) {
       return [];
     }
 
-    var normalizedQuery = query.toLowerCase();
-    var isValueFirst =
+    const normalizedQuery = query.toLowerCase();
+    const isValueFirst =
       normalizedQuery.indexOf('show field keys') >= 0 || normalizedQuery.indexOf('show retention policies') >= 0;
 
-    var res = {};
+    const res = {};
     _.each(influxResults.series, serie => {
       _.each(serie.values, value => {
         if (_.isArray(value)) {

+ 4 - 4
public/app/plugins/datasource/mixed/datasource.ts

@@ -6,15 +6,15 @@ class MixedDatasource {
   constructor(private $q, private datasourceSrv) {}
 
   query(options) {
-    var sets = _.groupBy(options.targets, 'datasource');
-    var promises = _.map(sets, targets => {
-      var dsName = targets[0].datasource;
+    const sets = _.groupBy(options.targets, 'datasource');
+    const promises = _.map(sets, targets => {
+      const dsName = targets[0].datasource;
       if (dsName === '-- Mixed --') {
         return this.$q([]);
       }
 
       return this.datasourceSrv.get(dsName).then(function(ds) {
-        var opt = angular.copy(options);
+        const opt = angular.copy(options);
         opt.targets = targets;
         return ds.query(opt);
       });

+ 2 - 2
public/app/plugins/datasource/mssql/datasource.ts

@@ -26,7 +26,7 @@ export class MssqlDatasource {
       return value;
     }
 
-    var quotedValues = _.map(value, function(val) {
+    const quotedValues = _.map(value, function(val) {
       if (typeof value === 'number') {
         return value;
       }
@@ -37,7 +37,7 @@ export class MssqlDatasource {
   }
 
   query(options) {
-    var queries = _.filter(options.targets, item => {
+    const queries = _.filter(options.targets, item => {
       return item.hide !== true;
     }).map(item => {
       return {

+ 1 - 1
public/app/plugins/datasource/mssql/response_parser.ts

@@ -4,7 +4,7 @@ export default class ResponseParser {
   constructor(private $q) {}
 
   processQueryResult(res) {
-    var data = [];
+    const data = [];
 
     if (!res.data.results) {
       return { data: data };

+ 3 - 3
public/app/plugins/datasource/mysql/datasource.ts

@@ -26,7 +26,7 @@ export class MysqlDatasource {
       return value;
     }
 
-    var quotedValues = _.map(value, function(val) {
+    const quotedValues = _.map(value, function(val) {
       if (typeof value === 'number') {
         return value;
       }
@@ -37,7 +37,7 @@ export class MysqlDatasource {
   }
 
   query(options) {
-    var queries = _.filter(options.targets, item => {
+    const queries = _.filter(options.targets, item => {
       return item.hide !== true;
     }).map(item => {
       return {
@@ -107,7 +107,7 @@ export class MysqlDatasource {
       format: 'table',
     };
 
-    var data = {
+    const data = {
       queries: [interpolatedQuery],
     };
 

+ 1 - 1
public/app/plugins/datasource/mysql/response_parser.ts

@@ -4,7 +4,7 @@ export default class ResponseParser {
   constructor(private $q) {}
 
   processQueryResult(res) {
-    var data = [];
+    const data = [];
 
     if (!res.data.results) {
       return { data: data };

+ 42 - 42
public/app/plugins/datasource/opentsdb/datasource.ts

@@ -35,9 +35,9 @@ export default class OpenTsDatasource {
 
   // Called once per panel (graph)
   query(options) {
-    var start = this.convertToTSDBTime(options.rangeRaw.from, false);
-    var end = this.convertToTSDBTime(options.rangeRaw.to, true);
-    var qs = [];
+    const start = this.convertToTSDBTime(options.rangeRaw.from, false);
+    const end = this.convertToTSDBTime(options.rangeRaw.to, true);
+    const qs = [];
 
     _.each(
       options.targets,
@@ -49,16 +49,16 @@ export default class OpenTsDatasource {
       }.bind(this)
     );
 
-    var queries = _.compact(qs);
+    const queries = _.compact(qs);
 
     // No valid targets, return the empty result to save a round trip.
     if (_.isEmpty(queries)) {
-      var d = this.$q.defer();
+      const d = this.$q.defer();
       d.resolve({ data: [] });
       return d.promise;
     }
 
-    var groupByTags = {};
+    const groupByTags = {};
     _.each(queries, function(query) {
       if (query.filters && query.filters.length > 0) {
         _.each(query.filters, function(val) {
@@ -77,8 +77,8 @@ export default class OpenTsDatasource {
 
     return this.performTimeSeriesQuery(queries, start, end).then(
       function(response) {
-        var metricToTargetMapping = this.mapMetricsToTargets(response.data, options, this.tsdbVersion);
-        var result = _.map(
+        const metricToTargetMapping = this.mapMetricsToTargets(response.data, options, this.tsdbVersion);
+        const result = _.map(
           response.data,
           function(metricData, index) {
             index = metricToTargetMapping[index];
@@ -102,14 +102,14 @@ export default class OpenTsDatasource {
   }
 
   annotationQuery(options) {
-    var start = this.convertToTSDBTime(options.rangeRaw.from, false);
-    var end = this.convertToTSDBTime(options.rangeRaw.to, true);
-    var qs = [];
-    var eventList = [];
+    const start = this.convertToTSDBTime(options.rangeRaw.from, false);
+    const end = this.convertToTSDBTime(options.rangeRaw.to, true);
+    const qs = [];
+    const eventList = [];
 
     qs.push({ aggregator: 'sum', metric: options.annotation.target });
 
-    var queries = _.compact(qs);
+    const queries = _.compact(qs);
 
     return this.performTimeSeriesQuery(queries, start, end).then(
       function(results) {
@@ -120,7 +120,7 @@ export default class OpenTsDatasource {
           }
           if (annotationObject) {
             _.each(annotationObject, function(annotation) {
-              var event = {
+              const event = {
                 text: annotation.description,
                 time: Math.floor(annotation.startTime) * 1000,
                 annotation: options.annotation,
@@ -145,7 +145,7 @@ export default class OpenTsDatasource {
     }
 
     if (target.tags && Object.keys(target.tags).length > 0) {
-      for (var tagKey in target.tags) {
+      for (const tagKey in target.tags) {
         if (this.templateSrv.variableExists(target.tags[tagKey])) {
           return true;
         }
@@ -160,7 +160,7 @@ export default class OpenTsDatasource {
     if (this.tsdbResolution === 2) {
       msResolution = true;
     }
-    var reqBody: any = {
+    const reqBody: any = {
       start: start,
       queries: queries,
       msResolution: msResolution,
@@ -175,7 +175,7 @@ export default class OpenTsDatasource {
       reqBody.end = end;
     }
 
-    var options = {
+    const options = {
       method: 'POST',
       url: this.url + '/api/query',
       data: reqBody,
@@ -190,7 +190,7 @@ export default class OpenTsDatasource {
   }
 
   _saveTagKeys(metricData) {
-    var tagKeys = Object.keys(metricData.tags);
+    const tagKeys = Object.keys(metricData.tags);
     _.each(metricData.aggregateTags, function(tag) {
       tagKeys.push(tag);
     });
@@ -209,21 +209,21 @@ export default class OpenTsDatasource {
       return this.$q.when([]);
     }
 
-    var keysArray = keys.split(',').map(function(key) {
+    const keysArray = keys.split(',').map(function(key) {
       return key.trim();
     });
-    var key = keysArray[0];
+    const key = keysArray[0];
     var keysQuery = key + '=*';
 
     if (keysArray.length > 1) {
       keysQuery += ',' + keysArray.splice(1).join(',');
     }
 
-    var m = metric + '{' + keysQuery + '}';
+    const m = metric + '{' + keysQuery + '}';
 
     return this._get('/api/search/lookup', { m: m, limit: 3000 }).then(function(result) {
       result = result.data.results;
-      var tagvs = [];
+      const tagvs = [];
       _.each(result, function(r) {
         if (tagvs.indexOf(r.tags[key]) === -1) {
           tagvs.push(r.tags[key]);
@@ -240,7 +240,7 @@ export default class OpenTsDatasource {
 
     return this._get('/api/search/lookup', { m: metric, limit: 1000 }).then(function(result) {
       result = result.data.results;
-      var tagks = [];
+      const tagks = [];
       _.each(result, function(r) {
         _.each(r.tags, function(tagv, tagk) {
           if (tagks.indexOf(tagk) === -1) {
@@ -253,7 +253,7 @@ export default class OpenTsDatasource {
   }
 
   _get(relativeUrl, params?) {
-    var options = {
+    const options = {
       method: 'GET',
       url: this.url + relativeUrl,
       params: params,
@@ -285,39 +285,39 @@ export default class OpenTsDatasource {
       return this.$q.reject(err);
     }
 
-    var responseTransform = function(result) {
+    const responseTransform = function(result) {
       return _.map(result, function(value) {
         return { text: value };
       });
     };
 
-    var metrics_regex = /metrics\((.*)\)/;
-    var tag_names_regex = /tag_names\((.*)\)/;
-    var tag_values_regex = /tag_values\((.*?),\s?(.*)\)/;
-    var tag_names_suggest_regex = /suggest_tagk\((.*)\)/;
-    var tag_values_suggest_regex = /suggest_tagv\((.*)\)/;
+    const metrics_regex = /metrics\((.*)\)/;
+    const tag_names_regex = /tag_names\((.*)\)/;
+    const tag_values_regex = /tag_values\((.*?),\s?(.*)\)/;
+    const tag_names_suggest_regex = /suggest_tagk\((.*)\)/;
+    const tag_values_suggest_regex = /suggest_tagv\((.*)\)/;
 
-    var metrics_query = interpolated.match(metrics_regex);
+    const metrics_query = interpolated.match(metrics_regex);
     if (metrics_query) {
       return this._performSuggestQuery(metrics_query[1], 'metrics').then(responseTransform);
     }
 
-    var tag_names_query = interpolated.match(tag_names_regex);
+    const tag_names_query = interpolated.match(tag_names_regex);
     if (tag_names_query) {
       return this._performMetricKeyLookup(tag_names_query[1]).then(responseTransform);
     }
 
-    var tag_values_query = interpolated.match(tag_values_regex);
+    const tag_values_query = interpolated.match(tag_values_regex);
     if (tag_values_query) {
       return this._performMetricKeyValueLookup(tag_values_query[1], tag_values_query[2]).then(responseTransform);
     }
 
-    var tag_names_suggest_query = interpolated.match(tag_names_suggest_regex);
+    const tag_names_suggest_query = interpolated.match(tag_names_suggest_regex);
     if (tag_names_suggest_query) {
       return this._performSuggestQuery(tag_names_suggest_query[1], 'tagk').then(responseTransform);
     }
 
-    var tag_values_suggest_query = interpolated.match(tag_values_suggest_regex);
+    const tag_values_suggest_query = interpolated.match(tag_values_suggest_regex);
     if (tag_values_suggest_query) {
       return this._performSuggestQuery(tag_values_suggest_query[1], 'tagv').then(responseTransform);
     }
@@ -360,8 +360,8 @@ export default class OpenTsDatasource {
   }
 
   transformMetricData(md, groupByTags, target, options, tsdbResolution) {
-    var metricLabel = this.createMetricLabel(md, target, groupByTags, options);
-    var dps = [];
+    const metricLabel = this.createMetricLabel(md, target, groupByTags, options);
+    const dps = [];
 
     // TSDB returns datapoints has a hash of ts => value.
     // Can't use _.pairs(invert()) because it stringifies keys/values
@@ -378,7 +378,7 @@ export default class OpenTsDatasource {
 
   createMetricLabel(md, target, groupByTags, options) {
     if (target.alias) {
-      var scopedVars = _.clone(options.scopedVars || {});
+      const scopedVars = _.clone(options.scopedVars || {});
       _.each(md.tags, function(value, key) {
         scopedVars['tag_' + key] = { value: value };
       });
@@ -386,7 +386,7 @@ export default class OpenTsDatasource {
     }
 
     var label = md.metric;
-    var tagData = [];
+    const tagData = [];
 
     if (!_.isEmpty(md.tags)) {
       _.each(_.toPairs(md.tags), function(tag) {
@@ -408,7 +408,7 @@ export default class OpenTsDatasource {
       return null;
     }
 
-    var query: any = {
+    const query: any = {
       metric: this.templateSrv.replace(target.metric, options.scopedVars, 'pipe'),
       aggregator: 'avg',
     };
@@ -454,7 +454,7 @@ export default class OpenTsDatasource {
     if (target.filters && target.filters.length > 0) {
       query.filters = angular.copy(target.filters);
       if (query.filters) {
-        for (var filter_key in query.filters) {
+        for (const filter_key in query.filters) {
           query.filters[filter_key].filter = this.templateSrv.replace(
             query.filters[filter_key].filter,
             options.scopedVars,
@@ -465,7 +465,7 @@ export default class OpenTsDatasource {
     } else {
       query.tags = angular.copy(target.tags);
       if (query.tags) {
-        for (var tag_key in query.tags) {
+        for (const tag_key in query.tags) {
           query.tags[tag_key] = this.templateSrv.replace(query.tags[tag_key], options.scopedVars, 'pipe');
         }
       }

+ 2 - 2
public/app/plugins/datasource/opentsdb/query_ctrl.ts

@@ -161,7 +161,7 @@ export class OpenTsQueryCtrl extends QueryCtrl {
     this.errors = this.validateTarget();
 
     if (!this.errors.filters) {
-      var currentFilter = {
+      const currentFilter = {
         type: this.target.currentFilterType,
         tagk: this.target.currentFilterKey,
         filter: this.target.currentFilterValue,
@@ -198,7 +198,7 @@ export class OpenTsQueryCtrl extends QueryCtrl {
   }
 
   validateTarget() {
-    var errs: any = {};
+    const errs: any = {};
 
     if (this.target.shouldDownsample) {
       try {

+ 3 - 3
public/app/plugins/datasource/postgres/datasource.ts

@@ -31,14 +31,14 @@ export class PostgresDatasource {
       return value;
     }
 
-    let quotedValues = _.map(value, v => {
+    const quotedValues = _.map(value, v => {
       return this.queryModel.quoteLiteral(v);
     });
     return quotedValues.join(',');
   }
 
   query(options) {
-    let queries = _.filter(options.targets, target => {
+    const queries = _.filter(options.targets, target => {
       return target.hide !== true;
     }).map(target => {
       let queryModel = new PostgresQuery(target, this.templateSrv, options.scopedVars);
@@ -111,7 +111,7 @@ export class PostgresDatasource {
     };
 
     let range = this.timeSrv.timeRange();
-    let data = {
+    const data = {
       queries: [interpolatedQuery],
       from: range.from.valueOf().toString(),
       to: range.to.valueOf().toString(),

+ 1 - 1
public/app/plugins/datasource/postgres/response_parser.ts

@@ -4,7 +4,7 @@ export default class ResponseParser {
   constructor(private $q) {}
 
   processQueryResult(res) {
-    var data = [];
+    const data = [];
 
     if (!res.data.results) {
       return { data: data };

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.