module.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*jshint globalstrict:true */
  2. /*global angular:true */
  3. /*global FileReader:false*/
  4. /*
  5. ## Dashcontrol
  6. Dash control allows for saving, loading and sharing of dashboards. Do not
  7. disable the dashcontrol module as a special instance of it allows for loading
  8. the default dashboard from dashboards/default
  9. ### Parameters
  10. * save
  11. ** gist :: Allow saving to gist. Requires registering an oauth domain with Github
  12. ** elasticsearch :: Allow saving to a special Kibana index within Elasticsearch
  13. ** local :: Allow saving to local file
  14. * load
  15. ** gist :: Allow loading from gists
  16. ** elasticsearch :: Allow searching and loading of elasticsearch saved dashboards
  17. ** local :: Allow loading of dashboards from Elasticsearch
  18. * hide_control :: Upon save, hide this panel
  19. * elasticsearch_size :: show this many dashboards under the ES section in the load drop down
  20. * temp :: Allow saving of temp dashboards
  21. * temp_ttl :: How long should temp dashboards persist
  22. */
  23. 'use strict';
  24. angular.module('kibana.dashcontrol', [])
  25. .controller('dashcontrol', function($scope, $http, timer, dashboard) {
  26. $scope.panel = $scope.panel || {};
  27. // Set and populate defaults
  28. var _d = {
  29. status : "Stable",
  30. group : "default",
  31. save : {
  32. gist: false,
  33. elasticsearch: true,
  34. local: true,
  35. 'default': true
  36. },
  37. load : {
  38. gist: true,
  39. elasticsearch: true,
  40. local: true
  41. },
  42. hide_control: false,
  43. elasticsearch_size: 20,
  44. temp: true,
  45. temp_ttl: '30d'
  46. };
  47. _.defaults($scope.panel,_d);
  48. // A hash of defaults for the dashboard object
  49. var _dash = {
  50. title: "",
  51. editable: true,
  52. rows: [],
  53. services: {}
  54. };
  55. $scope.init = function() {
  56. $scope.gist_pattern = /(^\d{5,}$)|(^[a-z0-9]{10,}$)|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
  57. $scope.gist = {};
  58. $scope.elasticsearch = {};
  59. };
  60. $scope.set_default = function() {
  61. if(dashboard.set_default()) {
  62. $scope.alert('Local Default Set',dashboard.current.title+' has been set as your local default','success',5000);
  63. } else {
  64. $scope.alert('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
  65. }
  66. };
  67. $scope.purge_default = function() {
  68. if(dashboard.purge_default()) {
  69. $scope.alert('Local Default Clear','Your local default dashboard has been cleared','success',5000);
  70. } else {
  71. $scope.alert('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
  72. }
  73. };
  74. $scope.elasticsearch_save = function(type,ttl) {
  75. dashboard.elasticsearch_save(type,($scope.elasticsearch.title || dashboard.current.title),ttl).then(
  76. function(result) {
  77. if(!_.isUndefined(result._id)) {
  78. $scope.alert('Dashboard Saved','This dashboard has been saved to Elasticsearch as "' +
  79. result._id + '"','success',5000);
  80. if(type === 'temp') {
  81. $scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
  82. }
  83. } else {
  84. $scope.alert('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
  85. }
  86. });
  87. };
  88. $scope.elasticsearch_delete = function(id) {
  89. dashboard.elasticsearch_delete(id).then(
  90. function(result) {
  91. if(!_.isUndefined(result)) {
  92. if(result.found) {
  93. $scope.alert('Dashboard Deleted',id+' has been deleted','success',5000);
  94. // Find the deleted dashboard in the cached list and remove it
  95. var toDelete = _.where($scope.elasticsearch.dashboards,{_id:id})[0];
  96. $scope.elasticsearch.dashboards = _.without($scope.elasticsearch.dashboards,toDelete);
  97. } else {
  98. $scope.alert('Dashboard Not Found','Could not find '+id+' in Elasticsearch','warning',5000);
  99. }
  100. } else {
  101. $scope.alert('Dashboard Not Deleted','An error occurred deleting the dashboard','error',5000);
  102. }
  103. }
  104. );
  105. };
  106. $scope.elasticsearch_dblist = function(query) {
  107. dashboard.elasticsearch_list(query,$scope.panel.elasticsearch_size).then(
  108. function(result) {
  109. if(!_.isUndefined(result.hits)) {
  110. $scope.panel.error = false;
  111. $scope.hits = result.hits.total;
  112. $scope.elasticsearch.dashboards = result.hits.hits;
  113. }
  114. });
  115. };
  116. $scope.save_gist = function() {
  117. dashboard.save_gist($scope.gist.title).then(
  118. function(link) {
  119. if(!_.isUndefined(link)) {
  120. $scope.gist.last = link;
  121. $scope.alert('Gist saved','You will be able to access your exported dashboard file at <a href="'+link+'">'+link+'</a> in a moment','success');
  122. } else {
  123. $scope.alert('Save failed','Gist could not be saved','error',5000);
  124. }
  125. });
  126. };
  127. $scope.gist_dblist = function(id) {
  128. dashboard.gist_list(id).then(
  129. function(files) {
  130. if(files && files.length > 0) {
  131. $scope.gist.files = files;
  132. } else {
  133. $scope.alert('Gist Failed','Could not retrieve dashboard list from gist','error',5000);
  134. }
  135. });
  136. };
  137. })
  138. .directive('dashUpload', function(timer, dashboard){
  139. return {
  140. restrict: 'A',
  141. link: function(scope, elem, attrs) {
  142. function file_selected(evt) {
  143. var files = evt.target.files; // FileList object
  144. // files is a FileList of File objects. List some properties.
  145. var output = [];
  146. var readerOnload = function(theFile) {
  147. return function(e) {
  148. dashboard.dash_load(JSON.parse(e.target.result));
  149. scope.$apply();
  150. };
  151. };
  152. for (var i = 0, f; f = files[i]; i++) {
  153. var reader = new FileReader();
  154. reader.onload = (readerOnload)(f);
  155. reader.readAsText(f);
  156. }
  157. }
  158. // Check for the various File API support.
  159. if (window.File && window.FileReader && window.FileList && window.Blob) {
  160. // Something
  161. document.getElementById('dashupload').addEventListener('change', file_selected, false);
  162. } else {
  163. alert('Sorry, the HTML5 File APIs are not fully supported in this browser.');
  164. }
  165. }
  166. };
  167. }).filter('gistid', function() {
  168. var gist_pattern = /(\d{5,})|([a-z0-9]{10,})|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
  169. return function(input, scope) {
  170. //return input+"boners"
  171. if(!(_.isUndefined(input))) {
  172. var output = input.match(gist_pattern);
  173. if(!_.isNull(output) && !_.isUndefined(output)) {
  174. return output[0].replace(/.*\//, '');
  175. }
  176. }
  177. };
  178. });