/// import angular from 'angular'; import $ from 'jquery'; var module = angular.module('grafana.directives'); var panelTemplate = `

{{ctrl.pluginName}}

`; 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(); }); } }; });