Allow to drag&drop tasks to another list

This commit is contained in:
Thomas Bruederli 2012-09-18 08:53:24 +02:00
parent 6a66bea555
commit 05a1cb527d
5 changed files with 99 additions and 29 deletions

View file

@ -510,6 +510,18 @@ class tasklist_database_driver extends tasklist_driver
return $this->rc->db->affected_rows($query);
}
/**
* Move a single task to another list
*
* @param array Hash array with task properties:
* @return boolean True on success, False on error
* @see tasklist_driver::move_task()
*/
public function move_task($prop)
{
return $this->edit_task($prop);
}
/**
* Remove a single task from the database
*

View file

@ -663,6 +663,27 @@ class tasklist_kolab_driver extends tasklist_driver
return $saved;
}
/**
* Move a single task to another list
*
* @param array Hash array with task properties:
* @return boolean True on success, False on error
* @see tasklist_driver::move_task()
*/
public function move_task($task)
{
$list_id = $task['list'];
if (!$list_id || !($folder = $this->folders[$list_id]))
return false;
// execute move command
if ($task['_fromlist'] && ($fromfolder = $this->folders[$task['_fromlist']])) {
return $fromfolder->move($task['uid'], $folder->name);
}
return false;
}
/**
* Remove a single task from the database
*

View file

@ -175,6 +175,17 @@ abstract class tasklist_driver
*/
abstract function edit_task($prop);
/**
* Move a single task to another list
*
* @param array Hash array with task properties:
* id: Task identifier
* list: New list identifier to move to
* _fromlist: Previous list identifier
* @return boolean True on success, False on error
*/
abstract function move_task($prop);
/**
* Remove a single task from the database
*

View file

@ -111,13 +111,13 @@ function rcube_tasklist_ui(settings)
*/
function init()
{
// sinitialize task list selectors
// initialize task list selectors
for (var id in me.tasklists) {
if ((li = rcmail.get_folder_li(id, 'rcmlitasklist'))) {
init_tasklist_li(li, id);
}
if (!me.tasklists.readonly && !me.selected_list) {
if (me.tasklists[id].editable && !me.selected_list) {
me.selected_list = id;
rcmail.enable_command('addtask', true);
$(li).click();
@ -284,7 +284,7 @@ function rcube_tasklist_ui(settings)
if (item.length && (id = item.data('id')) && (rec = listdata[id])) {
var list = rec.list && me.tasklists[rec.list] ? me.tasklists[rec.list] : {};
if (rec.readonly || list.readonly)
if (rec.readonly || !list.editable)
task_show_dialog(id);
else
task_edit_dialog(id, 'edit');
@ -674,7 +674,7 @@ function rcube_tasklist_ui(settings)
function draggable_start(event, ui)
{
$('.taskhead, #rootdroppable').droppable({
$('.taskhead, #rootdroppable, #'+rcmail.gui_objects.folderlist.id+' li').droppable({
hoverClass: 'droptarget',
accept: droppable_accept,
drop: draggable_dropped,
@ -694,14 +694,21 @@ function rcube_tasklist_ui(settings)
function droppable_accept(draggable)
{
var drag_id = draggable.data('id'),
parent_id = $(this).data('id'),
drop_id = $(this).data('id'),
drag_rec = listdata[drag_id] || {},
drop_rec = listdata[parent_id];
drop_rec = listdata[drop_id];
// drop target is another list
if ($(this).data('type') == 'tasklist') {
var drop_list = me.tasklists[drop_id],
from_list = me.tasklists[drop_rec.list];
return drop_id != drag_rec.list && drop_list && drop_list.editable && from_list && from_list.editable;
}
if (drop_rec && drop_rec.list != drag_rec.list)
return false;
if (parent_id == drag_rec.parent_id)
if (drop_id == drag_rec.parent_id)
return false;
while (drop_rec && drop_rec.parent_id) {
@ -715,23 +722,34 @@ function rcube_tasklist_ui(settings)
function draggable_dropped(event, ui)
{
var parent_id = $(this).data('id'),
var drop_id = $(this).data('id'),
task_id = ui.draggable.data('id'),
parent = parent_id ? $('li[rel="'+parent_id+'"] > ul.childtasks', rcmail.gui_objects.resultlist) : $(rcmail.gui_objects.resultlist),
rec = listdata[task_id],
li;
parent, li;
if (rec && parent.length) {
// submit changes to server
rec.parent_id = parent_id || 0;
save_task(rec, 'edit');
// dropped on another list -> move
if ($(this).data('type') == 'tasklist') {
if (rec) {
save_task({ id:rec.id, list:drop_id, _fromlist:rec.list }, 'move');
rec.list = drop_id;
}
}
// dropped on a new parent task or root
else {
parent = drop_id ? $('li[rel="'+drop_id+'"] > ul.childtasks', rcmail.gui_objects.resultlist) : $(rcmail.gui_objects.resultlist)
li = ui.draggable.parent();
li.slideUp(300, function(){
li.appendTo(parent);
resort_task(rec, li);
li.slideDown(300);
});
if (rec && parent.length) {
// submit changes to server
rec.parent_id = drop_id || 0;
save_task(rec, 'edit');
li = ui.draggable.parent();
li.slideUp(300, function(){
li.appendTo(parent);
resort_task(rec, li);
li.slideDown(300);
});
}
}
}
@ -816,7 +834,7 @@ function rcube_tasklist_ui(settings)
list = rec.list && me.tasklists[rec.list] ? me.tasklists[rec.list] :
(me.selected_list ? me.tasklists[me.selected_list] : { editable: action=='new' });
if (list.readonly || (action == 'edit' && (!rec || rec.readonly)))
if (!list.editable || (action == 'edit' && (!rec || rec.readonly)))
return false;
me.selected_task = $.extend({}, rec); // clone task object
@ -886,7 +904,7 @@ function rcube_tasklist_ui(settings)
$('#taskedit select.edit-alarm-type, #taskedit select.edit-alarm-offset').change();
// attachments
rcmail.enable_command('remove-attachment', !list.readonly);
rcmail.enable_command('remove-attachment', list.editable);
me.selected_task.deleted_attachments = [];
// we're sharing some code for uploads handling with app.js
rcmail.env.attachments = [];
@ -1187,7 +1205,7 @@ function rcube_tasklist_ui(settings)
function list_remove(id)
{
var list = me.tasklists[id];
if (list && !list.readonly) {
if (list && list.editable) {
alert('To be implemented')
}
}
@ -1348,13 +1366,15 @@ function rcube_tasklist_ui(settings)
$(li).click(function(e){
var id = $(this).data('id');
rcmail.select_folder(id, 'rcmlitasklist');
rcmail.enable_command('list-edit', 'list-remove', 'import', !me.tasklists[id].readonly);
rcmail.enable_command('list-edit', 'list-remove', 'import', me.tasklists[id].editable);
me.selected_list = id;
})
.dblclick(function(e){
list_edit_dialog($(this).data('id'));
})
.data('id', id);
})
.dblclick(function(e){
list_edit_dialog($(this).data('id'));
})
.data('id', id)
.data('type', 'tasklist')
.addClass(me.tasklists[id].editable ? null : 'readonly');
}

View file

@ -177,6 +177,12 @@ class tasklist extends rcube_plugin
}
break;
case 'move':
if ($success = $this->driver->move_task($rec)) {
$refresh = $this->driver->get_task($rec);
}
break;
case 'delete':
if (!($success = $this->driver->delete_task($rec, false)))
$this->rc->output->command('plugin.reload_data');