mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactor(): moved dashboard_srv and DashboardCtrl to typescript
This commit is contained in:
parent
b3f3b70b90
commit
1f9922a5aa
@ -1,22 +1,22 @@
|
|||||||
#! /usr/bin/env bash
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
deb_ver=3.0.0-beta41460581169
|
deb_ver=3.0.0-beta51460658374
|
||||||
rpm_ver=3.0.0-beta41460581169
|
rpm_ver=3.0.0-beta51460658374
|
||||||
|
|
||||||
#rpm_ver=3.0.0-1
|
#rpm_ver=3.0.0-1
|
||||||
|
|
||||||
wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
|
#wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
|
||||||
|
|
||||||
#package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
|
#package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
|
||||||
#package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
|
#package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
|
||||||
|
|
||||||
package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb
|
#package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb
|
||||||
package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb
|
#package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb
|
||||||
|
|
||||||
wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
|
#wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
|
||||||
|
|
||||||
package_cloud push grafana/testing/el/6 grafana-${rpm_ver}.x86_64.rpm
|
#package_cloud push grafana/testing/el/6 grafana-${rpm_ver}.x86_64.rpm
|
||||||
ackage_cloud push grafana/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
|
package_cloud push grafana/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
|
||||||
|
|
||||||
# package_cloud push grafana/stable/el/7 grafana-${version}-1.x86_64.rpm
|
# package_cloud push grafana/stable/el/7 grafana-${version}-1.x86_64.rpm
|
||||||
# package_cloud push grafana/stable/el/6 grafana-${version}-1.x86_64.rpm
|
# package_cloud push grafana/stable/el/6 grafana-${version}-1.x86_64.rpm
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
define([
|
define([
|
||||||
'./dashboardCtrl',
|
'./dashboard_ctrl',
|
||||||
'./dashboardLoaderSrv',
|
'./dashboardLoaderSrv',
|
||||||
'./dashnav/dashnav',
|
'./dashnav/dashnav',
|
||||||
'./submenu/submenu',
|
'./submenu/submenu',
|
||||||
@ -14,7 +14,6 @@ define([
|
|||||||
'./unsavedChangesSrv',
|
'./unsavedChangesSrv',
|
||||||
'./timepicker/timepicker',
|
'./timepicker/timepicker',
|
||||||
'./graphiteImportCtrl',
|
'./graphiteImportCtrl',
|
||||||
'./dynamicDashboardSrv',
|
|
||||||
'./importCtrl',
|
'./importCtrl',
|
||||||
'./impression_store',
|
'./impression_store',
|
||||||
], function () {});
|
], function () {});
|
||||||
|
@ -1,147 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'jquery',
|
|
||||||
'app/core/config',
|
|
||||||
'moment',
|
|
||||||
],
|
|
||||||
function (angular, $, config, moment) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var module = angular.module('grafana.controllers');
|
|
||||||
|
|
||||||
module.controller('DashboardCtrl', function(
|
|
||||||
$scope,
|
|
||||||
$rootScope,
|
|
||||||
dashboardKeybindings,
|
|
||||||
timeSrv,
|
|
||||||
templateValuesSrv,
|
|
||||||
dynamicDashboardSrv,
|
|
||||||
dashboardSrv,
|
|
||||||
unsavedChangesSrv,
|
|
||||||
dashboardViewStateSrv,
|
|
||||||
contextSrv,
|
|
||||||
$timeout) {
|
|
||||||
|
|
||||||
$scope.editor = { index: 0 };
|
|
||||||
$scope.panels = config.panels;
|
|
||||||
|
|
||||||
var resizeEventTimeout;
|
|
||||||
|
|
||||||
this.init = function(dashboard) {
|
|
||||||
$scope.resetRow();
|
|
||||||
$scope.registerWindowResizeEvent();
|
|
||||||
$scope.onAppEvent('show-json-editor', $scope.showJsonEditor);
|
|
||||||
$scope.setupDashboard(dashboard);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.setupDashboard = function(data) {
|
|
||||||
$rootScope.performance.dashboardLoadStart = new Date().getTime();
|
|
||||||
$rootScope.performance.panelsInitialized = 0;
|
|
||||||
$rootScope.performance.panelsRendered = 0;
|
|
||||||
|
|
||||||
var dashboard = dashboardSrv.create(data.dashboard, data.meta);
|
|
||||||
dashboardSrv.setCurrent(dashboard);
|
|
||||||
|
|
||||||
// init services
|
|
||||||
timeSrv.init(dashboard);
|
|
||||||
|
|
||||||
// template values service needs to initialize completely before
|
|
||||||
// the rest of the dashboard can load
|
|
||||||
templateValuesSrv.init(dashboard).finally(function() {
|
|
||||||
dynamicDashboardSrv.init(dashboard);
|
|
||||||
unsavedChangesSrv.init(dashboard, $scope);
|
|
||||||
|
|
||||||
$scope.dashboard = dashboard;
|
|
||||||
$scope.dashboardMeta = dashboard.meta;
|
|
||||||
$scope.dashboardViewState = dashboardViewStateSrv.create($scope);
|
|
||||||
|
|
||||||
dashboardKeybindings.shortcuts($scope);
|
|
||||||
|
|
||||||
$scope.updateSubmenuVisibility();
|
|
||||||
$scope.setWindowTitleAndTheme();
|
|
||||||
|
|
||||||
$scope.appEvent("dashboard-loaded", $scope.dashboard);
|
|
||||||
}).catch(function(err) {
|
|
||||||
if (err.data && err.data.message) { err.message = err.data.message; }
|
|
||||||
$scope.appEvent("alert-error", ['Dashboard init failed', 'Template variables could not be initialized: ' + err.message]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.updateSubmenuVisibility = function() {
|
|
||||||
$scope.submenuEnabled = $scope.dashboard.isSubmenuFeaturesEnabled();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.setWindowTitleAndTheme = function() {
|
|
||||||
window.document.title = config.window_title_prefix + $scope.dashboard.title;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.broadcastRefresh = function() {
|
|
||||||
$rootScope.performance.panelsRendered = 0;
|
|
||||||
$rootScope.$broadcast('refresh');
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.addRow = function(dash, row) {
|
|
||||||
dash.rows.push(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.addRowDefault = function() {
|
|
||||||
$scope.resetRow();
|
|
||||||
$scope.row.title = 'New row';
|
|
||||||
$scope.addRow($scope.dashboard, $scope.row);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.resetRow = function() {
|
|
||||||
$scope.row = {
|
|
||||||
title: '',
|
|
||||||
height: '250px',
|
|
||||||
editable: true,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.showJsonEditor = function(evt, options) {
|
|
||||||
var editScope = $rootScope.$new();
|
|
||||||
editScope.object = options.object;
|
|
||||||
editScope.updateHandler = options.updateHandler;
|
|
||||||
$scope.appEvent('show-dash-editor', { src: 'public/app/partials/edit_json.html', scope: editScope });
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.onDrop = function(panelId, row, dropTarget) {
|
|
||||||
var info = $scope.dashboard.getPanelInfoById(panelId);
|
|
||||||
if (dropTarget) {
|
|
||||||
var dropInfo = $scope.dashboard.getPanelInfoById(dropTarget.id);
|
|
||||||
dropInfo.row.panels[dropInfo.index] = info.panel;
|
|
||||||
info.row.panels[info.index] = dropTarget;
|
|
||||||
var dragSpan = info.panel.span;
|
|
||||||
info.panel.span = dropTarget.span;
|
|
||||||
dropTarget.span = dragSpan;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
info.row.panels.splice(info.index, 1);
|
|
||||||
info.panel.span = 12 - $scope.dashboard.rowSpan(row);
|
|
||||||
row.panels.push(info.panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rootScope.$broadcast('render');
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.registerWindowResizeEvent = function() {
|
|
||||||
angular.element(window).bind('resize', function() {
|
|
||||||
$timeout.cancel(resizeEventTimeout);
|
|
||||||
resizeEventTimeout = $timeout(function() { $scope.$broadcast('render'); }, 200);
|
|
||||||
});
|
|
||||||
$scope.$on('$destroy', function() {
|
|
||||||
angular.element(window).unbind('resize');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.timezoneChanged = function() {
|
|
||||||
$rootScope.$broadcast("refresh");
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.formatDate = function(date) {
|
|
||||||
return moment(date).format('MMM Do YYYY, h:mm:ss a');
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
154
public/app/features/dashboard/dashboard_ctrl.ts
Normal file
154
public/app/features/dashboard/dashboard_ctrl.ts
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import config from 'app/core/config';
|
||||||
|
import angular from 'angular';
|
||||||
|
import moment from 'moment';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import coreModule from 'app/core/core_module';
|
||||||
|
import {DynamicDashboardSrv} from './dynamic_dashboard_srv';
|
||||||
|
|
||||||
|
export class DashboardCtrl {
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(
|
||||||
|
private $scope,
|
||||||
|
private $rootScope,
|
||||||
|
dashboardKeybindings,
|
||||||
|
timeSrv,
|
||||||
|
templateValuesSrv,
|
||||||
|
dashboardSrv,
|
||||||
|
unsavedChangesSrv,
|
||||||
|
dashboardViewStateSrv,
|
||||||
|
contextSrv,
|
||||||
|
$timeout) {
|
||||||
|
|
||||||
|
$scope.editor = { index: 0 };
|
||||||
|
$scope.panels = config.panels;
|
||||||
|
$scope.dynamicDashboardSrv = new DynamicDashboardSrv();
|
||||||
|
|
||||||
|
var resizeEventTimeout;
|
||||||
|
|
||||||
|
$scope.setupDashboard = function(data) {
|
||||||
|
$rootScope.performance.dashboardLoadStart = new Date().getTime();
|
||||||
|
$rootScope.performance.panelsInitialized = 0;
|
||||||
|
$rootScope.performance.panelsRendered = 0;
|
||||||
|
|
||||||
|
var dashboard = dashboardSrv.create(data.dashboard, data.meta);
|
||||||
|
dashboardSrv.setCurrent(dashboard);
|
||||||
|
|
||||||
|
// init services
|
||||||
|
timeSrv.init(dashboard);
|
||||||
|
|
||||||
|
// template values service needs to initialize completely before
|
||||||
|
// the rest of the dashboard can load
|
||||||
|
templateValuesSrv.init(dashboard).finally(function() {
|
||||||
|
$scope.dynamicDashboardSrv.init(dashboard);
|
||||||
|
|
||||||
|
unsavedChangesSrv.init(dashboard, $scope);
|
||||||
|
|
||||||
|
$scope.dashboard = dashboard;
|
||||||
|
$scope.dashboardMeta = dashboard.meta;
|
||||||
|
$scope.dashboardViewState = dashboardViewStateSrv.create($scope);
|
||||||
|
|
||||||
|
dashboardKeybindings.shortcuts($scope);
|
||||||
|
|
||||||
|
$scope.updateSubmenuVisibility();
|
||||||
|
$scope.setWindowTitleAndTheme();
|
||||||
|
|
||||||
|
$scope.appEvent("dashboard-loaded", $scope.dashboard);
|
||||||
|
}).catch(function(err) {
|
||||||
|
if (err.data && err.data.message) { err.message = err.data.message; }
|
||||||
|
$scope.appEvent("alert-error", ['Dashboard init failed', 'Template variables could not be initialized: ' + err.message]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.templateVariableUpdated = function() {
|
||||||
|
$scope.dynamicDashboardSrv.update($scope.dashboard);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.updateSubmenuVisibility = function() {
|
||||||
|
$scope.submenuEnabled = $scope.dashboard.isSubmenuFeaturesEnabled();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.setWindowTitleAndTheme = function() {
|
||||||
|
window.document.title = config.window_title_prefix + $scope.dashboard.title;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.broadcastRefresh = function() {
|
||||||
|
$rootScope.performance.panelsRendered = 0;
|
||||||
|
$rootScope.$broadcast('refresh');
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addRow = function(dash, row) {
|
||||||
|
dash.rows.push(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addRowDefault = function() {
|
||||||
|
$scope.resetRow();
|
||||||
|
$scope.row.title = 'New row';
|
||||||
|
$scope.addRow($scope.dashboard, $scope.row);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.resetRow = function() {
|
||||||
|
$scope.row = {
|
||||||
|
title: '',
|
||||||
|
height: '250px',
|
||||||
|
editable: true,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.showJsonEditor = function(evt, options) {
|
||||||
|
var editScope = $rootScope.$new();
|
||||||
|
editScope.object = options.object;
|
||||||
|
editScope.updateHandler = options.updateHandler;
|
||||||
|
$scope.appEvent('show-dash-editor', { src: 'public/app/partials/edit_json.html', scope: editScope });
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.onDrop = function(panelId, row, dropTarget) {
|
||||||
|
var info = $scope.dashboard.getPanelInfoById(panelId);
|
||||||
|
if (dropTarget) {
|
||||||
|
var dropInfo = $scope.dashboard.getPanelInfoById(dropTarget.id);
|
||||||
|
dropInfo.row.panels[dropInfo.index] = info.panel;
|
||||||
|
info.row.panels[info.index] = dropTarget;
|
||||||
|
var dragSpan = info.panel.span;
|
||||||
|
info.panel.span = dropTarget.span;
|
||||||
|
dropTarget.span = dragSpan;
|
||||||
|
} else {
|
||||||
|
info.row.panels.splice(info.index, 1);
|
||||||
|
info.panel.span = 12 - $scope.dashboard.rowSpan(row);
|
||||||
|
row.panels.push(info.panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootScope.$broadcast('render');
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.registerWindowResizeEvent = function() {
|
||||||
|
angular.element(window).bind('resize', function() {
|
||||||
|
$timeout.cancel(resizeEventTimeout);
|
||||||
|
resizeEventTimeout = $timeout(function() { $scope.$broadcast('render'); }, 200);
|
||||||
|
});
|
||||||
|
$scope.$on('$destroy', function() {
|
||||||
|
angular.element(window).unbind('resize');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.timezoneChanged = function() {
|
||||||
|
$rootScope.$broadcast("refresh");
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formatDate = function(date) {
|
||||||
|
return moment(date).format('MMM Do YYYY, h:mm:ss a');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
init(dashboard) {
|
||||||
|
this.$scope.resetRow();
|
||||||
|
this.$scope.registerWindowResizeEvent();
|
||||||
|
this.$scope.onAppEvent('show-json-editor', this.$scope.showJsonEditor);
|
||||||
|
this.$scope.onAppEvent('template-variable-value-updated', this.$scope.templateVariableUpdated);
|
||||||
|
this.$scope.setupDashboard(dashboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coreModule.controller('DashboardCtrl', DashboardCtrl);
|
@ -1,181 +0,0 @@
|
|||||||
define([
|
|
||||||
'angular',
|
|
||||||
'lodash',
|
|
||||||
],
|
|
||||||
function (angular, _) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
|
||||||
|
|
||||||
module.service('dynamicDashboardSrv', function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.init = function(dashboard) {
|
|
||||||
if (dashboard.snapshot) { return; }
|
|
||||||
|
|
||||||
this.iteration = new Date().getTime();
|
|
||||||
this.process(dashboard);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.update = function(dashboard) {
|
|
||||||
if (dashboard.snapshot) { return; }
|
|
||||||
|
|
||||||
this.iteration = this.iteration + 1;
|
|
||||||
this.process(dashboard);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.process = function(dashboard) {
|
|
||||||
if (dashboard.templating.list.length === 0) { return; }
|
|
||||||
this.dashboard = dashboard;
|
|
||||||
|
|
||||||
var i, j, row, panel;
|
|
||||||
for (i = 0; i < this.dashboard.rows.length; i++) {
|
|
||||||
row = this.dashboard.rows[i];
|
|
||||||
// handle row repeats
|
|
||||||
if (row.repeat) {
|
|
||||||
this.repeatRow(row, i);
|
|
||||||
}
|
|
||||||
// clean up old left overs
|
|
||||||
else if (row.repeatRowId && row.repeatIteration !== this.iteration) {
|
|
||||||
this.dashboard.rows.splice(i, 1);
|
|
||||||
i = i - 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// repeat panels
|
|
||||||
for (j = 0; j < row.panels.length; j++) {
|
|
||||||
panel = row.panels[j];
|
|
||||||
if (panel.repeat) {
|
|
||||||
this.repeatPanel(panel, row);
|
|
||||||
}
|
|
||||||
// clean up old left overs
|
|
||||||
else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
|
|
||||||
row.panels = _.without(row.panels, panel);
|
|
||||||
j = j - 1;
|
|
||||||
} else if (!_.isEmpty(panel.scopedVars) && panel.repeatIteration !== this.iteration) {
|
|
||||||
panel.scopedVars = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// returns a new row clone or reuses a clone from previous iteration
|
|
||||||
this.getRowClone = function(sourceRow, repeatIndex, sourceRowIndex) {
|
|
||||||
if (repeatIndex === 0) {
|
|
||||||
return sourceRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
var i, panel, row, copy;
|
|
||||||
var sourceRowId = sourceRowIndex + 1;
|
|
||||||
|
|
||||||
// look for row to reuse
|
|
||||||
for (i = 0; i < this.dashboard.rows.length; i++) {
|
|
||||||
row = this.dashboard.rows[i];
|
|
||||||
if (row.repeatRowId === sourceRowId && row.repeatIteration !== this.iteration) {
|
|
||||||
copy = row;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!copy) {
|
|
||||||
copy = angular.copy(sourceRow);
|
|
||||||
this.dashboard.rows.splice(sourceRowIndex + repeatIndex, 0, copy);
|
|
||||||
|
|
||||||
// set new panel ids
|
|
||||||
for (i = 0; i < copy.panels.length; i++) {
|
|
||||||
panel = copy.panels[i];
|
|
||||||
panel.id = this.dashboard.getNextPanelId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy.repeat = null;
|
|
||||||
copy.repeatRowId = sourceRowId;
|
|
||||||
copy.repeatIteration = this.iteration;
|
|
||||||
return copy;
|
|
||||||
};
|
|
||||||
|
|
||||||
// returns a new row clone or reuses a clone from previous iteration
|
|
||||||
this.repeatRow = function(row, rowIndex) {
|
|
||||||
var variables = this.dashboard.templating.list;
|
|
||||||
var variable = _.findWhere(variables, {name: row.repeat});
|
|
||||||
if (!variable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var selected, copy, i, panel;
|
|
||||||
if (variable.current.text === 'All') {
|
|
||||||
selected = variable.options.slice(1, variable.options.length);
|
|
||||||
} else {
|
|
||||||
selected = _.filter(variable.options, {selected: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
_.each(selected, function(option, index) {
|
|
||||||
copy = self.getRowClone(row, index, rowIndex);
|
|
||||||
copy.scopedVars = {};
|
|
||||||
copy.scopedVars[variable.name] = option;
|
|
||||||
|
|
||||||
for (i = 0; i < copy.panels.length; i++) {
|
|
||||||
panel = copy.panels[i];
|
|
||||||
panel.scopedVars = {};
|
|
||||||
panel.scopedVars[variable.name] = option;
|
|
||||||
panel.repeatIteration = this.iteration;
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getPanelClone = function(sourcePanel, row, index) {
|
|
||||||
// if first clone return source
|
|
||||||
if (index === 0) {
|
|
||||||
return sourcePanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
var i, tmpId, panel, clone;
|
|
||||||
|
|
||||||
// first try finding an existing clone to use
|
|
||||||
for (i = 0; i < row.panels.length; i++) {
|
|
||||||
panel = row.panels[i];
|
|
||||||
if (panel.repeatIteration !== this.iteration && panel.repeatPanelId === sourcePanel.id) {
|
|
||||||
clone = panel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clone) {
|
|
||||||
clone = { id: this.dashboard.getNextPanelId() };
|
|
||||||
row.panels.push(clone);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save id
|
|
||||||
tmpId = clone.id;
|
|
||||||
// copy properties from source
|
|
||||||
angular.copy(sourcePanel, clone);
|
|
||||||
// restore id
|
|
||||||
clone.id = tmpId;
|
|
||||||
clone.repeatIteration = this.iteration;
|
|
||||||
clone.repeatPanelId = sourcePanel.id;
|
|
||||||
clone.repeat = null;
|
|
||||||
return clone;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.repeatPanel = function(panel, row) {
|
|
||||||
var variables = this.dashboard.templating.list;
|
|
||||||
var variable = _.findWhere(variables, {name: panel.repeat});
|
|
||||||
if (!variable) { return; }
|
|
||||||
|
|
||||||
var selected;
|
|
||||||
if (variable.current.text === 'All') {
|
|
||||||
selected = variable.options.slice(1, variable.options.length);
|
|
||||||
} else {
|
|
||||||
selected = _.filter(variable.options, {selected: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
_.each(selected, function(option, index) {
|
|
||||||
var copy = self.getPanelClone(panel, row, index);
|
|
||||||
copy.span = Math.max(12 / selected.length, panel.minSpan);
|
|
||||||
copy.scopedVars = copy.scopedVars || {};
|
|
||||||
copy.scopedVars[variable.name] = option;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
175
public/app/features/dashboard/dynamic_dashboard_srv.ts
Normal file
175
public/app/features/dashboard/dynamic_dashboard_srv.ts
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import config from 'app/core/config';
|
||||||
|
import angular from 'angular';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export class DynamicDashboardSrv {
|
||||||
|
iteration: number;
|
||||||
|
dashboard: any;
|
||||||
|
|
||||||
|
init(dashboard) {
|
||||||
|
if (dashboard.snapshot) { return; }
|
||||||
|
|
||||||
|
this.iteration = new Date().getTime();
|
||||||
|
this.process(dashboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
update(dashboard) {
|
||||||
|
if (dashboard.snapshot) { return; }
|
||||||
|
|
||||||
|
this.iteration = this.iteration + 1;
|
||||||
|
this.process(dashboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
process(dashboard) {
|
||||||
|
if (dashboard.templating.list.length === 0) { return; }
|
||||||
|
this.dashboard = dashboard;
|
||||||
|
|
||||||
|
var i, j, row, panel;
|
||||||
|
for (i = 0; i < this.dashboard.rows.length; i++) {
|
||||||
|
row = this.dashboard.rows[i];
|
||||||
|
// handle row repeats
|
||||||
|
if (row.repeat) {
|
||||||
|
this.repeatRow(row, i);
|
||||||
|
} else if (row.repeatRowId && row.repeatIteration !== this.iteration) {
|
||||||
|
// clean up old left overs
|
||||||
|
this.dashboard.rows.splice(i, 1);
|
||||||
|
i = i - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeat panels
|
||||||
|
for (j = 0; j < row.panels.length; j++) {
|
||||||
|
panel = row.panels[j];
|
||||||
|
if (panel.repeat) {
|
||||||
|
this.repeatPanel(panel, row);
|
||||||
|
} else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
|
||||||
|
// clean up old left overs
|
||||||
|
row.panels = _.without(row.panels, panel);
|
||||||
|
j = j - 1;
|
||||||
|
} else if (!_.isEmpty(panel.scopedVars) && panel.repeatIteration !== this.iteration) {
|
||||||
|
panel.scopedVars = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a new row clone or reuses a clone from previous iteration
|
||||||
|
getRowClone(sourceRow, repeatIndex, sourceRowIndex) {
|
||||||
|
if (repeatIndex === 0) {
|
||||||
|
return sourceRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i, panel, row, copy;
|
||||||
|
var sourceRowId = sourceRowIndex + 1;
|
||||||
|
|
||||||
|
// look for row to reuse
|
||||||
|
for (i = 0; i < this.dashboard.rows.length; i++) {
|
||||||
|
row = this.dashboard.rows[i];
|
||||||
|
if (row.repeatRowId === sourceRowId && row.repeatIteration !== this.iteration) {
|
||||||
|
copy = row;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!copy) {
|
||||||
|
copy = angular.copy(sourceRow);
|
||||||
|
this.dashboard.rows.splice(sourceRowIndex + repeatIndex, 0, copy);
|
||||||
|
|
||||||
|
// set new panel ids
|
||||||
|
for (i = 0; i < copy.panels.length; i++) {
|
||||||
|
panel = copy.panels[i];
|
||||||
|
panel.id = this.dashboard.getNextPanelId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copy.repeat = null;
|
||||||
|
copy.repeatRowId = sourceRowId;
|
||||||
|
copy.repeatIteration = this.iteration;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a new row clone or reuses a clone from previous iteration
|
||||||
|
repeatRow(row, rowIndex) {
|
||||||
|
var variables = this.dashboard.templating.list;
|
||||||
|
var variable = _.findWhere(variables, {name: row.repeat});
|
||||||
|
if (!variable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selected, copy, i, panel;
|
||||||
|
if (variable.current.text === 'All') {
|
||||||
|
selected = variable.options.slice(1, variable.options.length);
|
||||||
|
} else {
|
||||||
|
selected = _.filter(variable.options, {selected: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(selected, (option, index) => {
|
||||||
|
copy = this.getRowClone(row, index, rowIndex);
|
||||||
|
copy.scopedVars = {};
|
||||||
|
copy.scopedVars[variable.name] = option;
|
||||||
|
|
||||||
|
for (i = 0; i < copy.panels.length; i++) {
|
||||||
|
panel = copy.panels[i];
|
||||||
|
panel.scopedVars = {};
|
||||||
|
panel.scopedVars[variable.name] = option;
|
||||||
|
panel.repeatIteration = this.iteration;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getPanelClone(sourcePanel, row, index) {
|
||||||
|
// if first clone return source
|
||||||
|
if (index === 0) {
|
||||||
|
return sourcePanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i, tmpId, panel, clone;
|
||||||
|
|
||||||
|
// first try finding an existing clone to use
|
||||||
|
for (i = 0; i < row.panels.length; i++) {
|
||||||
|
panel = row.panels[i];
|
||||||
|
if (panel.repeatIteration !== this.iteration && panel.repeatPanelId === sourcePanel.id) {
|
||||||
|
clone = panel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clone) {
|
||||||
|
clone = { id: this.dashboard.getNextPanelId() };
|
||||||
|
row.panels.push(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save id
|
||||||
|
tmpId = clone.id;
|
||||||
|
// copy properties from source
|
||||||
|
angular.copy(sourcePanel, clone);
|
||||||
|
// restore id
|
||||||
|
clone.id = tmpId;
|
||||||
|
clone.repeatIteration = this.iteration;
|
||||||
|
clone.repeatPanelId = sourcePanel.id;
|
||||||
|
clone.repeat = null;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatPanel(panel, row) {
|
||||||
|
var variables = this.dashboard.templating.list;
|
||||||
|
var variable = _.findWhere(variables, {name: panel.repeat});
|
||||||
|
if (!variable) { return; }
|
||||||
|
|
||||||
|
var selected;
|
||||||
|
if (variable.current.text === 'All') {
|
||||||
|
selected = variable.options.slice(1, variable.options.length);
|
||||||
|
} else {
|
||||||
|
selected = _.filter(variable.options, {selected: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(selected, (option, index) => {
|
||||||
|
var copy = this.getPanelClone(panel, row, index);
|
||||||
|
copy.span = Math.max(12 / selected.length, panel.minSpan);
|
||||||
|
copy.scopedVars = copy.scopedVars || {};
|
||||||
|
copy.scopedVars[variable.name] = option;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ export class SubmenuCtrl {
|
|||||||
dashboard: any;
|
dashboard: any;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private $rootScope, private templateValuesSrv, private dynamicDashboardSrv) {
|
constructor(private $rootScope, private templateValuesSrv) {
|
||||||
this.annotations = this.dashboard.templating.list;
|
this.annotations = this.dashboard.templating.list;
|
||||||
this.variables = this.dashboard.templating.list;
|
this.variables = this.dashboard.templating.list;
|
||||||
}
|
}
|
||||||
@ -24,7 +24,6 @@ export class SubmenuCtrl {
|
|||||||
|
|
||||||
variableUpdated(variable) {
|
variableUpdated(variable) {
|
||||||
this.templateValuesSrv.variableUpdated(variable).then(() => {
|
this.templateValuesSrv.variableUpdated(variable).then(() => {
|
||||||
this.dynamicDashboardSrv.update(this.dashboard);
|
|
||||||
this.$rootScope.$emit('template-variable-value-updated');
|
this.$rootScope.$emit('template-variable-value-updated');
|
||||||
this.$rootScope.$broadcast('refresh');
|
this.$rootScope.$broadcast('refresh');
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ describe("Emitter", () => {
|
|||||||
expect(sub2Called).to.be(true);
|
expect(sub2Called).to.be(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('should handle errors', () => {
|
it('should handle errors', () => {
|
||||||
var events = new Emitter();
|
var events = new Emitter();
|
||||||
var sub1Called = 0;
|
var sub1Called = 0;
|
||||||
var sub2Called = 0;
|
var sub2Called = 0;
|
||||||
|
@ -1,267 +0,0 @@
|
|||||||
define([
|
|
||||||
'app/features/dashboard/dynamicDashboardSrv',
|
|
||||||
'app/features/dashboard/dashboardSrv'
|
|
||||||
], function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function dynamicDashScenario(desc, func) {
|
|
||||||
|
|
||||||
describe(desc, function() {
|
|
||||||
var ctx = {};
|
|
||||||
|
|
||||||
ctx.setup = function (setupFunc) {
|
|
||||||
|
|
||||||
beforeEach(module('grafana.services'));
|
|
||||||
beforeEach(module(function($provide) {
|
|
||||||
$provide.value('contextSrv', {
|
|
||||||
user: { timezone: 'utc'}
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(inject(function(dynamicDashboardSrv, dashboardSrv) {
|
|
||||||
ctx.dynamicDashboardSrv = dynamicDashboardSrv;
|
|
||||||
ctx.dashboardSrv = dashboardSrv;
|
|
||||||
|
|
||||||
var model = {
|
|
||||||
rows: [],
|
|
||||||
templating: { list: [] }
|
|
||||||
};
|
|
||||||
|
|
||||||
setupFunc(model);
|
|
||||||
ctx.dash = ctx.dashboardSrv.create(model);
|
|
||||||
ctx.dynamicDashboardSrv.init(ctx.dash);
|
|
||||||
ctx.rows = ctx.dash.rows;
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
func(ctx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamicDashScenario('given dashboard with panel repeat', function(ctx) {
|
|
||||||
ctx.setup(function(dash) {
|
|
||||||
dash.rows.push({
|
|
||||||
panels: [{id: 2, repeat: 'apps'}]
|
|
||||||
});
|
|
||||||
dash.templating.list.push({
|
|
||||||
name: 'apps',
|
|
||||||
current: {
|
|
||||||
text: 'se1, se2, se3',
|
|
||||||
value: ['se1', 'se2', 'se3']
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{text: 'se1', value: 'se1', selected: true},
|
|
||||||
{text: 'se2', value: 'se2', selected: true},
|
|
||||||
{text: 'se3', value: 'se3', selected: true},
|
|
||||||
{text: 'se4', value: 'se4', selected: false}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should repeat panel one time', function() {
|
|
||||||
expect(ctx.rows[0].panels.length).to.be(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should mark panel repeated', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].repeat).to.be('apps');
|
|
||||||
expect(ctx.rows[0].panels[1].repeatPanelId).to.be(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set scopedVars on panels', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].scopedVars.apps.value).to.be('se1');
|
|
||||||
expect(ctx.rows[0].panels[1].scopedVars.apps.value).to.be('se2');
|
|
||||||
expect(ctx.rows[0].panels[2].scopedVars.apps.value).to.be('se3');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After a second iteration', function() {
|
|
||||||
var repeatedPanelAfterIteration1;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
repeatedPanelAfterIteration1 = ctx.rows[0].panels[1];
|
|
||||||
ctx.rows[0].panels[0].fill = 10;
|
|
||||||
ctx.dynamicDashboardSrv.update(ctx.dash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have reused same panel instances', function() {
|
|
||||||
expect(ctx.rows[0].panels[1]).to.be(repeatedPanelAfterIteration1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('reused panel should copy properties from source', function() {
|
|
||||||
expect(ctx.rows[0].panels[1].fill).to.be(10);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have same panel count', function() {
|
|
||||||
expect(ctx.rows[0].panels.length).to.be(3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After a second iteration and selected values reduced', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
ctx.dash.templating.list[0].options[1].selected = false;
|
|
||||||
|
|
||||||
ctx.dynamicDashboardSrv.update(ctx.dash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clean up repeated panel', function() {
|
|
||||||
expect(ctx.rows[0].panels.length).to.be(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After a second iteration and panel repeat is turned off', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
ctx.rows[0].panels[0].repeat = null;
|
|
||||||
ctx.dynamicDashboardSrv.update(ctx.dash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clean up repeated panel', function() {
|
|
||||||
expect(ctx.rows[0].panels.length).to.be(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove scoped vars from reused panel', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].scopedVars).to.be.empty();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
dynamicDashScenario('given dashboard with row repeat', function(ctx) {
|
|
||||||
ctx.setup(function(dash) {
|
|
||||||
dash.rows.push({
|
|
||||||
repeat: 'servers',
|
|
||||||
panels: [{id: 2}]
|
|
||||||
});
|
|
||||||
dash.rows.push({panels: []});
|
|
||||||
dash.templating.list.push({
|
|
||||||
name: 'servers',
|
|
||||||
current: {
|
|
||||||
text: 'se1, se2',
|
|
||||||
value: ['se1', 'se2']
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{text: 'se1', value: 'se1', selected: true},
|
|
||||||
{text: 'se2', value: 'se2', selected: true},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should repeat row one time', function() {
|
|
||||||
expect(ctx.rows.length).to.be(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep panel ids on first row', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].id).to.be(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep first row as repeat', function() {
|
|
||||||
expect(ctx.rows[0].repeat).to.be('servers');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear repeat field on repeated row', function() {
|
|
||||||
expect(ctx.rows[1].repeat).to.be(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add scopedVars to rows', function() {
|
|
||||||
expect(ctx.rows[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
expect(ctx.rows[1].scopedVars.servers.value).to.be('se2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should generate a repeartRowId based on repeat row index', function() {
|
|
||||||
expect(ctx.rows[1].repeatRowId).to.be(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set scopedVars on row panels', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After a second iteration', function() {
|
|
||||||
var repeatedRowAfterFirstIteration;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
repeatedRowAfterFirstIteration = ctx.rows[1];
|
|
||||||
ctx.rows[0].height = 500;
|
|
||||||
ctx.dynamicDashboardSrv.update(ctx.dash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should still only have 2 rows', function() {
|
|
||||||
expect(ctx.rows.length).to.be(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip('should have updated props from source', function() {
|
|
||||||
expect(ctx.rows[1].height).to.be(500);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reuse row instance', function() {
|
|
||||||
expect(ctx.rows[1]).to.be(repeatedRowAfterFirstIteration);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('After a second iteration and selected values reduced', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
ctx.dash.templating.list[0].options[1].selected = false;
|
|
||||||
ctx.dynamicDashboardSrv.update(ctx.dash);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove repeated second row', function() {
|
|
||||||
expect(ctx.rows.length).to.be(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
dynamicDashScenario('given dashboard with row repeat and panel repeat', function(ctx) {
|
|
||||||
ctx.setup(function(dash) {
|
|
||||||
dash.rows.push({
|
|
||||||
repeat: 'servers',
|
|
||||||
panels: [{id: 2, repeat: 'metric'}]
|
|
||||||
});
|
|
||||||
dash.templating.list.push({
|
|
||||||
name: 'servers',
|
|
||||||
current: { text: 'se1, se2', value: ['se1', 'se2'] },
|
|
||||||
options: [
|
|
||||||
{text: 'se1', value: 'se1', selected: true},
|
|
||||||
{text: 'se2', value: 'se2', selected: true},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
dash.templating.list.push({
|
|
||||||
name: 'metric',
|
|
||||||
current: { text: 'm1, m2', value: ['m1', 'm2'] },
|
|
||||||
options: [
|
|
||||||
{text: 'm1', value: 'm1', selected: true},
|
|
||||||
{text: 'm2', value: 'm2', selected: true},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should repeat row one time', function() {
|
|
||||||
expect(ctx.rows.length).to.be(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should repeat panel on both rows', function() {
|
|
||||||
expect(ctx.rows[0].panels.length).to.be(2);
|
|
||||||
expect(ctx.rows[1].panels.length).to.be(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep panel ids on first row', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].id).to.be(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should mark second row as repeated', function() {
|
|
||||||
expect(ctx.rows[0].repeat).to.be('servers');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear repeat field on repeated row', function() {
|
|
||||||
expect(ctx.rows[1].repeat).to.be(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should generate a repeartRowId based on repeat row index', function() {
|
|
||||||
expect(ctx.rows[1].repeatRowId).to.be(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set scopedVars on row panels', function() {
|
|
||||||
expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
264
public/test/specs/dynamic_dashboard_srv_specs.ts
Normal file
264
public/test/specs/dynamic_dashboard_srv_specs.ts
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||||
|
|
||||||
|
import 'app/features/dashboard/dashboardSrv';
|
||||||
|
import {DynamicDashboardSrv} from '../../app/features/dashboard/dynamic_dashboard_srv';
|
||||||
|
|
||||||
|
function dynamicDashScenario(desc, func) {
|
||||||
|
|
||||||
|
describe(desc, function() {
|
||||||
|
var ctx: any = {};
|
||||||
|
|
||||||
|
ctx.setup = function (setupFunc) {
|
||||||
|
|
||||||
|
beforeEach(angularMocks.module('grafana.services'));
|
||||||
|
beforeEach(angularMocks.module(function($provide) {
|
||||||
|
$provide.value('contextSrv', {
|
||||||
|
user: { timezone: 'utc'}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(angularMocks.inject(function(dashboardSrv) {
|
||||||
|
ctx.dashboardSrv = dashboardSrv;
|
||||||
|
var model = {
|
||||||
|
rows: [],
|
||||||
|
templating: { list: [] }
|
||||||
|
};
|
||||||
|
|
||||||
|
setupFunc(model);
|
||||||
|
ctx.dash = ctx.dashboardSrv.create(model);
|
||||||
|
ctx.dynamicDashboardSrv = new DynamicDashboardSrv();
|
||||||
|
ctx.dynamicDashboardSrv.init(ctx.dash);
|
||||||
|
ctx.rows = ctx.dash.rows;
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
func(ctx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicDashScenario('given dashboard with panel repeat', function(ctx) {
|
||||||
|
ctx.setup(function(dash) {
|
||||||
|
dash.rows.push({
|
||||||
|
panels: [{id: 2, repeat: 'apps'}]
|
||||||
|
});
|
||||||
|
dash.templating.list.push({
|
||||||
|
name: 'apps',
|
||||||
|
current: {
|
||||||
|
text: 'se1, se2, se3',
|
||||||
|
value: ['se1', 'se2', 'se3']
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{text: 'se1', value: 'se1', selected: true},
|
||||||
|
{text: 'se2', value: 'se2', selected: true},
|
||||||
|
{text: 'se3', value: 'se3', selected: true},
|
||||||
|
{text: 'se4', value: 'se4', selected: false}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should repeat panel one time', function() {
|
||||||
|
expect(ctx.rows[0].panels.length).to.be(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark panel repeated', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].repeat).to.be('apps');
|
||||||
|
expect(ctx.rows[0].panels[1].repeatPanelId).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set scopedVars on panels', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].scopedVars.apps.value).to.be('se1');
|
||||||
|
expect(ctx.rows[0].panels[1].scopedVars.apps.value).to.be('se2');
|
||||||
|
expect(ctx.rows[0].panels[2].scopedVars.apps.value).to.be('se3');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration', function() {
|
||||||
|
var repeatedPanelAfterIteration1;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
repeatedPanelAfterIteration1 = ctx.rows[0].panels[1];
|
||||||
|
ctx.rows[0].panels[0].fill = 10;
|
||||||
|
ctx.dynamicDashboardSrv.update(ctx.dash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have reused same panel instances', function() {
|
||||||
|
expect(ctx.rows[0].panels[1]).to.be(repeatedPanelAfterIteration1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reused panel should copy properties from source', function() {
|
||||||
|
expect(ctx.rows[0].panels[1].fill).to.be(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have same panel count', function() {
|
||||||
|
expect(ctx.rows[0].panels.length).to.be(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration and selected values reduced', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
ctx.dash.templating.list[0].options[1].selected = false;
|
||||||
|
|
||||||
|
ctx.dynamicDashboardSrv.update(ctx.dash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clean up repeated panel', function() {
|
||||||
|
expect(ctx.rows[0].panels.length).to.be(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration and panel repeat is turned off', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
ctx.rows[0].panels[0].repeat = null;
|
||||||
|
ctx.dynamicDashboardSrv.update(ctx.dash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clean up repeated panel', function() {
|
||||||
|
expect(ctx.rows[0].panels.length).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove scoped vars from reused panel', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].scopedVars).to.be.empty();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
dynamicDashScenario('given dashboard with row repeat', function(ctx) {
|
||||||
|
ctx.setup(function(dash) {
|
||||||
|
dash.rows.push({
|
||||||
|
repeat: 'servers',
|
||||||
|
panels: [{id: 2}]
|
||||||
|
});
|
||||||
|
dash.rows.push({panels: []});
|
||||||
|
dash.templating.list.push({
|
||||||
|
name: 'servers',
|
||||||
|
current: {
|
||||||
|
text: 'se1, se2',
|
||||||
|
value: ['se1', 'se2']
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{text: 'se1', value: 'se1', selected: true},
|
||||||
|
{text: 'se2', value: 'se2', selected: true},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should repeat row one time', function() {
|
||||||
|
expect(ctx.rows.length).to.be(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep panel ids on first row', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].id).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep first row as repeat', function() {
|
||||||
|
expect(ctx.rows[0].repeat).to.be('servers');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clear repeat field on repeated row', function() {
|
||||||
|
expect(ctx.rows[1].repeat).to.be(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add scopedVars to rows', function() {
|
||||||
|
expect(ctx.rows[0].scopedVars.servers.value).to.be('se1');
|
||||||
|
expect(ctx.rows[1].scopedVars.servers.value).to.be('se2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate a repeartRowId based on repeat row index', function() {
|
||||||
|
expect(ctx.rows[1].repeatRowId).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set scopedVars on row panels', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
||||||
|
expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration', function() {
|
||||||
|
var repeatedRowAfterFirstIteration;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
repeatedRowAfterFirstIteration = ctx.rows[1];
|
||||||
|
ctx.rows[0].height = 500;
|
||||||
|
ctx.dynamicDashboardSrv.update(ctx.dash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should still only have 2 rows', function() {
|
||||||
|
expect(ctx.rows.length).to.be(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('should have updated props from source', function() {
|
||||||
|
expect(ctx.rows[1].height).to.be(500);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reuse row instance', function() {
|
||||||
|
expect(ctx.rows[1]).to.be(repeatedRowAfterFirstIteration);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration and selected values reduced', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
ctx.dash.templating.list[0].options[1].selected = false;
|
||||||
|
ctx.dynamicDashboardSrv.update(ctx.dash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove repeated second row', function() {
|
||||||
|
expect(ctx.rows.length).to.be(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
dynamicDashScenario('given dashboard with row repeat and panel repeat', function(ctx) {
|
||||||
|
ctx.setup(function(dash) {
|
||||||
|
dash.rows.push({
|
||||||
|
repeat: 'servers',
|
||||||
|
panels: [{id: 2, repeat: 'metric'}]
|
||||||
|
});
|
||||||
|
dash.templating.list.push({
|
||||||
|
name: 'servers',
|
||||||
|
current: { text: 'se1, se2', value: ['se1', 'se2'] },
|
||||||
|
options: [
|
||||||
|
{text: 'se1', value: 'se1', selected: true},
|
||||||
|
{text: 'se2', value: 'se2', selected: true},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
dash.templating.list.push({
|
||||||
|
name: 'metric',
|
||||||
|
current: { text: 'm1, m2', value: ['m1', 'm2'] },
|
||||||
|
options: [
|
||||||
|
{text: 'm1', value: 'm1', selected: true},
|
||||||
|
{text: 'm2', value: 'm2', selected: true},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should repeat row one time', function() {
|
||||||
|
expect(ctx.rows.length).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should repeat panel on both rows', function() {
|
||||||
|
expect(ctx.rows[0].panels.length).to.be(2);
|
||||||
|
expect(ctx.rows[1].panels.length).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep panel ids on first row', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].id).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark second row as repeated', function() {
|
||||||
|
expect(ctx.rows[0].repeat).to.be('servers');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clear repeat field on repeated row', function() {
|
||||||
|
expect(ctx.rows[1].repeat).to.be(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate a repeartRowId based on repeat row index', function() {
|
||||||
|
expect(ctx.rows[1].repeatRowId).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set scopedVars on row panels', function() {
|
||||||
|
expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
||||||
|
expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user