module.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. angular.module('kibana.dashcontrol', [])
  2. .controller('dashcontrol', function($scope, $routeParams, $http, eventBus, timer) {
  3. $scope.panel = $scope.panel || {};
  4. // Set and populate defaults
  5. var _d = {
  6. group : "default",
  7. save : {
  8. gist: true,
  9. elasticsearch: true,
  10. local: true,
  11. 'default': true
  12. },
  13. load : {
  14. gist: true,
  15. elasticsearch: true,
  16. local: true,
  17. },
  18. elasticsearch_size: 20,
  19. elasticsearch_saveto: $scope.config.kibana_index,
  20. }
  21. _.defaults($scope.panel,_d);
  22. $scope.init = function() {
  23. // A hash of defaults for the dashboard object
  24. var _dash = {
  25. title: "",
  26. editable: true,
  27. rows: [],
  28. }
  29. // Long ugly if statement for figuring out which dashboard to load on init
  30. // If there is no dashboard defined, find one
  31. if(_.isUndefined($scope.dashboards)) {
  32. // First check the URL for a path to a dashboard
  33. if(!(_.isUndefined($routeParams.type)) && !(_.isUndefined($routeParams.id))) {
  34. var _type = $routeParams.type;
  35. var _id = $routeParams.id;
  36. if(_type === 'elasticsearch') {
  37. $scope.elasticsearch_load(_id)
  38. }
  39. // No dashboard in the URL
  40. } else {
  41. // Check if browser supports localstorage, and if there's a dashboard
  42. if (Modernizr.localstorage &&
  43. !(_.isUndefined(localStorage['dashboard'])) &&
  44. localStorage['dashboard'] !== ''
  45. ) {
  46. var dashboard = JSON.parse(localStorage['dashboard']);
  47. _.defaults(dashboard,_dash);
  48. $scope.dash_load(JSON.stringify(dashboard))
  49. // No? Ok, grab default.json, its all we have now
  50. } else {
  51. $http({
  52. url: "default.json",
  53. method: "GET",
  54. }).success(function(data, status, headers, config) {
  55. var dashboard = data
  56. _.defaults(dashboard,_dash);
  57. $scope.dash_load(JSON.stringify(dashboard))
  58. }).error(function(data, status, headers, config) {
  59. $scope.alert('Default dashboard missing!','Could not locate default.json','error')
  60. });
  61. }
  62. }
  63. }
  64. $scope.gist_pattern = /(^\d{5,}$)|(^[a-z0-9]{10,}$)|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
  65. $scope.gist = {};
  66. $scope.elasticsearch = {};
  67. }
  68. $scope.export = function() {
  69. var blob = new Blob([angular.toJson($scope.dashboards,true)], {type: "application/json;charset=utf-8"});
  70. saveAs(blob, $scope.dashboards.title+"-"+new Date().getTime());
  71. }
  72. $scope.default = function() {
  73. if (Modernizr.localstorage) {
  74. localStorage['dashboard'] = angular.toJson($scope.dashboards);
  75. $scope.alert('Success',
  76. $scope.dashboards.title + " has been set as your default dashboard",
  77. 'success',5000)
  78. } else {
  79. $scope.alert('Bummer!',
  80. "Your browser is too old for this functionality",
  81. 'error',5000);
  82. }
  83. }
  84. $scope.purge = function() {
  85. if (Modernizr.localstorage) {
  86. localStorage['dashboard'] = '';
  87. $scope.alert('Success',
  88. 'Default dashboard cleared',
  89. 'success',5000)
  90. } else {
  91. $scope.alert('Doh!',
  92. "Your browser is too old for this functionality",
  93. 'error',5000);
  94. }
  95. }
  96. $scope.save_elasticsearch = function() {
  97. var save = _.clone($scope.dashboards)
  98. save.title = $scope.elasticsearch.title;
  99. var result = $scope.ejs.Document($scope.panel.elasticsearch_saveto,'dashboard',save.title).source({
  100. user: 'guest',
  101. group: 'guest',
  102. title: save.title,
  103. dashboard: angular.toJson(save)
  104. }).doIndex();
  105. result.then(function(result) {
  106. $scope.alert('Dashboard Saved','This dashboard has been saved to Elasticsearch','success',5000)
  107. $scope.elasticsearch_dblist($scope.elasticsearch.query);
  108. $scope.elasticsearch.title = '';
  109. })
  110. }
  111. $scope.delete_elasticsearch = function(dashboard) {
  112. var result = $scope.ejs.Document($scope.panel.elasticsearch_saveto,'dashboard',dashboard._id).doDelete();
  113. result.then(function(result) {
  114. $scope.alert('Dashboard Deleted','','success',5000)
  115. $scope.elasticsearch.dashboards = _.without($scope.elasticsearch.dashboards,dashboard)
  116. })
  117. }
  118. $scope.elasticsearch_load = function(id) {
  119. var request = $scope.ejs.Request().indices($scope.panel.elasticsearch_saveto).types('dashboard');
  120. var results = request.query(
  121. $scope.ejs.IdsQuery(id)
  122. ).size($scope.panel.elasticsearch_size).doSearch();
  123. results.then(function(results) {
  124. if(_.isUndefined(results)) {
  125. $scope.panel.error = 'Your query was unsuccessful';
  126. return;
  127. }
  128. $scope.panel.error = false;
  129. $scope.dash_load(results.hits.hits[0]['_source']['dashboard'])
  130. });
  131. }
  132. $scope.elasticsearch_dblist = function(query) {
  133. if($scope.panel.load.elasticsearch) {
  134. var request = $scope.ejs.Request().indices($scope.panel.elasticsearch_saveto).types('dashboard');
  135. var results = request.query(
  136. $scope.ejs.QueryStringQuery(query || '*')
  137. ).size($scope.panel.elasticsearch_size).doSearch();
  138. results.then(function(results) {
  139. if(_.isUndefined(results)) {
  140. $scope.panel.error = 'Your query was unsuccessful';
  141. return;
  142. }
  143. $scope.panel.error = false;
  144. $scope.hits = results.hits.total;
  145. $scope.elasticsearch.dashboards = results.hits.hits
  146. });
  147. }
  148. }
  149. $scope.save_gist = function() {
  150. var save = _.clone($scope.dashboards)
  151. save.title = $scope.gist.title;
  152. $http({
  153. url: "https://api.github.com/gists",
  154. method: "POST",
  155. data: {
  156. "description": save.title,
  157. "public": false,
  158. "files": {
  159. "kibana-dashboard.json": {
  160. "content": angular.toJson(save,true)
  161. }
  162. }
  163. }
  164. }).success(function(data, status, headers, config) {
  165. $scope.gist.last = data.html_url;
  166. $scope.alert('Gist saved','You will be able to access your exported dashboard file at <a href="'+data.html_url+'">'+data.html_url+'</a> in a moment','success')
  167. }).error(function(data, status, headers, config) {
  168. $scope.alert('Unable to save','Save to gist failed for some reason','error',5000)
  169. });
  170. }
  171. $scope.gist_dblist = function(id) {
  172. $http({
  173. url: "https://api.github.com/gists/"+id,
  174. method: "GET"
  175. }).success(function(data, status, headers, config) {
  176. $scope.gist.files = []
  177. _.each(data.files,function(v,k) {
  178. try {
  179. var file = JSON.parse(v.content)
  180. $scope.gist.files.push(file)
  181. } catch(e) {
  182. $scope.alert('Gist failure','The dashboard file is invalid','warning',5000)
  183. }
  184. });
  185. }).error(function(data, status, headers, config) {
  186. $scope.alert('Gist Failed','Could not retrieve dashboard list from gist','error',5000)
  187. });
  188. }
  189. $scope.dash_load = function(dashboard) {
  190. if(!_.isObject(dashboard))
  191. dashboard = JSON.parse(dashboard)
  192. eventBus.broadcast($scope.$id,'ALL','dashboard',dashboard)
  193. timer.cancel_all();
  194. }
  195. $scope.gist_id = function(string) {
  196. if($scope.is_gist(string))
  197. return string.match($scope.gist_pattern)[0].replace(/.*\//, '');
  198. }
  199. $scope.is_gist = function(string) {
  200. if(!_.isUndefined(string) && string != '' && !_.isNull(string.match($scope.gist_pattern)))
  201. return string.match($scope.gist_pattern).length > 0 ? true : false;
  202. else
  203. return false
  204. }
  205. $scope.init();
  206. })
  207. .directive('dashUpload', function(timer, eventBus){
  208. return {
  209. restrict: 'A',
  210. link: function(scope, elem, attrs) {
  211. function file_selected(evt) {
  212. var files = evt.target.files; // FileList object
  213. // files is a FileList of File objects. List some properties.
  214. var output = [];
  215. for (var i = 0, f; f = files[i]; i++) {
  216. var reader = new FileReader();
  217. reader.onload = (function(theFile) {
  218. return function(e) {
  219. scope.dash_load(JSON.parse(e.target.result))
  220. scope.$apply();
  221. };
  222. })(f);
  223. reader.readAsText(f);
  224. }
  225. }
  226. // Check for the various File API support.
  227. if (window.File && window.FileReader && window.FileList && window.Blob) {
  228. // Something
  229. document.getElementById('dashupload').addEventListener('change', file_selected, false);
  230. } else {
  231. alert('Sorry, the HTML5 File APIs are not fully supported in this browser.');
  232. }
  233. }
  234. }
  235. }).filter('gistid', function() {
  236. var gist_pattern = /(\d{5,})|([a-z0-9]{10,})|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
  237. return function(input, scope) {
  238. //return input+"boners"
  239. if(!(_.isUndefined(input))) {
  240. var output = input.match(gist_pattern);
  241. if(!_.isNull(output) && !_.isUndefined(output))
  242. return output[0].replace(/.*\//, '');
  243. }
  244. }
  245. });;