Merge branch '2013.03'
[tine20] / tine20 / Admin / js / Applications.js
1 /*
2  * Tine 2.0
3  * 
4  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
5  * @author      Philipp Schüle <p.schuele@metaways.de>
6  * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
7  *
8  * TODO         refactor this
9  * TODO         translate strings (enable/disable/settings)
10  */
11  
12 Ext.ns('Tine.Admin', 'Tine.Admin.Applications');
13
14 /*********************************** MAIN DIALOG ********************************************/
15
16 Tine.Admin.Applications.Main = function() {
17
18     // references to created toolbar and grid panel
19     var applicationToolbar = null;
20     var grid_applications = null;
21     
22     /**
23      * onclick handler for edit action
24      * 
25      * TODO     make that more generic?
26      */
27     var _settingsHandler = function(_button, _event) {
28         var selModel = Ext.getCmp('gridAdminApplications').getSelectionModel();
29         if (selModel.getCount() > 0) {
30             var selectedRows = selModel.getSelections();
31             var appName = selectedRows[0].data.name;
32             if (Tine[appName]) {
33                 _openSettingsWindow(appName);
34             }
35         } else {
36             _button.setDisabled(true);
37         }
38     };
39     
40     var _openSettingsWindow = function(appName) {
41         var translation = new Locale.Gettext();
42         translation.textdomain('Admin');
43         Tine[appName].AdminPanel.openWindow({
44             record: (Tine[appName].Model.Settings) ? new Tine[appName].Model.Settings(appName) : null,
45             title: String.format(translation.gettext('{0} Settings'), translateAppTitle(appName)),
46             listeners: {
47                 scope: this,
48                 'update': (Tine[appName].AdminPanel.onUpdate) ? Tine[appName].AdminPanel.onUpdate : Ext.emptyFn
49             }
50         });
51     }
52
53     var _enableDisableButtonHandler = function(state) {
54         var applicationIds = new Array();
55         var selectedRows = Ext.getCmp('gridAdminApplications').getSelectionModel().getSelections();
56         for (var i = 0; i < selectedRows.length; ++i) {
57             applicationIds.push(selectedRows[i].id);
58         }
59         
60         Ext.Ajax.request({
61             url : 'index.php',
62             method : 'post',
63             params : {
64                 method : 'Admin.setApplicationState',
65                 applicationIds : applicationIds,
66                 state: state
67             },
68             callback : function(_options, _success, _response) {
69                 if(_success === true) {
70                     var result = Ext.util.JSON.decode(_response.responseText);
71                     if(result.success === true) {
72                         // reload mainscreen because apps have to be loaded / unloaded
73                         Tine.Tinebase.ApplicationStarter.init();
74                         window.location = window.location.href.replace(/#+.*/, '');
75                     }
76                 }
77             }
78         });
79     };
80     
81     var translation = new Locale.Gettext();
82     translation.textdomain('Admin');
83     
84     var _action_enable = new Ext.Action({
85         text: translation.gettext('Enable Application'),
86         disabled: true,
87         handler: _enableDisableButtonHandler.createDelegate(this, ['enabled']),
88         iconCls: 'action_enable'
89     });
90
91     var _action_disable = new Ext.Action({
92         text: translation.gettext('Disable Application'),
93         disabled: true,
94         handler: _enableDisableButtonHandler.createDelegate(this, ['disabled']),
95         iconCls: 'action_disable'
96     });
97
98     var _action_settings = new Ext.Action({
99         text: translation.gettext('Settings'),
100         disabled: true,
101         handler: _settingsHandler,
102         iconCls: 'action_settings'
103     });
104
105     var _createApplicationaDataStore = function()
106     {
107         /**
108          * the datastore for lists
109          */
110         var ds_applications = new Ext.data.JsonStore({
111             url: 'index.php',
112             baseParams: {
113                 method: 'Admin.getApplications'
114             },
115             root: 'results',
116             totalProperty: 'totalcount',
117             id: 'id',
118             fields: Tine.Admin.Model.Application,
119             // turn on remote sorting
120             remoteSort: true
121         });
122         
123         ds_applications.setDefaultSort('name', 'asc');
124
125         ds_applications.on('beforeload', function(_dataSource, _options) {
126             _options = _options || {};
127             _options.params = _options.params || {};
128             _options.params.filter = Ext.getCmp('ApplicationsAdminQuickSearchField').getValue();
129         });
130         
131         //ds_applications.load({params:{start:0, limit:50}});
132         
133         return ds_applications;
134     };
135
136     var _showApplicationsToolbar = function()
137     {
138         // if toolbar was allready created set active toolbar and return
139         if (applicationToolbar)
140         {
141             Tine.Tinebase.MainScreen.setActiveToolbar(applicationToolbar, true);
142             return;
143         }
144         
145         this.translation = new Locale.Gettext();
146         this.translation.textdomain('Admin');
147         
148         _action_enable.setText(this.translation.gettext('enable application'));
149         _action_disable.setText(this.translation.gettext('disable application'));
150         //_action_settings.setText(this.translation.gettext('settings'));
151     
152         var ApplicationsAdminQuickSearchField = new Ext.ux.SearchField({
153             id: 'ApplicationsAdminQuickSearchField',
154             width:240,
155             emptyText: Tine.Tinebase.translation._hidden('enter searchfilter')
156         });
157         ApplicationsAdminQuickSearchField.on('change', function() {
158             Ext.getCmp('gridAdminApplications').getStore().load({params:{start:0, limit:50}});
159         });
160         
161         applicationToolbar = new Ext.Toolbar({
162             id: 'toolbarAdminApplications',
163             split: false,
164             //height: 26,
165             items: [{
166                 xtype: 'buttongroup',
167                 columns: 7,
168                 items: [
169                     Ext.apply(new Ext.Button(_action_enable), {
170                     scale: 'medium',
171                     rowspan: 2,
172                     iconAlign: 'top'
173                     }), {xtype: 'tbspacer', width: 10},
174                     Ext.apply(new Ext.Button(_action_disable), {
175                         scale: 'medium',
176                         rowspan: 2,
177                         iconAlign: 'top'
178                     }), {xtype: 'tbspacer', width: 10},
179                     {xtype: 'tbseparator'}, {xtype: 'tbspacer', width: 10},
180                     Ext.apply(new Ext.Button(_action_settings), {
181                         scale: 'medium',
182                         rowspan: 2,
183                         iconAlign: 'top'
184                     })
185                 ]
186             }, '->',
187                 this.translation.gettext('Search:'), ' ',
188 //                new Ext.ux.SelectBox({
189 //                    listClass:'x-combo-list-small',
190 //                      width:90,
191 //                      value:'Starts with',
192 //                      id:'search-type',
193 //                      store: new Ext.data.SimpleStore({
194 //                        fields: ['text'],
195 //                        expandData: true,
196 //                        data : ['Starts with', 'Ends with', 'Any match']
197 //                      }),
198 //                      displayField: 'text'
199 //                }),
200                 ' ',
201                 ApplicationsAdminQuickSearchField
202             ]
203         });
204         
205         Tine.Tinebase.MainScreen.setActiveToolbar(applicationToolbar, true);
206     };
207     
208     /**
209      * translate and return app title
210      * 
211      * TODO try to generalize this fn as this gets used in Tags.js + RoleEditDialog.js as well 
212      *      -> this could be moved to Tine.Admin.Application after Admin js refactoring
213      */
214     var translateAppTitle = function(appName) {
215         var app = Tine.Tinebase.appMgr.get(appName);
216         return (app) ? app.getTitle() : appName;
217     };
218
219     /**
220      * render enabled field (translate)
221      */
222     var _renderEnabled = function(_value, _cellObject, _record, _rowIndex, _colIndex, _dataStore) {
223         var translation = new Locale.Gettext();
224         translation.textdomain('Admin');
225         
226         var gridValue;
227         
228         switch(_value) {
229             case 'disabled':
230                 gridValue = translation.gettext('disabled');
231                 break;
232             case 'enabled':
233               gridValue = translation.gettext('enabled');
234               break;
235               
236             default:
237               gridValue = String.format(translation.gettext('unknown status ({0})'), value);
238               break;
239         }
240         
241         return gridValue;
242     };
243
244     /**
245      * creates the address grid
246      * 
247      */
248     var _showApplicationsGrid = function() 
249     {
250         // if grid panel was allready created set active content panel and return
251         if (grid_applications) {
252             Tine.Tinebase.MainScreen.setActiveContentPanel(grid_applications, true);
253             return;
254         }
255         
256         var ctxMenuGrid = new Ext.menu.Menu({
257             items: [
258                 _action_enable,
259                 _action_disable,
260                 _action_settings
261             ]
262         });
263
264         
265         var ds_applications = _createApplicationaDataStore();
266         
267         var pagingToolbar = new Ext.PagingToolbar({ // inline paging toolbar
268             pageSize: 50,
269             store: ds_applications,
270             displayInfo: true,
271             displayMsg: this.translation.gettext('Displaying application {0} - {1} of {2}'),
272             emptyMsg: this.translation.gettext("No applications to display")
273         });
274         
275         var cm_applications = new Ext.grid.ColumnModel({
276             defaults: {
277                 sortable: true,
278                 resizable: true
279             },
280             columns: [
281                 { header: this.translation.gettext('Order'),   id: 'order', dataIndex: 'order', width: 50},
282                 { header: this.translation.gettext('Name'),    id: 'name', dataIndex: 'name', renderer: translateAppTitle},
283                 { header: this.translation.gettext('Status'),  id: 'status', dataIndex: 'status', width: 150, renderer: _renderEnabled},
284                 { header: this.translation.gettext('Version'), id: 'version', dataIndex: 'version', width: 70}
285             ]
286         });
287
288         var rowSelectionModel = new Ext.grid.RowSelectionModel({multiSelect:true});
289         
290         rowSelectionModel.on('selectionchange', function(_selectionModel) {
291             var rowCount = _selectionModel.getCount();
292             var selected = _selectionModel.getSelections();
293
294             if ( Tine.Tinebase.common.hasRight('manage', 'Admin', 'apps') ) {
295                 if (rowCount < 1) {
296                     _action_enable.setDisabled(true);
297                     _action_disable.setDisabled(true);
298                     _action_settings.setDisabled(true);
299                 } else if (rowCount > 1) {
300                     _action_enable.setDisabled(false);
301                     _action_disable.setDisabled(false);
302                     _action_settings.setDisabled(true);
303                 } else {
304                     _action_enable.setDisabled(false);
305                     _action_disable.setDisabled(false);
306                     // check if app has admin panel and is enabled
307                     if (Tine[selected[0].data.name] && Tine[selected[0].data.name].AdminPanel && selected[0].data.status == 'enabled') {
308                         _action_settings.setDisabled(false);
309                     } else {
310                         _action_settings.setDisabled(true);
311                     }
312                 }
313                 
314                 // don't allow to disable Admin, Tinebase or Addressbook as we can't deal with this yet
315                 for (var i=0; i<selected.length; i++) {
316                     if (typeof selected[i].get == 'function' && selected[i].get('name').toString().match(/Tinebase|Admin|Addressbook/)) {
317                         _action_enable.setDisabled(true);
318                         _action_disable.setDisabled(true);
319                         break;
320                     }
321                 }
322             }
323         });
324                 
325         grid_applications = new Ext.grid.GridPanel({
326             id: 'gridAdminApplications',
327             store: ds_applications,
328             cm: cm_applications,
329             tbar: pagingToolbar,     
330             autoSizeColumns: false,
331             selModel: rowSelectionModel,
332             enableColLock:false,
333             autoExpandColumn: 'name',
334             border: false,
335             viewConfig: {
336                 /**
337                  * Return CSS class to apply to rows depending upon flags
338                  * - checks Flagged, Deleted and Seen
339                  * 
340                  * @param {} record
341                  * @param {} index
342                  * @return {String}
343                  */
344                 getRowClass: function(record, index) {
345                     //console.log(record);
346                     var className = '';
347                     switch(record.get('status')) {
348                         case 'disabled':
349                             className = 'grid_row_disabled';
350                             break;
351                         case 'enabled':
352                             className = 'grid_row_enabled';
353                             break;
354                     }
355                     return className;
356                 }
357             }
358         });
359         
360         Tine.Tinebase.MainScreen.setActiveContentPanel(grid_applications, true);
361         
362         grid_applications.on('rowcontextmenu', function(_grid, _rowIndex, _eventObject) {
363             _eventObject.stopEvent();
364             if(!_grid.getSelectionModel().isSelected(_rowIndex)) {
365                 _grid.getSelectionModel().selectRow(_rowIndex);
366
367                 if ( Tine.Tinebase.common.hasRight('manage', 'Admin', 'apps') ) {
368                     _action_enable.setDisabled(false);
369                     _action_disable.setDisabled(false);
370                 }
371                 
372                 // don't allow to disable Admin, Tinebase or Addressbook as we can't deal with this yet
373                 if(_grid.getSelectionModel().getSelected().get('name').toString().match(/Tinebase|Admin|Addressbook/)) {
374                     _action_enable.setDisabled(true);
375                     _action_disable.setDisabled(true);
376                 }
377             }
378             ctxMenuGrid.showAt(_eventObject.getXY());
379         }, this);
380         
381         grid_applications.on('rowdblclick', function(grid, index, e) {
382             var record = grid.getStore().getAt(index);
383             if (Tine[record.data.name].AdminPanel && record.data.status == 'enabled') {
384                 _openSettingsWindow(record.data.name);
385             }
386         }, this);
387           
388         return;
389     };
390     
391     // public functions and variables
392     return {
393         show: function() 
394         {
395             _showApplicationsToolbar();
396             _showApplicationsGrid();
397             
398             this.loadData();
399         },
400         
401         loadData: function()
402         {
403             var dataStore = Ext.getCmp('gridAdminApplications').getStore();
404             dataStore.load({ params: { start:0, limit:50 } });
405         },
406         
407         reload: function() 
408         {
409             if(Ext.ComponentMgr.all.containsKey('gridAdminApplications')) {
410                 setTimeout ("Ext.getCmp('gridAdminApplications').getStore().reload()", 200);
411             }
412         }
413     };
414     
415 }();