diff options
author | Thomas Bruederli <bruederli@kolabsys.com> | 2014-08-01 09:16:57 (GMT) |
---|---|---|
committer | Thomas Bruederli <bruederli@kolabsys.com> | 2014-08-01 09:16:57 (GMT) |
commit | 8fe64d74005f28efd5da62ef755ffd5ce00c0c6f (patch) | |
tree | 063657a817608524f4088a7c1c92f36892e6b196 /plugins | |
parent | e48f0dbf15b07abc9a5e73e234750d6e191301a9 (diff) | |
download | roundcubemail-plugins-kolab-8fe64d74005f28efd5da62ef755ffd5ce00c0c6f.tar.gz |
Show RSVP buttons for assigned tasks which require a response
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php | 4 | ||||
-rw-r--r-- | plugins/tasklist/localization/en_US.inc | 1 | ||||
-rw-r--r-- | plugins/tasklist/skins/larry/tasklist.css | 24 | ||||
-rw-r--r-- | plugins/tasklist/skins/larry/templates/mainview.html | 14 | ||||
-rw-r--r-- | plugins/tasklist/tasklist.js | 41 | ||||
-rw-r--r-- | plugins/tasklist/tasklist.php | 40 | ||||
-rw-r--r-- | plugins/tasklist/tasklist_ui.php | 1 |
7 files changed, 109 insertions, 16 deletions
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'); |