Merge branch 'master' of github.com:grafana/grafana

This commit is contained in:
Torkel Ödegaard
2016-02-29 13:43:18 +01:00
13 changed files with 52 additions and 23 deletions
+1
View File
@@ -22,6 +22,7 @@
* **Admin**: Admin can now have global overview of Grafana setup, closes [#3812](https://github.com/grafana/grafana/issues/3812)
* **graph**: Right side legend height is now fixed at row height, closes [#1277](https://github.com/grafana/grafana/issues/1277)
* **Table**: All content in table panel is now html escaped, closes [#3673](https://github.com/grafana/grafana/issues/3673)
* **graph**: Template variables can now be used in TimeShift and TimeFrom, closes[#1960](https://github.com/grafana/grafana/issues/1960)
### Bug fixes
* **Playlist**: Fix for memory leak when running a playlist, closes [#3794](https://github.com/grafana/grafana/pull/3794)
+3 -2
View File
@@ -43,8 +43,9 @@ func Register(r *macaron.Macaron) {
r.Get("/admin/orgs/edit/:id", reqGrafanaAdmin, Index)
r.Get("/admin/stats", reqGrafanaAdmin, Index)
r.Get("/apps", reqSignedIn, Index)
r.Get("/apps/edit/*", reqSignedIn, Index)
r.Get("/plugins", reqSignedIn, Index)
r.Get("/plugins/:id/edit", reqSignedIn, Index)
r.Get("/plugins/:id/page/:page", reqSignedIn, Index)
r.Get("/dashboard/*", reqSignedIn, Index)
r.Get("/dashboard-solo/*", reqSignedIn, Index)
+2 -2
View File
@@ -85,13 +85,13 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
if plugin.Pinned {
pageLink := &dtos.NavLink{
Text: plugin.Name,
Url: setting.AppSubUrl + "/apps/" + plugin.Id + "/edit",
Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/edit",
Img: plugin.Info.Logos.Small,
}
for _, page := range plugin.Pages {
pageLink.Children = append(pageLink.Children, &dtos.NavLink{
Url: setting.AppSubUrl + "/apps/" + plugin.Id + "/page/" + page.Slug,
Url: setting.AppSubUrl + "/plugins/" + plugin.Id + "/page/" + page.Slug,
Text: page.Name,
})
}
@@ -47,6 +47,9 @@ function (coreModule, kbn, rangeUtil) {
if (ctrl.$isEmpty(modelValue)) {
return true;
}
if (viewValue.indexOf('$') === 0) {
return true; // allow template variable
}
var info = rangeUtil.describeTextRange(viewValue);
return info.invalid !== true;
};
@@ -140,7 +140,11 @@ function (angular, $, _, moment) {
};
p.isSubmenuFeaturesEnabled = function() {
return this.templating.list.length > 0 || this.annotations.list.length > 0 || this.links.length > 0;
var visableTemplates = _.filter(this.templating.list, function(template) {
return template.hideVariable === undefined || template.hideVariable === false;
});
return visableTemplates.length > 0 || this.annotations.list.length > 0 || this.links.length > 0;
};
p.getPanelInfoById = function(panelId) {
@@ -1,6 +1,6 @@
<div class="submenu-controls">
<ul ng-if="ctrl.dashboard.templating.list.length > 0">
<li ng-repeat="variable in ctrl.variables" class="submenu-item">
<li ng-repeat="variable in ctrl.variables" ng-show="!variable.hideVariable" class="submenu-item">
<span class="submenu-item-label template-variable " ng-show="!variable.hideLabel">
{{variable.label || variable.name}}:
</span>
@@ -23,6 +23,7 @@
<thead>
<tr>
<th><strong>name</strong></th>
<th><strong>type</strong></th>
<th><strong>url</strong></th>
<th style="width: 60px;"></th>
<th style="width: 85px;"></th>
@@ -37,7 +38,10 @@
</a>
</td>
<td>
<span class="ellipsis">{{ds.url}}</span>
<span>{{ds.type}}</span>
</td>
<td>
<span>{{ds.url}}</span>
</td>
<td class="text-center">
<span ng-if="ds.isDefault">
@@ -17,6 +17,7 @@ class MetricsPanelCtrl extends PanelCtrl {
$timeout: any;
datasourceSrv: any;
timeSrv: any;
templateSrv: any;
timing: any;
range: any;
rangeRaw: any;
@@ -34,6 +35,7 @@ class MetricsPanelCtrl extends PanelCtrl {
this.$q = $injector.get('$q');
this.datasourceSrv = $injector.get('datasourceSrv');
this.timeSrv = $injector.get('timeSrv');
this.templateSrv = $injector.get('templateSrv');
if (!this.panel.targets) {
this.panel.targets = [{}];
@@ -119,7 +121,8 @@ class MetricsPanelCtrl extends PanelCtrl {
// check panel time overrrides
if (this.panel.timeFrom) {
var timeFromInfo = rangeUtil.describeTextRange(this.panel.timeFrom);
var timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
var timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
if (timeFromInfo.invalid) {
this.timeInfo = 'invalid time override';
return;
@@ -136,13 +139,14 @@ class MetricsPanelCtrl extends PanelCtrl {
}
if (this.panel.timeShift) {
var timeShiftInfo = rangeUtil.describeTextRange(this.panel.timeShift);
var timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
var timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
if (timeShiftInfo.invalid) {
this.timeInfo = 'invalid timeshift';
return;
}
var timeShift = '-' + this.panel.timeShift;
var timeShift = '-' + timeShiftInterpolated;
this.timeInfo += ' timeshift ' + timeShift;
this.range.from = dateMath.parseDateMath(timeShift, this.range.from, false);
this.range.to = dateMath.parseDateMath(timeShift, this.range.to, true);
@@ -1,4 +1,4 @@
<navbar icon="icon-gf icon-gf-apps" title="{{ctrl.appModel.name}}" title-url="apps/{{ctrl.pluginId}}/edit">
<navbar icon="icon-gf icon-gf-apps" title="{{ctrl.appModel.name}}" title-url="plugins/{{ctrl.pluginId}}/edit">
</navbar>
<div class="page-container">
@@ -91,11 +91,17 @@
</div>
</div>
</div>
<div class="gf-form">
<span class="gf-form-label width-7">Label</span>
<input type="text" class="gf-form-input max-width-14" ng-model='current.label' placeholder="optional display name"></input>
<editor-checkbox class="width-13" text="Hide label" model="current.hideLabel" change="runQuery()"></editor-checkbox>
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-7">Label</span>
<input type="text" class="gf-form-input max-width-14" ng-model='current.label' placeholder="optional display name"></input>
</div>
<div class="gf-form">
<editor-checkbox class="width-10" text="Hide label" model="current.hideLabel" change="runQuery()"></editor-checkbox>
<editor-checkbox class="width-11" text="Hide variable" model="current.hideVariable" change="runQuery()"></editor-checkbox>
</div>
</div>
</div>
<h5 class="section-heading">Value Options</h5>
@@ -167,13 +167,13 @@
<i class="fa fa-remove pointer" ng-click="ctrl.removeValueMap(map)"></i>
</li>
<li>
<input type="text" ng-model="ctrl.map.value" placeholder="value" class="input-mini tight-form-input" ng-blur="ctrl.render()">
<input type="text" ng-model="map.value" placeholder="value" class="input-mini tight-form-input" ng-blur="ctrl.render()">
</li>
<li class="tight-form-item">
<i class="fa fa-arrow-right"></i>
</li>
<li ng-repeat-end>
<input type="text" placeholder="text" ng-model="ctrl.map.text" class="input-mini tight-form-input" ng-blur="ctrl.render()">
<input type="text" placeholder="text" ng-model="map.text" class="input-mini tight-form-input" ng-blur="ctrl.render()">
</li>
<li>
@@ -50,7 +50,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
unitFormats: any[];
/** @ngInject */
constructor($scope, $injector, private $location, private linkSrv, private templateSrv) {
constructor($scope, $injector, private $location, private linkSrv) {
super($scope, $injector);
_.defaults(this.panel, panelDefaults);
}
@@ -213,7 +213,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
// value/number to text mapping
var value = parseFloat(map.value);
if (value === data.value) {
if (value === data.valueRounded) {
data.valueFormated = map.text;
return;
}
@@ -69,14 +69,20 @@ describe('SingleStatCtrl', function() {
singleStatScenario('When value to text mapping is specified', function(ctx) {
ctx.setup(function() {
ctx.datapoints = [[10,1]];
ctx.datapoints = [[9.9,1]];
ctx.ctrl.panel.valueMaps = [{value: '10', text: 'OK'}];
});
it('Should replace value with text', function() {
expect(ctx.data.value).to.be(10);
expect(ctx.data.valueFormated).to.be('OK');
it('value should remain', function() {
expect(ctx.data.value).to.be(9.9);
});
it('round should be rounded up', function() {
expect(ctx.data.valueRounded).to.be(10);
});
it('Should replace value with text', function() {
expect(ctx.data.valueFormated).to.be('OK');
});
});
});