mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' into redux-poc2
This commit is contained in:
@@ -8,11 +8,11 @@ import coreModule from 'app/core/core_module';
|
||||
class AdminSettingsCtrl {
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'server-settings', 1);
|
||||
|
||||
backendSrv.get('/api/admin/settings').then(function(settings) {
|
||||
backendSrv.get('/api/admin/settings').then(settings => {
|
||||
$scope.settings = settings;
|
||||
});
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class AdminSettingsCtrl {
|
||||
class AdminHomeCtrl {
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 1);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import angular from 'angular';
|
||||
export class AdminEditOrgCtrl {
|
||||
/** @ngInject */
|
||||
constructor($scope, $routeParams, backendSrv, $location, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
|
||||
if ($routeParams.id) {
|
||||
@@ -12,34 +12,34 @@ export class AdminEditOrgCtrl {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.getOrg = function(id) {
|
||||
backendSrv.get('/api/orgs/' + id).then(function(org) {
|
||||
$scope.getOrg = id => {
|
||||
backendSrv.get('/api/orgs/' + id).then(org => {
|
||||
$scope.org = org;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getOrgUsers = function(id) {
|
||||
backendSrv.get('/api/orgs/' + id + '/users').then(function(orgUsers) {
|
||||
$scope.getOrgUsers = id => {
|
||||
backendSrv.get('/api/orgs/' + id + '/users').then(orgUsers => {
|
||||
$scope.orgUsers = orgUsers;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
$scope.update = () => {
|
||||
if (!$scope.orgDetailsForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.put('/api/orgs/' + $scope.org.id, $scope.org).then(function() {
|
||||
backendSrv.put('/api/orgs/' + $scope.org.id, $scope.org).then(() => {
|
||||
$location.path('/admin/orgs');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateOrgUser = function(orgUser) {
|
||||
$scope.updateOrgUser = orgUser => {
|
||||
backendSrv.patch('/api/orgs/' + orgUser.orgId + '/users/' + orgUser.userId, orgUser);
|
||||
};
|
||||
|
||||
$scope.removeOrgUser = function(orgUser) {
|
||||
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + orgUser.userId).then(function() {
|
||||
$scope.removeOrgUser = orgUser => {
|
||||
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + orgUser.userId).then(() => {
|
||||
$scope.getOrgUsers($scope.org.id);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -9,72 +9,72 @@ export class AdminEditUserCtrl {
|
||||
$scope.permissions = {};
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-users', 1);
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
if ($routeParams.id) {
|
||||
$scope.getUser($routeParams.id);
|
||||
$scope.getUserOrgs($routeParams.id);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.getUser = function(id) {
|
||||
backendSrv.get('/api/users/' + id).then(function(user) {
|
||||
$scope.getUser = id => {
|
||||
backendSrv.get('/api/users/' + id).then(user => {
|
||||
$scope.user = user;
|
||||
$scope.user_id = id;
|
||||
$scope.permissions.isGrafanaAdmin = user.isGrafanaAdmin;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setPassword = function() {
|
||||
$scope.setPassword = () => {
|
||||
if (!$scope.passwordForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = { password: $scope.password };
|
||||
backendSrv.put('/api/admin/users/' + $scope.user_id + '/password', payload).then(function() {
|
||||
backendSrv.put('/api/admin/users/' + $scope.user_id + '/password', payload).then(() => {
|
||||
$location.path('/admin/users');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updatePermissions = function() {
|
||||
$scope.updatePermissions = () => {
|
||||
const payload = $scope.permissions;
|
||||
|
||||
backendSrv.put('/api/admin/users/' + $scope.user_id + '/permissions', payload).then(function() {
|
||||
backendSrv.put('/api/admin/users/' + $scope.user_id + '/permissions', payload).then(() => {
|
||||
$location.path('/admin/users');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.create = function() {
|
||||
$scope.create = () => {
|
||||
if (!$scope.userForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.post('/api/admin/users', $scope.user).then(function() {
|
||||
backendSrv.post('/api/admin/users', $scope.user).then(() => {
|
||||
$location.path('/admin/users');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getUserOrgs = function(id) {
|
||||
backendSrv.get('/api/users/' + id + '/orgs').then(function(orgs) {
|
||||
$scope.getUserOrgs = id => {
|
||||
backendSrv.get('/api/users/' + id + '/orgs').then(orgs => {
|
||||
$scope.orgs = orgs;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
$scope.update = () => {
|
||||
if (!$scope.userForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.put('/api/users/' + $scope.user_id, $scope.user).then(function() {
|
||||
backendSrv.put('/api/users/' + $scope.user_id, $scope.user).then(() => {
|
||||
$location.path('/admin/users');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateOrgUser = function(orgUser) {
|
||||
backendSrv.patch('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id, orgUser).then(function() {});
|
||||
$scope.updateOrgUser = orgUser => {
|
||||
backendSrv.patch('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id, orgUser).then(() => {});
|
||||
};
|
||||
|
||||
$scope.removeOrgUser = function(orgUser) {
|
||||
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id).then(function() {
|
||||
$scope.removeOrgUser = orgUser => {
|
||||
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id).then(() => {
|
||||
$scope.getUser($scope.user_id);
|
||||
$scope.getUserOrgs($scope.user_id);
|
||||
});
|
||||
@@ -82,19 +82,19 @@ export class AdminEditUserCtrl {
|
||||
|
||||
$scope.orgsSearchCache = [];
|
||||
|
||||
$scope.searchOrgs = function(queryStr, callback) {
|
||||
$scope.searchOrgs = (queryStr, callback) => {
|
||||
if ($scope.orgsSearchCache.length > 0) {
|
||||
callback(_.map($scope.orgsSearchCache, 'name'));
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.get('/api/orgs', { query: '' }).then(function(result) {
|
||||
backendSrv.get('/api/orgs', { query: '' }).then(result => {
|
||||
$scope.orgsSearchCache = result;
|
||||
callback(_.map(result, 'name'));
|
||||
});
|
||||
};
|
||||
|
||||
$scope.addOrgUser = function() {
|
||||
$scope.addOrgUser = () => {
|
||||
if (!$scope.addOrgForm.$valid) {
|
||||
return;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ export class AdminEditUserCtrl {
|
||||
|
||||
$scope.newOrg.loginOrEmail = $scope.user.login;
|
||||
|
||||
backendSrv.post('/api/orgs/' + orgInfo.id + '/users/', $scope.newOrg).then(function() {
|
||||
backendSrv.post('/api/orgs/' + orgInfo.id + '/users/', $scope.newOrg).then(() => {
|
||||
$scope.getUser($scope.user_id);
|
||||
$scope.getUserOrgs($scope.user_id);
|
||||
});
|
||||
|
||||
@@ -3,26 +3,26 @@ import angular from 'angular';
|
||||
export class AdminListOrgsCtrl {
|
||||
/** @ngInject */
|
||||
constructor($scope, backendSrv, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
$scope.getOrgs();
|
||||
};
|
||||
|
||||
$scope.getOrgs = function() {
|
||||
backendSrv.get('/api/orgs').then(function(orgs) {
|
||||
$scope.getOrgs = () => {
|
||||
backendSrv.get('/api/orgs').then(orgs => {
|
||||
$scope.orgs = orgs;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteOrg = function(org) {
|
||||
$scope.deleteOrg = org => {
|
||||
$scope.appEvent('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Do you want to delete organization ' + org.name + '?',
|
||||
text2: 'All dashboards for this organization will be removed!',
|
||||
icon: 'fa-trash',
|
||||
yesText: 'Delete',
|
||||
onConfirm: function() {
|
||||
backendSrv.delete('/api/orgs/' + org.id).then(function() {
|
||||
onConfirm: () => {
|
||||
backendSrv.delete('/api/orgs/' + org.id).then(() => {
|
||||
$scope.getOrgs();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ export default class AdminListUsersCtrl {
|
||||
this.showPaging = this.totalPages > 1;
|
||||
this.pages = [];
|
||||
|
||||
for (var i = 1; i < this.totalPages + 1; i++) {
|
||||
for (let i = 1; i < this.totalPages + 1; i++) {
|
||||
this.pages.push({ page: i, current: i === this.page });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ export class AlertTabCtrl {
|
||||
this.addNotificationSegment = this.uiSegmentSrv.newPlusButton();
|
||||
|
||||
// subscribe to graph threshold handle changes
|
||||
var thresholdChangedEventHandler = this.graphThresholdChanged.bind(this);
|
||||
const thresholdChangedEventHandler = this.graphThresholdChanged.bind(this);
|
||||
this.panelCtrl.events.on('threshold-changed', thresholdChangedEventHandler);
|
||||
|
||||
// set panel alert edit mode
|
||||
@@ -129,7 +129,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
|
||||
notificationAdded() {
|
||||
var model = _.find(this.notifications, {
|
||||
const model = _.find(this.notifications, {
|
||||
name: this.addNotificationSegment.value,
|
||||
});
|
||||
if (!model) {
|
||||
@@ -154,7 +154,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
|
||||
initModel() {
|
||||
var alert = (this.alert = this.panel.alert);
|
||||
const alert = (this.alert = this.panel.alert);
|
||||
if (!alert) {
|
||||
return;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ export class AlertTabCtrl {
|
||||
alert.handler = alert.handler || 1;
|
||||
alert.notifications = alert.notifications || [];
|
||||
|
||||
var defaultName = this.panel.title + ' alert';
|
||||
const defaultName = this.panel.title + ' alert';
|
||||
alert.name = alert.name || defaultName;
|
||||
|
||||
this.conditionModels = _.reduce(
|
||||
@@ -185,7 +185,7 @@ export class AlertTabCtrl {
|
||||
ThresholdMapper.alertToGraphThresholds(this.panel);
|
||||
|
||||
for (const addedNotification of alert.notifications) {
|
||||
var model = _.find(this.notifications, { id: addedNotification.id });
|
||||
const model = _.find(this.notifications, { id: addedNotification.id });
|
||||
if (model && model.isDefault === false) {
|
||||
model.iconClass = this.getNotificationIcon(model.type);
|
||||
this.alertNotifications.push(model);
|
||||
@@ -205,7 +205,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
|
||||
graphThresholdChanged(evt) {
|
||||
for (var condition of this.alert.conditions) {
|
||||
for (const condition of this.alert.conditions) {
|
||||
if (condition.type === 'query') {
|
||||
condition.evaluator.params[evt.handleIndex] = evt.threshold.value;
|
||||
this.evaluatorParamsChanged();
|
||||
@@ -232,12 +232,12 @@ export class AlertTabCtrl {
|
||||
let firstTarget;
|
||||
let foundTarget = null;
|
||||
|
||||
for (var condition of this.alert.conditions) {
|
||||
for (const condition of this.alert.conditions) {
|
||||
if (condition.type !== 'query') {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var target of this.panel.targets) {
|
||||
for (const target of this.panel.targets) {
|
||||
if (!firstTarget) {
|
||||
firstTarget = target;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
var datasourceName = foundTarget.datasource || this.panel.datasource;
|
||||
const datasourceName = foundTarget.datasource || this.panel.datasource;
|
||||
this.datasourceSrv.get(datasourceName).then(ds => {
|
||||
if (!ds.meta.alerting) {
|
||||
this.error = 'The datasource does not support alerting queries';
|
||||
@@ -270,7 +270,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
|
||||
buildConditionModel(source) {
|
||||
var cm: any = { source: source, type: source.type };
|
||||
const cm: any = { source: source, type: source.type };
|
||||
|
||||
cm.queryPart = new QueryPart(source.query, alertDef.alertQueryDef);
|
||||
cm.reducerPart = alertDef.createReducerPart(source.reducer);
|
||||
@@ -292,7 +292,7 @@ export class AlertTabCtrl {
|
||||
this.validateModel();
|
||||
}
|
||||
case 'get-param-options': {
|
||||
var result = this.panel.targets.map(target => {
|
||||
const result = this.panel.targets.map(target => {
|
||||
return this.uiSegmentSrv.newSegment({ value: target.refId });
|
||||
});
|
||||
|
||||
@@ -309,8 +309,8 @@ export class AlertTabCtrl {
|
||||
break;
|
||||
}
|
||||
case 'get-part-actions': {
|
||||
var result = [];
|
||||
for (var type of alertDef.reducerTypes) {
|
||||
const result = [];
|
||||
for (const type of alertDef.reducerTypes) {
|
||||
if (type.value !== conditionModel.source.reducer.type) {
|
||||
result.push(type);
|
||||
}
|
||||
@@ -321,7 +321,7 @@ export class AlertTabCtrl {
|
||||
}
|
||||
|
||||
addCondition(type) {
|
||||
var condition = this.buildDefaultCondition();
|
||||
const condition = this.buildDefaultCondition();
|
||||
// add to persited model
|
||||
this.alert.conditions.push(condition);
|
||||
// add to view model
|
||||
@@ -406,7 +406,7 @@ export class AlertTabCtrl {
|
||||
this.testing = true;
|
||||
this.testResult = false;
|
||||
|
||||
var payload = {
|
||||
const payload = {
|
||||
dashboard: this.dashboardSrv.getCurrent().getSaveModelClone(),
|
||||
panelId: this.panelCtrl.panel.id,
|
||||
};
|
||||
|
||||
@@ -11,6 +11,8 @@ export class AlertNotificationEditCtrl {
|
||||
model: any;
|
||||
defaults: any = {
|
||||
type: 'email',
|
||||
sendReminder: false,
|
||||
frequency: '15m',
|
||||
settings: {
|
||||
httpMethod: 'POST',
|
||||
autoResolve: true,
|
||||
@@ -18,12 +20,17 @@ export class AlertNotificationEditCtrl {
|
||||
},
|
||||
isDefault: false,
|
||||
};
|
||||
getFrequencySuggestion: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $routeParams, private backendSrv, private $location, private $templateCache, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
|
||||
this.isNew = !this.$routeParams.id;
|
||||
|
||||
this.getFrequencySuggestion = () => {
|
||||
return ['1m', '5m', '10m', '15m', '30m', '1h'];
|
||||
};
|
||||
|
||||
this.backendSrv
|
||||
.get(`/api/alert-notifiers`)
|
||||
.then(notifiers => {
|
||||
@@ -102,6 +109,7 @@ export class AlertNotificationEditCtrl {
|
||||
const payload = {
|
||||
name: this.model.name,
|
||||
type: this.model.type,
|
||||
frequency: this.model.frequency,
|
||||
settings: this.model.settings,
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,29 @@
|
||||
checked="ctrl.model.settings.uploadImage"
|
||||
tooltip="Captures an image and include it in the notification">
|
||||
</gf-form-switch>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Send reminders"
|
||||
label-class="width-12"
|
||||
checked="ctrl.model.sendReminder"
|
||||
tooltip="Send additional notifications for triggered alerts">
|
||||
</gf-form-switch>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form" ng-if="ctrl.model.sendReminder">
|
||||
<span class="gf-form-label width-12">Send reminder every
|
||||
<info-popover mode="right-normal" position="top center">
|
||||
Specify how often reminders should be sent, e.g. every 30s, 1m, 10m, 30m or 1h etc.
|
||||
</info-popover>
|
||||
</span>
|
||||
<input type="text" placeholder="Select or specify custom" class="gf-form-input width-15" ng-model="ctrl.model.frequency"
|
||||
bs-typeahead="ctrl.getFrequencySuggestion" data-min-length=0 ng-required="ctrl.model.sendReminder">
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<span class="alert alert-info width-30" ng-if="ctrl.model.sendReminder">
|
||||
Alert reminders are sent after rules are evaluated. Therefore a reminder can never be sent more frequently than a configured alert rule evaluation interval.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" ng-include src="ctrl.notifierTemplateId">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
export class ThresholdMapper {
|
||||
static alertToGraphThresholds(panel) {
|
||||
for (var i = 0; i < panel.alert.conditions.length; i++) {
|
||||
for (let i = 0; i < panel.alert.conditions.length; i++) {
|
||||
const condition = panel.alert.conditions[i];
|
||||
if (condition.type !== 'query') {
|
||||
continue;
|
||||
}
|
||||
|
||||
var evaluator = condition.evaluator;
|
||||
var thresholds = (panel.thresholds = []);
|
||||
const evaluator = condition.evaluator;
|
||||
const thresholds = (panel.thresholds = []);
|
||||
|
||||
switch (evaluator.type) {
|
||||
case 'gt': {
|
||||
@@ -51,13 +51,13 @@ export class ThresholdMapper {
|
||||
break;
|
||||
}
|
||||
|
||||
for (var t of panel.thresholds) {
|
||||
for (const t of panel.thresholds) {
|
||||
t.fill = true;
|
||||
t.line = true;
|
||||
t.colorMode = 'critical';
|
||||
}
|
||||
|
||||
var updated = true;
|
||||
const updated = true;
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { QueryPartDef, QueryPart } from 'app/core/components/query_part/query_part';
|
||||
|
||||
var alertQueryDef = new QueryPartDef({
|
||||
const alertQueryDef = new QueryPartDef({
|
||||
type: 'query',
|
||||
params: [
|
||||
{ name: 'queryRefId', type: 'string', dynamicLookup: true },
|
||||
@@ -15,9 +15,9 @@ var alertQueryDef = new QueryPartDef({
|
||||
defaultParams: ['#A', '15m', 'now', 'avg'],
|
||||
});
|
||||
|
||||
var conditionTypes = [{ text: 'Query', value: 'query' }];
|
||||
const conditionTypes = [{ text: 'Query', value: 'query' }];
|
||||
|
||||
var alertStateSortScore = {
|
||||
const alertStateSortScore = {
|
||||
alerting: 1,
|
||||
no_data: 2,
|
||||
pending: 3,
|
||||
@@ -25,7 +25,7 @@ var alertStateSortScore = {
|
||||
paused: 5,
|
||||
};
|
||||
|
||||
var evalFunctions = [
|
||||
const evalFunctions = [
|
||||
{ text: 'IS ABOVE', value: 'gt' },
|
||||
{ text: 'IS BELOW', value: 'lt' },
|
||||
{ text: 'IS OUTSIDE RANGE', value: 'outside_range' },
|
||||
@@ -33,9 +33,9 @@ var evalFunctions = [
|
||||
{ text: 'HAS NO VALUE', value: 'no_value' },
|
||||
];
|
||||
|
||||
var evalOperators = [{ text: 'OR', value: 'or' }, { text: 'AND', value: 'and' }];
|
||||
const evalOperators = [{ text: 'OR', value: 'or' }, { text: 'AND', value: 'and' }];
|
||||
|
||||
var reducerTypes = [
|
||||
const reducerTypes = [
|
||||
{ text: 'avg()', value: 'avg' },
|
||||
{ text: 'min()', value: 'min' },
|
||||
{ text: 'max()', value: 'max' },
|
||||
@@ -48,17 +48,17 @@ var reducerTypes = [
|
||||
{ text: 'count_non_null()', value: 'count_non_null' },
|
||||
];
|
||||
|
||||
var noDataModes = [
|
||||
const noDataModes = [
|
||||
{ text: 'Alerting', value: 'alerting' },
|
||||
{ text: 'No Data', value: 'no_data' },
|
||||
{ text: 'Keep Last State', value: 'keep_state' },
|
||||
{ text: 'Ok', value: 'ok' },
|
||||
];
|
||||
|
||||
var executionErrorModes = [{ text: 'Alerting', value: 'alerting' }, { text: 'Keep Last State', value: 'keep_state' }];
|
||||
const executionErrorModes = [{ text: 'Alerting', value: 'alerting' }, { text: 'Keep Last State', value: 'keep_state' }];
|
||||
|
||||
function createReducerPart(model) {
|
||||
var def = new QueryPartDef({ type: model.type, defaultParams: [] });
|
||||
const def = new QueryPartDef({ type: model.type, defaultParams: [] });
|
||||
return new QueryPart(model, def);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import $ from 'jquery';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import alertDef from '../alerting/state/alertDef';
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv, $compile) {
|
||||
function sanitizeString(str) {
|
||||
try {
|
||||
@@ -20,17 +20,17 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
|
||||
event: '=',
|
||||
onEdit: '&',
|
||||
},
|
||||
link: function(scope, element) {
|
||||
var event = scope.event;
|
||||
var title = event.title;
|
||||
var text = event.text;
|
||||
var dashboard = dashboardSrv.getCurrent();
|
||||
link: (scope, element) => {
|
||||
const event = scope.event;
|
||||
let title = event.title;
|
||||
let text = event.text;
|
||||
const dashboard = dashboardSrv.getCurrent();
|
||||
|
||||
var tooltip = '<div class="graph-annotation">';
|
||||
var titleStateClass = '';
|
||||
let tooltip = '<div class="graph-annotation">';
|
||||
let titleStateClass = '';
|
||||
|
||||
if (event.alertId) {
|
||||
var stateModel = alertDef.getStateDisplayModel(event.newState);
|
||||
const stateModel = alertDef.getStateDisplayModel(event.newState);
|
||||
titleStateClass = stateModel.stateClass;
|
||||
title = `<i class="icon-gf ${stateModel.iconClass}"></i> ${stateModel.text}`;
|
||||
text = alertDef.getAlertAnnotationInfo(event);
|
||||
@@ -42,7 +42,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
|
||||
title = '';
|
||||
}
|
||||
|
||||
var header = `<div class="graph-annotation__header">`;
|
||||
let header = `<div class="graph-annotation__header">`;
|
||||
if (event.login) {
|
||||
header += `<div class="graph-annotation__user" bs-tooltip="'Created by ${event.login}'"><img src="${
|
||||
event.avatarUrl
|
||||
@@ -70,7 +70,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
|
||||
tooltip += '<div>' + sanitizeString(text.replace(/\n/g, '<br>')) + '</div>';
|
||||
}
|
||||
|
||||
var tags = event.tags;
|
||||
const tags = event.tags;
|
||||
|
||||
if (tags && tags.length) {
|
||||
scope.tags = tags;
|
||||
@@ -81,7 +81,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
|
||||
tooltip += '</div>';
|
||||
tooltip += '</div>';
|
||||
|
||||
var $tooltip = $(tooltip);
|
||||
const $tooltip = $(tooltip);
|
||||
$tooltip.appendTo(element);
|
||||
|
||||
$compile(element.contents())(scope);
|
||||
|
||||
@@ -25,7 +25,7 @@ export class AnnotationsSrv {
|
||||
.all([this.getGlobalAnnotations(options), this.getAlertStates(options)])
|
||||
.then(results => {
|
||||
// combine the annotations and flatten results
|
||||
var annotations = _.flattenDeep(results[0]);
|
||||
let annotations = _.flattenDeep(results[0]);
|
||||
|
||||
// filter out annotations that do not belong to requesting panel
|
||||
annotations = _.filter(annotations, item => {
|
||||
@@ -40,7 +40,7 @@ export class AnnotationsSrv {
|
||||
annotations = makeRegions(annotations, options);
|
||||
|
||||
// look for alert state for this panel
|
||||
var alertState = _.find(results[1], { panelId: options.panel.id });
|
||||
const alertState = _.find(results[1], { panelId: options.panel.id });
|
||||
|
||||
return {
|
||||
annotations: annotations,
|
||||
@@ -82,14 +82,14 @@ export class AnnotationsSrv {
|
||||
}
|
||||
|
||||
getGlobalAnnotations(options) {
|
||||
var dashboard = options.dashboard;
|
||||
const dashboard = options.dashboard;
|
||||
|
||||
if (this.globalAnnotationsPromise) {
|
||||
return this.globalAnnotationsPromise;
|
||||
}
|
||||
|
||||
var range = this.timeSrv.timeRange();
|
||||
var promises = [];
|
||||
const range = this.timeSrv.timeRange();
|
||||
const promises = [];
|
||||
|
||||
for (const annotation of dashboard.annotations.list) {
|
||||
if (!annotation.enable) {
|
||||
@@ -155,7 +155,7 @@ export class AnnotationsSrv {
|
||||
delete annotation.snapshotData;
|
||||
}
|
||||
|
||||
for (var item of results) {
|
||||
for (const item of results) {
|
||||
item.source = annotation;
|
||||
}
|
||||
return results;
|
||||
|
||||
@@ -81,7 +81,7 @@ export class AnnotationsEditorCtrl {
|
||||
}
|
||||
|
||||
removeAnnotation(annotation) {
|
||||
var index = _.indexOf(this.annotations, annotation);
|
||||
const index = _.indexOf(this.annotations, annotation);
|
||||
this.annotations.splice(index, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export class EventEditorCtrl {
|
||||
close: any;
|
||||
timeFormated: string;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private annotationsSrv) {
|
||||
this.event.panelId = this.panelCtrl.panel.id;
|
||||
this.event.dashboardId = this.panelCtrl.dashboard.id;
|
||||
|
||||
@@ -55,7 +55,7 @@ export class EventManager {
|
||||
return;
|
||||
}
|
||||
|
||||
var types = {
|
||||
const types = {
|
||||
$__alerting: {
|
||||
color: ALERTING_COLOR,
|
||||
position: 'BOTTOM',
|
||||
@@ -102,8 +102,8 @@ export class EventManager {
|
||||
}
|
||||
} else {
|
||||
// annotations from query
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var item = annotations[i];
|
||||
for (let i = 0; i < annotations.length; i++) {
|
||||
const item = annotations[i];
|
||||
|
||||
// add properties used by jquery flot events
|
||||
item.min = item.time;
|
||||
|
||||
@@ -14,33 +14,33 @@ export function makeRegions(annotations, options) {
|
||||
}
|
||||
|
||||
function getRegions(events, range) {
|
||||
const region_events = _.filter(events, event => {
|
||||
const regionEvents = _.filter(events, event => {
|
||||
return event.regionId;
|
||||
});
|
||||
let regions = _.groupBy(region_events, 'regionId');
|
||||
let regions = _.groupBy(regionEvents, 'regionId');
|
||||
regions = _.compact(
|
||||
_.map(regions, region_events => {
|
||||
const region_obj = _.head(region_events);
|
||||
if (region_events && region_events.length > 1) {
|
||||
region_obj.timeEnd = region_events[1].time;
|
||||
region_obj.isRegion = true;
|
||||
return region_obj;
|
||||
_.map(regions, regionEvents => {
|
||||
const regionObj = _.head(regionEvents);
|
||||
if (regionEvents && regionEvents.length > 1) {
|
||||
regionObj.timeEnd = regionEvents[1].time;
|
||||
regionObj.isRegion = true;
|
||||
return regionObj;
|
||||
} else {
|
||||
if (region_events && region_events.length) {
|
||||
if (regionEvents && regionEvents.length) {
|
||||
// Don't change proper region object
|
||||
if (!region_obj.time || !region_obj.timeEnd) {
|
||||
if (!regionObj.time || !regionObj.timeEnd) {
|
||||
// This is cut region
|
||||
if (isStartOfRegion(region_obj)) {
|
||||
region_obj.timeEnd = range.to.valueOf() - 1;
|
||||
if (isStartOfRegion(regionObj)) {
|
||||
regionObj.timeEnd = range.to.valueOf() - 1;
|
||||
} else {
|
||||
// Start time = null
|
||||
region_obj.timeEnd = region_obj.time;
|
||||
region_obj.time = range.from.valueOf() + 1;
|
||||
regionObj.timeEnd = regionObj.time;
|
||||
regionObj.time = range.from.valueOf() + 1;
|
||||
}
|
||||
region_obj.isRegion = true;
|
||||
regionObj.isRegion = true;
|
||||
}
|
||||
|
||||
return region_obj;
|
||||
return regionObj;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ import '../annotations_srv';
|
||||
import 'app/features/dashboard/time_srv';
|
||||
import { AnnotationsSrv } from '../annotations_srv';
|
||||
|
||||
describe('AnnotationsSrv', function() {
|
||||
describe('AnnotationsSrv', () => {
|
||||
const $rootScope = {
|
||||
onAppEvent: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -128,7 +128,7 @@ export class ChangeTracker {
|
||||
});
|
||||
|
||||
// ignore template variable values
|
||||
_.each(dash.templating.list, function(value) {
|
||||
_.each(dash.templating.list, value => {
|
||||
value.current = null;
|
||||
value.options = null;
|
||||
value.filters = null;
|
||||
|
||||
@@ -8,7 +8,7 @@ export class CreateFolderCtrl {
|
||||
hasValidationError: boolean;
|
||||
validationError: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $location, private validationSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'manage-dashboards', 0);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ export class DashboardCtrl implements PanelContainer {
|
||||
}
|
||||
|
||||
setWindowTitleAndTheme() {
|
||||
window.document.title = config.window_title_prefix + this.dashboard.title;
|
||||
window.document.title = config.windowTitlePrefix + this.dashboard.title;
|
||||
}
|
||||
|
||||
showJsonEditor(evt, options) {
|
||||
@@ -144,7 +144,7 @@ export class DashboardCtrl implements PanelContainer {
|
||||
removePanel(panel: PanelModel, ask: boolean) {
|
||||
// confirm deletion
|
||||
if (ask !== false) {
|
||||
var text2, confirmText;
|
||||
let text2, confirmText;
|
||||
|
||||
if (panel.alert) {
|
||||
text2 = 'Panel includes an alert rule, removing panel will also remove alert rule';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import config from 'app/core/config';
|
||||
import locationUtil from 'app/core/utils/location_util';
|
||||
|
||||
export class DashboardImportCtrl {
|
||||
navModel: any;
|
||||
@@ -179,7 +180,8 @@ export class DashboardImportCtrl {
|
||||
folderId: this.folderId,
|
||||
})
|
||||
.then(res => {
|
||||
this.$location.url(res.importedUrl);
|
||||
const dashUrl = locationUtil.stripBaseFromUrl(res.importedUrl);
|
||||
this.$location.url(dashUrl);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ export class DashboardLoaderSrv {
|
||||
}
|
||||
|
||||
loadDashboard(type, slug, uid) {
|
||||
var promise;
|
||||
let promise;
|
||||
|
||||
if (type === 'script') {
|
||||
promise = this._loadScriptedDashboard(slug);
|
||||
@@ -59,7 +59,7 @@ export class DashboardLoaderSrv {
|
||||
});
|
||||
}
|
||||
|
||||
promise.then(function(result) {
|
||||
promise.then(result => {
|
||||
if (result.meta.dashboardNotFound !== true) {
|
||||
impressionSrv.addDashboardImpression(result.dashboard.id);
|
||||
}
|
||||
@@ -106,7 +106,7 @@ export class DashboardLoaderSrv {
|
||||
};
|
||||
|
||||
/*jshint -W054 */
|
||||
const script_func = new Function(
|
||||
const scriptFunc = new Function(
|
||||
'ARGS',
|
||||
'kbn',
|
||||
'dateMath',
|
||||
@@ -119,12 +119,12 @@ export class DashboardLoaderSrv {
|
||||
'services',
|
||||
result.data
|
||||
);
|
||||
const script_result = script_func(this.$routeParams, kbn, dateMath, _, moment, window, document, $, $, services);
|
||||
const scriptResult = scriptFunc(this.$routeParams, kbn, dateMath, _, moment, window, document, $, $, services);
|
||||
|
||||
// Handle async dashboard scripts
|
||||
if (_.isFunction(script_result)) {
|
||||
if (_.isFunction(scriptResult)) {
|
||||
const deferred = this.$q.defer();
|
||||
script_result(dashboard => {
|
||||
scriptResult(dashboard => {
|
||||
this.$timeout(() => {
|
||||
deferred.resolve({ data: dashboard });
|
||||
});
|
||||
@@ -132,7 +132,7 @@ export class DashboardLoaderSrv {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
return { data: script_result };
|
||||
return { data: scriptResult };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ export class DashboardMigrator {
|
||||
}
|
||||
|
||||
updateSchema(old) {
|
||||
var i, j, k, n;
|
||||
var oldVersion = this.dashboard.schemaVersion;
|
||||
var panelUpgrades = [];
|
||||
let i, j, k, n;
|
||||
const oldVersion = this.dashboard.schemaVersion;
|
||||
const panelUpgrades = [];
|
||||
this.dashboard.schemaVersion = 16;
|
||||
|
||||
if (oldVersion === this.dashboard.schemaVersion) {
|
||||
@@ -36,7 +36,7 @@ export class DashboardMigrator {
|
||||
}
|
||||
}
|
||||
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
// rename panel type
|
||||
if (panel.type === 'graphite') {
|
||||
panel.type = 'graph';
|
||||
@@ -83,8 +83,8 @@ export class DashboardMigrator {
|
||||
// schema version 3 changes
|
||||
if (oldVersion < 3) {
|
||||
// ensure panel ids
|
||||
var maxId = this.dashboard.getNextPanelId();
|
||||
panelUpgrades.push(function(panel) {
|
||||
let maxId = this.dashboard.getNextPanelId();
|
||||
panelUpgrades.push(panel => {
|
||||
if (!panel.id) {
|
||||
panel.id = maxId;
|
||||
maxId += 1;
|
||||
@@ -95,11 +95,11 @@ export class DashboardMigrator {
|
||||
// schema version 4 changes
|
||||
if (oldVersion < 4) {
|
||||
// move aliasYAxis changes
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
if (panel.type !== 'graph') {
|
||||
return;
|
||||
}
|
||||
_.each(panel.aliasYAxis, function(value, key) {
|
||||
_.each(panel.aliasYAxis, (value, key) => {
|
||||
panel.seriesOverrides = [{ alias: key, yaxis: value }];
|
||||
});
|
||||
delete panel.aliasYAxis;
|
||||
@@ -108,7 +108,7 @@ export class DashboardMigrator {
|
||||
|
||||
if (oldVersion < 6) {
|
||||
// move pulldowns to new schema
|
||||
var annotations = _.find(old.pulldowns, { type: 'annotations' });
|
||||
const annotations = _.find(old.pulldowns, { type: 'annotations' });
|
||||
|
||||
if (annotations) {
|
||||
this.dashboard.annotations = {
|
||||
@@ -118,7 +118,7 @@ export class DashboardMigrator {
|
||||
|
||||
// update template variables
|
||||
for (i = 0; i < this.dashboard.templating.list.length; i++) {
|
||||
var variable = this.dashboard.templating.list[i];
|
||||
const variable = this.dashboard.templating.list[i];
|
||||
if (variable.datasource === void 0) {
|
||||
variable.datasource = null;
|
||||
}
|
||||
@@ -140,29 +140,26 @@ export class DashboardMigrator {
|
||||
}
|
||||
|
||||
// ensure query refIds
|
||||
panelUpgrades.push(function(panel) {
|
||||
_.each(
|
||||
panel.targets,
|
||||
function(target) {
|
||||
if (!target.refId) {
|
||||
target.refId = this.dashboard.getNextQueryLetter(panel);
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
panelUpgrades.push(panel => {
|
||||
_.each(panel.targets, target => {
|
||||
if (!target.refId) {
|
||||
target.refId = this.dashboard.getNextQueryLetter(panel);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (oldVersion < 8) {
|
||||
panelUpgrades.push(function(panel) {
|
||||
_.each(panel.targets, function(target) {
|
||||
panelUpgrades.push(panel => {
|
||||
_.each(panel.targets, 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 = [];
|
||||
target.select = _.map(target.fields, field => {
|
||||
const parts = [];
|
||||
parts.push({ type: 'field', params: [field.name] });
|
||||
parts.push({ type: field.func, params: [] });
|
||||
if (field.mathExpr) {
|
||||
@@ -174,7 +171,7 @@ export class DashboardMigrator {
|
||||
return parts;
|
||||
});
|
||||
delete target.fields;
|
||||
_.each(target.groupBy, function(part) {
|
||||
_.each(target.groupBy, part => {
|
||||
if (part.type === 'time' && part.interval) {
|
||||
part.params = [part.interval];
|
||||
delete part.interval;
|
||||
@@ -198,13 +195,13 @@ export class DashboardMigrator {
|
||||
// schema version 9 changes
|
||||
if (oldVersion < 9) {
|
||||
// move aliasYAxis changes
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
if (panel.type !== 'singlestat' && panel.thresholds !== '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (panel.thresholds) {
|
||||
var k = panel.thresholds.split(',');
|
||||
const k = panel.thresholds.split(',');
|
||||
|
||||
if (k.length >= 3) {
|
||||
k.shift();
|
||||
@@ -217,14 +214,14 @@ export class DashboardMigrator {
|
||||
// schema version 10 changes
|
||||
if (oldVersion < 10) {
|
||||
// move aliasYAxis changes
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
if (panel.type !== 'table') {
|
||||
return;
|
||||
}
|
||||
|
||||
_.each(panel.styles, function(style) {
|
||||
_.each(panel.styles, style => {
|
||||
if (style.thresholds && style.thresholds.length >= 3) {
|
||||
var k = style.thresholds;
|
||||
const k = style.thresholds;
|
||||
k.shift();
|
||||
style.thresholds = k;
|
||||
}
|
||||
@@ -234,7 +231,7 @@ export class DashboardMigrator {
|
||||
|
||||
if (oldVersion < 12) {
|
||||
// update template variables
|
||||
_.each(this.dashboard.templating.list, function(templateVariable) {
|
||||
_.each(this.dashboard.templating.list, templateVariable => {
|
||||
if (templateVariable.refresh) {
|
||||
templateVariable.refresh = 1;
|
||||
}
|
||||
@@ -251,7 +248,7 @@ export class DashboardMigrator {
|
||||
|
||||
if (oldVersion < 12) {
|
||||
// update graph yaxes changes
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
if (panel.type !== 'graph') {
|
||||
return;
|
||||
}
|
||||
@@ -300,7 +297,7 @@ export class DashboardMigrator {
|
||||
|
||||
if (oldVersion < 13) {
|
||||
// update graph yaxes changes
|
||||
panelUpgrades.push(function(panel) {
|
||||
panelUpgrades.push(panel => {
|
||||
if (panel.type !== 'graph') {
|
||||
return;
|
||||
}
|
||||
@@ -309,7 +306,7 @@ export class DashboardMigrator {
|
||||
}
|
||||
|
||||
panel.thresholds = [];
|
||||
var t1: any = {},
|
||||
const t1: any = {},
|
||||
t2: any = {};
|
||||
|
||||
if (panel.grid.threshold1 !== null) {
|
||||
|
||||
@@ -144,8 +144,8 @@ export class DashboardModel {
|
||||
});
|
||||
|
||||
// make clone
|
||||
var copy: any = {};
|
||||
for (var property in this) {
|
||||
let copy: any = {};
|
||||
for (const property in this) {
|
||||
if (DashboardModel.nonPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
||||
continue;
|
||||
}
|
||||
@@ -258,7 +258,7 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
sortPanelsByGridPos() {
|
||||
this.panels.sort(function(panelA, panelB) {
|
||||
this.panels.sort((panelA, panelB) => {
|
||||
if (panelA.gridPos.y === panelB.gridPos.y) {
|
||||
return panelA.gridPos.x - panelB.gridPos.x;
|
||||
} else {
|
||||
@@ -542,7 +542,7 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
removePanel(panel: PanelModel) {
|
||||
var index = _.indexOf(this.panels, panel);
|
||||
const index = _.indexOf(this.panels, panel);
|
||||
this.panels.splice(index, 1);
|
||||
this.events.emit('panel-removed', panel);
|
||||
}
|
||||
@@ -559,7 +559,7 @@ export class DashboardModel {
|
||||
|
||||
expandRows() {
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
var panel = this.panels[i];
|
||||
const panel = this.panels[i];
|
||||
|
||||
if (panel.type !== 'row') {
|
||||
continue;
|
||||
@@ -573,7 +573,7 @@ export class DashboardModel {
|
||||
|
||||
collapseRows() {
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
var panel = this.panels[i];
|
||||
const panel = this.panels[i];
|
||||
|
||||
if (panel.type !== 'row') {
|
||||
continue;
|
||||
@@ -595,12 +595,12 @@ export class DashboardModel {
|
||||
return true;
|
||||
}
|
||||
|
||||
var visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
|
||||
const visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
|
||||
if (visibleVars.length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
|
||||
const visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
|
||||
if (visibleAnnotations.length > 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -773,10 +773,10 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
getNextQueryLetter(panel) {
|
||||
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
return _.find(letters, function(refId) {
|
||||
return _.every(panel.targets, function(other) {
|
||||
return _.find(letters, refId => {
|
||||
return _.every(panel.targets, other => {
|
||||
return other.refId !== refId;
|
||||
});
|
||||
});
|
||||
@@ -842,12 +842,20 @@ export class DashboardModel {
|
||||
})
|
||||
);
|
||||
|
||||
// Consider navbar and submenu controls, padding and margin
|
||||
let visibleHeight = window.innerHeight - 55 - 20;
|
||||
const navbarHeight = 55;
|
||||
const margin = 20;
|
||||
const submenuHeight = 50;
|
||||
|
||||
// Remove submenu if visible
|
||||
if (this.meta.submenuEnabled) {
|
||||
visibleHeight -= 50;
|
||||
let visibleHeight = viewHeight - navbarHeight - margin;
|
||||
|
||||
// Remove submenu height if visible
|
||||
if (this.meta.submenuEnabled && !this.meta.kiosk) {
|
||||
visibleHeight -= submenuHeight;
|
||||
}
|
||||
|
||||
// add back navbar height
|
||||
if (this.meta.kiosk === 'b') {
|
||||
visibleHeight += 55;
|
||||
}
|
||||
|
||||
const visibleGridHeight = Math.floor(visibleHeight / (GRID_CELL_HEIGHT + GRID_CELL_VMARGIN));
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar__spacer"></div>
|
||||
|
||||
<div class="navbar-buttons navbar-buttons--playlist" ng-if="ctrl.playlistSrv.isPlaying">
|
||||
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
|
||||
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a>
|
||||
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
|
||||
</div>
|
||||
|
||||
<div class="navbar__spacer"></div>
|
||||
|
||||
<div class="navbar-buttons navbar-buttons--actions">
|
||||
<button class="btn navbar-button navbar-button--add-panel" ng-show="::ctrl.dashboard.meta.canSave" bs-tooltip="'Add panel'" data-placement="bottom" ng-click="ctrl.addPanel()">
|
||||
<i class="gicon gicon-add-panel"></i>
|
||||
@@ -25,11 +25,11 @@
|
||||
<i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--share" ng-show="::ctrl.dashboard.meta.canShare" ng-click="ctrl.shareDashboard(0)" bs-tooltip="'Share dashboard'" data-placement="bottom">
|
||||
<button class="btn navbar-button navbar-button--share" ng-show="::ctrl.dashboard.meta.canShare" ng-click="ctrl.shareDashboard(0)" bs-tooltip="'Share dashboard'" data-placement="bottom">
|
||||
<i class="fa fa-share-square-o"></i></a>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--save" ng-show="ctrl.dashboard.meta.canSave" ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom">
|
||||
<button class="btn navbar-button navbar-button--save" ng-show="ctrl.dashboard.meta.canSave" ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom">
|
||||
<i class="fa fa-save"></i>
|
||||
</button>
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-buttons navbar-buttons--tv">
|
||||
<button class="btn navbar-button navbar-button--tv" ng-click="ctrl.toggleViewMode()" bs-tooltip="'Cycle view mode'" data-placement="bottom">
|
||||
<i class="fa fa-desktop"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<gf-time-picker class="gf-timepicker-nav" dashboard="ctrl.dashboard" ng-if="!ctrl.dashboard.timepicker.hidden"></gf-time-picker>
|
||||
|
||||
<div class="navbar-buttons navbar-buttons--close">
|
||||
|
||||
@@ -31,6 +31,10 @@ export class DashNavCtrl {
|
||||
this.$location.search(search);
|
||||
}
|
||||
|
||||
toggleViewMode() {
|
||||
appEvents.emit('toggle-kiosk-mode');
|
||||
}
|
||||
|
||||
close() {
|
||||
const search = this.$location.search();
|
||||
if (search.editview) {
|
||||
|
||||
@@ -5,9 +5,9 @@ import appEvents from 'app/core/app_events';
|
||||
export class ExportDataModalCtrl {
|
||||
private data: any[];
|
||||
private panel: string;
|
||||
asRows: Boolean = true;
|
||||
asRows = true;
|
||||
dateTimeFormat = 'YYYY-MM-DDTHH:mm:ssZ';
|
||||
excel: false;
|
||||
excel = false;
|
||||
|
||||
export() {
|
||||
if (this.panel === 'table') {
|
||||
|
||||
@@ -41,7 +41,7 @@ export class PanelModel {
|
||||
this.events = new Emitter();
|
||||
|
||||
// copy properties from persisted model
|
||||
for (var property in model) {
|
||||
for (const property in model) {
|
||||
this[property] = model[property];
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export class PanelModel {
|
||||
|
||||
getSaveModel() {
|
||||
const model: any = {};
|
||||
for (var property in this) {
|
||||
for (const property in this) {
|
||||
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const template = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
function dashRepeatOptionDirective(variableSrv) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
@@ -15,7 +15,7 @@ function dashRepeatOptionDirective(variableSrv) {
|
||||
scope: {
|
||||
panel: '=',
|
||||
},
|
||||
link: function(scope, element) {
|
||||
link: (scope, element) => {
|
||||
element.css({ display: 'block', width: '100%' });
|
||||
|
||||
scope.variables = variableSrv.variables.map(item => {
|
||||
@@ -36,7 +36,7 @@ function dashRepeatOptionDirective(variableSrv) {
|
||||
scope.panel.repeatDirection = 'h';
|
||||
}
|
||||
|
||||
scope.optionChanged = function() {
|
||||
scope.optionChanged = () => {
|
||||
if (scope.panel.repeat) {
|
||||
scope.panel.repeatDirection = 'h';
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ export class SettingsCtrl {
|
||||
}
|
||||
|
||||
deleteDashboard() {
|
||||
var confirmText = '';
|
||||
var text2 = this.dashboard.title;
|
||||
let confirmText = '';
|
||||
let text2 = this.dashboard.title;
|
||||
|
||||
const alerts = _.sumBy(this.dashboard.panels, panel => {
|
||||
return panel.alert ? 1 : 0;
|
||||
|
||||
@@ -11,7 +11,7 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
|
||||
};
|
||||
$scope.editor = { index: $scope.tabIndex || 0 };
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.modeSharePanel = $scope.panel ? true : false;
|
||||
|
||||
$scope.tabs = [{ title: 'Link', src: 'shareLink.html' }];
|
||||
@@ -34,8 +34,8 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
|
||||
$scope.buildUrl();
|
||||
};
|
||||
|
||||
$scope.buildUrl = function() {
|
||||
var baseUrl = $location.absUrl();
|
||||
$scope.buildUrl = () => {
|
||||
let baseUrl = $location.absUrl();
|
||||
const queryStart = baseUrl.indexOf('?');
|
||||
|
||||
if (queryStart !== -1) {
|
||||
@@ -72,7 +72,7 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
|
||||
|
||||
$scope.shareUrl = linkSrv.addParamsToUrl(baseUrl, params);
|
||||
|
||||
var soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/');
|
||||
let soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/');
|
||||
soloUrl = soloUrl.replace(config.appSubUrl + '/d/', config.appSubUrl + '/d-solo/');
|
||||
delete params.fullscreen;
|
||||
delete params.edit;
|
||||
@@ -90,15 +90,15 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
|
||||
|
||||
// This function will try to return the proper full name of the local timezone
|
||||
// Chrome does not handle the timezone offset (but phantomjs does)
|
||||
$scope.getLocalTimeZone = function() {
|
||||
$scope.getLocalTimeZone = () => {
|
||||
const utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z'));
|
||||
|
||||
// Older browser does not the internationalization API
|
||||
if (!(<any>window).Intl) {
|
||||
if (!(window as any).Intl) {
|
||||
return utcOffset;
|
||||
}
|
||||
|
||||
const dateFormat = (<any>window).Intl.DateTimeFormat();
|
||||
const dateFormat = (window as any).Intl.DateTimeFormat();
|
||||
if (!dateFormat.resolvedOptions) {
|
||||
return utcOffset;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv,
|
||||
return '&tz=' + encodeURIComponent(options.timeZone);
|
||||
};
|
||||
|
||||
$scope.getShareUrl = function() {
|
||||
$scope.getShareUrl = () => {
|
||||
return $scope.shareUrl;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class ShareSnapshotCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, $rootScope, $location, backendSrv, $timeout, timeSrv) {
|
||||
$scope.snapshot = {
|
||||
name: $scope.dashboard.title,
|
||||
@@ -25,8 +25,8 @@ export class ShareSnapshotCtrl {
|
||||
{ text: 'Public on the web', value: 3 },
|
||||
];
|
||||
|
||||
$scope.init = function() {
|
||||
backendSrv.get('/api/snapshot/shared-options').then(function(options) {
|
||||
$scope.init = () => {
|
||||
backendSrv.get('/api/snapshot/shared-options').then(options => {
|
||||
$scope.externalUrl = options['externalSnapshotURL'];
|
||||
$scope.sharingButtonText = options['externalSnapshotName'];
|
||||
$scope.externalEnabled = options['externalEnabled'];
|
||||
@@ -35,7 +35,7 @@ export class ShareSnapshotCtrl {
|
||||
|
||||
$scope.apiUrl = '/api/snapshots';
|
||||
|
||||
$scope.createSnapshot = function(external) {
|
||||
$scope.createSnapshot = external => {
|
||||
$scope.dashboard.snapshot = {
|
||||
timestamp: new Date(),
|
||||
};
|
||||
@@ -49,12 +49,12 @@ export class ShareSnapshotCtrl {
|
||||
|
||||
$rootScope.$broadcast('refresh');
|
||||
|
||||
$timeout(function() {
|
||||
$timeout(() => {
|
||||
$scope.saveSnapshot(external);
|
||||
}, $scope.snapshot.timeoutSeconds * 1000);
|
||||
};
|
||||
|
||||
$scope.saveSnapshot = function(external) {
|
||||
$scope.saveSnapshot = external => {
|
||||
const dash = $scope.dashboard.getSaveModelClone();
|
||||
$scope.scrubDashboard(dash);
|
||||
|
||||
@@ -67,7 +67,7 @@ export class ShareSnapshotCtrl {
|
||||
const postUrl = external ? $scope.externalUrl + $scope.apiUrl : $scope.apiUrl;
|
||||
|
||||
backendSrv.post(postUrl, cmdData).then(
|
||||
function(results) {
|
||||
results => {
|
||||
$scope.loading = false;
|
||||
|
||||
if (external) {
|
||||
@@ -88,17 +88,17 @@ export class ShareSnapshotCtrl {
|
||||
|
||||
$scope.step = 2;
|
||||
},
|
||||
function() {
|
||||
() => {
|
||||
$scope.loading = false;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.getSnapshotUrl = function() {
|
||||
$scope.getSnapshotUrl = () => {
|
||||
return $scope.snapshotUrl;
|
||||
};
|
||||
|
||||
$scope.scrubDashboard = function(dash) {
|
||||
$scope.scrubDashboard = dash => {
|
||||
// change title
|
||||
dash.title = $scope.snapshot.name;
|
||||
|
||||
@@ -106,7 +106,7 @@ export class ShareSnapshotCtrl {
|
||||
dash.time = timeSrv.timeRange();
|
||||
|
||||
// remove panel queries & links
|
||||
_.each(dash.panels, function(panel) {
|
||||
_.each(dash.panels, panel => {
|
||||
panel.targets = [];
|
||||
panel.links = [];
|
||||
panel.datasource = null;
|
||||
@@ -114,10 +114,10 @@ export class ShareSnapshotCtrl {
|
||||
|
||||
// remove annotation queries
|
||||
dash.annotations.list = _.chain(dash.annotations.list)
|
||||
.filter(function(annotation) {
|
||||
.filter(annotation => {
|
||||
return annotation.enable;
|
||||
})
|
||||
.map(function(annotation) {
|
||||
.map(annotation => {
|
||||
return {
|
||||
name: annotation.name,
|
||||
enable: annotation.enable,
|
||||
@@ -131,7 +131,7 @@ export class ShareSnapshotCtrl {
|
||||
.value();
|
||||
|
||||
// remove template queries
|
||||
_.each(dash.templating.list, function(variable) {
|
||||
_.each(dash.templating.list, variable => {
|
||||
variable.query = '';
|
||||
variable.options = variable.current;
|
||||
variable.refresh = false;
|
||||
@@ -149,21 +149,21 @@ export class ShareSnapshotCtrl {
|
||||
|
||||
// cleanup snapshotData
|
||||
delete $scope.dashboard.snapshot;
|
||||
$scope.dashboard.forEachPanel(function(panel) {
|
||||
$scope.dashboard.forEachPanel(panel => {
|
||||
delete panel.snapshotData;
|
||||
});
|
||||
_.each($scope.dashboard.annotations.list, function(annotation) {
|
||||
_.each($scope.dashboard.annotations.list, annotation => {
|
||||
delete annotation.snapshotData;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteSnapshot = function() {
|
||||
backendSrv.get($scope.deleteUrl).then(function() {
|
||||
$scope.deleteSnapshot = () => {
|
||||
backendSrv.get($scope.deleteUrl).then(() => {
|
||||
$scope.step = 3;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.saveExternalSnapshotRef = function(cmdData, results) {
|
||||
$scope.saveExternalSnapshotRef = (cmdData, results) => {
|
||||
// save external in local instance as well
|
||||
cmdData.external = true;
|
||||
cmdData.key = results.key;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DashboardImportCtrl } from '../dashboard_import_ctrl';
|
||||
import config from '../../../core/config';
|
||||
|
||||
describe('DashboardImportCtrl', function() {
|
||||
describe('DashboardImportCtrl', () => {
|
||||
const ctx: any = {};
|
||||
|
||||
let navModelSrv;
|
||||
@@ -26,8 +26,8 @@ describe('DashboardImportCtrl', function() {
|
||||
ctx.ctrl = new DashboardImportCtrl(backendSrv, validationSrv, navModelSrv, {}, {});
|
||||
});
|
||||
|
||||
describe('when uploading json', function() {
|
||||
beforeEach(function() {
|
||||
describe('when uploading json', () => {
|
||||
beforeEach(() => {
|
||||
config.datasources = {
|
||||
ds: {
|
||||
type: 'test-db',
|
||||
@@ -46,19 +46,19 @@ describe('DashboardImportCtrl', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should build input model', function() {
|
||||
it('should build input model', () => {
|
||||
expect(ctx.ctrl.inputs.length).toBe(1);
|
||||
expect(ctx.ctrl.inputs[0].name).toBe('ds');
|
||||
expect(ctx.ctrl.inputs[0].info).toBe('Select a Test DB data source');
|
||||
});
|
||||
|
||||
it('should set inputValid to false', function() {
|
||||
it('should set inputValid to false', () => {
|
||||
expect(ctx.ctrl.inputsValid).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when specifying grafana.com url', function() {
|
||||
beforeEach(function() {
|
||||
describe('when specifying grafana.com url', () => {
|
||||
beforeEach(() => {
|
||||
ctx.ctrl.gnetUrl = 'http://grafana.com/dashboards/123';
|
||||
// setup api mock
|
||||
backendSrv.get = jest.fn(() => {
|
||||
@@ -69,13 +69,13 @@ describe('DashboardImportCtrl', function() {
|
||||
return ctx.ctrl.checkGnetDashboard();
|
||||
});
|
||||
|
||||
it('should call gnet api with correct dashboard id', function() {
|
||||
it('should call gnet api with correct dashboard id', () => {
|
||||
expect(backendSrv.get.mock.calls[0][0]).toBe('api/gnet/dashboards/123');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when specifying dashboard id', function() {
|
||||
beforeEach(function() {
|
||||
describe('when specifying dashboard id', () => {
|
||||
beforeEach(() => {
|
||||
ctx.ctrl.gnetUrl = '2342';
|
||||
// setup api mock
|
||||
backendSrv.get = jest.fn(() => {
|
||||
@@ -86,7 +86,7 @@ describe('DashboardImportCtrl', function() {
|
||||
return ctx.ctrl.checkGnetDashboard();
|
||||
});
|
||||
|
||||
it('should call gnet api with correct dashboard id', function() {
|
||||
it('should call gnet api with correct dashboard id', () => {
|
||||
expect(backendSrv.get.mock.calls[0][0]).toBe('api/gnet/dashboards/2342');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,14 +6,14 @@ import { expect } from 'test/lib/common';
|
||||
|
||||
jest.mock('app/core/services/context_srv', () => ({}));
|
||||
|
||||
describe('DashboardModel', function() {
|
||||
describe('when creating dashboard with old schema', function() {
|
||||
describe('DashboardModel', () => {
|
||||
describe('when creating dashboard with old schema', () => {
|
||||
let model;
|
||||
let graph;
|
||||
let singlestat;
|
||||
let table;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
services: {
|
||||
filter: { time: { from: 'now-1d', to: 'now' }, list: [{}] },
|
||||
@@ -65,52 +65,52 @@ describe('DashboardModel', function() {
|
||||
table = model.panels[2];
|
||||
});
|
||||
|
||||
it('should have title', function() {
|
||||
it('should have title', () => {
|
||||
expect(model.title).toBe('No Title');
|
||||
});
|
||||
|
||||
it('should have panel id', function() {
|
||||
it('should have panel id', () => {
|
||||
expect(graph.id).toBe(1);
|
||||
});
|
||||
|
||||
it('should move time and filtering list', function() {
|
||||
it('should move time and filtering list', () => {
|
||||
expect(model.time.from).toBe('now-1d');
|
||||
expect(model.templating.list[0].allFormat).toBe('glob');
|
||||
});
|
||||
|
||||
it('graphite panel should change name too graph', function() {
|
||||
it('graphite panel should change name too graph', () => {
|
||||
expect(graph.type).toBe('graph');
|
||||
});
|
||||
|
||||
it('single stat panel should have two thresholds', function() {
|
||||
it('single stat panel should have two thresholds', () => {
|
||||
expect(singlestat.thresholds).toBe('20,30');
|
||||
});
|
||||
|
||||
it('queries without refId should get it', function() {
|
||||
it('queries without refId should get it', () => {
|
||||
expect(graph.targets[1].refId).toBe('B');
|
||||
});
|
||||
|
||||
it('update legend setting', function() {
|
||||
it('update legend setting', () => {
|
||||
expect(graph.legend.show).toBe(true);
|
||||
});
|
||||
|
||||
it('move aliasYAxis to series override', function() {
|
||||
it('move aliasYAxis to series override', () => {
|
||||
expect(graph.seriesOverrides[0].alias).toBe('test');
|
||||
expect(graph.seriesOverrides[0].yaxis).toBe(2);
|
||||
});
|
||||
|
||||
it('should move pulldowns to new schema', function() {
|
||||
it('should move pulldowns to new schema', () => {
|
||||
expect(model.annotations.list[1].name).toBe('old');
|
||||
});
|
||||
|
||||
it('table panel should only have two thresholds values', function() {
|
||||
it('table panel should only have two thresholds values', () => {
|
||||
expect(table.styles[0].thresholds[0]).toBe('20');
|
||||
expect(table.styles[0].thresholds[1]).toBe('30');
|
||||
expect(table.styles[1].thresholds[0]).toBe('200');
|
||||
expect(table.styles[1].thresholds[1]).toBe('300');
|
||||
});
|
||||
|
||||
it('graph grid to yaxes options', function() {
|
||||
it('graph grid to yaxes options', () => {
|
||||
expect(graph.yaxes[0].min).toBe(1);
|
||||
expect(graph.yaxes[0].max).toBe(10);
|
||||
expect(graph.yaxes[0].format).toBe('kbyte');
|
||||
@@ -126,11 +126,11 @@ describe('DashboardModel', function() {
|
||||
expect(graph.y_formats).toBe(undefined);
|
||||
});
|
||||
|
||||
it('dashboard schema version should be set to latest', function() {
|
||||
it('dashboard schema version should be set to latest', () => {
|
||||
expect(model.schemaVersion).toBe(16);
|
||||
});
|
||||
|
||||
it('graph thresholds should be migrated', function() {
|
||||
it('graph thresholds should be migrated', () => {
|
||||
expect(graph.thresholds.length).toBe(2);
|
||||
expect(graph.thresholds[0].op).toBe('gt');
|
||||
expect(graph.thresholds[0].value).toBe(200);
|
||||
@@ -140,16 +140,16 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when migrating to the grid layout', function() {
|
||||
describe('when migrating to the grid layout', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = {
|
||||
rows: [],
|
||||
};
|
||||
});
|
||||
|
||||
it('should create proper grid', function() {
|
||||
it('should create proper grid', () => {
|
||||
model.rows = [createRow({ collapse: false, height: 8 }, [[6], [6]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -158,7 +158,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should add special "row" panel if row is collapsed', function() {
|
||||
it('should add special "row" panel if row is collapsed', () => {
|
||||
model.rows = [createRow({ collapse: true, height: 8 }, [[6], [6]]), createRow({ height: 8 }, [[12]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -171,7 +171,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should add special "row" panel if row has visible title', function() {
|
||||
it('should add special "row" panel if row has visible title', () => {
|
||||
model.rows = [
|
||||
createRow({ showTitle: true, title: 'Row', height: 8 }, [[6], [6]]),
|
||||
createRow({ height: 8 }, [[12]]),
|
||||
@@ -189,7 +189,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should not add "row" panel if row has not visible title or not collapsed', function() {
|
||||
it('should not add "row" panel if row has not visible title or not collapsed', () => {
|
||||
model.rows = [
|
||||
createRow({ collapse: true, height: 8 }, [[12]]),
|
||||
createRow({ height: 8 }, [[12]]),
|
||||
@@ -212,7 +212,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should add all rows if even one collapsed or titled row is present', function() {
|
||||
it('should add all rows if even one collapsed or titled row is present', () => {
|
||||
model.rows = [createRow({ collapse: true, height: 8 }, [[6], [6]]), createRow({ height: 8 }, [[12]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -225,7 +225,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should properly place panels with fixed height', function() {
|
||||
it('should properly place panels with fixed height', () => {
|
||||
model.rows = [
|
||||
createRow({ height: 6 }, [[6], [6, 3], [6, 3]]),
|
||||
createRow({ height: 6 }, [[4], [4], [4, 3], [4, 3]]),
|
||||
@@ -245,7 +245,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should place panel to the right side of panel having bigger height', function() {
|
||||
it('should place panel to the right side of panel having bigger height', () => {
|
||||
model.rows = [createRow({ height: 6 }, [[4], [2, 3], [4, 6], [2, 3], [2, 3]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -260,7 +260,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should fill current row if it possible', function() {
|
||||
it('should fill current row if it possible', () => {
|
||||
model.rows = [createRow({ height: 9 }, [[4], [2, 3], [4, 6], [2, 3], [2, 3], [8, 3]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -276,7 +276,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should fill current row if it possible (2)', function() {
|
||||
it('should fill current row if it possible (2)', () => {
|
||||
model.rows = [createRow({ height: 8 }, [[4], [2, 3], [4, 6], [2, 3], [2, 3], [8, 3]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -292,7 +292,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should fill current row if panel height more than row height', function() {
|
||||
it('should fill current row if panel height more than row height', () => {
|
||||
model.rows = [createRow({ height: 6 }, [[4], [2, 3], [4, 8], [2, 3], [2, 3]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -307,7 +307,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should wrap panels to multiple rows', function() {
|
||||
it('should wrap panels to multiple rows', () => {
|
||||
model.rows = [createRow({ height: 6 }, [[6], [6], [12], [6], [3], [3]])];
|
||||
const dashboard = new DashboardModel(model);
|
||||
const panelGridPos = getGridPositions(dashboard);
|
||||
@@ -323,7 +323,7 @@ describe('DashboardModel', function() {
|
||||
expect(panelGridPos).toEqual(expectedGrid);
|
||||
});
|
||||
|
||||
it('should add repeated row if repeat set', function() {
|
||||
it('should add repeated row if repeat set', () => {
|
||||
model.rows = [
|
||||
createRow({ showTitle: true, title: 'Row', height: 8, repeat: 'server' }, [[6]]),
|
||||
createRow({ height: 8 }, [[12]]),
|
||||
@@ -344,7 +344,7 @@ describe('DashboardModel', function() {
|
||||
expect(dashboard.panels[3].repeat).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should ignore repeated row', function() {
|
||||
it('should ignore repeated row', () => {
|
||||
model.rows = [
|
||||
createRow({ showTitle: true, title: 'Row1', height: 8, repeat: 'server' }, [[6]]),
|
||||
createRow(
|
||||
@@ -364,7 +364,7 @@ describe('DashboardModel', function() {
|
||||
expect(dashboard.panels.length).toBe(2);
|
||||
});
|
||||
|
||||
it('minSpan should be twice', function() {
|
||||
it('minSpan should be twice', () => {
|
||||
model.rows = [createRow({ height: 8 }, [[6]])];
|
||||
model.rows[0].panels[0] = { minSpan: 12 };
|
||||
|
||||
@@ -372,7 +372,7 @@ describe('DashboardModel', function() {
|
||||
expect(dashboard.panels[0].minSpan).toBe(24);
|
||||
});
|
||||
|
||||
it('should assign id', function() {
|
||||
it('should assign id', () => {
|
||||
model.rows = [createRow({ collapse: true, height: 8 }, [[6], [6]])];
|
||||
model.rows[0].panels[0] = {};
|
||||
|
||||
|
||||
@@ -4,43 +4,43 @@ import { PanelModel } from '../panel_model';
|
||||
|
||||
jest.mock('app/core/services/context_srv', () => ({}));
|
||||
|
||||
describe('DashboardModel', function() {
|
||||
describe('when creating new dashboard model defaults only', function() {
|
||||
describe('DashboardModel', () => {
|
||||
describe('when creating new dashboard model defaults only', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({}, {});
|
||||
});
|
||||
|
||||
it('should have title', function() {
|
||||
it('should have title', () => {
|
||||
expect(model.title).toBe('No Title');
|
||||
});
|
||||
|
||||
it('should have meta', function() {
|
||||
it('should have meta', () => {
|
||||
expect(model.meta.canSave).toBe(true);
|
||||
expect(model.meta.canShare).toBe(true);
|
||||
});
|
||||
|
||||
it('should have default properties', function() {
|
||||
it('should have default properties', () => {
|
||||
expect(model.panels.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getting next panel id', function() {
|
||||
describe('when getting next panel id', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
panels: [{ id: 5 }],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return max id + 1', function() {
|
||||
it('should return max id + 1', () => {
|
||||
expect(model.getNextPanelId()).toBe(6);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSaveModelClone', function() {
|
||||
describe('getSaveModelClone', () => {
|
||||
it('should sort keys', () => {
|
||||
const model = new DashboardModel({});
|
||||
const saveModel = model.getSaveModelClone();
|
||||
@@ -68,20 +68,20 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('row and panel manipulation', function() {
|
||||
describe('row and panel manipulation', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({});
|
||||
});
|
||||
|
||||
it('adding panel should new up panel model', function() {
|
||||
it('adding panel should new up panel model', () => {
|
||||
dashboard.addPanel({ type: 'test', title: 'test' });
|
||||
|
||||
expect(dashboard.panels[0] instanceof PanelModel).toBe(true);
|
||||
});
|
||||
|
||||
it('duplicate panel should try to add to the right if there is space', function() {
|
||||
it('duplicate panel should try to add to the right if there is space', () => {
|
||||
const panel = { id: 10, gridPos: { x: 0, y: 0, w: 6, h: 2 } };
|
||||
|
||||
dashboard.addPanel(panel);
|
||||
@@ -95,7 +95,7 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('duplicate panel should remove repeat data', function() {
|
||||
it('duplicate panel should remove repeat data', () => {
|
||||
const panel = {
|
||||
id: 10,
|
||||
gridPos: { x: 0, y: 0, w: 6, h: 2 },
|
||||
@@ -111,29 +111,29 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Given editable false dashboard', function() {
|
||||
describe('Given editable false dashboard', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({ editable: false });
|
||||
});
|
||||
|
||||
it('Should set meta canEdit and canSave to false', function() {
|
||||
it('Should set meta canEdit and canSave to false', () => {
|
||||
expect(model.meta.canSave).toBe(false);
|
||||
expect(model.meta.canEdit).toBe(false);
|
||||
});
|
||||
|
||||
it('getSaveModelClone should remove meta', function() {
|
||||
it('getSaveModelClone should remove meta', () => {
|
||||
const clone = model.getSaveModelClone();
|
||||
expect(clone.meta).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when loading dashboard with old influxdb query schema', function() {
|
||||
describe('when loading dashboard with old influxdb query schema', () => {
|
||||
let model;
|
||||
let target;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
panels: [
|
||||
{
|
||||
@@ -185,7 +185,7 @@ describe('DashboardModel', function() {
|
||||
target = model.panels[0].targets[0];
|
||||
});
|
||||
|
||||
it('should update query schema', function() {
|
||||
it('should update query schema', () => {
|
||||
expect(target.fields).toBe(undefined);
|
||||
expect(target.select.length).toBe(2);
|
||||
expect(target.select[0].length).toBe(4);
|
||||
@@ -196,10 +196,10 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when creating dashboard model with missing list for annoations or templating', function() {
|
||||
describe('when creating dashboard model with missing list for annoations or templating', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
annotations: {
|
||||
enable: true,
|
||||
@@ -210,54 +210,54 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should add empty list', function() {
|
||||
it('should add empty list', () => {
|
||||
expect(model.annotations.list.length).toBe(1);
|
||||
expect(model.templating.list.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should add builtin annotation query', function() {
|
||||
it('should add builtin annotation query', () => {
|
||||
expect(model.annotations.list[0].builtIn).toBe(1);
|
||||
expect(model.templating.list.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Formatting epoch timestamp when timezone is set as utc', function() {
|
||||
describe('Formatting epoch timestamp when timezone is set as utc', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({ timezone: 'utc' });
|
||||
});
|
||||
|
||||
it('Should format timestamp with second resolution by default', function() {
|
||||
it('Should format timestamp with second resolution by default', () => {
|
||||
expect(dashboard.formatDate(1234567890000)).toBe('2009-02-13 23:31:30');
|
||||
});
|
||||
|
||||
it('Should format timestamp with second resolution even if second format is passed as parameter', function() {
|
||||
it('Should format timestamp with second resolution even if second format is passed as parameter', () => {
|
||||
expect(dashboard.formatDate(1234567890007, 'YYYY-MM-DD HH:mm:ss')).toBe('2009-02-13 23:31:30');
|
||||
});
|
||||
|
||||
it('Should format timestamp with millisecond resolution if format is passed as parameter', function() {
|
||||
it('Should format timestamp with millisecond resolution if format is passed as parameter', () => {
|
||||
expect(dashboard.formatDate(1234567890007, 'YYYY-MM-DD HH:mm:ss.SSS')).toBe('2009-02-13 23:31:30.007');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSubmenuVisibility with empty lists', function() {
|
||||
describe('updateSubmenuVisibility with empty lists', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({});
|
||||
model.updateSubmenuVisibility();
|
||||
});
|
||||
|
||||
it('should not enable submmenu', function() {
|
||||
it('should not enable submmenu', () => {
|
||||
expect(model.meta.submenuEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSubmenuVisibility with annotation', function() {
|
||||
describe('updateSubmenuVisibility with annotation', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
annotations: {
|
||||
list: [{}],
|
||||
@@ -266,15 +266,15 @@ describe('DashboardModel', function() {
|
||||
model.updateSubmenuVisibility();
|
||||
});
|
||||
|
||||
it('should enable submmenu', function() {
|
||||
it('should enable submmenu', () => {
|
||||
expect(model.meta.submenuEnabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSubmenuVisibility with template var', function() {
|
||||
describe('updateSubmenuVisibility with template var', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
templating: {
|
||||
list: [{}],
|
||||
@@ -283,15 +283,15 @@ describe('DashboardModel', function() {
|
||||
model.updateSubmenuVisibility();
|
||||
});
|
||||
|
||||
it('should enable submmenu', function() {
|
||||
it('should enable submmenu', () => {
|
||||
expect(model.meta.submenuEnabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSubmenuVisibility with hidden template var', function() {
|
||||
describe('updateSubmenuVisibility with hidden template var', () => {
|
||||
let model;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
templating: {
|
||||
list: [{ hide: 2 }],
|
||||
@@ -300,15 +300,15 @@ describe('DashboardModel', function() {
|
||||
model.updateSubmenuVisibility();
|
||||
});
|
||||
|
||||
it('should not enable submmenu', function() {
|
||||
it('should not enable submmenu', () => {
|
||||
expect(model.meta.submenuEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSubmenuVisibility with hidden annotation toggle', function() {
|
||||
describe('updateSubmenuVisibility with hidden annotation toggle', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({
|
||||
annotations: {
|
||||
list: [{ hide: true }],
|
||||
@@ -317,15 +317,15 @@ describe('DashboardModel', function() {
|
||||
dashboard.updateSubmenuVisibility();
|
||||
});
|
||||
|
||||
it('should not enable submmenu', function() {
|
||||
it('should not enable submmenu', () => {
|
||||
expect(dashboard.meta.submenuEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When collapsing row', function() {
|
||||
describe('When collapsing row', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({
|
||||
panels: [
|
||||
{ id: 1, type: 'graph', gridPos: { x: 0, y: 0, w: 24, h: 2 } },
|
||||
@@ -338,36 +338,36 @@ describe('DashboardModel', function() {
|
||||
dashboard.toggleRow(dashboard.panels[1]);
|
||||
});
|
||||
|
||||
it('should remove panels and put them inside collapsed row', function() {
|
||||
it('should remove panels and put them inside collapsed row', () => {
|
||||
expect(dashboard.panels.length).toBe(3);
|
||||
expect(dashboard.panels[1].panels.length).toBe(2);
|
||||
});
|
||||
|
||||
describe('and when removing row and its panels', function() {
|
||||
beforeEach(function() {
|
||||
describe('and when removing row and its panels', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.removeRow(dashboard.panels[1], true);
|
||||
});
|
||||
|
||||
it('should remove row and its panels', function() {
|
||||
it('should remove row and its panels', () => {
|
||||
expect(dashboard.panels.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and when removing only the row', function() {
|
||||
beforeEach(function() {
|
||||
describe('and when removing only the row', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.removeRow(dashboard.panels[1], false);
|
||||
});
|
||||
|
||||
it('should only remove row', function() {
|
||||
it('should only remove row', () => {
|
||||
expect(dashboard.panels.length).toBe(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When expanding row', function() {
|
||||
describe('When expanding row', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({
|
||||
panels: [
|
||||
{ id: 1, type: 'graph', gridPos: { x: 0, y: 0, w: 24, h: 6 } },
|
||||
@@ -387,16 +387,16 @@ describe('DashboardModel', function() {
|
||||
dashboard.toggleRow(dashboard.panels[1]);
|
||||
});
|
||||
|
||||
it('should add panels back', function() {
|
||||
it('should add panels back', () => {
|
||||
expect(dashboard.panels.length).toBe(5);
|
||||
});
|
||||
|
||||
it('should add them below row in array', function() {
|
||||
it('should add them below row in array', () => {
|
||||
expect(dashboard.panels[2].id).toBe(3);
|
||||
expect(dashboard.panels[3].id).toBe(4);
|
||||
});
|
||||
|
||||
it('should position them below row', function() {
|
||||
it('should position them below row', () => {
|
||||
expect(dashboard.panels[2].gridPos).toMatchObject({
|
||||
x: 0,
|
||||
y: 7,
|
||||
@@ -405,7 +405,7 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should move panels below down', function() {
|
||||
it('should move panels below down', () => {
|
||||
expect(dashboard.panels[4].gridPos).toMatchObject({
|
||||
x: 0,
|
||||
y: 9,
|
||||
@@ -414,22 +414,22 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('and when removing row and its panels', function() {
|
||||
beforeEach(function() {
|
||||
describe('and when removing row and its panels', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.removeRow(dashboard.panels[1], true);
|
||||
});
|
||||
|
||||
it('should remove row and its panels', function() {
|
||||
it('should remove row and its panels', () => {
|
||||
expect(dashboard.panels.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and when removing only the row', function() {
|
||||
beforeEach(function() {
|
||||
describe('and when removing only the row', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.removeRow(dashboard.panels[1], false);
|
||||
});
|
||||
|
||||
it('should only remove row', function() {
|
||||
it('should only remove row', () => {
|
||||
expect(dashboard.panels.length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import { HistorySrv } from '../history/history_srv';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
jest.mock('app/core/store');
|
||||
|
||||
describe('historySrv', function() {
|
||||
describe('historySrv', () => {
|
||||
const versionsResponse = versions();
|
||||
const restoreResponse = restore;
|
||||
|
||||
@@ -19,35 +19,35 @@ describe('historySrv', function() {
|
||||
const emptyDash = new DashboardModel({});
|
||||
const historyListOpts = { limit: 10, start: 0 };
|
||||
|
||||
describe('getHistoryList', function() {
|
||||
it('should return a versions array for the given dashboard id', function() {
|
||||
describe('getHistoryList', () => {
|
||||
it('should return a versions array for the given dashboard id', () => {
|
||||
backendSrv.get = jest.fn(() => Promise.resolve(versionsResponse));
|
||||
historySrv = new HistorySrv(backendSrv);
|
||||
|
||||
return historySrv.getHistoryList(dash, historyListOpts).then(function(versions) {
|
||||
return historySrv.getHistoryList(dash, historyListOpts).then(versions => {
|
||||
expect(versions).toEqual(versionsResponse);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array when not given an id', function() {
|
||||
return historySrv.getHistoryList(emptyDash, historyListOpts).then(function(versions) {
|
||||
it('should return an empty array when not given an id', () => {
|
||||
return historySrv.getHistoryList(emptyDash, historyListOpts).then(versions => {
|
||||
expect(versions).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array when not given a dashboard', function() {
|
||||
return historySrv.getHistoryList(null, historyListOpts).then(function(versions) {
|
||||
it('should return an empty array when not given a dashboard', () => {
|
||||
return historySrv.getHistoryList(null, historyListOpts).then(versions => {
|
||||
expect(versions).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('restoreDashboard', () => {
|
||||
it('should return a success response given valid parameters', function() {
|
||||
it('should return a success response given valid parameters', () => {
|
||||
const version = 6;
|
||||
backendSrv.post = jest.fn(() => Promise.resolve(restoreResponse(version)));
|
||||
historySrv = new HistorySrv(backendSrv);
|
||||
return historySrv.restoreDashboard(dash, version).then(function(response) {
|
||||
return historySrv.restoreDashboard(dash, version).then(response => {
|
||||
expect(response).toEqual(restoreResponse(version));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,10 +4,10 @@ import { expect } from 'test/lib/common';
|
||||
|
||||
jest.mock('app/core/services/context_srv', () => ({}));
|
||||
|
||||
describe('given dashboard with panel repeat', function() {
|
||||
var dashboard;
|
||||
describe('given dashboard with panel repeat', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
const dashboardJSON = {
|
||||
panels: [
|
||||
{ id: 1, type: 'row', gridPos: { x: 0, y: 0, h: 1, w: 24 } },
|
||||
@@ -35,7 +35,7 @@ describe('given dashboard with panel repeat', function() {
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should repeat panels when row is expanding', function() {
|
||||
it('should repeat panels when row is expanding', () => {
|
||||
expect(dashboard.panels.length).toBe(4);
|
||||
|
||||
// toggle row
|
||||
@@ -55,10 +55,10 @@ describe('given dashboard with panel repeat', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('given dashboard with panel repeat in horizontal direction', function() {
|
||||
var dashboard;
|
||||
describe('given dashboard with panel repeat in horizontal direction', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({
|
||||
panels: [
|
||||
{
|
||||
@@ -89,22 +89,22 @@ describe('given dashboard with panel repeat in horizontal direction', function()
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should repeat panel 3 times', function() {
|
||||
it('should repeat panel 3 times', () => {
|
||||
expect(dashboard.panels.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should mark panel repeated', function() {
|
||||
it('should mark panel repeated', () => {
|
||||
expect(dashboard.panels[0].repeat).toBe('apps');
|
||||
expect(dashboard.panels[1].repeatPanelId).toBe(2);
|
||||
});
|
||||
|
||||
it('should set scopedVars on panels', function() {
|
||||
it('should set scopedVars on panels', () => {
|
||||
expect(dashboard.panels[0].scopedVars.apps.value).toBe('se1');
|
||||
expect(dashboard.panels[1].scopedVars.apps.value).toBe('se2');
|
||||
expect(dashboard.panels[2].scopedVars.apps.value).toBe('se3');
|
||||
});
|
||||
|
||||
it('should place on first row and adjust width so all fit', function() {
|
||||
it('should place on first row and adjust width so all fit', () => {
|
||||
expect(dashboard.panels[0].gridPos).toMatchObject({
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -125,23 +125,23 @@ describe('given dashboard with panel repeat in horizontal direction', function()
|
||||
});
|
||||
});
|
||||
|
||||
describe('After a second iteration', function() {
|
||||
beforeEach(function() {
|
||||
describe('After a second iteration', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.panels[0].fill = 10;
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('reused panel should copy properties from source', function() {
|
||||
it('reused panel should copy properties from source', () => {
|
||||
expect(dashboard.panels[1].fill).toBe(10);
|
||||
});
|
||||
|
||||
it('should have same panel count', function() {
|
||||
it('should have same panel count', () => {
|
||||
expect(dashboard.panels.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('After a second iteration with different variable', function() {
|
||||
beforeEach(function() {
|
||||
describe('After a second iteration with different variable', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.templating.list.push({
|
||||
name: 'server',
|
||||
current: { text: 'se1, se2, se3', value: ['se1'] },
|
||||
@@ -151,46 +151,46 @@ describe('given dashboard with panel repeat in horizontal direction', function()
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should remove scopedVars value for last variable', function() {
|
||||
it('should remove scopedVars value for last variable', () => {
|
||||
expect(dashboard.panels[0].scopedVars.apps).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should have new variable value in scopedVars', function() {
|
||||
it('should have new variable value in scopedVars', () => {
|
||||
expect(dashboard.panels[0].scopedVars.server.value).toBe('se1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('After a second iteration and selected values reduced', function() {
|
||||
beforeEach(function() {
|
||||
describe('After a second iteration and selected values reduced', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.templating.list[0].options[1].selected = false;
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should clean up repeated panel', function() {
|
||||
it('should clean up repeated panel', () => {
|
||||
expect(dashboard.panels.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('After a second iteration and panel repeat is turned off', function() {
|
||||
beforeEach(function() {
|
||||
describe('After a second iteration and panel repeat is turned off', () => {
|
||||
beforeEach(() => {
|
||||
dashboard.panels[0].repeat = null;
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should clean up repeated panel', function() {
|
||||
it('should clean up repeated panel', () => {
|
||||
expect(dashboard.panels.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should remove scoped vars from reused panel', function() {
|
||||
it('should remove scoped vars from reused panel', () => {
|
||||
expect(dashboard.panels[0].scopedVars).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('given dashboard with panel repeat in vertical direction', function() {
|
||||
var dashboard;
|
||||
describe('given dashboard with panel repeat in vertical direction', () => {
|
||||
let dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboard = new DashboardModel({
|
||||
panels: [
|
||||
{ id: 1, type: 'row', gridPos: { x: 0, y: 0, h: 1, w: 24 } },
|
||||
@@ -218,7 +218,7 @@ describe('given dashboard with panel repeat in vertical direction', function() {
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should place on items on top of each other and keep witdh', function() {
|
||||
it('should place on items on top of each other and keep witdh', () => {
|
||||
expect(dashboard.panels[0].gridPos).toMatchObject({ x: 0, y: 0, h: 1, w: 24 }); // first row
|
||||
|
||||
expect(dashboard.panels[1].gridPos).toMatchObject({ x: 5, y: 1, h: 2, w: 8 });
|
||||
@@ -271,8 +271,8 @@ describe('given dashboard with row repeat and panel repeat in horizontal directi
|
||||
});
|
||||
|
||||
it('should panels in self row', () => {
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual([
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual([
|
||||
'row',
|
||||
'graph',
|
||||
'graph',
|
||||
@@ -290,7 +290,7 @@ describe('given dashboard with row repeat and panel repeat in horizontal directi
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be placed in their places', function() {
|
||||
it('should be placed in their places', () => {
|
||||
expect(dashboard.panels[0].gridPos).toMatchObject({ x: 0, y: 0, h: 1, w: 24 }); // 1st row
|
||||
|
||||
expect(dashboard.panels[1].gridPos).toMatchObject({ x: 0, y: 1, h: 2, w: 6 });
|
||||
@@ -311,10 +311,10 @@ describe('given dashboard with row repeat and panel repeat in horizontal directi
|
||||
});
|
||||
});
|
||||
|
||||
describe('given dashboard with row repeat', function() {
|
||||
describe('given dashboard with row repeat', () => {
|
||||
let dashboard, dashboardJSON;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
dashboardJSON = {
|
||||
panels: [
|
||||
{
|
||||
@@ -349,12 +349,12 @@ describe('given dashboard with row repeat', function() {
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should not repeat only row', function() {
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']);
|
||||
it('should not repeat only row', () => {
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph', 'row', 'graph']);
|
||||
});
|
||||
|
||||
it('should set scopedVars for each panel', function() {
|
||||
it('should set scopedVars for each panel', () => {
|
||||
dashboardJSON.templating.list[0].options[2].selected = true;
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
@@ -375,12 +375,12 @@ describe('given dashboard with row repeat', function() {
|
||||
expect(scopedVars).toEqual(['se1', 'se1', 'se1', 'se2', 'se2', 'se2', 'se3', 'se3', 'se3']);
|
||||
});
|
||||
|
||||
it('should repeat only configured row', function() {
|
||||
it('should repeat only configured row', () => {
|
||||
expect(dashboard.panels[6].id).toBe(4);
|
||||
expect(dashboard.panels[7].id).toBe(5);
|
||||
});
|
||||
|
||||
it('should repeat only row if it is collapsed', function() {
|
||||
it('should repeat only row if it is collapsed', () => {
|
||||
dashboardJSON.panels = [
|
||||
{
|
||||
id: 1,
|
||||
@@ -399,13 +399,13 @@ describe('given dashboard with row repeat', function() {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'row', 'row', 'graph']);
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual(['row', 'row', 'row', 'graph']);
|
||||
expect(dashboard.panels[0].panels).toHaveLength(2);
|
||||
expect(dashboard.panels[1].panels).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should properly repeat multiple rows', function() {
|
||||
it('should properly repeat multiple rows', () => {
|
||||
dashboardJSON.panels = [
|
||||
{
|
||||
id: 1,
|
||||
@@ -441,8 +441,8 @@ describe('given dashboard with row repeat', function() {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual([
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual([
|
||||
'row',
|
||||
'graph',
|
||||
'graph',
|
||||
@@ -469,7 +469,7 @@ describe('given dashboard with row repeat', function() {
|
||||
expect(dashboard.panels[12].scopedVars['hosts'].value).toBe('backend02');
|
||||
});
|
||||
|
||||
it('should assign unique ids for repeated panels', function() {
|
||||
it('should assign unique ids for repeated panels', () => {
|
||||
dashboardJSON.panels = [
|
||||
{
|
||||
id: 1,
|
||||
@@ -488,7 +488,7 @@ describe('given dashboard with row repeat', function() {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_ids = _.flattenDeep(
|
||||
const panelIds = _.flattenDeep(
|
||||
_.map(dashboard.panels, panel => {
|
||||
let ids = [];
|
||||
if (panel.panels && panel.panels.length) {
|
||||
@@ -498,10 +498,10 @@ describe('given dashboard with row repeat', function() {
|
||||
return ids;
|
||||
})
|
||||
);
|
||||
expect(panel_ids.length).toEqual(_.uniq(panel_ids).length);
|
||||
expect(panelIds.length).toEqual(_.uniq(panelIds).length);
|
||||
});
|
||||
|
||||
it('should place new panels in proper order', function() {
|
||||
it('should place new panels in proper order', () => {
|
||||
dashboardJSON.panels = [
|
||||
{ id: 1, type: 'row', gridPos: { x: 0, y: 0, h: 1, w: 24 }, repeat: 'apps' },
|
||||
{ id: 2, type: 'graph', gridPos: { x: 0, y: 1, h: 3, w: 12 } },
|
||||
@@ -511,10 +511,10 @@ describe('given dashboard with row repeat', function() {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']);
|
||||
const panel_y_positions = _.map(dashboard.panels, p => p.gridPos.y);
|
||||
expect(panel_y_positions).toEqual([0, 1, 1, 5, 7, 8, 8, 12]);
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'graph', 'row', 'graph', 'graph', 'graph']);
|
||||
const panelYPositions = _.map(dashboard.panels, p => p.gridPos.y);
|
||||
expect(panelYPositions).toEqual([0, 1, 1, 5, 7, 8, 8, 12]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -566,8 +566,8 @@ describe('given dashboard with row and panel repeat', () => {
|
||||
});
|
||||
|
||||
it('should repeat row and panels for each row', () => {
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
});
|
||||
|
||||
it('should clean up old repeated panels', () => {
|
||||
@@ -592,8 +592,8 @@ describe('given dashboard with row and panel repeat', () => {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
const panelTypes = _.map(dashboard.panels, 'type');
|
||||
expect(panelTypes).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
});
|
||||
|
||||
it('should set scopedVars for each row', () => {
|
||||
@@ -646,7 +646,7 @@ describe('given dashboard with row and panel repeat', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should repeat panels when row is expanding', function() {
|
||||
it('should repeat panels when row is expanding', () => {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ describe('saving dashboard as', () => {
|
||||
};
|
||||
|
||||
const mockDashboardSrv = {
|
||||
getCurrent: function() {
|
||||
getCurrent: () => {
|
||||
return {
|
||||
id: 5,
|
||||
meta: {},
|
||||
getSaveModelClone: function() {
|
||||
getSaveModelClone: () => {
|
||||
return json;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,11 +7,11 @@ describe('SaveProvisionedDashboardModalCtrl', () => {
|
||||
};
|
||||
|
||||
const mockDashboardSrv = {
|
||||
getCurrent: function() {
|
||||
getCurrent: () => {
|
||||
return {
|
||||
id: 5,
|
||||
meta: {},
|
||||
getSaveModelClone: function() {
|
||||
getSaveModelClone: () => {
|
||||
return json;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import config from 'app/core/config';
|
||||
import { LinkSrv } from 'app/features/panellinks/link_srv';
|
||||
|
||||
describe('ShareModalCtrl', () => {
|
||||
const ctx = <any>{
|
||||
const ctx = {
|
||||
timeSrv: {
|
||||
timeRange: () => {
|
||||
return { from: new Date(1000), to: new Date(2000) };
|
||||
@@ -26,9 +26,9 @@ describe('ShareModalCtrl', () => {
|
||||
templateSrv: {
|
||||
fillVariableValuesForUrl: () => {},
|
||||
},
|
||||
};
|
||||
} as any;
|
||||
|
||||
(<any>window).Intl.DateTimeFormat = () => {
|
||||
(window as any).Intl.DateTimeFormat = () => {
|
||||
return {
|
||||
resolvedOptions: () => {
|
||||
return { timeZone: 'UTC' };
|
||||
@@ -136,7 +136,7 @@ describe('ShareModalCtrl', () => {
|
||||
ctx.$location.absUrl = () => 'http://server/#!/test';
|
||||
ctx.scope.options.includeTemplateVars = true;
|
||||
|
||||
ctx.templateSrv.fillVariableValuesForUrl = function(params) {
|
||||
ctx.templateSrv.fillVariableValuesForUrl = params => {
|
||||
params['var-app'] = 'mupp';
|
||||
params['var-server'] = 'srv-01';
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { TimeSrv } from '../time_srv';
|
||||
import '../time_srv';
|
||||
import moment from 'moment';
|
||||
|
||||
describe('timeSrv', function() {
|
||||
describe('timeSrv', () => {
|
||||
const rootScope = {
|
||||
$on: jest.fn(),
|
||||
onAppEvent: jest.fn(),
|
||||
@@ -26,20 +26,20 @@ describe('timeSrv', function() {
|
||||
getTimezone: jest.fn(() => 'browser'),
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(() => {
|
||||
timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
|
||||
timeSrv.init(_dashboard);
|
||||
});
|
||||
|
||||
describe('timeRange', function() {
|
||||
it('should return unparsed when parse is false', function() {
|
||||
describe('timeRange', () => {
|
||||
it('should return unparsed when parse is false', () => {
|
||||
timeSrv.setTime({ from: 'now', to: 'now-1h' });
|
||||
const time = timeSrv.timeRange();
|
||||
expect(time.raw.from).toBe('now');
|
||||
expect(time.raw.to).toBe('now-1h');
|
||||
});
|
||||
|
||||
it('should return parsed when parse is true', function() {
|
||||
it('should return parsed when parse is true', () => {
|
||||
timeSrv.setTime({ from: 'now', to: 'now-1h' });
|
||||
const time = timeSrv.timeRange();
|
||||
expect(moment.isMoment(time.from)).toBe(true);
|
||||
@@ -47,8 +47,8 @@ describe('timeSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('init time from url', function() {
|
||||
it('should handle relative times', function() {
|
||||
describe('init time from url', () => {
|
||||
it('should handle relative times', () => {
|
||||
location = {
|
||||
search: jest.fn(() => ({
|
||||
from: 'now-2d',
|
||||
@@ -63,7 +63,7 @@ describe('timeSrv', function() {
|
||||
expect(time.raw.to).toBe('now');
|
||||
});
|
||||
|
||||
it('should handle formatted dates', function() {
|
||||
it('should handle formatted dates', () => {
|
||||
location = {
|
||||
search: jest.fn(() => ({
|
||||
from: '20140410T052010',
|
||||
@@ -79,7 +79,7 @@ describe('timeSrv', function() {
|
||||
expect(time.to.valueOf()).toEqual(new Date('2014-05-20T03:10:22Z').getTime());
|
||||
});
|
||||
|
||||
it('should handle formatted dates without time', function() {
|
||||
it('should handle formatted dates without time', () => {
|
||||
location = {
|
||||
search: jest.fn(() => ({
|
||||
from: '20140410',
|
||||
@@ -95,7 +95,7 @@ describe('timeSrv', function() {
|
||||
expect(time.to.valueOf()).toEqual(new Date('2014-05-20T00:00:00Z').getTime());
|
||||
});
|
||||
|
||||
it('should handle epochs', function() {
|
||||
it('should handle epochs', () => {
|
||||
location = {
|
||||
search: jest.fn(() => ({
|
||||
from: '1410337646373',
|
||||
@@ -111,7 +111,7 @@ describe('timeSrv', function() {
|
||||
expect(time.to.valueOf()).toEqual(1410337665699);
|
||||
});
|
||||
|
||||
it('should handle bad dates', function() {
|
||||
it('should handle bad dates', () => {
|
||||
location = {
|
||||
search: jest.fn(() => ({
|
||||
from: '20151126T00010%3C%2Fp%3E%3Cspan%20class',
|
||||
@@ -128,22 +128,22 @@ describe('timeSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setTime', function() {
|
||||
it('should return disable refresh if refresh is disabled for any range', function() {
|
||||
describe('setTime', () => {
|
||||
it('should return disable refresh if refresh is disabled for any range', () => {
|
||||
_dashboard.refresh = false;
|
||||
|
||||
timeSrv.setTime({ from: '2011-01-01', to: '2015-01-01' });
|
||||
expect(_dashboard.refresh).toBe(false);
|
||||
});
|
||||
|
||||
it('should restore refresh for absolute time range', function() {
|
||||
it('should restore refresh for absolute time range', () => {
|
||||
_dashboard.refresh = '30s';
|
||||
|
||||
timeSrv.setTime({ from: '2011-01-01', to: '2015-01-01' });
|
||||
expect(_dashboard.refresh).toBe('30s');
|
||||
});
|
||||
|
||||
it('should restore refresh after relative time range is set', function() {
|
||||
it('should restore refresh after relative time range is set', () => {
|
||||
_dashboard.refresh = '10s';
|
||||
timeSrv.setTime({
|
||||
from: moment([2011, 1, 1]),
|
||||
@@ -154,7 +154,7 @@ describe('timeSrv', function() {
|
||||
expect(_dashboard.refresh).toBe('10s');
|
||||
});
|
||||
|
||||
it('should keep refresh after relative time range is changed and now delay exists', function() {
|
||||
it('should keep refresh after relative time range is changed and now delay exists', () => {
|
||||
_dashboard.refresh = '10s';
|
||||
timeSrv.setTime({ from: 'now-1h', to: 'now-10s' });
|
||||
expect(_dashboard.refresh).toBe('10s');
|
||||
|
||||
@@ -13,7 +13,7 @@ export class TimeSrv {
|
||||
timeAtLoad: any;
|
||||
private autoRefreshBlocked: boolean;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope, private $timeout, private $location, private timer, private contextSrv) {
|
||||
// default time
|
||||
this.time = { from: '6h', to: 'now' };
|
||||
|
||||
@@ -5,10 +5,10 @@ export function inputDateDirective() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
link: function($scope, $elem, attrs, ngModel) {
|
||||
link: ($scope, $elem, attrs, ngModel) => {
|
||||
const format = 'YYYY-MM-DD HH:mm:ss';
|
||||
|
||||
const fromUser = function(text) {
|
||||
const fromUser = text => {
|
||||
if (text.indexOf('now') !== -1) {
|
||||
if (!dateMath.isValid(text)) {
|
||||
ngModel.$setValidity('error', false);
|
||||
@@ -18,7 +18,7 @@ export function inputDateDirective() {
|
||||
return text;
|
||||
}
|
||||
|
||||
var parsed;
|
||||
let parsed;
|
||||
if ($scope.ctrl.isUtc) {
|
||||
parsed = moment.utc(text, format);
|
||||
} else {
|
||||
@@ -34,7 +34,7 @@ export function inputDateDirective() {
|
||||
return parsed;
|
||||
};
|
||||
|
||||
const toUser = function(currentValue) {
|
||||
const toUser = currentValue => {
|
||||
if (moment.isMoment(currentValue)) {
|
||||
return currentValue.format(format);
|
||||
} else {
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
<div class="navbar-buttons navbar-buttons--zoom">
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(-1)'>
|
||||
<div class="navbar-buttons">
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(-1)' ng-if="ctrl.isAbsolute">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button" bs-tooltip="'Time range zoom out <br> CTRL+Z'" data-placement="bottom" ng-click='ctrl.zoom(2)'>
|
||||
<i class="fa fa-search-minus"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(1)'>
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-buttons">
|
||||
<button bs-tooltip="ctrl.tooltip" data-placement="bottom" ng-click="ctrl.openDropdown()" class="btn navbar-button gf-timepicker-nav-btn">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
<span ng-bind="ctrl.rangeString"></span>
|
||||
@@ -20,7 +10,15 @@
|
||||
<span ng-show="ctrl.dashboard.refresh" class="text-warning"> Refresh every {{ctrl.dashboard.refresh}}</span>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--refresh" ng-click="ctrl.timeSrv.refreshDashboard()">
|
||||
<button class="btn navbar-button navbar-button--tight" ng-click='ctrl.move(1)' ng-if="ctrl.isAbsolute">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--zoom" bs-tooltip="'Time range zoom out <br> CTRL+Z'" data-placement="bottom" ng-click='ctrl.zoom(2)'>
|
||||
<i class="fa fa-search-minus"></i>
|
||||
</button>
|
||||
|
||||
<button class="btn navbar-button navbar-button--refresh" ng-click="ctrl.timeSrv.refreshDashboard()">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@ export class TimePickerCtrl {
|
||||
isUtc: boolean;
|
||||
firstDayOfWeek: number;
|
||||
isOpen: boolean;
|
||||
isAbsolute: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private timeSrv) {
|
||||
@@ -65,6 +66,7 @@ export class TimePickerCtrl {
|
||||
this.tooltip = this.dashboard.formatDate(time.from) + ' <br>to<br>';
|
||||
this.tooltip += this.dashboard.formatDate(time.to);
|
||||
this.timeRaw = timeRaw;
|
||||
this.isAbsolute = moment.isMoment(this.timeRaw.to);
|
||||
}
|
||||
|
||||
zoom(factor) {
|
||||
@@ -75,7 +77,7 @@ export class TimePickerCtrl {
|
||||
const range = this.timeSrv.timeRange();
|
||||
|
||||
const timespan = (range.to.valueOf() - range.from.valueOf()) / 2;
|
||||
var to, from;
|
||||
let to, from;
|
||||
if (direction === -1) {
|
||||
to = range.to.valueOf() - timespan;
|
||||
from = range.from.valueOf() - timespan;
|
||||
|
||||
@@ -2,7 +2,7 @@ import angular from 'angular';
|
||||
import { ChangeTracker } from './change_tracker';
|
||||
|
||||
/** @ngInject */
|
||||
export function unsavedChangesSrv($rootScope, $q, $location, $timeout, contextSrv, dashboardSrv, $window) {
|
||||
export function unsavedChangesSrv(this: any, $rootScope, $q, $location, $timeout, contextSrv, dashboardSrv, $window) {
|
||||
this.init = function(dashboard, scope) {
|
||||
this.tracker = new ChangeTracker(dashboard, scope, 1000, $location, $window, $timeout, contextSrv, $rootScope);
|
||||
return this.tracker;
|
||||
|
||||
@@ -16,12 +16,12 @@ function uploadDashboardDirective(timer, alertSrv, $location) {
|
||||
scope: {
|
||||
onUpload: '&',
|
||||
},
|
||||
link: function(scope) {
|
||||
link: scope => {
|
||||
function file_selected(evt) {
|
||||
const files = evt.target.files; // FileList object
|
||||
const readerOnload = function() {
|
||||
return function(e) {
|
||||
var dash;
|
||||
const readerOnload = () => {
|
||||
return e => {
|
||||
let dash;
|
||||
try {
|
||||
dash = JSON.parse(e.target.result);
|
||||
} catch (err) {
|
||||
@@ -30,16 +30,21 @@ function uploadDashboardDirective(timer, alertSrv, $location) {
|
||||
return;
|
||||
}
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.$apply(() => {
|
||||
scope.onUpload({ dash: dash });
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0, f; (f = files[i]); i++) {
|
||||
let i = 0;
|
||||
let file = files[i];
|
||||
|
||||
while (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = readerOnload();
|
||||
reader.readAsText(f);
|
||||
reader.readAsText(file);
|
||||
i += 1;
|
||||
file = files[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,18 +22,18 @@ export class DashboardViewState {
|
||||
self.$scope = $scope;
|
||||
self.dashboard = $scope.dashboard;
|
||||
|
||||
$scope.onAppEvent('$routeUpdate', function() {
|
||||
$scope.onAppEvent('$routeUpdate', () => {
|
||||
const urlState = self.getQueryStringState();
|
||||
if (self.needsSync(urlState)) {
|
||||
self.update(urlState, true);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.onAppEvent('panel-change-view', function(evt, payload) {
|
||||
$scope.onAppEvent('panel-change-view', (evt, payload) => {
|
||||
self.update(payload);
|
||||
});
|
||||
|
||||
$scope.onAppEvent('panel-initialized', function(evt, payload) {
|
||||
$scope.onAppEvent('panel-initialized', (evt, payload) => {
|
||||
self.registerPanel(payload.scope);
|
||||
});
|
||||
|
||||
@@ -156,7 +156,7 @@ export class DashboardViewState {
|
||||
}
|
||||
|
||||
getPanelScope(id) {
|
||||
return _.find(this.panelScopes, function(panelScope) {
|
||||
return _.find(this.panelScopes, panelScope => {
|
||||
return panelScope.ctrl.panel.id === id;
|
||||
});
|
||||
}
|
||||
@@ -176,7 +176,7 @@ export class DashboardViewState {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$timeout(function() {
|
||||
this.$timeout(() => {
|
||||
if (self.oldTimeRange !== ctrl.range) {
|
||||
self.$rootScope.$broadcast('refresh');
|
||||
} else {
|
||||
@@ -216,7 +216,7 @@ export class DashboardViewState {
|
||||
}
|
||||
}
|
||||
|
||||
const unbind = panelScope.$on('$destroy', function() {
|
||||
const unbind = panelScope.$on('$destroy', () => {
|
||||
self.panelScopes = _.without(self.panelScopes, panelScope);
|
||||
unbind();
|
||||
});
|
||||
@@ -226,7 +226,7 @@ export class DashboardViewState {
|
||||
/** @ngInject */
|
||||
export function dashboardViewStateSrv($location, $timeout, $rootScope) {
|
||||
return {
|
||||
create: function($scope) {
|
||||
create: $scope => {
|
||||
return new DashboardViewState($scope, $location, $timeout, $rootScope);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export var iconMap = {
|
||||
export let iconMap = {
|
||||
'external link': 'fa-external-link',
|
||||
dashboard: 'fa-th-large',
|
||||
question: 'fa-question',
|
||||
|
||||
@@ -10,7 +10,7 @@ function dashLinksContainer() {
|
||||
restrict: 'E',
|
||||
controller: 'DashLinksContainerCtrl',
|
||||
template: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
|
||||
link: function() {},
|
||||
link: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ function dashLinksContainer() {
|
||||
function dashLink($compile, $sanitize, linkSrv) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, elem) {
|
||||
link: (scope, elem) => {
|
||||
const link = scope.link;
|
||||
var template =
|
||||
let template =
|
||||
'<div class="gf-form">' +
|
||||
'<a class="pointer gf-form-label" data-placement="bottom"' +
|
||||
(link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"' : '') +
|
||||
@@ -130,16 +130,16 @@ export class DashLinksContainerCtrl {
|
||||
function updateDashLinks() {
|
||||
const promises = _.map($scope.links, buildLinks);
|
||||
|
||||
$q.all(promises).then(function(results) {
|
||||
$q.all(promises).then(results => {
|
||||
$scope.generatedLinks = _.flatten(results);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.searchDashboards = function(link, limit) {
|
||||
return backendSrv.search({ tag: link.tags, limit: limit }).then(function(results) {
|
||||
$scope.searchDashboards = (link, limit) => {
|
||||
return backendSrv.search({ tag: link.tags, limit: limit }).then(results => {
|
||||
return _.reduce(
|
||||
results,
|
||||
function(memo, dash) {
|
||||
(memo, dash) => {
|
||||
// do not add current dashboard
|
||||
if (dash.id !== currentDashId) {
|
||||
memo.push({
|
||||
@@ -158,9 +158,9 @@ export class DashLinksContainerCtrl {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fillDropdown = function(link) {
|
||||
$scope.searchDashboards(link, 100).then(function(results) {
|
||||
_.each(results, function(hit) {
|
||||
$scope.fillDropdown = link => {
|
||||
$scope.searchDashboards(link, 100).then(results => {
|
||||
_.each(results, hit => {
|
||||
hit.url = linkSrv.getLinkUrl(hit);
|
||||
});
|
||||
link.searchHits = results;
|
||||
|
||||
@@ -2,14 +2,14 @@ import angular from 'angular';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export class ChangePasswordCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, backendSrv, $location, navModelSrv) {
|
||||
$scope.command = {};
|
||||
$scope.authProxyEnabled = config.authProxyEnabled;
|
||||
$scope.ldapEnabled = config.ldapEnabled;
|
||||
$scope.navModel = navModelSrv.getNav('profile', 'change-password', 0);
|
||||
|
||||
$scope.changePassword = function() {
|
||||
$scope.changePassword = () => {
|
||||
if (!$scope.userForm.$valid) {
|
||||
return;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export class ChangePasswordCtrl {
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.put('/api/user/password', $scope.command).then(function() {
|
||||
backendSrv.put('/api/user/password', $scope.command).then(() => {
|
||||
$location.path('profile');
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ export default class CreateTeamCtrl {
|
||||
email: string;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $location, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'teams', 0);
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ import angular from 'angular';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export class NewOrgCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, $http, backendSrv, navModelSrv) {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'admin', 'global-orgs', 1);
|
||||
$scope.newOrg = { name: '' };
|
||||
|
||||
$scope.createOrg = function() {
|
||||
backendSrv.post('/api/orgs/', $scope.newOrg).then(function(result) {
|
||||
backendSrv.post('/api/user/using/' + result.orgId).then(function() {
|
||||
$scope.createOrg = () => {
|
||||
backendSrv.post('/api/orgs/', $scope.newOrg).then(result => {
|
||||
backendSrv.post('/api/user/using/' + result.orgId).then(() => {
|
||||
window.location.href = config.appSubUrl + '/org';
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import angular from 'angular';
|
||||
|
||||
export class OrgApiKeysCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, $http, backendSrv, navModelSrv) {
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'apikeys', 0);
|
||||
|
||||
$scope.roleTypes = ['Viewer', 'Editor', 'Admin'];
|
||||
$scope.token = { role: 'Viewer' };
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.getTokens();
|
||||
};
|
||||
|
||||
$scope.getTokens = function() {
|
||||
backendSrv.get('/api/auth/keys').then(function(tokens) {
|
||||
$scope.getTokens = () => {
|
||||
backendSrv.get('/api/auth/keys').then(tokens => {
|
||||
$scope.tokens = tokens;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.removeToken = function(id) {
|
||||
$scope.removeToken = id => {
|
||||
backendSrv.delete('/api/auth/keys/' + id).then($scope.getTokens);
|
||||
};
|
||||
|
||||
$scope.addToken = function() {
|
||||
backendSrv.post('/api/auth/keys', $scope.token).then(function(result) {
|
||||
$scope.addToken = () => {
|
||||
backendSrv.post('/api/auth/keys', $scope.token).then(result => {
|
||||
const modalScope = $scope.$new(true);
|
||||
modalScope.key = result.key;
|
||||
modalScope.rootPath = window.location.origin + $scope.$root.appSubUrl;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import angular from 'angular';
|
||||
|
||||
export class OrgDetailsCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, $http, backendSrv, contextSrv, navModelSrv) {
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.getOrgInfo();
|
||||
$scope.navModel = navModelSrv.getNav('cfg', 'org-settings', 0);
|
||||
};
|
||||
|
||||
$scope.getOrgInfo = function() {
|
||||
backendSrv.get('/api/org').then(function(org) {
|
||||
$scope.getOrgInfo = () => {
|
||||
backendSrv.get('/api/org').then(org => {
|
||||
$scope.org = org;
|
||||
$scope.address = org.address;
|
||||
contextSrv.user.orgName = org.name;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
$scope.update = () => {
|
||||
if (!$scope.orgForm.$valid) {
|
||||
return;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export class OrgDetailsCtrl {
|
||||
backendSrv.put('/api/org', data).then($scope.getOrgInfo);
|
||||
};
|
||||
|
||||
$scope.updateAddress = function() {
|
||||
$scope.updateAddress = () => {
|
||||
if (!$scope.addressForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export class PrefsControlCtrl {
|
||||
];
|
||||
themes: any = [{ value: '', text: 'Default' }, { value: 'dark', text: 'Dark' }, { value: 'light', text: 'Light' }];
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $location) {}
|
||||
|
||||
$onInit() {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { coreModule } from 'app/core/core';
|
||||
|
||||
export class ProfileCtrl {
|
||||
user: any;
|
||||
old_theme: any;
|
||||
oldTheme: any;
|
||||
teams: any = [];
|
||||
orgs: any = [];
|
||||
userForm: any;
|
||||
@@ -12,7 +12,7 @@ export class ProfileCtrl {
|
||||
readonlyLoginFields = config.disableLoginForm;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
|
||||
this.getUser();
|
||||
this.getUserTeams();
|
||||
@@ -54,7 +54,7 @@ export class ProfileCtrl {
|
||||
|
||||
this.backendSrv.put('/api/user/', this.user).then(() => {
|
||||
this.contextSrv.user.name = this.user.name || this.user.login;
|
||||
if (this.old_theme !== this.user.theme) {
|
||||
if (this.oldTheme !== this.user.theme) {
|
||||
window.location.href = config.appSubUrl + this.$location.path();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import angular from 'angular';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export class SelectOrgCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, backendSrv, contextSrv) {
|
||||
contextSrv.sidemenu = false;
|
||||
|
||||
@@ -14,18 +14,18 @@ export class SelectOrgCtrl {
|
||||
},
|
||||
};
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.getUserOrgs();
|
||||
};
|
||||
|
||||
$scope.getUserOrgs = function() {
|
||||
backendSrv.get('/api/user/orgs').then(function(orgs) {
|
||||
$scope.getUserOrgs = () => {
|
||||
backendSrv.get('/api/user/orgs').then(orgs => {
|
||||
$scope.orgs = orgs;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setUsingOrg = function(org) {
|
||||
backendSrv.post('/api/user/using/' + org.orgId).then(function() {
|
||||
$scope.setUsingOrg = org => {
|
||||
backendSrv.post('/api/user/using/' + org.orgId).then(() => {
|
||||
window.location.href = config.appSubUrl + '/';
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ export class UserInviteCtrl {
|
||||
invite: any;
|
||||
inviteForm: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, navModelSrv, private $location) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'users', 0);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
// if we have snapshot data use that
|
||||
if (this.panel.snapshotData) {
|
||||
this.updateTimeRange();
|
||||
var data = this.panel.snapshotData;
|
||||
let data = this.panel.snapshotData;
|
||||
// backward compatibility
|
||||
if (!_.isArray(data)) {
|
||||
data = data.data;
|
||||
@@ -155,7 +155,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
}
|
||||
|
||||
calculateInterval() {
|
||||
var intervalOverride = this.panel.interval;
|
||||
let intervalOverride = this.panel.interval;
|
||||
|
||||
// if no panel interval check datasource
|
||||
if (intervalOverride) {
|
||||
@@ -164,7 +164,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
intervalOverride = this.datasource.interval;
|
||||
}
|
||||
|
||||
var res = kbn.calculateInterval(this.range, this.resolution, intervalOverride);
|
||||
const res = kbn.calculateInterval(this.range, this.resolution, intervalOverride);
|
||||
this.interval = res.interval;
|
||||
this.intervalMs = res.intervalMs;
|
||||
}
|
||||
@@ -174,15 +174,15 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
|
||||
// check panel time overrrides
|
||||
if (this.panel.timeFrom) {
|
||||
var timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
|
||||
var timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
|
||||
const timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
|
||||
const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
|
||||
if (timeFromInfo.invalid) {
|
||||
this.timeInfo = 'invalid time override';
|
||||
return;
|
||||
}
|
||||
|
||||
if (_.isString(this.range.raw.from)) {
|
||||
var timeFromDate = dateMath.parse(timeFromInfo.from);
|
||||
const timeFromDate = dateMath.parse(timeFromInfo.from);
|
||||
this.timeInfo = timeFromInfo.display;
|
||||
this.range.from = timeFromDate;
|
||||
this.range.to = dateMath.parse(timeFromInfo.to);
|
||||
@@ -192,14 +192,14 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
}
|
||||
|
||||
if (this.panel.timeShift) {
|
||||
var timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
|
||||
var timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
|
||||
const timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
|
||||
const timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
|
||||
if (timeShiftInfo.invalid) {
|
||||
this.timeInfo = 'invalid timeshift';
|
||||
return;
|
||||
}
|
||||
|
||||
var timeShift = '-' + timeShiftInterpolated;
|
||||
const 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);
|
||||
@@ -220,12 +220,12 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
|
||||
// make shallow copy of scoped vars,
|
||||
// and add built in variables interval and interval_ms
|
||||
var scopedVars = Object.assign({}, this.panel.scopedVars, {
|
||||
const scopedVars = Object.assign({}, this.panel.scopedVars, {
|
||||
__interval: { text: this.interval, value: this.interval },
|
||||
__interval_ms: { text: this.intervalMs, value: this.intervalMs },
|
||||
});
|
||||
|
||||
var metricsQuery = {
|
||||
const metricsQuery = {
|
||||
timezone: this.dashboard.getTimezone(),
|
||||
panelId: this.panel.id,
|
||||
dashboardId: this.dashboard.id,
|
||||
@@ -343,14 +343,14 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
}
|
||||
|
||||
removeQuery(target) {
|
||||
var index = _.indexOf(this.panel.targets, target);
|
||||
const index = _.indexOf(this.panel.targets, target);
|
||||
this.panel.targets.splice(index, 1);
|
||||
this.nextRefId = this.dashboard.getNextQueryLetter(this.panel);
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
moveQuery(target, direction) {
|
||||
var index = _.indexOf(this.panel.targets, target);
|
||||
const index = _.indexOf(this.panel.targets, target);
|
||||
_.move(this.panel.targets, index, index + direction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export class MetricsTabCtrl {
|
||||
this.helpOpen = !this.helpOpen;
|
||||
|
||||
this.backendSrv.get(`/api/plugins/${this.datasourceInstance.meta.id}/markdown/query_help`).then(res => {
|
||||
var md = new Remarkable();
|
||||
const md = new Remarkable();
|
||||
this.helpHtml = this.$sce.trustAsHtml(md.render(res));
|
||||
});
|
||||
}
|
||||
@@ -110,7 +110,7 @@ export class MetricsTabCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
export function metricsTabDirective() {
|
||||
'use strict';
|
||||
return {
|
||||
|
||||
@@ -43,7 +43,7 @@ export class PanelCtrl {
|
||||
this.events = this.panel.events;
|
||||
this.timing = {};
|
||||
|
||||
var plugin = config.panels[this.panel.type];
|
||||
const plugin = config.panels[this.panel.type];
|
||||
if (plugin) {
|
||||
this.pluginId = plugin.id;
|
||||
this.pluginName = plugin.name;
|
||||
@@ -105,7 +105,7 @@ export class PanelCtrl {
|
||||
this.editModeInitiated = true;
|
||||
this.events.emit('init-edit-mode', null);
|
||||
|
||||
var urlTab = (this.$injector.get('$routeParams').tab || '').toLowerCase();
|
||||
const urlTab = (this.$injector.get('$routeParams').tab || '').toLowerCase();
|
||||
if (urlTab) {
|
||||
this.editorTabs.forEach((tab, i) => {
|
||||
if (tab.title.toLowerCase() === urlTab) {
|
||||
@@ -117,16 +117,16 @@ export class PanelCtrl {
|
||||
|
||||
changeTab(newIndex) {
|
||||
this.editorTabIndex = newIndex;
|
||||
var route = this.$injector.get('$route');
|
||||
const route = this.$injector.get('$route');
|
||||
route.current.params.tab = this.editorTabs[newIndex].title.toLowerCase();
|
||||
route.updateParams();
|
||||
}
|
||||
|
||||
addEditorTab(title, directiveFn, index?) {
|
||||
var editorTab = { title, directiveFn };
|
||||
const editorTab = { title, directiveFn };
|
||||
|
||||
if (_.isString(directiveFn)) {
|
||||
editorTab.directiveFn = function() {
|
||||
editorTab.directiveFn = () => {
|
||||
return { templateUrl: directiveFn };
|
||||
};
|
||||
}
|
||||
@@ -225,9 +225,9 @@ export class PanelCtrl {
|
||||
|
||||
calculatePanelHeight() {
|
||||
if (this.fullscreen) {
|
||||
var docHeight = $(window).height();
|
||||
var editHeight = Math.floor(docHeight * 0.4);
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
const docHeight = $(window).height();
|
||||
const editHeight = Math.floor(docHeight * 0.4);
|
||||
const fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
this.containerHeight = this.panel.gridPos.h * GRID_CELL_HEIGHT + (this.panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
|
||||
@@ -293,7 +293,7 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
sharePanel() {
|
||||
var shareScope = this.$scope.$new();
|
||||
const shareScope = this.$scope.$new();
|
||||
shareScope.panel = this.panel;
|
||||
shareScope.dashboard = this.dashboard;
|
||||
|
||||
@@ -317,24 +317,24 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
getInfoContent(options) {
|
||||
var markdown = this.panel.description;
|
||||
let markdown = this.panel.description;
|
||||
|
||||
if (options.mode === 'tooltip') {
|
||||
markdown = this.error || this.panel.description;
|
||||
}
|
||||
|
||||
var linkSrv = this.$injector.get('linkSrv');
|
||||
var sanitize = this.$injector.get('$sanitize');
|
||||
var templateSrv = this.$injector.get('templateSrv');
|
||||
var interpolatedMarkdown = templateSrv.replace(markdown, this.panel.scopedVars);
|
||||
var html = '<div class="markdown-html">';
|
||||
const linkSrv = this.$injector.get('linkSrv');
|
||||
const sanitize = this.$injector.get('$sanitize');
|
||||
const templateSrv = this.$injector.get('templateSrv');
|
||||
const interpolatedMarkdown = templateSrv.replace(markdown, this.panel.scopedVars);
|
||||
let html = '<div class="markdown-html">';
|
||||
|
||||
html += new Remarkable().render(interpolatedMarkdown);
|
||||
|
||||
if (this.panel.links && this.panel.links.length > 0) {
|
||||
html += '<ul>';
|
||||
for (const link of this.panel.links) {
|
||||
var info = linkSrv.getPanelLinkAnchorInfo(link, this.panel.scopedVars);
|
||||
const info = linkSrv.getPanelLinkAnchorInfo(link, this.panel.scopedVars);
|
||||
html +=
|
||||
'<li><a class="panel-menu-link" href="' +
|
||||
info.href +
|
||||
@@ -352,7 +352,7 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
openInspector() {
|
||||
var modalScope = this.$scope.$new();
|
||||
const modalScope = this.$scope.$new();
|
||||
modalScope.panel = this.panel;
|
||||
modalScope.dashboard = this.dashboard;
|
||||
modalScope.panelInfoHtml = this.getInfoContent({ mode: 'inspector' });
|
||||
|
||||
@@ -54,13 +54,13 @@ const panelTemplate = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
module.directive('grafanaPanel', function($rootScope, $document, $timeout) {
|
||||
module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: panelTemplate,
|
||||
transclude: true,
|
||||
scope: { ctrl: '=' },
|
||||
link: function(scope, elem) {
|
||||
link: (scope, elem) => {
|
||||
const panelContainer = elem.find('.panel-container');
|
||||
const panelContent = elem.find('.panel-content');
|
||||
const cornerInfoElem = elem.find('.panel-info-corner');
|
||||
@@ -184,7 +184,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) {
|
||||
|
||||
infoDrop = new Drop({
|
||||
target: cornerInfoElem[0],
|
||||
content: function() {
|
||||
content: () => {
|
||||
return ctrl.getInfoContent({ mode: 'tooltip' });
|
||||
},
|
||||
classes: ctrl.error ? 'drop-error' : 'drop-help',
|
||||
@@ -208,7 +208,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) {
|
||||
scope.$watchGroup(['ctrl.error', 'ctrl.panel.description'], updatePanelCornerInfo);
|
||||
scope.$watchCollection('ctrl.panel.links', updatePanelCornerInfo);
|
||||
|
||||
cornerInfoElem.on('click', function() {
|
||||
cornerInfoElem.on('click', () => {
|
||||
infoDrop.close();
|
||||
scope.$apply(ctrl.openInspector.bind(ctrl));
|
||||
});
|
||||
@@ -216,7 +216,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) {
|
||||
elem.on('mouseenter', mouseEnter);
|
||||
elem.on('mouseleave', mouseLeave);
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
scope.$on('$destroy', () => {
|
||||
elem.off();
|
||||
cornerInfoElem.off();
|
||||
|
||||
@@ -232,7 +232,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) {
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('panelHelpCorner', function($rootScope) {
|
||||
module.directive('panelHelpCorner', $rootScope => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: `
|
||||
@@ -242,6 +242,6 @@ module.directive('panelHelpCorner', function($rootScope) {
|
||||
</span>
|
||||
</span>
|
||||
`,
|
||||
link: function(scope, elem) {},
|
||||
link: (scope, elem) => {},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -80,17 +80,17 @@ function createMenuTemplate(ctrl) {
|
||||
return html;
|
||||
}
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
function panelHeader($compile) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
link: function(scope, elem, attrs) {
|
||||
link: (scope, elem, attrs) => {
|
||||
const menuElem = elem.find('.panel-menu');
|
||||
let menuScope;
|
||||
let isDragged;
|
||||
|
||||
elem.click(function(evt) {
|
||||
elem.click(evt => {
|
||||
const targetClass = evt.target.className;
|
||||
|
||||
// remove existing scope
|
||||
|
||||
@@ -87,7 +87,7 @@ export class QueryRowCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
function queryEditorRowDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
@@ -40,7 +40,7 @@ export class QueryTroubleshooterCtrl {
|
||||
mockedResponse: string;
|
||||
jsonExplorer: JsonExplorer;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, private $timeout) {
|
||||
this.onRequestErrorEventListener = this.onRequestError.bind(this);
|
||||
this.onRequestResponseEventListener = this.onRequestResponse.bind(this);
|
||||
@@ -87,7 +87,7 @@ export class QueryTroubleshooterCtrl {
|
||||
}
|
||||
|
||||
handleMocking(data) {
|
||||
var mockedData;
|
||||
let mockedData;
|
||||
try {
|
||||
mockedData = JSON.parse(this.mockedResponse);
|
||||
} catch (err) {
|
||||
@@ -170,8 +170,8 @@ export function queryTroubleshooter() {
|
||||
panelCtrl: '=',
|
||||
isOpen: '=',
|
||||
},
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
ctrl.renderJsonExplorer = function(data) {
|
||||
link: (scope, elem, attrs, ctrl) => {
|
||||
ctrl.renderJsonExplorer = data => {
|
||||
const jsonElem = elem.find('.query-troubleshooter-json');
|
||||
|
||||
ctrl.jsonExplorer = new JsonExplorer(data, 3, {
|
||||
|
||||
@@ -7,7 +7,7 @@ export class SoloPanelCtrl {
|
||||
constructor($scope, $routeParams, $location, dashboardLoaderSrv, contextSrv, backendSrv) {
|
||||
let panelId;
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
contextSrv.sidemenu = false;
|
||||
appEvents.emit('toggle-sidemenu-hidden');
|
||||
|
||||
@@ -27,13 +27,13 @@ export class SoloPanelCtrl {
|
||||
return;
|
||||
}
|
||||
|
||||
dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug, $routeParams.uid).then(function(result) {
|
||||
dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug, $routeParams.uid).then(result => {
|
||||
result.meta.soloMode = true;
|
||||
$scope.initDashboard(result, $scope);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.initPanelScope = function() {
|
||||
$scope.initPanelScope = () => {
|
||||
const panelInfo = $scope.dashboard.getPanelInfoById(panelId);
|
||||
|
||||
// fake row ctrl scope
|
||||
|
||||
@@ -7,11 +7,11 @@ export class LinkSrv {
|
||||
constructor(private templateSrv, private timeSrv) {}
|
||||
|
||||
getLinkUrl(link) {
|
||||
var url = this.templateSrv.replace(link.url || '');
|
||||
var params = {};
|
||||
const url = this.templateSrv.replace(link.url || '');
|
||||
const params = {};
|
||||
|
||||
if (link.keepTime) {
|
||||
var range = this.timeSrv.timeRangeForUrl();
|
||||
const range = this.timeSrv.timeRangeForUrl();
|
||||
params['from'] = range.from;
|
||||
params['to'] = range.to;
|
||||
}
|
||||
@@ -24,16 +24,16 @@ export class LinkSrv {
|
||||
}
|
||||
|
||||
addParamsToUrl(url, params) {
|
||||
var paramsArray = [];
|
||||
const paramsArray = [];
|
||||
|
||||
_.each(params, function(value, key) {
|
||||
_.each(params, (value, key) => {
|
||||
if (value === null) {
|
||||
return;
|
||||
}
|
||||
if (value === true) {
|
||||
paramsArray.push(key);
|
||||
} else if (_.isArray(value)) {
|
||||
_.each(value, function(instance) {
|
||||
_.each(value, instance => {
|
||||
paramsArray.push(key + '=' + encodeURIComponent(instance));
|
||||
});
|
||||
} else {
|
||||
@@ -50,7 +50,7 @@ export class LinkSrv {
|
||||
|
||||
appendToQueryString(url, stringToAppend) {
|
||||
if (!_.isUndefined(stringToAppend) && stringToAppend !== null && stringToAppend !== '') {
|
||||
var pos = url.indexOf('?');
|
||||
const pos = url.indexOf('?');
|
||||
if (pos !== -1) {
|
||||
if (url.length - pos > 1) {
|
||||
url += '&';
|
||||
@@ -65,14 +65,14 @@ export class LinkSrv {
|
||||
}
|
||||
|
||||
getAnchorInfo(link) {
|
||||
var info: any = {};
|
||||
const info: any = {};
|
||||
info.href = this.getLinkUrl(link);
|
||||
info.title = this.templateSrv.replace(link.title || '');
|
||||
return info;
|
||||
}
|
||||
|
||||
getPanelLinkAnchorInfo(link, scopedVars) {
|
||||
var info: any = {};
|
||||
const info: any = {};
|
||||
if (link.type === 'absolute') {
|
||||
info.target = link.targetBlank ? '_blank' : '_self';
|
||||
info.href = this.templateSrv.replace(link.url || '', scopedVars);
|
||||
@@ -87,14 +87,14 @@ export class LinkSrv {
|
||||
info.target = link.targetBlank ? '_blank' : '';
|
||||
} else {
|
||||
info.title = this.templateSrv.replace(link.title || '', scopedVars);
|
||||
var slug = kbn.slugifyForUrl(link.dashboard || '');
|
||||
const slug = kbn.slugifyForUrl(link.dashboard || '');
|
||||
info.href = 'dashboard/db/' + slug + '?';
|
||||
}
|
||||
|
||||
var params = {};
|
||||
const params = {};
|
||||
|
||||
if (link.keepTime) {
|
||||
var range = this.timeSrv.timeRangeForUrl();
|
||||
const range = this.timeSrv.timeRangeForUrl();
|
||||
params['from'] = range.from;
|
||||
params['to'] = range.to;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ function panelLinksEditor() {
|
||||
restrict: 'E',
|
||||
controller: 'PanelLinksEditorCtrl',
|
||||
templateUrl: 'public/app/features/panellinks/module.html',
|
||||
link: function() {},
|
||||
link: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ export class PanelLinksEditorCtrl {
|
||||
constructor($scope, backendSrv) {
|
||||
$scope.panel.links = $scope.panel.links || [];
|
||||
|
||||
$scope.addLink = function() {
|
||||
$scope.addLink = () => {
|
||||
$scope.panel.links.push({
|
||||
type: 'dashboard',
|
||||
});
|
||||
};
|
||||
|
||||
$scope.searchDashboards = function(queryStr, callback) {
|
||||
backendSrv.search({ query: queryStr }).then(function(hits) {
|
||||
const dashboards = _.map(hits, function(dash) {
|
||||
$scope.searchDashboards = (queryStr, callback) => {
|
||||
backendSrv.search({ query: queryStr }).then(hits => {
|
||||
const dashboards = _.map(hits, dash => {
|
||||
return dash.title;
|
||||
});
|
||||
|
||||
@@ -35,8 +35,8 @@ export class PanelLinksEditorCtrl {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.dashboardChanged = function(link) {
|
||||
backendSrv.search({ query: link.dashboard }).then(function(hits) {
|
||||
$scope.dashboardChanged = link => {
|
||||
backendSrv.search({ query: link.dashboard }).then(hits => {
|
||||
const dashboard = _.find(hits, { title: link.dashboard });
|
||||
if (dashboard) {
|
||||
if (dashboard.url) {
|
||||
@@ -50,7 +50,7 @@ export class PanelLinksEditorCtrl {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteLink = function(link) {
|
||||
$scope.deleteLink = link => {
|
||||
$scope.panel.links = _.without($scope.panel.links, link);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ jest.mock('angular', () => {
|
||||
return new AngularJSMock();
|
||||
});
|
||||
|
||||
describe('linkSrv', function() {
|
||||
describe('linkSrv', () => {
|
||||
let linkSrv;
|
||||
const templateSrvMock = {};
|
||||
const timeSrvMock = {};
|
||||
@@ -15,24 +15,24 @@ describe('linkSrv', function() {
|
||||
linkSrv = new LinkSrv(templateSrvMock, timeSrvMock);
|
||||
});
|
||||
|
||||
describe('when appending query strings', function() {
|
||||
it('add ? to URL if not present', function() {
|
||||
describe('when appending query strings', () => {
|
||||
it('add ? to URL if not present', () => {
|
||||
const url = linkSrv.appendToQueryString('http://example.com', 'foo=bar');
|
||||
expect(url).toBe('http://example.com?foo=bar');
|
||||
});
|
||||
|
||||
it('do not add & to URL if ? is present but query string is empty', function() {
|
||||
it('do not add & to URL if ? is present but query string is empty', () => {
|
||||
const url = linkSrv.appendToQueryString('http://example.com?', 'foo=bar');
|
||||
expect(url).toBe('http://example.com?foo=bar');
|
||||
});
|
||||
|
||||
it('add & to URL if query string is present', function() {
|
||||
it('add & to URL if query string is present', () => {
|
||||
const url = linkSrv.appendToQueryString('http://example.com?foo=bar', 'hello=world');
|
||||
expect(url).toBe('http://example.com?foo=bar&hello=world');
|
||||
});
|
||||
|
||||
it('do not change the URL if there is nothing to append', function() {
|
||||
_.each(['', undefined, null], function(toAppend) {
|
||||
it('do not change the URL if there is nothing to append', () => {
|
||||
_.each(['', undefined, null], toAppend => {
|
||||
const url1 = linkSrv.appendToQueryString('http://example.com', toAppend);
|
||||
expect(url1).toBe('http://example.com');
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body" ng-form="playlistEditForm">
|
||||
<div class="page-container page-body" ng-form="ctrl.playlistEditForm">
|
||||
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-hide="ctrl.isNew">Edit Playlist</h3>
|
||||
<h3 class="page-sub-heading" ng-show="ctrl.isNew">New Playlist</h3>
|
||||
|
||||
<p class="playlist-description">A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational awareness, or just show off your metrics to your team or visitors.</p>
|
||||
|
||||
@@ -20,79 +20,71 @@
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Dashboards</h3>
|
||||
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.playlistItems">
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_id'">
|
||||
<i class="icon-gf icon-gf-dashboard"></i> {{playlistItem.title}}
|
||||
</td>
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_tag'">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{playlistItem.title}}</span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td class="selected-playlistitem-settings">
|
||||
<button class="btn btn-inverse btn-mini" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)">
|
||||
<i class="fa fa-arrow-up"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-mini" ng-hide="$last" ng-click="ctrl.movePlaylistItemDown(playlistItem)">
|
||||
<i class="fa fa-arrow-down"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-mini" ng-click="ctrl.removePlaylistItem(playlistItem)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="ctrl.playlistItems.length === 0">
|
||||
<td><em>Playlist is empty, add dashboards below.</em></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="playlist-search-containerwrapper">
|
||||
<div class="max-width-32">
|
||||
<h5 class="page-headering playlist-column-header">Available</h5>
|
||||
<div style="">
|
||||
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-headering">Add dashboards</h3>
|
||||
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
|
||||
|
||||
<div ng-if="ctrl.filteredDashboards.length > 0">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredDashboards">
|
||||
<td>
|
||||
<i class="icon-gf icon-gf-dashboard"></i>
|
||||
{{playlistItem.title}}
|
||||
<i class="fa fa-star" ng-show="playlistItem.isStarred"></i>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="tag in ctrl.filteredTags">
|
||||
<td>
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addTagPlaylistItem(tag)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<h5 class="page headering playlist-column-header">Selected</h5>
|
||||
<div ng-if="ctrl.filteredDashboards.length > 0">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="playlistItem in ctrl.playlistItems">
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_id'">
|
||||
<i class="icon-gf icon-gf-dashboard"></i> {{playlistItem.title}}
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredDashboards">
|
||||
<td>
|
||||
<i class="icon-gf icon-gf-dashboard"></i>
|
||||
{{playlistItem.title}}
|
||||
<i class="fa fa-star" ng-show="playlistItem.isStarred"></i>
|
||||
</td>
|
||||
<td ng-if="playlistItem.type === 'dashboard_by_tag'">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title">
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;">
|
||||
<table class="filter-table playlist-available-list">
|
||||
<tr ng-repeat="tag in ctrl.filteredTags">
|
||||
<td>
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{playlistItem.title}}</span>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td class="selected-playlistitem-settings">
|
||||
<button class="btn btn-inverse btn-mini" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)">
|
||||
<i class="fa fa-arrow-up"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-mini" ng-hide="$last" ng-click="ctrl.movePlaylistItemDown(playlistItem)">
|
||||
<i class="fa fa-arrow-down"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse btn-mini" ng-click="ctrl.removePlaylistItem(playlistItem)">
|
||||
<i class="fa fa-remove"></i>
|
||||
<td class="add-dashboard">
|
||||
<button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addTagPlaylistItem(tag)">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add to playlist
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -103,12 +95,8 @@
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<a class="btn btn-success " ng-show="ctrl.isNew"
|
||||
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
|
||||
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create new playlist</a>
|
||||
<a class="btn btn-success" ng-show="!ctrl.isNew()"
|
||||
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
|
||||
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
|
||||
<a class="btn btn-success" ng-show="ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create</a>
|
||||
<a class="btn btn-success" ng-show="!ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
|
||||
<a class="btn-text" ng-click="ctrl.backToList()">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,47 +1,68 @@
|
||||
<page-header model="ctrl.navModel"></page-header>
|
||||
|
||||
<div class="page-container page-body">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success pull-right" href="playlists/create">
|
||||
<i class="fa fa-plus"></i>
|
||||
New Playlist
|
||||
</a>
|
||||
<div ng-if="ctrl.playlists.length > 0">
|
||||
<div class="page-action-bar">
|
||||
<div class="page-action-bar__spacer"></div>
|
||||
<a class="btn btn-success pull-right" href="playlists/create">
|
||||
<i class="fa fa-plus"></i>
|
||||
New Playlist
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="filter-table filter-table--hover">
|
||||
<thead>
|
||||
<th><strong>Name</strong></th>
|
||||
<th style="width: 100px"></th>
|
||||
<th style="width: 78px"></th>
|
||||
</thead>
|
||||
<tr ng-repeat="playlist in ctrl.playlists">
|
||||
<td class="link-td">
|
||||
<a href="playlists/edit/{{playlist.id}}">{{playlist.name}}</a>
|
||||
</td>
|
||||
<td class="dropdown">
|
||||
<button class="btn btn-inverse btn-small" data-toggle="dropdown">
|
||||
Start playlist
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a href="{{playlist.startUrl}}">
|
||||
<i class="fa fa-play"></i> In Normal mode</span>
|
||||
</a>
|
||||
<a href="{{playlist.startUrl}}?kiosk=tv">
|
||||
<i class="fa fa-play"></i> In TV mode</span>
|
||||
</a>
|
||||
<a href="{{playlist.startUrl}}?kiosk=tv&autofitpanels">
|
||||
<i class="fa fa-play"></i> In TV mode <span class="muted">(with auto fit panels)</span>
|
||||
</a>
|
||||
<a href="{{playlist.startUrl}}?kiosk">
|
||||
<i class="fa fa-play"></i> In Kiosk mode</span>
|
||||
</a>
|
||||
<a ng-href="{{playlist.startUrl}}?kiosk&autofitpanels">
|
||||
<i class="fa fa-play"></i> In Kiosk mode <span class="muted">(with auto fit panels)</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a ng-click="ctrl.removePlaylist(playlist)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div ng-if="ctrl.playlists.length === 0">
|
||||
<empty-list-cta model="{
|
||||
title: 'There are no playlists created yet',
|
||||
buttonIcon: 'fa fa-plus',
|
||||
buttonLink: 'playlists/create',
|
||||
buttonTitle: ' Create Playlist',
|
||||
proTip: 'You can use playlists to remove control TVs',
|
||||
proTipLink: 'http://docs.grafana.org/reference/playlist/',
|
||||
proTipLinkTitle: 'Learn more',
|
||||
proTipTarget: '_blank'
|
||||
}" />
|
||||
</div>
|
||||
|
||||
<table class="filter-table">
|
||||
<thead>
|
||||
<th><strong>Name</strong></th>
|
||||
<th><strong>Start url</strong></th>
|
||||
<th style="width: 78px"></th>
|
||||
<th style="width: 78px"></th>
|
||||
<th style="width: 25px"></th>
|
||||
</thead>
|
||||
<tr ng-repeat="playlist in ctrl.playlists">
|
||||
<td>
|
||||
<a href="playlists/edit/{{playlist.id}}">{{playlist.name}}</a>
|
||||
</td>
|
||||
<td >
|
||||
<a href="playlists/play/{{playlist.id}}">playlists/play/{{playlist.id}}</a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="playlists/play/{{playlist.id}}" class="btn btn-inverse btn-small">
|
||||
<i class="fa fa-play"></i>
|
||||
Play
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a href="playlists/edit/{{playlist.id}}" class="btn btn-inverse btn-small">
|
||||
<i class="fa fa-edit"></i>
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a ng-click="ctrl.removePlaylist(playlist)" class="btn btn-danger btn-small">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -19,29 +19,18 @@ export class PlaylistEditCtrl {
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private backendSrv, private $location, $route, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists', 0);
|
||||
this.isNew = $route.current.params.id;
|
||||
this.isNew = !$route.current.params.id;
|
||||
|
||||
if ($route.current.params.id) {
|
||||
const playlistId = $route.current.params.id;
|
||||
|
||||
backendSrv.get('/api/playlists/' + playlistId).then(result => {
|
||||
this.playlist = result;
|
||||
this.navModel.node = {
|
||||
text: result.name,
|
||||
icon: this.navModel.node.icon,
|
||||
};
|
||||
this.navModel.breadcrumbs.push(this.navModel.node);
|
||||
});
|
||||
|
||||
backendSrv.get('/api/playlists/' + playlistId + '/items').then(result => {
|
||||
this.playlistItems = result;
|
||||
});
|
||||
} else {
|
||||
this.navModel.node = {
|
||||
text: 'New playlist',
|
||||
icon: this.navModel.node.icon,
|
||||
};
|
||||
this.navModel.breadcrumbs.push(this.navModel.node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +77,7 @@ export class PlaylistEditCtrl {
|
||||
}
|
||||
|
||||
savePlaylist(playlist, playlistItems) {
|
||||
var savePromise;
|
||||
let savePromise;
|
||||
|
||||
playlist.items = playlistItems;
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ function grafanaRoutes($routeProvider) {
|
||||
controller: 'PlaylistEditCtrl',
|
||||
})
|
||||
.when('/playlists/play/:id', {
|
||||
templateUrl: 'public/app/features/playlist/partials/playlists.html',
|
||||
controllerAs: 'ctrl',
|
||||
controller: 'PlaylistsCtrl',
|
||||
template: '',
|
||||
resolve: {
|
||||
init: function(playlistSrv, $route) {
|
||||
init: (playlistSrv, $route) => {
|
||||
const playlistId = $route.current.params.id;
|
||||
playlistSrv.start(playlistId);
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@ export class PlaylistSearchCtrl {
|
||||
|
||||
/** @ngInject */
|
||||
constructor($timeout, private backendSrv) {
|
||||
this.query = { query: '', tag: [], starred: false, limit: 30 };
|
||||
this.query = { query: '', tag: [], starred: false, limit: 20 };
|
||||
|
||||
$timeout(() => {
|
||||
this.query.query = '';
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import coreModule from '../../core/core_module';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import _ from 'lodash';
|
||||
import { toUrlParams } from 'app/core/utils/url';
|
||||
|
||||
class PlaylistSrv {
|
||||
private cancelPromise: any;
|
||||
@@ -8,45 +10,30 @@ class PlaylistSrv {
|
||||
private index: number;
|
||||
private interval: any;
|
||||
private startUrl: string;
|
||||
public isPlaying: boolean;
|
||||
isPlaying: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $location: any, private $timeout: any, private backendSrv: any, private $routeParams: any) {}
|
||||
constructor(private $location: any, private $timeout: any, private backendSrv: any) {}
|
||||
|
||||
next() {
|
||||
this.$timeout.cancel(this.cancelPromise);
|
||||
|
||||
const playedAllDashboards = this.index > this.dashboards.length - 1;
|
||||
|
||||
if (playedAllDashboards) {
|
||||
window.location.href = this.getUrlWithKioskMode();
|
||||
window.location.href = this.startUrl;
|
||||
return;
|
||||
}
|
||||
|
||||
const dash = this.dashboards[this.index];
|
||||
this.$location.url('dashboard/' + dash.uri);
|
||||
const queryParams = this.$location.search();
|
||||
const filteredParams = _.pickBy(queryParams, value => value !== null);
|
||||
|
||||
this.$location.url('dashboard/' + dash.uri + '?' + toUrlParams(filteredParams));
|
||||
|
||||
this.index++;
|
||||
this.cancelPromise = this.$timeout(() => this.next(), this.interval);
|
||||
}
|
||||
|
||||
getUrlWithKioskMode() {
|
||||
const inKioskMode = document.body.classList.contains('page-kiosk-mode');
|
||||
|
||||
// check if should add kiosk query param
|
||||
if (inKioskMode && this.startUrl.indexOf('kiosk') === -1) {
|
||||
return this.startUrl + '?kiosk=true';
|
||||
}
|
||||
|
||||
// check if should remove kiosk query param
|
||||
if (!inKioskMode) {
|
||||
return this.startUrl.split('?')[0];
|
||||
}
|
||||
|
||||
// already has kiosk query param, just return startUrl
|
||||
return this.startUrl;
|
||||
}
|
||||
|
||||
prev() {
|
||||
this.index = Math.max(this.index - 2, 0);
|
||||
this.next();
|
||||
@@ -59,10 +46,6 @@ class PlaylistSrv {
|
||||
this.index = 0;
|
||||
this.isPlaying = true;
|
||||
|
||||
if (this.$routeParams.kiosk) {
|
||||
appEvents.emit('toggle-kiosk-mode');
|
||||
}
|
||||
|
||||
this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
|
||||
this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
|
||||
this.dashboards = dashboards;
|
||||
@@ -73,6 +56,13 @@ class PlaylistSrv {
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (this.isPlaying) {
|
||||
const queryParams = this.$location.search();
|
||||
if (queryParams.kiosk) {
|
||||
appEvents.emit('toggle-kiosk-mode', { exit: true });
|
||||
}
|
||||
}
|
||||
|
||||
this.index = 0;
|
||||
this.isPlaying = false;
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ export class PlaylistsCtrl {
|
||||
this.navModel = navModelSrv.getNav('dashboards', 'playlists', 0);
|
||||
|
||||
backendSrv.get('/api/playlists').then(result => {
|
||||
this.playlists = result;
|
||||
this.playlists = result.map(item => {
|
||||
item.startUrl = `playlists/play/${item.id}`;
|
||||
return item;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import '../playlist_edit_ctrl';
|
||||
import { PlaylistEditCtrl } from '../playlist_edit_ctrl';
|
||||
|
||||
describe('PlaylistEditCtrl', () => {
|
||||
var ctx: any;
|
||||
let ctx: any;
|
||||
beforeEach(() => {
|
||||
const navModelSrv = {
|
||||
getNav: () => {
|
||||
|
||||
@@ -77,7 +77,7 @@ export class DatasourceSrv {
|
||||
|
||||
this.addDataSourceVariables(sources);
|
||||
|
||||
_.each(config.datasources, function(value) {
|
||||
_.each(config.datasources, value => {
|
||||
if (value.meta && value.meta.annotations) {
|
||||
sources.push(value);
|
||||
}
|
||||
@@ -95,9 +95,9 @@ export class DatasourceSrv {
|
||||
}
|
||||
|
||||
getMetricSources(options) {
|
||||
var metricSources = [];
|
||||
const metricSources = [];
|
||||
|
||||
_.each(config.datasources, function(value, key) {
|
||||
_.each(config.datasources, (value, key) => {
|
||||
if (value.meta && value.meta.metrics) {
|
||||
let metricSource = { value: key, name: key, meta: value.meta, sort: key };
|
||||
|
||||
@@ -121,7 +121,7 @@ export class DatasourceSrv {
|
||||
this.addDataSourceVariables(metricSources);
|
||||
}
|
||||
|
||||
metricSources.sort(function(a, b) {
|
||||
metricSources.sort((a, b) => {
|
||||
if (a.sort.toLowerCase() > b.sort.toLowerCase()) {
|
||||
return 1;
|
||||
}
|
||||
@@ -136,18 +136,18 @@ export class DatasourceSrv {
|
||||
|
||||
addDataSourceVariables(list) {
|
||||
// look for data source variables
|
||||
for (var i = 0; i < this.templateSrv.variables.length; i++) {
|
||||
var variable = this.templateSrv.variables[i];
|
||||
for (let i = 0; i < this.templateSrv.variables.length; i++) {
|
||||
const variable = this.templateSrv.variables[i];
|
||||
if (variable.type !== 'datasource') {
|
||||
continue;
|
||||
}
|
||||
|
||||
var first = variable.current.value;
|
||||
let first = variable.current.value;
|
||||
if (first === 'default') {
|
||||
first = config.defaultDatasource;
|
||||
}
|
||||
|
||||
var ds = config.datasources[first];
|
||||
const ds = config.datasources[first];
|
||||
|
||||
if (ds) {
|
||||
const key = `$${variable.name}`;
|
||||
|
||||
@@ -4,7 +4,7 @@ import config from 'app/core/config';
|
||||
import { coreModule, appEvents } from 'app/core/core';
|
||||
import { store } from 'app/stores/store';
|
||||
|
||||
var datasourceTypes = [];
|
||||
let datasourceTypes = [];
|
||||
|
||||
const defaults = {
|
||||
name: '',
|
||||
@@ -16,7 +16,7 @@ const defaults = {
|
||||
secureJsonData: {},
|
||||
};
|
||||
|
||||
var datasourceCreated = false;
|
||||
let datasourceCreated = false;
|
||||
|
||||
export class DataSourceEditCtrl {
|
||||
isNew: boolean;
|
||||
@@ -200,7 +200,7 @@ export class DataSourceEditCtrl {
|
||||
|
||||
coreModule.controller('DataSourceEditCtrl', DataSourceEditCtrl);
|
||||
|
||||
coreModule.directive('datasourceHttpSettings', function() {
|
||||
coreModule.directive('datasourceHttpSettings', () => {
|
||||
return {
|
||||
scope: {
|
||||
current: '=',
|
||||
@@ -209,15 +209,15 @@ coreModule.directive('datasourceHttpSettings', function() {
|
||||
},
|
||||
templateUrl: 'public/app/features/plugins/partials/ds_http_settings.html',
|
||||
link: {
|
||||
pre: function($scope, elem, attrs) {
|
||||
pre: ($scope, elem, attrs) => {
|
||||
// do not show access option if direct access is disabled
|
||||
$scope.showAccessOption = $scope.noDirectAccess !== 'true';
|
||||
$scope.showAccessHelp = false;
|
||||
$scope.toggleAccessHelp = function() {
|
||||
$scope.toggleAccessHelp = () => {
|
||||
$scope.showAccessHelp = !$scope.showAccessHelp;
|
||||
};
|
||||
|
||||
$scope.getSuggestUrls = function() {
|
||||
$scope.getSuggestUrls = () => {
|
||||
return [$scope.suggestUrl];
|
||||
};
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ import { importPluginModule } from './plugin_loader';
|
||||
|
||||
import { UnknownPanelCtrl } from 'app/plugins/panel/unknown/module';
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $templateCache) {
|
||||
function getTemplate(component) {
|
||||
if (component.template) {
|
||||
@@ -36,7 +36,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
// handle relative template urls for plugin templates
|
||||
options.Component.templateUrl = relativeTemplateUrlToAbs(options.Component.templateUrl, options.baseUrl);
|
||||
|
||||
return function() {
|
||||
return () => {
|
||||
return {
|
||||
templateUrl: options.Component.templateUrl,
|
||||
template: options.Component.template,
|
||||
@@ -69,14 +69,14 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
};
|
||||
|
||||
const panelInfo = config.panels[scope.panel.type];
|
||||
var panelCtrlPromise = Promise.resolve(UnknownPanelCtrl);
|
||||
let panelCtrlPromise = Promise.resolve(UnknownPanelCtrl);
|
||||
if (panelInfo) {
|
||||
panelCtrlPromise = importPluginModule(panelInfo.module).then(function(panelModule) {
|
||||
panelCtrlPromise = importPluginModule(panelInfo.module).then(panelModule => {
|
||||
return panelModule.PanelCtrl;
|
||||
});
|
||||
}
|
||||
|
||||
return panelCtrlPromise.then(function(PanelCtrl: any) {
|
||||
return panelCtrlPromise.then((PanelCtrl: any) => {
|
||||
componentInfo.Component = PanelCtrl;
|
||||
|
||||
if (!PanelCtrl || PanelCtrl.registered) {
|
||||
@@ -128,7 +128,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
}
|
||||
// Annotations
|
||||
case 'annotations-query-ctrl': {
|
||||
return importPluginModule(scope.ctrl.currentDatasource.meta.module).then(function(dsModule) {
|
||||
return importPluginModule(scope.ctrl.currentDatasource.meta.module).then(dsModule => {
|
||||
return {
|
||||
baseUrl: scope.ctrl.currentDatasource.meta.baseUrl,
|
||||
name: 'annotations-query-ctrl-' + scope.ctrl.currentDatasource.meta.id,
|
||||
@@ -144,7 +144,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
// Datasource ConfigCtrl
|
||||
case 'datasource-config-ctrl': {
|
||||
const dsMeta = scope.ctrl.datasourceMeta;
|
||||
return importPluginModule(dsMeta.module).then(function(dsModule): any {
|
||||
return importPluginModule(dsMeta.module).then((dsModule): any => {
|
||||
if (!dsModule.ConfigCtrl) {
|
||||
return { notFound: true };
|
||||
}
|
||||
@@ -161,7 +161,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
// AppConfigCtrl
|
||||
case 'app-config-ctrl': {
|
||||
const model = scope.ctrl.model;
|
||||
return importPluginModule(model.module).then(function(appModule) {
|
||||
return importPluginModule(model.module).then(appModule => {
|
||||
return {
|
||||
baseUrl: model.baseUrl,
|
||||
name: 'app-config-' + model.id,
|
||||
@@ -174,7 +174,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
// App Page
|
||||
case 'app-page': {
|
||||
const appModel = scope.ctrl.appModel;
|
||||
return importPluginModule(appModel.module).then(function(appModule) {
|
||||
return importPluginModule(appModel.module).then(appModule => {
|
||||
return {
|
||||
baseUrl: appModel.baseUrl,
|
||||
name: 'app-page-' + appModel.id + '-' + scope.ctrl.page.slug,
|
||||
@@ -206,9 +206,9 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
elem.empty();
|
||||
|
||||
// let a binding digest cycle complete before adding to dom
|
||||
setTimeout(function() {
|
||||
setTimeout(() => {
|
||||
elem.append(child);
|
||||
scope.$applyAsync(function() {
|
||||
scope.$applyAsync(() => {
|
||||
scope.$broadcast('component-did-mount');
|
||||
scope.$broadcast('refresh');
|
||||
});
|
||||
@@ -239,9 +239,9 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, elem, attrs) {
|
||||
link: (scope, elem, attrs) => {
|
||||
getModule(scope, attrs)
|
||||
.then(function(componentInfo) {
|
||||
.then(componentInfo => {
|
||||
registerPluginComponent(scope, elem, attrs, componentInfo);
|
||||
})
|
||||
.catch(err => {
|
||||
|
||||
@@ -65,7 +65,7 @@ System.config({
|
||||
});
|
||||
|
||||
function exposeToPlugin(name: string, component: any) {
|
||||
System.registerDynamic(name, [], true, function(require, exports, module) {
|
||||
System.registerDynamic(name, [], true, (require, exports, module) => {
|
||||
module.exports = component;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const templateSrv = {
|
||||
],
|
||||
};
|
||||
|
||||
describe('datasource_srv', function() {
|
||||
describe('datasource_srv', () => {
|
||||
const _datasourceSrv = new DatasourceSrv({}, {}, {}, templateSrv);
|
||||
|
||||
describe('when loading explore sources', () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ class StyleGuideCtrl {
|
||||
buttonVariants = ['-'];
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private $routeParams, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getNav('cfg', 'admin', 'styleguide', 1);
|
||||
this.theme = config.bootData.user.lightTheme ? 'light' : 'dark';
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AdhocVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { CustomVariable } from './custom_variable';
|
||||
import { ConstantVariable } from './constant_variable';
|
||||
import { AdhocVariable } from './adhoc_variable';
|
||||
|
||||
coreModule.factory('templateSrv', function() {
|
||||
coreModule.factory('templateSrv', () => {
|
||||
return templateSrv;
|
||||
});
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export class ConstantVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model, private variableSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class CustomVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model, private variableSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export class CustomVariable implements Variable {
|
||||
|
||||
updateOptions() {
|
||||
// extract options in comma separated string
|
||||
this.options = _.map(this.query.split(/[,]+/), function(text) {
|
||||
this.options = _.map(this.query.split(/[,]+/), text => {
|
||||
return { text: text.trim(), value: text.trim() };
|
||||
});
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ export class DatasourceVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model, private datasourceSrv, private variableSrv, private templateSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
this.refresh = 1;
|
||||
@@ -43,14 +43,14 @@ export class DatasourceVariable implements Variable {
|
||||
updateOptions() {
|
||||
const options = [];
|
||||
const sources = this.datasourceSrv.getMetricSources({ skipVariables: true });
|
||||
var regex;
|
||||
let regex;
|
||||
|
||||
if (this.regex) {
|
||||
regex = this.templateSrv.replace(this.regex, null, 'regex');
|
||||
regex = kbn.stringToJsRegex(regex);
|
||||
}
|
||||
|
||||
for (var i = 0; i < sources.length; i++) {
|
||||
for (let i = 0; i < sources.length; i++) {
|
||||
const source = sources[i];
|
||||
// must match on type
|
||||
if (source.meta.id !== this.query) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { variableTypes } from './variable';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
export class VariableEditorCtrl {
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor($scope, datasourceSrv, variableSrv, templateSrv) {
|
||||
$scope.variableTypes = variableTypes;
|
||||
$scope.ctrl = {};
|
||||
@@ -30,31 +30,31 @@ export class VariableEditorCtrl {
|
||||
|
||||
$scope.hideOptions = [{ value: 0, text: '' }, { value: 1, text: 'Label' }, { value: 2, text: 'Variable' }];
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.init = () => {
|
||||
$scope.mode = 'list';
|
||||
|
||||
$scope.variables = variableSrv.variables;
|
||||
$scope.reset();
|
||||
|
||||
$scope.$watch('mode', function(val) {
|
||||
$scope.$watch('mode', val => {
|
||||
if (val === 'new') {
|
||||
$scope.reset();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setMode = function(mode) {
|
||||
$scope.setMode = mode => {
|
||||
$scope.mode = mode;
|
||||
};
|
||||
|
||||
$scope.add = function() {
|
||||
$scope.add = () => {
|
||||
if ($scope.isValid()) {
|
||||
variableSrv.addVariable($scope.current);
|
||||
$scope.update();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.isValid = function() {
|
||||
$scope.isValid = () => {
|
||||
if (!$scope.ctrl.form.$valid) {
|
||||
return false;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export class VariableEditorCtrl {
|
||||
return true;
|
||||
};
|
||||
|
||||
$scope.validate = function() {
|
||||
$scope.validate = () => {
|
||||
$scope.infoText = '';
|
||||
if ($scope.current.type === 'adhoc' && $scope.current.datasource !== null) {
|
||||
$scope.infoText = 'Adhoc filters are applied automatically to all queries that target this datasource';
|
||||
@@ -96,7 +96,7 @@ export class VariableEditorCtrl {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.runQuery = function() {
|
||||
$scope.runQuery = () => {
|
||||
$scope.optionsLimit = 20;
|
||||
return variableSrv.updateOptions($scope.current).catch(err => {
|
||||
if (err.data && err.data.message) {
|
||||
@@ -106,23 +106,23 @@ export class VariableEditorCtrl {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.edit = function(variable) {
|
||||
$scope.edit = variable => {
|
||||
$scope.current = variable;
|
||||
$scope.currentIsNew = false;
|
||||
$scope.mode = 'edit';
|
||||
$scope.validate();
|
||||
};
|
||||
|
||||
$scope.duplicate = function(variable) {
|
||||
$scope.duplicate = variable => {
|
||||
const clone = _.cloneDeep(variable.getSaveModel());
|
||||
$scope.current = variableSrv.createVariableFromModel(clone);
|
||||
$scope.current.name = 'copy_of_' + variable.name;
|
||||
variableSrv.addVariable($scope.current);
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
$scope.update = () => {
|
||||
if ($scope.isValid()) {
|
||||
$scope.runQuery().then(function() {
|
||||
$scope.runQuery().then(() => {
|
||||
$scope.reset();
|
||||
$scope.mode = 'list';
|
||||
templateSrv.updateTemplateData();
|
||||
@@ -130,18 +130,18 @@ export class VariableEditorCtrl {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.reset = () => {
|
||||
$scope.currentIsNew = true;
|
||||
$scope.current = variableSrv.createVariableFromModel({ type: 'query' });
|
||||
|
||||
// this is done here in case a new data source type variable was added
|
||||
$scope.datasources = _.filter(datasourceSrv.getMetricSources(), function(ds) {
|
||||
$scope.datasources = _.filter(datasourceSrv.getMetricSources(), ds => {
|
||||
return !ds.meta.mixed && ds.value !== null;
|
||||
});
|
||||
|
||||
$scope.datasourceTypes = _($scope.datasources)
|
||||
.uniqBy('meta.id')
|
||||
.map(function(ds) {
|
||||
.map(ds => {
|
||||
return { text: ds.meta.name, value: ds.meta.id };
|
||||
})
|
||||
.value();
|
||||
@@ -164,11 +164,11 @@ export class VariableEditorCtrl {
|
||||
$scope.validate();
|
||||
};
|
||||
|
||||
$scope.removeVariable = function(variable) {
|
||||
$scope.removeVariable = variable => {
|
||||
variableSrv.removeVariable(variable);
|
||||
};
|
||||
|
||||
$scope.showMoreOptions = function() {
|
||||
$scope.showMoreOptions = () => {
|
||||
$scope.optionsLimit += 20;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import { Variable, assignModelProperties, variableTypes } from './variable';
|
||||
|
||||
export class IntervalVariable implements Variable {
|
||||
name: string;
|
||||
auto_count: number;
|
||||
auto_min: number;
|
||||
auto_count: number; // tslint:disable-line variable-name
|
||||
auto_min: number; // tslint:disable-line variable-name
|
||||
options: any;
|
||||
auto: boolean;
|
||||
query: string;
|
||||
@@ -28,7 +28,7 @@ export class IntervalVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
this.refresh = 2;
|
||||
@@ -65,7 +65,7 @@ export class IntervalVariable implements Variable {
|
||||
|
||||
updateOptions() {
|
||||
// extract options between quotes and/or comma
|
||||
this.options = _.map(this.query.match(/(["'])(.*?)\1|\w+/g), function(text) {
|
||||
this.options = _.map(this.query.match(/(["'])(.*?)\1|\w+/g), text => {
|
||||
text = text.replace(/["']+/g, '');
|
||||
return { text: text.trim(), value: text.trim() };
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ export class QueryVariable implements Variable {
|
||||
skipUrlSync: false,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
/** @ngInject */
|
||||
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private timeSrv) {
|
||||
// copy model properties to this instance
|
||||
assignModelProperties(this, model, this.defaults);
|
||||
@@ -91,7 +91,7 @@ export class QueryVariable implements Variable {
|
||||
if (this.useTags) {
|
||||
return this.metricFindQuery(datasource, this.tagsQuery).then(results => {
|
||||
this.tags = [];
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
this.tags.push(results[i].text);
|
||||
}
|
||||
return datasource;
|
||||
@@ -106,8 +106,8 @@ export class QueryVariable implements Variable {
|
||||
getValuesForTag(tagKey) {
|
||||
return this.datasourceSrv.get(this.datasource).then(datasource => {
|
||||
const query = this.tagValuesQuery.replace('$tag', tagKey);
|
||||
return this.metricFindQuery(datasource, query).then(function(results) {
|
||||
return _.map(results, function(value) {
|
||||
return this.metricFindQuery(datasource, query).then(results => {
|
||||
return _.map(results, value => {
|
||||
return value.text;
|
||||
});
|
||||
});
|
||||
@@ -142,7 +142,7 @@ export class QueryVariable implements Variable {
|
||||
}
|
||||
|
||||
metricNamesToVariableValues(metricNames) {
|
||||
var regex, options, i, matches;
|
||||
let regex, options, i, matches;
|
||||
options = [];
|
||||
|
||||
if (this.regex) {
|
||||
@@ -150,9 +150,9 @@ export class QueryVariable implements Variable {
|
||||
}
|
||||
for (i = 0; i < metricNames.length; i++) {
|
||||
const item = metricNames[i];
|
||||
var text = item.text === undefined || item.text === null ? item.value : item.text;
|
||||
let text = item.text === undefined || item.text === null ? item.value : item.text;
|
||||
|
||||
var value = item.value === undefined || item.value === null ? item.text : item.value;
|
||||
let value = item.value === undefined || item.value === null ? item.text : item.value;
|
||||
|
||||
if (_.isNumber(value)) {
|
||||
value = value.toString();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { AdhocVariable } from '../adhoc_variable';
|
||||
|
||||
describe('AdhocVariable', function() {
|
||||
describe('when serializing to url', function() {
|
||||
it('should set return key value and op separated by pipe', function() {
|
||||
describe('AdhocVariable', () => {
|
||||
describe('when serializing to url', () => {
|
||||
it('should set return key value and op separated by pipe', () => {
|
||||
const variable = new AdhocVariable({
|
||||
filters: [
|
||||
{ key: 'key1', operator: '=', value: 'value1' },
|
||||
@@ -15,8 +15,8 @@ describe('AdhocVariable', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when deserializing from url', function() {
|
||||
it('should restore filters', function() {
|
||||
describe('when deserializing from url', () => {
|
||||
it('should restore filters', () => {
|
||||
const variable = new AdhocVariable({});
|
||||
variable.setValueFromUrl(['key1|=|value1', 'key2|!=|value2', 'key3|=|value3a__gfp__value3b__gfp__value3c']);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TemplateSrv } from '../template_srv';
|
||||
|
||||
describe('templateSrv', function() {
|
||||
describe('templateSrv', () => {
|
||||
let _templateSrv;
|
||||
|
||||
function initTemplateSrv(variables) {
|
||||
@@ -8,58 +8,58 @@ describe('templateSrv', function() {
|
||||
_templateSrv.init(variables);
|
||||
}
|
||||
|
||||
describe('init', function() {
|
||||
beforeEach(function() {
|
||||
describe('init', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should initialize template data', function() {
|
||||
it('should initialize template data', () => {
|
||||
const target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).toBe('this.oogle.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass scoped vars', function() {
|
||||
beforeEach(function() {
|
||||
describe('replace can pass scoped vars', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should replace $test with scoped value', function() {
|
||||
it('should replace $test with scoped value', () => {
|
||||
const target = _templateSrv.replace('this.$test.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
expect(target).toBe('this.mupp.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test} with scoped value', function() {
|
||||
it('should replace ${test} with scoped value', () => {
|
||||
const target = _templateSrv.replace('this.${test}.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
expect(target).toBe('this.mupp.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:glob} with scoped value', function() {
|
||||
it('should replace ${test:glob} with scoped value', () => {
|
||||
const target = _templateSrv.replace('this.${test:glob}.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
expect(target).toBe('this.mupp.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with scoped text', function() {
|
||||
it('should replace $test with scoped text', () => {
|
||||
const target = _templateSrv.replaceWithText('this.$test.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
expect(target).toBe('this.asd.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test} with scoped text', function() {
|
||||
it('should replace ${test} with scoped text', () => {
|
||||
const target = _templateSrv.replaceWithText('this.${test}.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
expect(target).toBe('this.asd.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:glob} with scoped text', function() {
|
||||
it('should replace ${test:glob} with scoped text', () => {
|
||||
const target = _templateSrv.replaceWithText('this.${test:glob}.filters', {
|
||||
test: { value: 'mupp', text: 'asd' },
|
||||
});
|
||||
@@ -67,8 +67,8 @@ describe('templateSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAdhocFilters', function() {
|
||||
beforeEach(function() {
|
||||
describe('getAdhocFilters', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'datasource',
|
||||
@@ -80,24 +80,24 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return filters if datasourceName match', function() {
|
||||
it('should return filters if datasourceName match', () => {
|
||||
const filters = _templateSrv.getAdhocFilters('oogle');
|
||||
expect(filters).toMatchObject([1]);
|
||||
});
|
||||
|
||||
it('should return empty array if datasourceName does not match', function() {
|
||||
it('should return empty array if datasourceName does not match', () => {
|
||||
const filters = _templateSrv.getAdhocFilters('oogleasdasd');
|
||||
expect(filters).toMatchObject([]);
|
||||
});
|
||||
|
||||
it('should return filters when datasourceName match via data source variable', function() {
|
||||
it('should return filters when datasourceName match via data source variable', () => {
|
||||
const filters = _templateSrv.getAdhocFilters('logstash');
|
||||
expect(filters).toMatchObject([2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass multi / all format', function() {
|
||||
beforeEach(function() {
|
||||
describe('replace can pass multi / all format', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -107,44 +107,44 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should replace $test with globbed value', function() {
|
||||
it('should replace $test with globbed value', () => {
|
||||
const target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test} with globbed value', function() {
|
||||
it('should replace ${test} with globbed value', () => {
|
||||
const target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:glob} with globbed value', function() {
|
||||
it('should replace ${test:glob} with globbed value', () => {
|
||||
const target = _templateSrv.replace('this.${test:glob}.filters', {});
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with piped value', function() {
|
||||
it('should replace $test with piped value', () => {
|
||||
const target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||
expect(target).toBe('this=value1|value2');
|
||||
});
|
||||
|
||||
it('should replace ${test} with piped value', function() {
|
||||
it('should replace ${test} with piped value', () => {
|
||||
const target = _templateSrv.replace('this=${test}', {}, 'pipe');
|
||||
expect(target).toBe('this=value1|value2');
|
||||
});
|
||||
|
||||
it('should replace ${test:pipe} with piped value', function() {
|
||||
it('should replace ${test:pipe} with piped value', () => {
|
||||
const target = _templateSrv.replace('this=${test:pipe}', {});
|
||||
expect(target).toBe('this=value1|value2');
|
||||
});
|
||||
|
||||
it('should replace ${test:pipe} with piped value and $test with globbed value', function() {
|
||||
it('should replace ${test:pipe} with piped value and $test with globbed value', () => {
|
||||
const target = _templateSrv.replace('${test:pipe},$test', {}, 'glob');
|
||||
expect(target).toBe('value1|value2,{value1,value2}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option', function() {
|
||||
beforeEach(function() {
|
||||
describe('variable with all option', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -155,29 +155,29 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
it('should replace $test with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test} with formatted all value', function() {
|
||||
it('should replace ${test} with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:glob} with formatted all value', function() {
|
||||
it('should replace ${test:glob} with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.${test:glob}.filters', {});
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:pipe} with piped value and $test with globbed value', function() {
|
||||
it('should replace ${test:pipe} with piped value and $test with globbed value', () => {
|
||||
const target = _templateSrv.replace('${test:pipe},$test', {}, 'glob');
|
||||
expect(target).toBe('value1|value2,{value1,value2}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option and custom value', function() {
|
||||
beforeEach(function() {
|
||||
describe('variable with all option and custom value', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -189,143 +189,143 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
it('should replace $test with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).toBe('this.*.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test} with formatted all value', function() {
|
||||
it('should replace ${test} with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.${test}.filters', {}, 'glob');
|
||||
expect(target).toBe('this.*.filters');
|
||||
});
|
||||
|
||||
it('should replace ${test:glob} with formatted all value', function() {
|
||||
it('should replace ${test:glob} with formatted all value', () => {
|
||||
const target = _templateSrv.replace('this.${test:glob}.filters', {});
|
||||
expect(target).toBe('this.*.filters');
|
||||
});
|
||||
|
||||
it('should not escape custom all value', function() {
|
||||
it('should not escape custom all value', () => {
|
||||
const target = _templateSrv.replace('this.$test', {}, 'regex');
|
||||
expect(target).toBe('this.*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lucene format', function() {
|
||||
it('should properly escape $test with lucene escape sequences', function() {
|
||||
describe('lucene format', () => {
|
||||
it('should properly escape $test with lucene escape sequences', () => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'value/4' } }]);
|
||||
const target = _templateSrv.replace('this:$test', {}, 'lucene');
|
||||
expect(target).toBe('this:value\\/4');
|
||||
});
|
||||
|
||||
it('should properly escape ${test} with lucene escape sequences', function() {
|
||||
it('should properly escape ${test} with lucene escape sequences', () => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'value/4' } }]);
|
||||
const target = _templateSrv.replace('this:${test}', {}, 'lucene');
|
||||
expect(target).toBe('this:value\\/4');
|
||||
});
|
||||
|
||||
it('should properly escape ${test:lucene} with lucene escape sequences', function() {
|
||||
it('should properly escape ${test:lucene} with lucene escape sequences', () => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'value/4' } }]);
|
||||
const target = _templateSrv.replace('this:${test:lucene}', {});
|
||||
expect(target).toBe('this:value\\/4');
|
||||
});
|
||||
});
|
||||
|
||||
describe('format variable to string values', function() {
|
||||
it('single value should return value', function() {
|
||||
describe('format variable to string values', () => {
|
||||
it('single value should return value', () => {
|
||||
const result = _templateSrv.formatValue('test');
|
||||
expect(result).toBe('test');
|
||||
});
|
||||
|
||||
it('multi value and glob format should render glob string', function() {
|
||||
it('multi value and glob format should render glob string', () => {
|
||||
const result = _templateSrv.formatValue(['test', 'test2'], 'glob');
|
||||
expect(result).toBe('{test,test2}');
|
||||
});
|
||||
|
||||
it('multi value and lucene should render as lucene expr', function() {
|
||||
it('multi value and lucene should render as lucene expr', () => {
|
||||
const result = _templateSrv.formatValue(['test', 'test2'], 'lucene');
|
||||
expect(result).toBe('("test" OR "test2")');
|
||||
});
|
||||
|
||||
it('multi value and regex format should render regex string', function() {
|
||||
it('multi value and regex format should render regex string', () => {
|
||||
const result = _templateSrv.formatValue(['test.', 'test2'], 'regex');
|
||||
expect(result).toBe('(test\\.|test2)');
|
||||
});
|
||||
|
||||
it('multi value and pipe should render pipe string', function() {
|
||||
it('multi value and pipe should render pipe string', () => {
|
||||
const result = _templateSrv.formatValue(['test', 'test2'], 'pipe');
|
||||
expect(result).toBe('test|test2');
|
||||
});
|
||||
|
||||
it('multi value and distributed should render distributed string', function() {
|
||||
it('multi value and distributed should render distributed string', () => {
|
||||
const result = _templateSrv.formatValue(['test', 'test2'], 'distributed', {
|
||||
name: 'build',
|
||||
});
|
||||
expect(result).toBe('test,build=test2');
|
||||
});
|
||||
|
||||
it('multi value and distributed should render when not string', function() {
|
||||
it('multi value and distributed should render when not string', () => {
|
||||
const result = _templateSrv.formatValue(['test'], 'distributed', {
|
||||
name: 'build',
|
||||
});
|
||||
expect(result).toBe('test');
|
||||
});
|
||||
|
||||
it('multi value and csv format should render csv string', function() {
|
||||
it('multi value and csv format should render csv string', () => {
|
||||
const result = _templateSrv.formatValue(['test', 'test2'], 'csv');
|
||||
expect(result).toBe('test,test2');
|
||||
});
|
||||
|
||||
it('slash should be properly escaped in regex format', function() {
|
||||
it('slash should be properly escaped in regex format', () => {
|
||||
const result = _templateSrv.formatValue('Gi3/14', 'regex');
|
||||
expect(result).toBe('Gi3\\/14');
|
||||
});
|
||||
});
|
||||
|
||||
describe('can check if variable exists', function() {
|
||||
beforeEach(function() {
|
||||
describe('can check if variable exists', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should return true if exists', function() {
|
||||
it('should return true if exists', () => {
|
||||
const result = _templateSrv.variableExists('$test');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('can highlight variables in string', function() {
|
||||
beforeEach(function() {
|
||||
describe('can highlight variables in string', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should insert html', function() {
|
||||
it('should insert html', () => {
|
||||
const result = _templateSrv.highlightVariablesAsHtml('$test');
|
||||
expect(result).toBe('<span class="template-variable">$test</span>');
|
||||
});
|
||||
|
||||
it('should insert html anywhere in string', function() {
|
||||
it('should insert html anywhere in string', () => {
|
||||
const result = _templateSrv.highlightVariablesAsHtml('this $test ok');
|
||||
expect(result).toBe('this <span class="template-variable">$test</span> ok');
|
||||
});
|
||||
|
||||
it('should ignore if variables does not exist', function() {
|
||||
it('should ignore if variables does not exist', () => {
|
||||
const result = _templateSrv.highlightVariablesAsHtml('this $google ok');
|
||||
expect(result).toBe('this $google ok');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateTemplateData with simple value', function() {
|
||||
beforeEach(function() {
|
||||
describe('updateTemplateData with simple value', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: 'muuuu' } }]);
|
||||
});
|
||||
|
||||
it('should set current value and update template data', function() {
|
||||
it('should set current value and update template data', () => {
|
||||
const target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).toBe('this.muuuu.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value', function() {
|
||||
beforeEach(function() {
|
||||
describe('fillVariableValuesForUrl with multi value', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -338,15 +338,15 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should set multiple url params', function() {
|
||||
it('should set multiple url params', () => {
|
||||
const params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).toMatchObject(['val1', 'val2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl skip url sync', function() {
|
||||
beforeEach(function() {
|
||||
describe('fillVariableValuesForUrl skip url sync', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
name: 'test',
|
||||
@@ -359,15 +359,15 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not include template variable value in url', function() {
|
||||
it('should not include template variable value in url', () => {
|
||||
const params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value with skip url sync', function() {
|
||||
beforeEach(function() {
|
||||
describe('fillVariableValuesForUrl with multi value with skip url sync', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -381,19 +381,19 @@ describe('templateSrv', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not include template variable value in url', function() {
|
||||
it('should not include template variable value in url', () => {
|
||||
const params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value and scopedVars', function() {
|
||||
beforeEach(function() {
|
||||
describe('fillVariableValuesForUrl with multi value and scopedVars', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: ['val1', 'val2'] } }]);
|
||||
});
|
||||
|
||||
it('should set scoped value as url params', function() {
|
||||
it('should set scoped value as url params', () => {
|
||||
const params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params, {
|
||||
test: { value: 'val1' },
|
||||
@@ -402,12 +402,12 @@ describe('templateSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value, scopedVars and skip url sync', function() {
|
||||
beforeEach(function() {
|
||||
describe('fillVariableValuesForUrl with multi value, scopedVars and skip url sync', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([{ type: 'query', name: 'test', current: { value: ['val1', 'val2'] } }]);
|
||||
});
|
||||
|
||||
it('should not set scoped value as url params', function() {
|
||||
it('should not set scoped value as url params', () => {
|
||||
const params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params, {
|
||||
test: { name: 'test', value: 'val1', skipUrlSync: true },
|
||||
@@ -416,8 +416,8 @@ describe('templateSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('replaceWithText', function() {
|
||||
beforeEach(function() {
|
||||
describe('replaceWithText', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
@@ -434,18 +434,18 @@ describe('templateSrv', function() {
|
||||
_templateSrv.updateTemplateData();
|
||||
});
|
||||
|
||||
it('should replace with text except for grafanaVariables', function() {
|
||||
it('should replace with text except for grafanaVariables', () => {
|
||||
const target = _templateSrv.replaceWithText('Server: $server, period: $period');
|
||||
expect(target).toBe('Server: All, period: 13m');
|
||||
});
|
||||
});
|
||||
|
||||
describe('built in interval variables', function() {
|
||||
beforeEach(function() {
|
||||
describe('built in interval variables', () => {
|
||||
beforeEach(() => {
|
||||
initTemplateSrv([]);
|
||||
});
|
||||
|
||||
it('should replace $__interval_ms with interval milliseconds', function() {
|
||||
it('should replace $__interval_ms with interval milliseconds', () => {
|
||||
const target = _templateSrv.replace('10 * $__interval_ms', {
|
||||
__interval_ms: { text: '100', value: '100' },
|
||||
});
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
import { containsVariable, assignModelProperties } from '../variable';
|
||||
|
||||
describe('containsVariable', function() {
|
||||
describe('when checking if a string contains a variable', function() {
|
||||
it('should find it with $const syntax', function() {
|
||||
describe('containsVariable', () => {
|
||||
describe('when checking if a string contains a variable', () => {
|
||||
it('should find it with $const syntax', () => {
|
||||
const contains = containsVariable('this.$test.filters', 'test');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
|
||||
it('should not find it if only part matches with $const syntax', function() {
|
||||
it('should not find it if only part matches with $const syntax', () => {
|
||||
const contains = containsVariable('this.$serverDomain.filters', 'server');
|
||||
expect(contains).toBe(false);
|
||||
});
|
||||
|
||||
it('should find it if it ends with variable and passing multiple test strings', function() {
|
||||
it('should find it if it ends with variable and passing multiple test strings', () => {
|
||||
const contains = containsVariable('show field keys from $pgmetric', 'test string2', 'pgmetric');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
|
||||
it('should find it with [[var]] syntax', function() {
|
||||
it('should find it with [[var]] syntax', () => {
|
||||
const contains = containsVariable('this.[[test]].filters', 'test');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
|
||||
it('should find it when part of segment', function() {
|
||||
it('should find it when part of segment', () => {
|
||||
const contains = containsVariable('metrics.$env.$group-*', 'group');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
|
||||
it('should find it its the only thing', function() {
|
||||
it('should find it its the only thing', () => {
|
||||
const contains = containsVariable('$env', 'env');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to pass in multiple test strings', function() {
|
||||
it('should be able to pass in multiple test strings', () => {
|
||||
const contains = containsVariable('asd', 'asd2.$env', 'env');
|
||||
expect(contains).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('assignModelProperties', function() {
|
||||
it('only set properties defined in defaults', function() {
|
||||
describe('assignModelProperties', () => {
|
||||
it('only set properties defined in defaults', () => {
|
||||
const target: any = { test: 'asd' };
|
||||
assignModelProperties(target, { propA: 1, propB: 2 }, { propB: 0 });
|
||||
expect(target.propB).toBe(2);
|
||||
expect(target.test).toBe('asd');
|
||||
});
|
||||
|
||||
it('use default value if not found on source', function() {
|
||||
it('use default value if not found on source', () => {
|
||||
const target: any = { test: 'asd' };
|
||||
assignModelProperties(target, { propA: 1, propB: 2 }, { propC: 10 });
|
||||
expect(target.propC).toBe(10);
|
||||
|
||||
@@ -3,8 +3,8 @@ import { VariableSrv } from '../variable_srv';
|
||||
import moment from 'moment';
|
||||
import $q from 'q';
|
||||
|
||||
describe('VariableSrv', function() {
|
||||
const ctx = <any>{
|
||||
describe('VariableSrv', function(this: any) {
|
||||
const ctx = {
|
||||
datasourceSrv: {},
|
||||
timeSrv: {
|
||||
timeRange: () => {},
|
||||
@@ -29,12 +29,12 @@ describe('VariableSrv', function() {
|
||||
$location: {
|
||||
search: () => {},
|
||||
},
|
||||
};
|
||||
} as any;
|
||||
|
||||
function describeUpdateVariable(desc, fn) {
|
||||
describe(desc, () => {
|
||||
const scenario: any = {};
|
||||
scenario.setup = function(setupFn) {
|
||||
scenario.setup = setupFn => {
|
||||
scenario.setupFn = setupFn;
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ describe('VariableSrv', function() {
|
||||
//
|
||||
// Query variable update
|
||||
//
|
||||
describeUpdateVariable('query variable with empty current object and refresh', function(scenario) {
|
||||
describeUpdateVariable('query variable with empty current object and refresh', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -154,7 +154,7 @@ describe('VariableSrv', function() {
|
||||
|
||||
describeUpdateVariable(
|
||||
'query variable with multi select and new options does not contain some selected values',
|
||||
function(scenario) {
|
||||
scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -177,7 +177,7 @@ describe('VariableSrv', function() {
|
||||
|
||||
describeUpdateVariable(
|
||||
'query variable with multi select and new options does not contain any selected values',
|
||||
function(scenario) {
|
||||
scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -198,7 +198,7 @@ describe('VariableSrv', function() {
|
||||
}
|
||||
);
|
||||
|
||||
describeUpdateVariable('query variable with multi select and $__all selected', function(scenario) {
|
||||
describeUpdateVariable('query variable with multi select and $__all selected', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -219,7 +219,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('query variable with numeric results', function(scenario) {
|
||||
describeUpdateVariable('query variable with numeric results', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -237,7 +237,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('basic query variable', function(scenario) {
|
||||
describeUpdateVariable('basic query variable', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.queryResult = [{ text: 'backend1' }, { text: 'backend2' }];
|
||||
@@ -255,7 +255,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('and existing value still exists in options', function(scenario) {
|
||||
describeUpdateVariable('and existing value still exists in options', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.variableModel.current = { value: 'backend2', text: 'backend2' };
|
||||
@@ -267,7 +267,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('and regex pattern exists', function(scenario) {
|
||||
describeUpdateVariable('and regex pattern exists', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.variableModel.regex = '/apps.*(backend_[0-9]+)/';
|
||||
@@ -282,7 +282,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('and regex pattern exists and no match', function(scenario) {
|
||||
describeUpdateVariable('and regex pattern exists and no match', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.variableModel.regex = '/apps.*(backendasd[0-9]+)/';
|
||||
@@ -298,7 +298,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('regex pattern without slashes', function(scenario) {
|
||||
describeUpdateVariable('regex pattern without slashes', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.variableModel.regex = 'backend_01';
|
||||
@@ -313,7 +313,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('regex pattern remove duplicates', function(scenario) {
|
||||
describeUpdateVariable('regex pattern remove duplicates', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
|
||||
scenario.variableModel.regex = '/backend_01/';
|
||||
@@ -328,7 +328,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with include All', function(scenario) {
|
||||
describeUpdateVariable('with include All', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -345,7 +345,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with include all and custom value', function(scenario) {
|
||||
describeUpdateVariable('with include all and custom value', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -362,7 +362,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('without sort', function(scenario) {
|
||||
describeUpdateVariable('without sort', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -380,7 +380,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with alphabetical sort (asc)', function(scenario) {
|
||||
describeUpdateVariable('with alphabetical sort (asc)', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -398,7 +398,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with alphabetical sort (desc)', function(scenario) {
|
||||
describeUpdateVariable('with alphabetical sort (desc)', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -416,7 +416,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with numerical sort (asc)', function(scenario) {
|
||||
describeUpdateVariable('with numerical sort (asc)', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -434,7 +434,7 @@ describe('VariableSrv', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describeUpdateVariable('with numerical sort (desc)', function(scenario) {
|
||||
describeUpdateVariable('with numerical sort (desc)', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'query',
|
||||
@@ -455,7 +455,7 @@ describe('VariableSrv', function() {
|
||||
//
|
||||
// datasource variable update
|
||||
//
|
||||
describeUpdateVariable('datasource variable with regex filter', function(scenario) {
|
||||
describeUpdateVariable('datasource variable with regex filter', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'datasource',
|
||||
@@ -486,7 +486,7 @@ describe('VariableSrv', function() {
|
||||
//
|
||||
// Custom variable update
|
||||
//
|
||||
describeUpdateVariable('update custom variable', function(scenario) {
|
||||
describeUpdateVariable('update custom variable', scenario => {
|
||||
scenario.setup(() => {
|
||||
scenario.variableModel = {
|
||||
type: 'custom',
|
||||
|
||||
@@ -4,7 +4,7 @@ import _ from 'lodash';
|
||||
import { VariableSrv } from '../variable_srv';
|
||||
import $q from 'q';
|
||||
|
||||
describe('VariableSrv init', function() {
|
||||
describe('VariableSrv init', function(this: any) {
|
||||
const templateSrv = {
|
||||
init: vars => {
|
||||
this.variables = vars;
|
||||
@@ -17,12 +17,12 @@ describe('VariableSrv init', function() {
|
||||
}),
|
||||
};
|
||||
|
||||
const $injector = <any>{};
|
||||
const $injector = {} as any;
|
||||
const $rootscope = {
|
||||
$on: () => {},
|
||||
};
|
||||
|
||||
let ctx = <any>{};
|
||||
let ctx = {} as any;
|
||||
|
||||
function describeInitScenario(desc, fn) {
|
||||
describe(desc, () => {
|
||||
|
||||
@@ -32,7 +32,7 @@ export class TemplateSrv {
|
||||
updateTemplateData() {
|
||||
this.index = {};
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
for (let i = 0; i < this.variables.length; i++) {
|
||||
const variable = this.variables[i];
|
||||
|
||||
if (!variable.current || (!variable.current.isNone && !variable.current.value)) {
|
||||
@@ -48,9 +48,9 @@ export class TemplateSrv {
|
||||
}
|
||||
|
||||
getAdhocFilters(datasourceName) {
|
||||
var filters = [];
|
||||
let filters = [];
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
for (let i = 0; i < this.variables.length; i++) {
|
||||
const variable = this.variables[i];
|
||||
if (variable.type !== 'adhoc') {
|
||||
continue;
|
||||
@@ -77,7 +77,7 @@ export class TemplateSrv {
|
||||
if (value instanceof Array && value.length === 0) {
|
||||
return '__empty__';
|
||||
}
|
||||
const quotedValues = _.map(value, function(val) {
|
||||
const quotedValues = _.map(value, val => {
|
||||
return '"' + luceneEscape(val) + '"';
|
||||
});
|
||||
return '(' + quotedValues.join(' OR ') + ')';
|
||||
@@ -171,7 +171,7 @@ export class TemplateSrv {
|
||||
return variable.allValue;
|
||||
}
|
||||
const values = [];
|
||||
for (var i = 1; i < variable.options.length; i++) {
|
||||
for (let i = 1; i < variable.options.length; i++) {
|
||||
values.push(variable.options[i].value);
|
||||
}
|
||||
return values;
|
||||
@@ -182,7 +182,7 @@ export class TemplateSrv {
|
||||
return target;
|
||||
}
|
||||
|
||||
var variable, systemValue, value, fmt;
|
||||
let variable, systemValue, value, fmt;
|
||||
this.regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this.regex, (match, var1, var2, fmt2, var3, fmt3) => {
|
||||
@@ -227,7 +227,7 @@ export class TemplateSrv {
|
||||
return target;
|
||||
}
|
||||
|
||||
var variable;
|
||||
let variable;
|
||||
this.regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this.regex, (match, var1, var2, fmt2, var3) => {
|
||||
@@ -248,7 +248,7 @@ export class TemplateSrv {
|
||||
}
|
||||
|
||||
fillVariableValuesForUrl(params, scopedVars) {
|
||||
_.each(this.variables, function(variable) {
|
||||
_.each(this.variables, variable => {
|
||||
if (scopedVars && scopedVars[variable.name] !== void 0) {
|
||||
if (scopedVars[variable.name].skipUrlSync) {
|
||||
return;
|
||||
@@ -264,7 +264,7 @@ export class TemplateSrv {
|
||||
}
|
||||
|
||||
distributeVariable(value, variable) {
|
||||
value = _.map(value, function(val, index) {
|
||||
value = _.map(value, (val, index) => {
|
||||
if (index !== 0) {
|
||||
return variable + '=' + val;
|
||||
} else {
|
||||
|
||||
@@ -10,19 +10,19 @@ export interface Variable {
|
||||
getSaveModel();
|
||||
}
|
||||
|
||||
export var variableTypes = {};
|
||||
export let variableTypes = {};
|
||||
export { assignModelProperties };
|
||||
|
||||
export function containsVariable(...args: any[]) {
|
||||
var variableName = args[args.length - 1];
|
||||
var str = args[0] || '';
|
||||
let variableName = args[args.length - 1];
|
||||
let str = args[0] || '';
|
||||
|
||||
for (var i = 1; i < args.length - 1; i++) {
|
||||
for (let i = 1; i < args.length - 1; i++) {
|
||||
str += ' ' + args[i] || '';
|
||||
}
|
||||
|
||||
variableName = kbn.regexEscape(variableName);
|
||||
var findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
|
||||
var match = findVarRegex.exec(str);
|
||||
const findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
|
||||
const match = findVarRegex.exec(str);
|
||||
return match !== null;
|
||||
}
|
||||
|
||||
@@ -122,12 +122,13 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
const g = this.createGraph();
|
||||
const promises = g
|
||||
.getNode(variable.name)
|
||||
.getOptimizedInputEdges()
|
||||
.map(e => {
|
||||
const node = g.getNode(variable.name);
|
||||
let promises = [];
|
||||
if (node) {
|
||||
promises = node.getOptimizedInputEdges().map(e => {
|
||||
return this.updateOptions(this.variables.find(v => v.name === e.inputNode.name));
|
||||
});
|
||||
}
|
||||
|
||||
return this.$q.all(promises).then(() => {
|
||||
if (emitChangeEvents) {
|
||||
@@ -138,7 +139,7 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
selectOptionsForCurrentValue(variable) {
|
||||
var i, y, value, option;
|
||||
let i, y, value, option;
|
||||
const selected: any = [];
|
||||
|
||||
for (i = 0; i < variable.options.length; i++) {
|
||||
@@ -167,17 +168,17 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
if (_.isArray(variable.current.value)) {
|
||||
var selected = this.selectOptionsForCurrentValue(variable);
|
||||
let selected = this.selectOptionsForCurrentValue(variable);
|
||||
|
||||
// if none pick first
|
||||
if (selected.length === 0) {
|
||||
selected = variable.options[0];
|
||||
} else {
|
||||
selected = {
|
||||
value: _.map(selected, function(val) {
|
||||
value: _.map(selected, val => {
|
||||
return val.value;
|
||||
}),
|
||||
text: _.map(selected, function(val) {
|
||||
text: _.map(selected, val => {
|
||||
return val.text;
|
||||
}).join(' + '),
|
||||
};
|
||||
@@ -200,14 +201,14 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
setOptionFromUrl(variable, urlValue) {
|
||||
var promise = this.$q.when();
|
||||
let promise = this.$q.when();
|
||||
|
||||
if (variable.refresh) {
|
||||
promise = variable.updateOptions();
|
||||
}
|
||||
|
||||
return promise.then(() => {
|
||||
var option = _.find(variable.options, op => {
|
||||
let option = _.find(variable.options, op => {
|
||||
return op.text === urlValue || op.value === urlValue;
|
||||
});
|
||||
|
||||
@@ -249,7 +250,7 @@ export class VariableSrv {
|
||||
const params = this.$location.search();
|
||||
|
||||
// remove variable params
|
||||
_.each(params, function(value, key) {
|
||||
_.each(params, (value, key) => {
|
||||
if (key.indexOf('var-') === 0) {
|
||||
delete params[key];
|
||||
}
|
||||
@@ -262,7 +263,7 @@ export class VariableSrv {
|
||||
}
|
||||
|
||||
setAdhocFilter(options) {
|
||||
var variable = _.find(this.variables, {
|
||||
let variable = _.find(this.variables, {
|
||||
type: 'adhoc',
|
||||
datasource: options.datasource,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user