panel_header.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { coreModule } from 'app/core/core';
  2. import { AngularPanelMenuItem } from '@grafana/ui';
  3. const template = `
  4. <span class="panel-title">
  5. <span class="icon-gf panel-alert-icon"></span>
  6. <span class="panel-title-text">{{ctrl.panel.title | interpolateTemplateVars:this}}</span>
  7. <span class="panel-menu-container dropdown">
  8. <span class="fa fa-caret-down panel-menu-toggle" data-toggle="dropdown"></span>
  9. <ul class="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
  10. </ul>
  11. </span>
  12. <span class="panel-time-info" ng-if="ctrl.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.timeInfo}}</span>
  13. </span>`;
  14. function renderMenuItem(item: AngularPanelMenuItem, ctrl: any) {
  15. let html = '';
  16. let listItemClass = '';
  17. if (item.divider) {
  18. return '<li class="divider"></li>';
  19. }
  20. if (item.submenu) {
  21. listItemClass = 'dropdown-submenu';
  22. }
  23. html += `<li class="${listItemClass}"><a `;
  24. if (item.click) {
  25. html += ` ng-click="${item.click}"`;
  26. }
  27. if (item.href) {
  28. html += ` href="${item.href}"`;
  29. }
  30. html += `><i class="${item.icon}"></i>`;
  31. html += `<span class="dropdown-item-text" aria-label="${item.text} panel menu item">${item.text}</span>`;
  32. if (item.shortcut) {
  33. html += `<span class="dropdown-menu-item-shortcut">${item.shortcut}</span>`;
  34. }
  35. html += `</a>`;
  36. if (item.submenu) {
  37. html += '<ul class="dropdown-menu dropdown-menu--menu panel-menu">';
  38. for (const subitem of item.submenu) {
  39. html += renderMenuItem(subitem, ctrl);
  40. }
  41. html += '</ul>';
  42. }
  43. html += `</li>`;
  44. return html;
  45. }
  46. function createMenuTemplate(ctrl: any) {
  47. let html = '';
  48. for (const item of ctrl.getMenu()) {
  49. html += renderMenuItem(item, ctrl);
  50. }
  51. return html;
  52. }
  53. /** @ngInject */
  54. function panelHeader($compile: any) {
  55. return {
  56. restrict: 'E',
  57. template: template,
  58. link: (scope: any, elem: any, attrs: any) => {
  59. const menuElem = elem.find('.panel-menu');
  60. let menuScope: any;
  61. let isDragged: boolean;
  62. elem.click((evt: any) => {
  63. const targetClass = evt.target.className;
  64. // remove existing scope
  65. if (menuScope) {
  66. menuScope.$destroy();
  67. }
  68. menuScope = scope.$new();
  69. const menuHtml = createMenuTemplate(scope.ctrl);
  70. menuElem.html(menuHtml);
  71. $compile(menuElem)(menuScope);
  72. if (targetClass.indexOf('panel-title-text') >= 0 || targetClass.indexOf('panel-title') >= 0) {
  73. togglePanelMenu(evt);
  74. }
  75. });
  76. function togglePanelMenu(e: any) {
  77. if (!isDragged) {
  78. e.stopPropagation();
  79. elem.find('[data-toggle=dropdown]').dropdown('toggle');
  80. }
  81. }
  82. let mouseX: number, mouseY: number;
  83. elem.mousedown((e: any) => {
  84. mouseX = e.pageX;
  85. mouseY = e.pageY;
  86. });
  87. elem.mouseup((e: any) => {
  88. if (mouseX === e.pageX && mouseY === e.pageY) {
  89. isDragged = false;
  90. } else {
  91. isDragged = true;
  92. }
  93. });
  94. },
  95. };
  96. }
  97. coreModule.directive('panelHeader', panelHeader);