/// import angular from 'angular'; import $ from 'jquery'; import _ from 'lodash'; import Drop from 'tether-drop'; import {appEvents} from 'app/core/core'; var module = angular.module('grafana.directives'); var panelTemplate = `

{{ctrl.pluginName}}

`; module.directive('grafanaPanel', function($rootScope, $document) { return { restrict: 'E', template: panelTemplate, transclude: true, scope: { ctrl: "=" }, link: function(scope, elem) { var panelContainer = elem.find('.panel-container'); var cornerInfoElem = elem.find('.panel-info-corner'); var ctrl = scope.ctrl; var infoDrop; // the reason for handling these classes this way is for performance // limit the watchers on panels etc var transparentLastState = false; var lastHasAlertRule = false; 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; } // set initial transparency if (ctrl.panel.transparent) { transparentLastState = true; panelContainer.addClass('panel-transparent', true); } 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; } }); function updatePanelCornerInfo() { var cornerMode = ctrl.getInfoMode(); cornerInfoElem[0].className = 'panel-info-corner panel-info-corner--' + cornerMode; if (cornerMode) { if (infoDrop) { infoDrop.destroy(); } infoDrop = new Drop({ target: cornerInfoElem[0], content: function() { return ctrl.getInfoContent({mode: 'tooltip'}); }, classes: ctrl.error ? 'drop-error' : 'drop-help', openOn: 'hover', hoverOpenDelay: 100, tetherOptions: { attachment: 'bottom left', targetAttachment: 'top left', constraints: [ { to: 'window', attachment: 'together', pin: true } ], } }); } } scope.$watchGroup(['ctrl.error', 'ctrl.panel.description'], updatePanelCornerInfo); scope.$watchCollection('ctrl.panel.links', updatePanelCornerInfo); cornerInfoElem.on('click', function() { infoDrop.close(); scope.$apply(ctrl.openInspector.bind(ctrl)); }); elem.on('mouseenter', mouseEnter); elem.on('mouseleave', mouseLeave); scope.$on('$destroy', function() { elem.off(); cornerInfoElem.off(); if (infoDrop) { infoDrop.destroy(); } }); } }; }); module.directive('panelHelpCorner', function($rootScope) { return { restrict: 'E', template: ` `, link: function(scope, elem) { } }; });