3 commits - plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Wed Sep 19 08:56:53 CEST 2012


 plugins/tasklist/drivers/database/tasklist_database_driver.php |   34 ++
 plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php       |   21 +
 plugins/tasklist/drivers/tasklist_driver.php                   |   11 
 plugins/tasklist/localization/de_CH.inc                        |    1 
 plugins/tasklist/localization/en_US.inc                        |    1 
 plugins/tasklist/skins/larry/templates/mainview.html           |    2 
 plugins/tasklist/tasklist.js                                   |  133 +++++++---
 plugins/tasklist/tasklist.php                                  |   15 +
 8 files changed, 181 insertions(+), 37 deletions(-)

New commits:
commit 192bd3942cb08cf14c71aa3672f657a0f1e81628
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Tue Sep 18 19:27:42 2012 +0200

    Implement list deletion + minor bugfixes

diff --git a/plugins/tasklist/drivers/database/tasklist_database_driver.php b/plugins/tasklist/drivers/database/tasklist_database_driver.php
index 4a0c80b..639c8d4 100644
--- a/plugins/tasklist/drivers/database/tasklist_database_driver.php
+++ b/plugins/tasklist/drivers/database/tasklist_database_driver.php
@@ -175,7 +175,27 @@ class tasklist_database_driver extends tasklist_driver
      */
     public function remove_list($prop)
     {
-        // TODO: implement this
+        $list_id = $prop['id'];
+        if ($this->lists[$list_id]) {
+            // delete all tasks linked with this list
+            $this->rc->db->query(
+                "DELETE FROM " . $this->db_tasks . "
+                 WHERE tasklist_id=?",
+                $lisr_id
+            );
+
+            // delete list record
+            $query = $this->rc->db->query(
+                "DELETE FROM " . $this->db_lists . "
+                 WHERE tasklist_id=?
+                 AND user_id=?",
+                $list_id,
+                $this->rc->user->ID
+            );
+
+            return $this->rc->db->affected_rows($query);
+        }
+
         return false;
     }
 
diff --git a/plugins/tasklist/localization/de_CH.inc b/plugins/tasklist/localization/de_CH.inc
index a20a6f5..ac06095 100644
--- a/plugins/tasklist/localization/de_CH.inc
+++ b/plugins/tasklist/localization/de_CH.inc
@@ -60,3 +60,4 @@ $labels['savingdata'] = 'Daten werden gespeichert...';
 $labels['errorsaving'] = 'Fehler beim Speichern.';
 $labels['notasksfound'] = 'Für die aktuellen Kriterien wurden keine Aufgaben gefunden.';
 $labels['invalidstartduedates'] = 'Beginn der Aufgabe darf nicht grösser als das Enddatum sein.';
+$labels['deletelistconfirm'] = 'Möchten Sie diese Liste mit allen Aufgaben wirklich löschen?';
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index 98a8076..c657516 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -60,3 +60,4 @@ $labels['savingdata'] = 'Saving data...';
 $labels['errorsaving'] = 'Failed to save data.';
 $labels['notasksfound'] = 'No tasks found for the given criteria';
 $labels['invalidstartduedates'] = 'Start date must not be greater than due date.';
+$labels['deletelistconfirm'] = 'Do you really want to delete this list with all its tasks?';
diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html
index eb98e98..fbc7d5c 100644
--- a/plugins/tasklist/skins/larry/templates/mainview.html
+++ b/plugins/tasklist/skins/larry/templates/mainview.html
@@ -84,7 +84,7 @@
 	<ul class="toolbarmenu">
 		<li><roundcube:button command="list-edit" label="edit" classAct="active" /></li>
 		<li><roundcube:button command="list-remove" label="delete" classAct="active" /></li>
-		<li><roundcube:button command="list-import" label="tasklist.import" classAct="active" /></li>
+		<!--<li><roundcube:button command="list-import" label="tasklist.import" classAct="active" /></li>-->
 		<roundcube:if condition="env:tasklist_driver == 'kolab'" />
 		<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
 		<roundcube:endif />
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index e4ebc20..99c93de 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -130,6 +130,7 @@ function rcube_tasklist_ui(settings)
         rcmail.addEventListener('plugin.update_counts', update_counts);
         rcmail.addEventListener('plugin.insert_tasklist', insert_list);
         rcmail.addEventListener('plugin.update_tasklist', update_list);
+        rcmail.addEventListener('plugin.destroy_tasklist', destroy_list);
         rcmail.addEventListener('plugin.reload_data', function(){ list_tasks(null); });
         rcmail.addEventListener('plugin.unlock_saving', unlock_saving);
 
@@ -386,6 +387,24 @@ function rcube_tasklist_ui(settings)
     }
 
     /**
+     * Remove all tasks of the given list from the UI
+     */
+    function remove_tasks(list_id)
+    {
+        // remove all tasks of the given list from index
+        var newindex = $.grep(listindex, function(id, i){
+            return listdata[id] && listdata[id].list != list_id;
+        });
+
+        listindex = newindex;
+        render_tasklist();
+
+        // avoid reloading
+        me.tasklists[list_id].active = false;
+        loadstate.lists = active_lists();
+    }
+
+    /**
      * Callback if task data from server is ready
      */
     function data_ready(response)
@@ -430,6 +449,9 @@ function rcube_tasklist_ui(settings)
             msgbox.html(rcmail.gettext('notasksfound','tasklist')).show();
     }
 
+    /**
+     *
+     */
     function append_tags(taglist)
     {
         // find new tags
@@ -699,9 +721,9 @@ function rcube_tasklist_ui(settings)
             drop_rec = listdata[drop_id];
 
         // drop target is another list
-        if ($(this).data('type') == 'tasklist') {
+        if (drag_rec && $(this).data('type') == 'tasklist') {
             var  drop_list = me.tasklists[drop_id],
-               from_list = me.tasklists[drop_rec.list];
+               from_list = me.tasklists[drag_rec.list];
             return drop_id != drag_rec.list && drop_list && drop_list.editable && from_list && from_list.editable;
         }
 
@@ -1205,8 +1227,30 @@ function rcube_tasklist_ui(settings)
     function list_remove(id)
     {
         var list = me.tasklists[id];
-        if (list && list.editable) {
-            alert('To be implemented')
+        if (list && list.editable && confirm(rcmail.gettext('deletelistconfirm', 'tasklist'))) {
+            saving_lock = rcmail.set_busy(true, 'tasklist.savingdata');
+            rcmail.http_post('tasklist', { action:'remove', l:{ id:list.id } });
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Callback from server to finally remove the given list
+     */
+    function destroy_list(prop)
+    {
+        var list = me.tasklists[prop.id],
+            li = rcmail.get_folder_li(prop.id, 'rcmlitasklist');
+
+        if (li) {
+            $(li).remove();
+        }
+        if (list) {
+            list.active = false;
+            // delete me.tasklists[prop.id];
+            unlock_saving();
+            remove_tasks(list.id);
         }
     }
 
@@ -1220,8 +1264,8 @@ function rcube_tasklist_ui(settings)
             .append('<span class="handle"> </span>')
             .append('<span class="listname">'+Q(prop.name)+'</span>');
         $(rcmail.gui_objects.folderlist).append(li);
-        init_tasklist_li(li.get(0), prop.id);
         me.tasklists[prop.id] = prop;
+        init_tasklist_li(li.get(0), prop.id);
     }
 
     /**
@@ -1358,7 +1402,8 @@ function rcube_tasklist_ui(settings)
             if (me.tasklists[id]) {  // add or remove event source on click
                 me.tasklists[id].active = this.checked;
                 fetch_counts();
-                list_tasks(null);
+                if (!this.checked) remove_tasks(id);
+                else               list_tasks(null);
                 rcmail.http_post('tasklist', { action:'subscribe', l:{ id:id, active:me.tasklists[id].active?1:0 } });
             }
         }).data('id', id).get(0).checked = me.tasklists[id].active || false;
@@ -1366,7 +1411,7 @@ 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].editable);
+            rcmail.enable_command('list-edit', 'list-remove', 'list-import', me.tasklists[id].editable);
             me.selected_list = id;
         })
         .dblclick(function(e){
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index 0bf0a6f..88f87fa 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -143,6 +143,8 @@ class tasklist extends rcube_plugin
             $this->driver = new $driver_class($this);
             break;
         }
+
+        $this->rc->output->set_env('tasklist_driver', $driver_name);
     }
 
 
@@ -363,7 +365,7 @@ class tasklist extends rcube_plugin
 
         switch ($action) {
         case 'new':
-            $list += array('showalarms' => true, 'active' => true);
+            $list += array('showalarms' => true, 'active' => true, 'editable' => true);
             if ($insert_id = $this->driver->create_list($list)) {
                 $list['id'] = $insert_id;
                 $this->rc->output->command('plugin.insert_tasklist', $list);
@@ -383,6 +385,11 @@ class tasklist extends rcube_plugin
         case 'subscribe':
             $success = $this->driver->subscribe_list($list);
             break;
+
+        case 'remove':
+            if (($success = $this->driver->remove_list($list)))
+                $this->rc->output->command('plugin.destroy_tasklist', $list);
+            break;
         }
 
         if ($success)


commit 44635a867de5b6c4434e0148d8267e13c357406c
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Tue Sep 18 18:43:32 2012 +0200

    Fix move command to Kolab backend

diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index f9648e8..010be7b 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -678,7 +678,7 @@ class tasklist_kolab_driver extends tasklist_driver
 
         // execute move command
         if ($task['_fromlist'] && ($fromfolder = $this->folders[$task['_fromlist']])) {
-            return $fromfolder->move($task['uid'], $folder->name);
+            return $fromfolder->move($task['id'], $folder->name);
         }
 
         return false;


commit 05a1cb527d33e5cd6c0b426376c17efda0347d93
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Tue Sep 18 08:53:24 2012 +0200

    Allow to drag&drop tasks to another list

diff --git a/plugins/tasklist/drivers/database/tasklist_database_driver.php b/plugins/tasklist/drivers/database/tasklist_database_driver.php
index 3cbddb3..4a0c80b 100644
--- a/plugins/tasklist/drivers/database/tasklist_database_driver.php
+++ b/plugins/tasklist/drivers/database/tasklist_database_driver.php
@@ -511,6 +511,18 @@ class tasklist_database_driver extends tasklist_driver
     }
 
     /**
+     * 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
      *
      * @param array   Hash array with task properties
diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index f3e902a..f9648e8 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -664,6 +664,27 @@ class tasklist_kolab_driver extends tasklist_driver
     }
 
     /**
+     * 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
      *
      * @param array   Hash array with task properties:
diff --git a/plugins/tasklist/drivers/tasklist_driver.php b/plugins/tasklist/drivers/tasklist_driver.php
index 0d3a365..4e987f6 100644
--- a/plugins/tasklist/drivers/tasklist_driver.php
+++ b/plugins/tasklist/drivers/tasklist_driver.php
@@ -176,6 +176,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
      *
      * @param array   Hash array with task properties:
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index 36c30f2..e4ebc20 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -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;
-
-        if (rec && parent.length) {
-            // submit changes to server
-            rec.parent_id = parent_id || 0;
-            save_task(rec, 'edit');
-
-            li = ui.draggable.parent();
-            li.slideUp(300, function(){
-                li.appendTo(parent);
-                resort_task(rec, li);
-                li.slideDown(300);
-            });
+            parent, li;
+
+        // 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)
+
+            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');
     }
 
 
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index f01e238..0bf0a6f 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -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');





More information about the commits mailing list