module.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import angular from 'angular';
  2. import _ from 'lodash';
  3. import { iconMap } from './editor';
  4. function dashLinksContainer() {
  5. return {
  6. scope: {
  7. links: '=',
  8. },
  9. restrict: 'E',
  10. controller: 'DashLinksContainerCtrl',
  11. template: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>',
  12. link: function() {},
  13. };
  14. }
  15. /** @ngInject */
  16. function dashLink($compile, $sanitize, linkSrv) {
  17. return {
  18. restrict: 'E',
  19. link: function(scope, elem) {
  20. const link = scope.link;
  21. var template =
  22. '<div class="gf-form">' +
  23. '<a class="pointer gf-form-label" data-placement="bottom"' +
  24. (link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"' : '') +
  25. '>' +
  26. '<i></i> <span></span></a>';
  27. if (link.asDropdown) {
  28. template +=
  29. '<ul class="dropdown-menu" role="menu">' +
  30. '<li ng-repeat="dash in link.searchHits">' +
  31. '<a href="{{dash.url}}" target="{{dash.target}}">{{dash.title}}</a>' +
  32. '</li>' +
  33. '</ul>';
  34. }
  35. template += '</div>';
  36. elem.html(template);
  37. $compile(elem.contents())(scope);
  38. function update() {
  39. const linkInfo = linkSrv.getAnchorInfo(link);
  40. const anchor = elem.find('a');
  41. const span = elem.find('span');
  42. span.text(linkInfo.title);
  43. if (!link.asDropdown) {
  44. anchor.attr('href', linkInfo.href);
  45. sanitizeAnchor();
  46. }
  47. anchor.attr('data-placement', 'bottom');
  48. // tooltip
  49. anchor.tooltip({
  50. title: $sanitize(scope.link.tooltip),
  51. html: true,
  52. container: 'body',
  53. });
  54. }
  55. function sanitizeAnchor() {
  56. const anchor = elem.find('a');
  57. const anchorSanitized = $sanitize(anchor.parent().html());
  58. anchor.parent().html(anchorSanitized);
  59. }
  60. elem.find('i').attr('class', 'fa fa-fw ' + scope.link.icon);
  61. elem.find('a').attr('target', scope.link.target);
  62. // fix for menus on the far right
  63. if (link.asDropdown && scope.$last) {
  64. elem.find('.dropdown-menu').addClass('pull-right');
  65. }
  66. update();
  67. scope.$on('refresh', update);
  68. },
  69. };
  70. }
  71. export class DashLinksContainerCtrl {
  72. /** @ngInject */
  73. constructor($scope, $rootScope, $q, backendSrv, dashboardSrv, linkSrv) {
  74. const currentDashId = dashboardSrv.getCurrent().id;
  75. function buildLinks(linkDef) {
  76. if (linkDef.type === 'dashboards') {
  77. if (!linkDef.tags) {
  78. console.log('Dashboard link missing tag');
  79. return $q.when([]);
  80. }
  81. if (linkDef.asDropdown) {
  82. return $q.when([
  83. {
  84. title: linkDef.title,
  85. tags: linkDef.tags,
  86. keepTime: linkDef.keepTime,
  87. includeVars: linkDef.includeVars,
  88. target: linkDef.targetBlank ? '_blank' : '_self',
  89. icon: 'fa fa-bars',
  90. asDropdown: true,
  91. },
  92. ]);
  93. }
  94. return $scope.searchDashboards(linkDef, 7);
  95. }
  96. if (linkDef.type === 'link') {
  97. return $q.when([
  98. {
  99. url: linkDef.url,
  100. title: linkDef.title,
  101. icon: iconMap[linkDef.icon],
  102. tooltip: linkDef.tooltip,
  103. target: linkDef.targetBlank ? '_blank' : '_self',
  104. keepTime: linkDef.keepTime,
  105. includeVars: linkDef.includeVars,
  106. },
  107. ]);
  108. }
  109. return $q.when([]);
  110. }
  111. function updateDashLinks() {
  112. const promises = _.map($scope.links, buildLinks);
  113. $q.all(promises).then(function(results) {
  114. $scope.generatedLinks = _.flatten(results);
  115. });
  116. }
  117. $scope.searchDashboards = function(link, limit) {
  118. return backendSrv.search({ tag: link.tags, limit: limit }).then(function(results) {
  119. return _.reduce(
  120. results,
  121. function(memo, dash) {
  122. // do not add current dashboard
  123. if (dash.id !== currentDashId) {
  124. memo.push({
  125. title: dash.title,
  126. url: dash.url,
  127. target: link.target === '_self' ? '' : link.target,
  128. icon: 'fa fa-th-large',
  129. keepTime: link.keepTime,
  130. includeVars: link.includeVars,
  131. });
  132. }
  133. return memo;
  134. },
  135. []
  136. );
  137. });
  138. };
  139. $scope.fillDropdown = function(link) {
  140. $scope.searchDashboards(link, 100).then(function(results) {
  141. _.each(results, function(hit) {
  142. hit.url = linkSrv.getLinkUrl(hit);
  143. });
  144. link.searchHits = results;
  145. });
  146. };
  147. updateDashLinks();
  148. $rootScope.onAppEvent('dash-links-updated', updateDashLinks, $scope);
  149. }
  150. }
  151. angular.module('grafana.directives').directive('dashLinksContainer', dashLinksContainer);
  152. angular.module('grafana.directives').directive('dashLink', dashLink);
  153. angular.module('grafana.directives').controller('DashLinksContainerCtrl', DashLinksContainerCtrl);