From 87fc83678ce0baef4daa2fcf5b388cd87e40c5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 11 Feb 2016 21:02:01 +0100 Subject: [PATCH 001/133] feat(imports): work on datasource dashboards --- public/app/features/dashboard/all.js | 1 + .../dashboard/import_list/import_list.ts | 50 +++++++++++++++++++ public/app/features/datasources/edit_ctrl.js | 2 - .../features/datasources/partials/edit.html | 2 + .../graphite/dashboards/carbon_stats.json | 21 ++++++++ 5 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 public/app/features/dashboard/import_list/import_list.ts create mode 100644 public/app/plugins/datasource/graphite/dashboards/carbon_stats.json diff --git a/public/app/features/dashboard/all.js b/public/app/features/dashboard/all.js index 073ca2ae1d9..65338c3d0f1 100644 --- a/public/app/features/dashboard/all.js +++ b/public/app/features/dashboard/all.js @@ -13,6 +13,7 @@ define([ './timeSrv', './unsavedChangesSrv', './timepicker/timepicker', + './import_list/import_list', './graphiteImportCtrl', './dynamicDashboardSrv', './importCtrl', diff --git a/public/app/features/dashboard/import_list/import_list.ts b/public/app/features/dashboard/import_list/import_list.ts new file mode 100644 index 00000000000..f229e56d425 --- /dev/null +++ b/public/app/features/dashboard/import_list/import_list.ts @@ -0,0 +1,50 @@ +/// + +import angular from 'angular'; +import coreModule from 'app/core/core_module'; + +class DashboardScriptLoader { + +} + +export class DashImportListCtrl { + constructor(private $http) { + console.log('importList', this); + } + + load(json) { + var model = angular.fromJson(json); + console.log(model); + } + + import() { + var url = 'public/app/plugins/datasource/graphite/dashboards/carbon_stats.json'; + this.$http.get(url).then(res => { + this.load(res.data); + }); + } +} + +var template = ` + diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json new file mode 100644 index 00000000000..642f32b6e6a --- /dev/null +++ b/public/app/plugins/datasource/graphite/dashboards/carbon_stats.json @@ -0,0 +1,21 @@ +{ + "__inputs": { + "graphite": { + "type": "datasource", + "description": "Graphite datasource" + } + }, + + "title": "Carbon stats", + "version": 1, + "rows": [ + { + "panels": [ + { + "type": "graph", + "datasource": "__$graphite" + } + ] + } + ] +} From 00dd0e8a9d8a267aaf4470cbf5b23596289cb591 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 3 Mar 2016 11:02:18 +0100 Subject: [PATCH 002/133] fix(plugins): fixes missed dist loading for plugindir closes #4230 --- pkg/plugins/plugins.go | 6 ------ pkg/util/filepath.go | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index dcf8a9f0630..db674e5522a 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -89,12 +89,6 @@ func scan(pluginDir string) error { pluginPath: pluginDir, } - log.Info("Plugins: Scaning dir %s", pluginDir) - if util.ContainsDistFolder(pluginDir) { - log.Info("Plugins: Found dist folder in %s", pluginDir) - pluginDir = filepath.Join(pluginDir, "dist") - } - if err := util.Walk(pluginDir, true, true, scanner.walker); err != nil { if pluginDir != "data/plugins" { log.Warn("Could not scan dir \"%v\" error: %s", pluginDir, err) diff --git a/pkg/util/filepath.go b/pkg/util/filepath.go index c70f9260197..3ad8cac3147 100644 --- a/pkg/util/filepath.go +++ b/pkg/util/filepath.go @@ -80,35 +80,50 @@ func walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollow if err != nil { return walkFn(resolvedPath, info, err) } + var subFiles = make([]subFile, 0) for _, fileInfo := range list { path2 := filepath.Join(path, fileInfo.Name()) var resolvedPath2 string if resolvedPath != "" { resolvedPath2 = filepath.Join(resolvedPath, fileInfo.Name()) } - err = walk(path2, fileInfo, resolvedPath2, symlinkPathsFollowed, walkFn) + subFiles = append(subFiles, subFile{path: path2, resolvedPath: resolvedPath2, fileInfo: fileInfo}) + } + + if containsDistFolder(subFiles) { + err := walk( + filepath.Join(path, "dist"), + info, + filepath.Join(resolvedPath, "dist"), + symlinkPathsFollowed, + walkFn) + if err != nil { return err } + } else { + for _, p := range subFiles { + err = walk(p.path, p.fileInfo, p.resolvedPath, symlinkPathsFollowed, walkFn) + + if err != nil { + return err + } + } } + return nil } return nil } -func ContainsDistFolder(path string) bool { - info, err := os.Lstat(path) - if err != nil { - return false - } +type subFile struct { + path, resolvedPath string + fileInfo os.FileInfo +} - if !info.IsDir() { - return false - } - - list, err := ioutil.ReadDir(path) - for _, fileInfo := range list { - if fileInfo.IsDir() && fileInfo.Name() == "dist" { +func containsDistFolder(subFiles []subFile) bool { + for _, p := range subFiles { + if p.fileInfo.IsDir() && p.fileInfo.Name() == "dist" { return true } } From 662579e9a9770e3689e39c1f191e52490ef6417d Mon Sep 17 00:00:00 2001 From: utkarshcmu Date: Thu, 3 Mar 2016 02:08:51 -0800 Subject: [PATCH 003/133] Added preferences migrations --- .../sqlstore/migrations/migrations.go | 1 + .../sqlstore/migrations/preferences_mig.go | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 pkg/services/sqlstore/migrations/preferences_mig.go diff --git a/pkg/services/sqlstore/migrations/migrations.go b/pkg/services/sqlstore/migrations/migrations.go index 28ea3035bcd..21eb3601281 100644 --- a/pkg/services/sqlstore/migrations/migrations.go +++ b/pkg/services/sqlstore/migrations/migrations.go @@ -21,6 +21,7 @@ func AddMigrations(mg *Migrator) { addAppSettingsMigration(mg) addSessionMigration(mg) addPlaylistMigrations(mg) + addPreferencesMigrations(mg) } func addMigrationLogMigrations(mg *Migrator) { diff --git a/pkg/services/sqlstore/migrations/preferences_mig.go b/pkg/services/sqlstore/migrations/preferences_mig.go new file mode 100644 index 00000000000..0ce01857b75 --- /dev/null +++ b/pkg/services/sqlstore/migrations/preferences_mig.go @@ -0,0 +1,20 @@ +package migrations + +import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator" + +func addPreferencesMigrations(mg *Migrator) { + + preferencesV1 := Table{ + Name: "preferences", + Columns: []*Column{ + {Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, + {Name: "pref_id", Type: DB_Int, Nullable: false}, + {Name: "pref_type", Type: DB_NVarchar, Length: 255, Nullable: false}, + {Name: "pref_data", Type: DB_Text, Nullable: false}, + }, + } + + // create table + mg.AddMigration("create preferences table v1", NewAddTableMigration(preferencesV1)) + +} From 01d32828384bc63524b7ff289dbf3b8ae05e2fa0 Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 2 Mar 2016 18:01:43 +0100 Subject: [PATCH 004/133] docs(plugins): add initial documentation for datasource plugins --- docs/sources/plugins/datasources.md | 55 ++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/sources/plugins/datasources.md b/docs/sources/plugins/datasources.md index c33b033ffa3..41055cf84ed 100644 --- a/docs/sources/plugins/datasources.md +++ b/docs/sources/plugins/datasources.md @@ -4,6 +4,59 @@ page_description: Datasource plugins for Grafana page_keywords: grafana, plugins, documentation --- + > Our goal is not to have a very extensive documentation but rather have actual code that people can look at. An example implementation of a datasource can be found in the grafana repo under /examples/datasource-plugin-genericdatasource + # Datasources -TODO \ No newline at end of file +Datasource plugins enables people to develop plugins for any database that commuicates over http. Its up to the plugin to transform the data into time series data so that any grafana panel can then show it. + +To interact with the rest of grafana the plugins module file can export 5 different components. + +- Datasource (Required) +- QueryCtrl (Required) +- ConfigCtrl (Required) +- QueryOptionsCtrl +- AnnotationsQueryCtrl + +## Plugin json +There are two datasource specific settings for the plugin.json +``` +"metrics": true, +"annotations": false, +``` +These settings idicates what kind of data the plugin can deliver. Atleast one of them have to be true + +## Datasource +The javascript object that communicates with the database and transforms data to times series. + +The Datasource should contain the following functions. +``` +query(options) //used by panels to get data +testDatasource() //used by datasource configuration page to make sure the connection is working +annotationsQuery(options) // used dashboards to get annotations +metricFindQuery(options) // used by query editor to get metric suggestions. +``` + +## QueryCtrl + +A javascript class that will be instantiated and treated as an Angular controller when the user edits metrics in a panel. This class have to inherit from the app/plugins/sdk.QueryCtrl class. + +Requires a static template or templateUrl variable which will be rendered as the view for this controller. + +## ConfigCtrl + +A javascript class that will be instantiated and treated as an Angular controller when a user tries to edit or create a new datasource of this type. + +Requires a static template or templateUrl variable which will be rendered as the view for this controller. + +## QueryOptionsCtrl + +A javascript class that will be instantiated and treated as an Angular controller when the user edits metrics in a panel. This controller is responsible for handling panel wide settings for the datasource. Such as interval, rate and aggregations if needed. + +Requires a static template or templateUrl variable which will be rendered as the view for this controller. + +## AnnotationsQueryCtrl + +A javascript class that will be instantiated and treated as an Angular controller when the user choose this type of datasource in the templating menu in the dashboard. + +Requires a static template or templateUrl variable which will be rendered as the view for this controller. The fields that are bound to this controller is then sent to the Database objects annotationsQuery function. From ee635be441bcc0b436f78664206fc882e46a10c3 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 3 Mar 2016 13:26:23 +0100 Subject: [PATCH 005/133] docs(mkdocs): remove plugins from ref folder --- docs/mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index e88b5ec4237..ad3cbcd0198 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -62,7 +62,6 @@ pages: - ['reference/templating.md', 'Reference', 'Templating'] - ['reference/scripting.md', 'Reference', 'Scripting'] - ['reference/playlist.md', 'Reference', 'Playlist'] -- ['reference/plugins.md', 'Reference', 'Plugins'] - ['reference/export_import.md', 'Reference', 'Import & Export'] - ['reference/admin.md', 'Reference', 'Administration'] - ['reference/keyboard_shortcuts.md', 'Reference', 'Keyboard Shortcuts'] From 1d8222ef6a4f92f547d1143e340aba0f80518544 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 3 Mar 2016 16:37:21 +0100 Subject: [PATCH 006/133] feat(example): add basic annotation support for ds --- examples/datasource-plugin-genericdatasource/plugin.json | 2 +- .../src/datasource.js | 9 +++++++++ .../datasource-plugin-genericdatasource/src/module.js | 6 +++++- .../src/partials/annotations.editor.html | 9 +++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 examples/datasource-plugin-genericdatasource/src/partials/annotations.editor.html diff --git a/examples/datasource-plugin-genericdatasource/plugin.json b/examples/datasource-plugin-genericdatasource/plugin.json index 4c3a9accd05..5812a9b1bec 100644 --- a/examples/datasource-plugin-genericdatasource/plugin.json +++ b/examples/datasource-plugin-genericdatasource/plugin.json @@ -8,7 +8,7 @@ "staticRoot": ".", "metrics": true, - "annotations": false, + "annotations": true, "info": { "description": "generic datsource plugin", diff --git a/examples/datasource-plugin-genericdatasource/src/datasource.js b/examples/datasource-plugin-genericdatasource/src/datasource.js index 1b68cf61fb1..1a7fe9643dd 100644 --- a/examples/datasource-plugin-genericdatasource/src/datasource.js +++ b/examples/datasource-plugin-genericdatasource/src/datasource.js @@ -37,6 +37,15 @@ export class GenericDatasource { }); } + annotationQuery(options) { + return this.backendSrv.datasourceRequest({ + url: this.url + '/annotations', + method: 'GET' + }).then(result => { + return result.data; + }); + } + // Optional // Required for templating metricFindQuery(options) { diff --git a/examples/datasource-plugin-genericdatasource/src/module.js b/examples/datasource-plugin-genericdatasource/src/module.js index 5dc2f9c89d8..8ab46f4edec 100644 --- a/examples/datasource-plugin-genericdatasource/src/module.js +++ b/examples/datasource-plugin-genericdatasource/src/module.js @@ -7,9 +7,13 @@ GenericConfigCtrl.templateUrl = 'partials/config.html'; class GenericQueryOptionsCtrl {} GenericQueryOptionsCtrl.templateUrl = 'partials/query.options.html'; +class GenericAnnotationsQueryCtrl {} +GenericAnnotationsQueryCtrl.templateUrl = 'partials/annotations.editor.html' + export { GenericDatasource as Datasource, GenericDatasourceQueryCtrl as QueryCtrl, GenericConfigCtrl as ConfigCtrl, - GenericQueryOptionsCtrl as QueryOptionsCtrl + GenericQueryOptionsCtrl as QueryOptionsCtrl, + GenericAnnotationsQueryCtrl as AnnotationsQueryCtrl }; diff --git a/examples/datasource-plugin-genericdatasource/src/partials/annotations.editor.html b/examples/datasource-plugin-genericdatasource/src/partials/annotations.editor.html new file mode 100644 index 00000000000..f4422caa4fc --- /dev/null +++ b/examples/datasource-plugin-genericdatasource/src/partials/annotations.editor.html @@ -0,0 +1,9 @@ + +
Query
+
+
+ +
+
+ + From c21a2101989ed0b303072b9a8fefed60fd7a6236 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 4 Mar 2016 08:45:46 +0100 Subject: [PATCH 007/133] docs(datasource): add request objects to docs --- docs/sources/plugins/datasources.md | 71 ++++++++++++++++++- .../src/datasource.js | 3 +- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/sources/plugins/datasources.md b/docs/sources/plugins/datasources.md index 41055cf84ed..2edb8be5231 100644 --- a/docs/sources/plugins/datasources.md +++ b/docs/sources/plugins/datasources.md @@ -24,7 +24,7 @@ There are two datasource specific settings for the plugin.json "metrics": true, "annotations": false, ``` -These settings idicates what kind of data the plugin can deliver. Atleast one of them have to be true +These settings indicates what kind of data the plugin can deliver. At least one of them have to be true ## Datasource The javascript object that communicates with the database and transforms data to times series. @@ -37,6 +37,75 @@ annotationsQuery(options) // used dashboards to get annotations metricFindQuery(options) // used by query editor to get metric suggestions. ``` +### Query + +Request object passed to datasource.query function +```json +{ + range: { from: '2015-12-22T03:06:13.851Z',to: '2015-12-22T06:48:24.137Z' }, + interval: '5s', + targets: + [ { refId: 'B', target: 'upper_75' }, + { refId: 'A', target: 'upper_90' } ], + format: 'json', + maxDataPoints: 2495 //decided by the panel +} +``` + +Expected response from datasource.query +An array of +```json +[ + { + "target":"upper_75", + "datapoints":[ + [622,1450754160000], + [365,1450754220000] + ] + }, + { + "target":"upper_90", + "datapoints":[ + [861,1450754160000], + [767,1450754220000] + ] + } +] +``` + +### Annotation Query + +Request object passed to datasource.annotationsQuery function +```json +{ + range: { from: '2016-03-04T04:07:55.144Z', to: '2016-03-04T07:07:55.144Z' }, + rangeRaw: { from: 'now-3h', to: 'now' }, + annotation: { + datasource: 'generic datasource', + enable: true, + name: 'annotation name' + } +} +``` + +Expected result from datasource.annotationQuery +```json +[ + { + "annotation": { + "name": "annotation name", //should match the annotation name in grafana + "enabled": true, + "datasource": "generic datasource", + }, + "title": "Cluster outage", + "time": 1457075272576, + "text": "Joe causes brain split", + "tags": "joe, cluster, failure" + } +] +``` + + ## QueryCtrl A javascript class that will be instantiated and treated as an Angular controller when the user edits metrics in a panel. This class have to inherit from the app/plugins/sdk.QueryCtrl class. diff --git a/examples/datasource-plugin-genericdatasource/src/datasource.js b/examples/datasource-plugin-genericdatasource/src/datasource.js index 1a7fe9643dd..a59362f8268 100644 --- a/examples/datasource-plugin-genericdatasource/src/datasource.js +++ b/examples/datasource-plugin-genericdatasource/src/datasource.js @@ -40,7 +40,8 @@ export class GenericDatasource { annotationQuery(options) { return this.backendSrv.datasourceRequest({ url: this.url + '/annotations', - method: 'GET' + method: 'POST', + data: options }).then(result => { return result.data; }); From d318c84434f12cbd544b6a17af13f6ea4f9028e8 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 4 Mar 2016 08:47:22 +0100 Subject: [PATCH 008/133] docs(plugins): add json formating --- docs/sources/plugins/datasources.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/sources/plugins/datasources.md b/docs/sources/plugins/datasources.md index 2edb8be5231..92d20417929 100644 --- a/docs/sources/plugins/datasources.md +++ b/docs/sources/plugins/datasources.md @@ -42,13 +42,13 @@ metricFindQuery(options) // used by query editor to get metric suggestions. Request object passed to datasource.query function ```json { - range: { from: '2015-12-22T03:06:13.851Z',to: '2015-12-22T06:48:24.137Z' }, - interval: '5s', - targets: - [ { refId: 'B', target: 'upper_75' }, - { refId: 'A', target: 'upper_90' } ], - format: 'json', - maxDataPoints: 2495 //decided by the panel + "range": { "from": "2015-12-22T03:06:13.851Z", "to": "2015-12-22T06:48:24.137Z" }, + "interval": '5s', + "targets": + [ { refId: "B", target: "upper_75" }, + { refId: "A", target: "upper_90" } ], + "format": "json", + "maxDataPoints": 2495 //decided by the panel } ``` From c6a1076e3a7b7859bf15a0e8c92f7b9c91d9b691 Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 4 Mar 2016 09:14:25 +0100 Subject: [PATCH 009/133] docs(plugins): json formating --- docs/sources/plugins/datasources.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/sources/plugins/datasources.md b/docs/sources/plugins/datasources.md index 92d20417929..9362dfa8fc7 100644 --- a/docs/sources/plugins/datasources.md +++ b/docs/sources/plugins/datasources.md @@ -44,9 +44,10 @@ Request object passed to datasource.query function { "range": { "from": "2015-12-22T03:06:13.851Z", "to": "2015-12-22T06:48:24.137Z" }, "interval": '5s', - "targets": - [ { refId: "B", target: "upper_75" }, - { refId: "A", target: "upper_90" } ], + "targets": [ + { refId: "B", target: "upper_75" }, + { refId: "A", target: "upper_90" } + ], "format": "json", "maxDataPoints": 2495 //decided by the panel } From a6623357ad0425938ea0468a296ebce128da5283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 3 Mar 2016 22:31:07 +0100 Subject: [PATCH 010/133] ux(): minor tweak to validation state --- public/sass/base/_forms.scss | 15 --------------- public/sass/utils/_validation.scss | 5 +++-- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/public/sass/base/_forms.scss b/public/sass/base/_forms.scss index 25a95fafde8..4f1d0778e0b 100644 --- a/public/sass/base/_forms.scss +++ b/public/sass/base/_forms.scss @@ -143,21 +143,6 @@ input[type="checkbox"][readonly] { background-color: transparent; } - -// HTML5 invalid states -// Shares styles with the .control-group.error above -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; - &:focus { - border-color: darken(#ee5f5b, 10%); - $shadow: 0 0 6px lighten(#ee5f5b, 20%); - @include box-shadow($shadow); - } -} - input[type=text].input-fluid { width: 100%; box-sizing: border-box; diff --git a/public/sass/utils/_validation.scss b/public/sass/utils/_validation.scss index b59b65f6a54..1145212707e 100644 --- a/public/sass/utils/_validation.scss +++ b/public/sass/utils/_validation.scss @@ -1,7 +1,8 @@ input[type=text].ng-dirty.ng-invalid { - box-shadow: inset 0 0px 7px $red; } input.ng-dirty.ng-invalid { - color: $errorText; + box-shadow: inset 0 0px 5px $red; } + + From 31c317f5f7815ffcf3751e735755ad15bffa20d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Mar 2016 09:42:21 +0100 Subject: [PATCH 011/133] fix(graphite editor): fixed moving functions right and left, broken recently, fixes #3246 --- public/app/plugins/datasource/graphite/func_editor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/graphite/func_editor.js b/public/app/plugins/datasource/graphite/func_editor.js index cd1f747bc4d..57cdc844375 100644 --- a/public/app/plugins/datasource/graphite/func_editor.js +++ b/public/app/plugins/datasource/graphite/func_editor.js @@ -208,7 +208,7 @@ function (angular, _, $) { if ($target.hasClass('fa-arrow-left')) { $scope.$apply(function() { - _.move($scope.functions, $scope.$index, $scope.$index - 1); + _.move(ctrl.functions, $scope.$index, $scope.$index - 1); ctrl.targetChanged(); }); return; @@ -216,7 +216,7 @@ function (angular, _, $) { if ($target.hasClass('fa-arrow-right')) { $scope.$apply(function() { - _.move($scope.functions, $scope.$index, $scope.$index + 1); + _.move(ctrl.functions, $scope.$index, $scope.$index + 1); ctrl.targetChanged(); }); return; From ac499b3affa36b46100f27eb48d417efdbeacbac Mon Sep 17 00:00:00 2001 From: utkarshcmu Date: Fri, 4 Mar 2016 01:29:46 -0800 Subject: [PATCH 012/133] Minor Pre-PR fixes --- pkg/services/sqlstore/migrations/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/sqlstore/migrations/migrations.go b/pkg/services/sqlstore/migrations/migrations.go index 21eb3601281..7a6ba554246 100644 --- a/pkg/services/sqlstore/migrations/migrations.go +++ b/pkg/services/sqlstore/migrations/migrations.go @@ -21,7 +21,7 @@ func AddMigrations(mg *Migrator) { addAppSettingsMigration(mg) addSessionMigration(mg) addPlaylistMigrations(mg) - addPreferencesMigrations(mg) + addPreferencesMigrations(mg) } func addMigrationLogMigrations(mg *Migrator) { From 4b08f3909d9bbf59d7565728579eeddb35bc1775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Mar 2016 11:16:15 +0100 Subject: [PATCH 013/133] fix(graph): legend height calculation now takes into account series hidden from legend, fixes #4245 --- public/app/core/time_series2.ts | 17 +++++++++++++++++ public/app/plugins/panel/graph/graph.js | 13 +++++++++---- public/app/plugins/panel/graph/legend.js | 15 ++------------- public/app/plugins/panel/graph/module.ts | 1 + .../plugins/panel/graph/specs/graph_specs.ts | 16 ++++++++-------- public/sass/components/_panel_graph.scss | 6 ++++-- 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts index e17d4c53f5a..f5fcf5bd50c 100644 --- a/public/app/core/time_series2.ts +++ b/public/app/core/time_series2.ts @@ -180,4 +180,21 @@ export default class TimeSeries { } return false; } + + hideFromLegend(options) { + if (options.hideEmpty && this.allIsNull) { + return true; + } + // ignore series excluded via override + if (!this.legend) { + return true; + } + + // ignore zero series + if (options.hideZero && this.allIsZero) { + return true; + } + + return false; + } } diff --git a/public/app/plugins/panel/graph/graph.js b/public/app/plugins/panel/graph/graph.js index c7490d1133d..f88c2716299 100755 --- a/public/app/plugins/panel/graph/graph.js +++ b/public/app/plugins/panel/graph/graph.js @@ -69,8 +69,13 @@ function (angular, $, moment, _, kbn, GraphTooltip) { if (!panel.legend.show || panel.legend.rightSide) { return 0; } + if (panel.legend.alignAsTable) { - var total = 30 + (25 * data.length); + var legendSeries = _.filter(data, function(series) { + return series.hideFromLegend(panel.legend) === false; + }); + console.log(legendSeries.length); + var total = 23 + (22 * legendSeries.length); return Math.min(total, Math.floor(panelHeight/2)); } else { return 26; @@ -85,13 +90,14 @@ function (angular, $, moment, _, kbn, GraphTooltip) { } graphHeight -= 5; // padding - graphHeight -= panel.title ? 24 : 9; // subtract panel title bar + graphHeight -= panel.title ? 25 : 5; // subtract panel title bar graphHeight = graphHeight - getLegendHeight(graphHeight); // subtract one line legend elem.css('height', graphHeight + 'px'); return true; } catch(e) { // IE throws errors sometimes + console.log(e); return false; } } @@ -107,7 +113,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) { if (!setElementHeight()) { return true; } - if (_.isString(data)) { + if(_.isString(data)) { render_panel_as_graphite_png(data); return true; } @@ -226,7 +232,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) { for (var i = 0; i < data.length; i++) { var series = data[i]; - series.applySeriesOverrides(panel.seriesOverrides); series.data = series.getFlotPairs(series.nullPointMode || panel.nullPointMode, panel.y_formats); // if hidden remove points and disable stack diff --git a/public/app/plugins/panel/graph/legend.js b/public/app/plugins/panel/graph/legend.js index 8ff5d5dd83e..c69f6144a9f 100644 --- a/public/app/plugins/panel/graph/legend.js +++ b/public/app/plugins/panel/graph/legend.js @@ -145,16 +145,7 @@ function (angular, _, $) { for (i = 0; i < seriesList.length; i++) { var series = seriesList[i]; - // ignore empty series - if (panel.legend.hideEmpty && series.allIsNull) { - continue; - } - // ignore series excluded via override - if (!series.legend) { - continue; - } - // ignore zero series - if (panel.legend.hideZero && series.allIsZero) { + if (series.hideFromLegend(panel.legend)) { continue; } @@ -166,9 +157,7 @@ function (angular, _, $) { html += ''; html += ''; - html += '
'; - html += '' + _.escape(series.label) + ''; - html += '
'; + html += '' + _.escape(series.label) + ''; if (panel.legend.values) { var avg = series.formatValue(series.stats.avg); diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index bf89648b717..88c92ee320a 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -205,6 +205,7 @@ class GraphCtrl extends MetricsPanelCtrl { this.panel.tooltip.msResolution = this.panel.tooltip.msResolution || series.isMsResolutionNeeded(); } + series.applySeriesOverrides(this.panel.seriesOverrides); return series; } diff --git a/public/app/plugins/panel/graph/specs/graph_specs.ts b/public/app/plugins/panel/graph/specs/graph_specs.ts index ce8ccfe33d2..dae90224ff8 100644 --- a/public/app/plugins/panel/graph/specs/graph_specs.ts +++ b/public/app/plugins/panel/graph/specs/graph_specs.ts @@ -5,8 +5,8 @@ import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../.. import '../module'; import angular from 'angular'; import $ from 'jquery'; -import helpers from '../../../../../test/specs/helpers'; -import TimeSeries from '../../../../core/time_series2'; +import helpers from 'test/specs/helpers'; +import TimeSeries from 'app/core/time_series2'; import moment from 'moment'; describe('grafanaGraph', function() { @@ -182,11 +182,10 @@ describe('grafanaGraph', function() { ctx.setup(function(ctrl, data) { ctrl.panel.lines = true; ctrl.panel.fill = 5; - ctrl.panel.seriesOverrides = [ - { alias: 'test', fill: 0, points: true } - ]; - + data[0].zindex = 10; data[1].alias = 'test'; + data[1].lines = {fill: 0.001}; + data[1].points = {show: true}; }); it('should match second series and fill zero, and enable points', function() { @@ -197,8 +196,9 @@ describe('grafanaGraph', function() { }); graphScenario('should order series order according to zindex', function(ctx) { - ctx.setup(function(ctrl) { - ctrl.panel.seriesOverrides = [{ alias: 'series1', zindex: 2 }]; + ctx.setup(function(ctrl, data) { + data[1].zindex = 1; + data[0].zindex = 10; }); it('should move zindex 2 last', function() { diff --git a/public/sass/components/_panel_graph.scss b/public/sass/components/_panel_graph.scss index 3f0e104e48c..f58f3094fe0 100644 --- a/public/sass/components/_panel_graph.scss +++ b/public/sass/components/_panel_graph.scss @@ -39,6 +39,7 @@ .graph-legend-icon, .graph-legend-alias, .graph-legend-value { + cursor: pointer; float: left; white-space: nowrap; font-size: 85%; @@ -79,7 +80,7 @@ .graph-legend-table { width: 100%; - margin: 0; + margin-top: 4px; .graph-legend-series { display: table-row; @@ -174,7 +175,8 @@ } .graph-legend-series-hidden { - a { + .graph-legend-value, + .graph-legend-alias { color: $link-color-disabled; } } From b673bc138677abbe315153ed5da552a7b9ad03a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Mar 2016 12:13:40 +0100 Subject: [PATCH 014/133] ux(): minor fix to login page --- public/app/partials/login.html | 34 ++++++++++--------- .../plugins/datasource/graphite/datasource.ts | 5 ++- public/sass/pages/_login.scss | 6 +++- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/public/app/partials/login.html b/public/app/partials/login.html index 3608a56f99b..b63e587c00e 100644 --- a/public/app/partials/login.html +++ b/public/app/partials/login.html @@ -39,25 +39,27 @@ -