modx.grid.message.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /**
  2. * Loads the panel for managing user messages.
  3. *
  4. * @class MODx.panel.Messages
  5. * @extends MODx.FormPanel
  6. * @param {Object} config An object of configuration properties
  7. * @xtype modx-panel-messages
  8. */
  9. MODx.panel.Messages = function(config) {
  10. config = config || {};
  11. Ext.applyIf(config,{
  12. id: 'modx-panel-message'
  13. ,cls: 'container'
  14. ,bodyStyle: ''
  15. ,defaults: { collapsible: false ,autoHeight: true }
  16. ,url: MODx.config.connector_url
  17. ,baseParams: {
  18. action: 'security/message/getlist'
  19. }
  20. ,items: [{
  21. html: _('messages')
  22. ,id: 'modx-messages-header'
  23. ,xtype: 'modx-header'
  24. },MODx.getPageStructure([{
  25. title: _('messages')
  26. ,id: 'modx-messages-tab'
  27. ,autoHeight: true
  28. ,layout: 'form'
  29. ,defaults: { border: false ,msgTarget: 'side' }
  30. ,items: [{
  31. layout: 'form'
  32. ,autoHeight: true
  33. ,defaults: { border: false }
  34. ,items: [{
  35. html: '<p>' + _('messages_desc') + '</p>'
  36. ,id: 'modx-messages-msg'
  37. ,xtype: 'modx-description'
  38. },{
  39. xtype: 'modx-grid-message'
  40. ,cls: 'main-wrapper'
  41. ,user: config.user
  42. ,preventRender: true
  43. }]
  44. }]
  45. }])]
  46. });
  47. MODx.panel.Messages.superclass.constructor.call(this,config);
  48. };
  49. Ext.extend(MODx.panel.Messages,MODx.FormPanel);
  50. Ext.reg('modx-panel-messages',MODx.panel.Messages);
  51. /**
  52. * Loads a grid of Messages.
  53. *
  54. * @class MODx.grid.Message
  55. * @extends MODx.grid.Grid
  56. * @param {Object} config An object of options.
  57. * @xtype modx-grid-message
  58. */
  59. MODx.grid.Message = function(config) {
  60. config = config || {};
  61. this.exp = new Ext.grid.RowExpander({
  62. tpl : new Ext.Template(
  63. '<span style="float: right;">'
  64. ,'<i>'+_('sent_by')+': {sender_name:this.htmlEncode} <br />'+_('sent_on')+': {date_sent}</i><br /><br />'
  65. ,'</span>'
  66. ,'<h3>{subject:this.htmlEncode}</h3>'
  67. ,'<p>{message:this.htmlEncode}</p>'
  68. , {
  69. htmlEncode: function(value){
  70. return Ext.util.Format.htmlEncode(value);
  71. }
  72. }
  73. )
  74. });
  75. this.exp.on('expand',this.read,this);
  76. var disabled = !(MODx.perm.view_user || MODx.perm.view_role || MODx.perm.view_usergroup)
  77. Ext.applyIf(config,{
  78. title: _('messages')
  79. ,id: 'modx-grid-message'
  80. ,url: MODx.config.connector_url
  81. ,baseParams: {
  82. action: 'security/message/getlist'
  83. }
  84. ,fields: ['id','type','subject','message','sender','recipient','private'
  85. ,'date_sent','read','sender_name','recipient_name']
  86. ,autosave: true
  87. ,paging: true
  88. ,plugins: this.exp
  89. ,columns: [this.exp,{
  90. header: _('id')
  91. ,dataIndex: 'id'
  92. ,width: 30
  93. },{
  94. header: _('subject')
  95. ,dataIndex: 'subject'
  96. ,width: 200
  97. ,renderer: Ext.util.Format.htmlEncode
  98. },{
  99. header: _('sender')
  100. ,dataIndex: 'sender_name'
  101. ,width: 120
  102. ,renderer: Ext.util.Format.htmlEncode
  103. },{
  104. header: _('recipient')
  105. ,dataIndex: 'recipient_name'
  106. ,width: 120
  107. ,renderer: Ext.util.Format.htmlEncode
  108. },{
  109. header: _('date_sent')
  110. ,dataIndex: 'date_sent'
  111. ,width: 150
  112. },{
  113. header: _('read')
  114. ,dataIndex: 'read'
  115. ,width: 100
  116. ,editor: { xtype: 'combo-boolean' ,renderer: 'boolean' }
  117. ,editable: false
  118. }]
  119. ,tbar: [{
  120. text: _('message_new')
  121. ,cls:'primary-button'
  122. ,disabled: disabled
  123. ,scope: this
  124. ,handler: this.newMessage
  125. },'->',{
  126. xtype: 'modx-combo-message-type'
  127. ,name: 'type'
  128. ,id: 'modx-messages-filter'
  129. ,emptyText: _('filter_by_type')
  130. ,allowBlank: false
  131. ,editable: false
  132. ,typeAhead: false
  133. ,forceSelection: true
  134. // ,value: 'inbox'
  135. ,width: 200
  136. ,listeners: {
  137. 'select': {fn: this.filterByType, scope: this}
  138. }
  139. },{
  140. xtype: 'textfield'
  141. ,name: 'search'
  142. ,id: 'modx-messages-search'
  143. ,cls: 'x-form-filter'
  144. ,emptyText: _('search_ellipsis')
  145. ,listeners: {
  146. 'change': {fn: this.search, scope: this}
  147. ,'render': {fn: function(cmp) {
  148. new Ext.KeyMap(cmp.getEl(), {
  149. key: Ext.EventObject.ENTER
  150. ,fn: this.blur
  151. ,scope: cmp
  152. });
  153. },scope:this}
  154. }
  155. },{
  156. xtype: 'button'
  157. ,id: 'modx-filter-clear'
  158. ,cls: 'x-form-filter-clear'
  159. ,text: _('filter_clear')
  160. ,listeners: {
  161. 'click': {fn: this.clearFilter, scope: this},
  162. 'mouseout': { fn: function(evt){
  163. this.removeClass('x-btn-focus');
  164. }
  165. }
  166. }
  167. }]
  168. });
  169. MODx.grid.Message.superclass.constructor.call(this,config);
  170. };
  171. Ext.extend(MODx.grid.Message,MODx.grid.Grid,{
  172. read: function(exp,rec,body,ri) {
  173. var r = rec.data;
  174. if (r.read) return false;
  175. MODx.Ajax.request({
  176. url: this.config.url
  177. ,params: {
  178. action: 'security/message/read'
  179. ,id: r.id
  180. }
  181. ,listeners: {
  182. 'success': {fn:function(r) {
  183. var r2 = this.getStore().getAt(ri);
  184. r2.set('read',true);
  185. r2.commit();
  186. this.exp.expandRow(ri);
  187. },scope:this}
  188. }
  189. });
  190. }
  191. ,markUnread: function(btn,e) {
  192. var rec = this.getSelectionModel().getSelected();
  193. MODx.Ajax.request({
  194. url: this.config.url
  195. ,params: {
  196. action: 'security/message/unread'
  197. ,id: rec.data.id
  198. }
  199. ,listeners: {
  200. 'success': {fn:function(r) {
  201. rec.set('read',false);
  202. rec.commit();
  203. },scope:this}
  204. }
  205. });
  206. }
  207. ,getMenu: function() {
  208. var r = this.getSelectionModel().getSelected();
  209. var m = [{
  210. text: _('reply')
  211. ,scope: this
  212. ,handler: this.reply
  213. },{
  214. text: _('forward')
  215. ,scope: this
  216. ,handler: this.forward
  217. }];
  218. if (r.data.read && MODx.user.id != r.data.sender) {
  219. m.push({
  220. text: _('mark_unread')
  221. ,handler: this.markUnread
  222. });
  223. m.push('-');
  224. }
  225. if (MODx.user.id != r.data.sender) {
  226. m.push({
  227. text: _('delete')
  228. ,handler: this.remove.createDelegate(this, ['message_remove_confirm', 'security/message/remove'])
  229. });
  230. }
  231. return m;
  232. }
  233. ,reply: function(btn,e) {
  234. this.menu.record = {
  235. type: 'user'
  236. ,user: this.menu.record.sender
  237. ,subject: 'RE: ' + this.menu.record.subject
  238. ,message: ''
  239. };
  240. this.loadWindow(btn,e,{
  241. xtype: 'modx-window-message-create'
  242. });
  243. }
  244. ,forward: function(btn,e) {
  245. this.menu.record = {
  246. type: 'user'
  247. ,user: ''
  248. ,subject: 'Fwd: ' + this.menu.record.subject
  249. ,message: "\r\n--\r\n" + this.menu.record.message
  250. };
  251. this.loadWindow(btn,e,{
  252. xtype: 'modx-window-message-create'
  253. });
  254. }
  255. ,newMessage: function(btn,e) {
  256. this.menu.record = {
  257. type: 'user'
  258. ,user: ''
  259. ,subject: ''
  260. ,message: ''
  261. };
  262. this.loadWindow(btn,e,{
  263. xtype: 'modx-window-message-create'
  264. });
  265. }
  266. ,filterByType: function (combo) {
  267. this.getStore().baseParams.type = combo.getValue();
  268. this.getBottomToolbar().changePage(1);
  269. }
  270. ,search: function(tf,newValue) {
  271. var nv = newValue || tf;
  272. this.getStore().baseParams.search = Ext.isEmpty(nv) || Ext.isObject(nv) ? '' : nv;
  273. this.getBottomToolbar().changePage(1);
  274. return true;
  275. }
  276. ,clearFilter: function() {
  277. this.getStore().baseParams = {
  278. action: 'security/message/getList'
  279. };
  280. Ext.getCmp('modx-messages-search').reset();
  281. Ext.getCmp('modx-messages-filter').reset();
  282. this.getBottomToolbar().changePage(1);
  283. }
  284. });
  285. Ext.reg('modx-grid-message',MODx.grid.Message);
  286. /**
  287. * Generates the new message window.
  288. *
  289. * @class MODx.window.CreateMessage
  290. * @extends MODx.Window
  291. * @param {Object} config An object of options.
  292. * @xtype modx-window-message-create
  293. */
  294. MODx.window.CreateMessage = function(config) {
  295. config = config || {};
  296. Ext.applyIf(config,{
  297. title: _('message_create')
  298. ,url: MODx.config.connector_url
  299. ,action: 'security/message/create'
  300. ,fields: this.getFields()
  301. ,keys: []
  302. });
  303. MODx.window.CreateMessage.superclass.constructor.call(this,config);
  304. this.on('show',function() {
  305. this.fp.getForm().findField('type').fireEvent('select');
  306. },this);
  307. };
  308. Ext.extend(MODx.window.CreateMessage,MODx.Window,{
  309. tps: ['user','usergroup','role','all']
  310. ,getFields: function() {
  311. var data = [];
  312. if (MODx.perm.view_user) data.push(['user',_('user')]);
  313. if (MODx.perm.view_usergroup) data.push(['usergroup',_('usergroup')]);
  314. if (MODx.perm.view_role) data.push(['role',_('role')]);
  315. if (MODx.perm.view_user) data.push(['all',_('all')]);
  316. var items = [{
  317. xtype: 'combo'
  318. ,fieldLabel: _('recipient_type')
  319. ,name: 'type'
  320. ,hiddenName: 'type'
  321. ,store: new Ext.data.SimpleStore({
  322. fields: ['type','disp']
  323. ,data: data
  324. })
  325. ,mode: 'local'
  326. ,triggerAction: 'all'
  327. ,displayField: 'disp'
  328. ,valueField: 'type'
  329. ,editable: false
  330. ,value: data[0][0]
  331. ,listeners: {
  332. 'select': {fn:this.showRecipient,scope:this}
  333. }
  334. ,anchor: '100%'
  335. }];
  336. if (MODx.perm.view_user) items.push({
  337. xtype: 'modx-combo-user'
  338. ,id: 'mc-recipient-user'
  339. ,fieldLabel: _('user')
  340. ,allowBlank: true
  341. ,anchor: '100%'
  342. });
  343. if (MODx.perm.view_usergroup) items.push({
  344. xtype: 'modx-combo-usergroup'
  345. ,id: 'mc-recipient-usergroup'
  346. ,fieldLabel: _('usergroup')
  347. ,allowBlank: true
  348. ,anchor: '100%'
  349. });
  350. if (MODx.perm.view_role) items.push({
  351. xtype: 'modx-combo-role'
  352. ,id: 'mc-recipient-role'
  353. ,fieldLabel: _('role')
  354. ,allowBlank: true
  355. ,anchor: '100%'
  356. });
  357. if (MODx.perm.view_user) items.push({
  358. xtype: 'hidden'
  359. ,id: 'mc-recipient-all'
  360. ,name: 'all'
  361. ,fieldLabel: _('all')
  362. ,value: 'all'
  363. });
  364. items.push( [{
  365. xtype: 'textfield'
  366. ,fieldLabel: _('subject')
  367. ,name: 'subject'
  368. ,maxLength: 255
  369. ,anchor: '100%'
  370. },{
  371. xtype: 'textarea'
  372. ,fieldLabel: _('message')
  373. ,name: 'message'
  374. ,anchor: '100%'
  375. ,grow: true
  376. },{
  377. xtype: 'xcheckbox'
  378. ,name: 'sendemail'
  379. ,boxLabel: _('message_send_email')
  380. ,hideLabel: true
  381. ,inputValue: 0
  382. ,checked: false
  383. }]);
  384. return items;
  385. }
  386. ,showRecipient: function(cb,rec,i) {
  387. var form = this.fp.getForm();
  388. for (var x=0;x<this.tps.length;x++) {
  389. var f = form.findField('mc-recipient-'+this.tps[x]);
  390. if (f) { this.hideField(f); }
  391. }
  392. var type = rec ? rec.data.type : 'user';
  393. var fd = form.findField('mc-recipient-'+type);
  394. if (fd) { this.showField(fd);}
  395. }
  396. });
  397. Ext.reg('modx-window-message-create',MODx.window.CreateMessage);
  398. /**
  399. * Select Box with types of messages for showing to user.
  400. *
  401. * @class MODx.combo.MessageType
  402. * @extends MODx.Window
  403. * @param {Object} config An object of options.
  404. * @xtype modx-combo-message-type
  405. */
  406. MODx.combo.MessageType = function(config) {
  407. config = config || {};
  408. Ext.applyIf(config,{
  409. store: new Ext.data.SimpleStore({
  410. fields: ['d', 'v'],
  411. data: [
  412. [_('messages_inbox'), 'inbox'],
  413. [_('messages_outbox'), 'outbox']
  414. ]
  415. })
  416. ,displayField: 'd'
  417. ,valueField: 'v'
  418. ,mode: 'local'
  419. ,editable: false
  420. ,selectOnFocus: false
  421. ,preventRender: true
  422. ,forceSelection: true
  423. ,enableKeyEvents: true
  424. ,allowBlank: false
  425. });
  426. MODx.combo.MessageType.superclass.constructor.call(this, config);
  427. };
  428. Ext.extend(MODx.combo.MessageType, MODx.combo.ComboBox);
  429. Ext.reg('modx-combo-message-type', MODx.combo.MessageType);