///
import angular from 'angular';
import $ from 'jquery';
var module = angular.module('grafana.directives');
var panelTemplate = `
`;
module.directive('grafanaPanel', function($rootScope) {
return {
restrict: 'E',
template: panelTemplate,
transclude: true,
scope: { ctrl: "=" },
link: function(scope, elem) {
var panelContainer = elem.find('.panel-container');
var ctrl = scope.ctrl;
// the reason for handling these classes this way is for performance
// limit the watchers on panels etc
var transparentLastState;
var lastHasAlertRule;
var lastAlertState;
var hasAlertRule;
var lastHeight = 0;
function mouseEnter() {
panelContainer.toggleClass('panel-hover-highlight', true);
ctrl.dashboard.setPanelFocus(ctrl.panel.id);
}
function mouseLeave() {
panelContainer.toggleClass('panel-hover-highlight', false);
ctrl.dashboard.setPanelFocus(0);
}
// set initial height
if (!ctrl.containerHeight) {
ctrl.calculatePanelHeight();
panelContainer.css({minHeight: ctrl.containerHeight});
lastHeight = ctrl.containerHeight;
}
ctrl.events.on('render', () => {
if (lastHeight !== ctrl.containerHeight) {
panelContainer.css({minHeight: ctrl.containerHeight});
lastHeight = ctrl.containerHeight;
}
if (transparentLastState !== ctrl.panel.transparent) {
panelContainer.toggleClass('panel-transparent', ctrl.panel.transparent === true);
transparentLastState = ctrl.panel.transparent;
}
hasAlertRule = ctrl.panel.alert !== undefined;
if (lastHasAlertRule !== hasAlertRule) {
panelContainer.toggleClass('panel-has-alert', hasAlertRule);
lastHasAlertRule = hasAlertRule;
}
if (ctrl.alertState) {
if (lastAlertState) {
panelContainer.removeClass('panel-alert-state--' + lastAlertState);
}
if (ctrl.alertState.state === 'ok' || ctrl.alertState.state === 'alerting') {
panelContainer.addClass('panel-alert-state--' + ctrl.alertState.state);
}
lastAlertState = ctrl.alertState.state;
} else if (lastAlertState) {
panelContainer.removeClass('panel-alert-state--' + lastAlertState);
lastAlertState = null;
}
});
var lastFullscreen;
$rootScope.onAppEvent('panel-change-view', function(evt, payload) {
if (lastFullscreen !== ctrl.fullscreen) {
elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
lastFullscreen = ctrl.fullscreen;
}
}, scope);
elem.on('mouseenter', mouseEnter);
elem.on('mouseleave', mouseLeave);
scope.$on('$destroy', function() {
elem.off();
});
}
};
});
module.directive('panelResizer', function($rootScope) {
return {
restrict: 'E',
template: '',
link: function(scope, elem) {
var resizing = false;
var lastPanel;
var ctrl = scope.ctrl;
var handleOffset;
var originalHeight;
var originalWidth;
var maxWidth;
function dragStartHandler(e) {
e.preventDefault();
resizing = true;
handleOffset = $(e.target).offset();
originalHeight = parseInt(ctrl.row.height);
originalWidth = ctrl.panel.span;
maxWidth = $(document).width();
lastPanel = ctrl.row.panels[ctrl.row.panels.length - 1];
$('body').on('mousemove', moveHandler);
$('body').on('mouseup', dragEndHandler);
}
function moveHandler(e) {
ctrl.row.height = Math.round(originalHeight + (e.pageY - handleOffset.top));
ctrl.panel.span = originalWidth + (((e.pageX - handleOffset.left) / maxWidth) * 12);
ctrl.panel.span = Math.min(Math.max(ctrl.panel.span, 1), 12);
ctrl.row.updateRowSpan();
var rowSpan = ctrl.row.span;
// auto adjust other panels
if (Math.floor(rowSpan) < 14) {
// last panel should not push row down
if (lastPanel === ctrl.panel && rowSpan > 12) {
lastPanel.span -= rowSpan - 12;
} else if (lastPanel !== ctrl.panel) {
// reduce width of last panel so total in row is 12
lastPanel.span = lastPanel.span - (rowSpan - 12);
lastPanel.span = Math.min(Math.max(lastPanel.span, 1), 12);
}
}
ctrl.row.panelSpanChanged();
scope.$apply(function() {
ctrl.render();
});
}
function dragEndHandler() {
ctrl.panel.span = Math.round(ctrl.panel.span);
if (lastPanel) {
lastPanel.span = Math.round(lastPanel.span);
}
// first digest to propagate panel width change
// then render
$rootScope.$apply(function() {
ctrl.row.panelSpanChanged();
setTimeout(function() {
$rootScope.$broadcast('render');
});
});
$('body').off('mousemove', moveHandler);
$('body').off('mouseup', dragEndHandler);
}
elem.on('mousedown', dragStartHandler);
var unbind = scope.$on("$destroy", function() {
elem.off('mousedown', dragStartHandler);
unbind();
});
}
};
});