improve default attendees on event creation
authorsstamer <s.stamer@metaways.de>
Wed, 20 Aug 2014 15:45:04 +0000 (17:45 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 4 Sep 2014 09:26:48 +0000 (11:26 +0200)
* new default attendee mode 'intelligent'
* in intelligent mode, attendee from attendee filter are
  taken as default attendee
* if no attendee filter is in use, the container owner from
  the containerfilter is taken if container is personal
* switch to 'intelligent' mode when shift key is pressed
* prefer containerOwner over attendeeFilter if alt is
  pressed as well (this should be a hidden feature as
  alt key destroys window.open)
* add a preference 'defaultAttendeeStrategy'
  to the calendar prefs with selections 'me' and 'intelligent'

Change-Id: I46a2978fdabf91db889ece51f7bf7fad75167546
Reviewed-on: http://gerrit.tine20.com/customers/1030
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Calendar/Preference.php
tine20/Calendar/js/Model.js
tine20/Tinebase/Frontend/Json/Container.php
tine20/Tinebase/js/Models.js

index eefb377..bb9a3ad 100644 (file)
@@ -58,6 +58,11 @@ class Calendar_Preference extends Tinebase_Preference_Abstract
     const DEFAULTALARM_MINUTESBEFORE = 'defaultalarmminutesbefore';
     
     /**
+     * default alarm time in minutes before
+     */
+    const DEFAULTATTENDEE_STRATEGY = 'defaultAttendeeStrategy';
+    
+    /**
      * @var string application
      */
     protected $_application = 'Calendar';
@@ -78,6 +83,7 @@ class Calendar_Preference extends Tinebase_Preference_Abstract
             self::SEND_NOTIFICATION_OF_OWN_ACTIONS,
             self::DEFAULTALARM_ENABLED,
             self::DEFAULTALARM_MINUTESBEFORE,
+            self::DEFAULTATTENDEE_STRATEGY
         );
             
         return $allPrefs;
@@ -125,6 +131,10 @@ class Calendar_Preference extends Tinebase_Preference_Abstract
                 'label'         => $translate->_('Standard Alarm Time'),
                 'description'   => $translate->_('Minutes before the event starts'),
             ),
+            self::DEFAULTATTENDEE_STRATEGY => array(
+                    'label'         => $translate->_('Default Attendee Strategy'),
+                    'description'   => $translate->_('Default Attendee Strategy for new events'),
+            ),
         );
         
         return $prefDescriptions;
@@ -240,6 +250,28 @@ class Calendar_Preference extends Tinebase_Preference_Abstract
                 $preference->value      = 15;
                 $preference->options    = '';
                 break;
+            case self::DEFAULTATTENDEE_STRATEGY:
+                $preference->value      = 'intelligent';
+                $preference->options    = '<?xml version="1.0" encoding="UTF-8"?>
+                    <options>
+                        <option>
+                            <label>Me</label>
+                            <value>me</value>
+                        </option>
+                        <option>
+                            <label>Intelligent</label>
+                            <value>intelligent</value>
+                        </option>
+                        <option>
+                            <label>Calendar owner</label>
+                            <value>calendarOwner</value>
+                        </option>
+                        <option>
+                            <label>Filtered attendee</label>
+                            <value>filteredAttendee</value>
+                        </option>
+                    </options>';
+                break;
             default:
                 throw new Tinebase_Exception_NotFound('Default preference with name ' . $_preferenceName . ' not found.');
         }
index 30dbf14..286bea3 100644 (file)
@@ -153,23 +153,22 @@ Tine.Calendar.Model.Event = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model
 
 
 /**
- * @namespace Tine.Calendar.Model
- * 
  * get default data for a new event
- * @todo: attendee according to calendar selection
  *  
  * @return {Object} default data
  * @static
  */ 
 Tine.Calendar.Model.Event.getDefaultData = function() {
     var app = Tine.Tinebase.appMgr.get('Calendar'),
+        mainScreen = app.getMainScreen(),
+        centerPanel = mainScreen.getCenterPanel(),
+        westPanel = mainScreen.getWestPanel(),
+        container = westPanel.getContainerTreePanel().getDefaultContainer(),
+        prefs = app.getRegistry().get('preferences'),
         dtstart = new Date().clearTime().add(Date.HOUR, (new Date().getHours() + 1)),
-        // if dtstart is out of current period, take start of current period
-        mainPanel = app.getMainScreen().getCenterPanel(),
-        period = mainPanel.getCalendarPanel(mainPanel.activeView).getView().getPeriod(),
-        container = app.getMainScreen().getWestPanel().getContainerTreePanel().getDefaultContainer(),
-        prefs = app.getRegistry().get('preferences');
+        period = centerPanel.getCalendarPanel(centerPanel.activeView).getView().getPeriod();
         
+    // if dtstart is out of current period, take start of current period
     if (period.from.getTime() > dtstart.getTime() || period.until.getTime() < dtstart.getTime()) {
         dtstart = period.from.clearTime(true).add(Date.HOUR, 9);
     }
@@ -182,13 +181,13 @@ Tine.Calendar.Model.Event.getDefaultData = function() {
         transp: 'OPAQUE',
         editGrant: true,
         organizer: Tine.Tinebase.registry.get('userContact'),
-        attendee: [
+        attendee: Tine.Calendar.Model.Event.getDefaultAttendee() /*[
             Ext.apply(Tine.Calendar.Model.Attender.getDefaultData(), {
                 user_type: 'user',
                 user_id: Tine.Tinebase.registry.get('userContact'),
                 status: 'ACCEPTED'
             })
-        ]
+        ]*/
     };
     
     if (prefs.get('defaultalarmenabled')) {
@@ -198,6 +197,76 @@ Tine.Calendar.Model.Event.getDefaultData = function() {
     return data;
 };
 
+Tine.Calendar.Model.Event.getDefaultAttendee = function() {
+    var app = Tine.Tinebase.appMgr.get('Calendar'),
+        mainScreen = app.getMainScreen(),
+        centerPanel = mainScreen.getCenterPanel(),
+        westPanel = mainScreen.getWestPanel(),
+        filteredAttendee = westPanel.getAttendeeFilter().getValue() || [],
+        defaultAttendeeData = Tine.Calendar.Model.Attender.getDefaultData(),
+        filteredContainers = westPanel.getContainerTreePanel().getFilterPlugin().getFilter().value || [],
+        prefs = app.getRegistry().get('preferences'),
+        defaultAttendeeStrategy = prefs.get('defaultAttendeeStrategy') || 'me', // one of['me', 'intelligent', 'calendarOwner', 'filteredAttendee']
+        defaultAttendee = [];
+        
+    // shift -> change intelligent <-> me
+    if (Ext.EventObject.shiftKey) {
+        defaultAttendeeStrategy = defaultAttendeeStrategy == 'intelligent' ? 'me' :
+                                  defaultAttendeeStrategy == 'me' ? 'intelligent' :
+                                  defaultAttendeeStrategy;
+    }
+    
+    // alt -> prefer calendarOwner in intelligent mode
+    if (defaultAttendeeStrategy == 'intelligent') {
+        defaultAttendeeStrategy = filteredAttendee.length && !Ext.EventObject.altKey > 0 ? 'filteredAttendee' :
+                                  filteredContainers.length > 0 ? 'calendarOwner' :
+                                  'me';
+    }
+    
+    switch(defaultAttendeeStrategy) {
+        case 'me':
+            defaultAttendee.push(Ext.apply(Tine.Calendar.Model.Attender.getDefaultData(), {
+                user_type: 'user',
+                user_id: Tine.Tinebase.registry.get('userContact'),
+                status: 'ACCEPTED'
+            }));
+            break;
+            
+        case 'filteredAttendee':
+            var attendeeStore = Tine.Calendar.Model.Attender.getAttendeeStore(filteredAttendee),
+                ownAttendee = Tine.Calendar.Model.Attender.getAttendeeStore.getMyAttenderRecord(attendeeStore);
+                
+            attendeeStore.each(function(attendee){
+                var attendeeData = Ext.apply(attendee.data, defaultAttendeeData);
+                if (attendee == ownAttendee) {
+                    attendeeData.status = 'ACCEPTED';
+                }
+                defaultAttendee.push(attendeeData);
+            }, this);
+            break;
+            
+        case 'calendarOwner':
+            Ext.each(filteredContainers, function(container){
+                if (container.ownerContact) {
+                    var attendeeData = Ext.apply(Tine.Calendar.Model.Attender.getDefaultData(), {
+                        user_type: 'user',
+                        user_id: container.ownerContact
+                    });
+                    
+                    if (attendeeData.user_id.id == Tine.Tinebase.registry.get('userContact').id){
+                        attendeeData.status = 'ACCEPTED';
+                    }
+                    
+                    defaultAttendee.push(attendeeData);
+                }
+            }, this);
+            
+            break;
+    }
+    
+    return defaultAttendee;
+};
+
 Tine.Calendar.Model.Event.getFilterModel = function() {
     var app = Tine.Tinebase.appMgr.get('Calendar');
     
index a32a0c2..7f23768 100644 (file)
@@ -59,8 +59,15 @@ class Tinebase_Frontend_Json_Container
             if ($container instanceof Tinebase_Model_Container) {
                 $containerArray['account_grants'] = Tinebase_Container::getInstance()->getGrantsOfAccount(Tinebase_Core::getUser(), $container->getId())->toArray();
                 $containerArray['path'] = $container->getPath();
+                $ownerId = $container->getOwner();
             } else {
                 $containerArray['path'] = "personal/{$container->getId()}";
+                $ownerId = $container->getId();
+            }
+            try {
+                $containerArray['ownerContact'] = Addressbook_Controller_Contact::getInstance()->getContactByUserId($ownerId, true)->toArray();
+            } catch (Exception $e) {
+                Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . " can't resolve ownerContact: " . $e);
             }
             
             $response[] = $containerArray;
index 2cb61c6..74e8986 100644 (file)
@@ -84,6 +84,7 @@ Tine.Tinebase.Model.Container = Tine.Tinebase.data.Record.create(Tine.Tinebase.M
     {name: 'type'},
     {name: 'color'},
     {name: 'path'},
+    {name: 'ownerContact'},
     {name: 'is_container_node', type: 'boolean'},
     {name: 'dtselect', type: 'number'},
     {name: 'backend'},