Merge branch 'master' into graphite-series-by-tags

This commit is contained in:
Torkel Ödegaard
2017-11-16 16:20:44 +01:00
82 changed files with 10934 additions and 165 deletions

View File

@@ -63,7 +63,9 @@
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag" class="label label-tag">
{{tag}}
</span>
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
<span ng-click="ctrl.starDashboard(row, $event)">
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
</span>
</span>
<span class="search-result-link">

View File

@@ -19,7 +19,7 @@ export class SearchCtrl {
openCompleted: boolean;
/** @ngInject */
constructor($scope, private $location, private $timeout, private backendSrv, public contextSrv, $rootScope) {
constructor($scope, private $location, private $timeout, private backendSrv, private dashboardSrv, public contextSrv, $rootScope) {
$rootScope.onAppEvent('show-dash-search', this.openSearch.bind(this), $scope);
$rootScope.onAppEvent('hide-dash-search', this.closeSearch.bind(this), $scope);
}
@@ -161,6 +161,15 @@ export class SearchCtrl {
this.searchDashboards();
}
starDashboard(row, evt) {
this.dashboardSrv.starDashboard(row.id, row.isStarred).then(newState => {
row.isStarred = newState;
});
if (evt) {
evt.stopPropagation();
evt.preventDefault();
}
}
}
export function searchDirective() {

View File

@@ -475,6 +475,7 @@ kbn.valueFormats.wpm = kbn.formatBuilders.simpleCountUnit('wpm');
// Energy
kbn.valueFormats.watt = kbn.formatBuilders.decimalSIPrefix('W');
kbn.valueFormats.kwatt = kbn.formatBuilders.decimalSIPrefix('W', 1);
kbn.valueFormats.mwatt = kbn.formatBuilders.decimalSIPrefix('W', -1);
kbn.valueFormats.kwattm = kbn.formatBuilders.decimalSIPrefix('W/Min', 1);
kbn.valueFormats.voltamp = kbn.formatBuilders.decimalSIPrefix('VA');
kbn.valueFormats.kvoltamp = kbn.formatBuilders.decimalSIPrefix('VA', 1);
@@ -486,8 +487,10 @@ kbn.valueFormats.joule = kbn.formatBuilders.decimalSIPrefix('J');
kbn.valueFormats.ev = kbn.formatBuilders.decimalSIPrefix('eV');
kbn.valueFormats.amp = kbn.formatBuilders.decimalSIPrefix('A');
kbn.valueFormats.kamp = kbn.formatBuilders.decimalSIPrefix('A', 1);
kbn.valueFormats.mamp = kbn.formatBuilders.decimalSIPrefix('A', -1);
kbn.valueFormats.volt = kbn.formatBuilders.decimalSIPrefix('V');
kbn.valueFormats.kvolt = kbn.formatBuilders.decimalSIPrefix('V', 1);
kbn.valueFormats.mvolt = kbn.formatBuilders.decimalSIPrefix('V', -1);
kbn.valueFormats.dBm = kbn.formatBuilders.decimalSIPrefix('dBm');
kbn.valueFormats.ohm = kbn.formatBuilders.decimalSIPrefix('Ω');
@@ -891,6 +894,7 @@ kbn.getUnitFormats = function() {
submenu: [
{ text: 'millimetre (mm)', value: 'lengthmm' },
{ text: 'meter (m)', value: 'lengthm' },
{ text: 'feet (ft)', value: 'lengthft' },
{ text: 'kilometer (km)', value: 'lengthkm' },
{ text: 'mile (mi)', value: 'lengthmi' },
],
@@ -934,21 +938,24 @@ kbn.getUnitFormats = function() {
{
text: 'energy',
submenu: [
{ text: 'watt (W)', value: 'watt' },
{ text: 'kilowatt (kW)', value: 'kwatt' },
{ text: 'volt-ampere (VA)', value: 'voltamp' },
{ text: 'kilovolt-ampere (kVA)', value: 'kvoltamp' },
{ text: 'volt-ampere reactive (var)', value: 'voltampreact' },
{ text: 'kilovolt-ampere reactive (kvar)', value: 'kvoltampreact' },
{ text: 'watt-hour (Wh)', value: 'watth' },
{ text: 'kilowatt-hour (kWh)', value: 'kwatth' },
{ text: 'kilowatt-min (kWm)', value: 'kwattm' },
{ text: 'joule (J)', value: 'joule' },
{ text: 'electron volt (eV)', value: 'ev' },
{ text: 'Watt (W)', value: 'watt' },
{ text: 'Kilowatt (kW)', value: 'kwatt' },
{ text: 'Milliwatt (mW)', value: 'mwatt' },
{ text: 'Volt-ampere (VA)', value: 'voltamp' },
{ text: 'Kilovolt-ampere (kVA)', value: 'kvoltamp' },
{ text: 'Volt-ampere reactive (var)', value: 'voltampreact' },
{ text: 'Kilovolt-ampere reactive (kvar)', value: 'kvoltampreact' },
{ text: 'Watt-hour (Wh)', value: 'watth' },
{ text: 'Kilowatt-hour (kWh)', value: 'kwatth' },
{ text: 'Kilowatt-min (kWm)', value: 'kwattm' },
{ text: 'Joule (J)', value: 'joule' },
{ text: 'Electron volt (eV)', value: 'ev' },
{ text: 'Ampere (A)', value: 'amp' },
{ text: 'Kiloampere (kA)', value: 'kamp' },
{ text: 'Milliampere (mA)', value: 'mamp' },
{ text: 'Volt (V)', value: 'volt' },
{ text: 'Kilovolt (kV)', value: 'kvolt' },
{ text: 'Millivolt (mV)', value: 'mvolt' },
{ text: 'Decibel-milliwatt (dBm)', value: 'dBm' },
{ text: 'Ohm (Ω)', value: 'ohm' }
],

View File

@@ -131,6 +131,27 @@ export class DashboardSrv {
modalClass: 'modal--narrow'
});
}
starDashboard(dashboardId, isStarred) {
let promise;
if (isStarred) {
promise = this.backendSrv.delete('/api/user/stars/dashboard/' + dashboardId).then(() => {
return false;
});
} else {
promise = this.backendSrv.post('/api/user/stars/dashboard/' + dashboardId).then(() => {
return true;
});
}
return promise.then(res => {
if (this.dash && this.dash.id === dashboardId) {
this.dash.meta.isStarred = res;
}
return res;
});
}
}
coreModule.service('dashboardSrv', DashboardSrv);

View File

@@ -49,14 +49,9 @@ export class DashNavCtrl {
}
starDashboard() {
if (this.dashboard.meta.isStarred) {
return this.backendSrv.delete('/api/user/stars/dashboard/' + this.dashboard.id).then(() => {
this.dashboard.meta.isStarred = false;
});
}
this.backendSrv.post('/api/user/stars/dashboard/' + this.dashboard.id).then(() => {
this.dashboard.meta.isStarred = true;
this.dashboardSrv.starDashboard(this.dashboard.id, this.dashboard.meta.isStarred)
.then(newState => {
this.dashboard.meta.isStarred = newState;
});
}

View File

@@ -149,6 +149,10 @@ export class DataSourceEditCtrl {
return;
}
if (this.current.readOnly) {
return;
}
if (this.current.id) {
return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then((result) => {
this.current = result.datasource;

View File

@@ -6,6 +6,8 @@
<h1 ng-show="ctrl.isNew">Add data source</h1>
<h1 ng-hide="ctrl.isNew">Edit data source</h1>
<div ng-if="ctrl.current.readOnly" class="grafana-info-box span8">Disclaimer. This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.</div>
<div class="page-header-tabs" ng-show="ctrl.hasDashboards">
<ul class="gf-tabs">
<li class="gf-tabs-item">
@@ -29,20 +31,20 @@
<div class="gf-form-inline">
<div class="gf-form max-width-30">
<span class="gf-form-label width-7">Name</span>
<input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" required>
<input class="gf-form-input max-width-23" type="text" ng-model="ctrl.current.name" placeholder="name" ng-disabled="ctrl.current.readOnly" required>
<info-popover offset="0px -135px" mode="right-absolute">
The name is used when you select the data source in panels.
The <em>Default</em> data source is preselected in new
panels.
</info-popover>
</div>
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" switch-class="max-width-6"></gf-form-switch>
<gf-form-switch class="gf-form" label="Default" checked="ctrl.current.isDefault" ng-disabled="ctrl.current.readOnly" switch-class="max-width-6"></gf-form-switch>
</div>
<div class="gf-form max-width-30">
<span class="gf-form-label width-7">Type</span>
<div class="gf-form-select-wrapper max-width-23">
<select class="gf-form-input" ng-model="ctrl.current.type" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.userChangedType()"></select>
<select class="gf-form-input" ng-model="ctrl.current.type" ng-disabled="ctrl.current.readOnly" ng-options="v.id as v.name for v in ctrl.types" ng-change="ctrl.userChangedType()"></select>
</div>
</div>
</div>
@@ -71,9 +73,9 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success width-6" ng-show="ctrl.isNew" ng-click="ctrl.saveChanges()">Add</button>
<button type="submit" class="btn btn-success width-8" ng-show="!ctrl.isNew" ng-click="ctrl.saveChanges()">Save &amp; Test</button>
<button type="submit" class="btn btn-danger width-6" ng-show="!ctrl.isNew" ng-click="ctrl.delete()">
<button type="submit" class="btn btn-success width-6" ng-disabled="ctrl.current.readOnly" ng-show="ctrl.isNew" ng-click="ctrl.saveChanges()">Add</button>
<button type="submit" class="btn btn-success width-8" ng-disabled="ctrl.current.readOnly" ng-show="!ctrl.isNew" ng-click="ctrl.saveChanges()">Save &amp; Test</button>
<button type="submit" class="btn btn-danger width-6" ng-disabled="ctrl.current.readOnly" ng-show="!ctrl.isNew" ng-click="ctrl.delete()">
Delete
</button>
<a class="btn btn-link" href="datasources">Cancel</a>

View File

@@ -333,7 +333,7 @@ function (angular, _, moment, dateMath, kbn, templatingVariable) {
};
return backendSrv.datasourceRequest(options).then(function(result) {
return result;
return result.data;
});
};

View File

@@ -68,7 +68,7 @@ describe('CloudWatchDatasource', function() {
beforeEach(function() {
ctx.backendSrv.datasourceRequest = function(params) {
requestParams = params.data;
return ctx.$q.when(response);
return ctx.$q.when({data: response});
};
});
@@ -213,7 +213,7 @@ describe('CloudWatchDatasource', function() {
beforeEach(function() {
ctx.backendSrv.datasourceRequest = function(params) {
requestParams = params.data;
return ctx.$q.when(response);
return ctx.$q.when({data: response});
};
});
@@ -235,7 +235,7 @@ describe('CloudWatchDatasource', function() {
setupCallback();
ctx.backendSrv.datasourceRequest = args => {
scenario.request = args.data;
return ctx.$q.when(scenario.requestResponse);
return ctx.$q.when({data: scenario.requestResponse});
};
ctx.ds.metricFindQuery(query).then(args => {
scenario.result = args;

View File

@@ -19,6 +19,7 @@ export class PrometheusDatasource {
basicAuth: any;
withCredentials: any;
metricsNameCache: any;
interval: string;
/** @ngInject */
constructor(instanceSettings,
@@ -34,6 +35,7 @@ export class PrometheusDatasource {
this.directUrl = instanceSettings.directUrl;
this.basicAuth = instanceSettings.basicAuth;
this.withCredentials = instanceSettings.withCredentials;
this.interval = instanceSettings.jsonData.timeInterval || '15s';
}
_request(method, url, requestId?) {

View File

@@ -1,3 +1,16 @@
<datasource-http-settings current="ctrl.current" suggest-url="http://localhost:9090">
</datasource-http-settings>
<div class="gf-form-group">
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label">Scrape interval</span>
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="15s"></input>
<info-popover mode="right-absolute">
Set this to your global scrape interval defined in your Prometheus config file. This will be used as a lower limit for
the Prometheus step query parameter.
</info-popover>
</div>
</div>
</div>

View File

@@ -5,7 +5,7 @@ import {PrometheusDatasource} from '../datasource';
describe('PrometheusDatasource', function() {
var ctx = new helpers.ServiceTestContext();
var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp' };
var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp', jsonData: {}};
beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.services'));

View File

@@ -8,7 +8,7 @@ import PrometheusMetricFindQuery from '../metric_find_query';
describe('PrometheusMetricFindQuery', function() {
var ctx = new helpers.ServiceTestContext();
var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp' };
var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp', jsonData: {}};
beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.services'));

View File

@@ -8,7 +8,7 @@
<span class="dashlist-title">
{{dash.title}}
</span>
<span class="dashlist-star">
<span class="dashlist-star" ng-click="ctrl.starDashboard(dash, $event)">
<i class="fa" ng-class="{'fa-star': dash.isStarred, 'fa-star-o': dash.isStarred === false}"></i>
</span>
</a>

View File

@@ -21,7 +21,7 @@ class DashListCtrl extends PanelCtrl {
};
/** @ngInject */
constructor($scope, $injector, private backendSrv) {
constructor($scope, $injector, private backendSrv, private dashboardSrv) {
super($scope, $injector);
_.defaults(this.panel, this.panelDefaults);
@@ -105,6 +105,17 @@ class DashListCtrl extends PanelCtrl {
});
}
starDashboard(dash, evt) {
this.dashboardSrv.starDashboard(dash.id, dash.isStarred).then(newState => {
dash.isStarred = newState;
});
if (evt) {
evt.stopPropagation();
evt.preventDefault();
}
}
getRecentDashboards() {
this.groups[1].show = this.panel.recent;
if (!this.panel.recent) {

View File

@@ -13,9 +13,11 @@
padding: 7px;
background-color: $tight-form-bg;
.fa {
float: right;
padding-top: 3px;
}
.dashlist-star {
float: right;
}
.fa-star {
color: $orange;
}