+
Users
-
-
- Id |
- Name |
- Login |
- Email |
- Grafana Admin |
- |
-
-
- {{user.id}} |
- {{user.name}} |
- {{user.login}} |
- {{user.email}} |
- {{user.isAdmin}} |
-
-
-
- Edit
-
-
-
-
-
- |
-
+
diff --git a/public/app/features/annotations/annotationsSrv.js b/public/app/features/annotations/annotationsSrv.js
index 89c9b72ec1f..f131ad28393 100644
--- a/public/app/features/annotations/annotationsSrv.js
+++ b/public/app/features/annotations/annotationsSrv.js
@@ -7,14 +7,14 @@ define([
var module = angular.module('grafana.services');
- module.service('annotationsSrv', function(datasourceSrv, $q, alertSrv, $rootScope) {
+ module.service('annotationsSrv', function($rootScope, $q, datasourceSrv, alertSrv, timeSrv) {
var promiseCached;
var list = [];
var self = this;
this.init = function() {
$rootScope.onAppEvent('refresh', this.clearCache, $rootScope);
- $rootScope.onAppEvent('setup-dashboard', this.clearCache, $rootScope);
+ $rootScope.onAppEvent('dashboard-loaded', this.clearCache, $rootScope);
};
this.clearCache = function() {
@@ -22,7 +22,7 @@ define([
list = [];
};
- this.getAnnotations = function(rangeUnparsed, dashboard) {
+ this.getAnnotations = function(dashboard) {
if (dashboard.annotations.list.length === 0) {
return $q.when(null);
}
@@ -34,9 +34,13 @@ define([
self.dashboard = dashboard;
var annotations = _.where(dashboard.annotations.list, {enable: true});
+ var range = timeSrv.timeRange();
+ var rangeRaw = timeSrv.timeRange(false);
+
var promises = _.map(annotations, function(annotation) {
return datasourceSrv.get(annotation.datasource).then(function(datasource) {
- return datasource.annotationQuery(annotation, rangeUnparsed)
+ var query = {range: range, rangeRaw: rangeRaw, annotation: annotation};
+ return datasource.annotationQuery(query)
.then(self.receiveAnnotationResults)
.then(null, errorHandler);
}, this);
diff --git a/public/app/features/dashboard/dashboardCtrl.js b/public/app/features/dashboard/dashboardCtrl.js
index 80b3a101f3f..eb2aa3bad89 100644
--- a/public/app/features/dashboard/dashboardCtrl.js
+++ b/public/app/features/dashboard/dashboardCtrl.js
@@ -1,10 +1,10 @@
define([
'angular',
'jquery',
- 'config',
- 'lodash',
+ 'app/core/config',
+ 'moment',
],
-function (angular, $, config) {
+function (angular, $, config, moment) {
"use strict";
var module = angular.module('grafana.controllers');
@@ -150,6 +150,10 @@ function (angular, $, config) {
});
};
+ $scope.formatDate = function(date) {
+ return moment(date).format('MMM Do YYYY, h:mm:ss a');
+ };
+
});
});
diff --git a/public/app/features/dashboard/dashboardLoaderSrv.js b/public/app/features/dashboard/dashboardLoaderSrv.js
index 85e6374e0a3..f578a9d1075 100644
--- a/public/app/features/dashboard/dashboardLoaderSrv.js
+++ b/public/app/features/dashboard/dashboardLoaderSrv.js
@@ -3,7 +3,7 @@ define([
'moment',
'lodash',
'jquery',
- 'kbn',
+ 'app/core/utils/kbn',
'app/core/utils/datemath',
],
function (angular, moment, _, $, kbn, dateMath) {
diff --git a/public/app/features/dashboard/dashboardNavCtrl.js b/public/app/features/dashboard/dashboardNavCtrl.js
index eef2a8595a7..f367652d0c4 100644
--- a/public/app/features/dashboard/dashboardNavCtrl.js
+++ b/public/app/features/dashboard/dashboardNavCtrl.js
@@ -1,9 +1,7 @@
define([
'angular',
'lodash',
- 'config',
- 'store',
- 'filesaver'
+ 'vendor/filesaver'
],
function (angular, _) {
'use strict';
@@ -51,6 +49,21 @@ function (angular, _) {
$scope.appEvent('hide-dash-search');
};
+ $scope.makeEditable = function() {
+ $scope.dashboard.editable = true;
+
+ var clone = $scope.dashboard.getSaveModelClone();
+
+ backendSrv.saveDashboard(clone, {overwrite: false}).then(function(data) {
+ $scope.dashboard.version = data.version;
+ $scope.appEvent('dashboard-saved', $scope.dashboard);
+ $scope.appEvent('alert-success', ['Dashboard saved', 'Saved as ' + clone.title]);
+
+ //force refresh whole page
+ window.location.href = window.location.href;
+ }, $scope.handleSaveDashError);
+ };
+
$scope.saveDashboard = function(options) {
if ($scope.dashboardMeta.canSave === false) {
return;
diff --git a/public/app/features/dashboard/dashboardSrv.js b/public/app/features/dashboard/dashboardSrv.js
index 21318ac8370..559adff5c54 100644
--- a/public/app/features/dashboard/dashboardSrv.js
+++ b/public/app/features/dashboard/dashboardSrv.js
@@ -1,11 +1,10 @@
define([
'angular',
'jquery',
- 'kbn',
'lodash',
'moment',
],
-function (angular, $, kbn, _, moment) {
+function (angular, $, _, moment) {
'use strict';
var module = angular.module('grafana.services');
@@ -27,7 +26,7 @@ function (angular, $, kbn, _, moment) {
this.tags = data.tags || [];
this.style = data.style || "dark";
this.timezone = data.timezone || 'browser';
- this.editable = data.editable === false ? false : true;
+ this.editable = data.editable !== false;
this.hideControls = data.hideControls || false;
this.sharedCrosshair = data.sharedCrosshair || false;
this.rows = data.rows || [];
@@ -49,10 +48,10 @@ function (angular, $, kbn, _, moment) {
p._initMeta = function(meta) {
meta = meta || {};
- meta.canShare = meta.canShare === false ? false : true;
- meta.canSave = meta.canSave === false ? false : true;
- meta.canStar = meta.canStar === false ? false : true;
- meta.canEdit = meta.canEdit === false ? false : true;
+ meta.canShare = meta.canShare !== false;
+ meta.canSave = meta.canSave !== false;
+ meta.canStar = meta.canStar !== false;
+ meta.canEdit = meta.canEdit !== false;
if (!this.editable) {
meta.canEdit = false;
@@ -152,7 +151,6 @@ function (angular, $, kbn, _, moment) {
result.panel = panel;
result.row = row;
result.index = index;
- return;
}
});
});
@@ -216,10 +214,7 @@ function (angular, $, kbn, _, moment) {
};
p.formatDate = function(date, format) {
- if (!moment.isMoment(date)) {
- date = moment(date);
- }
-
+ date = moment.isMoment(date) ? date : moment(date);
format = format || 'YYYY-MM-DD HH:mm:ss';
return this.timezone === 'browser' ?
@@ -227,13 +222,21 @@ function (angular, $, kbn, _, moment) {
moment.utc(date).format(format);
};
+ p.getRelativeTime = function(date) {
+ date = moment.isMoment(date) ? date : moment(date);
+
+ return this.timezone === 'browser' ?
+ moment(date).fromNow() :
+ moment.utc(date).fromNow();
+ };
+
p._updateSchema = function(old) {
var i, j, k;
var oldVersion = this.schemaVersion;
var panelUpgrades = [];
- this.schemaVersion = 7;
+ this.schemaVersion = 8;
- if (oldVersion === 7) {
+ if (oldVersion === 8) {
return;
}
@@ -344,6 +347,49 @@ function (angular, $, kbn, _, moment) {
});
}
+ if (oldVersion < 8) {
+ panelUpgrades.push(function(panel) {
+ _.each(panel.targets, function(target) {
+ // update old influxdb query schema
+ if (target.fields && target.tags && target.groupBy) {
+ if (target.rawQuery) {
+ delete target.fields;
+ delete target.fill;
+ } else {
+ target.select = _.map(target.fields, function(field) {
+ var parts = [];
+ parts.push({type: 'field', params: [field.name]});
+ parts.push({type: field.func, params: []});
+ if (field.mathExpr) {
+ parts.push({type: 'math', params: [field.mathExpr]});
+ }
+ if (field.asExpr) {
+ parts.push({type: 'alias', params: [field.asExpr]});
+ }
+ return parts;
+ });
+ delete target.fields;
+ _.each(target.groupBy, function(part) {
+ if (part.type === 'time' && part.interval) {
+ part.params = [part.interval];
+ delete part.interval;
+ }
+ if (part.type === 'tag' && part.key) {
+ part.params = [part.key];
+ delete part.key;
+ }
+ });
+
+ if (target.fill) {
+ target.groupBy.push({type: 'fill', params: [target.fill]});
+ delete target.fill;
+ }
+ }
+ }
+ });
+ });
+ }
+
if (panelUpgrades.length === 0) {
return;
}
diff --git a/public/app/features/dashboard/graphiteImportCtrl.js b/public/app/features/dashboard/graphiteImportCtrl.js
index 2b6660c2a22..53338883274 100644
--- a/public/app/features/dashboard/graphiteImportCtrl.js
+++ b/public/app/features/dashboard/graphiteImportCtrl.js
@@ -1,7 +1,7 @@
define([
'angular',
'lodash',
- 'kbn'
+ 'app/core/utils/kbn'
],
function (angular, _, kbn) {
'use strict';
diff --git a/public/app/features/dashboard/keybindings.js b/public/app/features/dashboard/keybindings.js
index b417382bc45..2219cab2d4c 100644
--- a/public/app/features/dashboard/keybindings.js
+++ b/public/app/features/dashboard/keybindings.js
@@ -33,7 +33,7 @@ function(angular, $) {
}, { inputDisabled: true });
- keyboardManager.bind('ctrl+f', function() {
+ keyboardManager.bind('f', function() {
scope.appEvent('show-dash-search');
}, { inputDisabled: true });
diff --git a/public/app/features/dashboard/partials/dashboardTopNav.html b/public/app/features/dashboard/partials/dashboardTopNav.html
index 49fd6f412ac..c2e4d75cd95 100644
--- a/public/app/features/dashboard/partials/dashboardTopNav.html
+++ b/public/app/features/dashboard/partials/dashboardTopNav.html
@@ -37,6 +37,7 @@
Templating
Export
View JSON
+ Make Editable
Save As...
Delete dashboard
diff --git a/public/app/features/dashboard/partials/globalAlerts.html b/public/app/features/dashboard/partials/globalAlerts.html
new file mode 100644
index 00000000000..a849f50ffdd
--- /dev/null
+++ b/public/app/features/dashboard/partials/globalAlerts.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
Global alerts
+
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
diff --git a/public/app/features/dashboard/partials/graphiteImport.html b/public/app/features/dashboard/partials/graphiteImport.html
index 343b5d52e41..9c351346fe6 100644
--- a/public/app/features/dashboard/partials/graphiteImport.html
+++ b/public/app/features/dashboard/partials/graphiteImport.html
@@ -25,7 +25,7 @@
|
diff --git a/public/app/features/dashboard/partials/settings.html b/public/app/features/dashboard/partials/settings.html
index 543fad9de22..9b0e5674fe0 100644
--- a/public/app/features/dashboard/partials/settings.html
+++ b/public/app/features/dashboard/partials/settings.html
@@ -5,7 +5,7 @@
-
@@ -77,28 +77,30 @@
+
+
diff --git a/public/app/features/dashboard/partials/shareModal.html b/public/app/features/dashboard/partials/shareModal.html
index 75af7ee4c22..a8db481ca91 100644
--- a/public/app/features/dashboard/partials/shareModal.html
+++ b/public/app/features/dashboard/partials/shareModal.html
@@ -107,7 +107,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Drag and drop between the two lists.
-
-
-
-
Beasts
-
-
Left column of beasts is not draggable and accepts both beasts and priests
-
-
-
-
-
-
-
-
Priests
-
-
-
-
-
-
-
-
Terrorists
-
-
Each terrorist list item accepts a new terrorist. Shows inserting into a particular
- position in an array.
-
-
-
-
-
-
-
-
-