dashboard.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // jQuery UI style "widget" for editing an iTop "dashboard"
  2. $(function()
  3. {
  4. // the widget definition, where "itop" is the namespace,
  5. // "dashboard" the widget name
  6. $.widget( "itop.dashboard",
  7. {
  8. // default options
  9. options:
  10. {
  11. dashboard_id: '',
  12. layout_class: '',
  13. title: '',
  14. submit_to: 'index.php',
  15. submit_parameters: {},
  16. render_to: 'index.php',
  17. render_parameters: {},
  18. new_dashlet_parameters: {}
  19. },
  20. // the constructor
  21. _create: function()
  22. {
  23. var me = this;
  24. this.element
  25. .addClass('itop-dashboard')
  26. .bind('mark_as_modified.itop-dashboard', function(){me.mark_as_modified();} );
  27. this.ajax_div = $('<div></div>').appendTo(this.element);
  28. this._make_draggable();
  29. this.bModified = false;
  30. },
  31. // called when created, and later when changing options
  32. _refresh: function()
  33. {
  34. var oParams = this._get_state(this.options.render_parameters);
  35. var me = this;
  36. $.post(this.options.render_to, oParams, function(data){
  37. me.element.html(data);
  38. me._make_draggable();
  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. this._refresh();
  56. },
  57. // _setOption is called for each individual option that is changing
  58. _setOption: function( key, value )
  59. {
  60. // in 1.9 would use _super
  61. this._superApply(arguments);
  62. },
  63. _get_state: function(oMergeInto)
  64. {
  65. var oState = oMergeInto;
  66. oState.cells = [];
  67. this.element.find('.layout_cell').each(function() {
  68. var aList = [];
  69. $(this).find(':itop-dashlet').each(function() {
  70. var oDashlet = $(this).data('itopDashlet');
  71. if(oDashlet)
  72. {
  73. var oDashletParams = oDashlet.get_params();
  74. var sId = oDashletParams.dashlet_id;
  75. oState[sId] = oDashletParams;
  76. aList.push({dashlet_id: sId, dashlet_class: oDashletParams.dashlet_class} );
  77. }
  78. });
  79. if (aList.length == 0)
  80. {
  81. oState[0] = {dashlet_id: 0, dashlet_class: 'DashletEmptyCell'};
  82. aList.push({dashlet_id: 0, dashlet_class: 'DashletEmptyCell'});
  83. }
  84. oState.cells.push(aList);
  85. });
  86. oState.dashboard_id = this.options.dashboard_id;
  87. oState.layout_class = this.options.layout_class;
  88. oState.title = this.options.title;
  89. return oState;
  90. },
  91. // Modified means: at least one change has been applied
  92. mark_as_modified: function()
  93. {
  94. this.bModified = true;
  95. },
  96. is_modified: function()
  97. {
  98. return this.bModified;
  99. },
  100. // Dirty means: at least one change has not been committed yet
  101. is_dirty: function()
  102. {
  103. if ($('#dashboard_editor .ui-layout-east .itop-property-field-modified').size() > 0)
  104. {
  105. return true;
  106. }
  107. else
  108. {
  109. return false;
  110. }
  111. },
  112. // Force the changes of all the properties being "dirty"
  113. apply_changes: function()
  114. {
  115. $('#dashboard_editor .ui-layout-east .itop-property-field-modified').trigger('apply_changes');
  116. },
  117. save: function()
  118. {
  119. var oParams = this._get_state(this.options.submit_parameters);
  120. var me = this;
  121. $.post(this.options.submit_to, oParams, function(data){
  122. me.ajax_div.html(data);
  123. });
  124. },
  125. add_dashlet: function(options)
  126. {
  127. var sDashletId = this._get_new_id();
  128. var oDashlet = $('<div class="dashlet" id="dashlet_'+sDashletId+'"/>');
  129. oDashlet.appendTo(options.container);
  130. var oDashletProperties = $('<div class="dashlet_properties" id="dashlet_properties_'+sDashletId+'"/>');
  131. oDashletProperties.appendTo($('#dashlet_properties'));
  132. var oParams = this.options.new_dashlet_parameters;
  133. var sDashletClass = options.dashlet_class;
  134. oParams.dashlet_class = sDashletClass;
  135. oParams.dashlet_id = sDashletId;
  136. var me = this;
  137. $.post(this.options.render_to, oParams, function(data){
  138. me.ajax_div.html(data);
  139. $('#dashlet_'+sDashletId)
  140. .dashlet({dashlet_id: sDashletId, dashlet_class: sDashletClass})
  141. .dashlet('deselect_all')
  142. .dashlet('select')
  143. .draggable({
  144. revert: 'invalid', appendTo: 'body', zIndex: 9999,
  145. helper: function() {
  146. var oDragItem = $(this).dashlet('get_drag_icon');
  147. return oDragItem;
  148. },
  149. cursorAt: { top: 16, left: 16 }
  150. });
  151. if (options.refresh)
  152. {
  153. me._refresh();
  154. }
  155. });
  156. },
  157. _get_new_id: function()
  158. {
  159. var iMaxId = 0;
  160. this.element.find(':itop-dashlet').each(function() {
  161. var oDashlet = $(this).data('itopDashlet');
  162. if(oDashlet)
  163. {
  164. var oDashletParams = oDashlet.get_params();
  165. var id = parseInt(oDashletParams.dashlet_id, 10);
  166. if (id > iMaxId) iMaxId = id;
  167. }
  168. });
  169. return 1 + iMaxId;
  170. },
  171. _make_draggable: function()
  172. {
  173. var me = this;
  174. this.element.find('.dashlet').draggable({
  175. revert: 'invalid', appendTo: 'body', zIndex: 9999,
  176. helper: function() {
  177. var oDragItem = $(this).dashlet('get_drag_icon');
  178. return oDragItem;
  179. },
  180. cursorAt: { top: 16, left: 16 }
  181. });
  182. this.element.find('table td').droppable({
  183. accept: '.dashlet,.dashlet_icon',
  184. drop: function(event, ui) {
  185. $( this ).find( ".placeholder" ).remove();
  186. var bRefresh = $(this).hasClass('layout_extension');
  187. var oDashlet = ui.draggable;
  188. if (oDashlet.hasClass('dashlet'))
  189. {
  190. // moving around a dashlet
  191. oDashlet.detach();
  192. oDashlet.css({top: 0, left: 0});
  193. oDashlet.appendTo($(this));
  194. if( bRefresh )
  195. {
  196. // The layout was extended... refresh the whole dashboard
  197. me._refresh();
  198. }
  199. }
  200. else
  201. {
  202. // inserting a new dashlet
  203. var sDashletClass = ui.draggable.attr('dashlet_class');
  204. $(':itop-dashboard').dashboard('add_dashlet', {dashlet_class: sDashletClass, container: $(this), refresh: bRefresh });
  205. }
  206. }
  207. });
  208. }
  209. });
  210. });
  211. function UploadDashboard(oOptions)
  212. {
  213. var sFileId = 'dashboard_upload_file';
  214. 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>');
  215. $('body').append(oDlg);
  216. oOptions.file_id = sFileId;
  217. oDlg.dashboard_upload_dlg(oOptions);
  218. }
  219. //jQuery UI style "widget" for managing a "import dashboard" dialog (file upload)
  220. $(function()
  221. {
  222. // the widget definition, where "itop" is the namespace,
  223. // "dashboard-upload-dlg" the widget name
  224. $.widget( "itop.dashboard_upload_dlg",
  225. {
  226. // default options
  227. options:
  228. {
  229. dashboard_id: '',
  230. file_id: '',
  231. text: 'Select a dashboard file to import',
  232. title: 'Dahsboard Import',
  233. close_btn: 'Close',
  234. submit_to: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=import_dashboard'
  235. },
  236. // the constructor
  237. _create: function()
  238. {
  239. var me = this;
  240. var oButtons = {};
  241. oButtons[this.options.close_btn] = function() {
  242. me.element.dialog('close');
  243. //me.onClose();
  244. };
  245. $('#'+this.options.file_id).bind('change', function() { me._doUpload(); } );
  246. this.element
  247. .addClass('itop-dashboard_upload_dlg')
  248. .dialog({
  249. modal: true,
  250. width: 500,
  251. height: 'auto',
  252. title: this.options.title,
  253. close: function() { me._onClose(); },
  254. buttons: oButtons
  255. });
  256. },
  257. // called when created, and later when changing options
  258. _refresh: function()
  259. {
  260. },
  261. // events bound via _bind are removed automatically
  262. // revert other modifications here
  263. _destroy: function()
  264. {
  265. this.element
  266. .removeClass('itop-dashboard_upload_dlg');
  267. },
  268. // _setOptions is called with a hash of all options that are changing
  269. _setOptions: function()
  270. {
  271. // in 1.9 would use _superApply
  272. this._superApply(arguments);
  273. this._refresh();
  274. },
  275. // _setOption is called for each individual option that is changing
  276. _setOption: function( key, value )
  277. {
  278. // in 1.9 would use _super
  279. this._superApply(arguments);
  280. },
  281. _onClose: function()
  282. {
  283. this.element.remove();
  284. },
  285. _doUpload: function()
  286. {
  287. var me = this;
  288. $.ajaxFileUpload
  289. (
  290. {
  291. url: me.options.submit_to+'&id='+me.options.dashboard_id,
  292. secureuri:false,
  293. fileElementId: me.options.file_id,
  294. dataType: 'json',
  295. success: function (data, status)
  296. {
  297. if(typeof(data.error) != 'undefined')
  298. {
  299. if(data.error != '')
  300. {
  301. alert(data.error);
  302. me.element.dialog('close');
  303. }
  304. else
  305. {
  306. me.element.dialog('close');
  307. location.reload();
  308. }
  309. }
  310. },
  311. error: function (data, status, e)
  312. {
  313. alert(e);
  314. me.element.dialog('close');
  315. }
  316. }
  317. );
  318. }
  319. });
  320. });