diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js index 99c93de4..1605c49a 100644 --- a/plugins/tasklist/tasklist.js +++ b/plugins/tasklist/tasklist.js @@ -415,9 +415,14 @@ function rcube_tasklist_ui(settings) loadstate.filter = response.filter; loadstate.search = response.search; - for (var i=0; i < response.data.length; i++) { - listdata[response.data[i].id] = response.data[i]; - listindex.push(response.data[i].id); + for (var id, i=0; i < response.data.length; i++) { + id = response.data[i].id; + listindex.push(id); + listdata[id] = response.data[i]; + listdata[id].children = []; + // register a forward-pointer to child tasks + if (listdata[id].parent_id && listdata[listdata[id].parent_id]) + listdata[listdata[id].parent_id].children.push(id); } render_tasklist(); @@ -486,7 +491,8 @@ function rcube_tasklist_ui(settings) $('#taskselector a').each(function(i, elem){ var link = $(elem), f = link.parent().attr('class').replace(/\s\w+/, ''); - link.children('span').html(taskcounts[f] || '')[(taskcounts[f] ? 'show' : 'hide')](); + if (f != 'all') + link.children('span').html(taskcounts[f] || '')[(taskcounts[f] ? 'show' : 'hide')](); }); // spacial case: overdue @@ -498,9 +504,16 @@ function rcube_tasklist_ui(settings) */ function update_taskitem(rec) { + // handle a list of task records + if ($.isArray(rec)) { + $.each(rec, function(i,r){ update_taskitem(r); }); + return; + } + var id = rec.id, - oldid = rec.tempid || id; - oldindex = listindex.indexOf(oldid); + oldid = rec.tempid || id, + oldindex = listindex.indexOf(oldid), + list = me.tasklists[rec.list]; if (oldindex >= 0) listindex[oldindex] = id; @@ -509,7 +522,11 @@ function rcube_tasklist_ui(settings) listdata[id] = rec; - render_task(rec, oldid); + if (list.active) + render_task(rec, oldid); + else + $('li[rel="'+id+'"]', rcmail.gui_objects.resultlist).remove(); + append_tags(rec.tags || []); } @@ -683,6 +700,21 @@ function rcube_tasklist_ui(settings) return d; } + /** + * + */ + function get_all_childs(id) + { + var cid, childs = []; + for (var i=0; listdata[id].children && i < listdata[id].children.length; i++) { + cid = listdata[id].children[i]; + childs.push(cid); + childs = childs.concat(get_all_childs(cid)); + } + + return childs; + } + /* Helper functions for drag & drop functionality */ @@ -752,7 +784,11 @@ function rcube_tasklist_ui(settings) // dropped on another list -> move if ($(this).data('type') == 'tasklist') { if (rec) { - save_task({ id:rec.id, list:drop_id, _fromlist:rec.list }, 'move'); + var ids = [ rec.id ], + childs = get_all_childs(rec.id); + if (childs.length) + ids = ids.concat(childs); + save_task({ id:ids, list:drop_id, _fromlist:rec.list }, 'move'); rec.list = drop_id; } } diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php index 88f87fad..88eed947 100644 --- a/plugins/tasklist/tasklist.php +++ b/plugins/tasklist/tasklist.php @@ -180,8 +180,16 @@ class tasklist extends rcube_plugin break; case 'move': - if ($success = $this->driver->move_task($rec)) { - $refresh = $this->driver->get_task($rec); + $recs = array(); + foreach ((array)$rec['id'] as $id) { + $r = $rec; + $r['id'] = $id; + if ($this->driver->move_task($r)) { + $r = $this->driver->get_task($r); + $this->encode_task($r); + $refresh[] = $r; + $success = true; + } } break; @@ -207,7 +215,8 @@ class tasklist extends rcube_plugin $this->rc->output->command('plugin.unlock_saving'); if ($refresh) { - $this->encode_task($refresh); + if ($refresh['id']) + $this->encode_task($refresh); $this->rc->output->command('plugin.refresh_task', $refresh); } } @@ -405,7 +414,15 @@ class tasklist extends rcube_plugin */ public function fetch_counts() { - $lists = get_input_value('lists', RCUBE_INPUT_GPC);; + if (isset($_REQUEST['lists'])) { + $lists = get_input_value('lists', RCUBE_INPUT_GPC); + } + else { + foreach ($this->driver->get_lists() as $list) { + if ($list['active']) + $lists[] = $list['id']; + } + } $counts = $this->driver->count_tasks($lists); $this->rc->output->command('plugin.update_counts', $counts); } @@ -477,6 +494,7 @@ class tasklist extends rcube_plugin } // sort tasks according to their hierarchy level and due date + array_walk($data, array($this, 'task_walk_tree')); usort($data, array($this, 'task_sort_cmp')); $this->rc->output->command('plugin.data_ready', array('filter' => $f, 'lists' => $lists, 'search' => $search, 'data' => $data, 'tags' => array_values(array_unique($tags)))); @@ -526,19 +544,24 @@ class tasklist extends rcube_plugin $rec['attachments'][$k]['classname'] = rcmail_filetype2classname($attachment['mimetype'], $attachment['name']); } - if (!isset($rec['_depth'])) { - $rec['_depth'] = 0; - $parent_id = $this->task_tree[$rec['id']]; - while ($parent_id) { - $rec['_depth']++; - $rec['parent_title'] = $this->task_titles[$parent_id]; - $parent_id = $this->task_tree[$parent_id]; - } - } - $this->task_titles[$rec['id']] = $rec['title']; } + /** + * Callback function for array_walk over all tasks. + * Sets tree depth and parent titles + */ + private function task_walk_tree(&$rec) + { + $rec['_depth'] = 0; + $parent_id = $this->task_tree[$rec['id']]; + while ($parent_id) { + $rec['_depth']++; + $rec['parent_title'] = $this->task_titles[$parent_id]; + $parent_id = $this->task_tree[$parent_id]; + } + } + /** * Compare function for task list sorting. * Nested tasks need to be sorted to the end.