module.js 7.0 KB

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