Elastic: Kolab Notes support, tags functionality refactoring
This commit is contained in:
parent
d406ee4ec0
commit
623cf117ad
15 changed files with 523 additions and 400 deletions
|
@ -1118,7 +1118,7 @@ class kolab_notes extends rcube_plugin
|
|||
$path_imap = explode($delim, $newfolder);
|
||||
$list['name'] = kolab_storage::object_name($newfolder);
|
||||
$list['editname'] = rcube_charset::convert(array_pop($path_imap), 'UTF7-IMAP');
|
||||
$list['listname'] = (!empty($path_imap) ? str_repeat(' ', count($path_imap)) . '» ' : '') . $list['editname'];
|
||||
$list['listname'] = $list['editname'];
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ class kolab_notes_ui
|
|||
*/
|
||||
public function init_templates()
|
||||
{
|
||||
$this->plugin->register_handler('plugin.tagslist', array($this, 'tagslist'));
|
||||
$this->plugin->register_handler('plugin.notebooks', array($this, 'folders'));
|
||||
#$this->plugin->register_handler('plugin.folders_select', array($this, 'folders_select'));
|
||||
$this->plugin->register_handler('plugin.searchform', array($this->rc->output, 'search_form'));
|
||||
|
@ -55,8 +54,6 @@ class kolab_notes_ui
|
|||
$this->rc->output->include_script('treelist.js');
|
||||
$this->plugin->include_script('notes.js');
|
||||
|
||||
jqueryui::tagedit();
|
||||
|
||||
// include kolab folderlist widget if available
|
||||
if (in_array('libkolab', $this->plugin->api->loaded_plugins())) {
|
||||
$this->plugin->api->include_script('libkolab/js/folderlist.js');
|
||||
|
@ -216,13 +213,6 @@ class kolab_notes_ui
|
|||
return html::tag('table', $attrib, '<tbody></tbody>', html::$common_attrib);
|
||||
}
|
||||
|
||||
public function tagslist($attrib)
|
||||
{
|
||||
$attrib += array('id' => 'rcmkolabnotestagslist');
|
||||
$this->rc->output->add_gui_object('notestagslist', $attrib['id']);
|
||||
return html::tag('ul', $attrib, '', html::$common_attrib);
|
||||
}
|
||||
|
||||
public function editform($attrib)
|
||||
{
|
||||
$attrib += array('action' => '#', 'id' => 'rcmkolabnoteseditform');
|
||||
|
@ -267,9 +257,9 @@ class kolab_notes_ui
|
|||
)
|
||||
. html::div('form-group row',
|
||||
html::label(array('class' => 'col-sm-2 col-form-label'), $this->plugin->gettext('kolab_notes.tags'))
|
||||
. html::div(array('class' => 'tagline tagedit col-sm-10', 'style' => 'display:none'), ' ')
|
||||
. html::div(array('class' => 'tagline tagedit col-sm-10'), ' ')
|
||||
)
|
||||
. html::div(array('class' => 'dates', 'style' => 'display:none'),
|
||||
. html::div(array('class' => 'dates text-only', 'style' => 'display:none'),
|
||||
html::div('form-group row',
|
||||
html::label(array('class' => 'col-sm-2 col-form-label'), $this->plugin->gettext('created'))
|
||||
. html::span('col-sm-10', html::span('notecreated form-control-plaintext', ''))
|
||||
|
|
|
@ -36,11 +36,9 @@ function rcube_kolab_notes_ui(settings)
|
|||
var notebookslist;
|
||||
var noteslist;
|
||||
var notesdata = {};
|
||||
var tagsfilter = [];
|
||||
var tags = [];
|
||||
var taglist;
|
||||
var search_request;
|
||||
var search_query;
|
||||
var tag_draghelper;
|
||||
var render_no_focus;
|
||||
var me = this;
|
||||
|
||||
|
@ -273,62 +271,38 @@ function rcube_kolab_notes_ui(settings)
|
|||
$('#notessortmenu a.by-' + settings.sort_col).addClass('selected');
|
||||
}
|
||||
|
||||
// click-handler on tags list
|
||||
$(rcmail.gui_objects.notestagslist).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.notestagslist).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));
|
||||
}
|
||||
|
||||
filter_notes();
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
init_editor();
|
||||
|
||||
if (settings.selected_list) {
|
||||
notebookslist.select(settings.selected_list)
|
||||
}
|
||||
|
||||
rcmail.addEventListener('kolab-tags-search', filter_notes)
|
||||
.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('kolab-notes-init');
|
||||
}
|
||||
this.init = init;
|
||||
|
||||
|
@ -387,7 +361,7 @@ function rcube_kolab_notes_ui(settings)
|
|||
this.init_dialog = init_dialog;
|
||||
|
||||
/**
|
||||
* initialize tinyMCE editor
|
||||
* Initialize TinyMCE editor
|
||||
*/
|
||||
function init_editor(callback)
|
||||
{
|
||||
|
@ -682,24 +656,25 @@ function rcube_kolab_notes_ui(settings)
|
|||
reset_view();
|
||||
noteslist.clear(true);
|
||||
notesdata = {};
|
||||
tagsfilter = [];
|
||||
update_state();
|
||||
}
|
||||
|
||||
function filter_notes()
|
||||
/**
|
||||
* Filter notes by tag
|
||||
*/
|
||||
function filter_notes(tags)
|
||||
{
|
||||
// tagsfilter
|
||||
var id, note, tr, match;
|
||||
for (id in noteslist.rows) {
|
||||
tr = noteslist.rows[id].obj;
|
||||
note = notesdata[id];
|
||||
match = note.tags && note.tags.length;
|
||||
for (var i=0; match && note && i < tagsfilter.length; i++) {
|
||||
if ($.inArray(tagsfilter[i], note.tags) < 0)
|
||||
for (var i=0; match && note && i < tags.length; i++) {
|
||||
if ($.inArray(tags[i], note.tags) < 0)
|
||||
match = false;
|
||||
}
|
||||
|
||||
if (match || !tagsfilter.length) {
|
||||
if (match || !tags.length) {
|
||||
$(tr).show();
|
||||
}
|
||||
else {
|
||||
|
@ -711,9 +686,7 @@ function rcube_kolab_notes_ui(settings)
|
|||
me.selected_note = null;
|
||||
noteslist.clear_selection();
|
||||
}, function(){
|
||||
tagsfilter = [];
|
||||
filter_notes();
|
||||
update_tagcloud();
|
||||
filter_notes(tags);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +721,7 @@ function rcube_kolab_notes_ui(settings)
|
|||
notesdata[rec.id] = rec;
|
||||
}
|
||||
|
||||
render_tagslist(data.tags || [], !data.search)
|
||||
update_taglist();
|
||||
rcmail.set_busy(false, 'loading', ui_loading);
|
||||
|
||||
rcmail.triggerEvent('listupdate', {list: noteslist, rowcount:noteslist.rowcount});
|
||||
|
@ -796,6 +769,12 @@ function rcube_kolab_notes_ui(settings)
|
|||
titlecontainer = rcmail.gui_objects.noteviewtitle || container,
|
||||
is_html = false;
|
||||
|
||||
// tag-edit line
|
||||
if (window.kolab_tags_input) {
|
||||
$('.tagline', titlecontainer).parent('.form-group').show();
|
||||
taglist = kolab_tags_input($('.tagline', titlecontainer), data.tags, readonly);
|
||||
}
|
||||
|
||||
$('.notetitle', titlecontainer).val(data.title).prop('disabled', readonly).show();
|
||||
$('.dates .notecreated', titlecontainer).text(data.created || '');
|
||||
$('.dates .notechanged', titlecontainer).text(data.changed || '');
|
||||
|
@ -803,34 +782,6 @@ function rcube_kolab_notes_ui(settings)
|
|||
$('.dates', titlecontainer).show();
|
||||
}
|
||||
|
||||
// tag-edit line
|
||||
var tagline = $('.tagline', titlecontainer).empty()[readonly?'addClass':'removeClass']('disabled').show();
|
||||
$.each(typeof data.tags == 'object' && data.tags.length ? data.tags : [''], function(i,val) {
|
||||
$('<input>')
|
||||
.attr('name', 'tags[]')
|
||||
.attr('tabindex', '0')
|
||||
.addClass('tag')
|
||||
.val(val)
|
||||
.appendTo(tagline);
|
||||
});
|
||||
|
||||
if (!data.tags || !data.tags.length) {
|
||||
$('<span>').addClass('placeholder')
|
||||
.html(rcmail.gettext('notags', 'kolab_notes'))
|
||||
.appendTo(tagline)
|
||||
.click(function(e) { $(this).parent().find('.tagedit-list').trigger('click'); });
|
||||
}
|
||||
|
||||
$('.tagline input.tag', titlecontainer).tagedit({
|
||||
animSpeed: 100,
|
||||
allowEdit: false,
|
||||
allowAdd: !readonly,
|
||||
allowDelete: !readonly,
|
||||
checkNewEntriesCaseSensitive: false,
|
||||
autocompleteOptions: { source: tags, minLength: 0, noCheck: true },
|
||||
texts: { removeLinkTitle: rcmail.gettext('removetag', 'kolab_notes') }
|
||||
});
|
||||
|
||||
if (data.links) {
|
||||
$.each(data.links, function(i, link) {
|
||||
var li = $('<li>').addClass('link')
|
||||
|
@ -858,11 +809,6 @@ function rcube_kolab_notes_ui(settings)
|
|||
});
|
||||
}
|
||||
|
||||
if (!readonly) {
|
||||
$('.tagedit-list', titlecontainer)
|
||||
.on('click', function(){ $('.tagline .placeholder').hide(); });
|
||||
}
|
||||
|
||||
if (!data.list)
|
||||
data.list = list.id;
|
||||
|
||||
|
@ -891,9 +837,6 @@ function rcube_kolab_notes_ui(settings)
|
|||
// read possibly re-formatted content back from editor for later comparison
|
||||
me.selected_note.description = rcmail.editor.get_content().replace(/^\s*(<p><\/p>\n*)?/, '');
|
||||
is_html = true;
|
||||
|
||||
if (!me.selected_note.uid)
|
||||
$('.notetitle', titlecontainer).focus().select();
|
||||
}
|
||||
else {
|
||||
gui_object('noteseditform', container).hide();
|
||||
|
@ -911,6 +854,9 @@ function rcube_kolab_notes_ui(settings)
|
|||
// Elastic
|
||||
$(container).parents('.watermark').addClass('formcontainer');
|
||||
$('#notedetailsbox').parent().trigger('loaded');
|
||||
|
||||
if (!readonly)
|
||||
$('.notetitle', titlecontainer).focus().select();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1161,88 +1107,26 @@ function rcube_kolab_notes_ui(settings)
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Display the given counts to each tag
|
||||
*/
|
||||
function render_tagslist(newtags, replace)
|
||||
function update_taglist(tags)
|
||||
{
|
||||
if (replace) {
|
||||
tags = newtags;
|
||||
}
|
||||
else {
|
||||
var i, append = [];
|
||||
for (i=0; i < newtags.length; i++) {
|
||||
if ($.inArray(newtags[i], tags) < 0)
|
||||
append.push(newtags[i]);
|
||||
// compute counts first by iterating over all notes
|
||||
var counts = {};
|
||||
$.each(notesdata, 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]++;
|
||||
}
|
||||
if (!append.length) {
|
||||
update_tagcloud();
|
||||
return; // nothing to be added
|
||||
}
|
||||
tags = tags.concat(append);
|
||||
}
|
||||
|
||||
// sort tags first
|
||||
tags.sort(function(a,b){
|
||||
return a.toLowerCase() > b.toLowerCase() ? 1 : -1;
|
||||
})
|
||||
|
||||
var widget = $(rcmail.gui_objects.notestagslist).html('');
|
||||
|
||||
// append tags to tag cloud
|
||||
$.each(tags, function(i, tag){
|
||||
li = $('<li role="checkbox" aria-checked="false" tabindex="0"></li>')
|
||||
.attr('rel', tag)
|
||||
.data('value', tag)
|
||||
.html(Q(tag) + '<span class="count"></span>')
|
||||
.appendTo(widget)
|
||||
.draggable({
|
||||
addClasses: false,
|
||||
revert: 'invalid',
|
||||
revertDuration: 300,
|
||||
helper: tag_draggable_helper,
|
||||
start: tag_draggable_start,
|
||||
appendTo: 'body',
|
||||
cursor: 'pointer'
|
||||
});
|
||||
});
|
||||
|
||||
update_tagcloud();
|
||||
}
|
||||
rcmail.triggerEvent('kolab-tags-counts', {counter: counts});
|
||||
|
||||
/**
|
||||
* Display the given counts to each tag and set those inactive which don't
|
||||
* have any matching records in the current view.
|
||||
*/
|
||||
function update_tagcloud(counts)
|
||||
{
|
||||
// compute counts first by iterating over all visible task items
|
||||
if (typeof counts == 'undefined') {
|
||||
counts = {};
|
||||
$.each(notesdata, 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]++;
|
||||
}
|
||||
});
|
||||
if (tags && tags.length) {
|
||||
rcmail.triggerEvent('kolab-tags-refresh', {tags: tags});
|
||||
}
|
||||
|
||||
$(rcmail.gui_objects.notestagslist).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');
|
||||
|
||||
if (tagsfilter && tagsfilter.length && $.inArray(tag, tagsfilter)) {
|
||||
elem.addClass('selected').attr('aria-checked', 'true');
|
||||
}
|
||||
else {
|
||||
elem.removeClass('selected').attr('aria-checked', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1257,10 +1141,10 @@ function rcube_kolab_notes_ui(settings)
|
|||
|
||||
if (is_new || me.selected_note && data.id == me.selected_note.id) {
|
||||
render_note(data);
|
||||
render_tagslist(data.tags || []);
|
||||
update_taglist(data.tags || []);
|
||||
}
|
||||
else if (data.tags) {
|
||||
render_tagslist(data.tags);
|
||||
update_taglist(data.tags);
|
||||
}
|
||||
|
||||
// add list item on top
|
||||
|
@ -1291,7 +1175,8 @@ function rcube_kolab_notes_ui(settings)
|
|||
close_history_dialog();
|
||||
me.selected_note = null;
|
||||
$('.notetitle', rcmail.gui_objects.noteviewtitle).val('').hide();
|
||||
$('.tagline, .dates', rcmail.gui_objects.noteviewtitle).hide();
|
||||
$('.dates', rcmail.gui_objects.noteviewtitle).hide();
|
||||
$('.tagline', rcmail.gui_objects.noteviewtitle).parent('.form-group').hide();
|
||||
$(rcmail.gui_objects.noteseditform).hide().parents('.watermark').removeClass('formcontainer');
|
||||
$(rcmail.gui_objects.notesdetailview).hide();
|
||||
$(rcmail.gui_objects.notesattachmentslist).html('');
|
||||
|
@ -1350,7 +1235,7 @@ function rcube_kolab_notes_ui(settings)
|
|||
description: rcmail.editor.get_content().replace(/^\s*(<p><\/p>\n*)?/, ''),
|
||||
list: listselect.length ? listselect.val() : me.selected_note.list || me.selected_list,
|
||||
uid: me.selected_note.uid,
|
||||
tags: []
|
||||
tags: taglist ? kolab_tags_input_value(taglist) : []
|
||||
};
|
||||
|
||||
// copy links
|
||||
|
@ -1358,17 +1243,6 @@ function rcube_kolab_notes_ui(settings)
|
|||
savedata.links = me.selected_note.links;
|
||||
}
|
||||
|
||||
// collect tags
|
||||
$('.tagedit-list input[type="hidden"]', rcmail.gui_objects.noteviewtitle).each(function(i, elem){
|
||||
if (elem.value)
|
||||
savedata.tags.push(elem.value);
|
||||
});
|
||||
// including the "pending" one in the text box
|
||||
var newtag = $('#tagedit-input').val();
|
||||
if (newtag != '') {
|
||||
savedata.tags.push(newtag);
|
||||
}
|
||||
|
||||
return savedata;
|
||||
}
|
||||
|
||||
|
@ -1491,7 +1365,7 @@ function rcube_kolab_notes_ui(settings)
|
|||
rcmail.http_post('action', { _data: { uid: uids.join(','), list: me.selected_list }, _do: 'delete' }, true);
|
||||
|
||||
reset_view();
|
||||
update_tagcloud();
|
||||
update_taglist();
|
||||
noteslist.clear_selection();
|
||||
});
|
||||
}
|
||||
|
@ -1533,81 +1407,6 @@ function rcube_kolab_notes_ui(settings)
|
|||
window.history.replaceState({}, document.title, rcmail.url('', query));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Helper functions for drag & drop functionality of tags */
|
||||
|
||||
function tag_draggable_helper()
|
||||
{
|
||||
if (!tag_draghelper)
|
||||
tag_draghelper = $('<div class="tag-draghelper"></div>');
|
||||
else
|
||||
tag_draghelper.html('');
|
||||
|
||||
$(this).clone().addClass('tag').appendTo(tag_draghelper);
|
||||
return tag_draghelper;
|
||||
}
|
||||
|
||||
function tag_draggable_start(event, ui)
|
||||
{
|
||||
// register notes list to receive drop events
|
||||
$('li', rcmail.gui_objects.noteslist).droppable({
|
||||
hoverClass: 'droptarget',
|
||||
accept: tag_droppable_accept,
|
||||
drop: tag_draggable_dropped,
|
||||
addClasses: false
|
||||
});
|
||||
|
||||
// allow to drop tags onto edit form title
|
||||
$(rcmail.gui_objects.noteviewtitle).droppable({
|
||||
drop: function(event, ui){
|
||||
$('#tagedit-input').val(ui.draggable.data('value')).trigger('transformToTag');
|
||||
$('.tagline .placeholder', rcmail.gui_objects.noteviewtitle).hide();
|
||||
},
|
||||
addClasses: false
|
||||
})
|
||||
}
|
||||
|
||||
function tag_droppable_accept(draggable)
|
||||
{
|
||||
if (rcmail.busy)
|
||||
return false;
|
||||
|
||||
var tag = draggable.data('value'),
|
||||
drop_id = $(this).attr('id').replace(/^rcmrow/, ''),
|
||||
drop_rec = notesdata[drop_id];
|
||||
|
||||
// target already has this tag assigned
|
||||
if (!drop_rec || (drop_rec.tags && $.inArray(tag, drop_rec.tags) >= 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function tag_draggable_dropped(event, ui)
|
||||
{
|
||||
var drop_id = $(this).attr('id').replace(/^rcmrow/, ''),
|
||||
tag = ui.draggable.data('value'),
|
||||
rec = notesdata[drop_id],
|
||||
savedata;
|
||||
|
||||
if (rec && rec.id) {
|
||||
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(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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!-- notebooks list -->
|
||||
<div class="sidebar listbox" role="navigation" aria-labelledby="arial-label-notebooks">
|
||||
<div class="header">
|
||||
<a class="button icon menu-button" href="#menu"><span class="inner"><roundcube:label name="menu" /></span></a>
|
||||
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
|
||||
<span id="aria-label-notebooks" class="header-title"><roundcube:label name="kolab_notes.lists" /></span>
|
||||
<div id="notebook-search" class="searchbar toolbar" role="search" aria-labelledby="aria-label-notebooksearchform">
|
||||
<h2 id="aria-label-label-notebooksearchform" class="voice"><roundcube:label name="kolab_notes.arialabelfoldersearchform" /></h2>
|
||||
|
@ -21,16 +21,8 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scroller">
|
||||
<div id="notebooks-content" class="scroller">
|
||||
<roundcube:object name="plugin.notebooks" id="notebooks" class="listing treelist iconized" />
|
||||
<!--
|
||||
<div id="tagsbox" class="uibox listbox">
|
||||
<h2 class="boxtitle" id="aria-label-tagsbox"><roundcube:label name="kolab_notes.tags" id="taglist" /></h2>
|
||||
<div class="scroller">
|
||||
<roundcube:object name="plugin.tagslist" id="tagslist" class="tagcloud" role="region" aria-labelledby="aria-label-tagsbox" aria-controls="kolabnoteslist" />
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div class="footer toolbar" role="toolbar">
|
||||
<roundcube:button command="list-create" type="link" title="kolab_notes.newnotebook"
|
||||
|
@ -45,13 +37,12 @@
|
|||
<div class="list listbox selected" aria-labelledby="aria-label-noteslist">
|
||||
<div class="header">
|
||||
<a class="button icon menu-button" href="#menu"><span class="inner"><roundcube:label name="menu" /></span></a>
|
||||
<a class="button icon back-sidebar-button" href="#sidebar"><span class="inner"><roundcube:label name="kolab_notes.notebooks" /></span></a>
|
||||
<a class="button icon back-sidebar-button folders" href="#sidebar"><span class="inner"><roundcube:label name="kolab_notes.notebooks" /></span></a>
|
||||
<span id="aria-label-noteslist" class="header-title"><roundcube:label name="kolab_notes.notes" /></span>
|
||||
<roundcube:object name="plugin.searchform" id="searchform" wrapper="searchbar toolbar"
|
||||
label="notesearchform" label-domain="kolab_notes" buttontitle="kolab_notes.findnotes" ariatag="h2" />
|
||||
<a class="button icon toolbar-menu-button" href="#list-menu"><span class="inner"><roundcube:label name="menu" /></span></a>
|
||||
</div>
|
||||
<div class="pagenav toolbar" role="toolbar"></div>
|
||||
<div class="scroller">
|
||||
<h2 id="aria-label-noteslist" class="voice"><roundcube:label name="kolab_notes.notes" /></h2>
|
||||
<roundcube:object name="plugin.listing" id="kolabnoteslist" class="listing" summary="kolab_notes.arialabelnoteslist"
|
||||
|
@ -65,7 +56,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- contact details frame -->
|
||||
<!-- note details frame -->
|
||||
<div class="content" role="main">
|
||||
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
|
||||
<div class="header" role="toolbar" aria-labelledby="aria-label-toolbar">
|
||||
|
|
|
@ -68,17 +68,9 @@
|
|||
left: 252px;
|
||||
}
|
||||
|
||||
.notesview #tagsbox {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.notesview #notebooksbox {
|
||||
position: absolute;
|
||||
top: 252px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
bottom: 0px;
|
||||
|
@ -272,11 +264,6 @@
|
|||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.notesview .ui-dialog-content .tagline {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.notesview .notetitle .disabled .tagedit-list,
|
||||
.notesview .notetitle input.inline-edit:disabled {
|
||||
outline: none;
|
||||
padding-left: 0;
|
||||
|
@ -306,7 +293,6 @@
|
|||
}
|
||||
|
||||
.notesview .notetitle .dates,
|
||||
.notesview .notetitle .tagline,
|
||||
.notesdialog .notebookselect label {
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
|
@ -318,38 +304,6 @@
|
|||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.notesview .notetitle .tagline {
|
||||
position: relative;
|
||||
cursor: text;
|
||||
margin: 4px 0 0 0;
|
||||
}
|
||||
|
||||
.notesview .notetitle .tagline.disabled {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.notesview .notetitle .tagline .placeholder {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.notesview .notetitle .tagline.disabled .placeholder {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.notesview .notetitle .tagedit-list {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 32px;
|
||||
/* padding: 2px; */
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.notetitle .col-form-label {
|
||||
display: none;
|
||||
}
|
||||
|
@ -366,23 +320,6 @@
|
|||
clear: both;
|
||||
}
|
||||
|
||||
/* Firefox 3.6 */
|
||||
_:not(), _:-moz-handler-blocked, .notesview .notetitle .tagedit-list {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.notesview .notetitle .disabled .tagedit-list {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.notesview .notetitle #tagedit-input {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.notesview .tag-draghelper {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.notesview .notetitle .notecreated,
|
||||
.notesview .notetitle .notechanged {
|
||||
display: inline-block;
|
||||
|
|
18
plugins/kolab_notes/skins/larry/templates/listform.html
Normal file
18
plugins/kolab_notes/skins/larry/templates/listform.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<roundcube:object name="doctype" value="html5" />
|
||||
<html>
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="iframe fullheight">
|
||||
|
||||
<h1 class="voice"><roundcube:label name="kolab_notes.notes" /> : <roundcube:label name="kolab_notes.arialabelnotebookform" /></h1>
|
||||
|
||||
<div class="boxcontent">
|
||||
<roundcube:object name="notebookform" class="tabbed propform" />
|
||||
</div>
|
||||
|
||||
<roundcube:include file="/includes/footer.html" />
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -30,13 +30,6 @@
|
|||
<div id="mainscreencontent">
|
||||
|
||||
<div id="sidebar">
|
||||
<div id="tagsbox" class="uibox listbox">
|
||||
<h2 class="boxtitle" id="aria-label-tagsbox"><roundcube:label name="kolab_notes.tags" id="taglist" /></h2>
|
||||
<div class="scroller">
|
||||
<roundcube:object name="plugin.tagslist" id="tagslist" class="tagcloud" role="region" aria-labelledby="aria-label-tagsbox" aria-controls="kolabnoteslist" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="notebooksbox" class="uibox listbox" role="navigation" aria-labelledby="aria-label-notebooks">
|
||||
<h2 class="boxtitle" id="aria-label-notebooks"><roundcube:label name="kolab_notes.lists" />
|
||||
<a href="#notebooks" class="iconbutton search" title="<roundcube:label name='kolab_notes.findnotebooks' />" tabindex="0"><roundcube:label name="kolab_notes.findnotebooks" /></a>
|
||||
|
@ -160,8 +153,6 @@ $(document).ready(function(e){
|
|||
orientation:'v', relative:true, start:240, min:180, size:12, render:layout_view }).init();
|
||||
new rcube_splitter({ id:'noteslistsplitter2', p1:'#noteslistbox', p2:'#notedetailsbox',
|
||||
orientation:'v', relative:true, start:242, min:180, size:12, render:layout_view }).init();
|
||||
new rcube_splitter({ id:'notesviewsplitterv', p1:'#tagsbox', p2:'#notebooksbox',
|
||||
orientation:'h', relative:true, start:242, min:120, size:12, offset:4 }).init();
|
||||
|
||||
function layout_view()
|
||||
{
|
||||
|
@ -217,7 +208,6 @@ $(document).ready(function(e){
|
|||
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
|
||||
window.rcmail && rcmail.addEventListener('init', function() {
|
||||
if (rcmail.task == 'mail') {
|
||||
if (rcmail.task == 'mail' || rcmail.task == 'notes') {
|
||||
var msg_view = rcmail.env.action == 'show' || rcmail.env.action == 'preview';
|
||||
|
||||
if (!msg_view && rcmail.env.action) {
|
||||
|
@ -35,7 +35,13 @@ window.rcmail && rcmail.addEventListener('init', function() {
|
|||
|
||||
// load tags cloud
|
||||
if (rcmail.gui_objects.taglist) {
|
||||
load_tags();
|
||||
// Tags for kolab_notes plugin have to be initialized via an event
|
||||
if (rcmail.task == 'notes' && !window.kolabnotes) {
|
||||
rcmail.addEventListener('kolab-notes-init', load_tags);
|
||||
}
|
||||
else {
|
||||
load_tags();
|
||||
}
|
||||
}
|
||||
|
||||
// display tags in message subject (message window)
|
||||
|
@ -79,7 +85,7 @@ window.rcmail && rcmail.addEventListener('init', function() {
|
|||
return true;
|
||||
}
|
||||
if (p.command == 'reset-tags') {
|
||||
return !!(tagsfilter.length && rcmail.message_list);
|
||||
return !!(tagsfilter.length && main_list_widget());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -99,16 +105,31 @@ window.rcmail && rcmail.addEventListener('init', function() {
|
|||
$('a.menuselector span', $(this).parent()).text(title);
|
||||
});
|
||||
}
|
||||
|
||||
// Allow other plugins to update tags list
|
||||
rcmail.addEventListener('kolab-tags-counts', update_counts)
|
||||
.addEventListener('kolab-tags-refresh', refresh_tags);
|
||||
}
|
||||
});
|
||||
|
||||
var tagsfilter = [], tag_selector_element, tag_form_data, tag_form_save_func,
|
||||
var tag_selector_element, tag_form_data, tag_form_save_func,
|
||||
tagsfilter = [],
|
||||
tagscounts = [],
|
||||
reset_css = {color: '', backgroundColor: ''};
|
||||
|
||||
function main_list_widget()
|
||||
{
|
||||
if (rcmail.task == 'mail' && rcmail.message_list)
|
||||
return rcmail.message_list;
|
||||
|
||||
if (rcmail.task == 'notes' && rcmail.noteslist)
|
||||
return rcmail.noteslist;
|
||||
}
|
||||
|
||||
// fills tag cloud with tags list
|
||||
function load_tags()
|
||||
{
|
||||
var ul = $('#taglist'), clickable = rcmail.message_list;
|
||||
var ul = $('#taglist'), clickable = !!main_list_widget();
|
||||
|
||||
$.each(rcmail.env.tags, function(i, tag) {
|
||||
var li = add_tag_element(ul, tag, clickable);
|
||||
|
@ -130,9 +151,10 @@ function load_tags()
|
|||
|
||||
function add_tag_element(list, tag, clickable)
|
||||
{
|
||||
// @todo: .append('<span class="count"></span>')
|
||||
var element = $('<li>').attr('class', tag_class_name(tag))
|
||||
.text(tag.name).data('tag', tag.uid).appendTo(list);
|
||||
.text(tag.name).data('tag', tag.uid)
|
||||
.append('<span class="count">')
|
||||
.appendTo(list);
|
||||
|
||||
if (clickable) {
|
||||
element.click(function(e) {
|
||||
|
@ -173,12 +195,38 @@ function add_tag_element(list, tag, clickable)
|
|||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
})
|
||||
});
|
||||
|
||||
if (!$('html.touch').length) {
|
||||
element.draggable({
|
||||
addClasses: false,
|
||||
cursor: 'default',
|
||||
cursorAt: {left: -10},
|
||||
revert: 'invalid',
|
||||
revertDuration: 300,
|
||||
helper: tag_draggable_helper,
|
||||
start: tag_draggable_start,
|
||||
appendTo: 'body'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
function update_counts(p)
|
||||
{
|
||||
$('#taglist > li').each(function(i,li) {
|
||||
var elem = $(li), tagid = elem.data('tag'),
|
||||
tag = tag_find(tagid);
|
||||
count = tag && p.counter ? p.counter[tag.name] : '';
|
||||
|
||||
elem.children('.count').text(count ? count : '');
|
||||
});
|
||||
|
||||
tagscounts = p.counter;
|
||||
}
|
||||
|
||||
function manage_tags()
|
||||
{
|
||||
// display it as popup
|
||||
|
@ -388,6 +436,29 @@ function update_tags(response)
|
|||
// reset tag selector popup
|
||||
tag_selector_reset();
|
||||
|
||||
if (response.refresh) {
|
||||
var list = $('#taglist');
|
||||
|
||||
tagsfilter = $.map(list.children('.selected'), function(li) {
|
||||
return $(li).data('tag');
|
||||
});
|
||||
|
||||
list.html('');
|
||||
load_tags();
|
||||
update_counts({counter: tagscounts});
|
||||
|
||||
if (tagsfilter.length) {
|
||||
list.children('li').each(function() {
|
||||
if ($.inArray($(this).data('tag'), tagsfilter) > -1) {
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
});
|
||||
apply_tags_filter();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// remove deleted tags
|
||||
remove_tags(response['delete'], response.mark);
|
||||
|
||||
|
@ -405,9 +476,9 @@ function update_tags(response)
|
|||
var i, old, tag = this, id = tag.uid,
|
||||
filter = function() { return $(this).data('tag') == id; },
|
||||
tagbox = $('#taglist li').filter(filter),
|
||||
elements = $('span.tagbox').filter(filter),
|
||||
elements = $('.tagbox').filter(filter),
|
||||
win = rcmail.get_frame_window(rcmail.env.contentframe),
|
||||
framed = win && win.jQuery ? win.jQuery('span.tagbox').filter(function() { return win.jQuery(this).data('tag') == id; }) : [];
|
||||
framed = win && win.jQuery ? win.jQuery('.tagbox').filter(function() { return win.jQuery(this).data('tag') == id; }) : [];
|
||||
selected = $.inArray(String(id), tagsfilter);
|
||||
|
||||
for (i in rcmail.env.tags)
|
||||
|
@ -454,7 +525,8 @@ function remove_tags(tags, selection)
|
|||
}
|
||||
|
||||
var taglist = $('#taglist li'),
|
||||
tagboxes = $((selection && rcmail.message_list ? 'tr.selected ' : '') + 'span.tagbox'),
|
||||
list = main_list_widget(),
|
||||
tagboxes = $((selection && list ? 'tr.selected ' : '') + 'span.tagbox'),
|
||||
win = rcmail.get_frame_window(rcmail.env.contentframe),
|
||||
frame_tagboxes = win && win.jQuery ? win.jQuery('span.tagbox') : [],
|
||||
update_filter = false;
|
||||
|
@ -492,11 +564,28 @@ function remove_tags(tags, selection)
|
|||
}
|
||||
});
|
||||
|
||||
if (update_filter && rcmail.message_list) {
|
||||
if (update_filter && list) {
|
||||
apply_tags_filter();
|
||||
}
|
||||
}
|
||||
|
||||
// kolab-tags-refresh event handler, allowing plugins to refresh
|
||||
// the tags list e.g. when a new tag is created
|
||||
function refresh_tags(e)
|
||||
{
|
||||
// find a new tag
|
||||
$.each(e.tags || [], function() {
|
||||
for (var i in rcmail.env.tags) {
|
||||
if (rcmail.env.tags[i].name == this) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rcmail.http_post('plugin.kolab_tags', {_act: 'refresh'}, rcmail.display_message(rcmail.get_label('loading'), 'loading'));
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// unselect all selected tags in the tag cloud
|
||||
function reset_tags()
|
||||
{
|
||||
|
@ -602,8 +691,21 @@ function tag_remove(props, obj, event)
|
|||
// executes messages search according to selected messages
|
||||
function apply_tags_filter()
|
||||
{
|
||||
rcmail.enable_command('reset-tags', tagsfilter.length && rcmail.message_list);
|
||||
rcmail.qsearch();
|
||||
rcmail.enable_command('reset-tags', tagsfilter.length && main_list_widget());
|
||||
|
||||
if (rcmail.task == 'mail')
|
||||
rcmail.qsearch();
|
||||
else {
|
||||
// Convert tag id to tag label
|
||||
var tags = [];
|
||||
$.each(rcmail.env.tags, function() {
|
||||
if ($.inArray(this.uid, tagsfilter) > -1) {
|
||||
tags.push(this.name);
|
||||
}
|
||||
});
|
||||
|
||||
rcmail.triggerEvent('kolab-tags-search', tags);
|
||||
}
|
||||
}
|
||||
|
||||
// adds _tags argument to http search request
|
||||
|
@ -896,3 +998,162 @@ function tag_class_name(tag)
|
|||
{
|
||||
return 'kolab-tag-' + tag.uid.replace(/[^a-z0-9]/ig, '');
|
||||
}
|
||||
|
||||
function kolab_tags_input(element, tags, readonly)
|
||||
{
|
||||
var list,
|
||||
tagline = $(element)[readonly ? 'addClass' : 'removeClass']('disabled').empty().show(),
|
||||
source_callback = function(request, response) {
|
||||
request = request.term.toUpperCase();
|
||||
response($.map(rcmail.env.tags || [], function(v) {
|
||||
if (request.length && v.name.toUpperCase().indexOf(request) > -1)
|
||||
return v.name;
|
||||
}));
|
||||
};
|
||||
|
||||
$.each(tags && tags.length ? tags : [''], function(i,val) {
|
||||
$('<input>').attr({name: 'tags[]', tabindex: '0', 'class': 'tag'})
|
||||
.val(val)
|
||||
.appendTo(tagline);
|
||||
});
|
||||
|
||||
if (!tags || !tags.length) {
|
||||
$('<span>').addClass('placeholder')
|
||||
.text(rcmail.gettext('kolab_tags.notags'))
|
||||
.appendTo(tagline)
|
||||
.click(function(e) { list.trigger('click'); });
|
||||
}
|
||||
|
||||
$('input.tag', element).tagedit({
|
||||
animSpeed: 100,
|
||||
allowEdit: false,
|
||||
allowAdd: !readonly,
|
||||
allowDelete: !readonly,
|
||||
checkNewEntriesCaseSensitive: false,
|
||||
autocompleteOptions: { source: source_callback, minLength: 0, noCheck: true },
|
||||
texts: { removeLinkTitle: rcmail.gettext('kolab_tags.untag') }
|
||||
});
|
||||
|
||||
list = element.find('.tagedit-list');
|
||||
|
||||
list.addClass('form-control'); // Elastic
|
||||
|
||||
if (!readonly) {
|
||||
list.on('click', function() { $('.placeholder', element).hide(); });
|
||||
}
|
||||
|
||||
// Track changes on the list to style tag elements
|
||||
if (window.MutationObserver) {
|
||||
var observer = new MutationObserver(kolab_tags_input_update);
|
||||
observer.observe(list[0], {childList: true});
|
||||
}
|
||||
else {
|
||||
list.on('click keyup', kolab_tags_input_update);
|
||||
}
|
||||
|
||||
kolab_tags_input_update({target: list});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function kolab_tags_input_update(e)
|
||||
{
|
||||
var tags = {},
|
||||
target = e.length && e[0].target ? e[0].target : e.target;
|
||||
|
||||
// first generate tags list indexed by name
|
||||
$.each(rcmail.env.tags, function(i, tag) {
|
||||
tags[tag.name] = tag;
|
||||
});
|
||||
|
||||
$(target).find('li.tagedit-listelement-old:not([class*="tagbox"])').each(function() {
|
||||
var text = $('span', this).text();
|
||||
|
||||
$(this).addClass('tagbox');
|
||||
|
||||
if (tags[text]) {
|
||||
$(this).data('tag', tags[text].uid);
|
||||
tag_set_color(this, tags[text]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function kolab_tags_input_value(element)
|
||||
{
|
||||
var tags = [];
|
||||
|
||||
$(element || '.tagedit-list').find('input').each(function(i, elem) {
|
||||
if (elem.value)
|
||||
tags.push(elem.value);
|
||||
});
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
function tag_draggable_helper()
|
||||
{
|
||||
var draghelper = $('.tag-draghelper'),
|
||||
tagid = $(this).data('tag'),
|
||||
node = $(this).clone(),
|
||||
tagbox = $('<span class="tagbox">');
|
||||
|
||||
if (!draghelper.length) {
|
||||
draghelper = $('<div class="tag-draghelper"></div>');
|
||||
}
|
||||
|
||||
$('span.count', node).remove();
|
||||
tagbox.text(node.text()).appendTo(draghelper.html(''));
|
||||
tag_set_color(tagbox, tag_find(tagid));
|
||||
|
||||
return draghelper[0];
|
||||
}
|
||||
|
||||
function tag_draggable_start(event, ui)
|
||||
{
|
||||
// register notes list to receive drop events
|
||||
if (rcmail.gui_objects.noteslist) {
|
||||
$('tr', rcmail.gui_objects.noteslist).droppable({
|
||||
addClasses: false,
|
||||
hoverClass: 'droptarget',
|
||||
accept: tag_droppable_accept,
|
||||
drop: tag_draggable_dropped
|
||||
});
|
||||
}
|
||||
|
||||
// allow to drop tags onto edit form title
|
||||
$('body.task-notes .content.formcontainer,#notedetailstitle.boxtitle').droppable({
|
||||
addClasses: false,
|
||||
accept: function() { return $(this).is('.formcontainer,.boxtitle'); },
|
||||
drop: function(event, ui) {
|
||||
var tag = tag_find(ui.draggable.data('tag'));
|
||||
$('#tagedit-input').val(tag.name).trigger('transformToTag');
|
||||
$('.tagline .placeholder', rcmail.gui_objects.noteviewtitle).hide();
|
||||
}
|
||||
}).addClass('tag-droppable');
|
||||
}
|
||||
|
||||
function tag_draggable_dropped(event, ui)
|
||||
{
|
||||
var drop_id = $(this).attr('id').replace(/^rcmrow/, ''),
|
||||
tag = tag_find(ui.draggable.data('tag'));
|
||||
|
||||
rcmail.triggerEvent('kolab-tags-drop', {id: drop_id, tag: tag.name, list: $(this).parent()});
|
||||
}
|
||||
|
||||
function tag_droppable_accept(draggable)
|
||||
{
|
||||
if (rcmail.busy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var tag = tag_find(draggable.data('tag')),
|
||||
drop_id = $(this).attr('id').replace(/^rcmrow/, ''),
|
||||
data = rcmail.triggerEvent('kolab-tags-drop-data', {id: drop_id});
|
||||
|
||||
// target already has this tag assigned
|
||||
if (!data || (data.tags && $.inArray(tag.name, data.tags) >= 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
class kolab_tags extends rcube_plugin
|
||||
{
|
||||
public $task = 'mail';
|
||||
public $task = 'mail|notes';
|
||||
public $rc;
|
||||
public $home;
|
||||
|
||||
|
|
|
@ -46,12 +46,7 @@ class kolab_tags_engine
|
|||
*/
|
||||
public function ui()
|
||||
{
|
||||
// set templates of Files UI and widgets
|
||||
if ($this->rc->task != 'mail') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->rc->action && !in_array($this->rc->action, array('show', 'preview'))) {
|
||||
if ($this->rc->action && !in_array($this->rc->action, array('show', 'preview', 'dialog-ui'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -62,7 +57,7 @@ class kolab_tags_engine
|
|||
$this->rc->output->add_label('cancel', 'save');
|
||||
$this->plugin->add_label('tags', 'add', 'edit', 'delete', 'saving',
|
||||
'nameempty', 'nameexists', 'colorinvalid', 'untag', 'tagname',
|
||||
'tagcolor', 'tagsearchnew', 'newtag');
|
||||
'tagcolor', 'tagsearchnew', 'newtag', 'notags');
|
||||
|
||||
$this->rc->output->add_handlers(array(
|
||||
'plugin.taglist' => array($this, 'taglist'),
|
||||
|
@ -71,11 +66,12 @@ class kolab_tags_engine
|
|||
$ui = $this->rc->output->parse('kolab_tags.ui', false, false);
|
||||
$this->rc->output->add_footer($ui);
|
||||
|
||||
// load miniColors
|
||||
// load miniColors and tagedit
|
||||
jqueryui::miniColors();
|
||||
jqueryui::tagedit();
|
||||
|
||||
// Modify search filter (and set selected tags)
|
||||
if ($this->rc->action == 'show' || !$this->rc->action) {
|
||||
if ($this->rc->task == 'mail' && ($this->rc->action == 'show' || !$this->rc->action)) {
|
||||
$this->search_filter_mods();
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +279,18 @@ class kolab_tags_engine
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh tags list
|
||||
*/
|
||||
public function action_refresh()
|
||||
{
|
||||
$taglist = $this->backend->list_tags();
|
||||
$taglist = array_map(array($this, 'parse_tag'), $taglist);
|
||||
|
||||
$this->rc->output->set_env('tags', $taglist);
|
||||
$this->rc->output->command('plugin.kolab_tags', array('refresh' => 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Template object building tags list/cloud
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,7 @@ $labels['tagactions'] = 'Tag actions...';
|
|||
$labels['tagadd'] = 'Tag as...';
|
||||
$labels['tagremove'] = 'Remove tag...';
|
||||
$labels['untag'] = 'Remove tag';
|
||||
$labels['notags'] = 'No tags';
|
||||
$labels['tagremoveall'] = 'Remove all tags';
|
||||
$labels['add'] = 'Add';
|
||||
$labels['edit'] = 'Edit';
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
$(document).ready(function(e) {
|
||||
// put tags cloud under folders list
|
||||
var tagcloud = $('#tagcloud').detach();
|
||||
$('#folderlist-content > ul:last').after(tagcloud.show());
|
||||
$('#folderlist-content,#notebooks-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 ul').append(menu);
|
||||
$('#mailboxoptions-menu,#notebookactions-menu').find('ul').append(menu);
|
||||
|
||||
// Apply tags colors in Elastic-way
|
||||
rcmail.addEventListener('kolab-tags-update', function() {
|
||||
|
@ -58,7 +58,7 @@ $(document).ready(function(e) {
|
|||
|
||||
// Ignore tags coloring on lists, handled above, use default method for tagboxes only
|
||||
rcmail.addEventListener('kolab-tag-color', function(prop) {
|
||||
if ($(prop.obj).is('li')) {
|
||||
if ($(prop.obj).is('li:not(.tagedit-listelement)')) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -70,6 +70,7 @@ ul.toolbarmenu li span.icon.tagremoveall {
|
|||
}
|
||||
|
||||
.tag-draghelper .tag .count,
|
||||
#taglist li .count:empty,
|
||||
#taglist li.inactive .count {
|
||||
display: none;
|
||||
}
|
||||
|
@ -138,3 +139,86 @@ ul.toolbarmenu li span.icon.tagremoveall {
|
|||
#tag-selector li.search input {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
font-size: 0.9em;
|
||||
position: relative;
|
||||
cursor: text;
|
||||
margin: 4px 0 0 0;
|
||||
min-height: 31px;
|
||||
}
|
||||
|
||||
.tagline.disabled {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.tagline .tagedit-list {
|
||||
min-height: 31px;
|
||||
}
|
||||
|
||||
.tagline.disabled .tagedit-list {
|
||||
outline: none;
|
||||
padding-left: 0;
|
||||
border: 0;
|
||||
min-height: 31px;
|
||||
background: rgba(255,255,255,0.01);
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
-o-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.tagline .placeholder {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.tagline.disabled .placeholder {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tagedit-list {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 32px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tagedit-list #tagedit-input {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.tag-draghelper {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.tagedit span.tag-element,
|
||||
.tagedit-list li.tagedit-listelement-old {
|
||||
background: #ddeef5 !important;
|
||||
border: 0 !important;
|
||||
padding: 2px 20px 0 6px !important;
|
||||
line-height: 1.5 !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.tagedit-list li.tagedit-listelement-old a.tagedit-close,
|
||||
.tagedit-list li.tagedit-listelement-old a.tagedit-break,
|
||||
.tagedit-list li.tagedit-listelement-old a.tagedit-delete,
|
||||
.tagedit-list li.tagedit-listelement-old a.tagedit-save {
|
||||
position: absolute !important;
|
||||
top: 1px !important;
|
||||
right: 0;
|
||||
background: transparent !important;
|
||||
text-indent: initial !important;
|
||||
}
|
||||
|
||||
.tag-droppable.ui-droppable-hover {
|
||||
background-color: #e8e798;
|
||||
}
|
|
@ -31,11 +31,25 @@
|
|||
|
||||
$(document).ready(function(e) {
|
||||
// put tags cloud under folders list
|
||||
var tagcloud = $('#tagcloud').detach();
|
||||
$('#mailview-left').append(tagcloud.show());
|
||||
var containers, tagcloud = $('#tagcloud').detach();
|
||||
|
||||
new rcube_splitter({ id:'mailtagsplitter', p1:'#mailboxcontainer', p2:'#tagcloud',
|
||||
orientation:'h', relative:true, start:242, min:120, size:12, offset:4 }).init();
|
||||
if (rcmail.env.task == 'mail')
|
||||
containers = {
|
||||
sidebar: '#mailview-left',
|
||||
list: '#mailboxcontainer'
|
||||
};
|
||||
else if (rcmail.env.task == 'notes')
|
||||
containers = {
|
||||
sidebar: '#sidebar',
|
||||
list: '#notebooksbox'
|
||||
};
|
||||
|
||||
if (containers) {
|
||||
$(containers.sidebar).append(tagcloud.show());
|
||||
|
||||
new rcube_splitter({ id: rcmail.task + 'tagsplitter', p1:containers.list, p2:'#tagcloud',
|
||||
orientation:'h', relative:true, start:242, min:120, size:12, offset:4 }).init();
|
||||
}
|
||||
|
||||
// add tag message menu positions to Mark menu
|
||||
var menu = $('#tagmessagemenu li').detach();
|
||||
|
|
|
@ -42,6 +42,26 @@
|
|||
margin: 0 .5rem 0 .2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.count {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 2em;
|
||||
line-height: 1.4rem;
|
||||
margin: (@listing-line-height - 1.4rem)/2;
|
||||
padding: 0 .3em;
|
||||
border-radius: .4em;
|
||||
background: @color-list-secondary;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
||||
html.touch & {
|
||||
line-height: 2rem;
|
||||
margin: (@listing-touch-line-height - 2rem)/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#tagsform option:before,
|
||||
|
@ -93,14 +113,15 @@
|
|||
|
||||
.tagbox {
|
||||
color: #fff;
|
||||
background-color: @color-main;
|
||||
background-color: @color-main !important;
|
||||
border: 0 !important;
|
||||
border-radius: .25rem;
|
||||
max-width: 4em;
|
||||
padding: .1rem .4rem;
|
||||
margin-right: .2rem;
|
||||
font-weight: bold;
|
||||
|
||||
a {
|
||||
&:not(.tagedit-listelement) a {
|
||||
color: inherit;
|
||||
padding-left: .5rem;
|
||||
text-decoration: none;
|
||||
|
@ -110,3 +131,12 @@
|
|||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-droppable.formcontainer {
|
||||
&.ui-droppable-active {
|
||||
background-color: @color-black-shade-bg !important;
|
||||
}
|
||||
&.ui-droppable-hover {
|
||||
background-color: @color-list-droptarget-background !important;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue