plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Fri Aug 1 11:34:13 CEST 2014


 plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php |    4 +
 plugins/tasklist/localization/en_US.inc                  |    1 
 plugins/tasklist/skins/larry/tasklist.css                |   24 +++++---
 plugins/tasklist/skins/larry/templates/mainview.html     |   14 ++++-
 plugins/tasklist/tasklist.js                             |   41 +++++++++++++--
 plugins/tasklist/tasklist.php                            |   40 ++++++++++++++
 plugins/tasklist/tasklist_ui.php                         |    1 
 7 files changed, 109 insertions(+), 16 deletions(-)

New commits:
commit 8fe64d74005f28efd5da62ef755ffd5ce00c0c6f
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Fri Aug 1 11:16:57 2014 +0200

    Show RSVP buttons for assigned tasks which require a response

diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index 6370301..a3e6181 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -457,7 +457,7 @@ class tasklist_kolab_driver extends tasklist_driver
         $tomorrow_date = new DateTime('now + 1 day', $this->plugin->timezone);
         $tomorrow = $tomorrow_date->format('Y-m-d');
 
-        $counts = array('all' => 0, 'flagged' => 0, 'today' => 0, 'tomorrow' => 0, 'overdue' => 0, 'nodate' => 0);
+        $counts = array('all' => 0, 'flagged' => 0, 'today' => 0, 'tomorrow' => 0, 'overdue' => 0, 'nodate' => 0, 'mytasks' => 0);
         foreach ($lists as $list_id) {
             if (!$folder = $this->get_folder($list_id)) {
                 continue;
@@ -479,6 +479,8 @@ class tasklist_kolab_driver extends tasklist_driver
                     $counts['tomorrow']++;
                 else if ($rec['date'] < $today)
                     $counts['overdue']++;
+                if ($this->plugin->is_attendee($rec) !== false)
+                    $counts['mytasks']++;
             }
         }
 
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index 99a11b0..3fd045a 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -146,6 +146,7 @@ $labels['attendeedelegated'] = 'Assignee has delegated to $delegatedto';
 $labels['attendeein-process'] = 'Assignee is in-process';
 $labels['attendeecompleted'] = 'Assignee has completed';
 
+$labels['acceptinvitation'] = 'Do you accept this assignment?';
 $labels['itipdeclinetask'] = 'Decline your assignment to this task to the organizer';
 $labels['declinedeleteconfirm'] = 'Do you also want to delete this declined task from your tasks list?';
 $labels['itipcomment'] = 'Invitation/notification comment';
diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index f627136..ff8ba12 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -1132,12 +1132,18 @@ div.tasklist-invitebox td.label {
 	padding-right: 1em;
 }
 
-#event-rsvp .rsvp-buttons,
+#task-rsvp .rsvp-buttons,
+#task-rsvp .itip-reply-controls,
 div.tasklist-invitebox .itip-buttons div {
 	margin-top: 0.5em;
 }
 
-#event-rsvp input.button,
+#task-rsvp .itip-reply-controls a,
+#task-rsvp .itip-reply-controls label {
+	color: #333;
+}
+
+#task-rsvp input.button,
 div.tasklist-invitebox input.button {
 	font-weight: bold;
 	margin-right: 0.5em;
@@ -1164,7 +1170,7 @@ div.tasklist-invitebox .rsvp-status.hint {
 	font-style: italic;
 }
 
-#event-partstat .changersvp,
+#task-partstat .changersvp,
 .edit-attendees-table td.confirmstate span,
 div.tasklist-invitebox .rsvp-status.declined,
 div.tasklist-invitebox .rsvp-status.tentative,
@@ -1177,37 +1183,37 @@ div.tasklist-invitebox .rsvp-status.needs-action {
 	background: url(images/attendee-status.png) 2px -20px no-repeat;
 }
 
-#event-partstat .changersvp.declined,
+#task-partstat .changersvp.declined,
 div.tasklist-invitebox .rsvp-status.declined,
 .edit-attendees-table td.confirmstate span.declined {
 	background-position: 2px -40px;
 }
 
-#event-partstat .changersvp.tentative,
+#task-partstat .changersvp.tentative,
 div.tasklist-invitebox .rsvp-status.tentative,
 .edit-attendees-table td.confirmstate span.tentative {
 	background-position: 2px -60px;
 }
 
-#event-partstat .changersvp.delegated,
+#task-partstat .changersvp.delegated,
 div.tasklist-invitebox .rsvp-status.delegated,
 .edit-attendees-table td.confirmstate span.delegated {
 	background-position: 2px -180px;
 }
 
-#event-partstat .changersvp.needs-action,
+#task-partstat .changersvp.needs-action,
 div.tasklist-invitebox .rsvp-status.needs-action,
 .edit-attendees-table td.confirmstate span.needs-action {
 	background-position: 2px 0;
 }
 
-#event-partstat .changersvp.in-process,
+#task-partstat .changersvp.in-process,
 div.tasklist-invitebox .rsvp-status.in-process,
 .edit-attendees-table td.confirmstate span.in-process {
 	background-position: 2px -200px;
 }
 
-#event-partstat .changersvp.accepted,
+#task-partstat .changersvp.accepted,
 div.tasklist-invitebox .rsvp-status.accepted,
 .edit-attendees-table td.confirmstate span.accepted {
 	background-position: 2px -220px;
diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html
index ad018eb..5f6831f 100644
--- a/plugins/tasklist/skins/larry/templates/mainview.html
+++ b/plugins/tasklist/skins/larry/templates/mainview.html
@@ -90,7 +90,7 @@
 				<li class="later" role="radio" aria-checked="false" aria-labelledby="aria-radio-later"><a href="#later" id="aria-radio-later"><roundcube:label name="tasklist.later" /></a></li>
 				<li class="nodate" role="radio" aria-checked="false" aria-labelledby="aria-radio-nodate"><a href="#nodate" id="aria-radio-nodate"><roundcube:label name="tasklist.nodate" ucfirst="true" /></a></li>
 				<roundcube:if condition="env:tasklist_driver == 'kolab'" />
-				<li class="mytasks" role="radio" aria-checked="false" aria-labelledby="aria-radio-mytasks"><a href="#mytasks" id="aria-radio-mytasks" title="<roundcube:label name='tasklist.mytaskstitle'/>"><roundcube:label name="tasklist.mytasks" /></a></li>
+				<li class="mytasks" role="radio" aria-checked="false" aria-labelledby="aria-radio-mytasks"><a href="#mytasks" id="aria-radio-mytasks" title="<roundcube:label name='tasklist.mytaskstitle'/>"><roundcube:label name="tasklist.mytasks" /><span class="count"></span></a></li>
 				<li class="assigned" role="radio" aria-checked="false" aria-labelledby="aria-radio-assigned"><a href="#assigned" id="aria-radio-assigned" title="<roundcube:label name='tasklist.assignedtitle'/>"><roundcube:label name="tasklist.assigned" /></a></li>
 				<roundcube:endif />
 				<li class="complete" role="radio" aria-checked="false" aria-labelledby="aria-radio-complete"><a href="#complete" id="aria-radio-complete"><roundcube:label name="tasklist.complete" /><span class="count"></span></a></li>
@@ -195,6 +195,18 @@
 		<label><roundcube:label name="attachments" /></label>
 		<div class="task-text"></div>
 	</div>
+	<div id="task-created-changed" class="form-section">
+		<label><roundcube:label name="tasklist.created" /></label>
+		<span class="task-text task-created"></span>
+		<label><roundcube:label name="tasklist.changed" /></label>
+		<span class="task-text task-changed"></span>
+	</div>
+	<div id="task-rsvp-comment" class="form-section">
+		<label><roundcube:label name="tasklist.rsvpcomment" /></label>
+		<span class="task-text"></span>
+	</div>
+
+	<roundcube:object name="plugin.task_rsvp_buttons" id="task-rsvp" class="task-dialog-message" style="display:none" />
 </div>
 
 <roundcube:include file="/templates/taskedit.html" />
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index ffb0129..0a090e8 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -502,6 +502,35 @@ function rcube_tasklist_ui(settings)
             }
         });
 
+        // init RSVP widget
+        $('#task-rsvp input.button').click(function(e) {
+            var response = $(this).attr('rel');
+
+            if (me.selected_task && me.selected_task.attendees && response) {
+                // update attendee status
+                for (var data, i=0; i < me.selected_task.attendees.length; i++) {
+                    data = me.selected_task.attendees[i];
+                    if (settings.identity.emails.indexOf(';'+String(data.email).toLowerCase()) >= 0) {
+                        data.status = response.toUpperCase();
+                        delete data.rsvp;  // unset RSVP flag
+                    }
+                }
+
+                // submit status change to server
+                saving_lock = rcmail.set_busy(true, 'tasklist.savingdata');
+                rcmail.http_post('tasks/task', {
+                    action: 'rsvp',
+                    t: me.selected_task,
+                    filter: filtermask,
+                    status: response,
+                    noreply: $('#noreply-task-rsvp').prop('checked') ? 1 : 0,
+                    comment: $('#reply-comment-task-rsvp').val()
+                });
+
+                task_show_dialog(me.selected_task.id);
+            }
+        });
+
         // handle global document clicks: close popup menus
         $(document.body).click(clear_popups);
 
@@ -1613,7 +1642,7 @@ function rcube_tasklist_ui(settings)
         $('#task-completeness .task-text').html(((rec.complete || 0) * 100) + '%');
         $('#task-status')[(rec.status ? 'show' : 'hide')]().children('.task-text').html(rcmail.gettext('status-'+String(rec.status).toLowerCase(),'tasklist'));
         $('#task-list .task-text').html(Q(me.tasklists[rec.list] ? me.tasklists[rec.list].name : ''));
-        $('#task-attendees, #task-organizer').hide();
+        $('#task-attendees, #task-organizer, #task-created-changed, #task-rsvp-comment').hide();
 
         var itags = get_inherited_tags(rec);
         var taglist = $('#task-tags')[(rec.tags && rec.tags.length || itags.length ? 'show' : 'hide')]().children('.task-text').empty();
@@ -1657,7 +1686,6 @@ function rcube_tasklist_ui(settings)
 
         // list task attendees
         if (list.attendees && rec.attendees) {
-            console.log(rec.attendees)
 /*
             // sort resources to the end
             rec.attendees.sort(function(a,b) {
@@ -1720,13 +1748,16 @@ function rcube_tasklist_ui(settings)
                     .children('.task-text')
                     .html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
             }
-
-            $('#task-rsvp')[(rsvp && !is_organizer(event) && rec.status != 'CANCELLED' ? 'show' : 'hide')]();
+*/
+            var show_rsvp = rsvp && !is_organizer(rec) && rec.status != 'CANCELLED';
+            $('#task-rsvp')[(show_rsvp ? 'show' : 'hide')]();
             $('#task-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
 
+            if (show_rsvp && rec.comment) {
+                $('#task-rsvp-comment').show().children('.task-text').html(Q(rec.comment));
+            }
             $('#task-rsvp a.reply-comment-toggle').show();
             $('#task-rsvp .itip-reply-comment textarea').hide().val('');
-*/
 
             if (rec.organizer && !organizer) {
                 $('#task-organizer').show().children('.task-text').html(task_attendee_html(rec.organizer));
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index 78bb001..6820384 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -321,6 +321,22 @@ class tasklist extends rcube_plugin
 
             $this->rc->user->save_prefs(array('tasklist_collapsed_tasks' => join(',', array_unique($this->collapsed_tasks))));
             return;  // avoid further actions
+
+        case 'rsvp':
+            $status = get_input_value('status', RCUBE_INPUT_GPC);
+            $task = $this->driver->get_task($rec);
+            $task['attendees'] = $rec['attendees'];
+            $rec = $task;
+
+            if ($success = $this->driver->edit_task($rec)) {
+                $noreply = intval(get_input_value('noreply', RCUBE_INPUT_GPC)) || $status == 'needs-action';
+
+                if (!$noreply) {
+                    // let the reply clause further down send the iTip message
+                    $rec['_reportpartstat'] = $status;
+                }
+            }
+            break;
         }
 
         if ($success) {
@@ -354,6 +370,9 @@ class tasklist extends rcube_plugin
                 $sender = $task['attendees'][$idx];
                 $status = strtolower($sender['status']);
 
+                if (!empty($_POST['comment']))
+                    $task['comment'] = get_input_value('comment', RCUBE_INPUT_POST);
+
                 $itip = $this->load_itip();
                 $itip->set_sender_email($sender['email']);
 
@@ -1862,4 +1881,25 @@ class tasklist extends rcube_plugin
        $this->load_driver();
        return $this->driver->user_delete($args);
     }
+
+
+    /**
+     * Magic getter for public access to protected members
+     */
+    public function __get($name)
+    {
+        switch ($name) {
+            case 'ical':
+                return $this->get_ical();
+
+            case 'itip':
+                return $this->load_itip();
+
+            case 'driver':
+                $this->load_driver();
+                return $this->driver;
+        }
+
+        return null;
+    }
 }
diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php
index 21b322e..7d8f513 100644
--- a/plugins/tasklist/tasklist_ui.php
+++ b/plugins/tasklist/tasklist_ui.php
@@ -129,6 +129,7 @@ class tasklist_ui
         $this->plugin->register_handler('plugin.attendees_form', array($this, 'attendees_form'));
         $this->plugin->register_handler('plugin.identity_select', array($this, 'identity_select'));
         $this->plugin->register_handler('plugin.edit_attendees_notify', array($this, 'edit_attendees_notify'));
+        $this->plugin->register_handler('plugin.task_rsvp_buttons', array($this->plugin->itip, 'itip_rsvp_buttons'));
 
         $this->plugin->include_script('jquery.tagedit.js');
         $this->plugin->include_script('tasklist.js');




More information about the commits mailing list