add_graphite_func.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. define([
  2. 'angular',
  3. 'lodash',
  4. 'jquery',
  5. ],
  6. function (angular, _, $) {
  7. 'use strict';
  8. angular
  9. .module('grafana.directives')
  10. .directive('graphiteAddFunc', function($compile) {
  11. var inputTemplate = '<input type="text"'+
  12. ' class="gf-form-input"' +
  13. ' spellcheck="false" style="display:none"></input>';
  14. var buttonTemplate = '<a class="gf-form-label query-part dropdown-toggle"' +
  15. ' tabindex="1" gf-dropdown="functionMenu" data-toggle="dropdown">' +
  16. '<i class="fa fa-plus"></i></a>';
  17. return {
  18. link: function($scope, elem) {
  19. var ctrl = $scope.ctrl;
  20. var $input = $(inputTemplate);
  21. var $button = $(buttonTemplate);
  22. $input.appendTo(elem);
  23. $button.appendTo(elem);
  24. ctrl.datasource.getFuncDefs().then(function(funcDefs) {
  25. var allFunctions = _.map(funcDefs, 'name').sort();
  26. $scope.functionMenu = createFunctionDropDownMenu(funcDefs);
  27. $input.attr('data-provide', 'typeahead');
  28. $input.typeahead({
  29. source: allFunctions,
  30. minLength: 1,
  31. items: 10,
  32. updater: function (value) {
  33. var funcDef = ctrl.datasource.getFuncDef(value);
  34. if (!funcDef) {
  35. // try find close match
  36. value = value.toLowerCase();
  37. funcDef = _.find(allFunctions, function(funcName) {
  38. return funcName.toLowerCase().indexOf(value) === 0;
  39. });
  40. if (!funcDef) { return; }
  41. }
  42. $scope.$apply(function() {
  43. ctrl.addFunction(funcDef);
  44. });
  45. $input.trigger('blur');
  46. return '';
  47. }
  48. });
  49. $button.click(function() {
  50. $button.hide();
  51. $input.show();
  52. $input.focus();
  53. });
  54. $input.keyup(function() {
  55. elem.toggleClass('open', $input.val() === '');
  56. });
  57. $input.blur(function() {
  58. // clicking the function dropdown menu wont
  59. // work if you remove class at once
  60. setTimeout(function() {
  61. $input.val('');
  62. $input.hide();
  63. $button.show();
  64. elem.removeClass('open');
  65. }, 200);
  66. });
  67. $compile(elem.contents())($scope);
  68. });
  69. }
  70. };
  71. });
  72. function createFunctionDropDownMenu(funcDefs) {
  73. var categories = {};
  74. _.forEach(funcDefs, function(funcDef) {
  75. if (!funcDef.category) {
  76. return;
  77. }
  78. if (!categories[funcDef.category]) {
  79. categories[funcDef.category] = [];
  80. }
  81. categories[funcDef.category].push({
  82. text: funcDef.name,
  83. click: "ctrl.addFunction('" + funcDef.name + "')",
  84. });
  85. });
  86. return _.sortBy(_.map(categories, function(submenu, category) {
  87. return {
  88. text: category,
  89. submenu: _.sortBy(submenu, 'text')
  90. };
  91. }), 'text');
  92. }
  93. });