Преглед изворни кода

Merge branch 'master' into 14409/threshold-ux-changes

Torkel Ödegaard пре 7 година
родитељ
комит
c20e10a584
100 измењених фајлова са 8732 додато и 1758 уклоњено
  1. 14 5
      CHANGELOG.md
  2. 4 0
      conf/defaults.ini
  3. 4 0
      conf/sample.ini
  4. 52 1
      devenv/datasources.yaml
  5. 5394 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json
  6. 649 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json
  7. 651 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json
  8. 649 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json
  9. 1 1
      devenv/docker/blocks/elastic/docker-compose.yaml
  10. 7 4
      devenv/docker/blocks/elastic5/docker-compose.yaml
  11. 7 5
      devenv/docker/blocks/influxdb/docker-compose.yaml
  12. 1 1
      docs/sources/auth/github.md
  13. 1 1
      docs/sources/auth/gitlab.md
  14. 162 0
      docs/sources/features/explore/index.md
  15. 2 2
      latest.json
  16. 1 1
      package.json
  17. 2 2
      pkg/services/provisioning/dashboards/file_reader.go
  18. 3 0
      pkg/services/sqlstore/migrations/datasource_mig.go
  19. 3 0
      pkg/tsdb/elasticsearch/models.go
  20. 18 4
      pkg/tsdb/elasticsearch/time_series_query.go
  21. 60 0
      pkg/tsdb/elasticsearch/time_series_query_test.go
  22. 1 0
      public/app/core/components/AppNotifications/AppNotificationItem.tsx
  23. 2 2
      public/app/core/components/CustomScrollbar/CustomScrollbar.tsx
  24. 4 4
      public/app/core/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap
  25. 9 9
      public/app/core/components/PermissionList/AddPermission.tsx
  26. 8 7
      public/app/core/components/PermissionList/DisabledPermissionListItem.tsx
  27. 9 7
      public/app/core/components/PermissionList/PermissionListItem.tsx
  28. 0 26
      public/app/core/components/Picker/DescriptionOption.tsx
  29. 0 52
      public/app/core/components/Picker/DescriptionPicker.tsx
  30. 0 18
      public/app/core/components/Picker/NoOptionsMessage.tsx
  31. 0 60
      public/app/core/components/Picker/Select.tsx
  32. 0 52
      public/app/core/components/Picker/SimplePicker.tsx
  33. 0 22
      public/app/core/components/Picker/Unit/UnitOption.tsx
  34. 0 81
      public/app/core/components/Picker/Unit/UnitPicker.tsx
  35. 6 17
      public/app/core/components/Select/DataSourcePicker.tsx
  36. 2 2
      public/app/core/components/Select/IndicatorsContainer.tsx
  37. 20 0
      public/app/core/components/Select/NoOptionsMessage.tsx
  38. 5 5
      public/app/core/components/Select/OptionGroup.tsx
  39. 0 0
      public/app/core/components/Select/PickerOption.test.tsx
  40. 1 1
      public/app/core/components/Select/PickerOption.tsx
  41. 0 0
      public/app/core/components/Select/ResetStyles.tsx
  42. 232 0
      public/app/core/components/Select/Select.tsx
  43. 0 0
      public/app/core/components/Select/TeamPicker.test.tsx
  44. 3 17
      public/app/core/components/Select/TeamPicker.tsx
  45. 51 0
      public/app/core/components/Select/UnitPicker.tsx
  46. 0 0
      public/app/core/components/Select/UserPicker.test.tsx
  47. 10 17
      public/app/core/components/Select/UserPicker.tsx
  48. 0 0
      public/app/core/components/Select/__snapshots__/PickerOption.test.tsx.snap
  49. 0 29
      public/app/core/components/Select/__snapshots__/TeamPicker.test.tsx.snap
  50. 0 29
      public/app/core/components/Select/__snapshots__/UserPicker.test.tsx.snap
  51. 13 15
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  52. 10 5
      public/app/core/components/TagFilter/TagFilter.tsx
  53. 1 1
      public/app/core/components/TagFilter/TagOption.tsx
  54. 1 1
      public/app/core/components/code_editor/code_editor.ts
  55. 2 2
      public/app/core/directives/dropdown_typeahead.ts
  56. 45 7
      public/app/core/logs_model.ts
  57. 34 11
      public/app/core/specs/logs_model.test.ts
  58. 7 5
      public/app/features/alerting/partials/alert_tab.html
  59. 71 168
      public/app/features/dashboard/dashgrid/AddPanelPanel.tsx
  60. 4 12
      public/app/features/dashboard/dashgrid/DashboardGrid.tsx
  61. 17 5
      public/app/features/dashboard/dashgrid/PanelEditor.tsx
  62. 7 11
      public/app/features/dashboard/dashgrid/QueriesTab.tsx
  63. 1 2
      public/app/features/dashboard/dashgrid/VisualizationTab.tsx
  64. 1 1
      public/app/features/dashboard/dashnav/dashnav.ts
  65. 0 46
      public/app/features/dashboard/specs/AddPanelPanel.test.tsx
  66. 1 1
      public/app/features/datasources/state/actions.ts
  67. 9 27
      public/app/features/explore/Explore.tsx
  68. 12 19
      public/app/features/explore/Logs.tsx
  69. 1 0
      public/app/features/explore/QueryEditor.tsx
  70. 0 1
      public/app/features/panel/all.ts
  71. 0 28
      public/app/features/panel/panel_header.ts
  72. 0 188
      public/app/features/panel/query_troubleshooter.ts
  73. 0 71
      public/app/features/panel/viz_tab.ts
  74. 1 1
      public/app/features/teams/TeamMembers.tsx
  75. 57 0
      public/app/features/users/InviteeRow.tsx
  76. 0 1
      public/app/features/users/InviteesTable.test.tsx
  77. 4 37
      public/app/features/users/InviteesTable.tsx
  78. 0 1
      public/app/features/users/UsersListPage.test.tsx
  79. 2 8
      public/app/features/users/UsersListPage.tsx
  80. 1 1
      public/app/features/users/__mocks__/userMocks.ts
  81. 120 258
      public/app/features/users/__snapshots__/InviteesTable.test.tsx.snap
  82. 14 17
      public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts
  83. 8 1
      public/app/plugins/datasource/elasticsearch/query_builder.ts
  84. 7 0
      public/app/plugins/datasource/elasticsearch/query_def.ts
  85. 49 0
      public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts
  86. 92 192
      public/app/plugins/datasource/loki/img/loki_icon.svg
  87. 4 5
      public/app/plugins/panel/gauge/MappingRow.tsx
  88. 16 18
      public/app/plugins/panel/gauge/ValueOptions.tsx
  89. 10 10
      public/app/plugins/panel/table/column_options.html
  90. 7 15
      public/app/plugins/panel/text/editor.html
  91. 10 1
      public/app/plugins/panel/text/module.ts
  92. 2 6
      public/app/types/explore.ts
  93. 0 1
      public/sass/_grafana.scss
  94. 1 1
      public/sass/_variables.light.scss
  95. 2 2
      public/sass/base/_icons.scss
  96. 4 0
      public/sass/components/_code_editor.scss
  97. 19 2
      public/sass/components/_form_select_box.scss
  98. 1 1
      public/sass/components/_navbar.scss
  99. 15 67
      public/sass/components/_panel_add_panel.scss
  100. 1 1
      public/sass/components/_panel_editor.scss

+ 14 - 5
CHANGELOG.md

@@ -6,27 +6,36 @@
 ### Minor
 
 * **Elasticsearch**: Add support for offset in date histogram aggregation [#12653](https://github.com/grafana/grafana/issues/12653), thx [@mattiarossi](https://github.com/mattiarossi)
+* **Elasticsearch**: Add support for moving average and derivative using doc count (metric count) [#8843](https://github.com/grafana/grafana/issues/8843) [#11175](https://github.com/grafana/grafana/issues/11175)
 * **Auth**: Prevent password reset when login form is disabled or either LDAP or Auth Proxy is enabled [#14246](https://github.com/grafana/grafana/issues/14246), thx [@SilverFire](https://github.com/SilverFire)
 * **Dataproxy**: Override incoming Authorization header [#13815](https://github.com/grafana/grafana/issues/13815), thx [@kornholi](https://github.com/kornholi)
 * **Admin**: Fix prevent removing last grafana admin permissions [#11067](https://github.com/grafana/grafana/issues/11067), thx [@danielbh](https://github.com/danielbh)
+* **Templating**: Escaping "Custom" template variables [#13754](https://github.com/grafana/grafana/issues/13754), thx [@IntegersOfK](https://github.com/IntegersOfK)
+* **Admin**: When multiple user invitations, all links are the same as the first user who was invited [#14483](https://github.com/grafana/grafana/issues/14483)
+
+# 5.4.2 (2018-12-13)
+
+* **Datasource admin**: Fix for issue creating new data source when same name exists [#14467](https://github.com/grafana/grafana/issues/14467)
+* **OAuth**: Fix for oauth auto login setting, can now be set using env variable [#14435](https://github.com/grafana/grafana/issues/14435)
+* **Dashboard search**: Fix for searching tags in tags filter dropdown. 
 
 # 5.4.1 (2018-12-10)
 
 * **Stackdriver**: Fixes issue with data proxy and Authorization header [#14262](https://github.com/grafana/grafana/issues/14262)
-* **Units**: fixedUnit for Flow:l/min and mL/min [#14294](https://github.com/grafana/grafana/issues/14294), thx [@flopp999](https://github.com/flopp999). 
+* **Units**: fixedUnit for Flow:l/min and mL/min [#14294](https://github.com/grafana/grafana/issues/14294), thx [@flopp999](https://github.com/flopp999).
 * **Logging**: Fix for issue where data proxy logged a secret when debug logging was enabled, now redacted. [#14319](https://github.com/grafana/grafana/issues/14319)
 * **InfluxDB**: Add support for alerting on InfluxDB queries that use the cumulative_sum function. [#14314](https://github.com/grafana/grafana/pull/14314), thx [@nitti](https://github.com/nitti)
-* **Plugins**: Panel plugins should no receive the panel-initialized event again as usual. 
+* **Plugins**: Panel plugins should no receive the panel-initialized event again as usual.
 * **Embedded Graphs**: Iframe graph panels should now work as usual. [#14284](https://github.com/grafana/grafana/issues/14284)
 * **Postgres**: Improve PostgreSQL Query Editor if using different Schemas, [#14313](
 https://github.com/grafana/grafana/pull/14313)
 * **Quotas**: Fixed for updating org & user quotas. [#14347](https://github.com/grafana/grafana/pull/14347), thx [#moznion](https://github.com/moznion)
 * **Cloudwatch**: Add the AWS/SES Cloudwatch metrics of BounceRate and ComplaintRate to auto complete list. [#14401](https://github.com/grafana/grafana/pull/14401), thx [@sglajchEG](https://github.com/sglajchEG)
-* **Dashboard Search**: Fixed filtering by tag issues. 
+* **Dashboard Search**: Fixed filtering by tag issues.
 * **Graph**: Fixed time region issues, [#14425](https://github.com/grafana/grafana/issues/14425), [#14280](https://github.com/grafana/grafana/issues/14280)
-* **Graph**: Fixed issue with series color picker popover being placed outside window. 
+* **Graph**: Fixed issue with series color picker popover being placed outside window.
+
 
- 
 
 # 5.4.0 (2018-12-03)
 

+ 4 - 0
conf/defaults.ini

@@ -246,6 +246,10 @@ disable_signout_menu = false
 # URL to redirect the user to after sign out
 signout_redirect_url =
 
+# Set to true to attempt login with OAuth automatically, skipping the login screen.
+# This setting is ignored if multiple OAuth providers are configured.
+oauth_auto_login = false
+
 #################################### Anonymous Auth ######################
 [auth.anonymous]
 # enable anonymous access

+ 4 - 0
conf/sample.ini

@@ -226,6 +226,10 @@ log_queries =
 # URL to redirect the user to after sign out
 ;signout_redirect_url =
 
+# Set to true to attempt login with OAuth automatically, skipping the login screen.
+# This setting is ignored if multiple OAuth providers are configured.
+;oauth_auto_login = false
+
 #################################### Anonymous Auth ##########################
 [auth.anonymous]
 # enable anonymous access

+ 52 - 1
devenv/datasources.yaml

@@ -35,7 +35,7 @@ datasources:
       tsdbResolution: 1
       tsdbVersion: 1
 
-  - name: gdev-elasticsearch-metrics
+  - name: gdev-elasticsearch-v2-metrics
     type: elasticsearch
     access: proxy
     database: "[metrics-]YYYY.MM.DD"
@@ -43,6 +43,57 @@ datasources:
     jsonData:
       interval: Daily
       timeField: "@timestamp"
+      esVersion: 2
+
+  - name: gdev-elasticsearch-v2-logs
+    type: elasticsearch
+    access: proxy
+    database: "[logs-]YYYY.MM.DD"
+    url: http://localhost:9200
+    jsonData:
+      interval: Daily
+      timeField: "@timestamp"
+      esVersion: 2
+
+  - name: gdev-elasticsearch-v5-metrics
+    type: elasticsearch
+    access: proxy
+    database: "[metrics-]YYYY.MM.DD"
+    url: http://localhost:10200
+    jsonData:
+      interval: Daily
+      timeField: "@timestamp"
+      esVersion: 5
+
+  - name: gdev-elasticsearch-v5-logs
+    type: elasticsearch
+    access: proxy
+    database: "[logs-]YYYY.MM.DD"
+    url: http://localhost:10200
+    jsonData:
+      interval: Daily
+      timeField: "@timestamp"
+      esVersion: 5
+
+  - name: gdev-elasticsearch-v6-metrics
+    type: elasticsearch
+    access: proxy
+    database: "[metrics-]YYYY.MM.DD"
+    url: http://localhost:11200
+    jsonData:
+      interval: Daily
+      timeField: "@timestamp"
+      esVersion: 60
+
+  - name: gdev-elasticsearch-v6-logs
+    type: elasticsearch
+    access: proxy
+    database: "[logs-]YYYY.MM.DD"
+    url: http://localhost:11200
+    jsonData:
+      interval: Daily
+      timeField: "@timestamp"
+      esVersion: 60
 
   - name: gdev-mysql
     type: mysql

+ 5394 - 0
devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json

@@ -0,0 +1,5394 @@
+{
+  "annotations": {
+    "list": [
+      {
+        "builtIn": 1,
+        "datasource": "-- Grafana --",
+        "enable": false,
+        "hide": true,
+        "iconColor": "rgba(0, 211, 255, 1)",
+        "limit": 100,
+        "name": "Annotations & Alerts",
+        "showIn": 0,
+        "type": "dashboard"
+      }
+    ]
+  },
+  "editable": true,
+  "gnetId": null,
+  "graphTooltip": 0,
+  "iteration": 1542304484522,
+  "links": [
+    {
+      "icon": "external link",
+      "tags": [
+        "gdev",
+        "elasticsearch"
+      ],
+      "type": "dashboards"
+    }
+  ],
+  "panels": [
+    {
+      "collapsed": true,
+      "gridPos": {
+        "h": 1,
+        "w": 24,
+        "x": 0,
+        "y": 0
+      },
+      "id": 5,
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 1
+          },
+          "id": 2,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 1
+          },
+          "id": 3,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 10
+          },
+          "id": 8,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "1m",
+                    "min_doc_count": 50,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version one) - interval 1m + min doc count 50",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 10
+          },
+          "id": 9,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "1m",
+                    "min_doc_count": 50,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version two) - interval 1m + min doc count 50",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 19
+          },
+          "id": 6,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 10
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version one) - interval 5m + trim edges=10",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 19
+          },
+          "id": 7,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 10
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Basic (version two) - interval 5m + trim edges=10",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "title": "Basic date histogram with count",
+      "type": "row"
+    },
+    {
+      "collapsed": true,
+      "gridPos": {
+        "h": 1,
+        "w": 24,
+        "x": 0,
+        "y": 1
+      },
+      "id": 11,
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 2
+          },
+          "id": 12,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "missing": null
+                  },
+                  "type": "avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 2
+          },
+          "id": 13,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "missing": null
+                  },
+                  "type": "avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 11
+          },
+          "id": 14,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "missing": null
+                  },
+                  "type": "sum"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 11
+          },
+          "id": 15,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "missing": null
+                  },
+                  "type": "sum"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 20
+          },
+          "id": 16,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": true,
+            "max": true,
+            "min": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 20
+          },
+          "id": 21,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": true,
+            "max": true,
+            "min": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 29
+          },
+          "id": 17,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 29
+          },
+          "id": 22,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 38
+          },
+          "id": 18,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "sort": "min",
+            "sortDesc": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {
+                    "avg": true,
+                    "count": true,
+                    "max": true,
+                    "min": true,
+                    "std_deviation": true,
+                    "std_deviation_bounds_lower": true,
+                    "std_deviation_bounds_upper": true,
+                    "sum": true
+                  },
+                  "settings": {},
+                  "type": "extended_stats"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "extended stats (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 38
+          },
+          "id": 23,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "sort": "min",
+            "sortDesc": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {
+                    "avg": true,
+                    "count": true,
+                    "max": true,
+                    "min": true,
+                    "std_deviation": true,
+                    "std_deviation_bounds_lower": true,
+                    "std_deviation_bounds_upper": true,
+                    "sum": true
+                  },
+                  "settings": {},
+                  "type": "extended_stats"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "extended stats (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 47
+          },
+          "id": 19,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "percents": [
+                      25,
+                      50,
+                      75,
+                      95,
+                      99
+                    ]
+                  },
+                  "type": "percentiles"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "percentiles (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 47
+          },
+          "id": 24,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {
+                    "missing": null,
+                    "percents": [
+                      25,
+                      50,
+                      75,
+                      95,
+                      99
+                    ]
+                  },
+                  "type": "percentiles"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "percentiles (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 56
+          },
+          "id": 20,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": false,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 56
+          },
+          "id": 25,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": false,
+            "max": true,
+            "min": true,
+            "rightSide": false,
+            "show": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "",
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": null
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "title": "Basic date histogram with metric aggregation",
+      "type": "row"
+    },
+    {
+      "collapsed": true,
+      "gridPos": {
+        "h": 1,
+        "w": 24,
+        "x": 0,
+        "y": 2
+      },
+      "id": 27,
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 3
+          },
+          "id": 55,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "count"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 3
+          },
+          "id": 34,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "count"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 12
+          },
+          "id": 29,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 12
+          },
+          "id": 56,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 21
+          },
+          "id": 30,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "sum"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 21
+          },
+          "id": 35,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "sum"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 30
+          },
+          "id": 31,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 30
+          },
+          "id": 36,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 39
+          },
+          "id": 32,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 39
+          },
+          "id": 37,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 48
+          },
+          "id": 33,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 48
+          },
+          "id": 38,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {
+                    "minimize": false,
+                    "model": "simple",
+                    "window": 5
+                  },
+                  "type": "moving_avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "title": "Basic date histogram with moving average aggregation",
+      "type": "row"
+    },
+    {
+      "collapsed": true,
+      "gridPos": {
+        "h": 1,
+        "w": 24,
+        "x": 0,
+        "y": 3
+      },
+      "id": 39,
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 4
+          },
+          "id": 57,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "count"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 4
+          },
+          "id": 41,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "count"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 13
+          },
+          "id": 40,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 13
+          },
+          "id": 58,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "avg (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 22
+          },
+          "id": 42,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "sum"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 22
+          },
+          "id": 43,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "sum"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "sum (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 31
+          },
+          "id": 44,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 31
+          },
+          "id": 45,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "max"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "max (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 40
+          },
+          "id": 46,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 40
+          },
+          "id": 47,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "min"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "min (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 49
+          },
+          "id": 48,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version one) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 49
+          },
+          "id": 49,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "bucketAggs": [
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "5m",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "@value",
+                  "hide": true,
+                  "id": "1",
+                  "meta": {},
+                  "settings": {},
+                  "type": "cardinality"
+                },
+                {
+                  "field": "1",
+                  "id": "3",
+                  "meta": {},
+                  "pipelineAgg": "1",
+                  "settings": {},
+                  "type": "derivative"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "unique count (version two) - interval 5m",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "title": "Basic date histogram with derivative aggregation",
+      "type": "row"
+    },
+    {
+      "collapsed": true,
+      "gridPos": {
+        "h": 1,
+        "w": 24,
+        "x": 0,
+        "y": 4
+      },
+      "id": 54,
+      "panels": [
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_one",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 0,
+            "y": 5
+          },
+          "id": 51,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": true,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "sort": "min",
+            "sortDesc": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": true,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "{{@source}} - {{@hostname}} - {{@metric}} {{metric}}",
+              "bucketAggs": [
+                {
+                  "fake": true,
+                  "field": "@source",
+                  "id": "4",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_count",
+                    "size": "10"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "fake": true,
+                  "field": "@metric",
+                  "id": "5",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_term",
+                    "size": "10"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "fake": true,
+                  "field": "@hostname",
+                  "id": "3",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_term",
+                    "size": "5"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                },
+                {
+                  "field": "@value",
+                  "id": "6",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count/average with triple terms agg (version one) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "$version_two",
+          "decimals": 3,
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 12,
+            "x": 12,
+            "y": 5
+          },
+          "id": 52,
+          "legend": {
+            "alignAsTable": true,
+            "avg": true,
+            "current": true,
+            "max": true,
+            "min": true,
+            "rightSide": true,
+            "show": true,
+            "sort": "min",
+            "sortDesc": true,
+            "total": true,
+            "values": true
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": true,
+          "steppedLine": false,
+          "targets": [
+            {
+              "alias": "{{@source}} - {{@hostname}} - {{@metric}} {{metric}}",
+              "bucketAggs": [
+                {
+                  "fake": true,
+                  "field": "@source",
+                  "id": "4",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_count",
+                    "size": "10"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "fake": true,
+                  "field": "@metric",
+                  "id": "5",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_term",
+                    "size": "10"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "fake": true,
+                  "field": "@hostname",
+                  "id": "3",
+                  "settings": {
+                    "min_doc_count": 1,
+                    "order": "desc",
+                    "orderBy": "_term",
+                    "size": "5"
+                  },
+                  "type": "terms"
+                },
+                {
+                  "field": "@timestamp",
+                  "id": "2",
+                  "settings": {
+                    "interval": "auto",
+                    "min_doc_count": 0,
+                    "trimEdges": 0
+                  },
+                  "type": "date_histogram"
+                }
+              ],
+              "metrics": [
+                {
+                  "field": "select field",
+                  "id": "1",
+                  "type": "count"
+                },
+                {
+                  "field": "@value",
+                  "id": "6",
+                  "meta": {},
+                  "settings": {},
+                  "type": "avg"
+                }
+              ],
+              "refId": "A",
+              "target": "",
+              "timeField": "@timestamp"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "count/average with triple terms agg (version two) - interval auto",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "title": "Multiple metrics and aggregations",
+      "type": "row"
+    }
+  ],
+  "refresh": false,
+  "schemaVersion": 16,
+  "style": "dark",
+  "tags": [
+    "gdev",
+    "elasticsearch"
+  ],
+  "templating": {
+    "list": [
+      {
+        "current": {
+          "text": "gdev-elasticsearch-v2-metrics",
+          "value": "gdev-elasticsearch-v2-metrics"
+        },
+        "hide": 0,
+        "label": "Version One",
+        "name": "version_one",
+        "options": [],
+        "query": "elasticsearch",
+        "refresh": 1,
+        "regex": "/^gdev.*metrics$/",
+        "skipUrlSync": false,
+        "type": "datasource"
+      },
+      {
+        "current": {
+          "text": "gdev-elasticsearch-v5-metrics",
+          "value": "gdev-elasticsearch-v5-metrics"
+        },
+        "hide": 0,
+        "label": "Version Two",
+        "name": "version_two",
+        "options": [],
+        "query": "elasticsearch",
+        "refresh": 1,
+        "regex": "/^gdev.*metrics$/",
+        "skipUrlSync": false,
+        "type": "datasource"
+      }
+    ]
+  },
+  "time": {
+    "from": "now-3h",
+    "to": "now"
+  },
+  "timepicker": {
+    "refresh_intervals": [
+      "5s",
+      "10s",
+      "30s",
+      "1m",
+      "5m",
+      "15m",
+      "30m",
+      "1h",
+      "2h",
+      "1d"
+    ],
+    "time_options": [
+      "5m",
+      "15m",
+      "1h",
+      "6h",
+      "12h",
+      "24h",
+      "2d",
+      "7d",
+      "30d"
+    ]
+  },
+  "timezone": "",
+  "title": "Datasource tests - Elasticsearch comparison",
+  "uid": "fuFWehBmk",
+  "version": 10
+}

+ 649 - 0
devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json

@@ -0,0 +1,649 @@
+{
+  "annotations": {
+    "list": [
+      {
+        "builtIn": 1,
+        "datasource": "-- Grafana --",
+        "enable": false,
+        "hide": true,
+        "iconColor": "rgba(0, 211, 255, 1)",
+        "limit": 100,
+        "name": "Annotations & Alerts",
+        "showIn": 0,
+        "type": "dashboard"
+      },
+      {
+        "datasource": "Elastic 5 Logs",
+        "enable": false,
+        "iconColor": "rgba(255, 96, 96, 1)",
+        "limit": 100,
+        "name": "test",
+        "query": "",
+        "showIn": 0,
+        "textField": "description",
+        "type": "alert"
+      }
+    ]
+  },
+  "editable": true,
+  "gnetId": null,
+  "graphTooltip": 0,
+  "iteration": 1542303970887,
+  "links": [
+    {
+      "icon": "external link",
+      "tags": [
+        "gdev",
+        "elasticsearch"
+      ],
+      "type": "dashboards"
+    }
+  ],
+  "panels": [
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v2-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 0
+      },
+      "id": 1,
+      "legend": {
+        "alignAsTable": true,
+        "avg": false,
+        "current": false,
+        "max": true,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "3",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "1",
+                "size": "5"
+              },
+              "type": "terms"
+            },
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            }
+          ],
+          "query": "*",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Top 5 servers",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v2-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 0,
+        "y": 7
+      },
+      "id": 2,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "5m",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "percents": [
+                  25,
+                  50,
+                  75,
+                  95,
+                  99
+                ]
+              },
+              "type": "percentiles"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Percentiles & Metric filter",
+      "tooltip": {
+        "msResolution": false,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v2-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 12,
+        "y": 7
+      },
+      "id": 3,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {
+                "std_deviation_bounds_lower": true,
+                "std_deviation_bounds_upper": true
+              },
+              "settings": {},
+              "type": "extended_stats"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Standard dev",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "columns": [
+        {
+          "text": "@hostname",
+          "value": "@hostname"
+        },
+        {
+          "text": "Average",
+          "value": "Average"
+        },
+        {
+          "text": "Max",
+          "value": "Max"
+        },
+        {
+          "text": "Sum",
+          "value": "Sum"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v2-metrics",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 13
+      },
+      "id": 6,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        },
+        {
+          "colorMode": null,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "decimals": 2,
+          "pattern": "/.*/",
+          "thresholds": [],
+          "type": "number",
+          "unit": "short"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "2",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "_term",
+                "size": "0"
+              },
+              "type": "terms"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "avg"
+            },
+            {
+              "field": "@value",
+              "id": "3",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            },
+            {
+              "field": "@value",
+              "id": "4",
+              "meta": {},
+              "settings": {},
+              "type": "sum"
+            }
+          ],
+          "refId": "B",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Metrics",
+      "transform": "table",
+      "type": "table"
+    },
+    {
+      "columns": [
+        {
+          "text": "@timestamp",
+          "value": "@timestamp"
+        },
+        {
+          "text": "@message",
+          "value": "@message"
+        },
+        {
+          "text": "tags",
+          "value": "tags"
+        },
+        {
+          "text": "description",
+          "value": "description"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v2-logs",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 20
+      },
+      "id": 5,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "select field",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "size": 500
+              },
+              "type": "raw_document"
+            }
+          ],
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Log query",
+      "transform": "json",
+      "type": "table"
+    }
+  ],
+  "schemaVersion": 16,
+  "style": "dark",
+  "tags": [
+    "elasticsearch",
+    "gdev"
+  ],
+  "templating": {
+    "list": [
+      {
+        "datasource": "gdev-elasticsearch-v2-metrics",
+        "filters": [],
+        "hide": 0,
+        "label": "",
+        "name": "Filters",
+        "skipUrlSync": false,
+        "type": "adhoc"
+      }
+    ]
+  },
+  "time": {
+    "from": "now-30m",
+    "to": "now"
+  },
+  "timepicker": {
+    "collapse": false,
+    "enable": true,
+    "notice": false,
+    "now": true,
+    "refresh_intervals": [
+      "5s",
+      "10s",
+      "30s",
+      "1m",
+      "5m",
+      "15m",
+      "30m",
+      "1h",
+      "2h",
+      "1d"
+    ],
+    "status": "Stable",
+    "time_options": [
+      "5m",
+      "15m",
+      "1h",
+      "6h",
+      "12h",
+      "24h",
+      "2d",
+      "7d",
+      "30d"
+    ],
+    "type": "timepicker"
+  },
+  "timezone": "browser",
+  "title": "Datasource tests - Elasticsearch v2",
+  "uid": "RlqLq2fiz",
+  "version": 2
+}

+ 651 - 0
devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json

@@ -0,0 +1,651 @@
+{
+  "annotations": {
+    "list": [
+      {
+        "builtIn": 1,
+        "datasource": "-- Grafana --",
+        "enable": false,
+        "hide": true,
+        "iconColor": "rgba(0, 211, 255, 1)",
+        "limit": 100,
+        "name": "Annotations & Alerts",
+        "showIn": 0,
+        "type": "dashboard"
+      },
+      {
+        "datasource": "Elastic 5 Logs",
+        "enable": false,
+        "iconColor": "rgba(255, 96, 96, 1)",
+        "limit": 100,
+        "name": "test",
+        "query": "",
+        "showIn": 0,
+        "textField": "description",
+        "type": "alert"
+      }
+    ]
+  },
+  "editable": true,
+  "gnetId": null,
+  "graphTooltip": 0,
+  "iteration": 1542303896062,
+  "links": [
+    {
+      "asDropdown": false,
+      "icon": "external link",
+      "tags": [
+        "gdev",
+        "elasticsearch"
+      ],
+      "title": "Dashboard",
+      "type": "dashboards"
+    }
+  ],
+  "panels": [
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v5-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 0
+      },
+      "id": 1,
+      "legend": {
+        "alignAsTable": true,
+        "avg": false,
+        "current": false,
+        "max": true,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "3",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "1",
+                "size": "5"
+              },
+              "type": "terms"
+            },
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            }
+          ],
+          "query": "*",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Top 5 servers",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v5-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 0,
+        "y": 7
+      },
+      "id": 2,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "5m",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "percents": [
+                  25,
+                  50,
+                  75,
+                  95,
+                  99
+                ]
+              },
+              "type": "percentiles"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Percentiles & Metric filter",
+      "tooltip": {
+        "msResolution": false,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v5-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 12,
+        "y": 7
+      },
+      "id": 3,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {
+                "std_deviation_bounds_lower": true,
+                "std_deviation_bounds_upper": true
+              },
+              "settings": {},
+              "type": "extended_stats"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Standard dev",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "columns": [
+        {
+          "text": "@hostname",
+          "value": "@hostname"
+        },
+        {
+          "text": "Average",
+          "value": "Average"
+        },
+        {
+          "text": "Max",
+          "value": "Max"
+        },
+        {
+          "text": "Sum",
+          "value": "Sum"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v5-metrics",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 13
+      },
+      "id": 6,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        },
+        {
+          "colorMode": null,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "decimals": 2,
+          "pattern": "/.*/",
+          "thresholds": [],
+          "type": "number",
+          "unit": "short"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "2",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "_term",
+                "size": "0"
+              },
+              "type": "terms"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "avg"
+            },
+            {
+              "field": "@value",
+              "id": "3",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            },
+            {
+              "field": "@value",
+              "id": "4",
+              "meta": {},
+              "settings": {},
+              "type": "sum"
+            }
+          ],
+          "refId": "B",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Metrics",
+      "transform": "table",
+      "type": "table"
+    },
+    {
+      "columns": [
+        {
+          "text": "@timestamp",
+          "value": "@timestamp"
+        },
+        {
+          "text": "@message",
+          "value": "@message"
+        },
+        {
+          "text": "tags",
+          "value": "tags"
+        },
+        {
+          "text": "description",
+          "value": "description"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v5-logs",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 20
+      },
+      "id": 5,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "select field",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "size": 500
+              },
+              "type": "raw_document"
+            }
+          ],
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Log query",
+      "transform": "json",
+      "type": "table"
+    }
+  ],
+  "schemaVersion": 16,
+  "style": "dark",
+  "tags": [
+    "elasticsearch",
+    "gdev"
+  ],
+  "templating": {
+    "list": [
+      {
+        "datasource": "gdev-elasticsearch-v5-metrics",
+        "filters": [],
+        "hide": 0,
+        "label": "",
+        "name": "Filters",
+        "skipUrlSync": false,
+        "type": "adhoc"
+      }
+    ]
+  },
+  "time": {
+    "from": "now-30m",
+    "to": "now"
+  },
+  "timepicker": {
+    "collapse": false,
+    "enable": true,
+    "notice": false,
+    "now": true,
+    "refresh_intervals": [
+      "5s",
+      "10s",
+      "30s",
+      "1m",
+      "5m",
+      "15m",
+      "30m",
+      "1h",
+      "2h",
+      "1d"
+    ],
+    "status": "Stable",
+    "time_options": [
+      "5m",
+      "15m",
+      "1h",
+      "6h",
+      "12h",
+      "24h",
+      "2d",
+      "7d",
+      "30d"
+    ],
+    "type": "timepicker"
+  },
+  "timezone": "browser",
+  "title": "Datasource tests - Elasticsearch v5",
+  "uid": "8HjT32Bmz",
+  "version": 27
+}

+ 649 - 0
devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json

@@ -0,0 +1,649 @@
+{
+  "annotations": {
+    "list": [
+      {
+        "builtIn": 1,
+        "datasource": "-- Grafana --",
+        "enable": false,
+        "hide": true,
+        "iconColor": "rgba(0, 211, 255, 1)",
+        "limit": 100,
+        "name": "Annotations & Alerts",
+        "showIn": 0,
+        "type": "dashboard"
+      },
+      {
+        "datasource": "Elastic 5 Logs",
+        "enable": false,
+        "iconColor": "rgba(255, 96, 96, 1)",
+        "limit": 100,
+        "name": "test",
+        "query": "",
+        "showIn": 0,
+        "textField": "description",
+        "type": "alert"
+      }
+    ]
+  },
+  "editable": true,
+  "gnetId": null,
+  "graphTooltip": 0,
+  "iteration": 1542303999511,
+  "links": [
+    {
+      "icon": "external link",
+      "tags": [
+        "gdev",
+        "elasticsearch"
+      ],
+      "type": "dashboards"
+    }
+  ],
+  "panels": [
+    {
+      "aliasColors": {},
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v6-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 0
+      },
+      "id": 1,
+      "legend": {
+        "alignAsTable": true,
+        "avg": false,
+        "current": false,
+        "max": true,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "3",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "1",
+                "size": "5"
+              },
+              "type": "terms"
+            },
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            }
+          ],
+          "query": "*",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Top 5 servers",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v6-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 0,
+        "y": 7
+      },
+      "id": 2,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "5m",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "percents": [
+                  25,
+                  50,
+                  75,
+                  95,
+                  99
+                ]
+              },
+              "type": "percentiles"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Percentiles & Metric filter",
+      "tooltip": {
+        "msResolution": false,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "aliasColors": {
+        "Count": "#6ED0E0"
+      },
+      "bars": false,
+      "dashLength": 10,
+      "dashes": false,
+      "datasource": "gdev-elasticsearch-v6-metrics",
+      "editable": true,
+      "error": false,
+      "fill": 1,
+      "grid": {},
+      "gridPos": {
+        "h": 6,
+        "w": 12,
+        "x": 12,
+        "y": 7
+      },
+      "id": 3,
+      "legend": {
+        "alignAsTable": true,
+        "avg": true,
+        "current": false,
+        "max": false,
+        "min": false,
+        "rightSide": true,
+        "show": true,
+        "total": false,
+        "values": true
+      },
+      "lines": true,
+      "linewidth": 2,
+      "links": [],
+      "nullPointMode": "connected",
+      "percentage": false,
+      "pointradius": 5,
+      "points": false,
+      "renderer": "flot",
+      "seriesOverrides": [
+        {
+          "alias": "Count",
+          "lines": false,
+          "yaxis": 2,
+          "zindex": -1
+        }
+      ],
+      "spaceLength": 10,
+      "stack": false,
+      "steppedLine": false,
+      "targets": [
+        {
+          "alias": "{{metric}}",
+          "bucketAggs": [
+            {
+              "field": "@timestamp",
+              "id": "2",
+              "settings": {
+                "interval": "auto",
+                "min_doc_count": 0,
+                "trimEdges": 0
+              },
+              "type": "date_histogram"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {
+                "std_deviation_bounds_lower": true,
+                "std_deviation_bounds_upper": true
+              },
+              "settings": {},
+              "type": "extended_stats"
+            }
+          ],
+          "query": "@metric:cpu",
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "thresholds": [],
+      "timeFrom": null,
+      "timeRegions": [],
+      "timeShift": null,
+      "title": "Standard dev",
+      "tooltip": {
+        "msResolution": true,
+        "shared": true,
+        "sort": 0,
+        "value_type": "cumulative"
+      },
+      "type": "graph",
+      "xaxis": {
+        "buckets": null,
+        "mode": "time",
+        "name": null,
+        "show": true,
+        "values": []
+      },
+      "yaxes": [
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        },
+        {
+          "format": "short",
+          "logBase": 1,
+          "max": null,
+          "min": null,
+          "show": true
+        }
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
+    },
+    {
+      "columns": [
+        {
+          "text": "@hostname",
+          "value": "@hostname"
+        },
+        {
+          "text": "Average",
+          "value": "Average"
+        },
+        {
+          "text": "Max",
+          "value": "Max"
+        },
+        {
+          "text": "Sum",
+          "value": "Sum"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v6-metrics",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 13
+      },
+      "id": 6,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        },
+        {
+          "colorMode": null,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "decimals": 2,
+          "pattern": "/.*/",
+          "thresholds": [],
+          "type": "number",
+          "unit": "short"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [
+            {
+              "field": "@hostname",
+              "id": "2",
+              "settings": {
+                "min_doc_count": 1,
+                "order": "asc",
+                "orderBy": "_term",
+                "size": "0"
+              },
+              "type": "terms"
+            }
+          ],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "@value",
+              "id": "1",
+              "meta": {},
+              "settings": {},
+              "type": "avg"
+            },
+            {
+              "field": "@value",
+              "id": "3",
+              "meta": {},
+              "settings": {},
+              "type": "max"
+            },
+            {
+              "field": "@value",
+              "id": "4",
+              "meta": {},
+              "settings": {},
+              "type": "sum"
+            }
+          ],
+          "refId": "B",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Metrics",
+      "transform": "table",
+      "type": "table"
+    },
+    {
+      "columns": [
+        {
+          "text": "@timestamp",
+          "value": "@timestamp"
+        },
+        {
+          "text": "@message",
+          "value": "@message"
+        },
+        {
+          "text": "tags",
+          "value": "tags"
+        },
+        {
+          "text": "description",
+          "value": "description"
+        }
+      ],
+      "datasource": "gdev-elasticsearch-v6-logs",
+      "editable": true,
+      "error": false,
+      "fontSize": "100%",
+      "gridPos": {
+        "h": 7,
+        "w": 24,
+        "x": 0,
+        "y": 20
+      },
+      "id": 5,
+      "links": [],
+      "pageSize": null,
+      "scroll": true,
+      "showHeader": true,
+      "sort": {
+        "col": 0,
+        "desc": true
+      },
+      "styles": [
+        {
+          "dateFormat": "YYYY-MM-DD HH:mm:ss",
+          "pattern": "@timestamp",
+          "type": "date"
+        }
+      ],
+      "targets": [
+        {
+          "bucketAggs": [],
+          "dsType": "elasticsearch",
+          "metrics": [
+            {
+              "field": "select field",
+              "id": "1",
+              "meta": {},
+              "settings": {
+                "size": 500
+              },
+              "type": "raw_document"
+            }
+          ],
+          "refId": "A",
+          "target": "",
+          "timeField": "@timestamp"
+        }
+      ],
+      "title": "ES Log query",
+      "transform": "json",
+      "type": "table"
+    }
+  ],
+  "schemaVersion": 16,
+  "style": "dark",
+  "tags": [
+    "elasticsearch",
+    "gdev"
+  ],
+  "templating": {
+    "list": [
+      {
+        "datasource": "gdev-elasticsearch-v6-metrics",
+        "filters": [],
+        "hide": 0,
+        "label": "",
+        "name": "Filters",
+        "skipUrlSync": false,
+        "type": "adhoc"
+      }
+    ]
+  },
+  "time": {
+    "from": "now-30m",
+    "to": "now"
+  },
+  "timepicker": {
+    "collapse": false,
+    "enable": true,
+    "notice": false,
+    "now": true,
+    "refresh_intervals": [
+      "5s",
+      "10s",
+      "30s",
+      "1m",
+      "5m",
+      "15m",
+      "30m",
+      "1h",
+      "2h",
+      "1d"
+    ],
+    "status": "Stable",
+    "time_options": [
+      "5m",
+      "15m",
+      "1h",
+      "6h",
+      "12h",
+      "24h",
+      "2d",
+      "7d",
+      "30d"
+    ],
+    "type": "timepicker"
+  },
+  "timezone": "browser",
+  "title": "Datasource tests - Elasticsearch v6",
+  "uid": "NF8Pq2Biz",
+  "version": 2
+}

+ 1 - 1
devenv/docker/blocks/elastic/docker-compose.yaml

@@ -5,7 +5,7 @@
       - "9200:9200"
       - "9300:9300"
     volumes:
-      - ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
+      - ./docker/blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
 
   fake-elastic-data:
     image: grafana/fake-data-gen

+ 7 - 4
devenv/docker/blocks/elastic5/docker-compose.yaml

@@ -1,15 +1,18 @@
 # You need to run 'sysctl -w vm.max_map_count=262144' on the host machine
-
+version: '2'
+services:
   elasticsearch5:
     image: elasticsearch:5
     command: elasticsearch
     ports:
-      - "10200:9200"
-      - "10300:9300"
+      - '10200:9200'
+      - '10300:9300'
 
   fake-elastic5-data:
     image: grafana/fake-data-gen
-    network_mode: bridge
+    links:
+      - elasticsearch5
+    # network_mode: bridge
     environment:
       FD_DATASOURCE: elasticsearch
       FD_PORT: 10200

+ 7 - 5
devenv/docker/blocks/influxdb/docker-compose.yaml

@@ -1,17 +1,19 @@
+version: '2'
+services:
   influxdb:
     image: influxdb:latest
     container_name: influxdb
     ports:
-      - "2004:2004"
-      - "8083:8083"
-      - "8086:8086"
+      - '2004:2004'
+      - '8083:8083'
+      - '8086:8086'
     volumes:
       - ./docker/blocks/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf
 
   fake-influxdb-data:
     image: grafana/fake-data-gen
-    network_mode: bridge
+    links:
+      - influxdb
     environment:
       FD_DATASOURCE: influxdb
       FD_PORT: 8086
-

+ 1 - 1
docs/sources/auth/github.md

@@ -1,5 +1,5 @@
 +++
-title = "Google OAuth2 Authentication"
+title = "GitHub OAuth2 Authentication"
 description = "Grafana OAuthentication Guide "
 keywords = ["grafana", "configuration", "documentation", "oauth"]
 type = "docs"

+ 1 - 1
docs/sources/auth/gitlab.md

@@ -1,5 +1,5 @@
 +++
-title = "Google OAuth2 Authentication"
+title = "GitLab OAuth2 Authentication"
 description = "Grafana OAuthentication Guide "
 keywords = ["grafana", "configuration", "documentation", "oauth"]
 type = "docs"

+ 162 - 0
docs/sources/features/explore/index.md

@@ -0,0 +1,162 @@
++++
+title = "Explore"
+type = "docs"
+[menu.docs]
+name = "Explore"
+identifier = "explore"
+parent = "features"
+weight = 5
++++
+
+# Introduction
+
+One of the major new features of Grafana 6.0 is the new query-focused Explore workflow for troubleshooting and/or for data exploration.
+
+Grafana's dashboard UI is all about building dashboards for visualization. Explore strips away all the dashboard and panel options so that you can focus on the query. Iterate until you have a working query and then think about building a dashboard.
+
+For infrastructure monitoring and incident response, you no longer need to switch to other tools to debug what went wrong. Explore allows you to dig deeper into your metrics and logs to find the cause. Grafana's new logging datasource, [Loki](https://github.com/grafana/loki) is tightly integrated into Explore and allows you to correlate metrics and logs by viewing them side-by-side. This creates a new debugging workflow where you can:
+
+1. Receive an alert
+2. Drill down and examine metrics
+3. Drill down again and search logs related to the metric and time interval (and in the future, distributed traces).
+
+If you just want to explore your data and do not want to create a dashboard then Explore makes this much easier. Explore will show the results as both a graph and a table enabling you to see trends in the data and more detail at the same time (if the datasource supports both graph and table data).
+
+## Turning the Explore Feature On
+
+Explore will be officially released in Grafana 6.0. It is however already in the latest nightly builds of Grafana and can be turned using a feature flag in the config file. Restart Grafana after making the config file change.
+
+```ini
+[explore]
+# Enable the Explore section
+enabled = true
+```
+
+Or if using docker:
+
+```bash
+docker pull grafana/grafana:master
+docker run --name grafana -p 3000:3000 -e "GF_EXPLORE_ENABLED=true" grafana/grafana:master
+```
+
+## How to Start Exploring
+
+There is a new Explore icon on the menu bar to the left. This opens a new empty Explore tab.
+
+{{< docs-imagebox img="/img/docs/v60/explore_menu.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore Icon" >}}
+
+If you want to start with an existing query in a panel then choose the Explore option from the Panel menu. This opens an Explore tab with the query from the panel and allows you to tweak or iterate in the query outside of your dashboard.
+
+{{< docs-imagebox img="/img/docs/v60/explore_panel_menu.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}}
+
+Choose your datasource in the dropdown in the top left. Prometheus has a custom Explore implementation, the other datasources (for now) use their standard query editor.
+
+The query field is where you can write your query and explore your data. There are three buttons beside the query field, a clear button (X), an add query button (+) and the remove query button (-). Just like the normal query editor, you can add and remove multiple queries.
+
+## Split and Compare
+
+The Split feature is an easy way to compare graphs and tables side-by-side or to look at related data together on one page. Click the split button to duplicate the current query and split the page into two side-by-side queries. It is possible to select another datasource for the new query which for example, allows you to compare the same query for two different servers or to compare the staging environment to the production environment.
+
+{{< docs-imagebox img="/img/docs/v60/explore_split.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}}
+
+You can close the newly created query by clicking on the Close Split button.
+
+## Prometheus-specific Features
+
+The first version of Explore features a custom querying experience for Prometheus. When a query is executed, it actually executes two queries, a normal Prometheus query for the graph and an Instant Query for the table. An Instant Query returns the last value for each time series which shows a good summary of the data shown in the graph.
+
+### Metrics Explorer
+
+On the left-hand side of the query field is a `Metrics` button, clicking on this opens the Metric Explorer. This shows a hierarchical menu with metrics grouped by their prefix. For example, all the Alert Manager metrics will be grouped under the `alertmanager` prefix. This is a good starting point if you just want to explore which metrics are available.
+
+{{< docs-imagebox img="/img/docs/v60/explore_metric_explorer.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}}
+
+### Query Field
+
+The Query field supports autocomplete for metric names, function and works mostly the same way as the standard Prometheus query editor. Press the enter key to execute a query.
+
+The autocomplete menu can be trigger by pressing Ctrl + Space. The Autocomplete menu contains a new History section with a list of recently executed queries.
+
+Suggestions can appear under the query field - click on them to update your query with the suggested change.
+
+- For counters (monotonously increasing metrics), a rate function will be suggested.
+- For buckets, a histogram function will be suggested.
+- For recording rules, possible to expand the rules.
+
+### Table Filters
+
+Click on the filter button <span title="Filter for label" class="logs-label__icon fa fa-search-plus"></span> in a labels column in the Table panel to add filters to the query expression. This works with multiple queries too - the filter will be added for all the queries.
+
+## Logs Integration - Loki-specific Features
+
+For Grafana 6.0, the first log integration is for the new open source log aggregation system from Grafana Labs - [Loki](https://github.com/grafana/loki). Loki is designed to be very cost effective, as it does not index the contents of the logs, but rather a set of labels for each log stream. The logs from Loki are queried in a similar way to querying with label selectors in Prometheus. It uses labels to group log streams which can be made to match up with your Prometheus labels. Read more about Grafana Loki [here](https://github.com/grafana/loki) or the Grafana Labs hosted variant: [Grafana Cloud Logs](https://grafana.com/loki).
+
+### Switching from Metrics to Logs
+
+If you switch from a Prometheus query to a logs query (you can do a split first to have your metrics and logs side by side) then it will keep the labels from your query that exist in the logs and use those to query the log streams. For example, the following Prometheus query:
+
+`grafana_alerting_active_alerts{job="grafana"}`
+
+after switching to the Logs datasource, the query changes to:
+
+`{job="grafana"}`
+
+This will return a chunk of logs in the selected time range that can be grepped/text searched.
+
+### Log Queries
+
+A log query consists of two parts: **log stream selector**, and a **search expression**. For performance reasons you need to start by choosing a log stream by selecting a log label.
+
+The Logs Explorer (the `Log labels` button) next to the query field shows a list of labels of available log streams. An alternative way to write a query is to use the query field's autocomplete - you start by typing a left curly brace `{` and the autocomplete menu will suggest a list of labels. Press the `enter` key to execute the query.
+
+Once the result is returned, the log panel shows a list of log rows and a bar chart where the x-axis shows the time and the y-axis shows the frequency/count.
+
+{{< docs-imagebox img="/img/docs/v60/explore_loki.png" class="docs-image--no-shadow" caption="Explore Loki Log Streams" >}}
+
+#### Log Stream Selector
+
+For the label part of the query expression, wrap it in curly braces `{}` and then use the key value syntax for selecting labels. Multiple label expressions are separated by a comma:
+
+`{app="mysql",name="mysql-backup"}`
+
+The following label matching operators are currently supported:
+
+- `=` exactly equal.
+- `!=` not equal.
+- `=~` regex-match.
+- `!~` do not regex-match.
+
+Examples:
+
+- `{name=~"mysql.+"}`
+- `{name!~"mysql.+"}`
+
+The [same rules that apply for Prometheus Label Selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors) apply for Loki Log Stream Selectors.
+
+Another way to add a label selector, is in the table section, clicking on the **Filter** button beside a label will add the label to the query expression. This even works for multiple queries and will the label selector to each query.
+
+#### Search Expression
+
+After writing the Log Stream Selector, you can filter the results further by writing a search expression. The search expression can be just text or a regex expression.
+
+Example queries:
+
+- `{job="mysql"} error`
+- `{name="kafka"} tsdb-ops.*io:2003`
+- `{instance=~"kafka-[23]",name="kafka"} kafka.server:type=ReplicaManager`
+
+### Deduping
+
+Log data can be very repetitive and Explore can help by hiding duplicate log lines. There are a few different deduplication algorithms that you can use:
+
+- `exact` Exact matches are done on the whole line, except for date fields.
+- `numbers` Matches on the line after stripping out numbers (durations, IP addresses etc.).
+- `signature` The most aggressive deduping - strips all letters and numbers, and matches on the remaining whitespace and punctuation.
+
+### Timestamp, Local time and Labels
+
+There are some other check boxes under the logging graph apart from the Deduping options.
+
+- Timestamp: shows/hides the Timestamp column
+- Local time: shows/hides the Local time column
+- Labels: shows/hides the label filters column

+ 2 - 2
latest.json

@@ -1,4 +1,4 @@
 {
-  "stable": "5.4.0",
-  "testing": "5.4.0"
+  "stable": "5.4.2",
+  "testing": "5.4.2"
 }

+ 1 - 1
package.json

@@ -155,7 +155,7 @@
     "react-popper": "^1.3.0",
     "react-highlight-words": "0.11.0",
     "react-redux": "^5.0.7",
-    "react-select": "2.1.0",
+    "@torkelo/react-select": "2.1.1",
     "react-sizeme": "^2.3.6",
     "react-table": "^6.8.6",
     "react-transition-group": "^2.2.1",

+ 2 - 2
pkg/services/provisioning/dashboards/file_reader.go

@@ -333,12 +333,12 @@ func (fr *fileReader) resolvePath(path string) string {
 	copy := path
 	path, err := filepath.Abs(path)
 	if err != nil {
-		fr.log.Error("Could not create absolute path ", "path", path)
+		fr.log.Error("Could not create absolute path", "path", copy, "error", err)
 	}
 
 	path, err = filepath.EvalSymlinks(path)
 	if err != nil {
-		fr.log.Error("Failed to read content of symlinked path: %s", path)
+		fr.log.Error("Failed to read content of symlinked path", "path", copy, "error", err)
 	}
 
 	if path == "" {

+ 3 - 0
pkg/services/sqlstore/migrations/datasource_mig.go

@@ -127,4 +127,7 @@ func addDataSourceMigration(mg *Migrator) {
 	mg.AddMigration("Add read_only data column", NewAddColumnMigration(tableV2, &Column{
 		Name: "read_only", Type: DB_Bool, Nullable: true,
 	}))
+
+	const migrateLoggingToLoki = `UPDATE data_source SET type = 'loki' WHERE type = 'logging'`
+	mg.AddMigration("Migrate logging ds to loki ds", NewRawSqlMigration(migrateLoggingToLoki))
 }

+ 3 - 0
pkg/tsdb/elasticsearch/models.go

@@ -73,5 +73,8 @@ func isPipelineAgg(metricType string) bool {
 
 func describeMetric(metricType, field string) string {
 	text := metricAggType[metricType]
+	if metricType == countType {
+		return text
+	}
 	return text + " " + field
 }

+ 18 - 4
pkg/tsdb/elasticsearch/time_series_query.go

@@ -89,15 +89,29 @@ func (e *timeSeriesQuery) execute() (*tsdb.Response, error) {
 		}
 
 		for _, m := range q.Metrics {
-			if m.Type == "count" {
+			if m.Type == countType {
 				continue
 			}
 
 			if isPipelineAgg(m.Type) {
 				if _, err := strconv.Atoi(m.PipelineAggregate); err == nil {
-					aggBuilder.Pipeline(m.ID, m.Type, m.PipelineAggregate, func(a *es.PipelineAggregation) {
-						a.Settings = m.Settings.MustMap()
-					})
+					var appliedAgg *MetricAgg
+					for _, pipelineMetric := range q.Metrics {
+						if pipelineMetric.ID == m.PipelineAggregate {
+							appliedAgg = pipelineMetric
+							break
+						}
+					}
+					if appliedAgg != nil {
+						bucketPath := m.PipelineAggregate
+						if appliedAgg.Type == countType {
+							bucketPath = "_count"
+						}
+
+						aggBuilder.Pipeline(m.ID, m.Type, bucketPath, func(a *es.PipelineAggregation) {
+							a.Settings = m.Settings.MustMap()
+						})
+					}
 				} else {
 					continue
 				}

+ 60 - 0
pkg/tsdb/elasticsearch/time_series_query_test.go

@@ -418,6 +418,38 @@ func TestExecuteTimeSeriesQuery(t *testing.T) {
 			So(pl.BucketPath, ShouldEqual, "3")
 		})
 
+		Convey("With moving average doc count", func() {
+			c := newFakeClient(5)
+			_, err := executeTsdbQuery(c, `{
+				"timeField": "@timestamp",
+				"bucketAggs": [
+					{ "type": "date_histogram", "field": "@timestamp", "id": "4" }
+				],
+				"metrics": [
+					{ "id": "3", "type": "count", "field": "select field" },
+					{
+						"id": "2",
+						"type": "moving_avg",
+						"field": "3",
+						"pipelineAgg": "3"
+					}
+				]
+			}`, from, to, 15*time.Second)
+			So(err, ShouldBeNil)
+			sr := c.multisearchRequests[0].Requests[0]
+
+			firstLevel := sr.Aggs[0]
+			So(firstLevel.Key, ShouldEqual, "4")
+			So(firstLevel.Aggregation.Type, ShouldEqual, "date_histogram")
+			So(firstLevel.Aggregation.Aggs, ShouldHaveLength, 1)
+
+			movingAvgAgg := firstLevel.Aggregation.Aggs[0]
+			So(movingAvgAgg.Key, ShouldEqual, "2")
+			So(movingAvgAgg.Aggregation.Type, ShouldEqual, "moving_avg")
+			pl := movingAvgAgg.Aggregation.Aggregation.(*es.PipelineAggregation)
+			So(pl.BucketPath, ShouldEqual, "_count")
+		})
+
 		Convey("With broken moving average", func() {
 			c := newFakeClient(5)
 			_, err := executeTsdbQuery(c, `{
@@ -483,6 +515,34 @@ func TestExecuteTimeSeriesQuery(t *testing.T) {
 			So(plAgg.BucketPath, ShouldEqual, "3")
 		})
 
+		Convey("With derivative doc count", func() {
+			c := newFakeClient(5)
+			_, err := executeTsdbQuery(c, `{
+				"timeField": "@timestamp",
+				"bucketAggs": [
+					{ "type": "date_histogram", "field": "@timestamp", "id": "4" }
+				],
+				"metrics": [
+					{ "id": "3", "type": "count", "field": "select field" },
+					{
+						"id": "2",
+						"type": "derivative",
+						"pipelineAgg": "3"
+					}
+				]
+			}`, from, to, 15*time.Second)
+			So(err, ShouldBeNil)
+			sr := c.multisearchRequests[0].Requests[0]
+
+			firstLevel := sr.Aggs[0]
+			So(firstLevel.Key, ShouldEqual, "4")
+			So(firstLevel.Aggregation.Type, ShouldEqual, "date_histogram")
+
+			derivativeAgg := firstLevel.Aggregation.Aggs[0]
+			So(derivativeAgg.Key, ShouldEqual, "2")
+			plAgg := derivativeAgg.Aggregation.Aggregation.(*es.PipelineAggregation)
+			So(plAgg.BucketPath, ShouldEqual, "_count")
+		})
 	})
 }
 

+ 1 - 0
public/app/core/components/AppNotifications/AppNotificationItem.tsx

@@ -20,6 +20,7 @@ export default class AppNotificationItem extends Component<Props> {
 
   render() {
     const { appNotification, onClearNotification } = this.props;
+
     return (
       <div className={`alert-${appNotification.severity} alert`}>
         <div className="alert-icon">

+ 2 - 2
public/app/core/components/CustomScrollbar/CustomScrollbar.tsx

@@ -28,8 +28,8 @@ class CustomScrollbar extends PureComponent<Props> {
       <Scrollbars
         className={customClassName}
         autoHeight={true}
-        autoHeightMin={'100%'}
-        autoHeightMax={'100%'}
+        autoHeightMin={'inherit'}
+        autoHeightMax={'inherit'}
         renderTrackHorizontal={props => <div {...props} className="track-horizontal" />}
         renderTrackVertical={props => <div {...props} className="track-vertical" />}
         renderThumbHorizontal={props => <div {...props} className="thumb-horizontal" />}

+ 4 - 4
public/app/core/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap

@@ -6,8 +6,8 @@ exports[`CustomScrollbar renders correctly 1`] = `
   style={
     Object {
       "height": "auto",
-      "maxHeight": "100%",
-      "minHeight": "100%",
+      "maxHeight": "inherit",
+      "minHeight": "inherit",
       "overflow": "hidden",
       "position": "relative",
       "width": "100%",
@@ -23,8 +23,8 @@ exports[`CustomScrollbar renders correctly 1`] = `
         "left": undefined,
         "marginBottom": 0,
         "marginRight": 0,
-        "maxHeight": "calc(100% + 0px)",
-        "minHeight": "calc(100% + 0px)",
+        "maxHeight": "calc(inherit + 0px)",
+        "minHeight": "calc(inherit + 0px)",
         "overflow": "scroll",
         "position": "relative",
         "right": undefined,

+ 9 - 9
public/app/core/components/PermissionList/AddPermission.tsx

@@ -1,7 +1,7 @@
 import React, { Component } from 'react';
-import { UserPicker } from 'app/core/components/Picker/UserPicker';
-import { TeamPicker, Team } from 'app/core/components/Picker/TeamPicker';
-import DescriptionPicker, { OptionWithDescription } from 'app/core/components/Picker/DescriptionPicker';
+import { UserPicker } from 'app/core/components/Select/UserPicker';
+import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker';
+import { Select, SelectOptionItem } from 'app/core/components/Select/Select';
 import { User } from 'app/types';
 import {
   dashboardPermissionLevels,
@@ -61,7 +61,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
     this.setState({ teamId: team && !Array.isArray(team) ? team.id : 0 });
   };
 
-  onPermissionChanged = (permission: OptionWithDescription) => {
+  onPermissionChanged = (permission: SelectOptionItem) => {
     this.setState({ permission: permission.value });
   };
 
@@ -121,11 +121,11 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
             ) : null}
 
             <div className="gf-form">
-              <DescriptionPicker
-                optionsWithDesc={dashboardPermissionLevels}
-                onSelected={this.onPermissionChanged}
-                disabled={false}
-                className={'gf-form-select-box__control--menu-right'}
+              <Select
+                isSearchable={false}
+                options={dashboardPermissionLevels}
+                onChange={this.onPermissionChanged}
+                className="gf-form-select-box__control--menu-right"
               />
             </div>
 

+ 8 - 7
public/app/core/components/PermissionList/DisabledPermissionListItem.tsx

@@ -1,5 +1,5 @@
 import React, { Component } from 'react';
-import DescriptionPicker from 'app/core/components/Picker/DescriptionPicker';
+import Select from 'app/core/components/Select/Select';
 import { dashboardPermissionLevels } from 'app/types/acl';
 
 export interface Props {
@@ -9,6 +9,7 @@ export interface Props {
 export default class DisabledPermissionListItem extends Component<Props, any> {
   render() {
     const { item } = this.props;
+    const currentPermissionLevel = dashboardPermissionLevels.find(dp => dp.value === item.permission);
 
     return (
       <tr className="gf-form-disabled">
@@ -23,12 +24,12 @@ export default class DisabledPermissionListItem extends Component<Props, any> {
         <td className="query-keyword">Can</td>
         <td>
           <div className="gf-form">
-            <DescriptionPicker
-              optionsWithDesc={dashboardPermissionLevels}
-              onSelected={() => {}}
-              disabled={true}
-              className={'gf-form-select-box__control--menu-right'}
-              value={item.permission}
+            <Select
+              options={dashboardPermissionLevels}
+              onChange={() => {}}
+              isDisabled={true}
+              className="gf-form-select-box__control--menu-right"
+              value={currentPermissionLevel}
             />
           </div>
         </td>

+ 9 - 7
public/app/core/components/PermissionList/PermissionListItem.tsx

@@ -1,5 +1,5 @@
 import React, { PureComponent } from 'react';
-import DescriptionPicker from 'app/core/components/Picker/DescriptionPicker';
+import { Select } from 'app/core/components/Select/Select';
 import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
 import { FolderInfo } from 'app/types';
 
@@ -50,6 +50,7 @@ export default class PermissionsListItem extends PureComponent<Props> {
   render() {
     const { item, folderInfo } = this.props;
     const inheritedFromRoot = item.dashboardId === -1 && !item.inherited;
+    const currentPermissionLevel = dashboardPermissionLevels.find(dp => dp.value === item.permission);
 
     return (
       <tr className={setClassNameHelper(item.inherited)}>
@@ -74,12 +75,13 @@ export default class PermissionsListItem extends PureComponent<Props> {
         <td className="query-keyword">Can</td>
         <td>
           <div className="gf-form">
-            <DescriptionPicker
-              optionsWithDesc={dashboardPermissionLevels}
-              onSelected={this.onPermissionChanged}
-              disabled={item.inherited}
-              className={'gf-form-select-box__control--menu-right'}
-              value={item.permission}
+            <Select
+              isSearchable={false}
+              options={dashboardPermissionLevels}
+              onChange={this.onPermissionChanged}
+              isDisabled={item.inherited}
+              className="gf-form-select-box__control--menu-right"
+              value={currentPermissionLevel}
             />
           </div>
         </td>

+ 0 - 26
public/app/core/components/Picker/DescriptionOption.tsx

@@ -1,26 +0,0 @@
-import React from 'react';
-import { components } from 'react-select';
-import { OptionProps } from 'react-select/lib/components/Option';
-
-// https://github.com/JedWatson/react-select/issues/3038
-interface ExtendedOptionProps extends OptionProps<any> {
-  data: any;
-}
-
-export const Option = (props: ExtendedOptionProps) => {
-  const { children, isSelected, data } = props;
-
-  return (
-    <components.Option {...props}>
-      <div className="gf-form-select-box__desc-option">
-        <div className="gf-form-select-box__desc-option__body">
-          <div>{children}</div>
-          {data.description && <div className="gf-form-select-box__desc-option__desc">{data.description}</div>}
-        </div>
-        {isSelected && <i className="fa fa-check" aria-hidden="true" />}
-      </div>
-    </components.Option>
-  );
-};
-
-export default Option;

+ 0 - 52
public/app/core/components/Picker/DescriptionPicker.tsx

@@ -1,52 +0,0 @@
-import React, { Component } from 'react';
-import Select from 'react-select';
-import DescriptionOption from './DescriptionOption';
-import IndicatorsContainer from './IndicatorsContainer';
-import ResetStyles from './ResetStyles';
-import NoOptionsMessage from './NoOptionsMessage';
-
-export interface OptionWithDescription {
-  value: any;
-  label: string;
-  description: string;
-}
-
-export interface Props {
-  optionsWithDesc: OptionWithDescription[];
-  onSelected: (permission) => void;
-  disabled: boolean;
-  className?: string;
-  value?: any;
-}
-
-const getSelectedOption = (optionsWithDesc, value) => optionsWithDesc.find(option => option.value === value);
-
-class DescriptionPicker extends Component<Props, any> {
-  render() {
-    const { optionsWithDesc, onSelected, disabled, className, value } = this.props;
-    const selectedOption = getSelectedOption(optionsWithDesc, value);
-    return (
-      <div className="permissions-picker">
-        <Select
-          placeholder="Choose"
-          classNamePrefix={`gf-form-select-box`}
-          className={`width-7 gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-          options={optionsWithDesc}
-          components={{
-            Option: DescriptionOption,
-            IndicatorsContainer,
-            NoOptionsMessage,
-          }}
-          styles={ResetStyles}
-          isDisabled={disabled}
-          onChange={onSelected}
-          getOptionValue={i => i.value}
-          getOptionLabel={i => i.label}
-          value={selectedOption}
-        />
-      </div>
-    );
-  }
-}
-
-export default DescriptionPicker;

+ 0 - 18
public/app/core/components/Picker/NoOptionsMessage.tsx

@@ -1,18 +0,0 @@
-import React from 'react';
-import { components } from 'react-select';
-import { OptionProps } from 'react-select/lib/components/Option';
-
-export interface Props {
-  children: Element;
-}
-
-export const PickerOption = (props: OptionProps<any>) => {
-  const { children, className } = props;
-  return (
-    <components.Option {...props}>
-      <div className={`description-picker-option__button btn btn-link ${className}`}>{children}</div>
-    </components.Option>
-  );
-};
-
-export default PickerOption;

+ 0 - 60
public/app/core/components/Picker/Select.tsx

@@ -1,60 +0,0 @@
-// import React, { PureComponent } from 'react';
-// import Select as ReactSelect from 'react-select';
-// import DescriptionOption from './DescriptionOption';
-// import IndicatorsContainer from './IndicatorsContainer';
-// import ResetStyles from './ResetStyles';
-//
-// export interface OptionType {
-//   label: string;
-//   value: string;
-// }
-//
-// interface Props {
-//   defaultValue?: any;
-//   getOptionLabel: (item: T) => string;
-//   getOptionValue: (item: T) => string;
-//   onChange: (item: T) => {} | void;
-//   options: T[];
-//   placeholder?: string;
-//   width?: number;
-//   value: T;
-//   className?: string;
-// }
-//
-// export class Select<T> extends PureComponent<Props<T>> {
-//   static defaultProps = {
-//     width: null,
-//     className: '',
-//   }
-//
-//   render() {
-//     const { defaultValue, getOptionLabel, getOptionValue, onSelected, options, placeholder, width, value, className } = this.props;
-//     let widthClass = '';
-//     if (width) {
-//       widthClass = 'width-'+width;
-//     }
-//
-//   return (
-//     <ReactSelect
-//       classNamePrefix="gf-form-select-box"
-//       className={`gf-form-input gf-form-input--form-dropdown ${widthClass} ${className}`}
-//       components={{
-//         Option: DescriptionOption,
-//         IndicatorsContainer,
-//       }}
-//       defaultValue={defaultValue}
-//       value={value}
-//       getOptionLabel={getOptionLabel}
-//       getOptionValue={getOptionValue}
-//       menuShouldScrollIntoView={false}
-//       isSearchable={false}
-//       onChange={onSelected}
-//       options={options}
-//       placeholder={placeholder || 'Choose'}
-//       styles={ResetStyles}
-//     />
-//   );
-// }
-// }
-//
-// export default Select;

+ 0 - 52
public/app/core/components/Picker/SimplePicker.tsx

@@ -1,52 +0,0 @@
-import React, { SFC } from 'react';
-import Select from 'react-select';
-import DescriptionOption from './DescriptionOption';
-import IndicatorsContainer from './IndicatorsContainer';
-import ResetStyles from './ResetStyles';
-
-interface Props {
-  className?: string;
-  defaultValue?: any;
-  getOptionLabel: (item: any) => string;
-  getOptionValue: (item: any) => string;
-  onSelected: (item: any) => {} | void;
-  options: any[];
-  placeholder?: string;
-  width?: number;
-  value: any;
-}
-
-const SimplePicker: SFC<Props> = ({
-  className,
-  defaultValue,
-  getOptionLabel,
-  getOptionValue,
-  onSelected,
-  options,
-  placeholder,
-  width,
-  value,
-}) => {
-  return (
-    <Select
-      classNamePrefix="gf-form-select-box"
-      className={`${width ? 'width-' + width : ''} gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-      components={{
-        Option: DescriptionOption,
-        IndicatorsContainer,
-      }}
-      defaultValue={defaultValue}
-      value={value}
-      getOptionLabel={getOptionLabel}
-      getOptionValue={getOptionValue}
-      menuShouldScrollIntoView={false}
-      isSearchable={false}
-      onChange={onSelected}
-      options={options}
-      placeholder={placeholder || 'Choose'}
-      styles={ResetStyles}
-    />
-  );
-};
-
-export default SimplePicker;

+ 0 - 22
public/app/core/components/Picker/Unit/UnitOption.tsx

@@ -1,22 +0,0 @@
-import React, { SFC } from 'react';
-import { components } from 'react-select';
-import { OptionProps } from 'react-select/lib/components/Option';
-
-interface ExtendedOptionProps extends OptionProps<any> {
-  data: any;
-}
-
-const UnitOption: SFC<ExtendedOptionProps> = props => {
-  const { children, isSelected, className } = props;
-
-  return (
-    <components.Option {...props}>
-      <div className={`unit-picker-option__button btn btn-link ${className}`}>
-        {isSelected && <i className="fa fa-check pull-right" aria-hidden="true" />}
-        <div className="gf-form">{children}</div>
-      </div>
-    </components.Option>
-  );
-};
-
-export default UnitOption;

+ 0 - 81
public/app/core/components/Picker/Unit/UnitPicker.tsx

@@ -1,81 +0,0 @@
-import React, { PureComponent } from 'react';
-import Select from 'react-select';
-import UnitGroup from './UnitGroup';
-import UnitOption from './UnitOption';
-import ResetStyles from '../ResetStyles';
-import kbn from '../../../utils/kbn';
-
-interface Props {
-  onSelected: (item: any) => {} | void;
-  defaultValue?: string;
-  width?: number;
-}
-
-export default class UnitPicker extends PureComponent<Props> {
-  static defaultProps = {
-    width: 12,
-  };
-
-  render() {
-    const { defaultValue, onSelected, width } = this.props;
-
-    const unitGroups = kbn.getUnitFormats();
-
-    // Need to transform the data structure to work well with Select
-    const groupOptions = unitGroups.map(group => {
-      const options = group.submenu.map(unit => {
-        return {
-          label: unit.text,
-          value: unit.value,
-        };
-      });
-
-      return {
-        label: group.text,
-        options,
-      };
-    });
-
-    // const styles = {
-    //   ...ResetStyles,
-    //   menu: () => ({
-    //     maxHeight: '75%',
-    //     overflow: 'scroll',
-    //   }),
-    //   menuList: () =>
-    //     ({
-    //       overflowY: 'auto',
-    //       position: 'relative',
-    //     } as React.CSSProperties),
-    //   valueContainer: () =>
-    //     ({
-    //       overflow: 'hidden',
-    //       textOverflow: 'ellipsis',
-    //       maxWidth: '90px',
-    //       whiteSpace: 'nowrap',
-    //     } as React.CSSProperties),
-    // };
-
-    const value = groupOptions.map(group => {
-      return group.options.find(option => option.value === defaultValue);
-    });
-
-    return (
-      <Select
-        classNamePrefix="gf-form-select-box"
-        className={`width-${width} gf-form-input gf-form-input--form-dropdown`}
-        defaultValue={value}
-        isSearchable={true}
-        menuShouldScrollIntoView={false}
-        options={groupOptions}
-        placeholder="Choose"
-        onChange={onSelected}
-        components={{
-          Group: UnitGroup,
-          Option: UnitOption,
-        }}
-        styles={ResetStyles}
-      />
-    );
-  }
-}

+ 6 - 17
public/app/features/dashboard/dashgrid/DataSourcePicker.tsx → public/app/core/components/Select/DataSourcePicker.tsx

@@ -3,16 +3,13 @@ import React, { PureComponent } from 'react';
 import _ from 'lodash';
 
 // Components
-import ResetStyles from 'app/core/components/Picker/ResetStyles';
-import { Option, SingleValue } from 'app/core/components/Picker/PickerOption';
-import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
-import Select from 'react-select';
+import Select from './Select';
 
 // Types
 import { DataSourceSelectItem } from 'app/types';
 
 export interface Props {
-  onChangeDataSource: (ds: DataSourceSelectItem) => void;
+  onChange: (ds: DataSourceSelectItem) => void;
   datasources: DataSourceSelectItem[];
   current: DataSourceSelectItem;
   onBlur?: () => void;
@@ -32,7 +29,7 @@ export class DataSourcePicker extends PureComponent<Props> {
 
   onChange = item => {
     const ds = this.props.datasources.find(ds => ds.name === item.value);
-    this.props.onChangeDataSource(ds);
+    this.props.onChange(ds);
   };
 
   render() {
@@ -53,27 +50,19 @@ export class DataSourcePicker extends PureComponent<Props> {
     return (
       <div className="gf-form-inline">
         <Select
-          classNamePrefix={`gf-form-select-box`}
+          className="ds-picker"
           isMulti={false}
-          menuShouldScrollIntoView={false}
           isClearable={false}
-          className="gf-form-input gf-form-input--form-dropdown ds-picker"
-          onChange={item => this.onChange(item)}
+          backspaceRemovesValue={false}
+          onChange={this.onChange}
           options={options}
-          styles={ResetStyles}
           autoFocus={autoFocus}
           onBlur={onBlur}
           openMenuOnFocus={true}
           maxMenuHeight={500}
           placeholder="Select datasource"
-          loadingMessage={() => 'Loading datasources...'}
           noOptionsMessage={() => 'No datasources found'}
           value={value}
-          components={{
-            Option,
-            SingleValue,
-            IndicatorsContainer,
-          }}
         />
       </div>
     );

+ 2 - 2
public/app/core/components/Picker/IndicatorsContainer.tsx → public/app/core/components/Select/IndicatorsContainer.tsx

@@ -1,5 +1,5 @@
-import React from 'react';
-import { components } from 'react-select';
+import React from 'react';
+import { components } from '@torkelo/react-select';
 
 export const IndicatorsContainer = props => {
   const isOpen = props.selectProps.menuIsOpen;

+ 20 - 0
public/app/core/components/Select/NoOptionsMessage.tsx

@@ -0,0 +1,20 @@
+import React from 'react';
+import { components } from '@torkelo/react-select';
+import { OptionProps } from '@torkelo/react-select/lib/components/Option';
+
+export interface Props {
+  children: Element;
+}
+
+export const NoOptionsMessage = (props: OptionProps<any>) => {
+  const { children } = props;
+  return (
+    <components.Option {...props}>
+      <div className="gf-form-select-box__desc-option">
+        <div className="gf-form-select-box__desc-option__body">{children}</div>
+      </div>
+    </components.Option>
+  );
+};
+
+export default NoOptionsMessage;

+ 5 - 5
public/app/core/components/Picker/Unit/UnitGroup.tsx → public/app/core/components/Select/OptionGroup.tsx

@@ -9,7 +9,7 @@ interface State {
   expanded: boolean;
 }
 
-export default class UnitGroup extends PureComponent<ExtendedGroupProps, State> {
+export default class OptionGroup extends PureComponent<ExtendedGroupProps, State> {
   state = {
     expanded: false,
   };
@@ -41,10 +41,10 @@ export default class UnitGroup extends PureComponent<ExtendedGroupProps, State>
     const { expanded } = this.state;
 
     return (
-      <div className="width-21 unit-picker-group" style={{ marginBottom: '5px' }}>
-        <div className="unit-picker-group-item" onClick={this.onToggleChildren}>
-          <span style={{ textTransform: 'capitalize' }}>{label}</span>
-          <i className={`fa ${expanded ? 'fa-minus' : 'fa-plus'}`} />{' '}
+      <div className="gf-form-select-box__option-group">
+        <div className="gf-form-select-box__option-group__header" onClick={this.onToggleChildren}>
+          <span className="flex-grow">{label}</span>
+          <i className={`fa ${expanded ? 'fa-caret-left' : 'fa-caret-down'}`} />{' '}
         </div>
         {expanded && children}
       </div>

+ 0 - 0
public/app/core/components/Picker/PickerOption.test.tsx → public/app/core/components/Select/PickerOption.test.tsx


+ 1 - 1
public/app/core/components/Picker/PickerOption.tsx → public/app/core/components/Select/PickerOption.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { components } from 'react-select';
+import { components } from '@torkelo/react-select';
 import { OptionProps } from 'react-select/lib/components/Option';
 
 // https://github.com/JedWatson/react-select/issues/3038

+ 0 - 0
public/app/core/components/Picker/ResetStyles.tsx → public/app/core/components/Select/ResetStyles.tsx


+ 232 - 0
public/app/core/components/Select/Select.tsx

@@ -0,0 +1,232 @@
+// Libraries
+import classNames from 'classnames';
+import React, { PureComponent } from 'react';
+import { default as ReactSelect } from '@torkelo/react-select';
+import { default as ReactAsyncSelect } from '@torkelo/react-select/lib/Async';
+import { components } from '@torkelo/react-select';
+
+// Components
+import { Option, SingleValue } from './PickerOption';
+import OptionGroup from './OptionGroup';
+import IndicatorsContainer from './IndicatorsContainer';
+import NoOptionsMessage from './NoOptionsMessage';
+import ResetStyles from './ResetStyles';
+import CustomScrollbar from '../CustomScrollbar/CustomScrollbar';
+
+export interface SelectOptionItem {
+  label?: string;
+  value?: any;
+  imgUrl?: string;
+  description?: string;
+  [key: string]: any;
+}
+
+interface CommonProps {
+  defaultValue?: any;
+  getOptionLabel?: (item: SelectOptionItem) => string;
+  getOptionValue?: (item: SelectOptionItem) => string;
+  onChange: (item: SelectOptionItem) => {} | void;
+  placeholder?: string;
+  width?: number;
+  value?: SelectOptionItem;
+  className?: string;
+  isDisabled?: boolean;
+  isSearchable?: boolean;
+  isClearable?: boolean;
+  autoFocus?: boolean;
+  openMenuOnFocus?: boolean;
+  onBlur?: () => void;
+  maxMenuHeight?: number;
+  isLoading: boolean;
+  noOptionsMessage?: () => string;
+  isMulti?: boolean;
+  backspaceRemovesValue: boolean;
+}
+
+interface SelectProps {
+  options: SelectOptionItem[];
+}
+
+interface AsyncProps {
+  defaultOptions: boolean;
+  loadOptions: (query: string) => Promise<SelectOptionItem[]>;
+  loadingMessage?: () => string;
+}
+
+export const MenuList = props => {
+  return (
+    <components.MenuList {...props}>
+      <CustomScrollbar autoHide={false}>{props.children}</CustomScrollbar>
+    </components.MenuList>
+  );
+};
+
+export class Select extends PureComponent<CommonProps & SelectProps> {
+  static defaultProps = {
+    width: null,
+    className: '',
+    isDisabled: false,
+    isSearchable: true,
+    isClearable: false,
+    isMulti: false,
+    openMenuOnFocus: false,
+    autoFocus: false,
+    isLoading: false,
+    backspaceRemovesValue: true,
+    maxMenuHeight: 300,
+  };
+
+  render() {
+    const {
+      defaultValue,
+      getOptionLabel,
+      getOptionValue,
+      onChange,
+      options,
+      placeholder,
+      width,
+      value,
+      className,
+      isDisabled,
+      isLoading,
+      isSearchable,
+      isClearable,
+      backspaceRemovesValue,
+      isMulti,
+      autoFocus,
+      openMenuOnFocus,
+      onBlur,
+      maxMenuHeight,
+      noOptionsMessage,
+    } = this.props;
+
+    let widthClass = '';
+    if (width) {
+      widthClass = 'width-' + width;
+    }
+
+    const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
+
+    return (
+      <ReactSelect
+        classNamePrefix="gf-form-select-box"
+        className={selectClassNames}
+        components={{
+          Option,
+          SingleValue,
+          IndicatorsContainer,
+          MenuList,
+          Group: OptionGroup,
+        }}
+        defaultValue={defaultValue}
+        value={value}
+        getOptionLabel={getOptionLabel}
+        getOptionValue={getOptionValue}
+        menuShouldScrollIntoView={false}
+        isSearchable={isSearchable}
+        onChange={onChange}
+        options={options}
+        placeholder={placeholder || 'Choose'}
+        styles={ResetStyles}
+        isDisabled={isDisabled}
+        isLoading={isLoading}
+        isClearable={isClearable}
+        autoFocus={autoFocus}
+        onBlur={onBlur}
+        openMenuOnFocus={openMenuOnFocus}
+        maxMenuHeight={maxMenuHeight}
+        noOptionsMessage={noOptionsMessage}
+        isMulti={isMulti}
+        backspaceRemovesValue={backspaceRemovesValue}
+      />
+    );
+  }
+}
+
+export class AsyncSelect extends PureComponent<CommonProps & AsyncProps> {
+  static defaultProps = {
+    width: null,
+    className: '',
+    components: {},
+    loadingMessage: () => 'Loading...',
+    isDisabled: false,
+    isClearable: false,
+    isMulti: false,
+    isSearchable: true,
+    backspaceRemovesValue: true,
+    autoFocus: false,
+    openMenuOnFocus: false,
+    maxMenuHeight: 300,
+  };
+
+  render() {
+    const {
+      defaultValue,
+      getOptionLabel,
+      getOptionValue,
+      onChange,
+      placeholder,
+      width,
+      value,
+      className,
+      loadOptions,
+      defaultOptions,
+      isLoading,
+      loadingMessage,
+      noOptionsMessage,
+      isDisabled,
+      isSearchable,
+      isClearable,
+      backspaceRemovesValue,
+      autoFocus,
+      onBlur,
+      openMenuOnFocus,
+      maxMenuHeight,
+      isMulti,
+    } = this.props;
+
+    let widthClass = '';
+    if (width) {
+      widthClass = 'width-' + width;
+    }
+
+    const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
+
+    return (
+      <ReactAsyncSelect
+        classNamePrefix="gf-form-select-box"
+        className={selectClassNames}
+        components={{
+          Option,
+          SingleValue,
+          IndicatorsContainer,
+          NoOptionsMessage,
+        }}
+        defaultValue={defaultValue}
+        value={value}
+        getOptionLabel={getOptionLabel}
+        getOptionValue={getOptionValue}
+        menuShouldScrollIntoView={false}
+        onChange={onChange}
+        loadOptions={loadOptions}
+        isLoading={isLoading}
+        defaultOptions={defaultOptions}
+        placeholder={placeholder || 'Choose'}
+        styles={ResetStyles}
+        loadingMessage={loadingMessage}
+        noOptionsMessage={noOptionsMessage}
+        isDisabled={isDisabled}
+        isSearchable={isSearchable}
+        isClearable={isClearable}
+        autoFocus={autoFocus}
+        onBlur={onBlur}
+        openMenuOnFocus={openMenuOnFocus}
+        maxMenuHeight={maxMenuHeight}
+        isMulti={isMulti}
+        backspaceRemovesValue={backspaceRemovesValue}
+      />
+    );
+  }
+}
+
+export default Select;

+ 0 - 0
public/app/core/components/Picker/TeamPicker.test.tsx → public/app/core/components/Select/TeamPicker.test.tsx


+ 3 - 17
public/app/core/components/Picker/TeamPicker.tsx → public/app/core/components/Select/TeamPicker.tsx

@@ -1,11 +1,7 @@
 import React, { Component } from 'react';
-import AsyncSelect from 'react-select/lib/Async';
-import PickerOption from './PickerOption';
+import { AsyncSelect } from './Select';
 import { debounce } from 'lodash';
 import { getBackendSrv } from 'app/core/services/backend_srv';
-import ResetStyles from './ResetStyles';
-import IndicatorsContainer from './IndicatorsContainer';
-import NoOptionsMessage from './NoOptionsMessage';
 
 export interface Team {
   id: number;
@@ -45,6 +41,7 @@ export class TeamPicker extends Component<Props, State> {
       const teams = result.teams.map(team => {
         return {
           id: team.id,
+          value: team.id,
           label: team.name,
           name: team.name,
           imgUrl: team.avatarUrl,
@@ -62,24 +59,13 @@ export class TeamPicker extends Component<Props, State> {
     return (
       <div className="user-picker">
         <AsyncSelect
-          classNamePrefix={`gf-form-select-box`}
-          isMulti={false}
           isLoading={isLoading}
           defaultOptions={true}
           loadOptions={this.debouncedSearch}
           onChange={onSelected}
-          className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-          styles={ResetStyles}
-          components={{
-            Option: PickerOption,
-            IndicatorsContainer,
-            NoOptionsMessage,
-          }}
+          className={className}
           placeholder="Select a team"
-          loadingMessage={() => 'Loading...'}
           noOptionsMessage={() => 'No teams found'}
-          getOptionValue={i => i.id}
-          getOptionLabel={i => i.label}
         />
       </div>
     );

+ 51 - 0
public/app/core/components/Select/UnitPicker.tsx

@@ -0,0 +1,51 @@
+import React, { PureComponent } from 'react';
+import Select from './Select';
+import kbn from 'app/core/utils/kbn';
+
+interface Props {
+  onChange: (item: any) => {} | void;
+  defaultValue?: string;
+  width?: number;
+}
+
+export default class UnitPicker extends PureComponent<Props> {
+  static defaultProps = {
+    width: 12,
+  };
+
+  render() {
+    const { defaultValue, onChange, width } = this.props;
+
+    const unitGroups = kbn.getUnitFormats();
+
+    // Need to transform the data structure to work well with Select
+    const groupOptions = unitGroups.map(group => {
+      const options = group.submenu.map(unit => {
+        return {
+          label: unit.text,
+          value: unit.value,
+        };
+      });
+
+      return {
+        label: group.text,
+        options,
+      };
+    });
+
+    const value = groupOptions.map(group => {
+      return group.options.find(option => option.value === defaultValue);
+    });
+
+    return (
+      <Select
+        width={width}
+        defaultValue={value}
+        isSearchable={true}
+        options={groupOptions}
+        placeholder="Choose"
+        onChange={onChange}
+      />
+    );
+  }
+}

+ 0 - 0
public/app/core/components/Picker/UserPicker.test.tsx → public/app/core/components/Select/UserPicker.test.tsx


+ 10 - 17
public/app/core/components/Picker/UserPicker.tsx → public/app/core/components/Select/UserPicker.tsx

@@ -1,12 +1,15 @@
+// Libraries
 import React, { Component } from 'react';
-import AsyncSelect from 'react-select/lib/Async';
-import PickerOption from './PickerOption';
+
+// Components
+import { AsyncSelect } from './Select';
+
+// Utils & Services
 import { debounce } from 'lodash';
 import { getBackendSrv } from 'app/core/services/backend_srv';
+
+// Types
 import { User } from 'app/types';
-import ResetStyles from './ResetStyles';
-import IndicatorsContainer from './IndicatorsContainer';
-import NoOptionsMessage from './NoOptionsMessage';
 
 export interface Props {
   onSelected: (user: User) => void;
@@ -40,6 +43,7 @@ export class UserPicker extends Component<Props, State> {
       .then(result => {
         return result.map(user => ({
           id: user.userId,
+          value: user.userId,
           label: user.login === user.email ? user.login : `${user.login} - ${user.email}`,
           imgUrl: user.avatarUrl,
           login: user.login,
@@ -57,24 +61,13 @@ export class UserPicker extends Component<Props, State> {
     return (
       <div className="user-picker">
         <AsyncSelect
-          classNamePrefix={`gf-form-select-box`}
-          isMulti={false}
+          className={className}
           isLoading={isLoading}
           defaultOptions={true}
           loadOptions={this.debouncedSearch}
           onChange={onSelected}
-          className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-          styles={ResetStyles}
-          components={{
-            Option: PickerOption,
-            IndicatorsContainer,
-            NoOptionsMessage,
-          }}
           placeholder="Select user"
-          loadingMessage={() => 'Loading...'}
           noOptionsMessage={() => 'No users found'}
-          getOptionValue={i => i.id}
-          getOptionLabel={i => i.label}
         />
       </div>
     );

+ 0 - 0
public/app/core/components/Picker/__snapshots__/PickerOption.test.tsx.snap → public/app/core/components/Select/__snapshots__/PickerOption.test.tsx.snap


+ 0 - 29
public/app/core/components/Picker/__snapshots__/TeamPicker.test.tsx.snap → public/app/core/components/Select/__snapshots__/TeamPicker.test.tsx.snap

@@ -57,35 +57,6 @@ exports[`TeamPicker renders correctly 1`] = `
                 }
               }
               tabIndex="0"
-              theme={
-                Object {
-                  "borderRadius": 4,
-                  "colors": Object {
-                    "danger": "#DE350B",
-                    "dangerLight": "#FFBDAD",
-                    "neutral0": "hsl(0, 0%, 100%)",
-                    "neutral10": "hsl(0, 0%, 90%)",
-                    "neutral20": "hsl(0, 0%, 80%)",
-                    "neutral30": "hsl(0, 0%, 70%)",
-                    "neutral40": "hsl(0, 0%, 60%)",
-                    "neutral5": "hsl(0, 0%, 95%)",
-                    "neutral50": "hsl(0, 0%, 50%)",
-                    "neutral60": "hsl(0, 0%, 40%)",
-                    "neutral70": "hsl(0, 0%, 30%)",
-                    "neutral80": "hsl(0, 0%, 20%)",
-                    "neutral90": "hsl(0, 0%, 10%)",
-                    "primary": "#2684FF",
-                    "primary25": "#DEEBFF",
-                    "primary50": "#B2D4FF",
-                    "primary75": "#4C9AFF",
-                  },
-                  "spacing": Object {
-                    "baseUnit": 4,
-                    "controlHeight": 38,
-                    "menuGutter": 8,
-                  },
-                }
-              }
               type="text"
               value=""
             />

+ 0 - 29
public/app/core/components/Picker/__snapshots__/UserPicker.test.tsx.snap → public/app/core/components/Select/__snapshots__/UserPicker.test.tsx.snap

@@ -57,35 +57,6 @@ exports[`UserPicker renders correctly 1`] = `
                 }
               }
               tabIndex="0"
-              theme={
-                Object {
-                  "borderRadius": 4,
-                  "colors": Object {
-                    "danger": "#DE350B",
-                    "dangerLight": "#FFBDAD",
-                    "neutral0": "hsl(0, 0%, 100%)",
-                    "neutral10": "hsl(0, 0%, 90%)",
-                    "neutral20": "hsl(0, 0%, 80%)",
-                    "neutral30": "hsl(0, 0%, 70%)",
-                    "neutral40": "hsl(0, 0%, 60%)",
-                    "neutral5": "hsl(0, 0%, 95%)",
-                    "neutral50": "hsl(0, 0%, 50%)",
-                    "neutral60": "hsl(0, 0%, 40%)",
-                    "neutral70": "hsl(0, 0%, 30%)",
-                    "neutral80": "hsl(0, 0%, 20%)",
-                    "neutral90": "hsl(0, 0%, 10%)",
-                    "primary": "#2684FF",
-                    "primary25": "#DEEBFF",
-                    "primary50": "#B2D4FF",
-                    "primary75": "#4C9AFF",
-                  },
-                  "spacing": Object {
-                    "baseUnit": 4,
-                    "controlHeight": 38,
-                    "menuGutter": 8,
-                  },
-                }
-              }
               type="text"
               value=""
             />

+ 13 - 15
public/app/core/components/SharedPreferences/SharedPreferences.tsx

@@ -1,7 +1,7 @@
 import React, { PureComponent } from 'react';
 
 import { Label } from 'app/core/components/Label/Label';
-import SimplePicker from 'app/core/components/Picker/SimplePicker';
+import Select from 'app/core/components/Select/Select';
 import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
 
 import { DashboardSearchHit } from 'app/types';
@@ -17,12 +17,12 @@ export interface State {
   dashboards: DashboardSearchHit[];
 }
 
-const themes = [{ value: '', text: 'Default' }, { value: 'dark', text: 'Dark' }, { value: 'light', text: 'Light' }];
+const themes = [{ value: '', label: 'Default' }, { value: 'dark', label: 'Dark' }, { value: 'light', label: 'Light' }];
 
 const timezones = [
-  { value: '', text: 'Default' },
-  { value: 'browser', text: 'Local browser time' },
-  { value: 'utc', text: 'UTC' },
+  { value: '', label: 'Default' },
+  { value: 'browser', label: 'Local browser time' },
+  { value: 'utc', label: 'UTC' },
 ];
 
 export class SharedPreferences extends PureComponent<Props, State> {
@@ -91,12 +91,11 @@ export class SharedPreferences extends PureComponent<Props, State> {
         <h3 className="page-heading">Preferences</h3>
         <div className="gf-form">
           <span className="gf-form-label width-11">UI Theme</span>
-          <SimplePicker
+          <Select
+            isSearchable={false}
             value={themes.find(item => item.value === theme)}
             options={themes}
-            getOptionValue={i => i.value}
-            getOptionLabel={i => i.text}
-            onSelected={theme => this.onThemeChanged(theme.value)}
+            onChange={theme => this.onThemeChanged(theme.value)}
             width={20}
           />
         </div>
@@ -107,11 +106,11 @@ export class SharedPreferences extends PureComponent<Props, State> {
           >
             Home Dashboard
           </Label>
-          <SimplePicker
+          <Select
             value={dashboards.find(dashboard => dashboard.id === homeDashboardId)}
             getOptionValue={i => i.id}
             getOptionLabel={i => i.title}
-            onSelected={(dashboard: DashboardSearchHit) => this.onHomeDashboardChanged(dashboard.id)}
+            onChange={(dashboard: DashboardSearchHit) => this.onHomeDashboardChanged(dashboard.id)}
             options={dashboards}
             placeholder="Chose default dashboard"
             width={20}
@@ -119,11 +118,10 @@ export class SharedPreferences extends PureComponent<Props, State> {
         </div>
         <div className="gf-form">
           <label className="gf-form-label width-11">Timezone</label>
-          <SimplePicker
+          <Select
+            isSearchable={false}
             value={timezones.find(item => item.value === timezone)}
-            getOptionValue={i => i.value}
-            getOptionLabel={i => i.text}
-            onSelected={timezone => this.onTimeZoneChanged(timezone.value)}
+            onChange={timezone => this.onTimeZoneChanged(timezone.value)}
             options={timezones}
             width={20}
           />

+ 10 - 5
public/app/core/components/TagFilter/TagFilter.tsx

@@ -1,11 +1,12 @@
 import React from 'react';
-import AsyncSelect from 'react-select/lib/Async';
+import AsyncSelect from '@torkelo/react-select/lib/Async';
+
 import { TagOption } from './TagOption';
 import { TagBadge } from './TagBadge';
-import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
-import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
-import { components } from 'react-select';
-import ResetStyles from 'app/core/components/Picker/ResetStyles';
+import IndicatorsContainer from 'app/core/components/Select/IndicatorsContainer';
+import NoOptionsMessage from 'app/core/components/Select/NoOptionsMessage';
+import { components } from '@torkelo/react-select';
+import ResetStyles from 'app/core/components/Select/ResetStyles';
 
 export interface Props {
   tags: string[];
@@ -51,6 +52,10 @@ export class TagFilter extends React.Component<Props, any> {
       getOptionLabel: i => i.label,
       value: tags,
       styles: ResetStyles,
+      filterOption: (option, searchQuery) => {
+        const regex = RegExp(searchQuery, 'i');
+        return regex.test(option.value);
+      },
       components: {
         Option: TagOption,
         IndicatorsContainer,

+ 1 - 1
public/app/core/components/TagFilter/TagOption.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { components } from 'react-select';
+import { components } from '@torkelo/react-select';
 import { OptionProps } from 'react-select/lib/components/Option';
 import { TagBadge } from './TagBadge';
 

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

@@ -84,7 +84,7 @@ function link(scope, elem, attrs) {
   // disable depreacation warning
   codeEditor.$blockScrolling = Infinity;
   // Padding hacks
-  (codeEditor.renderer as any).setScrollMargin(15, 15);
+  (codeEditor.renderer as any).setScrollMargin(10, 10);
   codeEditor.renderer.setPadding(10);
 
   setThemeMode();

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

@@ -12,7 +12,7 @@ export function dropdownTypeahead($compile) {
   const buttonTemplate =
     '<a class="gf-form-label tight-form-func dropdown-toggle"' +
     ' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
-    ' data-placement="top"><i class="fa fa-plus"></i></a>';
+    ' ><i class="fa fa-plus"></i></a>';
 
   return {
     scope: {
@@ -130,7 +130,7 @@ export function dropdownTypeahead2($compile) {
   const buttonTemplate =
     '<a class="gf-form-input dropdown-toggle"' +
     ' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
-    ' data-placement="top"><i class="fa fa-plus"></i></a>';
+    ' ><i class="fa fa-plus"></i></a>';
 
   return {
     scope: {

+ 45 - 7
public/app/core/logs_model.ts

@@ -108,11 +108,21 @@ export interface LogsParser {
    * Used to filter rows, and first capture group contains the value.
    */
   buildMatcher: (label: string) => RegExp;
+
+  /**
+   * Returns all parsable substrings from a line, used for highlighting
+   */
+  getFields: (line: string) => string[];
+
+  /**
+   * Gets the label name from a parsable substring of a line
+   */
+  getLabelFromField: (field: string) => string;
+
   /**
-   * Regex to find a field in the log line.
-   * First capture group contains the label value, second capture group the value.
+   * Gets the label value from a parsable substring of a line
    */
-  fieldRegex: RegExp;
+  getValueFromField: (field: string) => string;
   /**
    * Function to verify if this is a valid parser for the given line.
    * The parser accepts the line unless it returns undefined.
@@ -120,20 +130,48 @@ export interface LogsParser {
   test: (line: string) => any;
 }
 
+const LOGFMT_REGEXP = /(?:^|\s)(\w+)=("[^"]*"|\S+)/;
+
 export const LogsParsers: { [name: string]: LogsParser } = {
   JSON: {
-    buildMatcher: label => new RegExp(`(?:{|,)\\s*"${label}"\\s*:\\s*"([^"]*)"`),
-    fieldRegex: /"(\w+)"\s*:\s*"([^"]*)"/,
+    buildMatcher: label => new RegExp(`(?:{|,)\\s*"${label}"\\s*:\\s*"?([\\d\\.]+|[^"]*)"?`),
+    getFields: line => {
+      const fields = [];
+      try {
+        const parsed = JSON.parse(line);
+        _.map(parsed, (value, key) => {
+          const fieldMatcher = new RegExp(`"${key}"\\s*:\\s*"?${_.escapeRegExp(JSON.stringify(value))}"?`);
+
+          const match = line.match(fieldMatcher);
+          if (match) {
+            fields.push(match[0]);
+          }
+        });
+      } catch {}
+      return fields;
+    },
+    getLabelFromField: field => (field.match(/^"(\w+)"\s*:/) || [])[1],
+    getValueFromField: field => (field.match(/:\s*(.*)$/) || [])[1],
     test: line => {
       try {
         return JSON.parse(line);
       } catch (error) {}
     },
   },
+
   logfmt: {
     buildMatcher: label => new RegExp(`(?:^|\\s)${label}=("[^"]*"|\\S+)`),
-    fieldRegex: /(?:^|\s)(\w+)=("[^"]*"|\S+)/,
-    test: line => LogsParsers.logfmt.fieldRegex.test(line),
+    getFields: line => {
+      const fields = [];
+      line.replace(new RegExp(LOGFMT_REGEXP, 'g'), substring => {
+        fields.push(substring.trim());
+        return '';
+      });
+      return fields;
+    },
+    getLabelFromField: field => (field.match(LOGFMT_REGEXP) || [])[1],
+    getValueFromField: field => (field.match(LOGFMT_REGEXP) || [])[2],
+    test: line => LOGFMT_REGEXP.test(line),
   },
 };
 

+ 34 - 11
public/app/core/specs/logs_model.test.ts

@@ -240,11 +240,16 @@ describe('LogsParsers', () => {
       expect(parser.test('foo=bar')).toBeTruthy();
     });
 
-    test('should have a valid fieldRegex', () => {
-      const match = 'foo=bar'.match(parser.fieldRegex);
-      expect(match).toBeDefined();
-      expect(match[1]).toBe('foo');
-      expect(match[2]).toBe('bar');
+    test('should return parsed fields', () => {
+      expect(parser.getFields('foo=bar baz="42 + 1"')).toEqual(['foo=bar', 'baz="42 + 1"']);
+    });
+
+    test('should return label for field', () => {
+      expect(parser.getLabelFromField('foo=bar')).toBe('foo');
+    });
+
+    test('should return value for field', () => {
+      expect(parser.getValueFromField('foo=bar')).toBe('bar');
     });
 
     test('should build a valid value matcher', () => {
@@ -263,18 +268,36 @@ describe('LogsParsers', () => {
       expect(parser.test('{"foo":"bar"}')).toBeTruthy();
     });
 
-    test('should have a valid fieldRegex', () => {
-      const match = '{"foo":"bar"}'.match(parser.fieldRegex);
-      expect(match).toBeDefined();
-      expect(match[1]).toBe('foo');
-      expect(match[2]).toBe('bar');
+    test('should return parsed fields', () => {
+      expect(parser.getFields('{ "foo" : "bar", "baz" : 42 }')).toEqual(['"foo" : "bar"', '"baz" : 42']);
     });
 
-    test('should build a valid value matcher', () => {
+    test('should return parsed fields for nested quotes', () => {
+      expect(parser.getFields(`{"foo":"bar: '[value=\\"42\\"]'"}`)).toEqual([`"foo":"bar: '[value=\\"42\\"]'"`]);
+    });
+
+    test('should return label for field', () => {
+      expect(parser.getLabelFromField('"foo" : "bar"')).toBe('foo');
+    });
+
+    test('should return value for field', () => {
+      expect(parser.getValueFromField('"foo" : "bar"')).toBe('"bar"');
+      expect(parser.getValueFromField('"foo" : 42')).toBe('42');
+      expect(parser.getValueFromField('"foo" : 42.1')).toBe('42.1');
+    });
+
+    test('should build a valid value matcher for strings', () => {
       const matcher = parser.buildMatcher('foo');
       const match = '{"foo":"bar"}'.match(matcher);
       expect(match).toBeDefined();
       expect(match[1]).toBe('bar');
     });
+
+    test('should build a valid value matcher for integers', () => {
+      const matcher = parser.buildMatcher('foo');
+      const match = '{"foo":42.1}'.match(matcher);
+      expect(match).toBeDefined();
+      expect(match[1]).toBe('42.1');
+    });
   });
 });

+ 7 - 5
public/app/features/alerting/partials/alert_tab.html

@@ -1,5 +1,5 @@
-<div class="panel-option-section__body">
-	<div class="edit-tab-with-sidemenu" ng-if="ctrl.alert">
+<div class="panel-option-section__body" ng-if="ctrl.alert">
+	<div class="edit-tab-with-sidemenu">
 		<aside class="edit-sidemenu-aside">
 			<ul class="edit-sidemenu">
 				<li ng-class="{active: ctrl.subTabIndex === 0}">
@@ -177,10 +177,12 @@
 			</div>
 		</div>
 	</div>
+</div>
 
-	<div class="gf-form-group" ng-if="!ctrl.alert">
-		<div class="gf-form-button-row">
-			<button class="btn btn-inverse" ng-click="ctrl.enable()">
+<div class="gf-form-group p-t-4 p-b-4" ng-if="!ctrl.alert">
+	<div class="empty-list-cta">
+		<div class="empty-list-cta__title">Panel has no alert rule defined</div>
+			<button class="empty-list-cta__button btn btn-xlarge btn-success" ng-click="ctrl.enable()">
 				<i class="icon-gf icon-gf-alert"></i>
 				Create Alert
 			</button>

+ 71 - 168
public/app/features/dashboard/dashgrid/AddPanelPanel.tsx

@@ -1,13 +1,12 @@
 import React from 'react';
 import _ from 'lodash';
-import classNames from 'classnames';
 import config from 'app/core/config';
 import { PanelModel } from '../panel_model';
 import { DashboardModel } from '../dashboard_model';
-import ScrollBar from 'app/core/components/ScrollBar/ScrollBar';
 import store from 'app/core/store';
 import { LS_PANEL_COPY_KEY } from 'app/core/constants';
-import Highlighter from 'react-highlight-words';
+import { updateLocation } from 'app/core/actions';
+import { store as reduxStore } from 'app/store/store';
 
 export interface AddPanelPanelProps {
   panel: PanelModel;
@@ -15,64 +14,25 @@ export interface AddPanelPanelProps {
 }
 
 export interface AddPanelPanelState {
-  filter: string;
-  panelPlugins: any[];
   copiedPanelPlugins: any[];
-  tab: string;
 }
 
 export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelPanelState> {
-  private scrollbar: ScrollBar;
-
   constructor(props) {
     super(props);
     this.handleCloseAddPanel = this.handleCloseAddPanel.bind(this);
-    this.renderPanelItem = this.renderPanelItem.bind(this);
-    this.panelSizeChanged = this.panelSizeChanged.bind(this);
 
     this.state = {
-      panelPlugins: this.getPanelPlugins(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
-      filter: '',
-      tab: 'Add',
+      copiedPanelPlugins: this.getCopiedPanelPlugins(),
     };
   }
 
-  componentDidMount() {
-    this.props.panel.events.on('panel-size-changed', this.panelSizeChanged);
-  }
-
-  componentWillUnmount() {
-    this.props.panel.events.off('panel-size-changed', this.panelSizeChanged);
-  }
-
-  panelSizeChanged() {
-    setTimeout(() => {
-      this.scrollbar.update();
-    });
-  }
-
-  getPanelPlugins(filter) {
-    let panels = _.chain(config.panels)
-      .filter({ hideFromList: false })
-      .map(item => item)
-      .value();
-
-    // add special row type
-    panels.push({ id: 'row', name: 'Row', sort: 8, info: { logos: { small: 'public/img/icn-row.svg' } } });
-
-    panels = this.filterPanels(panels, filter);
-
-    // add sort by sort property
-    return _.sortBy(panels, 'sort');
-  }
-
-  getCopiedPanelPlugins(filter) {
+  getCopiedPanelPlugins() {
     const panels = _.chain(config.panels)
       .filter({ hideFromList: false })
       .map(item => item)
       .value();
-    let copiedPanels = [];
+    const copiedPanels = [];
 
     const copiedPanelJson = store.get(LS_PANEL_COPY_KEY);
     if (copiedPanelJson) {
@@ -86,32 +46,64 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
         copiedPanels.push(pluginCopy);
       }
     }
+    return _.sortBy(copiedPanels, 'sort');
+  }
 
-    copiedPanels = this.filterPanels(copiedPanels, filter);
+  handleCloseAddPanel(evt) {
+    evt.preventDefault();
+    this.props.dashboard.removePanel(this.props.dashboard.panels[0]);
+  }
 
-    return _.sortBy(copiedPanels, 'sort');
+  copyButton(panel) {
+    return (
+      <button className="btn-inverse btn" onClick={() => this.onPasteCopiedPanel(panel)} title={panel.name}>
+        Paste copied Panel
+      </button>
+    );
   }
 
-  onAddPanel = panelPluginInfo => {
+  moveToEdit(panel) {
+    reduxStore.dispatch(
+      updateLocation({
+        query: {
+          panelId: panel.id,
+          edit: true,
+          fullscreen: true,
+        },
+        partial: true,
+      })
+    );
+  }
+
+  onCreateNewPanel = () => {
     const dashboard = this.props.dashboard;
     const { gridPos } = this.props.panel;
 
     const newPanel: any = {
-      type: panelPluginInfo.id,
+      type: 'graph',
       title: 'Panel Title',
       gridPos: { x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h },
     };
 
-    if (panelPluginInfo.id === 'row') {
-      newPanel.title = 'Row title';
-      newPanel.gridPos = { x: 0, y: 0 };
-    }
+    dashboard.addPanel(newPanel);
+    dashboard.removePanel(this.props.panel);
+
+    this.moveToEdit(newPanel);
+  };
+
+  onPasteCopiedPanel = panelPluginInfo => {
+    const dashboard = this.props.dashboard;
+    const { gridPos } = this.props.panel;
+
+    const newPanel: any = {
+      type: panelPluginInfo.id,
+      title: 'Panel Title',
+      gridPos: { x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h },
+    };
 
     // apply panel template / defaults
     if (panelPluginInfo.defaults) {
       _.defaults(newPanel, panelPluginInfo.defaults);
-      newPanel.gridPos.w = panelPluginInfo.defaults.gridPos.w;
-      newPanel.gridPos.h = panelPluginInfo.defaults.gridPos.h;
       newPanel.title = panelPluginInfo.defaults.title;
       store.delete(LS_PANEL_COPY_KEY);
     }
@@ -120,133 +112,44 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     dashboard.removePanel(this.props.panel);
   };
 
-  handleCloseAddPanel(evt) {
-    evt.preventDefault();
-    this.props.dashboard.removePanel(this.props.dashboard.panels[0]);
-  }
-
-  renderText(text: string) {
-    const searchWords = this.state.filter.split('');
-    return <Highlighter highlightClassName="highlight-search-match" textToHighlight={text} searchWords={searchWords} />;
-  }
-
-  renderPanelItem(panel, index) {
-    return (
-      <div key={index} className="add-panel__item" onClick={() => this.onAddPanel(panel)} title={panel.name}>
-        <img className="add-panel__item-img" src={panel.info.logos.small} />
-        <div className="add-panel__item-name">{this.renderText(panel.name)}</div>
-      </div>
-    );
-  }
-
-  noCopiedPanelPlugins() {
-    return <div className="add-panel__no-panels">No copied panels yet.</div>;
-  }
-
-  filterChange(evt) {
-    this.setState({
-      filter: evt.target.value,
-      panelPlugins: this.getPanelPlugins(evt.target.value),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value),
-    });
-  }
-
-  filterKeyPress(evt) {
-    if (evt.key === 'Enter') {
-      const panel = _.head(this.state.panelPlugins);
-      if (panel) {
-        this.onAddPanel(panel);
-      }
-    }
-  }
-
-  filterPanels(panels, filter) {
-    const regex = new RegExp(filter, 'i');
-    return panels.filter(panel => {
-      return regex.test(panel.name);
-    });
-  }
+  onCreateNewRow = () => {
+    const dashboard = this.props.dashboard;
 
-  openCopy() {
-    this.setState({
-      tab: 'Copy',
-      filter: '',
-      panelPlugins: this.getPanelPlugins(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
-    });
-  }
+    const newRow: any = {
+      type: 'row',
+      title: 'Row title',
+      gridPos: { x: 0, y: 0 },
+    };
 
-  openAdd() {
-    this.setState({
-      tab: 'Add',
-      filter: '',
-      panelPlugins: this.getPanelPlugins(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
-    });
-  }
+    dashboard.addPanel(newRow);
+    dashboard.removePanel(this.props.panel);
+  };
 
   render() {
-    const addClass = classNames({
-      'active active--panel': this.state.tab === 'Add',
-      '': this.state.tab === 'Copy',
-    });
-
-    const copyClass = classNames({
-      '': this.state.tab === 'Add',
-      'active active--panel': this.state.tab === 'Copy',
-    });
-
-    let panelTab;
-
-    if (this.state.tab === 'Add') {
-      panelTab = this.state.panelPlugins.map(this.renderPanelItem);
-    } else if (this.state.tab === 'Copy') {
-      if (this.state.copiedPanelPlugins.length > 0) {
-        panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem);
-      } else {
-        panelTab = this.noCopiedPanelPlugins();
-      }
+    let addCopyButton;
+
+    if (this.state.copiedPanelPlugins.length === 1) {
+      addCopyButton = this.copyButton(this.state.copiedPanelPlugins[0]);
     }
 
     return (
       <div className="panel-container add-panel-container">
         <div className="add-panel">
-          <div className="add-panel__header">
+          <div className="add-panel__header grid-drag-handle">
             <i className="gicon gicon-add-panel" />
-            <span className="add-panel__title">New Panel</span>
-            <ul className="gf-tabs">
-              <li className="gf-tabs-item">
-                <div className={'gf-tabs-link pointer ' + addClass} onClick={this.openAdd.bind(this)}>
-                  Add
-                </div>
-              </li>
-              <li className="gf-tabs-item">
-                <div className={'gf-tabs-link pointer ' + copyClass} onClick={this.openCopy.bind(this)}>
-                  Paste
-                </div>
-              </li>
-            </ul>
             <button className="add-panel__close" onClick={this.handleCloseAddPanel}>
               <i className="fa fa-close" />
             </button>
           </div>
-          <ScrollBar ref={element => (this.scrollbar = element)} className="add-panel__items">
-            <div className="add-panel__searchbar">
-              <label className="gf-form gf-form--grow gf-form--has-input-icon">
-                <input
-                  type="text"
-                  autoFocus
-                  className="gf-form-input gf-form--grow"
-                  placeholder="Panel Search Filter"
-                  value={this.state.filter}
-                  onChange={this.filterChange.bind(this)}
-                  onKeyPress={this.filterKeyPress.bind(this)}
-                />
-                <i className="gf-form-input-icon fa fa-search" />
-              </label>
-            </div>
-            {panelTab}
-          </ScrollBar>
+          <div className="add-panel-btn-container">
+            <button className="btn-success btn btn-large" onClick={this.onCreateNewPanel}>
+              Edit Panel
+            </button>
+            {addCopyButton}
+            <button className="btn-inverse btn" onClick={this.onCreateNewRow}>
+              Add Row
+            </button>
+          </div>
         </div>
       </div>
     );

+ 4 - 12
public/app/features/dashboard/dashgrid/DashboardGrid.tsx

@@ -45,7 +45,7 @@ function GridWrapper({
       isResizable={isResizable}
       measureBeforeMount={false}
       containerPadding={[0, 0]}
-      useCSSTransforms={true}
+      useCSSTransforms={false}
       margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
       cols={GRID_COLUMN_COUNT}
       rowHeight={GRID_CELL_HEIGHT}
@@ -67,7 +67,7 @@ export interface DashboardGridProps {
   dashboard: DashboardModel;
 }
 
-export class DashboardGrid extends React.Component<DashboardGridProps, any> {
+export class DashboardGrid extends React.Component<DashboardGridProps> {
   gridToPanelMap: any;
   panelMap: { [id: string]: PanelModel };
 
@@ -79,8 +79,6 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     this.onDragStop = this.onDragStop.bind(this);
     this.onWidthChange = this.onWidthChange.bind(this);
 
-    this.state = { animated: false };
-
     // subscribe to dashboard events
     const dashboard = this.props.dashboard;
     dashboard.on('panel-added', this.triggerForceUpdate.bind(this));
@@ -145,7 +143,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
 
   onViewModeChanged(payload) {
     ignoreNextWidthChange = true;
-    this.setState({ animated: !payload.fullscreen });
+    this.forceUpdate();
   }
 
   updateGridPos(item, layout) {
@@ -169,12 +167,6 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     this.updateGridPos(newItem, layout);
   }
 
-  componentDidMount() {
-    setTimeout(() => {
-      this.setState({ animated: true });
-    });
-  }
-
   renderPanels() {
     const panelElements = [];
 
@@ -198,7 +190,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
   render() {
     return (
       <SizedReactLayoutGrid
-        className={classNames({ layout: true, animated: this.state.animated })}
+        className={classNames({ layout: true })}
         layout={this.buildLayout()}
         isResizable={this.props.dashboard.meta.canEdit}
         isDraggable={this.props.dashboard.meta.canEdit}

+ 17 - 5
public/app/features/dashboard/dashgrid/PanelEditor.tsx

@@ -53,7 +53,7 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
         return <GeneralTab panel={panel} />;
       case 'queries':
         return <QueriesTab panel={panel} dashboard={dashboard} />;
-      case 'alerts':
+      case 'alert':
         return <AlertTab angularPanel={angularPanel} />;
       case 'visualization':
         return (
@@ -72,18 +72,30 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
 
   render() {
     const { plugin } = this.props;
-    const activeTab = store.getState().location.query.tab || 'queries';
+    let activeTab = store.getState().location.query.tab || 'queries';
 
-    const tabs = [
+    const tabs: PanelEditorTab[] = [
       { id: 'queries', text: 'Queries' },
       { id: 'visualization', text: 'Visualization' },
       { id: 'advanced', text: 'Panel Options' },
     ];
 
+    // handle panels that do not have queries tab
+    if (plugin.exports.PanelCtrl) {
+      if (!plugin.exports.PanelCtrl.prototype.onDataReceived) {
+        // remove queries tab
+        tabs.shift();
+        // switch tab
+        if (activeTab === 'queries') {
+          activeTab = 'visualization';
+        }
+      }
+    }
+
     if (config.alertingEnabled && plugin.id === 'graph') {
       tabs.push({
-        id: 'alerts',
-        text: 'Alerts',
+        id: 'alert',
+        text: 'Alert',
       });
     }
 

+ 7 - 11
public/app/features/dashboard/dashgrid/QueriesTab.tsx

@@ -6,7 +6,7 @@ import _ from 'lodash';
 // Components
 import './../../panel/metrics_tab';
 import { EditorTabBody } from './EditorTabBody';
-import { DataSourcePicker } from './DataSourcePicker';
+import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
 import { QueryInspector } from './QueryInspector';
 import { QueryOptions } from './QueryOptions';
 import { AngularQueryComponentScope } from 'app/features/panel/metrics_tab';
@@ -205,20 +205,14 @@ export class QueriesTab extends PureComponent<Props, State> {
   renderToolbar = () => {
     const { currentDS } = this.state;
 
-    return (
-      <DataSourcePicker
-        datasources={this.datasources}
-        onChangeDataSource={this.onChangeDataSource}
-        current={currentDS}
-      />
-    );
+    return <DataSourcePicker datasources={this.datasources} onChange={this.onChangeDataSource} current={currentDS} />;
   };
 
   renderMixedPicker = () => {
     return (
       <DataSourcePicker
         datasources={this.datasources}
-        onChangeDataSource={this.onAddMixedQuery}
+        onChange={this.onAddMixedQuery}
         current={null}
         autoFocus={true}
         onBlur={this.onMixedPickerBlur}
@@ -258,7 +252,7 @@ export class QueriesTab extends PureComponent<Props, State> {
       <EditorTabBody heading="Queries" renderToolbar={this.renderToolbar} toolbarItems={[queryInspector, dsHelp]}>
         <>
           <PanelOptionSection>
-            <div className="query-editor-rows gf-form-group">
+            <div className="query-editor-rows">
               <div ref={element => (this.element = element)} />
 
               <div className="gf-form-query">
@@ -266,9 +260,11 @@ export class QueriesTab extends PureComponent<Props, State> {
                   <label className="gf-form-label">
                     <span className="gf-form-query-letter-cell-carret muted">
                       <i className="fa fa-caret-down" />
-                    </span>
+                    </span>{' '}
                     <span className="gf-form-query-letter-cell-letter">{panel.getNextQueryLetter()}</span>
                   </label>
+                </div>
+                <div className="gf-form">
                   {!isAddingMixed && (
                     <button className="btn btn-secondary gf-form-btn" onClick={this.onAddQueryClick}>
                       Add Query

+ 1 - 2
public/app/features/dashboard/dashgrid/VisualizationTab.tsx

@@ -174,8 +174,7 @@ export class VisualizationTab extends PureComponent<Props, State> {
             />
             <i className="gf-form-input-icon fa fa-search" />
           </label>
-          <div className="flex-grow" />
-          <button className="btn btn-link" onClick={this.onCloseVizPicker}>
+          <button className="btn btn-link toolbar__close" onClick={this.onCloseVizPicker}>
             <i className="fa fa-chevron-up" />
           </button>
         </>

+ 1 - 1
public/app/features/dashboard/dashnav/dashnav.ts

@@ -91,7 +91,7 @@ export class DashNavCtrl {
 
     this.dashboard.addPanel({
       type: 'add-panel',
-      gridPos: { x: 0, y: 0, w: 12, h: 9 },
+      gridPos: { x: 0, y: 0, w: 12, h: 8 },
       title: 'Panel Title',
     });
   }

+ 0 - 46
public/app/features/dashboard/specs/AddPanelPanel.test.tsx

@@ -1,46 +0,0 @@
-import React from 'react';
-import { AddPanelPanel } from './../dashgrid/AddPanelPanel';
-import { PanelModel } from '../panel_model';
-import { shallow } from 'enzyme';
-import config from '../../../core/config';
-import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks';
-
-jest.mock('app/core/store', () => ({
-  get: key => {
-    return null;
-  },
-  delete: key => {
-    return null;
-  },
-}));
-
-describe('AddPanelPanel', () => {
-  let wrapper, dashboardMock, panel;
-
-  beforeEach(() => {
-    config.panels = [
-      getPanelPlugin({ id: 'singlestat', sort: 2 }),
-      getPanelPlugin({ id: 'hidden', sort: 100, hideFromList: true }),
-      getPanelPlugin({ id: 'graph', sort: 1 }),
-      getPanelPlugin({ id: 'alexander_zabbix', sort: 100 }),
-      getPanelPlugin({ id: 'piechart', sort: 100 }),
-    ];
-
-    dashboardMock = { toggleRow: jest.fn() };
-
-    panel = new PanelModel({ collapsed: false });
-    wrapper = shallow(<AddPanelPanel panel={panel} dashboard={dashboardMock} />);
-  });
-
-  it('should fetch all panels sorted with core plugins first', () => {
-    expect(wrapper.find('.add-panel__item').get(1).props.title).toBe('singlestat');
-    expect(wrapper.find('.add-panel__item').get(4).props.title).toBe('piechart');
-  });
-
-  it('should filter', () => {
-    wrapper.find('input').simulate('change', { target: { value: 'p' } });
-
-    expect(wrapper.find('.add-panel__item').get(1).props.title).toBe('piechart');
-    expect(wrapper.find('.add-panel__item').get(0).props.title).toBe('graph');
-  });
-});

+ 1 - 1
public/app/features/datasources/state/actions.ts

@@ -191,7 +191,7 @@ export function deleteDataSource(): ThunkResult<void> {
 export function nameExits(dataSources, name) {
   return (
     dataSources.filter(dataSource => {
-      return dataSource.name === name;
+      return dataSource.name.toLowerCase() === name.toLowerCase();
     }).length > 0
   );
 }

+ 9 - 27
public/app/features/explore/Explore.tsx

@@ -1,6 +1,5 @@
 import React from 'react';
 import { hot } from 'react-hot-loader';
-import Select from 'react-select';
 import _ from 'lodash';
 
 import { DataSource } from 'app/types/datasources';
@@ -25,10 +24,7 @@ import {
   makeTimeSeriesList,
   updateHistory,
 } from 'app/core/utils/explore';
-import ResetStyles from 'app/core/components/Picker/ResetStyles';
-import PickerOption from 'app/core/components/Picker/PickerOption';
-import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
-import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
+import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
 import TableModel from 'app/core/table_model';
 import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
 import { Emitter } from 'app/core/utils/emitter';
@@ -158,10 +154,12 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
     if (!datasourceSrv) {
       throw new Error('No datasource service passed as props.');
     }
+
     const datasources = datasourceSrv.getExternal();
     const exploreDatasources = datasources.map(ds => ({
       value: ds.name,
-      label: ds.name,
+      name: ds.name,
+      meta: ds.meta,
     }));
 
     if (datasources.length > 0) {
@@ -885,7 +883,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
     } = this.state;
     const graphHeight = showingGraph && showingTable ? '200px' : '400px';
     const exploreClass = split ? 'explore explore-split' : 'explore';
-    const selectedDatasource = datasource ? exploreDatasources.find(d => d.label === datasource.name) : undefined;
+    const selectedDatasource = datasource ? exploreDatasources.find(d => d.name === datasource.name) : undefined;
     const graphLoading = queryTransactions.some(qt => qt.resultType === 'Graph' && !qt.done);
     const tableLoading = queryTransactions.some(qt => qt.resultType === 'Table' && !qt.done);
     const logsLoading = queryTransactions.some(qt => qt.resultType === 'Logs' && !qt.done);
@@ -910,26 +908,10 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
           )}
           {!datasourceMissing ? (
             <div className="navbar-buttons">
-              <Select
-                classNamePrefix={`gf-form-select-box`}
-                isMulti={false}
-                menuShouldScrollIntoView={false}
-                isLoading={datasourceLoading}
-                isClearable={false}
-                className="gf-form-input gf-form-input--form-dropdown datasource-picker"
+              <DataSourcePicker
                 onChange={this.onChangeDatasource}
-                options={exploreDatasources}
-                styles={ResetStyles}
-                maxMenuHeight={500}
-                placeholder="Select datasource"
-                loadingMessage={() => 'Loading datasources...'}
-                noOptionsMessage={() => 'No datasources found'}
-                value={selectedDatasource}
-                components={{
-                  Option: PickerOption,
-                  IndicatorsContainer,
-                  NoOptionsMessage,
-                }}
+                datasources={exploreDatasources}
+                current={selectedDatasource}
               />
             </div>
           ) : null}
@@ -948,7 +930,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
             </button>
           </div>
           <div className="navbar-buttons relative">
-            <button className="btn navbar-button--primary" onClick={this.onSubmit}>
+            <button className="btn navbar-button navbar-button--primary" onClick={this.onSubmit}>
               Run Query{' '}
               {loading ? <i className="fa fa-spinner fa-spin run-icon" /> : <i className="fa fa-level-down run-icon" />}
             </button>

+ 12 - 19
public/app/features/explore/Logs.tsx

@@ -73,7 +73,7 @@ interface RowState {
   fieldStats: LogsLabelStat[];
   fieldValue: string;
   parsed: boolean;
-  parser: LogsParser;
+  parser?: LogsParser;
   parsedFieldHighlights: string[];
   showFieldStats: boolean;
 }
@@ -94,7 +94,7 @@ class Row extends PureComponent<RowProps, RowState> {
     fieldStats: null,
     fieldValue: null,
     parsed: false,
-    parser: null,
+    parser: undefined,
     parsedFieldHighlights: [],
     showFieldStats: false,
   };
@@ -110,19 +110,16 @@ class Row extends PureComponent<RowProps, RowState> {
   onClickHighlight = (fieldText: string) => {
     const { getRows } = this.props;
     const { parser } = this.state;
+    const allRows = getRows();
 
-    const fieldMatch = fieldText.match(parser.fieldRegex);
-    if (fieldMatch) {
-      const allRows = getRows();
-      // Build value-agnostic row matcher based on the field label
-      const fieldLabel = fieldMatch[1];
-      const fieldValue = fieldMatch[2];
-      const matcher = parser.buildMatcher(fieldLabel);
-      const fieldStats = calculateFieldStats(allRows, matcher);
-      const fieldCount = fieldStats.reduce((sum, stat) => sum + stat.count, 0);
-
-      this.setState({ fieldCount, fieldLabel, fieldStats, fieldValue, showFieldStats: true });
-    }
+    // Build value-agnostic row matcher based on the field label
+    const fieldLabel = parser.getLabelFromField(fieldText);
+    const fieldValue = parser.getValueFromField(fieldText);
+    const matcher = parser.buildMatcher(fieldLabel);
+    const fieldStats = calculateFieldStats(allRows, matcher);
+    const fieldCount = fieldStats.reduce((sum, stat) => sum + stat.count, 0);
+
+    this.setState({ fieldCount, fieldLabel, fieldStats, fieldValue, showFieldStats: true });
   };
 
   onMouseOverMessage = () => {
@@ -141,11 +138,7 @@ class Row extends PureComponent<RowProps, RowState> {
       const parser = getParser(row.entry);
       if (parser) {
         // Use parser to highlight detected fields
-        const parsedFieldHighlights = [];
-        this.props.row.entry.replace(new RegExp(parser.fieldRegex, 'g'), substring => {
-          parsedFieldHighlights.push(substring.trim());
-          return '';
-        });
+        const parsedFieldHighlights = parser.getFields(this.props.row.entry);
         this.setState({ parsedFieldHighlights, parsed: true, parser });
       }
     }

+ 1 - 0
public/app/features/explore/QueryEditor.tsx

@@ -53,6 +53,7 @@ export default class QueryEditor extends PureComponent<QueryEditorProps, any> {
     };
 
     this.component = loader.load(this.element, scopeProps, template);
+    this.props.onQueryChange(target, false);
   }
 
   componentWillUnmount() {

+ 0 - 1
public/app/features/panel/all.ts

@@ -4,4 +4,3 @@ import './solo_panel_ctrl';
 import './query_ctrl';
 import './panel_editor_tab';
 import './query_editor_row';
-import './query_troubleshooter';

+ 0 - 28
public/app/features/panel/panel_header.ts

@@ -1,4 +1,3 @@
-import $ from 'jquery';
 import { coreModule } from 'app/core/core';
 
 const template = `
@@ -93,40 +92,13 @@ function panelHeader($compile) {
         }
       });
 
-      elem.find('.panel-menu-toggle').click(() => {
-        togglePanelStackPosition();
-      });
-
       function togglePanelMenu(e) {
         if (!isDragged) {
           e.stopPropagation();
-          togglePanelStackPosition();
           elem.find('[data-toggle=dropdown]').dropdown('toggle');
         }
       }
 
-      /**
-       * Hack for adding special class 'dropdown-menu-open' to the panel.
-       * This class sets z-index for panel and prevents menu overlapping.
-       */
-      function togglePanelStackPosition() {
-        const menuOpenClass = 'dropdown-menu-open';
-        const panelGridClass = '.react-grid-item.panel';
-
-        let panelElem = elem
-          .find('[data-toggle=dropdown]')
-          .parentsUntil('.panel')
-          .parent();
-        const menuElem = elem.find('[data-toggle=dropdown]').parent();
-        panelElem = panelElem && panelElem.length ? panelElem[0] : undefined;
-        if (panelElem) {
-          panelElem = $(panelElem);
-          $(panelGridClass).removeClass(menuOpenClass);
-          const state = !menuElem.hasClass('open');
-          panelElem.toggleClass(menuOpenClass, state);
-        }
-      }
-
       let mouseX, mouseY;
       elem.mousedown(e => {
         mouseX = e.pageX;

+ 0 - 188
public/app/features/panel/query_troubleshooter.ts

@@ -1,188 +0,0 @@
-import _ from 'lodash';
-import appEvents from 'app/core/app_events';
-import { coreModule, JsonExplorer } from 'app/core/core';
-
-const template = `
-<div class="query-troubleshooter" ng-if="ctrl.isOpen">
-  <div class="query-troubleshooter__header">
-    <a class="pointer" ng-click="ctrl.toggleMocking()">Mock Response</a>
-    <a class="pointer" ng-click="ctrl.toggleExpand()" ng-hide="ctrl.allNodesExpanded">
-      <i class="fa fa-plus-square-o"></i> Expand All
-    </a>
-    <a class="pointer" ng-click="ctrl.toggleExpand()" ng-show="ctrl.allNodesExpanded">
-      <i class="fa fa-minus-square-o"></i> Collapse All
-    </a>
-    <a class="pointer" clipboard-button="ctrl.getClipboardText()"><i class="fa fa-clipboard"></i> Copy to Clipboard</a>
-  </div>
-  <div class="query-troubleshooter__body" ng-hide="ctrl.isMocking">
-    <i class="fa fa-spinner fa-spin" ng-show="ctrl.isLoading"></i>
-    <div class="query-troubleshooter-json"></div>
-  </div>
-  <div class="query-troubleshooter__body" ng-show="ctrl.isMocking">
-    <div class="gf-form p-l-1 gf-form--v-stretch">
-			<textarea class="gf-form-input" style="width: 95%" rows="10" ng-model="ctrl.mockedResponse"  placeholder="JSON"></textarea>
-    </div>
-  </div>
-</div>
-`;
-
-export class QueryTroubleshooterCtrl {
-  isOpen: any;
-  isLoading: boolean;
-  showResponse: boolean;
-  panelCtrl: any;
-  renderJsonExplorer: (data) => void;
-  onRequestErrorEventListener: any;
-  onRequestResponseEventListener: any;
-  hasError: boolean;
-  allNodesExpanded: boolean;
-  isMocking: boolean;
-  mockedResponse: string;
-  jsonExplorer: JsonExplorer;
-
-  /** @ngInject */
-  constructor($scope, private $timeout) {
-    this.onRequestErrorEventListener = this.onRequestError.bind(this);
-    this.onRequestResponseEventListener = this.onRequestResponse.bind(this);
-
-    appEvents.on('ds-request-response', this.onRequestResponseEventListener);
-    appEvents.on('ds-request-error', this.onRequestErrorEventListener);
-
-    $scope.$on('$destroy', this.removeEventsListeners.bind(this));
-    $scope.$watch('ctrl.isOpen', this.stateChanged.bind(this));
-  }
-
-  removeEventsListeners() {
-    appEvents.off('ds-request-response', this.onRequestResponseEventListener);
-    appEvents.off('ds-request-error', this.onRequestErrorEventListener);
-  }
-
-  toggleMocking() {
-    this.isMocking = !this.isMocking;
-  }
-
-  onRequestError(err) {
-    // ignore if closed
-    if (!this.isOpen) {
-      return;
-    }
-
-    this.isOpen = true;
-    this.hasError = true;
-    this.onRequestResponse(err);
-  }
-
-  stateChanged() {
-    if (this.isOpen) {
-      this.panelCtrl.refresh();
-      this.isLoading = true;
-    }
-  }
-
-  getClipboardText(): string {
-    if (this.jsonExplorer) {
-      return JSON.stringify(this.jsonExplorer.json, null, 2);
-    }
-    return '';
-  }
-
-  handleMocking(data) {
-    let mockedData;
-    try {
-      mockedData = JSON.parse(this.mockedResponse);
-    } catch (err) {
-      appEvents.emit('alert-error', ['Failed to parse mocked response']);
-      return;
-    }
-
-    data.data = mockedData;
-  }
-
-  onRequestResponse(data) {
-    // ignore if closed
-    if (!this.isOpen) {
-      return;
-    }
-
-    if (this.isMocking) {
-      this.handleMocking(data);
-      return;
-    }
-
-    this.isLoading = false;
-    data = _.cloneDeep(data);
-
-    if (data.headers) {
-      delete data.headers;
-    }
-
-    if (data.config) {
-      data.request = data.config;
-      delete data.config;
-      delete data.request.transformRequest;
-      delete data.request.transformResponse;
-      delete data.request.paramSerializer;
-      delete data.request.jsonpCallbackParam;
-      delete data.request.headers;
-      delete data.request.requestId;
-      delete data.request.inspect;
-      delete data.request.retry;
-      delete data.request.timeout;
-    }
-
-    if (data.data) {
-      data.response = data.data;
-
-      if (data.status === 200) {
-        // if we are in error state, assume we automatically opened
-        // and auto close it again
-        if (this.hasError) {
-          this.hasError = false;
-          this.isOpen = false;
-        }
-      }
-
-      delete data.data;
-      delete data.status;
-      delete data.statusText;
-      delete data.$$config;
-    }
-
-    this.$timeout(_.partial(this.renderJsonExplorer, data));
-  }
-
-  toggleExpand(depth) {
-    if (this.jsonExplorer) {
-      this.allNodesExpanded = !this.allNodesExpanded;
-      this.jsonExplorer.openAtDepth(this.allNodesExpanded ? 20 : 1);
-    }
-  }
-}
-
-export function queryTroubleshooter() {
-  return {
-    restrict: 'E',
-    template: template,
-    controller: QueryTroubleshooterCtrl,
-    bindToController: true,
-    controllerAs: 'ctrl',
-    scope: {
-      panelCtrl: '=',
-      isOpen: '=',
-    },
-    link: (scope, elem, attrs, ctrl) => {
-      ctrl.renderJsonExplorer = data => {
-        const jsonElem = elem.find('.query-troubleshooter-json');
-
-        ctrl.jsonExplorer = new JsonExplorer(data, 3, {
-          animateOpen: true,
-        });
-
-        const html = ctrl.jsonExplorer.render(true);
-        jsonElem.html(html);
-      };
-    },
-  };
-}
-
-coreModule.directive('queryTroubleshooter', queryTroubleshooter);

+ 0 - 71
public/app/features/panel/viz_tab.ts

@@ -1,71 +0,0 @@
-import coreModule from 'app/core/core_module';
-import { DashboardModel } from '../dashboard/dashboard_model';
-import { VizTypePicker } from '../dashboard/dashgrid/VizTypePicker';
-import { react2AngularDirective } from 'app/core/utils/react2angular';
-import { PanelPlugin } from 'app/types/plugins';
-
-export class VizTabCtrl {
-  panelCtrl: any;
-  dashboard: DashboardModel;
-
-  /** @ngInject */
-  constructor($scope) {
-    this.panelCtrl = $scope.ctrl;
-    this.dashboard = this.panelCtrl.dashboard;
-
-    $scope.ctrl = this;
-  }
-
-  onTypeChanged = (plugin: PanelPlugin) => {};
-}
-
-const template = `
-<div class="gf-form-group ">
-  <div class="gf-form-query">
-    <div class="gf-form">
-      <label class="gf-form-label">
-        <img src="public/app/plugins/panel/graph/img/icn-graph-panel.svg" style="width: 16px; height: 16px" />
-        Graph
-        <i class="fa fa-caret-down" />
-      </label>
-		</div>
-
-		<div class="gf-form gf-form--grow">
-			<label class="gf-form-label gf-form-label--grow"></label>
-		</div>
-	</div>
-
-	<br />
-	<br />
-
-  <div class="query-editor-rows gf-form-group">
-	  <div ng-repeat="tab in ctrl.panelCtrl.optionTabs">
-	    <div class="gf-form-query">
-		    <div class="gf-form gf-form-query-letter-cell">
-			    <label class="gf-form-label">
-				    <span class="gf-form-query-letter-cell-carret">
-					    <i class="fa fa-caret-down"></i>
-				    </span>
-				    <span class="gf-form-query-letter-cell-letter">{{tab.title}}</span>
-          </label>
-			  </div>
-        <div class="gf-form gf-form--grow">
-			    <label class="gf-form-label gf-form-label--grow"></label>
-		    </div>
-			</div>
-		</div>
-	</div>
-</div>`;
-
-/** @ngInject */
-export function vizTabDirective() {
-  'use strict';
-  return {
-    restrict: 'E',
-    template: template,
-    controller: VizTabCtrl,
-  };
-}
-
-react2AngularDirective('vizTypePicker', VizTypePicker, ['currentType', ['onTypeChanged', { watchDepth: 'reference' }]]);
-coreModule.directive('vizTab', vizTabDirective);

+ 1 - 1
public/app/features/teams/TeamMembers.tsx

@@ -1,7 +1,7 @@
 import React, { PureComponent } from 'react';
 import { connect } from 'react-redux';
 import SlideDown from 'app/core/components/Animations/SlideDown';
-import { UserPicker } from 'app/core/components/Picker/UserPicker';
+import { UserPicker } from 'app/core/components/Select/UserPicker';
 import DeleteButton from 'app/core/components/DeleteButton/DeleteButton';
 import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
 import { TeamMember, User } from 'app/types';

+ 57 - 0
public/app/features/users/InviteeRow.tsx

@@ -0,0 +1,57 @@
+import React, { createRef, PureComponent } from 'react';
+import { connect } from 'react-redux';
+import { Invitee } from 'app/types';
+import { revokeInvite } from './state/actions';
+
+export interface Props {
+  invitee: Invitee;
+  revokeInvite: typeof revokeInvite;
+}
+
+class InviteeRow extends PureComponent<Props> {
+  private copyUrlRef = createRef<HTMLTextAreaElement>();
+
+  copyToClipboard = () => {
+    const node = this.copyUrlRef.current;
+
+    if (node) {
+      node.select();
+      document.execCommand('copy');
+    }
+  };
+
+  render() {
+    const { invitee, revokeInvite } = this.props;
+    return (
+      <tr>
+        <td>{invitee.email}</td>
+        <td>{invitee.name}</td>
+        <td className="text-right">
+          <button className="btn btn-inverse btn-mini" onClick={this.copyToClipboard}>
+            <textarea
+              readOnly={true}
+              value={invitee.url}
+              style={{ position: 'absolute', right: -1000 }}
+              ref={this.copyUrlRef}
+            />
+            <i className="fa fa-clipboard" /> Copy Invite
+          </button>
+          &nbsp;
+        </td>
+        <td>
+          <button className="btn btn-danger btn-mini" onClick={() => revokeInvite(invitee.code)}>
+            <i className="fa fa-remove" />
+          </button>
+        </td>
+      </tr>
+    );
+  }
+}
+
+const mapDispatchToProps = {
+  revokeInvite,
+};
+
+export default connect(() => {
+  return {};
+}, mapDispatchToProps)(InviteeRow);

+ 0 - 1
public/app/features/users/InviteesTable.test.tsx

@@ -7,7 +7,6 @@ import { getMockInvitees } from './__mocks__/userMocks';
 const setup = (propOverrides?: object) => {
   const props: Props = {
     invitees: [] as Invitee[],
-    onRevokeInvite: jest.fn(),
   };
 
   Object.assign(props, propOverrides);

+ 4 - 37
public/app/features/users/InviteesTable.tsx

@@ -1,25 +1,14 @@
-import React, { createRef, PureComponent } from 'react';
+import React, { PureComponent } from 'react';
 import { Invitee } from 'app/types';
+import InviteeRow from './InviteeRow';
 
 export interface Props {
   invitees: Invitee[];
-  onRevokeInvite: (code: string) => void;
 }
 
 export default class InviteesTable extends PureComponent<Props> {
-  private copyUrlRef = createRef<HTMLTextAreaElement>();
-
-  copyToClipboard = () => {
-    const node = this.copyUrlRef.current;
-
-    if (node) {
-      node.select();
-      document.execCommand('copy');
-    }
-  };
-
   render() {
-    const { invitees, onRevokeInvite } = this.props;
+    const { invitees } = this.props;
 
     return (
       <table className="filter-table form-inline">
@@ -33,29 +22,7 @@ export default class InviteesTable extends PureComponent<Props> {
         </thead>
         <tbody>
           {invitees.map((invitee, index) => {
-            return (
-              <tr key={`${invitee.id}-${index}`}>
-                <td>{invitee.email}</td>
-                <td>{invitee.name}</td>
-                <td className="text-right">
-                  <button className="btn btn-inverse btn-mini" onClick={this.copyToClipboard}>
-                    <textarea
-                      readOnly={true}
-                      value={invitee.url}
-                      style={{ position: 'absolute', right: -1000 }}
-                      ref={this.copyUrlRef}
-                    />
-                    <i className="fa fa-clipboard" /> Copy Invite
-                  </button>
-                  &nbsp;
-                </td>
-                <td>
-                  <button className="btn btn-danger btn-mini" onClick={() => onRevokeInvite(invitee.code)}>
-                    <i className="fa fa-remove" />
-                  </button>
-                </td>
-              </tr>
-            );
+            return <InviteeRow key={`${invitee.id}-${index}`} invitee={invitee} />;
           })}
         </tbody>
       </table>

+ 0 - 1
public/app/features/users/UsersListPage.test.tsx

@@ -16,7 +16,6 @@ const setup = (propOverrides?: object) => {
     invitees: [] as Invitee[],
     searchQuery: '',
     externalUserMngInfo: '',
-    revokeInvite: jest.fn(),
     loadInvitees: jest.fn(),
     loadUsers: jest.fn(),
     updateUser: jest.fn(),

+ 2 - 8
public/app/features/users/UsersListPage.tsx

@@ -9,7 +9,7 @@ import UsersTable from './UsersTable';
 import InviteesTable from './InviteesTable';
 import { Invitee, NavModel, OrgUser } from 'app/types';
 import appEvents from 'app/core/app_events';
-import { loadUsers, loadInvitees, revokeInvite, setUsersSearchQuery, updateUser, removeUser } from './state/actions';
+import { loadUsers, loadInvitees, setUsersSearchQuery, updateUser, removeUser } from './state/actions';
 import { getNavModel } from '../../core/selectors/navModel';
 import { getInvitees, getUsers, getUsersSearchQuery } from './state/selectors';
 
@@ -25,7 +25,6 @@ export interface Props {
   setUsersSearchQuery: typeof setUsersSearchQuery;
   updateUser: typeof updateUser;
   removeUser: typeof removeUser;
-  revokeInvite: typeof revokeInvite;
 }
 
 export interface State {
@@ -79,10 +78,6 @@ export class UsersListPage extends PureComponent<Props, State> {
     });
   };
 
-  onRevokeInvite = code => {
-    this.props.revokeInvite(code);
-  };
-
   onShowInvites = () => {
     this.setState(prevState => ({
       showInvites: !prevState.showInvites,
@@ -93,7 +88,7 @@ export class UsersListPage extends PureComponent<Props, State> {
     const { invitees, users } = this.props;
 
     if (this.state.showInvites) {
-      return <InviteesTable invitees={invitees} onRevokeInvite={code => this.onRevokeInvite(code)} />;
+      return <InviteesTable invitees={invitees} />;
     } else {
       return (
         <UsersTable
@@ -141,7 +136,6 @@ const mapDispatchToProps = {
   setUsersSearchQuery,
   updateUser,
   removeUser,
-  revokeInvite,
 };
 
 export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(UsersListPage));

+ 1 - 1
public/app/features/users/__mocks__/userMocks.ts

@@ -48,7 +48,7 @@ export const getMockInvitees = (amount: number) => {
       orgId: 1,
       role: 'viewer',
       status: 'not accepted',
-      url: `localhost/invite/$${i}`,
+      url: `localhost/invite/${i}`,
     });
   }
 

+ 120 - 258
public/app/features/users/__snapshots__/InviteesTable.test.tsx.snap

@@ -49,270 +49,132 @@ exports[`Render should render invitees 1`] = `
     </tr>
   </thead>
   <tbody>
-    <tr
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-0",
+          "createdOn": "2018-10-02",
+          "email": "invitee-0@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 0,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-0",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/0",
+        }
+      }
       key="0-0"
-    >
-      <td>
-        invitee-0@test.com
-      </td>
-      <td>
-        invitee-0
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$0"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
-    <tr
+    />
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-1",
+          "createdOn": "2018-10-02",
+          "email": "invitee-1@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 1,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-1",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/1",
+        }
+      }
       key="1-1"
-    >
-      <td>
-        invitee-1@test.com
-      </td>
-      <td>
-        invitee-1
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$1"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
-    <tr
+    />
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-2",
+          "createdOn": "2018-10-02",
+          "email": "invitee-2@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 2,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-2",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/2",
+        }
+      }
       key="2-2"
-    >
-      <td>
-        invitee-2@test.com
-      </td>
-      <td>
-        invitee-2
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$2"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
-    <tr
+    />
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-3",
+          "createdOn": "2018-10-02",
+          "email": "invitee-3@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 3,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-3",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/3",
+        }
+      }
       key="3-3"
-    >
-      <td>
-        invitee-3@test.com
-      </td>
-      <td>
-        invitee-3
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$3"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
-    <tr
+    />
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-4",
+          "createdOn": "2018-10-02",
+          "email": "invitee-4@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 4,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-4",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/4",
+        }
+      }
       key="4-4"
-    >
-      <td>
-        invitee-4@test.com
-      </td>
-      <td>
-        invitee-4
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$4"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
-    <tr
+    />
+    <Connect(InviteeRow)
+      invitee={
+        Object {
+          "code": "asdfasdfsadf-5",
+          "createdOn": "2018-10-02",
+          "email": "invitee-5@test.com",
+          "emailSent": true,
+          "emailSentOn": "2018-10-02",
+          "id": 5,
+          "invitedByEmail": "admin@grafana.com",
+          "invitedByLogin": "admin",
+          "invitedByName": "admin",
+          "name": "invitee-5",
+          "orgId": 1,
+          "role": "viewer",
+          "status": "not accepted",
+          "url": "localhost/invite/5",
+        }
+      }
       key="5-5"
-    >
-      <td>
-        invitee-5@test.com
-      </td>
-      <td>
-        invitee-5
-      </td>
-      <td
-        className="text-right"
-      >
-        <button
-          className="btn btn-inverse btn-mini"
-          onClick={[Function]}
-        >
-          <textarea
-            readOnly={true}
-            style={
-              Object {
-                "position": "absolute",
-                "right": -1000,
-              }
-            }
-            value="localhost/invite/$5"
-          />
-          <i
-            className="fa fa-clipboard"
-          />
-           Copy Invite
-        </button>
-         
-      </td>
-      <td>
-        <button
-          className="btn btn-danger btn-mini"
-          onClick={[Function]}
-        >
-          <i
-            className="fa fa-remove"
-          />
-        </button>
-      </td>
-    </tr>
+    />
   </tbody>
 </table>
 `;

+ 14 - 17
public/app/plugins/datasource/cloudwatch/query_parameter_ctrl.ts

@@ -2,21 +2,6 @@ import angular from 'angular';
 import coreModule from 'app/core/core_module';
 import _ from 'lodash';
 
-export class CloudWatchQueryParameter {
-  constructor() {
-    return {
-      templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/query.parameter.html',
-      controller: 'CloudWatchQueryParameterCtrl',
-      restrict: 'E',
-      scope: {
-        target: '=',
-        datasource: '=',
-        onChange: '&',
-      },
-    };
-  }
-}
-
 export class CloudWatchQueryParameterCtrl {
   /** @ngInject */
   constructor($scope, templateSrv, uiSegmentSrv, datasourceSrv, $q) {
@@ -240,5 +225,17 @@ export class CloudWatchQueryParameterCtrl {
   }
 }
 
-coreModule.directive('cloudwatchQueryParameter', CloudWatchQueryParameter);
-coreModule.controller('CloudWatchQueryParameterCtrl', CloudWatchQueryParameterCtrl);
+export function cloudWatchQueryParameter() {
+  return {
+    templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/query.parameter.html',
+    controller: CloudWatchQueryParameterCtrl,
+    restrict: 'E',
+    scope: {
+      target: '=',
+      datasource: '=',
+      onChange: '&',
+    },
+  };
+}
+
+coreModule.directive('cloudwatchQueryParameter', cloudWatchQueryParameter);

+ 8 - 1
public/app/plugins/datasource/elasticsearch/query_builder.ts

@@ -270,7 +270,14 @@ export class ElasticQueryBuilder {
 
       if (queryDef.isPipelineAgg(metric.type)) {
         if (metric.pipelineAgg && /^\d*$/.test(metric.pipelineAgg)) {
-          metricAgg = { buckets_path: metric.pipelineAgg };
+          const appliedAgg = queryDef.findMetricById(target.metrics, metric.pipelineAgg);
+          if (appliedAgg) {
+            if (appliedAgg.type === 'count') {
+              metricAgg = { buckets_path: '_count' };
+            } else {
+              metricAgg = { buckets_path: metric.pipelineAgg };
+            }
+          }
         } else {
           continue;
         }

+ 7 - 0
public/app/plugins/datasource/elasticsearch/query_def.ts

@@ -213,6 +213,9 @@ export function describeOrder(order) {
 
 export function describeMetric(metric) {
   const def = _.find(metricAggTypes, { value: metric.type });
+  if (!def.requiresField && !isPipelineAgg(metric.type)) {
+    return def.text;
+  }
   return def.text + ' ' + metric.field;
 }
 
@@ -236,3 +239,7 @@ export function defaultMetricAgg() {
 export function defaultBucketAgg() {
   return { type: 'date_histogram', id: '2', settings: { interval: 'auto' } };
 }
+
+export const findMetricById = (metrics: any[], id: any) => {
+  return _.find(metrics, { id: id });
+};

+ 49 - 0
public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts

@@ -250,6 +250,31 @@ describe('ElasticQueryBuilder', () => {
     expect(firstLevel.aggs['2'].moving_avg.buckets_path).toBe('3');
   });
 
+  it('with moving average doc count', () => {
+    const query = builder.build({
+      metrics: [
+        {
+          id: '3',
+          type: 'count',
+          field: 'select field',
+        },
+        {
+          id: '2',
+          type: 'moving_avg',
+          field: '3',
+          pipelineAgg: '3',
+        },
+      ],
+      bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '4' }],
+    });
+
+    const firstLevel = query.aggs['4'];
+
+    expect(firstLevel.aggs['2']).not.toBe(undefined);
+    expect(firstLevel.aggs['2'].moving_avg).not.toBe(undefined);
+    expect(firstLevel.aggs['2'].moving_avg.buckets_path).toBe('_count');
+  });
+
   it('with broken moving average', () => {
     const query = builder.build({
       metrics: [
@@ -304,6 +329,30 @@ describe('ElasticQueryBuilder', () => {
     expect(firstLevel.aggs['2'].derivative.buckets_path).toBe('3');
   });
 
+  it('with derivative doc count', () => {
+    const query = builder.build({
+      metrics: [
+        {
+          id: '3',
+          type: 'count',
+          field: 'select field',
+        },
+        {
+          id: '2',
+          type: 'derivative',
+          pipelineAgg: '3',
+        },
+      ],
+      bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '4' }],
+    });
+
+    const firstLevel = query.aggs['4'];
+
+    expect(firstLevel.aggs['2']).not.toBe(undefined);
+    expect(firstLevel.aggs['2'].derivative).not.toBe(undefined);
+    expect(firstLevel.aggs['2'].derivative.buckets_path).toBe('_count');
+  });
+
   it('with histogram', () => {
     const query = builder.build({
       metrics: [{ id: '1', type: 'count' }],

+ 92 - 192
public/app/plugins/datasource/loki/img/loki_icon.svg

@@ -2,7 +2,8 @@
 <!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 width="200px" height="200px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
+	 width="264.2px" height="318px" viewBox="-181.1 -67 264.2 318" style="enable-background:new -181.1 -67 264.2 318;"
+	 xml:space="preserve">
 <style type="text/css">
 	.st0{fill:url(#SVGID_1_);}
 	.st1{fill:url(#SVGID_2_);}
@@ -19,198 +20,97 @@
 	.st12{fill:url(#SVGID_13_);}
 	.st13{fill:url(#SVGID_14_);}
 	.st14{fill:url(#SVGID_15_);}
-	.st15{fill:url(#SVGID_16_);}
-	.st16{fill:url(#SVGID_17_);}
-	.st17{fill:url(#SVGID_18_);}
-	.st18{fill:url(#SVGID_19_);}
-	.st19{fill:url(#SVGID_20_);}
-	.st20{fill:url(#SVGID_21_);}
-	.st21{fill:url(#SVGID_22_);}
-	.st22{fill:url(#SVGID_23_);}
-	.st23{fill:url(#SVGID_24_);}
-	.st24{fill:url(#SVGID_25_);}
-	.st25{fill:url(#SVGID_26_);}
-	.st26{fill:url(#SVGID_27_);}
-	.st27{fill:url(#SVGID_28_);}
-	.st28{fill:url(#SVGID_29_);}
-	.st29{fill:url(#SVGID_30_);}
-	.st30{fill:url(#SVGID_31_);}
-	.st31{fill:url(#SVGID_32_);}
 </style>
 <g>
-	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="135.0285" y1="238.7858" x2="135.0285" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st0" d="M179.5,130c-6.9-9.5-18.6-16.1-30.2-17.9l-38.1-4.6l0,22.4l34.7,4c5.8,0.9,12.3,4.3,15.8,9.1
-		c3.5,4.7,4.9,10.5,4,16.3c-1.7,10.8-11,18.5-21.6,18.5c-1.1,0-2.3-0.1-3.4-0.3l-37.9-4.7c-5.1,8-12.2,14.7-20.6,19.2l55.2,7.4
-		c2.3,0.4,4.6,0.5,6.8,0.5c21.3,0,40-15.6,43.4-37.3C189.3,151.1,186.4,139.5,179.5,130z"/>
-	<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="56.0866" y1="238.7858" x2="56.0866" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st1" d="M90.5,171c1.3-1.6,2.4-3.3,3.5-5.1c1-1.7,1.9-3.4,2.7-5.2c2.3-5.3,3.5-11.2,3.5-17.3l0-4l0-5.6l0-5.6l0-22.4
-		l0-5.6l0-5.6L100,43.9C100,19.7,80.2,0,55.9,0S12,19.8,12,44.1l0.1,66.7c5.7-7.6,13.3-13.7,22.1-17.6L34.1,44
-		c0-12.1,9.8-21.9,21.8-21.9c12.1,0,21.9,9.8,21.9,21.8L78,91.2l0,5.6l0,5.6l0,22.4l0,5.6l0,5.6l0,7.5c0,5.2-1.8,9.9-4.8,13.7
-		c-1.5,1.9-3.3,3.5-5.3,4.8c-3.4,2.2-7.4,3.5-11.7,3.5c-0.7,0-1.4,0-2,0l-1.4-0.2c-10.8-1.7-18.6-11.1-18.5-21.8
-		c0-1.1,0.1-2.1,0.2-3.2c0.7-4.3,2.6-8.1,5.3-11.1c1.6-1.8,3.5-3.3,5.5-4.5c3.2-1.8,6.9-2.9,10.8-2.9c1.1,0,2.3,0.1,3.4,0.3l7.5,1.2
-		l0-22.4l-4-0.6c-2.3-0.4-4.6-0.5-6.8-0.5c-3.7,0-7.3,0.5-10.8,1.4c-1.9,0.5-3.7,1.1-5.5,1.8c-1.9,0.8-3.8,1.7-5.5,2.7
-		c-11.2,6.4-19.4,17.7-21.6,31.4c-0.4,2.4-0.5,4.9-0.5,7.3c0,1.2,0.1,2.3,0.2,3.5c0,0.3,0.1,0.6,0.1,0.9c0.1,1.1,0.3,2.3,0.5,3.4
-		c0.1,0.3,0.1,0.7,0.2,1c0.2,1.1,0.5,2.1,0.8,3.2c0.1,0.4,0.2,0.7,0.3,1.1c0.3,1,0.7,2,1.1,3c0.1,0.3,0.3,0.7,0.4,1
-		c0.4,1,0.9,1.9,1.4,2.9c0.2,0.3,0.3,0.6,0.5,0.9c0.5,1,1.1,1.9,1.7,2.8c0.2,0.2,0.3,0.5,0.5,0.7c0.7,1,1.4,1.9,2.1,2.9
-		c0.1,0.1,0.2,0.3,0.4,0.4c0.8,1,1.7,1.9,2.6,2.8c0.1,0.1,0.1,0.1,0.2,0.2c1,1,2,1.9,3,2.7c0,0,0.1,0,0.1,0.1
-		c1.1,0.9,2.2,1.7,3.3,2.5c0,0,0,0,0.1,0.1c1.1,0.8,2.3,1.5,3.5,2.1c0.1,0,0.1,0.1,0.2,0.1c1.1,0.6,2.3,1.2,3.5,1.7
-		c0.2,0.1,0.3,0.1,0.5,0.2c1.1,0.5,2.2,0.9,3.3,1.2c0.3,0.1,0.6,0.2,0.9,0.3c1,0.3,2.1,0.6,3.2,0.8c0.4,0.1,0.8,0.2,1.2,0.2
-		c2.7,0.5,5.5,0.8,8.3,0.8C70.1,187.5,82.4,181.1,90.5,171z"/>
-	<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="26.7057" y1="238.7858" x2="26.7057" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st2" d="M28.2,177.5c-1-0.9-2-1.8-3-2.7"/>
-	<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="12.7354" y1="238.7858" x2="12.7354" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st3" d="M13,151.9c-0.2-1.1-0.4-2.2-0.5-3.4"/>
-	<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="14.8849" y1="238.7858" x2="14.8849" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st4" d="M15.4,160.1c-0.4-1-0.8-2-1.1-3"/>
-	<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="18.6023" y1="238.7858" x2="18.6023" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st5" d="M19.5,167.8c-0.6-0.9-1.2-1.9-1.7-2.8"/>
-	<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="16.5561" y1="238.7858" x2="16.5561" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st6" d="M17.2,164c-0.5-0.9-1-1.9-1.4-2.9"/>
-	<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="12.2907" y1="238.7858" x2="12.2907" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st7" d="M12.2,144.1c0,1.2,0.1,2.3,0.2,3.5"/>
-	<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="23.7117" y1="238.7858" x2="23.7117" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st8" d="M25,174.6c-0.9-0.9-1.8-1.9-2.6-2.8"/>
-	<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="20.9974" y1="238.7858" x2="20.9974" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st9" d="M22.1,171.3c-0.8-0.9-1.5-1.9-2.1-2.9"/>
-	<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="13.6059" y1="238.7858" x2="13.6059" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st10" d="M14,156.1c-0.3-1-0.6-2.1-0.8-3.2"/>
-	<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="37.1094" y1="238.7858" x2="37.1094" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st11" d="M38.8,184c-1.2-0.5-2.3-1.1-3.5-1.7"/>
-	<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="45.1619" y1="238.7858" x2="45.1619" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st12" d="M46.8,186.5c-1.1-0.2-2.1-0.5-3.2-0.8"/>
-	<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="29.9487" y1="238.7858" x2="29.9487" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st13" d="M31.6,180c-1.1-0.8-2.2-1.6-3.3-2.5"/>
-	<linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="41.0239" y1="238.7858" x2="41.0239" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st14" d="M42.7,185.4c-1.1-0.4-2.3-0.8-3.3-1.2"/>
-	<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="33.4189" y1="238.7858" x2="33.4189" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st15" d="M35.2,182.2c-1.2-0.7-2.4-1.4-3.5-2.1"/>
-	<linearGradient id="SVGID_17_" gradientUnits="userSpaceOnUse" x1="53.9595" y1="238.7858" x2="53.9595" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st16" d="M54.1,154.2c-0.1,0-0.1,0-0.2-0.1"/>
-	<linearGradient id="SVGID_18_" gradientUnits="userSpaceOnUse" x1="21.1405" y1="238.7858" x2="21.1405" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st17" d="M21.4,178.8c-0.2-0.2-0.3-0.3-0.5-0.5"/>
-	<linearGradient id="SVGID_19_" gradientUnits="userSpaceOnUse" x1="35.2646" y1="238.7858" x2="35.2646" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st18" d="M35.2,182.2c0.1,0,0.1,0.1,0.2,0.1"/>
-	<linearGradient id="SVGID_20_" gradientUnits="userSpaceOnUse" x1="39.0979" y1="238.7858" x2="39.0979" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st19" d="M39.3,184.2c-0.2-0.1-0.3-0.1-0.5-0.2"/>
-	<linearGradient id="SVGID_21_" gradientUnits="userSpaceOnUse" x1="31.6434" y1="238.7858" x2="31.6434" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st20" d="M31.7,180.1C31.7,180.1,31.6,180.1,31.7,180.1"/>
-	<linearGradient id="SVGID_22_" gradientUnits="userSpaceOnUse" x1="28.2485" y1="238.7858" x2="28.2485" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st21" d="M28.3,177.6C28.3,177.5,28.2,177.5,28.3,177.6"/>
-	<linearGradient id="SVGID_23_" gradientUnits="userSpaceOnUse" x1="43.1314" y1="238.7858" x2="43.1314" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st22" d="M43.6,185.7c-0.3-0.1-0.6-0.2-0.9-0.3"/>
-	<linearGradient id="SVGID_24_" gradientUnits="userSpaceOnUse" x1="47.3468" y1="238.7858" x2="47.3468" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st23" d="M46.8,186.5c0.4,0.1,0.8,0.2,1.2,0.2"/>
-	<linearGradient id="SVGID_25_" gradientUnits="userSpaceOnUse" x1="19.6975" y1="238.7858" x2="19.6975" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st24" d="M19.9,168.4c-0.2-0.2-0.3-0.5-0.5-0.7"/>
-	<linearGradient id="SVGID_26_" gradientUnits="userSpaceOnUse" x1="17.4923" y1="238.7858" x2="17.4923" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st25" d="M17.7,164.9c-0.2-0.3-0.3-0.6-0.5-0.9"/>
-	<linearGradient id="SVGID_27_" gradientUnits="userSpaceOnUse" x1="12.4278" y1="238.7858" x2="12.4278" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st26" d="M12.5,148.5c0-0.3-0.1-0.6-0.1-0.9"/>
-	<linearGradient id="SVGID_28_" gradientUnits="userSpaceOnUse" x1="13.0965" y1="238.7858" x2="13.0965" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st27" d="M13.2,152.9c-0.1-0.3-0.1-0.7-0.2-1"/>
-	<linearGradient id="SVGID_29_" gradientUnits="userSpaceOnUse" x1="14.1769" y1="238.7858" x2="14.1769" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st28" d="M14.3,157.1c-0.1-0.3-0.2-0.7-0.3-1.1"/>
-	<linearGradient id="SVGID_30_" gradientUnits="userSpaceOnUse" x1="15.6479" y1="238.7858" x2="15.6479" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st29" d="M15.9,161.1c-0.2-0.3-0.3-0.7-0.4-1"/>
-	<linearGradient id="SVGID_31_" gradientUnits="userSpaceOnUse" x1="22.2436" y1="238.7858" x2="22.2436" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st30" d="M22.4,171.7c-0.1-0.1-0.2-0.3-0.4-0.4"/>
-	<linearGradient id="SVGID_32_" gradientUnits="userSpaceOnUse" x1="25.1051" y1="238.7858" x2="25.1051" y2="2.4079">
-		<stop  offset="0" style="stop-color:#FBED1D"/>
-		<stop  offset="1" style="stop-color:#F05A2A"/>
-	</linearGradient>
-	<path class="st31" d="M25.2,174.8c-0.1-0.1-0.1-0.1-0.2-0.2"/>
+	
+		<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="342.6804" y1="897.3058" x2="342.6804" y2="547.4434" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st0" points="-127.3,-58.2 -127.5,-59.1 -128.3,-58.9 	"/>
+	
+		<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="295.8044" y1="887.3397" x2="295.8044" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st1" points="-108.3,219.3 -130.7,223.8 -126.2,246.3 -103.8,241.8 	"/>
+	
+		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="442.4363" y1="887.3397" x2="442.4363" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st2" points="-27.8,190 71.3,170.1 66.8,147.7 -32.3,167.5 	"/>
+	
+		<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="367.5056" y1="887.3397" x2="367.5056" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st3" points="-67.5,174.6 -63,197 -40.5,192.5 -45,170.1 	"/>
+	
+		<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="331.6549" y1="887.3397" x2="331.6549" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st4" points="-68.6,234.7 -73.1,212.3 -95.6,216.8 -91.1,239.2 	"/>
+	
+		<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="295.8044" y1="887.3397" x2="295.8044" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st5" points="-133.3,211.1 -110.8,206.6 -115.3,184.2 -137.8,188.7 	"/>
+	
+		<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="442.4363" y1="887.3397" x2="442.4363" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st6" points="73.8,182.8 -25.3,202.7 -20.8,225.1 78.3,205.3 	"/>
+	
+		<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="367.5056" y1="887.3397" x2="367.5056" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st7" points="-60.4,209.7 -55.9,232.2 -33.5,227.7 -38,205.2 	"/>
+	
+		<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="331.6549" y1="887.3397" x2="331.6549" y2="537.4772" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st8" points="-98.1,204.1 -75.7,199.6 -80.2,177.1 -102.6,181.6 	"/>
+	
+		<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="289.1909" y1="880.5443" x2="289.1909" y2="548.7296" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st9" points="-140.3,176 -130.8,174.1 -166.8,-5.6 -176.3,-3.7 	"/>
+	
+		<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="302.4872" y1="889.7463" x2="302.4872" y2="533.4922" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st10" points="-127.3,173.4 -117.8,171.5 -156.4,-21.4 -165.9,-19.5 	"/>
+	
+		<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="325.1889" y1="908.8145" x2="325.1889" y2="501.9178" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st11" points="-105,168.9 -95.5,167 -139.7,-53.3 -149.2,-51.4 	"/>
+	
+		<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="338.4852" y1="896.2529" x2="338.4852" y2="522.7181" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st12" points="-92,166.3 -82.5,164.4 -123,-37.9 -132.5,-36 	"/>
+	
+		<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="360.8988" y1="870.7903" x2="360.8988" y2="564.8808" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st13" points="-70,161.9 -60.5,160 -93.7,-5.7 -103.2,-3.8 	"/>
+	
+		<linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="374.1951" y1="875.2039" x2="374.1951" y2="557.5726" gradientTransform="matrix(0.9805 -0.1964 0.1964 0.9805 -567.5302 -509.0906)">
+		<stop  offset="0" style="stop-color:#F9EC1C"/>
+		<stop  offset="1" style="stop-color:#F05A2B"/>
+	</linearGradient>
+	<polygon class="st14" points="-57,159.3 -47.5,157.4 -81.9,-14.6 -91.4,-12.7 	"/>
 </g>
 </svg>

+ 4 - 5
public/app/plugins/panel/gauge/MappingRow.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import { Label } from 'app/core/components/Label/Label';
-import SimplePicker from 'app/core/components/Picker/SimplePicker';
+import { Select } from 'app/core/components/Select/Select';
 import { MappingType, RangeMap, ValueMap } from 'app/types';
 
 interface Props {
@@ -135,13 +135,12 @@ export default class MappingRow extends PureComponent<Props, State> {
       <div className="mapping-row">
         <div className="gf-form-inline mapping-row-type">
           <Label width={5}>Type</Label>
-          <SimplePicker
+          <Select
             placeholder="Choose type"
+            isSearchable={false}
             options={mappingOptions}
             value={mappingOptions.find(o => o.value === type)}
-            getOptionLabel={i => i.label}
-            getOptionValue={i => i.value}
-            onSelected={type => this.onMappingTypeChange(type.value)}
+            onChange={type => this.onMappingTypeChange(type.value)}
             width={7}
           />
         </div>

+ 16 - 18
public/app/plugins/panel/gauge/ValueOptions.tsx

@@ -1,21 +1,21 @@
 import React, { PureComponent } from 'react';
 import { Label } from 'app/core/components/Label/Label';
-import SimplePicker from 'app/core/components/Picker/SimplePicker';
-import UnitPicker from 'app/core/components/Picker/Unit/UnitPicker';
+import Select from 'app/core/components/Select/Select';
+import UnitPicker from 'app/core/components/Select/UnitPicker';
 import { OptionModuleProps } from './module';
 
 const statOptions = [
-  { value: 'min', text: 'Min' },
-  { value: 'max', text: 'Max' },
-  { value: 'avg', text: 'Average' },
-  { value: 'current', text: 'Current' },
-  { value: 'total', text: 'Total' },
-  { value: 'name', text: 'Name' },
-  { value: 'first', text: 'First' },
-  { value: 'delta', text: 'Delta' },
-  { value: 'diff', text: 'Difference' },
-  { value: 'range', text: 'Range' },
-  { value: 'last_time', text: 'Time of last point' },
+  { value: 'min', label: 'Min' },
+  { value: 'max', label: 'Max' },
+  { value: 'avg', label: 'Average' },
+  { value: 'current', label: 'Current' },
+  { value: 'total', label: 'Total' },
+  { value: 'name', label: 'Name' },
+  { value: 'first', label: 'First' },
+  { value: 'delta', label: 'Delta' },
+  { value: 'diff', label: 'Difference' },
+  { value: 'range', label: 'Range' },
+  { value: 'last_time', label: 'Time of last point' },
 ];
 
 const labelWidth = 6;
@@ -43,18 +43,16 @@ export default class ValueOptions extends PureComponent<OptionModuleProps> {
         <h5 className="page-heading">Value</h5>
         <div className="gf-form-inline">
           <Label width={labelWidth}>Stat</Label>
-          <SimplePicker
+          <Select
             width={12}
             options={statOptions}
-            getOptionLabel={i => i.text}
-            getOptionValue={i => i.value}
-            onSelected={this.onStatChange}
+            onChange={this.onStatChange}
             value={statOptions.find(option => option.value === stat)}
           />
         </div>
         <div className="gf-form-inline">
           <Label width={labelWidth}>Unit</Label>
-          <UnitPicker defaultValue={unit} onSelected={value => this.onUnitChange(value)} />
+          <UnitPicker defaultValue={unit} onChange={this.onUnitChange} />
         </div>
         <div className="gf-form-inline">
           <Label width={labelWidth}>Decimals</Label>

+ 10 - 10
public/app/plugins/panel/table/column_options.html

@@ -3,51 +3,51 @@
     <h5 class="section-heading">Options</h5>
     <div class="gf-form-inline">
       <div class="gf-form">
-        <label class="gf-form-label width-13">Apply to columns named</label>
+        <label class="gf-form-label width-12">Apply to columns named</label>
         <input type="text" placeholder="Name or regex" class="gf-form-input width-13" ng-model="style.pattern" bs-tooltip="'Specify regex using /my.*regex/ syntax'"
             bs-typeahead="editor.getColumnNames" ng-blur="editor.render()" data-min-length=0 data-items=100 ng-model-onblur
             data-placement="right">
       </div>
     </div>
     <div class="gf-form" ng-if="style.type !== 'hidden'">
-      <label class="gf-form-label width-13">Column Header</label>
-      <input type="text" class="gf-form-input width-13" ng-model="style.alias" ng-change="editor.render()" ng-model-onblur placeholder="Override header label">
+      <label class="gf-form-label width-12">Column Header</label>
+      <input type="text" class="gf-form-input width-12" ng-model="style.alias" ng-change="editor.render()" ng-model-onblur placeholder="Override header label">
     </div>
-    <gf-form-switch class="gf-form" label-class="width-13" label="Render value as link" checked="style.link" change="editor.render()"></gf-form-switch>
+    <gf-form-switch class="gf-form" label-class="width-12" label="Render value as link" checked="style.link" change="editor.render()"></gf-form-switch>
   </div>
 
   <div class="section gf-form-group">
     <h5 class="section-heading">Type</h5>
 
     <div class="gf-form">
-      <label class="gf-form-label width-11">Type</label>
+      <label class="gf-form-label width-10">Type</label>
       <div class="gf-form-select-wrapper width-16">
         <select class="gf-form-input" ng-model="style.type" ng-options="c.value as c.text for c in editor.columnTypes" ng-change="editor.render()"></select>
       </div>
     </div>
     <div class="gf-form" ng-if="style.type === 'date'">
-      <label class="gf-form-label width-11">Date Format</label>
+      <label class="gf-form-label width-10">Date Format</label>
       <gf-form-dropdown model="style.dateFormat" css-class="gf-form-input width-16" lookup-text="true"
         	get-options="editor.dateFormats" on-change="editor.render()" allow-custom="true">
       </gf-form-dropdown>
     </div>
 
     <div ng-if="style.type === 'string'">
-      <gf-form-switch class="gf-form" label-class="width-11" ng-if="style.type === 'string'" label="Sanitize HTML" checked="style.sanitize"
+      <gf-form-switch class="gf-form" label-class="width-10" ng-if="style.type === 'string'" label="Sanitize HTML" checked="style.sanitize"
           change="editor.render()"></gf-form-switch>
     </div>
     <div ng-if="style.type === 'string'">
-      <gf-form-switch class="gf-form" label-class="width-11" ng-if="style.type === 'string'" label="Preserve Formatting" checked="style.preserveFormat"
+      <gf-form-switch class="gf-form" label-class="width-10" ng-if="style.type === 'string'" label="Preserve Formatting" checked="style.preserveFormat"
           change="editor.render()"></gf-form-switch>
     </div>
 
     <div ng-if="style.type === 'number'">
       <div class="gf-form">
-        <label class="gf-form-label width-11">Unit</label>
+        <label class="gf-form-label width-10">Unit</label>
         <div class="gf-form-dropdown-typeahead width-16" ng-model="style.unit" dropdown-typeahead2="editor.unitFormats" dropdown-typeahead-on-select="editor.setUnitFormat(style, $subItem)"></div>
       </div>
       <div class="gf-form">
-        <label class="gf-form-label width-11">Decimals</label>
+        <label class="gf-form-label width-10">Decimals</label>
         <input type="number" class="gf-form-input width-4" data-placement="right" ng-model="style.decimals" ng-change="editor.render()"
             ng-model-onblur>
       </div>

+ 7 - 15
public/app/plugins/panel/text/editor.html

@@ -1,23 +1,15 @@
-<div class="gf-form-group">
-	<div class="gf-form-inline">
-		<div class="gf-form">
-			<span class="gf-form-label">Mode</span>
-			<span class="gf-form-select-wrapper">
-				<select class="gf-form-input" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown']"></select>
-			</span>
-		</div>
+<div class="gf-form-inline">
+	<div class="gf-form">
+		<span class="gf-form-label">Mode</span>
+		<span class="gf-form-select-wrapper">
+			<select class="gf-form-input" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown']"></select>
+		</span>
 	</div>
 </div>
 
-<h3 class="page-heading">Content</h3>
-
-<span ng-show="ctrl.panel.mode == 'markdown'">
-	(This area uses <a target="_blank" href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>. HTML is not supported)
-</span>
-
 <div class="gf-form-inline">
 	<div class="gf-form gf-form--grow">
-		<code-editor content="ctrl.panel.content" on-change="ctrl.render()" data-mode="markdown" data-max-lines=20 code-editor-focus="true">
+		<code-editor content="ctrl.panel.content" on-change="ctrl.render()" data-mode="markdown" data-max-lines=20>
 		</code-editor>
 	</div>
 </div>

+ 10 - 1
public/app/plugins/panel/text/module.ts

@@ -2,6 +2,15 @@ import _ from 'lodash';
 import { PanelCtrl } from 'app/plugins/sdk';
 import Remarkable from 'remarkable';
 
+const defaultContent = `
+# Title
+
+For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)
+
+
+
+`;
+
 export class TextPanelCtrl extends PanelCtrl {
   static templateUrl = `public/app/plugins/panel/text/module.html`;
   static scrollable = true;
@@ -11,7 +20,7 @@ export class TextPanelCtrl extends PanelCtrl {
   // Set and populate defaults
   panelDefaults = {
     mode: 'markdown', // 'html', 'markdown', 'text'
-    content: '# title',
+    content: defaultContent,
   };
 
   /** @ngInject */

+ 2 - 6
public/app/types/explore.ts

@@ -3,6 +3,7 @@ import { Value } from 'slate';
 import { DataQuery, RawTimeRange } from './series';
 import TableModel from 'app/core/table_model';
 import { LogsModel } from 'app/core/logs_model';
+import { DataSourceSelectItem } from 'app/types/datasources';
 
 export interface CompletionItem {
   /**
@@ -74,11 +75,6 @@ export interface CompletionItemGroup {
   skipSort?: boolean;
 }
 
-interface ExploreDatasource {
-  value: string;
-  label: string;
-}
-
 export interface HistoryItem {
   ts: number;
   query: DataQuery;
@@ -159,7 +155,7 @@ export interface ExploreState {
   datasourceLoading: boolean | null;
   datasourceMissing: boolean;
   datasourceName?: string;
-  exploreDatasources: ExploreDatasource[];
+  exploreDatasources: DataSourceSelectItem[];
   graphInterval: number; // in ms
   graphResult?: any[];
   history: HistoryItem[];

+ 0 - 1
public/sass/_grafana.scss

@@ -101,7 +101,6 @@
 @import 'components/delete_button';
 @import 'components/add_data_source.scss';
 @import 'components/page_loader';
-@import 'components/unit-picker';
 @import 'components/thresholds';
 @import 'components/toggle_button_group';
 @import 'components/value-mappings';

+ 1 - 1
public/sass/_variables.light.scss

@@ -383,7 +383,7 @@ $checkbox-color: $gray-7;
 
 //Panel Edit
 // -------------------------
-$panel-editor-shadow: 2px 2px 8px $gray-3;
+$panel-editor-shadow: 0px 0px 8px $gray-3;
 $panel-editor-border: 1px solid $dark-4;
 $panel-editor-side-menu-shadow: drop-shadow(0 0 2px $gray-3);
 $panel-editor-toolbar-view-bg: $white;

+ 2 - 2
public/sass/base/_icons.scss

@@ -221,11 +221,11 @@
     background-image: url('../img/icons_#{$theme-name}_theme/icon_advanced.svg');
   }
 
-  .gicon-alerts-active {
+  .gicon-alert-active {
     background-image: url('../img/icons_#{$theme-name}_theme/icon_alerting_active.svg');
   }
 
-  .gicon-alerts {
+  .gicon-alert {
     background-image: url('../img/icons_#{$theme-name}_theme/icon_alerting.svg');
   }
 

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

@@ -12,6 +12,10 @@
     @include border-radius($input-border-radius-sm);
     border: $input-btn-border-width solid $input-border-color;
   }
+
+  .ace_content {
+    z-index: 0;
+  }
 }
 
 .ace_editor.ace_autocomplete {

+ 19 - 2
public/sass/components/_form_select_box.scss

@@ -79,6 +79,7 @@ $select-input-bg-disabled: $input-bg-disabled;
 .gf-form-select-box__option {
   border-left: 2px solid transparent;
   white-space: nowrap;
+  background-color: $input-bg;
 
   &.gf-form-select-box__option--is-focused {
     color: $dropdownLinkColorHover;
@@ -116,7 +117,7 @@ $select-input-bg-disabled: $input-bg-disabled;
 .gf-form-select-box__select-arrow {
   border-color: $input-color-select-arrow transparent transparent;
   border-style: solid;
-  border-width: 5px 5px 2.5px;
+  border-width: 4px 4px 2.5px;
   display: inline-block;
   height: 0;
   width: 0;
@@ -125,7 +126,7 @@ $select-input-bg-disabled: $input-bg-disabled;
   &.gf-form-select-box__select-arrow--reversed {
     border-color: transparent transparent $input-color-select-arrow;
     top: -2px;
-    border-width: 0 5px 5px;
+    border-width: 0 4px 4px;
   }
 }
 
@@ -170,3 +171,19 @@ $select-input-bg-disabled: $input-bg-disabled;
   width: 16px;
   margin-right: 10px;
 }
+
+.gf-form-select-box__option-group__header {
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  justify-items: center;
+  cursor: pointer;
+  padding: 7px 10px;
+  width: 100%;
+  border-bottom: 1px solid $hr-border-color;
+  text-transform: capitalize;
+
+  .fa {
+    padding-right: 2px;
+  }
+}

+ 1 - 1
public/sass/components/_navbar.scss

@@ -3,7 +3,7 @@
   padding-left: 40px;
   z-index: $zindex-navbar-fixed;
   height: $navbarHeight;
-  padding-right: $spacer;
+  padding-right: 20px;
   display: flex;
   flex-grow: 1;
   border-bottom: 1px solid transparent;

+ 15 - 67
public/sass/components/_panel_add_panel.scss

@@ -4,24 +4,26 @@
 
 .add-panel {
   height: 100%;
-
-  .baron__root {
-    height: calc(100% - 43px);
-  }
 }
 
 .add-panel__header {
+  top: 0;
+  position: absolute;
   padding: 0 15px;
   display: flex;
   align-items: center;
-  background: $page-header-bg;
-  box-shadow: $page-header-shadow;
-  border-bottom: 1px solid $page-header-border-color;
+  width: 100%;
+  cursor: move;
 
   .gicon {
     font-size: 30px;
     margin-right: $spacer;
   }
+
+  &:hover {
+    transition: background-color 0.1s ease-in-out;
+    background-color: $panel-header-hover-bg;
+  }
 }
 
 .add-panel__close {
@@ -32,68 +34,14 @@
   margin-right: -10px;
 }
 
-.add-panel__title {
-  font-size: $font-size-md;
-  margin-right: $spacer*2;
-}
-
-.add-panel__sub-title {
-  font-style: italic;
-  color: $text-muted;
-  position: relative;
-  top: 1px;
-}
-
-.add-panel__items {
-  padding: 3px 8px;
+.add-panel-btn-container {
   display: flex;
-  flex-direction: row;
-  flex-wrap: wrap;
-  overflow: auto;
+  justify-content: center;
+  align-items: center;
   height: 100%;
-  align-content: flex-start;
-  justify-content: space-around;
-  position: relative;
-}
-
-.add-panel__item {
-  background: $card-background;
-  box-shadow: $card-shadow;
+  flex-direction: column;
 
-  border-radius: 3px;
-  padding: $spacer/3 $spacer;
-  width: 31%;
-  height: 60px;
-  text-align: center;
-  margin: $gf-form-margin;
-  cursor: pointer;
-
-  &.active,
-  &:hover {
-    background: $card-background-hover;
+  .btn {
+    margin-bottom: 10px;
   }
 }
-
-.add-panel__item-name {
-  text-overflow: ellipsis;
-  overflow: hidden;
-  white-space: nowrap;
-  font-size: $font-size-sm;
-}
-
-.add-panel__item-img {
-  height: calc(100% - 15px);
-}
-
-.add-panel__searchbar {
-  width: 100%;
-  margin-bottom: 10px;
-  margin-top: 7px;
-}
-
-.add-panel__no-panels {
-  color: $text-color-weak;
-  font-style: italic;
-  width: 100%;
-  padding: 3px 8px;
-}

+ 1 - 1
public/sass/components/_panel_editor.scss

@@ -257,7 +257,7 @@
   .btn {
     position: absolute;
     right: 0;
-    top: 2px;
+    top: 0px;
   }
 }
 

Неке датотеке нису приказане због велике количине промена