panelMenu.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. define([
  2. 'angular',
  3. 'jquery',
  4. 'lodash',
  5. ],
  6. function (angular, $, _) {
  7. 'use strict';
  8. angular
  9. .module('grafana.directives')
  10. .directive('panelMenu', function($compile, linkSrv) {
  11. var linkTemplate =
  12. '<span class="panel-title drag-handle pointer">' +
  13. '<span class="panel-title-text drag-handle">{{panel.title | interpolateTemplateVars:this}}</span>' +
  14. '<span class="panel-links-icon"></span>' +
  15. '<span class="panel-time-info" ng-show="panelMeta.timeInfo"><i class="fa fa-clock-o"></i> {{panelMeta.timeInfo}}</span>' +
  16. '</span>';
  17. function createMenuTemplate($scope) {
  18. var template = '<div class="panel-menu small">';
  19. if ($scope.dashboardMeta.canEdit) {
  20. template += '<div class="panel-menu-inner">';
  21. template += '<div class="panel-menu-row">';
  22. template += '<a class="panel-menu-icon pull-left" ng-click="updateColumnSpan(-1)"><i class="fa fa-minus"></i></a>';
  23. template += '<a class="panel-menu-icon pull-left" ng-click="updateColumnSpan(1)"><i class="fa fa-plus"></i></a>';
  24. template += '<a class="panel-menu-icon pull-right" ng-click="removePanel(panel)"><i class="fa fa-remove"></i></a>';
  25. template += '<div class="clearfix"></div>';
  26. template += '</div>';
  27. }
  28. template += '<div class="panel-menu-row">';
  29. template += '<a class="panel-menu-link" gf-dropdown="extendedMenu"><i class="fa fa-bars"></i></a>';
  30. _.each($scope.panelMeta.menu, function(item) {
  31. // skip edit actions if not editor
  32. if (item.role === 'Editor' && !$scope.dashboardMeta.canEdit) {
  33. return;
  34. }
  35. template += '<a class="panel-menu-link" ';
  36. if (item.click) { template += ' ng-click="' + item.click + '"'; }
  37. if (item.editorLink) { template += ' dash-editor-link="' + item.editorLink + '"'; }
  38. template += '>';
  39. template += item.text + '</a>';
  40. });
  41. template += '</div>';
  42. template += '</div>';
  43. template += '</div>';
  44. return template;
  45. }
  46. function getExtendedMenu($scope) {
  47. var menu = angular.copy($scope.panelMeta.extendedMenu);
  48. if ($scope.panel.links) {
  49. _.each($scope.panel.links, function(link) {
  50. var info = linkSrv.getPanelLinkAnchorInfo(link, $scope.panel.scopedVars);
  51. menu.push({text: info.title, href: info.href, target: info.target });
  52. });
  53. }
  54. return menu;
  55. }
  56. return {
  57. restrict: 'A',
  58. link: function($scope, elem) {
  59. var $link = $(linkTemplate);
  60. var $panelContainer = elem.parents(".panel-container");
  61. var menuScope = null;
  62. var timeout = null;
  63. var $menu = null;
  64. elem.append($link);
  65. $scope.$watchCollection('panel.links', function(newValue) {
  66. var showIcon = (newValue ? newValue.length > 0 : false) && $scope.panel.title !== '';
  67. $link.toggleClass('has-panel-links', showIcon);
  68. });
  69. function dismiss(time, force) {
  70. clearTimeout(timeout);
  71. timeout = null;
  72. if (time) {
  73. timeout = setTimeout(dismiss, time);
  74. return;
  75. }
  76. // if hovering or draging pospone close
  77. if (force !== true) {
  78. if ($menu.is(':hover') || $scope.dashboard.$$panelDragging) {
  79. dismiss(2200);
  80. return;
  81. }
  82. }
  83. if (menuScope) {
  84. $menu.unbind();
  85. $menu.remove();
  86. menuScope.$destroy();
  87. menuScope = null;
  88. $menu = null;
  89. $panelContainer.removeClass('panel-highlight');
  90. }
  91. }
  92. var showMenu = function(e) {
  93. // if menu item is clicked and menu was just removed from dom ignore this event
  94. if (!$.contains(document, e.target)) {
  95. return;
  96. }
  97. if ($menu) {
  98. dismiss();
  99. return;
  100. }
  101. var menuTemplate = createMenuTemplate($scope);
  102. $menu = $(menuTemplate);
  103. $menu.mouseleave(function() {
  104. dismiss(1000);
  105. });
  106. menuScope = $scope.$new();
  107. menuScope.extendedMenu = getExtendedMenu($scope);
  108. menuScope.dismiss = function() {
  109. dismiss(null, true);
  110. };
  111. $(".panel-container").removeClass('panel-highlight');
  112. $panelContainer.toggleClass('panel-highlight');
  113. $('.panel-menu').remove();
  114. elem.append($menu);
  115. $scope.$apply(function() {
  116. $compile($menu.contents())(menuScope);
  117. var menuWidth = $menu[0].offsetWidth;
  118. var menuHeight = $menu[0].offsetHeight;
  119. var windowWidth = $(window).width();
  120. var panelLeftPos = $(elem).offset().left;
  121. var panelWidth = $(elem).width();
  122. var menuLeftPos = (panelWidth / 2) - (menuWidth/2);
  123. var stickingOut = panelLeftPos + menuLeftPos + menuWidth - windowWidth;
  124. if (stickingOut > 0) {
  125. menuLeftPos -= stickingOut + 10;
  126. }
  127. if (panelLeftPos + menuLeftPos < 0) {
  128. menuLeftPos = 0;
  129. }
  130. if ($scope.fullscreen) {
  131. menuHeight = -(menuHeight/2);
  132. }
  133. $menu.css({'left': menuLeftPos, top: -menuHeight});
  134. });
  135. dismiss(2200);
  136. };
  137. elem.click(showMenu);
  138. $compile(elem.contents())($scope);
  139. }
  140. };
  141. });
  142. });