Explorar o código

Merge branch '14293-metric-display-names' into reactify-stackdriver

# Conflicts:
#	public/app/plugins/datasource/stackdriver/partials/query.aggregation.html
#	public/app/plugins/datasource/stackdriver/partials/query.editor.html
#	public/app/plugins/datasource/stackdriver/partials/query.filter.html
#	public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts
#	public/app/plugins/datasource/stackdriver/query_ctrl.ts
#	public/app/plugins/datasource/stackdriver/query_filter_ctrl.ts
#	public/sass/_grafana.scss
Erik Sundell %!s(int64=7) %!d(string=hai) anos
pai
achega
9e558b70d7
Modificáronse 100 ficheiros con 9381 adicións e 882 borrados
  1. 1 0
      .gitignore
  2. 28 0
      CHANGELOG.md
  3. 29 275
      Gopkg.lock
  4. 4 4
      Gopkg.toml
  5. 2 2
      README.md
  6. 4 0
      conf/defaults.ini
  7. 4 0
      conf/sample.ini
  8. 52 1
      devenv/datasources.yaml
  9. 5394 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json
  10. 649 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json
  11. 651 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json
  12. 649 0
      devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json
  13. 1 1
      devenv/docker/blocks/elastic/docker-compose.yaml
  14. 7 4
      devenv/docker/blocks/elastic5/docker-compose.yaml
  15. 7 5
      devenv/docker/blocks/influxdb/docker-compose.yaml
  16. 1 1
      docs/sources/auth/github.md
  17. 1 1
      docs/sources/auth/gitlab.md
  18. 162 0
      docs/sources/features/explore/index.md
  19. 2 2
      latest.json
  20. 9 7
      package.json
  21. 11 11
      packaging/publish/publish_both.sh
  22. 1 0
      pkg/cmd/grafana-server/server.go
  23. 8 0
      pkg/infra/serverlock/model.go
  24. 116 0
      pkg/infra/serverlock/serverlock.go
  25. 40 0
      pkg/infra/serverlock/serverlock_integration_test.go
  26. 55 0
      pkg/infra/serverlock/serverlock_test.go
  27. 1 1
      pkg/login/ldap.go
  28. 1 1
      pkg/login/ldap_test.go
  29. 1 0
      pkg/plugins/datasource_plugin.go
  30. 8 3
      pkg/services/cleanup/cleanup.go
  31. 2 2
      pkg/services/provisioning/dashboards/file_reader.go
  32. 3 0
      pkg/services/sqlstore/migrations/datasource_mig.go
  33. 1 0
      pkg/services/sqlstore/migrations/migrations.go
  34. 22 0
      pkg/services/sqlstore/migrations/serverlock_migrations.go
  35. 3 0
      pkg/tsdb/elasticsearch/models.go
  36. 18 4
      pkg/tsdb/elasticsearch/time_series_query.go
  37. 60 0
      pkg/tsdb/elasticsearch/time_series_query_test.go
  38. 38 0
      public/app/core/components/Animations/FadeIn.tsx
  39. 1 1
      public/app/core/components/Animations/SlideDown.tsx
  40. 1 0
      public/app/core/components/AppNotifications/AppNotificationItem.tsx
  41. 36 0
      public/app/core/components/ClickOutsideWrapper/ClickOutsideWrapper.tsx
  42. 67 0
      public/app/core/components/CopyToClipboard/CopyToClipboard.tsx
  43. 2 2
      public/app/core/components/CustomScrollbar/CustomScrollbar.tsx
  44. 4 4
      public/app/core/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap
  45. 43 0
      public/app/core/components/Form/Element.tsx
  46. 53 0
      public/app/core/components/Form/Input.test.tsx
  47. 94 0
      public/app/core/components/Form/Input.tsx
  48. 19 0
      public/app/core/components/Form/Label.tsx
  49. 11 0
      public/app/core/components/Form/__snapshots__/Input.test.tsx.snap
  50. 3 0
      public/app/core/components/Form/index.ts
  51. 51 0
      public/app/core/components/JSONFormatter/JSONFormatter.tsx
  52. 1 0
      public/app/core/components/Label/Label.tsx
  53. 9 9
      public/app/core/components/PermissionList/AddPermission.tsx
  54. 8 7
      public/app/core/components/PermissionList/DisabledPermissionListItem.tsx
  55. 9 7
      public/app/core/components/PermissionList/PermissionListItem.tsx
  56. 0 25
      public/app/core/components/Picker/DescriptionOption.tsx
  57. 0 52
      public/app/core/components/Picker/DescriptionPicker.tsx
  58. 0 18
      public/app/core/components/Picker/NoOptionsMessage.tsx
  59. 0 22
      public/app/core/components/Picker/PickerOption.tsx
  60. 0 49
      public/app/core/components/Picker/SimplePicker.tsx
  61. 0 17
      public/app/core/components/Picker/__snapshots__/PickerOption.test.tsx.snap
  62. 32 0
      public/app/core/components/Portal/Portal.tsx
  63. 72 0
      public/app/core/components/Select/DataSourcePicker.tsx
  64. 2 2
      public/app/core/components/Select/IndicatorsContainer.tsx
  65. 20 0
      public/app/core/components/Select/NoOptionsMessage.tsx
  66. 59 0
      public/app/core/components/Select/OptionGroup.tsx
  67. 2 2
      public/app/core/components/Select/PickerOption.test.tsx
  68. 44 0
      public/app/core/components/Select/PickerOption.tsx
  69. 4 2
      public/app/core/components/Select/ResetStyles.tsx
  70. 232 0
      public/app/core/components/Select/Select.tsx
  71. 0 0
      public/app/core/components/Select/TeamPicker.test.tsx
  72. 9 18
      public/app/core/components/Select/TeamPicker.tsx
  73. 51 0
      public/app/core/components/Select/UnitPicker.tsx
  74. 0 0
      public/app/core/components/Select/UserPicker.test.tsx
  75. 16 18
      public/app/core/components/Select/UserPicker.tsx
  76. 21 0
      public/app/core/components/Select/__snapshots__/PickerOption.test.tsx.snap
  77. 0 29
      public/app/core/components/Select/__snapshots__/TeamPicker.test.tsx.snap
  78. 0 29
      public/app/core/components/Select/__snapshots__/UserPicker.test.tsx.snap
  79. 13 15
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  80. 9 16
      public/app/core/components/Switch/Switch.tsx
  81. 10 5
      public/app/core/components/TagFilter/TagFilter.tsx
  82. 1 1
      public/app/core/components/TagFilter/TagOption.tsx
  83. 18 35
      public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx
  84. 11 26
      public/app/core/components/Tooltip/Popover.tsx
  85. 72 0
      public/app/core/components/Tooltip/Popper.tsx
  86. 9 28
      public/app/core/components/Tooltip/Tooltip.tsx
  87. 2 2
      public/app/core/components/Tooltip/__snapshots__/Popover.test.tsx.snap
  88. 3 3
      public/app/core/components/Tooltip/__snapshots__/Tooltip.test.tsx.snap
  89. 88 0
      public/app/core/components/Tooltip/withPopper.tsx
  90. 0 58
      public/app/core/components/Tooltip/withTooltip.tsx
  91. 1 1
      public/app/core/components/code_editor/code_editor.ts
  92. 9 22
      public/app/core/components/colorpicker/ColorPicker.tsx
  93. 1 1
      public/app/core/components/colorpicker/SeriesColorPicker.tsx
  94. 2 2
      public/app/core/components/manage_dashboards/manage_dashboards.html
  95. 8 8
      public/app/core/components/search/search_results.html
  96. 45 9
      public/app/core/components/switch.ts
  97. 4 0
      public/app/core/constants.ts
  98. 6 3
      public/app/core/directives/dash_class.ts
  99. 2 2
      public/app/core/directives/dropdown_typeahead.ts
  100. 45 7
      public/app/core/logs_model.ts

+ 1 - 0
.gitignore

@@ -76,3 +76,4 @@ debug.test
 /devenv/bulk_alerting_dashboards/*.json
 
 /scripts/build/release_publisher/release_publisher
+*.patch

+ 28 - 0
CHANGELOG.md

@@ -6,9 +6,37 @@
 ### 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)
+* **LDAP**: Upgrade go-ldap to v3 [#14548](https://github.com/grafana/grafana/issues/14548)
+
+# 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).
+* **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.
+* **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.
+* **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.
+
+
 
 # 5.4.0 (2018-12-03)
 

+ 29 - 275
Gopkg.lock

@@ -2,39 +2,30 @@
 
 
 [[projects]]
-  digest = "1:f8ad8a53fa865a70efbe215b0ca34735523f50ea39e0efde319ab6fc80089b44"
   name = "cloud.google.com/go"
   packages = ["compute/metadata"]
-  pruneopts = "NUT"
   revision = "056a55f54a6cc77b440b31a56a5e7c3982d32811"
   version = "v0.22.0"
 
 [[projects]]
-  digest = "1:167b6f65a6656de568092189ae791253939f076df60231fdd64588ac703892a1"
   name = "github.com/BurntSushi/toml"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "b26d9c308763d68093482582cea63d69be07a0f0"
   version = "v0.3.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:7d23e6e1889b8bb4bbb37a564708fdab4497ce232c3a99d66406c975b642a6ff"
   name = "github.com/Unknwon/com"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "7677a1d7c1137cd3dd5ba7a076d0c898a1ef4520"
 
 [[projects]]
   branch = "master"
-  digest = "1:1610787cd9726e29d8fecc2a80e43e4fced008a1f560fec6688fc4d946f17835"
   name = "github.com/VividCortex/mysqlerr"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "6c6b55f8796f578c870b7e19bafb16103bc40095"
 
 [[projects]]
-  digest = "1:58294d68772aab5a8941b7d5d228eff7cccf63f895e914bc9bc38fda80471ea5"
   name = "github.com/aws/aws-sdk-go"
   packages = [
     "aws",
@@ -70,523 +61,399 @@
     "service/ec2",
     "service/ec2/ec2iface",
     "service/s3",
-    "service/sts",
+    "service/sts"
   ]
-  pruneopts = "NUT"
   revision = "fde4ded7becdeae4d26bf1212916aabba79349b4"
   version = "v1.14.12"
 
 [[projects]]
   branch = "master"
-  digest = "1:79cad073c7be02632d3fa52f62486848b089f560db1e94536de83a408c0f4726"
   name = "github.com/benbjohnson/clock"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "7dc76406b6d3c05b5f71a86293cbcf3c4ea03b19"
 
 [[projects]]
   branch = "master"
-  digest = "1:707ebe952a8b3d00b343c01536c79c73771d100f63ec6babeaed5c79e2b8a8dd"
   name = "github.com/beorn7/perks"
   packages = ["quantile"]
-  pruneopts = "NUT"
   revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
 
 [[projects]]
   branch = "master"
-  digest = "1:433a2ff0ef4e2f8634614aab3174783c5ff80120b487712db96cc3712f409583"
   name = "github.com/bmizerany/assert"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "b7ed37b82869576c289d7d97fb2bbd8b64a0cb28"
 
 [[projects]]
   branch = "master"
-  digest = "1:d8f9145c361920507a4f85ffb7f70b96beaedacba2ce8c00aa663adb08689d3e"
   name = "github.com/bradfitz/gomemcache"
   packages = ["memcache"]
-  pruneopts = "NUT"
   revision = "1952afaa557dc08e8e0d89eafab110fb501c1a2b"
 
 [[projects]]
   branch = "master"
-  digest = "1:8ecb89af7dfe3ac401bdb0c9390b134ef96a97e85f732d2b0604fb7b3977839f"
   name = "github.com/codahale/hdrhistogram"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "3a0bb77429bd3a61596f5e8a3172445844342120"
 
 [[projects]]
-  digest = "1:5dba68a1600a235630e208cb7196b24e58fcbb77bb7a6bec08fcd23f081b0a58"
   name = "github.com/codegangsta/cli"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
   version = "v1.20.0"
 
 [[projects]]
-  digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
   name = "github.com/davecgh/go-spew"
   packages = ["spew"]
-  pruneopts = "NUT"
   revision = "346938d642f2ec3594ed81d874461961cd0faa76"
   version = "v1.1.0"
 
 [[projects]]
-  digest = "1:1b318d2dd6cea8a1a8d8ec70348852303bd3e491df74e8bca6e32eb5a4d06970"
   name = "github.com/denisenkom/go-mssqldb"
   packages = [
     ".",
-    "internal/cp",
+    "internal/cp"
   ]
-  pruneopts = "NUT"
   revision = "270bc3860bb94dd3a3ffd047377d746c5e276726"
 
 [[projects]]
   branch = "master"
-  digest = "1:2da5f11ad66ff01a27a5c3dba4620b7eee2327be75b32c9ee9f87c9a8001ecbf"
   name = "github.com/facebookgo/inject"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "cc1aa653e50f6a9893bcaef89e673e5b24e1e97b"
 
 [[projects]]
   branch = "master"
-  digest = "1:1108df7f658c90db041e0d6174d55be689aaeb0585913b9c3c7aab51a3a6b2b1"
   name = "github.com/facebookgo/structtag"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "217e25fb96916cc60332e399c9aa63f5c422ceed"
 
 [[projects]]
-  digest = "1:ade392a843b2035effb4b4a2efa2c3bab3eb29b992e98bacf9c898b0ecb54e45"
   name = "github.com/fatih/color"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
   version = "v1.7.0"
 
 [[projects]]
-  digest = "1:e05711632e1515319b014e8fe4cbe1d30ab024c473403f60cf0fdeb4c586a474"
   name = "github.com/go-ini/ini"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
   version = "v1.36.0"
 
-[[projects]]
-  digest = "1:7e1c00b9959544fa1ccca7cf0407a5b29ac6d5201059c4fac6f599cb99bfd24d"
-  name = "github.com/go-ldap/ldap"
-  packages = ["."]
-  pruneopts = "NUT"
-  revision = "bb7a9ca6e4fbc2129e3db588a34bc970ffe811a9"
-  version = "v2.5.1"
-
 [[projects]]
   branch = "master"
-  digest = "1:682a0aca743a1a4a36697f3d7f86c0ed403c4e3a780db9935f633242855eac9c"
   name = "github.com/go-macaron/binding"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "ac54ee249c27dca7e76fad851a4a04b73bd1b183"
 
 [[projects]]
   branch = "master"
-  digest = "1:6326b27f8e0c8e135c8674ddbc619fae879664ac832e8e6fa6a23ce0d279ed4d"
   name = "github.com/go-macaron/gzip"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "cad1c6580a07c56f5f6bc52d66002a05985c5854"
 
 [[projects]]
   branch = "master"
-  digest = "1:fb8711b648d1ff03104fc1d9593a13cb1d5120be7ba2b01641c14ccae286a9e3"
   name = "github.com/go-macaron/inject"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "d8a0b8677191f4380287cfebd08e462217bac7ad"
 
 [[projects]]
   branch = "master"
-  digest = "1:21577aafe885f088e8086a3415f154c63c0b7ce956a6994df2ac5776bc01b7e3"
   name = "github.com/go-macaron/session"
   packages = [
     ".",
     "memcache",
     "postgres",
-    "redis",
+    "redis"
   ]
-  pruneopts = "NUT"
   revision = "068d408f9c54c7fa7fcc5e2bdd3241ab21280c9e"
 
 [[projects]]
-  digest = "1:fddd4bada6100d6fc49a9f32f18ba5718db45a58e4b00aa6377e1cfbf06af34f"
   name = "github.com/go-sql-driver/mysql"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "2cc627ac8defc45d65066ae98f898166f580f9a4"
 
 [[projects]]
-  digest = "1:a1efdbc2762667c8a41cbf02b19a0549c846bf2c1d08cad4f445e3344089f1f0"
   name = "github.com/go-stack/stack"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
   version = "v1.7.0"
 
 [[projects]]
-  digest = "1:b9d4f09cdaaa9e7dca5ed0b501ca5519eb2168dd01fc5d174c54edfe42a7d5ed"
   name = "github.com/go-xorm/builder"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "bad0a612f0d6277b953910822ab5dfb30dd18237"
   version = "v0.2.0"
 
 [[projects]]
-  digest = "1:30fb106b0cd6d64ea6fccded579c8f7d788460092f885fcc8f3edd02fc2085a4"
   name = "github.com/go-xorm/core"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "da1adaf7a28ca792961721a34e6e04945200c890"
   version = "v0.5.7"
 
 [[projects]]
-  digest = "1:007d1354e4f44e6a393337e7623bcf911dfe75d6ef30fb767a6a0b65d302f5ed"
   name = "github.com/go-xorm/xorm"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "1933dd69e294c0a26c0266637067f24dbb25770c"
   version = "v0.6.4"
 
 [[projects]]
   branch = "master"
-  digest = "1:ffbb19fb66f140b5ea059428d1f84246a055d1bc3d9456c1e5c3d143611f03d0"
   name = "github.com/golang/protobuf"
   packages = [
     "proto",
     "ptypes",
     "ptypes/any",
     "ptypes/duration",
-    "ptypes/timestamp",
+    "ptypes/timestamp"
   ]
-  pruneopts = "NUT"
   revision = "927b65914520a8b7d44f5c9057611cfec6b2e2d0"
 
 [[projects]]
   branch = "master"
-  digest = "1:f14d1b50e0075fb00177f12a96dd7addf93d1e2883c25befd17285b779549795"
   name = "github.com/gopherjs/gopherjs"
   packages = ["js"]
-  pruneopts = "NUT"
   revision = "8dffc02ea1cb8398bb73f30424697c60fcf8d4c5"
 
 [[projects]]
-  digest = "1:3b708ebf63bfa9ba3313bedb8526bc0bb284e51474e65e958481476a9d4a12aa"
   name = "github.com/gorilla/websocket"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
   version = "v1.2.0"
 
 [[projects]]
-  digest = "1:4e771d1c6e15ca4516ad971c34205c822b5cff2747179679d7b321e4e1bfe431"
   name = "github.com/gosimple/slug"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "e9f42fa127660e552d0ad2b589868d403a9be7c6"
   version = "v1.1.1"
 
 [[projects]]
   branch = "master"
-  digest = "1:08e53c69cd267ef7d71eeae5d953153d0d2bc1b8e0b498731fe9acaead7001b6"
   name = "github.com/grafana/grafana-plugin-model"
   packages = [
     "go/datasource",
-    "go/renderer",
+    "go/renderer"
   ]
-  pruneopts = "NUT"
   revision = "84176c64269d8060f99e750ee8aba6f062753336"
 
 [[projects]]
   branch = "master"
-  digest = "1:58ba5285227b0f635652cd4aa82c4cfd00b590191eadd823462f0c9f64e3ae07"
   name = "github.com/hashicorp/go-hclog"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "69ff559dc25f3b435631604f573a5fa1efdb6433"
 
 [[projects]]
-  digest = "1:532090ffc3b05a7e4c0229dd2698d79149f2e0683df993224a8b202f607fb605"
   name = "github.com/hashicorp/go-plugin"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "e8d22c780116115ae5624720c9af0c97afe4f551"
 
 [[projects]]
   branch = "master"
-  digest = "1:8925116d1edcd85fc0c014e1aa69ce12892489b48ee633a605c46d893b8c151f"
   name = "github.com/hashicorp/go-version"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "23480c0665776210b5fbbac6eaaee40e3e6a96b7"
 
 [[projects]]
   branch = "master"
-  digest = "1:8deb0c5545c824dfeb0ac77ab8eb67a3d541eab76df5c85ce93064ef02d44cd0"
   name = "github.com/hashicorp/yamux"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "7221087c3d281fda5f794e28c2ea4c6e4d5c4558"
 
 [[projects]]
-  digest = "1:efbe016b6d198cf44f1db0ed2fbdf1b36ebf1f6956cc9b76d6affa96f022d368"
   name = "github.com/inconshreveable/log15"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "0decfc6c20d9ca0ad143b0e89dcaa20f810b4fb3"
   version = "v2.13"
 
 [[projects]]
-  digest = "1:ac6d01547ec4f7f673311b4663909269bfb8249952de3279799289467837c3cc"
   name = "github.com/jmespath/go-jmespath"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "0b12d6b5"
 
 [[projects]]
-  digest = "1:6ddab442e52381bab82fb6c07ef3f4b565ff7ec4b8fae96d8dd4b8573a460597"
   name = "github.com/jtolds/gls"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "77f18212c9c7edc9bd6a33d383a7b545ce62f064"
   version = "v4.2.1"
 
 [[projects]]
-  digest = "1:1da1796a71eb70f1e3e085984d044f67840bb0326816ec8276231aa87b1b9fc3"
   name = "github.com/klauspost/compress"
   packages = [
     "flate",
-    "gzip",
+    "gzip"
   ]
-  pruneopts = "NUT"
   revision = "6c8db69c4b49dd4df1fff66996cf556176d0b9bf"
   version = "v1.2.1"
 
 [[projects]]
-  digest = "1:5e55a8699c9ff7aba1e4c8952aeda209685d88d4cb63a8766c338e333b8e65d6"
   name = "github.com/klauspost/cpuid"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da"
   version = "v1.1"
 
 [[projects]]
-  digest = "1:b95da1293525625ef6f07be79d537b9bf2ecd7901efcf9a92193edafbd55b9ef"
   name = "github.com/klauspost/crc32"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
   version = "v1.1"
 
 [[projects]]
-  digest = "1:7b21c7fc5551b46d1308b4ffa9e9e49b66c7a8b0ba88c0130474b0e7a20d859f"
   name = "github.com/kr/pretty"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "73f6ac0b30a98e433b289500d779f50c1a6f0712"
   version = "v0.1.0"
 
 [[projects]]
-  digest = "1:c3a7836b5904db0f8b609595b619916a6831cb35b8b714aec39f96d00c6155d8"
   name = "github.com/kr/text"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "e2ffdb16a802fe2bb95e2e35ff34f0e53aeef34f"
   version = "v0.1.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:7a1e592f0349d56fac8ce47f28469e4e7f4ce637cb26f40c88da9dff25db1c98"
   name = "github.com/lib/pq"
   packages = [
     ".",
-    "oid",
+    "oid"
   ]
-  pruneopts = "NUT"
   revision = "d34b9ff171c21ad295489235aec8b6626023cd04"
 
 [[projects]]
-  digest = "1:08c231ec84231a7e23d67e4b58f975e1423695a32467a362ee55a803f9de8061"
   name = "github.com/mattn/go-colorable"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
   version = "v0.0.9"
 
 [[projects]]
-  digest = "1:bc4f7eec3b7be8c6cb1f0af6c1e3333d5bb71072951aaaae2f05067b0803f287"
   name = "github.com/mattn/go-isatty"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
   version = "v0.0.3"
 
 [[projects]]
-  digest = "1:536979f1c56397dbf91c2785159b37dec37e35d3bffa3cd1cfe66d25f51f8088"
   name = "github.com/mattn/go-sqlite3"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "323a32be5a2421b8c7087225079c6c900ec397cd"
   version = "v1.7.0"
 
 [[projects]]
-  digest = "1:5985ef4caf91ece5d54817c11ea25f182697534f8ae6521eadcd628c142ac4b6"
   name = "github.com/matttproud/golang_protobuf_extensions"
   packages = ["pbutil"]
-  pruneopts = "NUT"
   revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
   version = "v1.0.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:18b773b92ac82a451c1276bd2776c1e55ce057ee202691ab33c8d6690efcc048"
   name = "github.com/mitchellh/go-testing-interface"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28"
 
 [[projects]]
-  digest = "1:3b517122f3aad1ecce45a630ea912b3092b4729f25532a911d0cb2935a1f9352"
   name = "github.com/oklog/run"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39"
   version = "v1.0.0"
 
 [[projects]]
-  digest = "1:7da29c22bcc5c2ffb308324377dc00b5084650348c2799e573ed226d8cc9faf0"
   name = "github.com/opentracing/opentracing-go"
   packages = [
     ".",
     "ext",
-    "log",
+    "log"
   ]
-  pruneopts = "NUT"
   revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
   version = "v1.0.2"
 
 [[projects]]
-  digest = "1:748946761cf99c8b73cef5a3c0ee3e040859dd713a20cece0d0e0dc04e6ceca7"
   name = "github.com/patrickmn/go-cache"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "a3647f8e31d79543b2d0f0ae2fe5c379d72cedc0"
   version = "v2.1.0"
 
 [[projects]]
-  digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
   name = "github.com/pkg/errors"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
   version = "v0.8.0"
 
 [[projects]]
-  digest = "1:4759bed95e3a52febc18c071db28790a5c6e9e106ee201a37add6f6a056f8f9c"
   name = "github.com/prometheus/client_golang"
   packages = [
     "api",
     "api/prometheus/v1",
     "prometheus",
-    "prometheus/promhttp",
+    "prometheus/promhttp"
   ]
-  pruneopts = "NUT"
   revision = "967789050ba94deca04a5e84cce8ad472ce313c1"
   version = "v0.9.0-pre1"
 
 [[projects]]
   branch = "master"
-  digest = "1:32d10bdfa8f09ecf13598324dba86ab891f11db3c538b6a34d1c3b5b99d7c36b"
   name = "github.com/prometheus/client_model"
   packages = ["go"]
-  pruneopts = "NUT"
   revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
 
 [[projects]]
   branch = "master"
-  digest = "1:768b555b86742de2f28beb37f1dedce9a75f91f871d75b5717c96399c1a78c08"
   name = "github.com/prometheus/common"
   packages = [
     "expfmt",
     "internal/bitbucket.org/ww/goautoneg",
-    "model",
+    "model"
   ]
-  pruneopts = "NUT"
   revision = "d811d2e9bf898806ecfb6ef6296774b13ffc314c"
 
 [[projects]]
   branch = "master"
-  digest = "1:c4a213a8d73fbb0b13f717ba7996116602ef18ecb42b91d77405877914cb0349"
   name = "github.com/prometheus/procfs"
   packages = [
     ".",
     "internal/util",
     "nfs",
-    "xfs",
+    "xfs"
   ]
-  pruneopts = "NUT"
   revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e"
 
 [[projects]]
   branch = "master"
-  digest = "1:16e2136a67ec44aa2d1d6b0fd65394b3c4a8b2a1b6730c77967f7b7b06b179b2"
   name = "github.com/rainycape/unidecode"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "cb7f23ec59bec0d61b19c56cd88cee3d0cc1870c"
 
 [[projects]]
-  digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04"
   name = "github.com/sergi/go-diff"
   packages = ["diffmatchpatch"]
-  pruneopts = "NUT"
   revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
   version = "v1.0.0"
 
 [[projects]]
-  digest = "1:1f0b284a6858827de4c27c66b49b2b25df3e16b031c2b57b7892273131e7dd2b"
   name = "github.com/smartystreets/assertions"
   packages = [
     ".",
     "internal/go-render/render",
-    "internal/oglematchers",
+    "internal/oglematchers"
   ]
-  pruneopts = "NUT"
   revision = "7678a5452ebea5b7090a6b163f844c133f523da2"
   version = "1.8.3"
 
 [[projects]]
-  digest = "1:7efd0b2309cdd6468029fa30c808c50a820c9344df07e1a4bbdaf18f282907aa"
   name = "github.com/smartystreets/goconvey"
   packages = [
     "convey",
     "convey/gotest",
-    "convey/reporting",
+    "convey/reporting"
   ]
-  pruneopts = "NUT"
   revision = "9e8dc3f972df6c8fcc0375ef492c24d0bb204857"
   version = "1.6.3"
 
 [[projects]]
   branch = "master"
-  digest = "1:a66add8dd963bfc72649017c1b321198f596cb4958cb1a11ff91a1be8691020b"
   name = "github.com/teris-io/shortid"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "771a37caa5cf0c81f585d7b6df4dfc77e0615b5c"
 
 [[projects]]
-  digest = "1:3d48c38e0eca8c66df62379c5ae7a83fb5cd839b94f241354c07ba077da7bc45"
   name = "github.com/uber/jaeger-client-go"
   packages = [
     ".",
@@ -604,55 +471,45 @@
     "thrift-gen/jaeger",
     "thrift-gen/sampling",
     "thrift-gen/zipkincore",
-    "utils",
+    "utils"
   ]
-  pruneopts = "NUT"
   revision = "b043381d944715b469fd6b37addfd30145ca1758"
   version = "v2.14.0"
 
 [[projects]]
-  digest = "1:0f09db8429e19d57c8346ad76fbbc679341fa86073d3b8fb5ac919f0357d8f4c"
   name = "github.com/uber/jaeger-lib"
   packages = ["metrics"]
-  pruneopts = "NUT"
   revision = "ed3a127ec5fef7ae9ea95b01b542c47fbd999ce5"
   version = "v1.5.0"
 
 [[projects]]
-  digest = "1:4c7d12ad3ef47bb03892a52e2609dc9a9cff93136ca9c7d31c00b79fcbc23c7b"
   name = "github.com/yudai/gojsondiff"
   packages = [
     ".",
-    "formatter",
+    "formatter"
   ]
-  pruneopts = "NUT"
   revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6"
   version = "1.0.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:e50cbf8eba568d59b71e08c22c2a77809ed4646ae06ef4abb32b3d3d3fdb1a77"
   name = "github.com/yudai/golcs"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68"
 
 [[projects]]
   branch = "master"
-  digest = "1:758f363e0dff33cf00b234be2efb12f919d79b42d5ae3909ff9eb69ef2c3cca5"
   name = "golang.org/x/crypto"
   packages = [
     "ed25519",
     "ed25519/internal/edwards25519",
     "md4",
-    "pbkdf2",
+    "pbkdf2"
   ]
-  pruneopts = "NUT"
   revision = "1a580b3eff7814fc9b40602fd35256c63b50f491"
 
 [[projects]]
   branch = "master"
-  digest = "1:0b3fee9c4472022a0982ee0d81e08b3cc3e595f50befd7a4b358b48540d9d8c5"
   name = "golang.org/x/net"
   packages = [
     "context",
@@ -662,43 +519,35 @@
     "http2/hpack",
     "idna",
     "internal/timeseries",
-    "trace",
+    "trace"
   ]
-  pruneopts = "NUT"
   revision = "2491c5de3490fced2f6cff376127c667efeed857"
 
 [[projects]]
   branch = "master"
-  digest = "1:46bd4e66bfce5e77f08fc2e8dcacc3676e679241ce83d9c150ff0397d686dd44"
   name = "golang.org/x/oauth2"
   packages = [
     ".",
     "google",
     "internal",
     "jws",
-    "jwt",
+    "jwt"
   ]
-  pruneopts = "NUT"
   revision = "cdc340f7c179dbbfa4afd43b7614e8fcadde4269"
 
 [[projects]]
   branch = "master"
-  digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239"
   name = "golang.org/x/sync"
   packages = ["errgroup"]
-  pruneopts = "NUT"
   revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
 
 [[projects]]
   branch = "master"
-  digest = "1:ec21c5bf0572488865b93e30ffd9132afbf85bec0b20c2d6cbcf349cf2031ed5"
   name = "golang.org/x/sys"
   packages = ["unix"]
-  pruneopts = "NUT"
   revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b"
 
 [[projects]]
-  digest = "1:e7071ed636b5422cc51c0e3a6cebc229d6c9fffc528814b519a980641422d619"
   name = "golang.org/x/text"
   packages = [
     "collate",
@@ -714,14 +563,12 @@
     "unicode/bidi",
     "unicode/cldr",
     "unicode/norm",
-    "unicode/rangetable",
+    "unicode/rangetable"
   ]
-  pruneopts = "NUT"
   revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
   version = "v0.3.0"
 
 [[projects]]
-  digest = "1:dbd5568923513ee74aa626d027e2a8a352cf8f35df41d19f4e34491d1858c38b"
   name = "google.golang.org/appengine"
   packages = [
     ".",
@@ -734,22 +581,18 @@
     "internal/modules",
     "internal/remote_api",
     "internal/urlfetch",
-    "urlfetch",
+    "urlfetch"
   ]
-  pruneopts = "NUT"
   revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
   version = "v1.0.0"
 
 [[projects]]
   branch = "master"
-  digest = "1:3c24554c312721e98fa6b76403e7100cf974eb46b1255ea7fc6471db9a9ce498"
   name = "google.golang.org/genproto"
   packages = ["googleapis/rpc/status"]
-  pruneopts = "NUT"
   revision = "7bb2a897381c9c5ab2aeb8614f758d7766af68ff"
 
 [[projects]]
-  digest = "1:840b77b6eb539b830bb760b6e30b688ed2ff484bd83466fce2395835ed9367fe"
   name = "google.golang.org/grpc"
   packages = [
     ".",
@@ -776,167 +619,78 @@
     "stats",
     "status",
     "tap",
-    "transport",
+    "transport"
   ]
-  pruneopts = "NUT"
   revision = "1e2570b1b19ade82d8dbb31bba4e65e9f9ef5b34"
   version = "v1.11.1"
 
 [[projects]]
   branch = "v3"
-  digest = "1:1244a9b3856f70d5ffb74bbfd780fc9d47f93f2049fa265c6fb602878f507bf8"
   name = "gopkg.in/alexcesaro/quotedprintable.v3"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "2caba252f4dc53eaf6b553000885530023f54623"
 
 [[projects]]
-  digest = "1:aea6e9483c167cc6fdf1274c442558c5dda8fd3373372be04d98c79100868da1"
   name = "gopkg.in/asn1-ber.v1"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "379148ca0225df7a432012b8df0355c2a2063ac0"
   version = "v1.2"
 
 [[projects]]
-  digest = "1:24bfc2e8bf971485cb5ba0f0e5b08a1b806cca5828134df76b32d1ea50f2ab49"
   name = "gopkg.in/bufio.v1"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "567b2bfa514e796916c4747494d6ff5132a1dfce"
   version = "v1"
 
 [[projects]]
-  digest = "1:e05711632e1515319b014e8fe4cbe1d30ab024c473403f60cf0fdeb4c586a474"
   name = "gopkg.in/ini.v1"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
   version = "v1.36.0"
 
 [[projects]]
-  digest = "1:3b0cf3a465fd07f76e5fc1a9d0783c662dac0de9fc73d713ebe162768fd87b5f"
+  name = "gopkg.in/ldap.v3"
+  packages = ["."]
+  revision = "5c2c0f997205c29de14cb6c35996370c2c5dfab1"
+  version = "v3"
+
+[[projects]]
   name = "gopkg.in/macaron.v1"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "c1be95e6d21e769e44e1ec33cec9da5837861c10"
   version = "v1.3.1"
 
 [[projects]]
   branch = "v2"
-  digest = "1:d52332f9e9f2c6343652e13aa3fd40cfd03353520c9a48d90f21215d3012d50f"
   name = "gopkg.in/mail.v2"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "5bc5c8bb07bd8d2803831fbaf8cbd630fcde2c68"
 
 [[projects]]
-  digest = "1:00126f697efdcab42f07c89ac8bf0095fb2328aef6464e070055154088cea859"
   name = "gopkg.in/redis.v2"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "e6179049628164864e6e84e973cfb56335748dea"
   version = "v2.3.2"
 
 [[projects]]
-  digest = "1:a50fabe7a46692dc7c656310add3d517abe7914df02afd151ef84da884605dc8"
   name = "gopkg.in/square/go-jose.v2"
   packages = [
     ".",
     "cipher",
-    "json",
+    "json"
   ]
-  pruneopts = "NUT"
   revision = "ef984e69dd356202fd4e4910d4d9c24468bdf0b8"
   version = "v2.1.9"
 
 [[projects]]
   branch = "v2"
-  digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
   name = "gopkg.in/yaml.v2"
   packages = ["."]
-  pruneopts = "NUT"
   revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
 
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  input-imports = [
-    "github.com/BurntSushi/toml",
-    "github.com/Unknwon/com",
-    "github.com/VividCortex/mysqlerr",
-    "github.com/aws/aws-sdk-go/aws",
-    "github.com/aws/aws-sdk-go/aws/awserr",
-    "github.com/aws/aws-sdk-go/aws/awsutil",
-    "github.com/aws/aws-sdk-go/aws/credentials",
-    "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
-    "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
-    "github.com/aws/aws-sdk-go/aws/defaults",
-    "github.com/aws/aws-sdk-go/aws/ec2metadata",
-    "github.com/aws/aws-sdk-go/aws/endpoints",
-    "github.com/aws/aws-sdk-go/aws/request",
-    "github.com/aws/aws-sdk-go/aws/session",
-    "github.com/aws/aws-sdk-go/service/cloudwatch",
-    "github.com/aws/aws-sdk-go/service/ec2",
-    "github.com/aws/aws-sdk-go/service/ec2/ec2iface",
-    "github.com/aws/aws-sdk-go/service/s3",
-    "github.com/aws/aws-sdk-go/service/sts",
-    "github.com/benbjohnson/clock",
-    "github.com/bmizerany/assert",
-    "github.com/codegangsta/cli",
-    "github.com/davecgh/go-spew/spew",
-    "github.com/denisenkom/go-mssqldb",
-    "github.com/facebookgo/inject",
-    "github.com/fatih/color",
-    "github.com/go-ldap/ldap",
-    "github.com/go-macaron/binding",
-    "github.com/go-macaron/gzip",
-    "github.com/go-macaron/session",
-    "github.com/go-macaron/session/memcache",
-    "github.com/go-macaron/session/postgres",
-    "github.com/go-macaron/session/redis",
-    "github.com/go-sql-driver/mysql",
-    "github.com/go-stack/stack",
-    "github.com/go-xorm/core",
-    "github.com/go-xorm/xorm",
-    "github.com/gorilla/websocket",
-    "github.com/gosimple/slug",
-    "github.com/grafana/grafana-plugin-model/go/datasource",
-    "github.com/grafana/grafana-plugin-model/go/renderer",
-    "github.com/hashicorp/go-hclog",
-    "github.com/hashicorp/go-plugin",
-    "github.com/hashicorp/go-version",
-    "github.com/inconshreveable/log15",
-    "github.com/lib/pq",
-    "github.com/mattn/go-isatty",
-    "github.com/mattn/go-sqlite3",
-    "github.com/opentracing/opentracing-go",
-    "github.com/opentracing/opentracing-go/ext",
-    "github.com/opentracing/opentracing-go/log",
-    "github.com/patrickmn/go-cache",
-    "github.com/pkg/errors",
-    "github.com/prometheus/client_golang/api",
-    "github.com/prometheus/client_golang/api/prometheus/v1",
-    "github.com/prometheus/client_golang/prometheus",
-    "github.com/prometheus/client_golang/prometheus/promhttp",
-    "github.com/prometheus/client_model/go",
-    "github.com/prometheus/common/expfmt",
-    "github.com/prometheus/common/model",
-    "github.com/smartystreets/goconvey/convey",
-    "github.com/teris-io/shortid",
-    "github.com/uber/jaeger-client-go/config",
-    "github.com/yudai/gojsondiff",
-    "github.com/yudai/gojsondiff/formatter",
-    "golang.org/x/net/context/ctxhttp",
-    "golang.org/x/oauth2",
-    "golang.org/x/oauth2/google",
-    "golang.org/x/oauth2/jwt",
-    "golang.org/x/sync/errgroup",
-    "gopkg.in/ini.v1",
-    "gopkg.in/macaron.v1",
-    "gopkg.in/mail.v2",
-    "gopkg.in/square/go-jose.v2",
-    "gopkg.in/yaml.v2",
-  ]
+  inputs-digest = "88f0eb826b9c154ba46ea3bb64767707d86db75449ec75199eb2b8cf2b337fd4"
   solver-name = "gps-cdcl"
   solver-version = 1

+ 4 - 4
Gopkg.toml

@@ -58,10 +58,6 @@ ignored = [
   name = "github.com/fatih/color"
   version = "1.5.0"
 
-[[constraint]]
-  name = "github.com/go-ldap/ldap"
-  version = "2.5.1"
-
 [[constraint]]
   branch = "master"
   name = "github.com/go-macaron/binding"
@@ -211,3 +207,7 @@ ignored = [
 [[constraint]]
   name = "gopkg.in/square/go-jose.v2"
   version = "2.1.9"
+
+[[constraint]]
+  name = "gopkg.in/ldap.v3"
+  version = "3.0.0"

+ 2 - 2
README.md

@@ -25,7 +25,7 @@ the latest master builds [here](https://grafana.com/grafana/download)
 ### Dependencies
 
 - Go (Latest Stable)
-- NodeJS LTS
+- Node.js LTS
 
 ### Building the backend
 ```bash
@@ -37,7 +37,7 @@ go run build.go build
 
 ### Building frontend assets
 
-For this you need nodejs (v.6+).
+For this you need Node.js (LTS version).
 
 To build the assets, rebuild on file change, and serve them by Grafana's webserver (http://localhost:3000):
 ```bash

+ 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"
 }

+ 9 - 7
package.json

@@ -20,9 +20,9 @@
     "@types/enzyme": "^3.1.13",
     "@types/jest": "^23.3.2",
     "@types/node": "^8.0.31",
-    "@types/react": "^16.4.14",
+    "@types/react": "^16.7.6",
     "@types/react-custom-scrollbars": "^4.0.5",
-    "@types/react-dom": "^16.0.7",
+    "@types/react-dom": "^16.0.9",
     "@types/react-select": "^2.0.4",
     "angular-mocks": "1.6.6",
     "autoprefixer": "^6.4.0",
@@ -148,17 +148,18 @@
     "prismjs": "^1.6.0",
     "prop-types": "^15.6.2",
     "rc-cascader": "^0.14.0",
-    "react": "^16.5.0",
+    "react": "^16.6.3",
     "react-custom-scrollbars": "^4.2.1",
-    "react-dom": "^16.5.0",
+    "react-dom": "^16.6.3",
     "react-grid-layout": "0.16.6",
+    "react-popper": "^1.3.0",
     "react-highlight-words": "0.11.0",
-    "react-popper": "^0.7.5",
     "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",
+    "react-virtualized": "^9.21.0",
     "redux": "^4.0.0",
     "redux-logger": "^3.0.6",
     "redux-thunk": "^2.3.0",
@@ -175,6 +176,7 @@
     "tslint-react": "^3.6.0"
   },
   "resolutions": {
-    "caniuse-db": "1.0.30000772"
+    "caniuse-db": "1.0.30000772",
+    "**/@types/react": "16.7.6"
   }
 }

+ 11 - 11
packaging/publish/publish_both.sh

@@ -1,17 +1,17 @@
 #! /usr/bin/env bash
-version=5.0.2
+version=5.4.2
 
-wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${version}_amd64.deb
+# wget https://dl.grafana.com/oss/release/grafana_${version}_amd64.deb
+#
+# package_cloud push grafana/stable/debian/jessie grafana_${version}_amd64.deb
+# package_cloud push grafana/stable/debian/wheezy grafana_${version}_amd64.deb
+# package_cloud push grafana/stable/debian/stretch grafana_${version}_amd64.deb
+#
+# package_cloud push grafana/testing/debian/jessie grafana_${version}_amd64.deb
+# package_cloud push grafana/testing/debian/wheezy grafana_${version}_amd64.deb --verbose
+# package_cloud push grafana/testing/debian/stretch grafana_${version}_amd64.deb --verbose
 
-package_cloud push grafana/stable/debian/jessie grafana_${version}_amd64.deb
-package_cloud push grafana/stable/debian/wheezy grafana_${version}_amd64.deb
-package_cloud push grafana/stable/debian/stretch grafana_${version}_amd64.deb
-
-package_cloud push grafana/testing/debian/jessie grafana_${version}_amd64.deb
-package_cloud push grafana/testing/debian/wheezy grafana_${version}_amd64.deb --verbose
-package_cloud push grafana/testing/debian/stretch grafana_${version}_amd64.deb --verbose
-
-wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${version}-1.x86_64.rpm
+wget https://dl.grafana.com/oss/release/grafana-${version}-1.x86_64.rpm
 
 package_cloud push grafana/testing/el/6 grafana-${version}-1.x86_64.rpm --verbose
 package_cloud push grafana/testing/el/7 grafana-${version}-1.x86_64.rpm --verbose

+ 1 - 0
pkg/cmd/grafana-server/server.go

@@ -28,6 +28,7 @@ import (
 
 	// self registering services
 	_ "github.com/grafana/grafana/pkg/extensions"
+	_ "github.com/grafana/grafana/pkg/infra/serverlock"
 	_ "github.com/grafana/grafana/pkg/metrics"
 	_ "github.com/grafana/grafana/pkg/plugins"
 	_ "github.com/grafana/grafana/pkg/services/alerting"

+ 8 - 0
pkg/infra/serverlock/model.go

@@ -0,0 +1,8 @@
+package serverlock
+
+type serverLock struct {
+	Id            int64
+	OperationUid  string
+	LastExecution int64
+	Version       int64
+}

+ 116 - 0
pkg/infra/serverlock/serverlock.go

@@ -0,0 +1,116 @@
+package serverlock
+
+import (
+	"context"
+	"time"
+
+	"github.com/grafana/grafana/pkg/log"
+	"github.com/grafana/grafana/pkg/registry"
+	"github.com/grafana/grafana/pkg/services/sqlstore"
+)
+
+func init() {
+	registry.RegisterService(&ServerLockService{})
+}
+
+// ServerLockService allows servers in HA mode to claim a lock
+// and execute an function if the server was granted the lock
+type ServerLockService struct {
+	SQLStore *sqlstore.SqlStore `inject:""`
+	log      log.Logger
+}
+
+// Init this service
+func (sl *ServerLockService) Init() error {
+	sl.log = log.New("infra.lockservice")
+	return nil
+}
+
+// LockAndExecute try to create a lock for this server and only executes the
+// `fn` function when successful. This should not be used at low internal. But services
+// that needs to be run once every ex 10m.
+func (sl *ServerLockService) LockAndExecute(ctx context.Context, actionName string, maxInterval time.Duration, fn func()) error {
+	// gets or creates a lockable row
+	rowLock, err := sl.getOrCreate(ctx, actionName)
+	if err != nil {
+		return err
+	}
+
+	// avoid execution if last lock happened less than `maxInterval` ago
+	if rowLock.LastExecution != 0 {
+		lastExeuctionTime := time.Unix(rowLock.LastExecution, 0)
+		if lastExeuctionTime.Unix() > time.Now().Add(-maxInterval).Unix() {
+			return nil
+		}
+	}
+
+	// try to get lock based on rowLow version
+	acquiredLock, err := sl.acquireLock(ctx, rowLock)
+	if err != nil {
+		return err
+	}
+
+	if acquiredLock {
+		fn()
+	}
+
+	return nil
+}
+
+func (sl *ServerLockService) acquireLock(ctx context.Context, serverLock *serverLock) (bool, error) {
+	var result bool
+
+	err := sl.SQLStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
+		newVersion := serverLock.Version + 1
+		sql := `UPDATE server_lock SET
+			version = ?,
+			last_execution = ?
+		WHERE
+			id = ? AND version = ?`
+
+		res, err := dbSession.Exec(sql, newVersion, time.Now().Unix(), serverLock.Id, serverLock.Version)
+		if err != nil {
+			return err
+		}
+
+		affected, err := res.RowsAffected()
+		result = affected == 1
+
+		return err
+	})
+
+	return result, err
+}
+
+func (sl *ServerLockService) getOrCreate(ctx context.Context, actionName string) (*serverLock, error) {
+	var result *serverLock
+
+	err := sl.SQLStore.WithTransactionalDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
+		lockRows := []*serverLock{}
+		err := dbSession.Where("operation_uid = ?", actionName).Find(&lockRows)
+		if err != nil {
+			return err
+		}
+
+		if len(lockRows) > 0 {
+			result = lockRows[0]
+			return nil
+		}
+
+		lockRow := &serverLock{
+			OperationUid:  actionName,
+			LastExecution: 0,
+		}
+
+		_, err = dbSession.Insert(lockRow)
+		if err != nil {
+			return err
+		}
+
+		result = lockRow
+
+		return nil
+	})
+
+	return result, err
+}

+ 40 - 0
pkg/infra/serverlock/serverlock_integration_test.go

@@ -0,0 +1,40 @@
+// +build integration
+
+package serverlock
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func TestServerLok(t *testing.T) {
+	sl := createTestableServerLock(t)
+
+	Convey("Server lock integration tests", t, func() {
+		counter := 0
+		var err error
+		incCounter := func() { counter++ }
+		atInterval := time.Second * 1
+		ctx := context.Background()
+
+		//this time `fn` should be executed
+		So(sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter), ShouldBeNil)
+
+		//this should not execute `fn`
+		So(sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter), ShouldBeNil)
+		So(sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter), ShouldBeNil)
+		So(sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter), ShouldBeNil)
+		So(sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter), ShouldBeNil)
+
+		// wait 5 second.
+		<-time.After(atInterval * 2)
+
+		// now `fn` should be executed again
+		err = sl.LockAndExecute(ctx, "test-operation", atInterval, incCounter)
+		So(err, ShouldBeNil)
+		So(counter, ShouldEqual, 2)
+	})
+}

+ 55 - 0
pkg/infra/serverlock/serverlock_test.go

@@ -0,0 +1,55 @@
+package serverlock
+
+import (
+	"context"
+	"testing"
+
+	"github.com/grafana/grafana/pkg/log"
+	"github.com/grafana/grafana/pkg/services/sqlstore"
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func createTestableServerLock(t *testing.T) *ServerLockService {
+	t.Helper()
+
+	sqlstore := sqlstore.InitTestDB(t)
+
+	return &ServerLockService{
+		SQLStore: sqlstore,
+		log:      log.New("test-logger"),
+	}
+}
+
+func TestServerLock(t *testing.T) {
+	Convey("Server lock", t, func() {
+		sl := createTestableServerLock(t)
+		operationUID := "test-operation"
+
+		first, err := sl.getOrCreate(context.Background(), operationUID)
+		So(err, ShouldBeNil)
+
+		lastExecution := first.LastExecution
+		Convey("trying to create three new row locks", func() {
+			for i := 0; i < 3; i++ {
+				first, err = sl.getOrCreate(context.Background(), operationUID)
+				So(err, ShouldBeNil)
+				So(first.OperationUid, ShouldEqual, operationUID)
+				So(first.Id, ShouldEqual, 1)
+			}
+
+			Convey("Should not create new since lock already exist", func() {
+				So(lastExecution, ShouldEqual, first.LastExecution)
+			})
+		})
+
+		Convey("Should be able to create lock on first row", func() {
+			gotLock, err := sl.acquireLock(context.Background(), first)
+			So(err, ShouldBeNil)
+			So(gotLock, ShouldBeTrue)
+
+			gotLock, err = sl.acquireLock(context.Background(), first)
+			So(err, ShouldBeNil)
+			So(gotLock, ShouldBeFalse)
+		})
+	})
+}

+ 1 - 1
pkg/login/ldap.go

@@ -9,11 +9,11 @@ import (
 	"strings"
 
 	"github.com/davecgh/go-spew/spew"
-	"github.com/go-ldap/ldap"
 	"github.com/grafana/grafana/pkg/bus"
 	"github.com/grafana/grafana/pkg/log"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/setting"
+	"gopkg.in/ldap.v3"
 )
 
 type ILdapConn interface {

+ 1 - 1
pkg/login/ldap_test.go

@@ -5,10 +5,10 @@ import (
 	"crypto/tls"
 	"testing"
 
-	"github.com/go-ldap/ldap"
 	"github.com/grafana/grafana/pkg/bus"
 	m "github.com/grafana/grafana/pkg/models"
 	. "github.com/smartystreets/goconvey/convey"
+	"gopkg.in/ldap.v3"
 )
 
 func TestLdapAuther(t *testing.T) {

+ 1 - 0
pkg/plugins/datasource_plugin.go

@@ -24,6 +24,7 @@ type DataSourcePlugin struct {
 	Metrics      bool              `json:"metrics"`
 	Alerting     bool              `json:"alerting"`
 	Explore      bool              `json:"explore"`
+	Table        bool              `json:"tables"`
 	Logs         bool              `json:"logs"`
 	QueryOptions map[string]bool   `json:"queryOptions,omitempty"`
 	BuiltIn      bool              `json:"builtIn,omitempty"`

+ 8 - 3
pkg/services/cleanup/cleanup.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/grafana/grafana/pkg/bus"
+	"github.com/grafana/grafana/pkg/infra/serverlock"
 	"github.com/grafana/grafana/pkg/log"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/registry"
@@ -15,8 +16,9 @@ import (
 )
 
 type CleanUpService struct {
-	log log.Logger
-	Cfg *setting.Cfg `inject:""`
+	log               log.Logger
+	Cfg               *setting.Cfg                  `inject:""`
+	ServerLockService *serverlock.ServerLockService `inject:""`
 }
 
 func init() {
@@ -38,7 +40,10 @@ func (srv *CleanUpService) Run(ctx context.Context) error {
 			srv.cleanUpTmpFiles()
 			srv.deleteExpiredSnapshots()
 			srv.deleteExpiredDashboardVersions()
-			srv.deleteOldLoginAttempts()
+			srv.ServerLockService.LockAndExecute(ctx, "delete old login attempts", time.Minute*10, func() {
+				srv.deleteOldLoginAttempts()
+			})
+
 		case <-ctx.Done():
 			return ctx.Err()
 		}

+ 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))
 }

+ 1 - 0
pkg/services/sqlstore/migrations/migrations.go

@@ -31,6 +31,7 @@ func AddMigrations(mg *Migrator) {
 	addTagMigration(mg)
 	addLoginAttemptMigrations(mg)
 	addUserAuthMigrations(mg)
+	addServerlockMigrations(mg)
 }
 
 func addMigrationLogMigrations(mg *Migrator) {

+ 22 - 0
pkg/services/sqlstore/migrations/serverlock_migrations.go

@@ -0,0 +1,22 @@
+package migrations
+
+import "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
+
+func addServerlockMigrations(mg *migrator.Migrator) {
+	serverLock := migrator.Table{
+		Name: "server_lock",
+		Columns: []*migrator.Column{
+			{Name: "id", Type: migrator.DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			{Name: "operation_uid", Type: migrator.DB_NVarchar, Length: 100},
+			{Name: "version", Type: migrator.DB_BigInt},
+			{Name: "last_execution", Type: migrator.DB_BigInt, Nullable: false},
+		},
+		Indices: []*migrator.Index{
+			{Cols: []string{"operation_uid"}, Type: migrator.UniqueIndex},
+		},
+	}
+
+	mg.AddMigration("create server_lock table", migrator.NewAddTableMigration(serverLock))
+
+	mg.AddMigration("add index server_lock.operation_uid", migrator.NewAddIndexMigration(serverLock, serverLock.Indices[0]))
+}

+ 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")
+		})
 	})
 }
 

+ 38 - 0
public/app/core/components/Animations/FadeIn.tsx

@@ -0,0 +1,38 @@
+import React, { SFC } from 'react';
+import Transition from 'react-transition-group/Transition';
+
+interface Props {
+  duration: number;
+  children: JSX.Element;
+  in: boolean;
+  unmountOnExit?: boolean;
+}
+
+export const FadeIn: SFC<Props> = props => {
+  const defaultStyle = {
+    transition: `opacity ${props.duration}ms linear`,
+    opacity: 0,
+  };
+
+  const transitionStyles = {
+    exited: { opacity: 0, display: 'none' },
+    entering: { opacity: 0 },
+    entered: { opacity: 1 },
+    exiting: { opacity: 0 },
+  };
+
+  return (
+    <Transition in={props.in} timeout={props.duration} unmountOnExit={props.unmountOnExit || false}>
+      {state => (
+        <div
+          style={{
+            ...defaultStyle,
+            ...transitionStyles[state],
+          }}
+        >
+          {props.children}
+        </div>
+      )}
+    </Transition>
+  );
+};

+ 1 - 1
public/app/core/components/Animations/SlideDown.tsx

@@ -23,7 +23,7 @@ export default ({ children, in: inProp, maxHeight = defaultMaxHeight, style = de
   const transitionStyles = {
     exited: { maxHeight: 0 },
     entering: { maxHeight: maxHeight },
-    entered: { maxHeight: maxHeight, overflow: 'visible' },
+    entered: { maxHeight: 'unset', overflow: 'visible' },
     exiting: { maxHeight: 0 },
   };
 

+ 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">

+ 36 - 0
public/app/core/components/ClickOutsideWrapper/ClickOutsideWrapper.tsx

@@ -0,0 +1,36 @@
+import { PureComponent } from 'react';
+import ReactDOM from 'react-dom';
+
+export interface Props {
+  onClick: () => void;
+}
+
+interface State {
+  hasEventListener: boolean;
+}
+
+export class ClickOutsideWrapper extends PureComponent<Props, State> {
+  state = {
+    hasEventListener: false,
+  };
+
+  componentDidMount() {
+    window.addEventListener('click', this.onOutsideClick, false);
+  }
+
+  componentWillUnmount() {
+    window.removeEventListener('click', this.onOutsideClick, false);
+  }
+
+  onOutsideClick = event => {
+    const domNode = ReactDOM.findDOMNode(this) as Element;
+
+    if (!domNode || !domNode.contains(event.target)) {
+      this.props.onClick();
+    }
+  };
+
+  render() {
+    return this.props.children;
+  }
+}

+ 67 - 0
public/app/core/components/CopyToClipboard/CopyToClipboard.tsx

@@ -0,0 +1,67 @@
+import React, { PureComponent, ReactNode } from 'react';
+import ClipboardJS from 'clipboard';
+
+interface Props {
+  text: () => string;
+  elType?: string;
+  onSuccess?: (evt: any) => void;
+  onError?: (evt: any) => void;
+  className?: string;
+  children?: ReactNode;
+}
+
+export class CopyToClipboard extends PureComponent<Props> {
+  clipboardjs: any;
+  myRef: any;
+
+  constructor(props) {
+    super(props);
+    this.myRef = React.createRef();
+  }
+
+  componentDidMount() {
+    const { text, onSuccess, onError } = this.props;
+
+    this.clipboardjs = new ClipboardJS(this.myRef.current, {
+      text: text,
+    });
+
+    if (onSuccess) {
+      this.clipboardjs.on('success', evt => {
+        evt.clearSelection();
+        onSuccess(evt);
+      });
+    }
+
+    if (onError) {
+      this.clipboardjs.on('error', evt => {
+        console.error('Action:', evt.action);
+        console.error('Trigger:', evt.trigger);
+        onError(evt);
+      });
+    }
+  }
+
+  componentWillUnmount() {
+    if (this.clipboardjs) {
+      this.clipboardjs.destroy();
+    }
+  }
+
+  getElementType = () => {
+    return this.props.elType || 'button';
+  };
+
+  render() {
+    const { elType, text, children, onError, onSuccess, ...restProps } = this.props;
+
+    return React.createElement(
+      this.getElementType(),
+      {
+        ref: this.myRef,
+        ...restProps,
+      },
+      this.props.children
+    );
+  }
+}

+ 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,

+ 43 - 0
public/app/core/components/Form/Element.tsx

@@ -0,0 +1,43 @@
+import React, { PureComponent, ReactNode, ReactElement } from 'react';
+import { Label } from './Label';
+import { uniqueId } from 'lodash';
+
+interface Props {
+  label?: ReactNode;
+  labelClassName?: string;
+  id?: string;
+  children: ReactElement<any>;
+}
+
+export class Element extends PureComponent<Props> {
+  elementId: string = this.props.id || uniqueId('form-element-');
+
+  get elementLabel() {
+    const { label, labelClassName } = this.props;
+
+    if (label) {
+      return (
+        <Label htmlFor={this.elementId} className={labelClassName}>
+          {label}
+        </Label>
+      );
+    }
+
+    return null;
+  }
+
+  get children() {
+    const { children } = this.props;
+
+    return React.cloneElement(children, { id: this.elementId });
+  }
+
+  render() {
+    return (
+      <div className="our-custom-wrapper-class">
+        {this.elementLabel}
+        {this.children}
+      </div>
+    );
+  }
+}

+ 53 - 0
public/app/core/components/Form/Input.test.tsx

@@ -0,0 +1,53 @@
+import React from 'react';
+import renderer from 'react-test-renderer';
+import { shallow } from 'enzyme';
+import { Input, EventsWithValidation } from './Input';
+import { ValidationEvents } from 'app/types';
+
+const TEST_ERROR_MESSAGE = 'Value must be empty or less than 3 chars';
+const testBlurValidation: ValidationEvents = {
+  [EventsWithValidation.onBlur]: [
+    {
+      rule: (value: string) => {
+        if (!value || value.length < 3) {
+          return true;
+        }
+        return false;
+      },
+      errorMessage: TEST_ERROR_MESSAGE,
+    },
+  ],
+};
+
+describe('Input', () => {
+  it('renders correctly', () => {
+    const tree = renderer.create(<Input />).toJSON();
+    expect(tree).toMatchSnapshot();
+  });
+
+  it('should validate with error onBlur', () => {
+    const wrapper = shallow(<Input validationEvents={testBlurValidation} />);
+    const evt = {
+      persist: jest.fn,
+      target: {
+        value: 'I can not be more than 2 chars',
+      },
+    };
+
+    wrapper.find('input').simulate('blur', evt);
+    expect(wrapper.state('error')).toBe(TEST_ERROR_MESSAGE);
+  });
+
+  it('should validate without error onBlur', () => {
+    const wrapper = shallow(<Input validationEvents={testBlurValidation} />);
+    const evt = {
+      persist: jest.fn,
+      target: {
+        value: 'Hi',
+      },
+    };
+
+    wrapper.find('input').simulate('blur', evt);
+    expect(wrapper.state('error')).toBe(null);
+  });
+});

+ 94 - 0
public/app/core/components/Form/Input.tsx

@@ -0,0 +1,94 @@
+import React, { PureComponent } from 'react';
+import classNames from 'classnames';
+import { ValidationEvents, ValidationRule } from 'app/types';
+import { validate, hasValidationEvent } from 'app/core/utils/validate';
+
+export enum InputStatus {
+  Invalid = 'invalid',
+  Valid = 'valid',
+}
+
+export enum InputTypes {
+  Text = 'text',
+  Number = 'number',
+  Password = 'password',
+  Email = 'email',
+}
+
+export enum EventsWithValidation {
+  onBlur = 'onBlur',
+  onFocus = 'onFocus',
+  onChange = 'onChange',
+}
+
+interface Props extends React.HTMLProps<HTMLInputElement> {
+  validationEvents?: ValidationEvents;
+  hideErrorMessage?: boolean;
+
+  // Override event props and append status as argument
+  onBlur?: (event: React.FocusEvent<HTMLInputElement>, status?: InputStatus) => void;
+  onFocus?: (event: React.FocusEvent<HTMLInputElement>, status?: InputStatus) => void;
+  onChange?: (event: React.FormEvent<HTMLInputElement>, status?: InputStatus) => void;
+}
+
+export class Input extends PureComponent<Props> {
+  static defaultProps = {
+    className: '',
+  };
+
+  state = {
+    error: null,
+  };
+
+  get status() {
+    return this.state.error ? InputStatus.Invalid : InputStatus.Valid;
+  }
+
+  get isInvalid() {
+    return this.status === InputStatus.Invalid;
+  }
+
+  validatorAsync = (validationRules: ValidationRule[]) => {
+    return evt => {
+      const errors = validate(evt.target.value, validationRules);
+      this.setState(prevState => {
+        return {
+          ...prevState,
+          error: errors ? errors[0] : null,
+        };
+      });
+    };
+  };
+
+  populateEventPropsWithStatus = (restProps, validationEvents: ValidationEvents) => {
+    const inputElementProps = { ...restProps };
+    Object.keys(EventsWithValidation).forEach((eventName: EventsWithValidation) => {
+      if (hasValidationEvent(eventName, validationEvents) || restProps[eventName]) {
+        inputElementProps[eventName] = async evt => {
+          evt.persist(); // Needed for async. https://reactjs.org/docs/events.html#event-pooling
+          if (hasValidationEvent(eventName, validationEvents)) {
+            await this.validatorAsync(validationEvents[eventName]).apply(this, [evt]);
+          }
+          if (restProps[eventName]) {
+            restProps[eventName].apply(null, [evt, this.status]);
+          }
+        };
+      }
+    });
+    return inputElementProps;
+  };
+
+  render() {
+    const { validationEvents, className, hideErrorMessage, ...restProps } = this.props;
+    const { error } = this.state;
+    const inputClassName = classNames('gf-form-input', { invalid: this.isInvalid }, className);
+    const inputElementProps = this.populateEventPropsWithStatus(restProps, validationEvents);
+
+    return (
+      <div className="our-custom-wrapper-class">
+        <input {...inputElementProps} className={inputClassName} />
+        {error && !hideErrorMessage && <span>{error}</span>}
+      </div>
+    );
+  }
+}

+ 19 - 0
public/app/core/components/Form/Label.tsx

@@ -0,0 +1,19 @@
+import React, { PureComponent, ReactNode } from 'react';
+
+interface Props {
+  children: ReactNode;
+  htmlFor?: string;
+  className?: string;
+}
+
+export class Label extends PureComponent<Props> {
+  render() {
+    const { children, htmlFor, className } = this.props;
+
+    return (
+      <label className={`custom-label-class ${className || ''}`} htmlFor={htmlFor}>
+        {children}
+      </label>
+    );
+  }
+}

+ 11 - 0
public/app/core/components/Form/__snapshots__/Input.test.tsx.snap

@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Input renders correctly 1`] = `
+<div
+  className="our-custom-wrapper-class"
+>
+  <input
+    className="gf-form-input"
+  />
+</div>
+`;

+ 3 - 0
public/app/core/components/Form/index.ts

@@ -0,0 +1,3 @@
+export { Element } from './Element';
+export { Input } from './Input';
+export { Label } from './Label';

+ 51 - 0
public/app/core/components/JSONFormatter/JSONFormatter.tsx

@@ -0,0 +1,51 @@
+import React, { PureComponent, createRef } from 'react';
+// import JSONFormatterJS, { JSONFormatterConfiguration } from 'json-formatter-js';
+import { JsonExplorer } from 'app/core/core'; // We have made some monkey-patching of json-formatter-js so we can't switch right now
+
+interface Props {
+  className?: string;
+  json: {};
+  config?: any;
+  open?: number;
+  onDidRender?: (formattedJson: any) => void;
+}
+
+export class JSONFormatter extends PureComponent<Props> {
+  private wrapperRef = createRef<HTMLDivElement>();
+
+  static defaultProps = {
+    open: 3,
+    config: {
+      animateOpen: true,
+    },
+  };
+
+  componentDidMount() {
+    this.renderJson();
+  }
+
+  componentDidUpdate() {
+    this.renderJson();
+  }
+
+  renderJson = () => {
+    const { json, config, open, onDidRender } = this.props;
+    const wrapperEl = this.wrapperRef.current;
+    const formatter = new JsonExplorer(json, open, config);
+    const hasChildren: boolean = wrapperEl.hasChildNodes();
+    if (hasChildren) {
+      wrapperEl.replaceChild(formatter.render(), wrapperEl.lastChild);
+    } else {
+      wrapperEl.appendChild(formatter.render());
+    }
+
+    if (onDidRender) {
+      onDidRender(formatter.json);
+    }
+  };
+
+  render() {
+    const { className } = this.props;
+    return <div className={className} ref={this.wrapperRef} />;
+  }
+}

+ 1 - 0
public/app/core/components/Label/Label.tsx

@@ -6,6 +6,7 @@ interface Props {
   for?: string;
   children: ReactNode;
   width?: number;
+  className?: string;
 }
 
 export const Label: SFC<Props> = props => {

+ 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 - 25
public/app/core/components/Picker/DescriptionOption.tsx

@@ -1,25 +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, className } = props;
-  return (
-    <components.Option {...props}>
-      <div className={`description-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 className="gf-form">
-          <div className="muted width-17">{data.description}</div>
-        </div>
-      </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 - 22
public/app/core/components/Picker/PickerOption.tsx

@@ -1,22 +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 PickerOption = (props: ExtendedOptionProps) => {
-  const { children, data, className } = props;
-  return (
-    <components.Option {...props}>
-      <div className={`description-picker-option__button btn btn-link ${className}`}>
-        {data.avatarUrl && <img src={data.avatarUrl} alt={data.label} className="user-picker-option__avatar" />}
-        {children}
-      </div>
-    </components.Option>
-  );
-};
-
-export default PickerOption;

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

@@ -1,49 +0,0 @@
-import React, { SFC } from 'react';
-import Select from 'react-select';
-import DescriptionOption from './DescriptionOption';
-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} gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-      components={{
-        Option: DescriptionOption,
-      }}
-      defaultValue={defaultValue}
-      value={value}
-      getOptionLabel={getOptionLabel}
-      getOptionValue={getOptionValue}
-      isSearchable={false}
-      onChange={onSelected}
-      options={options}
-      placeholder={placeholder || 'Choose'}
-      styles={ResetStyles}
-    />
-  );
-};
-
-export default SimplePicker;

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

@@ -1,17 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`PickerOption renders correctly 1`] = `
-<div>
-  <div
-    className="description-picker-option__button btn btn-link class-for-user-picker"
-  >
-    <img
-      alt="User picker label"
-      className="user-picker-option__avatar"
-      src="url/to/avatar"
-    />
-    Model title
-  </div>
-</div>
-`;
-  

+ 32 - 0
public/app/core/components/Portal/Portal.tsx

@@ -0,0 +1,32 @@
+import { PureComponent } from 'react';
+import ReactDOM from 'react-dom';
+
+interface Props {
+  className?: string;
+  root?: HTMLElement;
+}
+
+export default class BodyPortal extends PureComponent<Props> {
+  node: HTMLElement = document.createElement('div');
+  portalRoot: HTMLElement;
+
+  constructor(props) {
+    super(props);
+    const { className, root = document.body } = this.props;
+
+    if (className) {
+      this.node.classList.add(className);
+    }
+
+    this.portalRoot = root;
+    this.portalRoot.appendChild(this.node);
+  }
+
+  componentWillUnmount() {
+    this.portalRoot.removeChild(this.node);
+  }
+
+  render() {
+    return ReactDOM.createPortal(this.props.children, this.node);
+  }
+}

+ 72 - 0
public/app/core/components/Select/DataSourcePicker.tsx

@@ -0,0 +1,72 @@
+// Libraries
+import React, { PureComponent } from 'react';
+import _ from 'lodash';
+
+// Components
+import Select from './Select';
+
+// Types
+import { DataSourceSelectItem } from 'app/types';
+
+export interface Props {
+  onChange: (ds: DataSourceSelectItem) => void;
+  datasources: DataSourceSelectItem[];
+  current: DataSourceSelectItem;
+  onBlur?: () => void;
+  autoFocus?: boolean;
+}
+
+export class DataSourcePicker extends PureComponent<Props> {
+  static defaultProps = {
+    autoFocus: false,
+  };
+
+  searchInput: HTMLElement;
+
+  constructor(props) {
+    super(props);
+  }
+
+  onChange = item => {
+    const ds = this.props.datasources.find(ds => ds.name === item.value);
+    this.props.onChange(ds);
+  };
+
+  render() {
+    const { datasources, current, autoFocus, onBlur } = this.props;
+
+    const options = datasources.map(ds => ({
+      value: ds.name,
+      label: ds.name,
+      imgUrl: ds.meta.info.logos.small,
+    }));
+
+    const value = current && {
+      label: current.name,
+      value: current.name,
+      imgUrl: current.meta.info.logos.small,
+    };
+
+    return (
+      <div className="gf-form-inline">
+        <Select
+          className="ds-picker"
+          isMulti={false}
+          isClearable={false}
+          backspaceRemovesValue={false}
+          onChange={this.onChange}
+          options={options}
+          autoFocus={autoFocus}
+          onBlur={onBlur}
+          openMenuOnFocus={true}
+          maxMenuHeight={500}
+          placeholder="Select datasource"
+          noOptionsMessage={() => 'No datasources found'}
+          value={value}
+        />
+      </div>
+    );
+  }
+}
+
+export default DataSourcePicker;

+ 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;

+ 59 - 0
public/app/core/components/Select/OptionGroup.tsx

@@ -0,0 +1,59 @@
+import React, { PureComponent } from 'react';
+import { GroupProps } from 'react-select/lib/components/Group';
+
+interface ExtendedGroupProps extends GroupProps<any> {
+  data: {
+    label: string;
+    expanded: boolean;
+    options: any[];
+  };
+}
+
+interface State {
+  expanded: boolean;
+}
+
+export default class OptionGroup extends PureComponent<ExtendedGroupProps, State> {
+  state = {
+    expanded: false,
+  };
+
+  componentDidMount() {
+    if (this.props.data.expanded) {
+      this.setState({ expanded: true });
+    } else if (this.props.selectProps && this.props.selectProps.value) {
+      const { value } = this.props.selectProps.value;
+
+      if (value && this.props.options.some(option => option.value === value)) {
+        this.setState({ expanded: true });
+      }
+    }
+  }
+
+  componentDidUpdate(nextProps) {
+    if (nextProps.selectProps.inputValue !== '') {
+      this.setState({ expanded: true });
+    }
+  }
+
+  onToggleChildren = () => {
+    this.setState(prevState => ({
+      expanded: !prevState.expanded,
+    }));
+  };
+
+  render() {
+    const { children, label } = this.props;
+    const { expanded } = this.state;
+
+    return (
+      <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>
+    );
+  }
+}

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

@@ -1,4 +1,4 @@
-import React from 'react';
+import React from 'react';
 import renderer from 'react-test-renderer';
 import PickerOption from './PickerOption';
 
@@ -24,7 +24,7 @@ const model = {
   children: 'Model title',
   data: {
     title: 'Model title',
-    avatarUrl: 'url/to/avatar',
+    imgUrl: 'url/to/avatar',
     label: 'User picker label',
   },
   className: 'class-for-user-picker',

+ 44 - 0
public/app/core/components/Select/PickerOption.tsx

@@ -0,0 +1,44 @@
+import React from 'react';
+import { components } from '@torkelo/react-select';
+import { OptionProps } from 'react-select/lib/components/Option';
+
+// https://github.com/JedWatson/react-select/issues/3038
+interface ExtendedOptionProps extends OptionProps<any> {
+  data: {
+    description?: string;
+    imgUrl?: string;
+  };
+}
+
+export const Option = (props: ExtendedOptionProps) => {
+  const { children, isSelected, data } = props;
+
+  return (
+    <components.Option {...props}>
+      <div className="gf-form-select-box__desc-option">
+        {data.imgUrl && <img className="gf-form-select-box__desc-option__img" src={data.imgUrl} />}
+        <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>
+  );
+};
+
+// was not able to type this without typescript error
+export const SingleValue = props => {
+  const { children, data } = props;
+
+  return (
+    <components.SingleValue {...props}>
+      <div className="gf-form-select-box__img-value">
+        {data.imgUrl && <img className="gf-form-select-box__desc-option__img" src={data.imgUrl} />}
+        {children}
+      </div>
+    </components.SingleValue>
+  );
+};
+
+export default Option;

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

@@ -1,4 +1,4 @@
-export default {
+export default {
   clearIndicator: () => ({}),
   container: () => ({}),
   control: () => ({}),
@@ -11,7 +11,9 @@
   loadingIndicator: () => ({}),
   loadingMessage: () => ({}),
   menu: () => ({}),
-  menuList: () => ({}),
+  menuList: ({ maxHeight }: { maxHeight: number }) => ({
+    maxHeight,
+  }),
   multiValue: () => ({}),
   multiValueLabel: () => ({}),
   multiValueRemove: () => ({}),

+ 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


+ 9 - 18
public/app/core/components/Picker/TeamPicker.tsx → public/app/core/components/Select/TeamPicker.tsx

@@ -1,11 +1,8 @@
 import React, { Component } from 'react';
-import AsyncSelect from 'react-select/lib/Async';
-import PickerOption from './PickerOption';
+import _ from 'lodash';
+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;
@@ -41,13 +38,18 @@ export class TeamPicker extends Component<Props, State> {
     const backendSrv = getBackendSrv();
     this.setState({ isLoading: true });
 
+    if (_.isNil(query)) {
+      query = '';
+    }
+
     return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then(result => {
       const teams = result.teams.map(team => {
         return {
           id: team.id,
+          value: team.id,
           label: team.name,
           name: team.name,
-          avatarUrl: team.avatarUrl,
+          imgUrl: team.avatarUrl,
         };
       });
 
@@ -62,24 +64,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


+ 16 - 18
public/app/core/components/Picker/UserPicker.tsx → public/app/core/components/Select/UserPicker.tsx

@@ -1,12 +1,16 @@
+// Libraries
 import React, { Component } from 'react';
-import AsyncSelect from 'react-select/lib/Async';
-import PickerOption from './PickerOption';
+import _ from 'lodash';
+
+// 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;
@@ -35,13 +39,18 @@ export class UserPicker extends Component<Props, State> {
     const backendSrv = getBackendSrv();
     this.setState({ isLoading: true });
 
+    if (_.isNil(query)) {
+      query = '';
+    }
+
     return backendSrv
       .get(`/api/org/users?query=${query}&limit=10`)
       .then(result => {
         return result.map(user => ({
           id: user.userId,
+          value: user.userId,
           label: user.login === user.email ? user.login : `${user.login} - ${user.email}`,
-          avatarUrl: user.avatarUrl,
+          imgUrl: user.avatarUrl,
           login: user.login,
         }));
       })
@@ -57,24 +66,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>
     );

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

@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PickerOption renders correctly 1`] = `
+<div>
+  <div
+    className="gf-form-select-box__desc-option"
+  >
+    <img
+      className="gf-form-select-box__desc-option__img"
+      src="url/to/avatar"
+    />
+    <div
+      className="gf-form-select-box__desc-option__body"
+    >
+      <div>
+        Model title
+      </div>
+    </div>
+  </div>
+</div>
+`;

+ 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}
           />

+ 9 - 16
public/app/core/components/Switch/Switch.tsx

@@ -5,8 +5,8 @@ export interface Props {
   label: string;
   checked: boolean;
   labelClass?: string;
-  small?: boolean;
   switchClass?: string;
+  transparent?: boolean;
   onChange: (event) => any;
 }
 
@@ -25,27 +25,20 @@ export class Switch extends PureComponent<Props, State> {
   };
 
   render() {
-    const { labelClass = '', switchClass = '', label, checked, small } = this.props;
+    const { labelClass = '', switchClass = '', label, checked, transparent } = this.props;
+
     const labelId = `check-${this.state.id}`;
-    let labelClassName = `gf-form-label ${labelClass} pointer`;
-    let switchClassName = `gf-form-switch ${switchClass}`;
-    if (small) {
-      labelClassName += ' gf-form-label--small';
-      switchClassName += ' gf-form-switch--small';
-    }
+    const labelClassName = `gf-form-label ${labelClass} ${transparent ? 'gf-form-label--transparent' : ''} pointer`;
+    const switchClassName = `gf-form-switch ${switchClass} ${transparent ? 'gf-form-switch--transparent' : ''}`;
 
     return (
-      <div className="gf-form">
-        {label && (
-          <label htmlFor={labelId} className={labelClassName}>
-            {label}
-          </label>
-        )}
+      <label htmlFor={labelId} className="gf-form gf-form-switch-container">
+        {label && <div className={labelClassName}>{label}</div>}
         <div className={switchClassName}>
           <input id={labelId} type="checkbox" checked={checked} onChange={this.internalOnChange} />
-          <label htmlFor={labelId} />
+          <span className="gf-form-switch__slider" />
         </div>
-      </div>
+      </label>
     );
   }
 }

+ 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';
 

+ 18 - 35
public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx

@@ -1,43 +1,20 @@
-import React, { SFC, ReactNode, PureComponent, ReactElement } from 'react';
+import React, { SFC, ReactNode, PureComponent } from 'react';
+import Tooltip from 'app/core/components/Tooltip/Tooltip';
 
 interface ToggleButtonGroupProps {
-  onChange: (value) => void;
-  value?: any;
   label?: string;
-  render: (props) => void;
+  children: JSX.Element[];
+  transparent?: boolean;
 }
 
 export default class ToggleButtonGroup extends PureComponent<ToggleButtonGroupProps> {
-  getValues() {
-    const { children } = this.props;
-    return React.Children.toArray(children).map((c: ReactElement<any>) => c.props.value);
-  }
-
-  smallChildren() {
-    const { children } = this.props;
-    return React.Children.toArray(children).every((c: ReactElement<any>) => c.props.className.includes('small'));
-  }
-
-  handleToggle(toggleValue) {
-    const { value, onChange } = this.props;
-    if (value && value === toggleValue) {
-      return;
-    }
-    onChange(toggleValue);
-  }
-
   render() {
-    const { value, label } = this.props;
-    const values = this.getValues();
-    const selectedValue = value || values[0];
-    const labelClassName = `gf-form-label ${this.smallChildren() ? 'small' : ''}`;
+    const { children, label, transparent } = this.props;
 
     return (
       <div className="gf-form">
-        <div className="toggle-button-group">
-          {label && <label className={labelClassName}>{label}</label>}
-          {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this) })}
-        </div>
+        {label && <label className={`gf-form-label ${transparent ? 'gf-form-label--transparent' : ''}`}>{label}</label>}
+        <div className={`toggle-button-group ${transparent ? 'toggle-button-group--transparent' : ''}`}>{children}</div>
       </div>
     );
   }
@@ -49,15 +26,15 @@ interface ToggleButtonProps {
   value: any;
   className?: string;
   children: ReactNode;
-  title?: string;
+  tooltip?: string;
 }
 
 export const ToggleButton: SFC<ToggleButtonProps> = ({
   children,
   selected,
   className = '',
-  title = null,
-  value,
+  value = null,
+  tooltip,
   onChange,
 }) => {
   const handleChange = event => {
@@ -68,9 +45,15 @@ export const ToggleButton: SFC<ToggleButtonProps> = ({
   };
 
   const btnClassName = `btn ${className} ${selected ? 'active' : ''}`;
-  return (
-    <button className={btnClassName} onClick={handleChange} title={title}>
+  const button = (
+    <button className={btnClassName} onClick={handleChange}>
       <span>{children}</span>
     </button>
   );
+
+  if (tooltip) {
+    return <Tooltip content={tooltip}>{button}</Tooltip>;
+  } else {
+    return button;
+  }
 };

+ 11 - 26
public/app/core/components/Tooltip/Popover.tsx

@@ -1,34 +1,19 @@
-import React from 'react';
-import withTooltip from './withTooltip';
-import { Target } from 'react-popper';
+import React, { PureComponent } from 'react';
+import Popper from './Popper';
+import withPopper, { UsingPopperProps } from './withPopper';
 
-interface PopoverProps {
-  tooltipSetState: (prevState: object) => void;
-}
-
-class Popover extends React.Component<PopoverProps, any> {
-  constructor(props) {
-    super(props);
-    this.toggleTooltip = this.toggleTooltip.bind(this);
-  }
+class Popover extends PureComponent<UsingPopperProps> {
+  render() {
+    const { children, hidePopper, showPopper, className, ...restProps } = this.props;
 
-  toggleTooltip() {
-    const { tooltipSetState } = this.props;
-    tooltipSetState(prevState => {
-      return {
-        ...prevState,
-        show: !prevState.show,
-      };
-    });
-  }
+    const togglePopper = restProps.show ? hidePopper : showPopper;
 
-  render() {
     return (
-      <Target className="popper__target" onClick={this.toggleTooltip}>
-        {this.props.children}
-      </Target>
+      <div className={`popper__manager ${className}`} onClick={togglePopper}>
+        <Popper {...restProps}>{children}</Popper>
+      </div>
     );
   }
 }
 
-export default withTooltip(Popover);
+export default withPopper(Popover);

+ 72 - 0
public/app/core/components/Tooltip/Popper.tsx

@@ -0,0 +1,72 @@
+import React, { PureComponent } from 'react';
+import Portal from 'app/core/components/Portal/Portal';
+import { Manager, Popper as ReactPopper, Reference } from 'react-popper';
+import Transition from 'react-transition-group/Transition';
+
+const defaultTransitionStyles = {
+  transition: 'opacity 200ms linear',
+  opacity: 0,
+};
+
+const transitionStyles = {
+  exited: { opacity: 0 },
+  entering: { opacity: 0 },
+  entered: { opacity: 1 },
+  exiting: { opacity: 0 },
+};
+
+interface Props {
+  renderContent: (content: any) => any;
+  show: boolean;
+  placement?: any;
+  content: string | ((props: any) => JSX.Element);
+  refClassName?: string;
+}
+
+class Popper extends PureComponent<Props> {
+  render() {
+    const { children, renderContent, show, placement, refClassName } = this.props;
+    const { content } = this.props;
+
+    return (
+      <Manager>
+        <Reference>
+          {({ ref }) => (
+            <div className={`popper_ref ${refClassName || ''}`} ref={ref}>
+              {children}
+            </div>
+          )}
+        </Reference>
+        <Transition in={show} timeout={100} mountOnEnter={true} unmountOnExit={true}>
+          {transitionState => (
+            <Portal>
+              <ReactPopper placement={placement}>
+                {({ ref, style, placement, arrowProps }) => {
+                  return (
+                    <div
+                      ref={ref}
+                      style={{
+                        ...style,
+                        ...defaultTransitionStyles,
+                        ...transitionStyles[transitionState],
+                      }}
+                      data-placement={placement}
+                      className="popper"
+                    >
+                      <div className="popper__background">
+                        {renderContent(content)}
+                        <div ref={arrowProps.ref} data-placement={placement} className="popper__arrow" />
+                      </div>
+                    </div>
+                  );
+                }}
+              </ReactPopper>
+            </Portal>
+          )}
+        </Transition>
+      </Manager>
+    );
+  }
+}
+
+export default Popper;

+ 9 - 28
public/app/core/components/Tooltip/Tooltip.tsx

@@ -1,36 +1,17 @@
 import React, { PureComponent } from 'react';
-import withTooltip from './withTooltip';
-import { Target } from 'react-popper';
-
-interface Props {
-  tooltipSetState: (prevState: object) => void;
-}
-
-class Tooltip extends PureComponent<Props> {
-  showTooltip = () => {
-    const { tooltipSetState } = this.props;
-
-    tooltipSetState(prevState => ({
-      ...prevState,
-      show: true,
-    }));
-  };
-
-  hideTooltip = () => {
-    const { tooltipSetState } = this.props;
-    tooltipSetState(prevState => ({
-      ...prevState,
-      show: false,
-    }));
-  };
+import Popper from './Popper';
+import withPopper, { UsingPopperProps } from './withPopper';
 
+class Tooltip extends PureComponent<UsingPopperProps> {
   render() {
+    const { children, hidePopper, showPopper, className, ...restProps } = this.props;
+
     return (
-      <Target className="popper__target" onMouseOver={this.showTooltip} onMouseOut={this.hideTooltip}>
-        {this.props.children}
-      </Target>
+      <div className={`popper__manager ${className}`} onMouseEnter={showPopper} onMouseLeave={hidePopper}>
+        <Popper {...restProps}>{children}</Popper>
+      </div>
     );
   }
 }
 
-export default withTooltip(Tooltip);
+export default withPopper(Tooltip);

+ 2 - 2
public/app/core/components/Tooltip/__snapshots__/Popover.test.tsx.snap

@@ -3,10 +3,10 @@
 exports[`Popover renders correctly 1`] = `
 <div
   className="popper__manager test-class"
+  onClick={[Function]}
 >
   <div
-    className="popper__target"
-    onClick={[Function]}
+    className="popper_ref "
   >
     <button>
       Button with Popover

+ 3 - 3
public/app/core/components/Tooltip/__snapshots__/Tooltip.test.tsx.snap

@@ -3,11 +3,11 @@
 exports[`Tooltip renders correctly 1`] = `
 <div
   className="popper__manager test-class"
+  onMouseEnter={[Function]}
+  onMouseLeave={[Function]}
 >
   <div
-    className="popper__target"
-    onMouseOut={[Function]}
-    onMouseOver={[Function]}
+    className="popper_ref "
   >
     <a
       href="http://www.grafana.com"

+ 88 - 0
public/app/core/components/Tooltip/withPopper.tsx

@@ -0,0 +1,88 @@
+import React from 'react';
+
+export interface UsingPopperProps {
+  showPopper: (prevState: object) => void;
+  hidePopper: (prevState: object) => void;
+  renderContent: (content: any) => any;
+  show: boolean;
+  placement?: string;
+  content: string | ((props: any) => JSX.Element);
+  className?: string;
+  refClassName?: string;
+}
+
+interface Props {
+  placement?: string;
+  className?: string;
+  refClassName?: string;
+  content: string | ((props: any) => JSX.Element);
+}
+
+interface State {
+  placement: string;
+  show: boolean;
+}
+
+export default function withPopper(WrappedComponent) {
+  return class extends React.Component<Props, State> {
+    constructor(props) {
+      super(props);
+      this.setState = this.setState.bind(this);
+      this.state = {
+        placement: this.props.placement || 'auto',
+        show: false,
+      };
+    }
+
+    componentWillReceiveProps(nextProps) {
+      if (nextProps.placement && nextProps.placement !== this.state.placement) {
+        this.setState(prevState => {
+          return {
+            ...prevState,
+            placement: nextProps.placement,
+          };
+        });
+      }
+    }
+
+    showPopper = () => {
+      this.setState(prevState => ({
+        ...prevState,
+        show: true,
+      }));
+    };
+
+    hidePopper = () => {
+      this.setState(prevState => ({
+        ...prevState,
+        show: false,
+      }));
+    };
+
+    renderContent(content) {
+      if (typeof content === 'function') {
+        // If it's a function we assume it's a React component
+        const ReactComponent = content;
+        return <ReactComponent />;
+      }
+      return content;
+    }
+
+    render() {
+      const { show, placement } = this.state;
+      const className = this.props.className || '';
+
+      return (
+        <WrappedComponent
+          {...this.props}
+          showPopper={this.showPopper}
+          hidePopper={this.hidePopper}
+          renderContent={this.renderContent}
+          show={show}
+          placement={placement}
+          className={className}
+        />
+      );
+    }
+  };
+}

+ 0 - 58
public/app/core/components/Tooltip/withTooltip.tsx

@@ -1,58 +0,0 @@
-import React from 'react';
-import { Manager, Popper, Arrow } from 'react-popper';
-
-interface IwithTooltipProps {
-  placement?: string;
-  content: string | ((props: any) => JSX.Element);
-  className?: string;
-}
-
-export default function withTooltip(WrappedComponent) {
-  return class extends React.Component<IwithTooltipProps, any> {
-    constructor(props) {
-      super(props);
-
-      this.setState = this.setState.bind(this);
-      this.state = {
-        placement: this.props.placement || 'auto',
-        show: false,
-      };
-    }
-
-    componentWillReceiveProps(nextProps) {
-      if (nextProps.placement && nextProps.placement !== this.state.placement) {
-        this.setState(prevState => {
-          return {
-            ...prevState,
-            placement: nextProps.placement,
-          };
-        });
-      }
-    }
-
-    renderContent(content) {
-      if (typeof content === 'function') {
-        // If it's a function we assume it's a React component
-        const ReactComponent = content;
-        return <ReactComponent />;
-      }
-      return content;
-    }
-
-    render() {
-      const { content, className } = this.props;
-
-      return (
-        <Manager className={`popper__manager ${className || ''}`}>
-          <WrappedComponent {...this.props} tooltipSetState={this.setState} />
-          {this.state.show ? (
-            <Popper placement={this.state.placement} className="popper">
-              {this.renderContent(content)}
-              <Arrow className="popper__arrow" />
-            </Popper>
-          ) : null}
-        </Manager>
-      );
-    }
-  };
-}

+ 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();

+ 9 - 22
public/app/core/components/colorpicker/ColorPicker.tsx

@@ -1,6 +1,5 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
-import $ from 'jquery';
 import Drop from 'tether-drop';
 import { ColorPickerPopover } from './ColorPickerPopover';
 import { react2AngularDirective } from 'app/core/utils/react2angular';
@@ -11,29 +10,17 @@ export interface Props {
 }
 
 export class ColorPicker extends React.Component<Props, any> {
-  pickerElem: any;
+  pickerElem: HTMLElement;
   colorPickerDrop: any;
 
-  constructor(props) {
-    super(props);
-    this.openColorPicker = this.openColorPicker.bind(this);
-    this.closeColorPicker = this.closeColorPicker.bind(this);
-    this.setPickerElem = this.setPickerElem.bind(this);
-    this.onColorSelect = this.onColorSelect.bind(this);
-  }
-
-  setPickerElem(elem) {
-    this.pickerElem = $(elem);
-  }
-
-  openColorPicker() {
+  openColorPicker = () => {
     const dropContent = <ColorPickerPopover color={this.props.color} onColorSelect={this.onColorSelect} />;
 
     const dropContentElem = document.createElement('div');
     ReactDOM.render(dropContent, dropContentElem);
 
     const drop = new Drop({
-      target: this.pickerElem[0],
+      target: this.pickerElem,
       content: dropContentElem,
       position: 'top center',
       classes: 'drop-popover',
@@ -48,23 +35,23 @@ export class ColorPicker extends React.Component<Props, any> {
 
     this.colorPickerDrop = drop;
     this.colorPickerDrop.open();
-  }
+  };
 
-  closeColorPicker() {
+  closeColorPicker = () => {
     setTimeout(() => {
       if (this.colorPickerDrop && this.colorPickerDrop.tether) {
         this.colorPickerDrop.destroy();
       }
     }, 100);
-  }
+  };
 
-  onColorSelect(color) {
+  onColorSelect = color => {
     this.props.onChange(color);
-  }
+  };
 
   render() {
     return (
-      <div className="sp-replacer sp-light" onClick={this.openColorPicker} ref={this.setPickerElem}>
+      <div className="sp-replacer sp-light" onClick={this.openColorPicker} ref={element => (this.pickerElem = element)}>
         <div className="sp-preview">
           <div className="sp-preview-inner" style={{ backgroundColor: this.props.color }} />
         </div>

+ 1 - 1
public/app/core/components/colorpicker/SeriesColorPicker.tsx

@@ -44,7 +44,7 @@ export class SeriesColorPicker extends React.Component<SeriesColorPickerProps> {
     const drop = new Drop({
       target: this.pickerElem,
       content: dropContentElem,
-      position: 'top center',
+      position: 'bottom center',
       classes: 'drop-popover',
       openOn: 'hover',
       hoverCloseDelay: 200,

+ 2 - 2
public/app/core/components/manage_dashboards/manage_dashboards.html

@@ -64,10 +64,10 @@
 
   <div class="search-results" ng-show="ctrl.sections.length > 0">
     <div class="search-results-filter-row">
-      <gf-form-switch
+      <gf-form-checkbox
         on-change="ctrl.onSelectAllChanged()"
         checked="ctrl.selectAllChecked"
-        switch-class="gf-form-switch--transparent gf-form-switch--search-result-filter-row__checkbox"
+        switch-class="gf-form-checkbox--transparent"
       />
       <div class="search-results-filter-row__filters">
         <div class="gf-form-select-wrapper" ng-show="!(ctrl.canMove || ctrl.canDelete)">

+ 8 - 8
public/app/core/components/search/search_results.html

@@ -1,12 +1,12 @@
 <div ng-repeat="section in ctrl.results" class="search-section">
   <div class="search-section__header pointer" ng-hide="section.hideHeader" ng-class="{'selected': section.selected}" ng-click="ctrl.toggleFolderExpand(section)">
-    <div ng-click="ctrl.toggleSelection(section, $event)">
-      <gf-form-switch
+    <div ng-click="ctrl.toggleSelection(section, $event)" class="center-vh">
+      <gf-form-checkbox
          ng-show="ctrl.editable"
          on-change="ctrl.selectionChanged($event)"
          checked="section.checked"
-         switch-class="gf-form-switch--transparent gf-form-switch--search-result__section">
-      </gf-form-switch>
+         switch-class="gf-form-checkbox--transparent">
+      </gf-form-checkbox>
     </div>
     <i class="search-section__header__icon" ng-class="section.icon"></i>
     <span class="search-section__header__text">{{::section.title}}</span>
@@ -21,13 +21,13 @@
 
   <div ng-if="section.expanded">
     <a ng-repeat="item in section.items" class="search-item search-item--indent" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}" >
-      <div ng-click="ctrl.toggleSelection(item, $event)">
-        <gf-form-switch
+      <div ng-click="ctrl.toggleSelection(item, $event)" class="center-vh">
+        <gf-form-checkbox
            ng-show="ctrl.editable"
            on-change="ctrl.selectionChanged()"
            checked="item.checked"
-           switch-class="gf-form-switch--transparent gf-form-switch--search-result__item">
-        </gf-form-switch>
+           switch-class="gf-form-checkbox--transparent">
+        </gf-form-checkbox>
       </div>
       <span class="search-item__icon">
         <i class="gicon mini gicon-dashboard-list"></i>

+ 45 - 9
public/app/core/components/switch.ts

@@ -1,16 +1,33 @@
 import coreModule from 'app/core/core_module';
 
 const template = `
-<label for="check-{{ctrl.id}}" class="gf-form-label {{ctrl.labelClass}} pointer" ng-show="ctrl.label">
-  {{ctrl.label}}
-  <info-popover mode="right-normal" ng-if="ctrl.tooltip" position="top center">
-    {{ctrl.tooltip}}
-  </info-popover>
+<label for="check-{{ctrl.id}}" class="gf-form-switch-container">
+  <div class="gf-form-label {{ctrl.labelClass}}" ng-show="ctrl.label">
+    {{ctrl.label}}
+    <info-popover mode="right-normal" ng-if="ctrl.tooltip" position="top center">
+      {{ctrl.tooltip}}
+    </info-popover>
+  </div>
+  <div class="gf-form-switch {{ctrl.switchClass}}" ng-if="ctrl.show">
+    <input id="check-{{ctrl.id}}" type="checkbox" ng-model="ctrl.checked" ng-change="ctrl.internalOnChange()">
+    <span class="gf-form-switch__slider"></span>
+  </div>
+</label>
+`;
+
+const checkboxTemplate = `
+<label for="check-{{ctrl.id}}" class="gf-form-switch-container">
+   <div class="gf-form-label {{ctrl.labelClass}}" ng-show="ctrl.label">
+    {{ctrl.label}}
+    <info-popover mode="right-normal" ng-if="ctrl.tooltip" position="top center">
+      {{ctrl.tooltip}}
+    </info-popover>
+  </div>
+  <div class="gf-form-checkbox {{ctrl.switchClass}}" ng-if="ctrl.show">
+    <input id="check-{{ctrl.id}}" type="checkbox" ng-model="ctrl.checked" ng-change="ctrl.internalOnChange()">
+    <span class="gf-form-switch__checkbox"></span>
+  </div>
 </label>
-<div class="gf-form-switch {{ctrl.switchClass}}" ng-if="ctrl.show">
-  <input id="check-{{ctrl.id}}" type="checkbox" ng-model="ctrl.checked" ng-change="ctrl.internalOnChange()">
-  <label for="check-{{ctrl.id}}" data-on="Yes" data-off="No"></label>
-</div>
 `;
 
 export class SwitchCtrl {
@@ -51,4 +68,23 @@ export function switchDirective() {
   };
 }
 
+export function checkboxDirective() {
+  return {
+    restrict: 'E',
+    controller: SwitchCtrl,
+    controllerAs: 'ctrl',
+    bindToController: true,
+    scope: {
+      checked: '=',
+      label: '@',
+      labelClass: '@',
+      tooltip: '@',
+      switchClass: '@',
+      onChange: '&',
+    },
+    template: checkboxTemplate,
+  };
+}
+
 coreModule.directive('gfFormSwitch', switchDirective);
+coreModule.directive('gfFormCheckbox', checkboxDirective);

+ 4 - 0
public/app/core/constants.ts

@@ -11,3 +11,7 @@ export const LS_PANEL_COPY_KEY = 'panel-copy';
 
 export const DASHBOARD_TOOLBAR_HEIGHT = 55;
 export const DASHBOARD_TOP_PADDING = 20;
+
+export const PANEL_HEADER_HEIGHT = 27;
+export const PANEL_BORDER = 2;
+export const PANEL_OPTIONS_KEY_PREFIX = 'options-';

+ 6 - 3
public/app/core/directives/dash_class.ts

@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import _ from 'lodash';
 import coreModule from '../core_module';
 
@@ -5,18 +6,20 @@ import coreModule from '../core_module';
 function dashClass($timeout) {
   return {
     link: ($scope, elem) => {
+      const body = $('body');
+
       $scope.ctrl.dashboard.events.on('view-mode-changed', panel => {
         console.log('view-mode-changed', panel.fullscreen);
         if (panel.fullscreen) {
-          elem.addClass('panel-in-fullscreen');
+          body.addClass('panel-in-fullscreen');
         } else {
           $timeout(() => {
-            elem.removeClass('panel-in-fullscreen');
+            body.removeClass('panel-in-fullscreen');
           });
         }
       });
 
-      elem.toggleClass('panel-in-fullscreen', $scope.ctrl.dashboard.meta.fullscreen === true);
+      body.toggleClass('panel-in-fullscreen', $scope.ctrl.dashboard.meta.fullscreen === true);
 
       $scope.$watch('ctrl.dashboardViewState.state.editview', newValue => {
         if (newValue) {

+ 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),
   },
 };
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio