diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 67fccb6d..9b342c54 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -1991,6 +1991,8 @@ class calendar extends rcube_plugin $this->lib->attachment = $attachment; $this->register_handler('plugin.attachmentframe', array($this->lib, 'attachment_frame')); $this->register_handler('plugin.attachmentcontrols', array($this->lib, 'attachment_header')); + $this->rc->output->set_env('filename', $attachment['name']); + $this->rc->output->set_env('mimetype', $attachment['mimetype']); $this->rc->output->send('calendar.attachment'); } // deliver attachment content diff --git a/plugins/kolab_tags/kolab_tags.js b/plugins/kolab_tags/kolab_tags.js index dfb0e5e9..c412cb2f 100644 --- a/plugins/kolab_tags/kolab_tags.js +++ b/plugins/kolab_tags/kolab_tags.js @@ -26,7 +26,7 @@ */ window.rcmail && rcmail.addEventListener('init', function() { - if (rcmail.task == 'mail' || rcmail.task == 'notes') { + if (/^(mail|notes|tasks)$/.test(rcmail.task)) { var msg_view = rcmail.env.action == 'show' || rcmail.env.action == 'preview'; if (!msg_view && rcmail.env.action) { @@ -124,6 +124,9 @@ function main_list_widget() if (rcmail.task == 'notes' && rcmail.noteslist) return rcmail.noteslist; + + if (rcmail.task == 'tasks' && rcmail.gui_objects.resultlist) + return rcmail.gui_objects.resultlist; } // fills tag cloud with tags list @@ -1157,3 +1160,22 @@ function tag_droppable_accept(draggable) return true; } + +// Convert list of tag names into "blocks" and add to the specified element +function kolab_tags_text_block(tags, element, del_btn) +{ + if (tags && tags.length) { + var items = []; + + tags.sort(); + + $.each(tags, function(i,val) { + var tag = tag_find(val, 'name'); + if (tag) { + items.push(tag_box_element(tag, del_btn)); + } + }); + + $(element).append(items); + } +}; diff --git a/plugins/kolab_tags/kolab_tags.php b/plugins/kolab_tags/kolab_tags.php index b4fff996..ec47f7f3 100644 --- a/plugins/kolab_tags/kolab_tags.php +++ b/plugins/kolab_tags/kolab_tags.php @@ -23,7 +23,7 @@ class kolab_tags extends rcube_plugin { - public $task = 'mail|notes'; + public $task = 'mail|notes|tasks'; public $rc; public $home; diff --git a/plugins/kolab_tags/skins/elastic/templates/ui.html b/plugins/kolab_tags/skins/elastic/templates/ui.html index 728d4e8e..996bc6ac 100644 --- a/plugins/kolab_tags/skins/elastic/templates/ui.html +++ b/plugins/kolab_tags/skins/elastic/templates/ui.html @@ -28,7 +28,7 @@ $(document).ready(function(e) { // put tags cloud under folders list var tagcloud = $('#tagcloud').detach(); - $('#folderlist-content,#notebooks-content').children('ul:first').after(tagcloud.show()); + $('#folderlist-content,#notebooks-content,#tasklists-content').children('ul:first').after(tagcloud.show()); // add tag message menu positions to Mark menu var menu = $('#tagmessagemenu li').detach(); @@ -36,7 +36,7 @@ $(document).ready(function(e) { // add tags management menu positions to folder actions menu menu = $('#tagsmenu li').detach(); - $('#mailboxoptions-menu,#notebookactions-menu').find('ul').append(menu); + $('#mailboxoptions-menu,#notebookactions-menu,#tasklistactions-menu').find('ul').append(menu); // Apply tags colors in Elastic-way rcmail.addEventListener('kolab-tags-update', function() { diff --git a/plugins/kolab_tags/skins/larry/templates/ui.html b/plugins/kolab_tags/skins/larry/templates/ui.html index ffa02531..b4606f2a 100644 --- a/plugins/kolab_tags/skins/larry/templates/ui.html +++ b/plugins/kolab_tags/skins/larry/templates/ui.html @@ -26,7 +26,6 @@ - + + diff --git a/plugins/tasklist/skins/elastic/templates/print.html b/plugins/tasklist/skins/elastic/templates/print.html new file mode 100644 index 00000000..04b1f7ff --- /dev/null +++ b/plugins/tasklist/skins/elastic/templates/print.html @@ -0,0 +1,15 @@ + + +
+
+ + + +
+
+ +
+ +
+ + diff --git a/plugins/tasklist/skins/elastic/templates/taskedit.html b/plugins/tasklist/skins/elastic/templates/taskedit.html new file mode 100644 index 00000000..f262b003 --- /dev/null +++ b/plugins/tasklist/skins/elastic/templates/taskedit.html @@ -0,0 +1,127 @@ + diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css index 4b47f63a..0241dc34 100644 --- a/plugins/tasklist/skins/larry/tasklist.css +++ b/plugins/tasklist/skins/larry/tasklist.css @@ -64,17 +64,9 @@ ul.toolbarmenu li span.icon.taskadd, width: 15px; } -#tagsbox { - position: absolute; - top: 42px; - left: 0; - width: 100%; - height: 242px; -} - #tasklistsbox { position: absolute; - top: 300px; + top: 42px; left: 0; width: 100%; bottom: 0px; @@ -105,7 +97,6 @@ ul.toolbarmenu li span.icon.taskadd, top: 68px; } - #taskselector { margin: -1px 40px 0 0; padding: 0; @@ -118,7 +109,6 @@ ul.toolbarmenu li span.icon.taskadd, padding-right: 0.3em; } -.tagcloud li, #taskselector li a { display: inline-block; color: #004458; @@ -130,12 +120,10 @@ ul.toolbarmenu li span.icon.taskadd, border-color: transparent; } -.webkit .tagcloud li, .webkit #taskselector li a { padding-bottom: 0.25em; } - #taskselector li:first-child { border-top: 0; border-radius: 4px 4px 0 0; @@ -155,7 +143,6 @@ ul.toolbarmenu li span.icon.taskadd, color: #97b3bf; } -.tagcloud li.selected, #taskselector li.selected a { color: #fff; background: #005d76; @@ -201,51 +188,6 @@ ul.toolbarmenu li span.icon.taskadd, border-color: #ff3800 transparent; } -.tagcloud { - padding: 0; - margin: 6px; - list-style: none; -} - -.tagcloud li { - display: inline-block; - color: #004458; - padding-right: 0.2em; - margin-right: 0.3em; - margin-bottom: 0.4em; - min-width: 1.2em; - cursor: pointer; -} - -.tagcloud li.inactive { - color: #89b3be; - padding-right: 0.6em; - font-size: 80%; -/* display: none; */ -} - -.tagcloud li .count { - position: relative; - top: -1px; - margin-left: 5px; - padding: 0.2em 0.5em; - font-size: 80%; - font-weight: bold; - color: #59838e; - background: #c7e3ef; - border: 1px solid #b0ccd7; - border-radius: 8px; -} - -.tagcloud li.selected .count { - border: none; -} - -.tag-draghelper .tag .count, -.tagcloud li.inactive .count { - display: none; -} - #tasklistsbox .treelist li { margin: 0; display: block; @@ -280,7 +222,7 @@ ul.toolbarmenu li span.icon.taskadd, display: block; } -#tasklistsbox .treelist li span.listname { +#tasklistsbox .treelist li a.listname { display: block; position: absolute; top: 7px; @@ -296,11 +238,11 @@ ul.toolbarmenu li span.icon.taskadd, } .quickview-active #tasklistsbox .treelist li input, -.quickview-active #tasklistsbox .treelist li span.listname { +.quickview-active #tasklistsbox .treelist li a.listname { opacity: 0.35; } -.quickview-active #tasklistsbox .treelist div.focusview span.listname { +.quickview-active #tasklistsbox .treelist div.focusview a.listname { opacity: 1.0; } @@ -381,19 +323,19 @@ ul.toolbarmenu li span.icon.taskadd, outline: 2px solid rgba(30,150,192, 0.5); } -#tasklistsbox .treelist li.selected > div > span.listname { +#tasklistsbox .treelist li.selected > div > a.listname { font-weight: bold; } -#tasklistsbox .treelist .readonly > span.listname { +#tasklistsbox .treelist .readonly > a.listname { background-position: right -142px; } -#tasklistsbox .treelist .user > span.listname { +#tasklistsbox .treelist .user > a.listname { background-position: right -160px; } -#tasklistsbox .treelist .virtual > span.listname { +#tasklistsbox .treelist .virtual > a.listname { color: #aaa; top: 4px; left: 20px; @@ -1019,14 +961,14 @@ a.morelink:hover { display: block; color: #333; font-weight: bold; - padding: 3px 4px 3px 30px; + padding: 2px 4px 2px 30px; text-shadow: 0px 1px 1px #fff; text-decoration: none; white-space: nowrap; line-height: 20px; } -#taskedit-attachments ul li a.file { +#taskedit-attachments ul li a.filename { padding: 0; } @@ -1243,7 +1185,7 @@ label.block { min-height: 290px; } -.tasklistview .uidialog .propform #taskedit-tasklistame { +.tasklistview .uidialog .propform #taskedit-tasklistname { width: 20em; } @@ -1486,10 +1428,11 @@ div.messagetasklinks .messagetaskref input.complete { padding-right: 0; } - -/** Special hacks for IE7 **/ -/** They need to be in this file to also affect the task-create dialog embedded in mail view **/ - -html.ie7 #taskedit-completeness-slider { - display: inline; +.form-section label + div { + line-height: 2; + vertical-align: top; +} + +.form-section label + div { + display: inline-block; } diff --git a/plugins/tasklist/skins/larry/templates/kolabacl.html b/plugins/tasklist/skins/larry/templates/kolabacl.html deleted file mode 100644 index 1cf26fc7..00000000 --- a/plugins/tasklist/skins/larry/templates/kolabacl.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -<roundcube:object name="pagetitle" /> - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/tasklist/skins/larry/templates/listform.html b/plugins/tasklist/skins/larry/templates/listform.html new file mode 100644 index 00000000..0fd3b63c --- /dev/null +++ b/plugins/tasklist/skins/larry/templates/listform.html @@ -0,0 +1,18 @@ + + + +<roundcube:object name="pagetitle" /> + + + + +

:

+ +
+ +
+ + + + + diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html index ca40df13..ea4a5c11 100644 --- a/plugins/tasklist/skins/larry/templates/mainview.html +++ b/plugins/tasklist/skins/larry/templates/mainview.html @@ -22,13 +22,6 @@ -
-

-
- -
-
- diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js index 67c958ba..a4951e2a 100644 --- a/plugins/tasklist/tasklist.js +++ b/plugins/tasklist/tasklist.js @@ -58,7 +58,6 @@ function rcube_tasklist_ui(settings) }; /* private vars */ - var tagsfilter = []; var filtermask = FILTER_MASK_ALL; var loadstate = { filter:-1, lists:'', search:null }; var idcount = 0; @@ -69,13 +68,12 @@ function rcube_tasklist_ui(settings) var taskcounts = {}; var listindex = []; var listdata = {}; - var tags = []; + var tagsfilter = []; var draghelper; var search_request; var search_query; var completeness_slider; var task_draghelper; - var tag_draghelper; var task_drag_active = false; var list_scroll_top = 0; var scroll_delay = 400; @@ -93,11 +91,11 @@ function rcube_tasklist_ui(settings) // general datepicker settings var datepicker_settings = { // translate from PHP format to datepicker format - dateFormat: settings['date_format'].replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'), - firstDay : settings['first_day'], -// dayNamesMin: settings['days_short'], -// monthNames: settings['months'], -// monthNamesShort: settings['months'], + dateFormat: settings.date_format.replace(/M/g, 'm').replace(/mmmmm/, 'MM').replace(/mmm/, 'M').replace(/dddd/, 'DD').replace(/ddd/, 'D').replace(/yy/g, 'y'), + firstDay : settings.first_day, +// dayNamesMin: settings.days_short, +// monthNames: settings.months, +// monthNamesShort: settings.months, changeMonth: false, showOtherMonths: true, selectOtherMonths: true @@ -122,6 +120,8 @@ function rcube_tasklist_ui(settings) this.list_remove = list_remove; this.list_showurl = list_showurl; this.list_edit_dialog = list_edit_dialog; + this.list_set_sort_and_order = list_set_sort_and_order; + this.get_setting = get_setting; this.unlock_saving = unlock_saving; /* imports */ @@ -211,6 +211,13 @@ function rcube_tasklist_ui(settings) rcmail.display_message(rcmail.gettext('notasklistsfound','tasklist'), 'info'); }); + // Make Elastic checkboxes pretty + if (window.UI && UI.pretty_checkbox) { + tasklists_widget.addEventListener('add-item', function(prop) { + UI.pretty_checkbox($(prop.li).find('input').addClass('flex-checkbox')); + }); + } + // init (delegate) event handler on tasklist checkboxes tasklists_widget.container.on('click', 'input[type=checkbox]', function(e) { var list, id = this.value; @@ -344,57 +351,6 @@ function rcube_tasklist_ui(settings) return false; }).find('input[type=text]').placeholder(rcmail.gettext('createnewtask','tasklist')); - // click-handler on tags list - $(rcmail.gui_objects.tagslist).on('click', 'li', function(e){ - var item = e.target.nodeName == 'LI' ? $(e.target) : $(e.target).closest('li'), - tag = item.data('value'); - - if (!tag) - return false; - - // reset selection on regular clicks - var index = $.inArray(tag, tagsfilter); - var shift = e.shiftKey || e.ctrlKey || e.metaKey; - - if (!shift) { - if (tagsfilter.length > 1) - index = -1; - - $('li', rcmail.gui_objects.tagslist).removeClass('selected').attr('aria-checked', 'false'); - tagsfilter = []; - } - - // add tag to filter - if (index < 0) { - item.addClass('selected').attr('aria-checked', 'true'); - tagsfilter.push(tag); - } - else if (shift) { - item.removeClass('selected').attr('aria-checked', 'false'); - var a = tagsfilter.slice(0,index); - tagsfilter = a.concat(tagsfilter.slice(index+1)); - } - - list_tasks(); - - // clear text selection in IE after shift+click - if (shift && document.selection) - document.selection.empty(); - - e.preventDefault(); - return false; - }) - .on('keypress', 'li', function(e) { - if (e.keyCode == 13) { - $(this).trigger('click', { pointerType:'keyboard' }); - } - }) - .mousedown(function(e){ - // disable content selection with the mouse - e.preventDefault(); - return false; - }); - // click-handler on task list items (delegate) $(rcmail.gui_objects.resultlist).on('click', function(e){ var item = $(e.target); @@ -419,7 +375,7 @@ function rcube_tasklist_ui(settings) case 'childtoggle': rec.collapsed = !rec.collapsed; li.children('.childtasks:first').toggle().attr('aria-hidden', rec.collapsed ? 'true' : 'false'); - $(e.target).toggleClass('collapsed').html(rec.collapsed ? '▶' : '▼'); + $(e.target).toggleClass('collapsed').html('').append($('').text(rec.collapsed ? '▶' : '▼')); rcmail.http_post('tasks/task', { action:'collapse', t:{ id:rec.id, list:rec.list }, collapsed:rec.collapsed?1:0 }); if (e.shiftKey) // expand/collapse all childs li.children('.childtasks:first .childtoggle.'+(rec.collapsed?'expanded':'collapsed')).click(); @@ -447,7 +403,7 @@ function rcube_tasklist_ui(settings) return false; var link = $(e.target).html(''), - input = $('').appendTo(link).val(rec.date || '') + input = $('').appendTo(link).val(rec.date || ''); input.datepicker($.extend({ onClose: function(dateText, inst) { @@ -487,8 +443,11 @@ function rcube_tasklist_ui(settings) return true; default: - if (e.target.nodeName != 'INPUT') + if (e.target.nodeName != 'INPUT') { task_show_dialog(id); + $(rcmail.gui_objects.resultlist).find('.selected').removeClass('selected'); + $(item).addClass('selected'); + } break; } @@ -507,6 +466,9 @@ function rcube_tasklist_ui(settings) task_edit_dialog(id, 'edit'); clearSelection(); } + + $(rcmail.gui_objects.resultlist).find('.selected').removeClass('selected'); + $(item).addClass('selected'); }) .on('keydown', '.taskhead', function(e) { if (e.target.nodeName == 'INPUT' && e.target.type == 'text') @@ -556,12 +518,16 @@ function rcube_tasklist_ui(settings) focused_subclass = item.get(0) !== e.target ? e.target.className : null; } } + + $(item).addClass('focused'); }) .on('focusout', '.taskhead', function(e){ var item = $(e.target); if (focused_task && item.data('id') == focused_task) { focused_task = focused_subclass = null; } + + $(item).removeClass('focused'); }); /** @@ -649,6 +615,35 @@ function rcube_tasklist_ui(settings) }, 1); } }, datepicker_settings); + + rcmail.addEventListener('kolab-tags-search', filter_tasks) +/* + // TODO + .addEventListener('kolab-tags-drop-data', function(e) { return notesdata[e.id]; }) + .addEventListener('kolab-tags-drop', function(e) { + if ($(e.list).is('#kolabnoteslist')) { + return; + } + + var rec = notesdata[e.id]; + + if (rec && rec.id && e.tag) { + savedata = me.selected_note && rec.uid == me.selected_note.uid ? get_save_data() : $.extend({}, rec); + + if (savedata.id) delete savedata.id; + if (savedata.html) delete savedata.html; + + if (!savedata.tags) + savedata.tags = []; + savedata.tags.push(e.tag); + + rcmail.lock_form(rcmail.gui_objects.noteseditform, true); + saving_lock = rcmail.set_busy(true, 'kolab_notes.savingdata'); + rcmail.http_post('action', { _data: savedata, _do: 'edit' }, true); + } + }); +*/ + rcmail.triggerEvent('tasklist-init'); } /** @@ -656,18 +651,23 @@ function rcube_tasklist_ui(settings) */ function init_taskedit() { - $('#taskedit').tabs({ + $('#taskedit:not([data-notabs])').tabs({ activate: function(event, ui) { // reset autocompletion on tab change (#3389) rcmail.ksearch_blur(); } }); - var completeness_slider_change = function(e, ui){ - var v = completeness_slider.slider('value'); - if (v >= 98) v = 100; - if (v <= 2) v = 0; - $('#taskedit-completeness').val(v); + $('#taskedit li.nav-item a').on('click', function() { + // reset autocompletion on tab change (#3389) + rcmail.ksearch_blur(); + }); + + var completeness_slider_change = function(e, ui) { + var v = completeness_slider.slider('value'); + if (v >= 98) v = 100; + if (v <= 2) v = 0; + $('#taskedit-completeness').val(v); }; completeness_slider = $('#taskedit-completeness-slider').slider({ range: 'min', @@ -691,46 +691,47 @@ function rcube_tasklist_ui(settings) return false; }); - // init attendees autocompletion - var ac_props; - // parallel autocompletion - if (rcmail.env.autocomplete_threads > 0) { - ac_props = { - threads: rcmail.env.autocomplete_threads, - sources: rcmail.env.autocomplete_sources - }; - } - rcmail.init_address_input_events($('#edit-attendee-name'), ac_props); - rcmail.addEventListener('autocomplete_insert', function(e) { - var success = false; - if (e.field.name == 'participant') { - success = add_attendees(e.insert, { role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype:(e.data && e.data.type == 'group' ? 'GROUP' : 'INDIVIDUAL') }); - } - if (e.field && success) { - e.field.value = ''; - } - }); + // init attendees autocompletion + var ac_props; + // parallel autocompletion + if (rcmail.env.autocomplete_threads > 0) { + ac_props = { + threads: rcmail.env.autocomplete_threads, + sources: rcmail.env.autocomplete_sources + }; + } + rcmail.init_address_input_events($('#edit-attendee-name'), ac_props); + rcmail.addEventListener('autocomplete_insert', function(e) { + var cutype, success = false; + if (e.field.name == 'participant') { + cutype = e.data && e.data.type == 'group' ? 'GROUP' : 'INDIVIDUAL'; + success = add_attendees(e.insert, { role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype: cutype }); + } + if (e.field && success) { + e.field.value = ''; + } + }); - $('#edit-attendee-add').click(function() { - var input = $('#edit-attendee-name'); - rcmail.ksearch_blur(); - if (add_attendees(input.val(), { role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype:'INDIVIDUAL' })) { - input.val(''); - } - }); + $('#edit-attendee-add').click(function() { + var input = $('#edit-attendee-name'); + rcmail.ksearch_blur(); + if (add_attendees(input.val(), { role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype:'INDIVIDUAL' })) { + input.val(''); + } + }); - // handle change of "send invitations" checkbox - $('#edit-attendees-invite').change(function() { - $('#edit-attendees-donotify,input.edit-attendee-reply').prop('checked', this.checked); - // hide/show comment field - $('#taskeditform .attendees-commentbox')[this.checked ? 'show' : 'hide'](); - }); + // handle change of "send invitations" checkbox + $('#edit-attendees-invite').change(function() { + $('#edit-attendees-donotify,input.edit-attendee-reply').prop('checked', this.checked); + // hide/show comment field + $('#taskeditform .attendees-commentbox')[this.checked ? 'show' : 'hide'](); + }); - // delegate change task to "send invitations" checkbox - $('#edit-attendees-donotify').change(function() { - $('#edit-attendees-invite').click(); - return false; - }); + // delegate change task to "send invitations" checkbox + $('#edit-attendees-donotify').change(function() { + $('#edit-attendees-invite').click(); + return false; + }); // configure drop-down menu on time input fields based on jquery UI autocomplete $('#taskedit-starttime, #taskedit-time').each(function() { @@ -788,6 +789,15 @@ function rcube_tasklist_ui(settings) $('#taskselector li.all').addClass('selected').attr('aria-checked', 'true'); } + /** + * Filter tasks by tag + */ + function filter_tasks(tags) + { + tagsfilter = tags; + list_tasks(); + } + /** * Remove all tasks of the given list from the UI */ @@ -811,8 +821,8 @@ function rcube_tasklist_ui(settings) { // close show dialog first var buttons = {}, - $dialog = $("#tasksimport"), - form = rcmail.gui_objects.importform; + $dialog = $("#tasksimport").clone(true).removeClass('uidialog'), + form = $dialog.find('form').get(0); if ($dialog.is(':ui-dialog')) $dialog.dialog('close'); @@ -845,32 +855,22 @@ function rcube_tasklist_ui(settings) }; buttons[rcmail.gettext('cancel', 'tasklist')] = function() { - $dialog.dialog("close"); + $(this).dialog('close'); }; // open jquery UI dialog - $dialog.dialog({ - modal: true, - resizable: false, + this.import_dialog = rcmail.show_popup_dialog($dialog, rcmail.gettext('tasklist.importtasks'), buttons, { closeOnEscape: false, - title: rcmail.gettext('importtasks', 'tasklist'), - open: function() { - $dialog.parent().find('.ui-dialog-buttonset .ui-button').first().addClass('mainaction'); - }, - close: function() { - $('.ui-dialog-buttonpane button', $dialog.parent()).button('enable'); - $dialog.dialog("destroy").hide(); - }, - buttons: buttons, - width: 520 - }).show(); + button_classes: ['import mainaction', 'cancel'], + close: null // do not remove the $dialog element + }); }; // callback from server if import succeeded this.import_success = function(p) { this.import_succeeded = true; - $("#tasksimport:ui-dialog").dialog('close'); + this.import_dialog.dialog('close'); rcmail.set_busy(false, null, saving_lock); saving_lock = null; rcmail.gui_objects.importform.reset(); @@ -893,85 +893,71 @@ function rcube_tasklist_ui(settings) // open a tasks export dialog this.export_tasks = function() { - // close show dialog first - var $dialog = $("#tasksexport"), - form = rcmail.gui_objects.exportform, - buttons = {}; + // close show dialog first + var $dialog = $("#tasksexport").clone(true).removeClass('uidialog'), + form = $dialog.find('form').get(0), + buttons = {}; - if (!form) - return; + if ($dialog.is(':ui-dialog')) + $dialog.dialog('close'); - if ($dialog.is(':ui-dialog')) - $dialog.dialog('close'); + $("#task-export-list").val(''); - $("#task-export-list").val(''); + buttons[rcmail.gettext('export', 'tasklist')] = function() { + var data = {}, + source = $('#task-export-list').val(), + form_elements = $('select, input', form); - buttons[rcmail.gettext('export', 'tasklist')] = function() { - var data = {}, - source = $('#task-export-list option:selected').val(), - form_elements = $('select, input', form); + // "current view" export, use hidden form to POST task IDs + if (source === '') { + var cache = {}, tasks = [], inputs = [], + postform = $('#tasks-export-form-post'); - // "current view" export, use hidden form to POST task IDs - if (source === '') { - var cache = {}, tasks = [], inputs = [], - postform = $('#tasks-export-form-post'); + $.each(listindex || [], function() { + var rec = listdata[this]; + if (match_filter(rec, cache)) { + tasks.push(rec.id); + } + }); - $.each(listindex || [], function() { - var rec = listdata[this]; - if (match_filter(rec, cache)) { - tasks.push(rec.id); + // copy form inputs, there may be controls added by other plugins + form_elements.each(function() { + if (this.type != 'checkbox' || this.checked) + inputs.push($('').attr({type: 'hidden', name: this.name, value: this.value})); + }); + + inputs.push($('').attr({type: 'hidden', name: '_token', value: rcmail.env.request_token})); + inputs.push($('').attr({type: 'hidden', name: 'id', value: tasks.join(',')})); + + if (!postform.length) + postform = $('
') + .attr({style: 'display: none', method: 'POST', action: '?_task=tasks&_action=export'}) + .appendTo('body'); + + postform.html('').append(inputs).submit(); } - }); + // otherwise we can use simple GET + else { + form_elements.each(function() { + if (this.type != 'checkbox' || this.checked) + data[this.name] = $(this).val(); + }); - // copy form inputs, there may be controls added by other plugins - form_elements.each(function() { - if (this.type != 'checkbox' || this.checked) - inputs.push($('').attr({type: 'hidden', name: this.name, value: this.value})); - }); + rcmail.goto_url('export', data, false); + } - inputs.push($('').attr({type: 'hidden', name: '_token', value: rcmail.env.request_token})); - inputs.push($('').attr({type: 'hidden', name: 'id', value: tasks.join(',')})); + $(this).dialog('close'); + }; - if (!postform.length) - postform = $('') - .attr({style: 'display: none', method: 'POST', action: '?_task=tasks&_action=export'}) - .appendTo('body'); + buttons[rcmail.gettext('cancel', 'tasklist')] = function() { + $(this).dialog('close'); + }; - postform.html('').append(inputs).submit(); - } - // otherwise we can use simple GET - else { - form_elements.each(function() { - if (this.type != 'checkbox' || this.checked) - data[this.name] = $(this).val(); - }); - - rcmail.goto_url('export', data); - } - - $dialog.dialog("close"); - }; - - buttons[rcmail.gettext('cancel', 'tasklist')] = function() { - $dialog.dialog("close"); - }; - - // open jquery UI dialog - $dialog.dialog({ - modal: true, - resizable: false, - closeOnEscape: false, - title: rcmail.gettext('exporttitle', 'tasklist'), - open: function() { - $dialog.parent().find('.ui-dialog-buttonset .ui-button').first().addClass('mainaction'); - }, - close: function() { - $('.ui-dialog-buttonpane button', $dialog.parent()).button('enable'); - $dialog.dialog("destroy").hide(); - }, - buttons: buttons, - width: 520 - }).show(); + // open jquery UI dialog + rcmail.show_popup_dialog($dialog, rcmail.gettext('exporttitle', 'tasklist'), buttons, { + button_classes: ['export mainaction', 'cancel'], + close: null // do not remove the $dialog element + }); }; /* // download the selected task as iCal @@ -982,7 +968,6 @@ function rcube_tasklist_ui(settings) } }; */ - /** * Modify query parameters for refresh requests */ @@ -1020,7 +1005,7 @@ function rcube_tasklist_ui(settings) // sort index before rendering listindex.sort(function(a, b) { return task_cmp(listdata[a], listdata[b]); }); - append_tags(response.tags || []); + update_taglist(response.tags || []); render_tasklist(); // show selected task dialog @@ -1078,7 +1063,7 @@ function rcube_tasklist_ui(settings) return; fix_tree_toggles(); - update_tagcloud(activetags); + update_taglist();//activetags); if (!count) { msgbox.html(rcmail.gettext('notasksfound','tasklist')).show(); @@ -1097,7 +1082,7 @@ function rcube_tasklist_ui(settings) childs = $('.childtasks li', li); $('.childtoggle', li)[(childs.length ? 'show' : 'hide')](); - }) + }); } /** @@ -1111,7 +1096,7 @@ function rcube_tasklist_ui(settings) $('.taskitem .childtoggle') .removeClass(collapsed ? 'expanded' : 'collapsed') .addClass(collapsed ? 'collapsed' : 'expanded') - .html(collapsed ? '▶' : '▼'); + .html('').append($('').text(collapsed ? '▶' : '▼')); // store new toggle collapse states var ids = []; @@ -1124,131 +1109,29 @@ function rcube_tasklist_ui(settings) } } - /** - * - */ - function append_tags(taglist) - { - // find new tags - var newtags = []; - for (var i=0; i < taglist.length; i++) { - if ($.inArray(taglist[i], tags) < 0) - newtags.push(taglist[i]); - } - tags = tags.concat(newtags); - - // append new tags to tag cloud - $.each(newtags, function(i, tag){ - $('
  • ') - .attr('rel', tag) - .data('value', tag) - .html(Q(tag) + '') - .appendTo(rcmail.gui_objects.tagslist) - .draggable({ - addClasses: false, - revert: 'invalid', - revertDuration: 300, - helper: tag_draggable_helper, - start: tag_draggable_start, - appendTo: 'body', - cursor: 'pointer' - }); - }); - - // re-sort tags list - $(rcmail.gui_objects.tagslist).children('li').sortElements(function(a,b){ - return $.text([a]).toLowerCase() > $.text([b]).toLowerCase() ? 1 : -1; - }); - } - /** * Display the given counts to each tag and set those inactive which don't * have any matching tasks in the current view. */ - function update_tagcloud(counts) + function update_taglist(tags) { - // compute counts first by iterating over all visible task items - if (typeof counts == 'undefined') { - counts = {}; - $('li.taskitem', rcmail.gui_objects.resultlist).each(function(i,li){ - var t, id = $(li).attr('rel'), - rec = listdata[id]; - for (var j=0; rec && rec.tags && j < rec.tags.length; j++) { - t = rec.tags[j]; - if (typeof counts[t] == 'undefined') - counts[t] = 0; - counts[t]++; - } - }); - } - - $(rcmail.gui_objects.tagslist).children('li').each(function(i,li){ - var elem = $(li), tag = elem.attr('rel'), - count = counts[tag] || 0; - - elem.children('.count').html(count+''); - if (count == 0) elem.addClass('inactive'); - else elem.removeClass('inactive'); + var counts = {}; + $.each(listdata, function(id, rec) { + for (var t, j=0; rec && rec.tags && j < rec.tags.length; j++) { + t = rec.tags[j]; + if (typeof counts[t] == 'undefined') + counts[t] = 0; + counts[t]++; + } }); - } - /* Helper functions for drag & drop functionality of tags */ - - function tag_draggable_helper() - { - if (!tag_draghelper) - tag_draghelper = $('
    '); - else - tag_draghelper.html(''); + rcmail.triggerEvent('kolab-tags-counts', {counter: counts}); - $(this).clone().addClass('tag').appendTo(tag_draghelper); - return tag_draghelper; - } - - function tag_draggable_start(event, ui) - { - $('.taskhead').droppable({ - hoverClass: 'droptarget', - accept: tag_droppable_accept, - drop: tag_draggable_dropped, - addClasses: false - }); - } - - function tag_droppable_accept(draggable) - { - if (rcmail.busy) - return false; - - var tag = draggable.data('value'), - drop_id = $(this).data('id'), - drop_rec = listdata[drop_id], - list = drop_rec && me.tasklists[drop_rec.list] ? me.tasklists[drop_rec.list] : { editable:true }; - - // target is not editable or already has this tag assigned - if (!drop_rec || drop_rec.readonly || !me.has_permission(list, 'i') || (drop_rec.tags && $.inArray(tag, drop_rec.tags) >= 0)) { - return false; - } - - return true; - } - - function tag_draggable_dropped(event, ui) - { - var drop_id = $(this).data('id'), - tag = ui.draggable.data('value'), - rec = listdata[drop_id]; - - if (rec && rec.id) { - if (!rec.tags) rec.tags = []; - rec.tags.push(tag); - save_task(rec, 'edit'); + if (tags && tags.length) { + rcmail.triggerEvent('kolab-tags-refresh', {tags: tags}); } } - /** - * - */ function update_counts(counts) { // got new data @@ -1333,8 +1216,7 @@ function rcube_tasklist_ui(settings) $('li[rel="'+id+'"]', rcmail.gui_objects.resultlist).remove(); } - append_tags(rec.tags || []); - update_tagcloud(); + update_taglist(rec.tags || []); fix_tree_toggles(); // refresh currently displayed task details dialog @@ -1368,8 +1250,8 @@ function rcube_tasklist_ui(settings) var save_task_confirm = function(rec, action, updates) { var data = $.extend({}, rec, updates || {}), - notify = false, partstat = false, html = '', - do_confirm = settings.itip_notify & 2; + notify = false, partstat = false, html = '', + do_confirm = settings.itip_notify & 2; // task has attendees, ask whether to notify them if (me.has_attendees(rec) && me.is_organizer(rec)) { @@ -1383,13 +1265,13 @@ function rcube_tasklist_ui(settings) } // ask whether to change my partstat and notify organizer else if (data._status_before !== undefined && data.status && data._status_before != data.status && me.is_attendee(rec)) { - partstat = true; - if (do_confirm) { - html = rcmail.gettext('partstatupdatenotification', 'tasklist'); - } - else if (settings.itip_notify & 1) { - data._reportpartstat = data.status == 'CANCELLED' ? 'DECLINED' : data.status; - } + partstat = true; + if (do_confirm) { + html = rcmail.gettext('partstatupdatenotification', 'tasklist'); + } + else if (settings.itip_notify & 1) { + data._reportpartstat = data.status == 'CANCELLED' ? 'DECLINED' : data.status; + } } // remove to avoid endless recursion @@ -1402,6 +1284,7 @@ function rcube_tasklist_ui(settings) var buttons = []; buttons.push({ text: rcmail.gettext('saveandnotify', 'tasklist'), + 'class': 'mainaction save notify', click: function() { if (notify) data._notify = 1; if (partstat) data._reportpartstat = data.status == 'CANCELLED' ? 'DECLINED' : data.status; @@ -1411,6 +1294,7 @@ function rcube_tasklist_ui(settings) }); buttons.push({ text: rcmail.gettext('save', 'tasklist'), + 'class': 'save', click: function() { save_task(data, action); $(this).dialog('close'); @@ -1418,10 +1302,11 @@ function rcube_tasklist_ui(settings) }); buttons.push({ text: rcmail.gettext('cancel', 'tasklist'), + 'class': 'cancel', click: function() { $(this).dialog('close'); if (updates) - render_task(rec, rec.id); // restore previous state + render_task(rec, rec.id); // restore previous state } }); @@ -1466,17 +1351,13 @@ function rcube_tasklist_ui(settings) */ function render_task(rec, replace) { - var tags_html = ''; - for (var j=0; rec.tags && j < rec.tags.length; j++) - tags_html += '' + Q(rec.tags[j]) + ''; - var label_id = rcmail.html_identifier(rec.id) + '-title'; var div = $('
    ').addClass('taskhead').html( '
    ' + '' + '' + '' + text2html(Q(rec.title)) + '' + - '' + tags_html + '' + + '' + '' + Q(rec.date || rcmail.gettext('nodate','tasklist')) + '' + '' ) @@ -1495,6 +1376,14 @@ function rcube_tasklist_ui(settings) revertDuration: 300 }); + if (window.kolab_tags_text_block) { + var tags = rec.tags || []; + + if (tags.length) { + window.kolab_tags_text_block(tags, $('.tags', div)); + } + } + if (is_complete(rec)) div.addClass('complete'); if (rec.flagged) @@ -1514,7 +1403,7 @@ function rcube_tasklist_ui(settings) li = $('
  • ') .attr('rel', rec.id) .addClass('taskitem') - .append((rec.collapsed ? '