misc.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import angular from 'angular';
  2. import Clipboard from 'clipboard';
  3. import coreModule from '../core_module';
  4. import kbn from 'app/core/utils/kbn';
  5. import { appEvents } from 'app/core/core';
  6. /** @ngInject */
  7. function tip($compile) {
  8. return {
  9. restrict: 'E',
  10. link: function(scope, elem, attrs) {
  11. let _t =
  12. '<i class="grafana-tip fa fa-' +
  13. (attrs.icon || 'question-circle') +
  14. '" bs-tooltip="\'' +
  15. kbn.addslashes(elem.text()) +
  16. '\'"></i>';
  17. _t = _t.replace(/{/g, '\\{').replace(/}/g, '\\}');
  18. elem.replaceWith($compile(angular.element(_t))(scope));
  19. },
  20. };
  21. }
  22. function clipboardButton() {
  23. return {
  24. scope: {
  25. getText: '&clipboardButton',
  26. },
  27. link: function(scope, elem) {
  28. scope.clipboard = new Clipboard(elem[0], {
  29. text: function() {
  30. return scope.getText();
  31. },
  32. });
  33. scope.clipboard.on('success', () => {
  34. appEvents.emit('alert-success', ['Content copied to clipboard']);
  35. });
  36. scope.$on('$destroy', function() {
  37. if (scope.clipboard) {
  38. scope.clipboard.destroy();
  39. }
  40. });
  41. },
  42. };
  43. }
  44. /** @ngInject */
  45. function compile($compile) {
  46. return {
  47. restrict: 'A',
  48. link: function(scope, element, attrs) {
  49. scope.$watch(
  50. function(scope) {
  51. return scope.$eval(attrs.compile);
  52. },
  53. function(value) {
  54. element.html(value);
  55. $compile(element.contents())(scope);
  56. }
  57. );
  58. },
  59. };
  60. }
  61. function watchChange() {
  62. return {
  63. scope: { onchange: '&watchChange' },
  64. link: function(scope, element) {
  65. element.on('input', function() {
  66. scope.$apply(function() {
  67. scope.onchange({ inputValue: element.val() });
  68. });
  69. });
  70. },
  71. };
  72. }
  73. /** @ngInject */
  74. function editorOptBool($compile) {
  75. return {
  76. restrict: 'E',
  77. link: function(scope, elem, attrs) {
  78. const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
  79. const tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
  80. const showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : '';
  81. const template =
  82. '<div class="editor-option gf-form-checkbox text-center"' +
  83. showIf +
  84. '>' +
  85. ' <label for="' +
  86. attrs.model +
  87. '" class="small">' +
  88. attrs.text +
  89. tip +
  90. '</label>' +
  91. '<input class="cr1" id="' +
  92. attrs.model +
  93. '" type="checkbox" ' +
  94. ' ng-model="' +
  95. attrs.model +
  96. '"' +
  97. ngchange +
  98. ' ng-checked="' +
  99. attrs.model +
  100. '"></input>' +
  101. ' <label for="' +
  102. attrs.model +
  103. '" class="cr1"></label>';
  104. elem.replaceWith($compile(angular.element(template))(scope));
  105. },
  106. };
  107. }
  108. /** @ngInject */
  109. function editorCheckbox($compile, $interpolate) {
  110. return {
  111. restrict: 'E',
  112. link: function(scope, elem, attrs) {
  113. const text = $interpolate(attrs.text)(scope);
  114. const model = $interpolate(attrs.model)(scope);
  115. const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
  116. const tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
  117. const label = '<label for="' + scope.$id + model + '" class="checkbox-label">' + text + tip + '</label>';
  118. let template =
  119. '<input class="cr1" id="' +
  120. scope.$id +
  121. model +
  122. '" type="checkbox" ' +
  123. ' ng-model="' +
  124. model +
  125. '"' +
  126. ngchange +
  127. ' ng-checked="' +
  128. model +
  129. '"></input>' +
  130. ' <label for="' +
  131. scope.$id +
  132. model +
  133. '" class="cr1"></label>';
  134. template = template + label;
  135. elem.addClass('gf-form-checkbox');
  136. elem.html($compile(angular.element(template))(scope));
  137. },
  138. };
  139. }
  140. /** @ngInject */
  141. function gfDropdown($parse, $compile, $timeout) {
  142. function buildTemplate(items, placement?) {
  143. const upclass = placement === 'top' ? 'dropup' : '';
  144. const ul = ['<ul class="dropdown-menu ' + upclass + '" role="menu" aria-labelledby="drop1">', '</ul>'];
  145. for (let index = 0; index < items.length; index++) {
  146. const item = items[index];
  147. if (item.divider) {
  148. ul.splice(index + 1, 0, '<li class="divider"></li>');
  149. continue;
  150. }
  151. let li =
  152. '<li' +
  153. (item.submenu && item.submenu.length ? ' class="dropdown-submenu"' : '') +
  154. '>' +
  155. '<a tabindex="-1" ng-href="' +
  156. (item.href || '') +
  157. '"' +
  158. (item.click ? ' ng-click="' + item.click + '"' : '') +
  159. (item.target ? ' target="' + item.target + '"' : '') +
  160. (item.method ? ' data-method="' + item.method + '"' : '') +
  161. '>' +
  162. (item.text || '') +
  163. '</a>';
  164. if (item.submenu && item.submenu.length) {
  165. li += buildTemplate(item.submenu).join('\n');
  166. }
  167. li += '</li>';
  168. ul.splice(index + 1, 0, li);
  169. }
  170. return ul;
  171. }
  172. return {
  173. restrict: 'EA',
  174. scope: true,
  175. link: function postLink(scope, iElement, iAttrs) {
  176. const getter = $parse(iAttrs.gfDropdown),
  177. items = getter(scope);
  178. $timeout(function() {
  179. const placement = iElement.data('placement');
  180. const dropdown = angular.element(buildTemplate(items, placement).join(''));
  181. dropdown.insertAfter(iElement);
  182. $compile(iElement.next('ul.dropdown-menu'))(scope);
  183. });
  184. iElement.addClass('dropdown-toggle').attr('data-toggle', 'dropdown');
  185. },
  186. };
  187. }
  188. coreModule.directive('tip', tip);
  189. coreModule.directive('clipboardButton', clipboardButton);
  190. coreModule.directive('compile', compile);
  191. coreModule.directive('watchChange', watchChange);
  192. coreModule.directive('editorOptBool', editorOptBool);
  193. coreModule.directive('editorCheckbox', editorCheckbox);
  194. coreModule.directive('gfDropdown', gfDropdown);