Merge branch 'master' of https://git.tine20.org/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         this.app = Tine.Tinebase.appMgr.get('Calendar');
50         
51         
52         this.iMIPrecord = new Tine.Calendar.Model.iMIP(this.preparedPart.preparedData);
53         if (! Ext.isFunction(this.iMIPrecord.get('event').beginEdit)) {
54             this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
55                 responseText: Ext.util.JSON.encode(this.preparedPart.preparedData.event)
56             }));
57         }
58         
59         this.initIMIPToolbar();
60         
61         this.on('afterrender', this.showIMIP, this);
62             
63         Tine.Calendar.iMIPDetailsPanel.superclass.initComponent.call(this);
64     },
65     
66     /**
67      * (re) prepare IMIP
68      */
69     prepareIMIP: function() {
70         this.iMIPclause.setText(this.app.i18n._('Checking Calendar Data...'));
71         
72         Tine.Calendar.iMIPPrepare(this.iMIPrecord.data, function(result, response) {
73             this.preparedPart.preparedData = result;
74             if (response.error) {
75                 // give up!
76                 this.iMIPrecord.set('preconditions', {'GENERIC': 'generic problem'});
77             } else {
78                 this.iMIPrecord = new Tine.Calendar.Model.iMIP(result);
79                 this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
80                     responseText: Ext.util.JSON.encode(result.event)
81                 }));
82             }
83             
84             this.showIMIP();
85         }, this);
86     },
87     
88     /**
89      * process IMIP
90      * 
91      * @param {String} status
92      */
93     processIMIP: function(status) {
94         Tine.log.debug('Tine.Calendar.iMIPDetailsPanel::processIMIP status: ' + status);
95         this.getLoadMask().show();
96         
97         Tine.Calendar.iMIPProcess(this.iMIPrecord.data, status, function(result, response) {
98             this.preparedPart.preparedData = result;
99             if (response.error) {
100                 // precondition changed?  
101                 return this.prepareIMIP();
102             }
103             
104             // load result
105             this.iMIPrecord = new Tine.Calendar.Model.iMIP(result);
106             this.iMIPrecord.set('event', Tine.Calendar.backend.recordReader({
107                 responseText: Ext.util.JSON.encode(result.event)
108             }));
109             
110             this.showIMIP();
111         }, this);
112     },
113     
114     /**
115      * iMIP action toolbar
116      */
117     initIMIPToolbar: function() {
118         var singleRecordPanel = this.getSingleRecordPanel();
119         
120         this.actions = [];
121         this.statusActions = [];
122         
123         Tine.Calendar.Model.Attender.getAttendeeStatusStore().each(function(status) {
124             // NEEDS-ACTION is not appropriate in iMIP context
125             if (status.id == 'NEEDS-ACTION') return;
126             
127             this.statusActions.push(new Ext.Action({
128                 text: status.get('status_name'),
129                 handler: this.processIMIP.createDelegate(this, [status.id]),
130                 iconCls: 'cal-response-action-' + status.id
131             }));
132         }, this);
133         
134         this.actions = this.actions.concat(this.statusActions);
135         
136         // add more actions here (no spam / apply / crush / send event / ...)
137         
138         this.iMIPclause = new Ext.Toolbar.TextItem({
139             text: ''
140         });
141         this.tbar = this.actionToolbar = new Ext.Toolbar({
142             items: [{
143                     xtype: 'tbitem',
144                     cls: 'CalendarIconCls',
145                     width: 16,
146                     height: 16,
147                     style: 'margin: 3px 5px 2px 5px;'
148                 },
149                 this.iMIPclause,
150                 '->'
151             ].concat(this.actions)
152         });
153     },
154     
155     /**
156      * show/layout iMIP panel
157      */
158     showIMIP: function() {
159         
160         var singleRecordPanel = this.getSingleRecordPanel(),
161             preconditions = this.iMIPrecord.get('preconditions'),
162             method = this.iMIPrecord.get('method'),
163             event = this.iMIPrecord.get('event'),
164             myAttenderRecord = event.getMyAttenderRecord(),
165             myAttenderstatus = myAttenderRecord ? myAttenderRecord.get('status') : null;
166             
167         // reset actions
168         Ext.each(this.actions, function(action) {action.setHidden(true)});
169         
170         // check preconditions
171         if (preconditions) {
172             if (preconditions.hasOwnProperty('EVENTEXISTS')) {
173                 this.iMIPclause.setText(this.app.i18n._("The event of this message does not exist"));
174             }
175             
176             else if (preconditions.hasOwnProperty('ORIGINATOR')) {
177                 // display spam box -> might be accepted by user?
178                 this.iMIPclause.setText(this.app.i18n._("The sender is not authorised to update the event"));
179             }
180             
181             else if (preconditions.hasOwnProperty('RECENT')) {
182 //            else if (preconditions.hasOwnProperty('TOPROCESS')) {
183                 this.iMIPclause.setText(this.app.i18n._("This message is already processed"));
184             }
185             
186             else if (preconditions.hasOwnProperty('ATTENDEE')) {
187                 // party crush button?
188                 this.iMIPclause.setText(this.app.i18n._("You are not an attendee of this event"));
189             } 
190             
191             else {
192                 this.iMIPclause.setText(this.app.i18n._("Unsupported message"));
193             }
194         } 
195         
196         // method specific text / actions
197         else {
198             switch (method) {
199                 case 'REQUEST':
200                     if (! myAttenderRecord) {
201                         // might happen in shared folders -> we might want to become a party crusher?
202                         this.iMIPclause.setText(this.app.i18n._("This is an event invitation for someone else."));
203                     } else if (myAttenderstatus !== 'NEEDS-ACTION') {
204                         this.iMIPclause.setText(this.app.i18n._("You have already replied to this event invitation."));
205                     } else {
206                         this.iMIPclause.setText(this.app.i18n._('You received an event invitation. Set your response to:'));
207                         Ext.each(this.statusActions, function(action) {action.setHidden(false)});
208                     }
209                     break;
210                     
211                     
212                 case 'REPLY':
213                     // Someone replied => autoprocessing atm.
214                     this.iMIPclause.setText(this.app.i18n._('An invited attendee responded to the invitation.'));
215                     break;
216                     
217                 default:            
218                     this.iMIPclause.setText(this.app.i18n._("Unsupported method"));
219                     break;
220             }
221         }
222         
223         this.getLoadMask().hide();
224         singleRecordPanel.setVisible(true);
225         singleRecordPanel.setHeight(150);
226         
227         try {
228             singleRecordPanel.loadRecord(event);
229         } catch (e) {
230             singleRecordPanel.setVisible(false);
231         }
232         
233     }
234
235 });