modx.panel.dashboard.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. MODx.panel.Dashboard = function(config) {
  2. config = config || {};
  3. Ext.applyIf(config,{
  4. id: 'modx-panel-dashboard'
  5. ,url: MODx.config.connector_url
  6. ,baseParams: {
  7. action: 'system/dashboard/update'
  8. }
  9. ,cls: 'container'
  10. ,defaults: { collapsible: false ,autoHeight: true }
  11. ,items: [{
  12. html: _('dashboard')
  13. ,id: 'modx-dashboard-header'
  14. ,xtype: 'modx-header'
  15. },{
  16. xtype: 'modx-tabs'
  17. ,defaults: {
  18. autoHeight: true
  19. ,border: false
  20. }
  21. ,id: 'modx-dashboard-tabs'
  22. ,forceLayout: true
  23. ,deferredRender: false
  24. ,stateful: true
  25. ,stateId: 'modx-dashboard-tabpanel'
  26. ,stateEvents: ['tabchange']
  27. ,getState:function() {
  28. return {activeTab:this.items.indexOf(this.getActiveTab())};
  29. }
  30. // todo: the layout is inconsistent with other panels, refactor the structure
  31. ,items: [{
  32. title: _('general_information')
  33. ,cls: 'form-with-labels'
  34. ,defaults: { border: false, cls: 'main-wrapper' }
  35. ,layout: 'form'
  36. ,id: 'modx-dashboard-form'
  37. ,labelAlign: 'top'
  38. ,items: [{
  39. xtype: 'hidden'
  40. ,name: 'id'
  41. ,id: 'modx-dashboard-id'
  42. ,value: config.record.id
  43. },{
  44. layout: 'column'
  45. ,border: false
  46. ,defaults: {
  47. layout: 'form'
  48. ,labelAlign: 'top'
  49. ,anchor: '100%'
  50. ,border: false
  51. }
  52. ,items: [{
  53. columnWidth: .7
  54. ,cls: 'main-content'
  55. ,items: [{
  56. name: 'name'
  57. ,id: 'modx-dashboard-name'
  58. ,xtype: 'textfield'
  59. ,fieldLabel: _('name')
  60. ,description: MODx.expandHelp ? '' : _('dashboard_desc_name')
  61. ,allowBlank: false
  62. ,enableKeyEvents: true
  63. ,anchor: '100%'
  64. ,listeners: {
  65. 'keyup': {scope:this,fn:function(f,e) {
  66. Ext.getCmp('modx-dashboard-header').getEl().update(_('dashboard')+': '+f.getValue());
  67. }}
  68. }
  69. },{
  70. xtype: MODx.expandHelp ? 'label' : 'hidden'
  71. ,forId: 'modx-dashboard-name'
  72. ,html: _('dashboard_desc_name')
  73. ,cls: 'desc-under'
  74. },{
  75. name: 'description'
  76. ,id: 'modx-dashboard-description'
  77. ,xtype: 'textarea'
  78. ,fieldLabel: _('description')
  79. ,description: MODx.expandHelp ? '' : _('dashboard_desc_description')
  80. ,anchor: '100%'
  81. ,grow: true
  82. },{
  83. xtype: MODx.expandHelp ? 'label' : 'hidden'
  84. ,forId: 'modx-dashboard-description'
  85. ,html: _('dashboard_desc_description')
  86. ,cls: 'desc-under'
  87. }]
  88. },{
  89. columnWidth: .3
  90. ,cls: 'main-content'
  91. ,items: [{
  92. name: 'hide_trees'
  93. ,id: 'modx-dashboard-hide-trees'
  94. ,xtype: 'xcheckbox'
  95. ,boxLabel: _('dashboard_hide_trees')
  96. ,description: MODx.expandHelp ? '' : _('dashboard_desc_hide_trees')
  97. ,inputValue: 1
  98. },{
  99. xtype: MODx.expandHelp ? 'label' : 'hidden'
  100. ,forId: 'modx-dashboard-hide-trees'
  101. ,html: _('dashboard_desc_hide_trees')
  102. ,cls: 'desc-under'
  103. }]
  104. }]
  105. },{
  106. html: '<p>'+_('dashboard_widgets.intro_msg')+'</p>'
  107. ,xtype: 'modx-description'
  108. },{
  109. xtype: 'modx-grid-dashboard-widget-placements'
  110. ,preventRender: true
  111. ,dashboard: config.record.id
  112. ,autoHeight: true
  113. ,anchor: '100%'
  114. ,listeners: {
  115. 'afterRemoveRow': {fn:this.markDirty,scope:this}
  116. ,'updateRole': {fn:this.markDirty,scope:this}
  117. ,'addMember': {fn:this.markDirty,scope:this}
  118. }
  119. }]
  120. }]
  121. }]
  122. ,listeners: {
  123. 'setup': {fn:this.setup,scope:this}
  124. ,'success': {fn:this.success,scope:this}
  125. ,'beforeSubmit': {fn:this.beforeSubmit,scope:this}
  126. }
  127. });
  128. MODx.panel.Dashboard.superclass.constructor.call(this,config);
  129. };
  130. Ext.extend(MODx.panel.Dashboard,MODx.FormPanel,{
  131. initialized: false
  132. ,setup: function() {
  133. if (this.initialized) { return false; }
  134. if (Ext.isEmpty(this.config.record.id)) {
  135. this.fireEvent('ready');
  136. return false;
  137. }
  138. this.getForm().setValues(this.config.record);
  139. Ext.defer(function() {
  140. Ext.getCmp('modx-dashboard-header').update(_('dashboard')+': '+this.config.record.name);
  141. }, 250, this);
  142. /*
  143. var d = this.config.record.usergroups;
  144. var g = Ext.getCmp('modx-grid-dashboard-usergroups');
  145. if (d && g) {
  146. g.getStore().loadData(d);
  147. }*/
  148. var d = this.config.record.widgets;
  149. var g = Ext.getCmp('modx-grid-dashboard-widget-placements');
  150. if (d && g) {
  151. g.getStore().loadData(d);
  152. }
  153. this.fireEvent('ready',this.config.record);
  154. MODx.fireEvent('ready');
  155. this.initialized = true;
  156. }
  157. ,beforeSubmit: function(o) {
  158. var bp = {};
  159. var wg = Ext.getCmp('modx-grid-dashboard-widget-placements');
  160. if (wg) {
  161. bp['widgets'] = wg.encode();
  162. }
  163. Ext.apply(o.form.baseParams,bp);
  164. }
  165. ,success: function(o) {
  166. if (Ext.isEmpty(this.config.record) || Ext.isEmpty(this.config.record.id)) {
  167. MODx.loadPage('system/dashboards/update', 'id='+o.result.object.id);
  168. } else {
  169. Ext.getCmp('modx-abtn-save').setDisabled(false);
  170. var wg = Ext.getCmp('modx-grid-dashboard-widget-placements');
  171. if (wg) { wg.getStore().commitChanges(); }
  172. }
  173. }
  174. });
  175. Ext.reg('modx-panel-dashboard',MODx.panel.Dashboard);
  176. MODx.grid.DashboardWidgetPlacements = function(config) {
  177. config = config || {};
  178. this.exp = new Ext.grid.RowExpander({
  179. tpl : new Ext.Template(
  180. '<p class="desc">{description_trans}</p>'
  181. )
  182. });
  183. Ext.applyIf(config,{
  184. id: 'modx-grid-dashboard-widget-placements'
  185. ,url: MODx.config.connector_url
  186. ,action: 'system/dashboard/widget/placement/getList'
  187. ,fields: ['dashboard','widget','rank','name','name_trans','description','description_trans']
  188. ,autoHeight: true
  189. ,primaryKey: 'widget'
  190. ,cls: 'modx-grid modx-grid-draggable'
  191. ,plugins: [this.exp,new Ext.ux.dd.GridDragDropRowOrder({
  192. copy: false // false by default
  193. ,scrollable: true // enable scrolling support (default is false)
  194. ,targetCfg: {}
  195. ,listeners: {
  196. 'afterrowmove': {fn:this.onAfterRowMove,scope:this}
  197. }
  198. })]
  199. ,columns: [this.exp,{
  200. header: _('widget')
  201. ,dataIndex: 'name_trans'
  202. ,width: 600
  203. },{
  204. header: _('rank')
  205. ,dataIndex: 'rank'
  206. ,width: 80
  207. ,editor: { xtype: 'numberfield', allowBlank: false, allowNegative: false }
  208. }]
  209. ,tbar: [{
  210. text: _('widget_place')
  211. ,cls:'primary-button'
  212. ,handler: this.placeWidget
  213. ,scope: this
  214. }]
  215. });
  216. MODx.grid.DashboardWidgetPlacements.superclass.constructor.call(this,config);
  217. this.propRecord = Ext.data.Record.create(['dashboard','widget','rank','name','name_trans','description','description_trans']);
  218. };
  219. Ext.extend(MODx.grid.DashboardWidgetPlacements,MODx.grid.LocalGrid,{
  220. getMenu: function() {
  221. return [{
  222. text: _('widget_unplace')
  223. ,handler: this.unplaceWidget
  224. ,scope: this
  225. }];
  226. }
  227. ,onAfterRowMove: function(dt,sri,ri,sels) {
  228. var s = this.getStore();
  229. var sourceRec = s.data.items[sri];
  230. var total = s.data.length;
  231. sourceRec.set('rank',sri);
  232. sourceRec.commit();
  233. /* get all rows below ri, and up their rank by 1 */
  234. var brec;
  235. for (var x=(ri-1);x<total;x++) {
  236. brec = s.data.items[x];
  237. if (brec) {
  238. brec.set('rank',x);
  239. brec.commit();
  240. }
  241. }
  242. return true;
  243. }
  244. ,unplaceWidget: function(btn,e) {
  245. var rec = this.getSelectionModel().getSelected();
  246. var s = this.getStore();
  247. var idx = s.indexOf(rec);
  248. var total = s.getTotalCount();
  249. var r,x;
  250. for (x=idx;x<total;x++) {
  251. r = s.getAt(x);
  252. if (r) {
  253. r.set('rank',r.get('rank')-1);
  254. r.commit();
  255. }
  256. }
  257. s.remove(rec);
  258. }
  259. ,placeWidget: function(btn,e) {
  260. if (!this.windows.placeWidget) {
  261. this.windows.placeWidget = MODx.load({
  262. xtype: 'modx-window-dashboard-widget-place'
  263. ,listeners: {
  264. 'success': {fn:function(vs) {
  265. var rec = new this.propRecord(vs);
  266. this.getStore().add(rec);
  267. },scope:this}
  268. }
  269. });
  270. }
  271. this.windows.placeWidget.reset();
  272. this.windows.placeWidget.setValues({
  273. dashboard: this.config.dashboard
  274. });
  275. this.windows.placeWidget.show(btn);
  276. }
  277. });
  278. Ext.reg('modx-grid-dashboard-widget-placements',MODx.grid.DashboardWidgetPlacements);
  279. MODx.window.DashboardWidgetPlace = function(config) {
  280. config = config || {};
  281. this.ident = config.ident || 'dbugadd'+Ext.id();
  282. Ext.applyIf(config,{
  283. title: _('widget_place')
  284. // ,frame: true
  285. ,id: 'modx-window-dashboard-widget-place'
  286. ,fields: [{
  287. xtype: 'modx-combo-dashboard-widgets'
  288. ,fieldLabel: _('widget')
  289. ,name: 'widget'
  290. ,hiddenName: 'widget'
  291. ,id: 'modx-'+this.ident+'-widget'
  292. ,allowBlank: false
  293. ,msgTarget: 'under'
  294. ,anchor: '100%'
  295. }]
  296. });
  297. MODx.window.DashboardWidgetPlace.superclass.constructor.call(this,config);
  298. };
  299. Ext.extend(MODx.window.DashboardWidgetPlace,MODx.Window,{
  300. submit: function() {
  301. var f = this.fp.getForm();
  302. var fld = f.findField('widget');
  303. var g = Ext.getCmp('modx-grid-dashboard-widget-placements');
  304. var s = g.getStore();
  305. if (s.find('widget',fld.getValue()) != -1) {
  306. fld.markInvalid(_('dashboard_widget_err_placed'));
  307. return false;
  308. }
  309. var rank = s.data.length > 0
  310. // Get the rank of the last record
  311. ? s.data.items[s.data.length - 1].get('rank') + 1
  312. // Or set it to '0' if no record found
  313. : 0;
  314. var fldStore = fld.getStore();
  315. var fldRi = fldStore.find('id',fld.getValue());
  316. var rec = fldStore.getAt(fldRi);
  317. if (id != '' && this.fp.getForm().isValid()) {
  318. if (this.fireEvent('success',{
  319. widget: fld.getValue()
  320. ,dashboard: g.config.dashboard
  321. ,name: rec.data.name
  322. ,name_trans: rec.data.name_trans
  323. ,description: rec.data.description
  324. ,description_trans: rec.data.description_trans
  325. ,rank: rank
  326. })) {
  327. this.fp.getForm().reset();
  328. this.hide();
  329. return true;
  330. }
  331. } else {
  332. MODx.msg.alert(_('error'),_('widget_err_ns'));
  333. }
  334. return true;
  335. }
  336. });
  337. Ext.reg('modx-window-dashboard-widget-place',MODx.window.DashboardWidgetPlace);
  338. /*
  339. MODx.grid.DashboardUserGroups = function(config) {
  340. config = config || {};
  341. Ext.applyIf(config,{
  342. id: 'modx-grid-dashboard-usergroups'
  343. ,url: MODx.config.connector_url
  344. ,action: 'system/dashboard/group/getList'
  345. ,fields: ['id','name']
  346. ,autoHeight: true
  347. ,primaryKey: 'user'
  348. ,columns: [{
  349. header: _('user_group')
  350. ,dataIndex: 'name'
  351. ,width: 600
  352. }]
  353. ,tbar: [{
  354. text: _('dashboard_usergroup_add')
  355. ,handler: this.addUserGroup
  356. ,scope: this
  357. }]
  358. });
  359. MODx.grid.DashboardUserGroups.superclass.constructor.call(this,config);
  360. this.propRecord = Ext.data.Record.create(['id','name']);
  361. };
  362. Ext.extend(MODx.grid.DashboardUserGroups,MODx.grid.LocalGrid,{
  363. getMenu: function() {
  364. return [{
  365. text: _('dashboard_usergroup_remove')
  366. ,handler: this.remove.createDelegate(this,[{
  367. title: _('dashboard_usergroup_remove')
  368. ,text: _('dashboard_usergroup_remove_confirm')
  369. }])
  370. ,scope: this
  371. }];
  372. }
  373. ,addUserGroup: function(btn,e) {
  374. this.loadWindow(btn,e,{
  375. xtype: 'modx-window-dashboard-usergroup-add'
  376. ,listeners: {
  377. 'success': {fn:function(vs) {
  378. var rec = new this.propRecord(vs);
  379. this.getStore().add(rec);
  380. },scope:this}
  381. }
  382. });
  383. var w = Ext.getCmp('modx-window-dashboard-usergroup-add');
  384. w.reset();
  385. w.setValues({
  386. dashboard: this.config.dashboard
  387. });
  388. }
  389. });
  390. Ext.reg('modx-grid-dashboard-usergroups',MODx.grid.DashboardUserGroups);
  391. MODx.window.DashboardUserGroupAdd = function(config) {
  392. config = config || {};
  393. this.ident = config.ident || 'dbugadd'+Ext.id();
  394. Ext.applyIf(config,{
  395. title: _('dashboard_usergroup_add')
  396. ,frame: true
  397. ,id: 'modx-window-dashboard-usergroup-add'
  398. ,fields: [{
  399. xtype: 'modx-combo-usergroup'
  400. ,fieldLabel: _('user_group')
  401. ,name: 'usergroup'
  402. ,hiddenName: 'usergroup'
  403. ,id: 'modx-'+this.ident+'-usergroup'
  404. ,allowBlank: false
  405. }]
  406. });
  407. MODx.window.DashboardUserGroupAdd.superclass.constructor.call(this,config);
  408. };
  409. Ext.extend(MODx.window.DashboardUserGroupAdd,MODx.Window,{
  410. submit: function() {
  411. var f = this.fp.getForm();
  412. var fld = f.findField('usergroup');
  413. if (id != '' && this.fp.getForm().isValid()) {
  414. if (this.fireEvent('success',{
  415. id: fld.getValue()
  416. ,name: fld.getRawValue()
  417. })) {
  418. this.fp.getForm().reset();
  419. this.hide();
  420. return true;
  421. }
  422. } else {
  423. MODx.msg.alert(_('error'),_('user_group_err_ns'));
  424. }
  425. return true;
  426. }
  427. });
  428. Ext.reg('modx-window-dashboard-usergroup-add',MODx.window.DashboardUserGroupAdd);
  429. */
  430. MODx.combo.DashboardWidgets = function(config) {
  431. config = config || {};
  432. Ext.applyIf(config,{
  433. name: 'widget'
  434. ,hiddenName: 'widget'
  435. ,displayField: 'name_trans'
  436. ,valueField: 'id'
  437. ,fields: ['id','name','name_trans','description','description_trans']
  438. // ,listWidth: 400
  439. ,pageSize: 20
  440. ,url: MODx.config.connector_url
  441. ,baseParams: {
  442. action: 'system/dashboard/widget/getlist'
  443. ,combo: true
  444. }
  445. ,tpl: new Ext.XTemplate('<tpl for=".">'
  446. ,'<div class="x-combo-list-item">'
  447. ,'<h4 class="modx-combo-title">{name_trans:htmlEncode}</h4>'
  448. ,'<p class="modx-combo-desc">{description_trans:htmlEncode}</p>'
  449. ,'</div></tpl>')
  450. });
  451. MODx.combo.DashboardWidgets.superclass.constructor.call(this,config);
  452. };
  453. Ext.extend(MODx.combo.DashboardWidgets,MODx.combo.ComboBox);
  454. Ext.reg('modx-combo-dashboard-widgets',MODx.combo.DashboardWidgets);