dashboard.js 11 KB

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