dashboard.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. // jQuery UI style "widget" for editing an iTop "dashboard"
  2. ////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // dashboard
  5. //
  6. $(function()
  7. {
  8. // the widget definition, where "itop" is the namespace,
  9. // "dashboard" the widget name
  10. $.widget( "itop.dashboard",
  11. {
  12. // default options
  13. options:
  14. {
  15. dashboard_id: '',
  16. layout_class: '',
  17. title: '',
  18. auto_reload: false,
  19. auto_reload_sec: 300,
  20. submit_to: 'index.php',
  21. submit_parameters: {},
  22. render_to: 'index.php',
  23. render_parameters: {},
  24. new_dashlet_parameters: {}
  25. },
  26. // the constructor
  27. _create: function()
  28. {
  29. var me = this;
  30. this.element
  31. .addClass('itop-dashboard')
  32. .bind('add_dashlet.itop_dashboard', function(event, oParams){
  33. me.add_dashlet(oParams);
  34. });
  35. this.ajax_div = $('<div></div>');
  36. this.element.after(this.ajax_div);
  37. this._make_draggable();
  38. },
  39. // called when created, and later when changing options
  40. _refresh: function()
  41. {
  42. },
  43. // events bound via _bind are removed automatically
  44. // revert other modifications here
  45. _destroy: function()
  46. {
  47. this.element
  48. .removeClass('itop-dashboard');
  49. this.ajax_div.remove();
  50. $(document).unbind('keyup.dashboard_editor');
  51. },
  52. // _setOptions is called with a hash of all options that are changing
  53. _setOptions: function()
  54. {
  55. // in 1.9 would use _superApply
  56. this._superApply(arguments);
  57. },
  58. // _setOption is called for each individual option that is changing
  59. _setOption: function( key, value )
  60. {
  61. // in 1.9 would use _super
  62. this._superApply(arguments);
  63. },
  64. _get_state: function(oMergeInto)
  65. {
  66. var oState = oMergeInto;
  67. oState.cells = [];
  68. this.element.find('.layout_cell').each(function() {
  69. var aList = [];
  70. $(this).find(':itop-dashlet').each(function() {
  71. var oDashlet = $(this).data('itopDashlet');
  72. if(oDashlet)
  73. {
  74. var oDashletParams = oDashlet.get_params();
  75. var sId = oDashletParams.dashlet_id;
  76. oState[sId] = oDashletParams;
  77. aList.push({dashlet_id: sId, dashlet_class: oDashletParams.dashlet_class} );
  78. }
  79. });
  80. if (aList.length == 0)
  81. {
  82. oState[0] = {dashlet_id: 0, dashlet_class: 'DashletEmptyCell'};
  83. aList.push({dashlet_id: 0, dashlet_class: 'DashletEmptyCell'});
  84. }
  85. oState.cells.push(aList);
  86. });
  87. oState.dashboard_id = this.options.dashboard_id;
  88. oState.layout_class = this.options.layout_class;
  89. oState.title = this.options.title;
  90. oState.auto_reload = this.options.auto_reload;
  91. oState.auto_reload_sec = this.options.auto_reload_sec;
  92. return oState;
  93. },
  94. _get_new_id: function()
  95. {
  96. var iMaxId = 0;
  97. this.element.find(':itop-dashlet').each(function() {
  98. var oDashlet = $(this).data('itopDashlet');
  99. if(oDashlet)
  100. {
  101. var oDashletParams = oDashlet.get_params();
  102. var id = parseInt(oDashletParams.dashlet_id, 10);
  103. if (id > iMaxId) iMaxId = id;
  104. }
  105. });
  106. return 1 + iMaxId;
  107. },
  108. _make_draggable: function()
  109. {
  110. var me = this;
  111. this.element.find('.dashlet').draggable({
  112. revert: 'invalid', appendTo: 'body', zIndex: 9999, distance: 10,
  113. helper: function() {
  114. var oDragItem = $(this).dashlet('get_drag_icon');
  115. return oDragItem;
  116. },
  117. cursorAt: { top: 16, left: 16 }
  118. });
  119. this.element.find('table td').droppable({
  120. accept: '.dashlet,.dashlet_icon',
  121. drop: function(event, ui) {
  122. $( this ).find( ".placeholder" ).remove();
  123. var bRefresh = $(this).hasClass('layout_extension');
  124. var oDropped = ui.draggable;
  125. if (oDropped.hasClass('dashlet'))
  126. {
  127. // moving around a dashlet
  128. oDropped.detach();
  129. oDropped.css({top: 0, left: 0});
  130. oDropped.appendTo($(this));
  131. var oDashlet = ui.draggable.data('itopDashlet');
  132. me.on_dashlet_moved(oDashlet, $(this), bRefresh);
  133. }
  134. else
  135. {
  136. // inserting a new dashlet
  137. var sDashletClass = ui.draggable.attr('dashlet_class');
  138. $('.itop-dashboard').trigger('add_dashlet', {dashlet_class: sDashletClass, container: $(this), refresh: bRefresh });
  139. }
  140. }
  141. });
  142. },
  143. add_dashlet: function(options)
  144. {
  145. // 1) Create empty divs for the dashlet and its properties
  146. //
  147. var sDashletId = this._get_new_id();
  148. var oDashlet = $('<div class="dashlet" id="dashlet_'+sDashletId+'"/>');
  149. oDashlet.appendTo(options.container);
  150. var oDashletProperties = $('<div class="dashlet_properties" id="dashlet_properties_'+sDashletId+'"/>');
  151. oDashletProperties.appendTo($('#dashlet_properties'));
  152. // 2) Ajax call to fill the divs with default values
  153. // => in return, it must call add_dashlet_finalize
  154. //
  155. this.add_dashlet_ajax(options, sDashletId);
  156. },
  157. add_dashlet_finalize: function(options, sDashletId, sDashletClass)
  158. {
  159. $('#dashlet_'+sDashletId)
  160. .dashlet({dashlet_id: sDashletId, dashlet_class: sDashletClass})
  161. .dashlet('deselect_all')
  162. .dashlet('select')
  163. .draggable({
  164. revert: 'invalid', appendTo: 'body', zIndex: 9999, distance: 10,
  165. helper: function() {
  166. var oDragItem = $(this).dashlet('get_drag_icon');
  167. return oDragItem;
  168. },
  169. cursorAt: { top: 16, left: 16 }
  170. });
  171. if (options.refresh)
  172. {
  173. this._refresh();
  174. }
  175. },
  176. on_dashlet_moved: function(oDashlet, oReceiver, bRefresh)
  177. {
  178. if (bRefresh)
  179. {
  180. // The layout was extended... refresh the whole dashboard
  181. this._refresh();
  182. }
  183. }
  184. });
  185. });
  186. ////////////////////////////////////////////////////////////////////////////////
  187. //
  188. // runtimedashboard (extends dashboard)
  189. //
  190. $(function()
  191. {
  192. // the widget definition, where "itop" is the namespace,
  193. // "dashboard" the widget name
  194. $.widget( "itop.runtimedashboard", $.itop.dashboard,
  195. {
  196. // default options
  197. options:
  198. {
  199. dashboard_id: '',
  200. layout_class: '',
  201. title: '',
  202. auto_reload: '',
  203. auto_reload_sec: '',
  204. submit_to: 'index.php',
  205. submit_parameters: {},
  206. render_to: 'index.php',
  207. render_parameters: {},
  208. new_dashlet_parameters: {}
  209. },
  210. // the constructor
  211. _create: function()
  212. {
  213. var me = this;
  214. this._superApply(arguments);
  215. this.element
  216. .addClass('itop-runtimedashboard')
  217. .bind('mark_as_modified.itop-dashboard', function(){me.mark_as_modified();} );
  218. this.bModified = false;
  219. },
  220. // events bound via _bind are removed automatically
  221. // revert other modifications here
  222. _destroy: function()
  223. {
  224. this.element
  225. .removeClass('itop-runtimedashboard');
  226. this._superApply(arguments);
  227. },
  228. // _setOptions is called with a hash of all options that are changing
  229. _setOptions: function()
  230. {
  231. this.bRefreshNeeded = false;
  232. this._superApply(arguments);
  233. if (this.bRefreshNeeded)
  234. {
  235. this._refresh();
  236. }
  237. },
  238. // _setOption is called for each individual option that is changing
  239. _setOption: function( key, value )
  240. {
  241. this._superApply(arguments);
  242. if ((key != 'auto_reload') && (key != 'auto_reload_sec'))
  243. {
  244. this.bRefreshNeeded = true;
  245. }
  246. },
  247. // called when created, and later when changing options
  248. _refresh: function()
  249. {
  250. this._super();
  251. var oParams = this._get_state(this.options.render_parameters);
  252. var me = this;
  253. $.post(this.options.render_to, oParams, function(data){
  254. me.element.html(data);
  255. me._make_draggable();
  256. });
  257. },
  258. // Modified means: at least one change has been applied
  259. mark_as_modified: function()
  260. {
  261. this.bModified = true;
  262. },
  263. is_modified: function()
  264. {
  265. return this.bModified;
  266. },
  267. // Dirty means: at least one change has not been committed yet
  268. is_dirty: function()
  269. {
  270. if ($('#dashboard_editor .ui-layout-east .itop-property-field-modified').size() > 0)
  271. {
  272. return true;
  273. }
  274. else
  275. {
  276. return false;
  277. }
  278. },
  279. // Force the changes of all the properties being "dirty"
  280. apply_changes: function()
  281. {
  282. $('#dashboard_editor .ui-layout-east .itop-property-field-modified').trigger('apply_changes');
  283. },
  284. save: function()
  285. {
  286. var oParams = this._get_state(this.options.submit_parameters);
  287. var me = this;
  288. $.post(this.options.submit_to, oParams, function(data){
  289. me.ajax_div.html(data);
  290. });
  291. },
  292. add_dashlet_ajax: function(options, sDashletId)
  293. {
  294. var oParams = this.options.new_dashlet_parameters;
  295. var sDashletClass = options.dashlet_class;
  296. oParams.dashlet_class = sDashletClass;
  297. oParams.dashlet_id = sDashletId;
  298. var me = this;
  299. $.post(this.options.render_to, oParams, function(data){
  300. me.ajax_div.html(data);
  301. me.add_dashlet_finalize(options, sDashletId, sDashletClass);
  302. });
  303. }
  304. });
  305. });
  306. ////////////////////////////////////////////////////////////////////////////////
  307. //
  308. // Helper to upload the file selected in the "import dashboard" dialog
  309. //
  310. function UploadDashboard(oOptions)
  311. {
  312. var sFileId = 'dashboard_upload_file';
  313. var oDlg = $('<div id="dashboard_upload_dlg"><form><p>'+oOptions.text+'</p><p><input type="file" id="'+sFileId+'" name="dashboard_upload_file"></p></form></div>');
  314. $('body').append(oDlg);
  315. oOptions.file_id = sFileId;
  316. oDlg.dashboard_upload_dlg(oOptions);
  317. }
  318. ////////////////////////////////////////////////////////////////////////////////
  319. //
  320. // dashboard_upload_dlg
  321. //
  322. //jQuery UI style "widget" for managing a "import dashboard" dialog (file upload)
  323. $(function()
  324. {
  325. // the widget definition, where "itop" is the namespace,
  326. // "dashboard-upload-dlg" the widget name
  327. $.widget( "itop.dashboard_upload_dlg",
  328. {
  329. // default options
  330. options:
  331. {
  332. dashboard_id: '',
  333. file_id: '',
  334. text: 'Select a dashboard file to import',
  335. title: 'Dahsboard Import',
  336. close_btn: 'Close',
  337. submit_to: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=import_dashboard'
  338. },
  339. // the constructor
  340. _create: function()
  341. {
  342. var me = this;
  343. var oButtons = {};
  344. oButtons[this.options.close_btn] = function() {
  345. me.element.dialog('close');
  346. //me.onClose();
  347. };
  348. $('#'+this.options.file_id).bind('change', function() { me._doUpload(); } );
  349. this.element
  350. .addClass('itop-dashboard_upload_dlg')
  351. .dialog({
  352. modal: true,
  353. width: 500,
  354. height: 'auto',
  355. title: this.options.title,
  356. close: function() { me._onClose(); },
  357. buttons: oButtons
  358. });
  359. },
  360. // called when created, and later when changing options
  361. _refresh: function()
  362. {
  363. },
  364. // events bound via _bind are removed automatically
  365. // revert other modifications here
  366. _destroy: function()
  367. {
  368. this.element
  369. .removeClass('itop-dashboard_upload_dlg');
  370. },
  371. // _setOptions is called with a hash of all options that are changing
  372. _setOptions: function()
  373. {
  374. // in 1.9 would use _superApply
  375. this._superApply(arguments);
  376. this._refresh();
  377. },
  378. // _setOption is called for each individual option that is changing
  379. _setOption: function( key, value )
  380. {
  381. // in 1.9 would use _super
  382. this._superApply(arguments);
  383. },
  384. _onClose: function()
  385. {
  386. this.element.remove();
  387. },
  388. _doUpload: function()
  389. {
  390. var me = this;
  391. $.ajaxFileUpload
  392. (
  393. {
  394. url: me.options.submit_to+'&id='+me.options.dashboard_id,
  395. secureuri:false,
  396. fileElementId: me.options.file_id,
  397. dataType: 'json',
  398. success: function (data, status)
  399. {
  400. if(typeof(data.error) != 'undefined')
  401. {
  402. if(data.error != '')
  403. {
  404. alert(data.error);
  405. me.element.dialog('close');
  406. }
  407. else
  408. {
  409. me.element.dialog('close');
  410. location.reload();
  411. }
  412. }
  413. },
  414. error: function (data, status, e)
  415. {
  416. alert(e);
  417. me.element.dialog('close');
  418. }
  419. }
  420. );
  421. }
  422. });
  423. });