diff --git a/bower.json b/bower.json
index 557ee9c9f8f..2624254acbe 100644
--- a/bower.json
+++ b/bower.json
@@ -13,7 +13,7 @@
"tests"
],
"dependencies": {
- "jquery": "~2.1.4",
+ "jquery": "~2.2.4",
"angular": "~1.5.3",
"angular-route": "~1.5.3",
"angular-mocks": "~1.5.3",
diff --git a/package.json b/package.json
index ba12e20c020..f33695438b9 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"company": "Coding Instinct AB"
},
"name": "grafana",
- "version": "3.1.0",
+ "version": "3.1.1",
"repository": {
"type": "git",
"url": "http://github.com/grafana/grafana.git"
diff --git a/public/app/core/routes/routes.ts b/public/app/core/routes/routes.ts
index 487e9deef27..baf77c32b30 100644
--- a/public/app/core/routes/routes.ts
+++ b/public/app/core/routes/routes.ts
@@ -30,6 +30,7 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/dashboard-solo/:type/:slug', {
templateUrl: 'public/app/features/panel/partials/soloPanel.html',
controller : 'SoloPanelCtrl',
+ reloadOnSearch: false,
pageClass: 'page-dashboard',
})
.when('/dashboard/new', {
diff --git a/public/app/features/dashboard/dashboardSrv.js b/public/app/features/dashboard/dashboardSrv.js
index 937d5266c56..19590ec0c0e 100644
--- a/public/app/features/dashboard/dashboardSrv.js
+++ b/public/app/features/dashboard/dashboardSrv.js
@@ -16,10 +16,6 @@ function (angular, $, _, moment) {
data = {};
}
- if (!data.id && data.version) {
- data.schemaVersion = data.version;
- }
-
this.id = data.id || null;
this.title = data.title || 'No Title';
this.autoUpdate = data.autoUpdate;
diff --git a/public/app/features/dashboard/timeSrv.js b/public/app/features/dashboard/timeSrv.js
index cd52155ff5f..c6d0b754e85 100644
--- a/public/app/features/dashboard/timeSrv.js
+++ b/public/app/features/dashboard/timeSrv.js
@@ -13,6 +13,8 @@ define([
module.service('timeSrv', function($rootScope, $timeout, $routeParams, timer) {
var self = this;
+ $rootScope.$on('zoom-out', function(e, factor) { self.zoomOut(factor); });
+
this.init = function(dashboard) {
timer.cancel_all();
@@ -137,6 +139,24 @@ define([
return {from: from, to: to};
};
+ this.zoomOut = function(factor) {
+ var range = this.timeRange();
+
+ var timespan = (range.to.valueOf() - range.from.valueOf());
+ var center = range.to.valueOf() - timespan/2;
+
+ var to = (center + (timespan*factor)/2);
+ var from = (center - (timespan*factor)/2);
+
+ if (to > Date.now() && range.to <= Date.now()) {
+ var offset = to - Date.now();
+ from = from - offset;
+ to = Date.now();
+ }
+
+ this.setTime({from: moment.utc(from), to: moment.utc(to) });
+ };
+
});
});
diff --git a/public/app/features/dashboard/timepicker/timepicker.ts b/public/app/features/dashboard/timepicker/timepicker.ts
index b22ec162dd6..e1b853e6d55 100644
--- a/public/app/features/dashboard/timepicker/timepicker.ts
+++ b/public/app/features/dashboard/timepicker/timepicker.ts
@@ -29,7 +29,6 @@ export class TimePickerCtrl {
constructor(private $scope, private $rootScope, private timeSrv) {
$scope.ctrl = this;
- $rootScope.onAppEvent('zoom-out', () => this.zoom(2), $scope);
$rootScope.onAppEvent('shift-time-forward', () => this.move(1), $scope);
$rootScope.onAppEvent('shift-time-backward', () => this.move(-1), $scope);
$rootScope.onAppEvent('refresh', () => this.init(), $scope);
@@ -72,21 +71,7 @@ export class TimePickerCtrl {
}
zoom(factor) {
- var range = this.timeSrv.timeRange();
-
- var timespan = (range.to.valueOf() - range.from.valueOf());
- var center = range.to.valueOf() - timespan/2;
-
- var to = (center + (timespan*factor)/2);
- var from = (center - (timespan*factor)/2);
-
- if (to > Date.now() && range.to <= Date.now()) {
- var offset = to - Date.now();
- from = from - offset;
- to = Date.now();
- }
-
- this.timeSrv.setTime({from: moment.utc(from), to: moment.utc(to) });
+ this.$rootScope.appEvent('zoom-out', 2);
}
move(direction) {
diff --git a/public/app/features/dashboard/viewStateSrv.js b/public/app/features/dashboard/viewStateSrv.js
index 035bfb6ae6e..2ea365c3b49 100644
--- a/public/app/features/dashboard/viewStateSrv.js
+++ b/public/app/features/dashboard/viewStateSrv.js
@@ -107,9 +107,12 @@ function (angular, _, $) {
this.dashboard.meta.fullscreen = this.state.fullscreen;
if (!this.state.fullscreen) {
- this.state.panelId = null;
this.state.fullscreen = null;
this.state.edit = null;
+ // clear panel id unless in solo mode
+ if (!this.dashboard.meta.soloMode) {
+ this.state.panelId = null;
+ }
}
$location.search(this.serializeToUrl());
@@ -193,11 +196,13 @@ function (angular, _, $) {
var self = this;
self.panelScopes.push(panelScope);
- if (self.state.panelId === panelScope.ctrl.panel.id) {
- if (self.state.edit) {
- panelScope.ctrl.editPanel();
- } else {
- panelScope.ctrl.viewPanel();
+ if (!self.dashboard.meta.soloMode) {
+ if (self.state.panelId === panelScope.ctrl.panel.id) {
+ if (self.state.edit) {
+ panelScope.ctrl.editPanel();
+ } else {
+ panelScope.ctrl.viewPanel();
+ }
}
}
diff --git a/public/app/features/panel/solo_panel_ctrl.js b/public/app/features/panel/solo_panel_ctrl.js
index 0eb271675ee..de299d7f9fe 100644
--- a/public/app/features/panel/solo_panel_ctrl.js
+++ b/public/app/features/panel/solo_panel_ctrl.js
@@ -17,15 +17,12 @@ function (angular, $) {
var params = $location.search();
panelId = parseInt(params.panelId);
- // add fullscreen param;
- params.fullscreen = true;
- $location.search(params);
+ $scope.onAppEvent("dashboard-initialized", $scope.initPanelScope);
dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug).then(function(result) {
+ result.meta.soloMode = true;
$scope.initDashboard(result, $scope);
});
-
- $scope.onAppEvent("dashboard-initialized", $scope.initPanelScope);
};
$scope.initPanelScope = function() {
diff --git a/public/app/features/templating/templateValuesSrv.js b/public/app/features/templating/templateValuesSrv.js
index fb751a2ce3a..9ecb02f0a0b 100644
--- a/public/app/features/templating/templateValuesSrv.js
+++ b/public/app/features/templating/templateValuesSrv.js
@@ -10,6 +10,7 @@ function (angular, _, kbn) {
module.service('templateValuesSrv', function($q, $rootScope, datasourceSrv, $location, templateSrv, timeSrv) {
var self = this;
+ this.variableLock = {};
function getNoneOption() { return { text: 'None', value: '', isNone: true }; }
@@ -90,6 +91,8 @@ function (angular, _, kbn) {
} else {
lock.resolve();
}
+ }).finally(function() {
+ delete self.variableLock[variable.name];
});
};
@@ -124,7 +127,7 @@ function (angular, _, kbn) {
templateSrv.setGrafanaVariable('$__auto_interval', interval);
};
- this.setVariableValue = function(variable, option, initPhase) {
+ this.setVariableValue = function(variable, option) {
variable.current = angular.copy(option);
if (_.isArray(variable.current.text)) {
@@ -134,13 +137,7 @@ function (angular, _, kbn) {
self.selectOptionsForCurrentValue(variable);
templateSrv.updateTemplateData();
- // on first load, variable loading is ordered to ensure
- // that parents are updated before children.
- if (initPhase) {
- return $q.when();
- }
-
- return self.updateOptionsInChildVariables(variable);
+ return this.updateOptionsInChildVariables(variable);
};
this.variableUpdated = function(variable) {
@@ -149,6 +146,11 @@ function (angular, _, kbn) {
};
this.updateOptionsInChildVariables = function(updatedVariable) {
+ // if there is a variable lock ignore cascading update because we are in a boot up scenario
+ if (self.variableLock[updatedVariable.name]) {
+ return $q.when();
+ }
+
var promises = _.map(self.variables, function(otherVariable) {
if (otherVariable === updatedVariable) {
return;
diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js
index 8e736c75e6f..2e3d36c2925 100644
--- a/public/app/plugins/datasource/elasticsearch/datasource.js
+++ b/public/app/plugins/datasource/elasticsearch/datasource.js
@@ -205,13 +205,8 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
};
function escapeForJson(value) {
- return value
- .replace(/\s/g, '\\ ')
- .replace(/\"/g, '\\"');
- }
-
- function luceneThenJsonFormat(value) {
- return escapeForJson(templateSrv.luceneFormat(value));
+ var luceneQuery = JSON.stringify(value);
+ return luceneQuery.substr(1, luceneQuery.length - 2);
}
this.getFields = function(query) {
@@ -256,7 +251,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
var header = this.getQueryHeader('count', range.from, range.to);
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
- esQuery = esQuery.replace("$lucene_query", escapeForJson(queryDef.query || '*'));
+ esQuery = esQuery.replace("$lucene_query", escapeForJson(queryDef.query));
esQuery = esQuery.replace(/\$timeFrom/g, range.from.valueOf());
esQuery = esQuery.replace(/\$timeTo/g, range.to.valueOf());
esQuery = header + '\n' + esQuery + '\n';
@@ -270,8 +265,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
};
this.metricFindQuery = function(query) {
- query = templateSrv.replace(query, {}, luceneThenJsonFormat);
query = angular.fromJson(query);
+ query.query = templateSrv.replace(query.query || '*', {}, 'lucene');
+
if (!query) {
return $q.when([]);
}
diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts
index efb107e3b16..3fb82526256 100644
--- a/public/app/plugins/datasource/graphite/datasource.ts
+++ b/public/app/plugins/datasource/graphite/datasource.ts
@@ -40,7 +40,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
};
if (options.panelId) {
- httpOptions.requestId = 'panel' + options.panelId;
+ httpOptions.requestId = this.name + '.panelId.' + options.panelId;
}
return this.doGraphiteRequest(httpOptions).then(this.convertDataPointsToMs);
diff --git a/public/app/plugins/datasource/graphite/specs/datasource_specs.ts b/public/app/plugins/datasource/graphite/specs/datasource_specs.ts
index 237c37cfcc7..df7300d65eb 100644
--- a/public/app/plugins/datasource/graphite/specs/datasource_specs.ts
+++ b/public/app/plugins/datasource/graphite/specs/datasource_specs.ts
@@ -5,7 +5,7 @@ import {GraphiteDatasource} from "../datasource";
describe('graphiteDatasource', function() {
var ctx = new helpers.ServiceTestContext();
- var instanceSettings: any = {url: ['']};
+ var instanceSettings: any = {url: [''], name: 'graphiteProd'};
beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.services'));
@@ -24,9 +24,10 @@ describe('graphiteDatasource', function() {
describe('When querying influxdb with one target using query editor target spec', function() {
var query = {
- rangeRaw: { from: 'now-1h', to: 'now' },
- targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}],
- maxDataPoints: 500,
+ panelId: 3,
+ rangeRaw: { from: 'now-1h', to: 'now' },
+ targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}],
+ maxDataPoints: 500,
};
var results;
@@ -46,6 +47,10 @@ describe('graphiteDatasource', function() {
expect(requestOptions.url).to.be('/render');
});
+ it('should set unique requestId', function() {
+ expect(requestOptions.requestId).to.be('graphiteProd.panelId.3');
+ });
+
it('should query correctly', function() {
var params = requestOptions.data.split('&');
expect(params).to.contain('target=prod1.count');
diff --git a/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json
index e008317a96e..0c2e0e85728 100644
--- a/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json
+++ b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json
@@ -167,7 +167,7 @@
"valueName": "current"
},
{
- "content": "\nPrometheus\n\n
You're using Prometheus, an open-source systems monitoring and alerting toolkit originally built at SoundCloud. For more information, check out the Grafana and Prometheus projects.
", + "content": "You're using Prometheus, an open-source systems monitoring and alerting toolkit originally built at SoundCloud. For more information, check out the Grafana and Prometheus projects.
", "editable": true, "error": false, "id": 9, diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index b543e933b90..8fbde9e84a1 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -157,7 +157,7 @@ class GraphCtrl extends MetricsPanelCtrl { } zoomOut(evt) { - this.publishAppEvent('zoom-out', evt); + this.publishAppEvent('zoom-out', 2); } onDataSnapshotLoad(snapshotData) { diff --git a/public/vendor/jquery/.bower.json b/public/vendor/jquery/.bower.json index 49cf1b54efb..25f5cf87975 100644 --- a/public/vendor/jquery/.bower.json +++ b/public/vendor/jquery/.bower.json @@ -1,39 +1,25 @@ { "name": "jquery", - "version": "2.1.4", "main": "dist/jquery.js", "license": "MIT", "ignore": [ - "**/.*", - "build", - "dist/cdn", - "speed", - "test", - "*.md", - "AUTHORS.txt", - "Gruntfile.js", "package.json" ], - "devDependencies": { - "sizzle": "2.1.1-jquery.2.1.2", - "requirejs": "2.1.10", - "qunit": "1.14.0", - "sinon": "1.8.1" - }, "keywords": [ "jquery", "javascript", + "browser", "library" ], - "homepage": "https://github.com/jquery/jquery", - "_release": "2.1.4", + "homepage": "https://github.com/jquery/jquery-dist", + "version": "2.2.4", + "_release": "2.2.4", "_resolution": { "type": "version", - "tag": "2.1.4", - "commit": "7751e69b615c6eca6f783a81e292a55725af6b85" + "tag": "2.2.4", + "commit": "c0185ab7c75aab88762c5aae780b9d83b80eda72" }, - "_source": "git://github.com/jquery/jquery.git", - "_target": "~2.1.4", - "_originalSource": "jquery", - "_direct": true + "_source": "https://github.com/jquery/jquery-dist.git", + "_target": "~2.2.4", + "_originalSource": "jquery" } \ No newline at end of file diff --git a/public/vendor/jquery/AUTHORS.txt b/public/vendor/jquery/AUTHORS.txt new file mode 100644 index 00000000000..dde64cac7ac --- /dev/null +++ b/public/vendor/jquery/AUTHORS.txt @@ -0,0 +1,278 @@ +Authors ordered by first contribution. + +John Resig