Fix listing of other user's calendars and sub-folders

This commit is contained in:
Thomas Bruederli 2014-05-15 11:57:54 +02:00
parent df08826c03
commit 715b2b790a
8 changed files with 99 additions and 48 deletions

View file

@ -2705,7 +2705,7 @@ function rcube_calendar_ui(settings)
// insert to #calendar-select options if writeable
select = $('#edit-calendar');
if (fc && !cal.readonly && select.length && !select.find('option[value="'+id+'"]').length) {
$('<option>').attr('value', id).text(Q(cal.name)).appendTo(select);
$('<option>').attr('value', id).html(cal.name).appendTo(select);
}
}
@ -2751,7 +2751,6 @@ function rcube_calendar_ui(settings)
calendars_list.addEventListener('insert-item', function(p) {
var cal = p.data;
if (cal && cal.id) {
cal.active = true;
add_calendar_source(cal);
// add css classes related to this calendar to document

View file

@ -33,6 +33,8 @@ class kolab_calendar
public $alarms = false;
public $categories = array();
public $storage;
public $type = 'event';
public $name;
protected $cal;
@ -197,6 +199,25 @@ class kolab_calendar
}
/**
* Update properties of this calendar folder
*
* @see calendar_driver::edit_calendar()
*/
public function update(&$prop)
{
$prop['oldname'] = $this->get_realname();
$newfolder = kolab_storage::folder_update($prop);
if ($newfolder === false) {
$this->cal->last_error = $this->cal->gettext(kolab_storage::$last_error);
return false;
}
// create ID
return kolab_storage::folder_id($newfolder);
}
/**
* Getter for a single event object
*/

View file

@ -129,7 +129,13 @@ class kolab_driver extends calendar_driver
$listname = $cal->get_foldername();
$imap_path = explode('/', $cal->name);
$topname = array_pop($imap_path);
$parent_id = kolab_storage::folder_id(join('/', $imap_path), true);
$parent_id = kolab_storage::folder_id(join('/', $imap_path));
// turn a kolab_storage_folder object into a kolab_calendar
if ($cal instanceof kolab_storage_folder) {
$cal = new kolab_calendar($cal->name, $this->cal);
$this->calendars[$cal->id] = $cal;
}
// special handling for user or virtual folders
if ($cal instanceof kolab_storage_user_folder) {
@ -141,7 +147,7 @@ class kolab_driver extends calendar_driver
'color' => $cal->get_color(),
'active' => $cal->is_active(),
'owner' => $cal->get_owner(),
'virtual' => false,
'virtual' => false,
'readonly' => true,
'class_name' => 'user',
);
@ -306,16 +312,7 @@ class kolab_driver extends calendar_driver
public function edit_calendar($prop)
{
if ($prop['id'] && ($cal = $this->get_calendar($prop['id']))) {
$prop['oldname'] = $cal->get_realname();
$newfolder = kolab_storage::folder_update($prop);
if ($newfolder === false) {
$this->last_error = $this->cal->gettext(kolab_storage::$last_error);
return false;
}
// create ID
$id = kolab_storage::folder_id($newfolder);
$id = $cal->update($prop);
}
else {
$id = $prop['id'];

View file

@ -130,6 +130,20 @@ class kolab_user_calendar extends kolab_calendar
return false;
}
/**
* Update properties of this calendar folder
*
* @see calendar_driver::edit_calendar()
*/
public function update(&$prop)
{
// don't change anything.
// let kolab_driver save props in local prefs
return $prop['id'];
}
/**
* Getter for a single event object
*/

View file

@ -229,7 +229,7 @@ class calendar_ui
if ($attrib['activeonly'] && !$prop['active'])
continue;
$html .= html::tag('li', array('id' => 'rcmlical' . rcube_utils::html_identifier($id)),
$html .= html::tag('li', array('id' => 'rcmlical' . $id),
$content = $this->calendar_list_item($id, $prop, $jsenv)
);
}
@ -243,7 +243,7 @@ class calendar_ui
/**
* Return html for a structured list <ul> for the folder tree
*/
public function list_tree_html(&$node, &$data, &$jsenv, $attrib)
public function list_tree_html($node, $data, &$jsenv, $attrib)
{
$out = '';
foreach ($node->children as $folder) {

View file

@ -86,7 +86,7 @@ $labels['nmonthsback'] = '$nr months back';
$labels['showurl'] = 'Show calendar URL';
$labels['showurldescription'] = 'Use the following address to access (read only) your calendar from other applications. You can copy and paste this into any calendar software that supports the iCal format.';
$labels['caldavurldescription'] = 'Copy this address to a <a href="http://en.wikipedia.org/wiki/CalDAV" target="_blank">CalDAV</a> client application (e.g. Evolution or Mozilla Thunderbird) to fully synchronize this specific calendar with your computer or mobile device.';
$labels['calsearchresults'] = 'Additional Results';
$labels['calsearchresults'] = 'Available Calendars';
// agenda view
$labels['listrange'] = 'Range to display:';

View file

@ -297,6 +297,10 @@ pre {
padding: 2px 8px 2px 8px;
}
#calendars .searchresults .listing li {
background-color: #c7e3ef;
}
#calfeedurl,
#caldavurl {
width: 98%;

View file

@ -62,39 +62,12 @@ function kolab_folderlist(node, p)
return;
var li = $(this).closest('li'),
id = li.attr('id').replace(new RegExp('^'+p.id_prefix), ''),
id = li.attr('id').replace(new RegExp('^'+p.id_prefix), '')
node = search_results_widget.get_node(id),
prop = search_results[id],
parent_id = prop.parent || null,
has_children = node.children && node.children.length,
dom_node = has_children ? li.children().first().clone(true, true) : li.children().first();
has_children = node.children && node.children.length;
// find parent node and insert at the right place
if (parent_id && $('#' + p.id_prefix + parent_id, me.container).length) {
prop.listname = prop.editname;
dom_node.children('span,a').first().html(Q(prop.listname));
}
// TODO: copy parent tree too
// replace virtual node with a real one
if (me.get_node(id)) {
$(me.get_item(id, true)).children().first()
.replaceWith(dom_node)
.removeClass('virtual');
}
else {
// move this result item to the main list widget
me.insert({
id: id,
classes: [],
virtual: prop.virtual,
html: dom_node,
}, parent_id, parent_id ? true : false);
}
delete prop.html;
me.triggerEvent('insert-item', { id: id, data: prop, item: li });
// copy item to the main list
add_result2list(id, li, true);
if (has_children) {
li.find('input[type=checkbox]').first().prop('disabled', true).get(0).checked = true;
@ -127,6 +100,49 @@ function kolab_folderlist(node, p)
}
}
// helper method to (recursively) add a search result item to the main list widget
function add_result2list(id, li, active)
{
var node = search_results_widget.get_node(id),
prop = search_results[id],
parent_id = prop.parent || null,
has_children = node.children && node.children.length,
dom_node = has_children ? li.children().first().clone(true, true) : li.children().first();
// find parent node and insert at the right place
if (parent_id && me.get_node(parent_id)) {
dom_node.children('span,a').first().html(Q(prop.editname));
}
else if (parent_id && search_results[parent_id]) {
// copy parent tree from search results
add_result2list(parent_id, $(search_results_widget.get_item(parent_id)), false);
}
else if (parent_id) {
// use full name for list display
dom_node.children('span,a').first().html(Q(prop.name));
}
// replace virtual node with a real one
if (me.get_node(id)) {
$(me.get_item(id, true)).children().first()
.replaceWith(dom_node)
.removeClass('virtual');
}
else {
// move this result item to the main list widget
me.insert({
id: id,
classes: [],
virtual: prop.virtual,
html: dom_node,
}, parent_id, parent_id ? true : false);
}
delete prop.html;
prop.active = active;
me.triggerEvent('insert-item', { id: id, data: prop, item: li });
}
// do some magic when search is performed on the widget
this.addEventListener('search', function(search) {
// hide search results