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