Merge branch 'master' of https://git.tine20.org:443/git/tine20
[tine20] / tine20 / Calendar / js / iMIPDetailsPanel.js
1 /*
2  * Tine 2.0
3  * 
4  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
5  * @author      Cornelius Weiss <c.weiss@metaways.de>
6  * @copyright   Copyright (c) 2011 Metaways Infosystems GmbH (http://www.metaways.de)
7  */
8 Ext.ns('Tine.Calendar');
9
10 /**
11  * display panel for MIME type text/calendar
12  * 
13  * NOTE: this panel is registered on Tine.Calendar::init
14  * 
15  * @namespace   Tine.Calendar
16  * @class       Tine.Calendar.iMIPDetailsPanel
17  * @author      Cornelius Weiss <c.weiss@metaways.de>
18  * @constructor
19  */
20 Tine.Calendar.iMIPDetailsPanel = Ext.extend(Tine.Calendar.EventDetailsPanel, {
21     /**
22      * @cfg {Object} preparedPart
23      * server prepared text/calendar iMIP part 
24      */
25     preparedPart: null,
26     
27     /**
28      * @property actionToolbar
29      * @type Ext.Toolbar
30      */
31     actionToolbar: null,
32     
33     /**
34      * @property iMIPrecord
35      * @type Tine.Calendar.Model.iMIP
36      */
37     iMIPrecord: null,
38     
39     /**
40      * @property statusActions
41      * @type Array
42      */
43     statusActions:[],
44     
45     /**
46      * init this component
47      */
48     initComponent: function() {
49         try {
50             this.app = Tine.Tinebase.appMgr.get('Calendar');
51             
52             
53             this.iMIPrecord = new Tine.Calendar.Model.iMIP(this.preparedPart.preparedData);
54             if (! Ext.isFunction(this.iMIPrecord.get('event').beginEdit)) {
55                 this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
56                     responseText: Ext.util.JSON.encode(this.preparedPart.preparedData.event)
57                 }));
58             }
59             
60             this.initIMIPToolbar();
61             
62             this.on('afterrender', this.showIMIP, this);
63                 
64             Tine.Calendar.iMIPDetailsPanel.superclass.initComponent.call(this);
65         } catch (e) {
66             Tine.log.error('Tine.Calendar.iMIPDetailsPanel::initComponent');
67             Tine.log.error(e.stack ? e.stack : e);
68         }
69     },
70     
71     /**
72      * (re) prepare IMIP
73      */
74     prepareIMIP: function() {
75         this.iMIPclause.setText(this.app.i18n._('Checking Calendar Data...'));
76         
77         Tine.Calendar.iMIPPrepare(this.iMIPrecord.data, function(result, response) {
78             this.preparedPart.preparedData = result;
79             if (response.error) {
80                 // give up!
81                 this.iMIPrecord.set('preconditions', {'GENERIC': 'generic problem'});
82             } else {
83                 this.iMIPrecord = new Tine.Calendar.Model.iMIP(result);
84                 this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
85                     responseText: Ext.util.JSON.encode(result.event)
86                 }));
87             }
88             
89             this.showIMIP();
90         }, this);
91     },
92     
93     /**
94      * process IMIP
95      * 
96      * @param {String} status
97      */
98     processIMIP: function(status) {
99         Tine.log.debug('Tine.Calendar.iMIPDetailsPanel::processIMIP status: ' + status);
100         this.getLoadMask().show();
101         
102         Tine.Calendar.iMIPProcess(this.iMIPrecord.data, status, function(result, response) {
103             this.preparedPart.preparedData = result;
104             if (response.error) {
105                 // precondition changed?  
106                 return this.prepareIMIP();
107             }
108             
109             // load result
110             this.iMIPrecord = new Tine.Calendar.Model.iMIP(result);
111             this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
112                 responseText: Ext.util.JSON.encode(result.event)
113             }));
114             
115             this.showIMIP();
116         }, this);
117     },
118     
119     /**
120      * iMIP action toolbar
121      */
122     initIMIPToolbar: function() {
123         var singleRecordPanel = this.getSingleRecordPanel();
124         
125         this.actions = [];
126         this.statusActions = [];
127         
128         Tine.Tinebase.widgets.keyfield.StoreMgr.get('Calendar', 'attendeeStatus').each(function(status) {
129             // NEEDS-ACTION is not appropriate in iMIP context
130             if (status.id == 'NEEDS-ACTION') return;
131             
132             this.statusActions.push(new Ext.Action({
133                 text: status.get('i18nValue'),
134                 handler: this.processIMIP.createDelegate(this, [status.id]),
135                 icon: status.get('icon')
136             }));
137         }, this);
138         
139         this.actions = this.actions.concat(this.statusActions);
140         
141         // add more actions here (no spam / apply / crush / send event / ...)
142         
143         this.iMIPclause = new Ext.Toolbar.TextItem({
144             text: ''
145         });
146         this.tbar = this.actionToolbar = new Ext.Toolbar({
147             items: [{
148                     xtype: 'tbitem',
149                     cls: 'CalendarIconCls',
150                     width: 16,
151                     height: 16,
152                     style: 'margin: 3px 5px 2px 5px;'
153                 },
154                 this.iMIPclause,
155                 '->'
156             ].concat(this.actions)
157         });
158     },
159     
160     /**
161      * show/layout iMIP panel
162      */
163     showIMIP: function() {
164         try {
165             var singleRecordPanel = this.getSingleRecordPanel(),
166                 preconditions = this.iMIPrecord.get('preconditions'),
167                 method = this.iMIPrecord.get('method'),
168                 event = this.iMIPrecord.get('event'),
169                 myAttenderRecord = event.getMyAttenderRecord(),
170                 myAttenderstatus = myAttenderRecord ? myAttenderRecord.get('status') : null;
171                 
172             // reset actions
173             Ext.each(this.actions, function(action) {action.setHidden(true)});
174             
175             // check preconditions
176             if (preconditions) {
177                 if (preconditions.hasOwnProperty('EVENTEXISTS')) {
178                     this.iMIPclause.setText(this.app.i18n._("The event of this message does not exist"));
179                 }
180                 
181                 else if (preconditions.hasOwnProperty('ORIGINATOR')) {
182                     // display spam box -> might be accepted by user?
183                     this.iMIPclause.setText(this.app.i18n._("The sender is not authorised to update the event"));
184                 }
185                 
186                 else if (preconditions.hasOwnProperty('RECENT')) {
187     //            else if (preconditions.hasOwnProperty('TOPROCESS')) {
188                     this.iMIPclause.setText(this.app.i18n._("This message is already processed"));
189                 }
190                 
191                 else if (preconditions.hasOwnProperty('ATTENDEE')) {
192                     // party crush button?
193                     this.iMIPclause.setText(this.app.i18n._("You are not an attendee of this event"));
194                 } 
195                 
196                 else {
197                     this.iMIPclause.setText(this.app.i18n._("Unsupported message"));
198                 }
199             } 
200             
201             // method specific text / actions
202             else {
203                 switch (method) {
204                     case 'REQUEST':
205                         if (! myAttenderRecord) {
206                             // might happen in shared folders -> we might want to become a party crusher?
207                             this.iMIPclause.setText(this.app.i18n._("This is an event invitation for someone else."));
208                         } else if (myAttenderstatus !== 'NEEDS-ACTION') {
209                             this.iMIPclause.setText(this.app.i18n._("You have already replied to this event invitation."));
210                         } else {
211                             this.iMIPclause.setText(this.app.i18n._('You received an event invitation. Set your response to:'));
212                             Ext.each(this.statusActions, function(action) {action.setHidden(false)});
213                         }
214                         break;
215                         
216                         
217                     case 'REPLY':
218                         // Someone replied => autoprocessing atm.
219                         this.iMIPclause.setText(this.app.i18n._('An invited attendee responded to the invitation.'));
220                         break;
221                         
222                     default:            
223                         this.iMIPclause.setText(this.app.i18n._("Unsupported method"));
224                         break;
225                 }
226             }
227             
228             this.getLoadMask().hide();
229             singleRecordPanel.setVisible(true);
230             singleRecordPanel.setHeight(150);
231             
232             
233             this.record = event;
234             singleRecordPanel.loadRecord(event);
235         } catch (e) {
236             Tine.log.error('Tine.Calendar.iMIPDetailsPanel::showIMIP');
237             Tine.log.error(e.stack ? e.stack : e);
238             
239             singleRecordPanel.setVisible(false);
240         }
241         
242     }
243
244 });