panel_menu.js 6.0 KB

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