Refine virtual user folders handling in new folder navigation according to #3378
This commit is contained in:
parent
7e6056770e
commit
dc335c4d26
9 changed files with 139 additions and 16 deletions
|
@ -93,10 +93,13 @@ class kolab_driver extends calendar_driver
|
||||||
$this->calendars = array();
|
$this->calendars = array();
|
||||||
|
|
||||||
foreach ($folders as $folder) {
|
foreach ($folders as $folder) {
|
||||||
if ($folder instanceof kolab_storage_folder_user)
|
if ($folder instanceof kolab_storage_folder_user) {
|
||||||
$calendar = new kolab_user_calendar($folder->name, $this->cal);
|
$calendar = new kolab_user_calendar($folder->name, $this->cal);
|
||||||
else
|
$calendar->subscriptions = count($folder->children) > 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
$calendar = new kolab_calendar($folder->name, $this->cal);
|
$calendar = new kolab_calendar($folder->name, $this->cal);
|
||||||
|
}
|
||||||
|
|
||||||
if ($calendar->ready) {
|
if ($calendar->ready) {
|
||||||
$this->calendars[$calendar->id] = $calendar;
|
$this->calendars[$calendar->id] = $calendar;
|
||||||
|
@ -210,7 +213,7 @@ class kolab_driver extends calendar_driver
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cal->subscriptions) {
|
if ($cal->subscriptions) {
|
||||||
$calendars[$cal->id]['subscribed'] = (bool)$cal->is_subscribed();
|
$calendars[$cal->id]['subscribed'] = $cal->is_subscribed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +491,7 @@ class kolab_driver extends calendar_driver
|
||||||
foreach (kolab_storage::list_user_folders($user, 'event', false) as $foldername) {
|
foreach (kolab_storage::list_user_folders($user, 'event', false) as $foldername) {
|
||||||
$cal = new kolab_calendar($foldername, $this->cal);
|
$cal = new kolab_calendar($foldername, $this->cal);
|
||||||
$this->calendars[$cal->id] = $cal;
|
$this->calendars[$cal->id] = $cal;
|
||||||
|
$calendar->subscriptions = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ class kolab_user_calendar extends kolab_calendar
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ready = !empty($this->userdata['kolabtargetfolder']);
|
$this->ready = !empty($this->userdata['kolabtargetfolder']);
|
||||||
|
$this->storage->type = 'event';
|
||||||
|
|
||||||
if ($this->ready) {
|
if ($this->ready) {
|
||||||
// ID is derrived from the user's kolabtargetfolder attribute
|
// ID is derrived from the user's kolabtargetfolder attribute
|
||||||
|
@ -141,6 +142,15 @@ class kolab_user_calendar extends kolab_calendar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check subscription status of this folder
|
||||||
|
*
|
||||||
|
* @return boolean True if subscribed, false if not
|
||||||
|
*/
|
||||||
|
public function is_subscribed()
|
||||||
|
{
|
||||||
|
return $this->storage->is_subscribed();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update properties of this calendar folder
|
* Update properties of this calendar folder
|
||||||
|
@ -201,7 +211,7 @@ class kolab_user_calendar extends kolab_calendar
|
||||||
|
|
||||||
// aggregate all calendar folders the user shares (but are not subscribed)
|
// aggregate all calendar folders the user shares (but are not subscribed)
|
||||||
foreach (kolab_storage::list_user_folders($this->userdata, 'event', false) as $foldername) {
|
foreach (kolab_storage::list_user_folders($this->userdata, 'event', false) as $foldername) {
|
||||||
if (!kolab_storage::folder_is_subscribed($foldername, true)) {
|
if (!empty($_REQUEST['_quickview']) || !kolab_storage::folder_is_subscribed($foldername, true)) {
|
||||||
$cal = new kolab_calendar($foldername, $this->cal);
|
$cal = new kolab_calendar($foldername, $this->cal);
|
||||||
foreach ($cal->list_events($start, $end, $search, 1) as $event) {
|
foreach ($cal->list_events($start, $end, $search, 1) as $event) {
|
||||||
$this->events[$event['id']] = $event;
|
$this->events[$event['id']] = $event;
|
||||||
|
@ -302,7 +312,7 @@ class kolab_user_calendar extends kolab_calendar
|
||||||
'id' => md5($this->id . $from->format('U') . '/' . $to->format('U')),
|
'id' => md5($this->id . $from->format('U') . '/' . $to->format('U')),
|
||||||
'calendar' => $this->id,
|
'calendar' => $this->id,
|
||||||
'changed' => $fb['created'] ?: new DateTime(),
|
'changed' => $fb['created'] ?: new DateTime(),
|
||||||
'title' => $titlemap[$type] ?: $type,
|
'title' => $this->get_name() . ' ' . ($titlemap[$type] ?: $type),
|
||||||
'start' => $from,
|
'start' => $from,
|
||||||
'end' => $to,
|
'end' => $to,
|
||||||
'free_busy' => $statusmap[$type] ?: 'busy',
|
'free_busy' => $statusmap[$type] ?: 'busy',
|
||||||
|
|
|
@ -298,6 +298,8 @@ class calendar_ui
|
||||||
$classes[] = 'readonly';
|
$classes[] = 'readonly';
|
||||||
if ($prop['subscribed'])
|
if ($prop['subscribed'])
|
||||||
$classes[] = 'subscribed';
|
$classes[] = 'subscribed';
|
||||||
|
if ($prop['subscribed'] === 2)
|
||||||
|
$classes[] = 'partial';
|
||||||
if ($prop['class'])
|
if ($prop['class'])
|
||||||
$classes[] = $prop['class'];
|
$classes[] = $prop['class'];
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,11 @@ pre {
|
||||||
background-position: -16px -110px;
|
background-position: -16px -110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#calendars .treelist div.subscribed.partial a.subscribed,
|
||||||
|
#calendars .treelist div.subscribed.partial a.subscribed:focus {
|
||||||
|
background-position: -16px -148px;
|
||||||
|
}
|
||||||
|
|
||||||
#calendars .treelist li a.quickview {
|
#calendars .treelist li a.quickview {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 3.6 KiB |
|
@ -149,7 +149,8 @@ function kolab_folderlist(node, p)
|
||||||
prop = search_results[id],
|
prop = search_results[id],
|
||||||
parent_id = prop.parent || null,
|
parent_id = prop.parent || null,
|
||||||
has_children = node.children && node.children.length,
|
has_children = node.children && node.children.length,
|
||||||
dom_node = has_children ? li.children().first().clone(true, true) : li.children().first();
|
dom_node = has_children ? li.children().first().clone(true, true) : li.children().first(),
|
||||||
|
childs = [];
|
||||||
|
|
||||||
// find parent node and insert at the right place
|
// find parent node and insert at the right place
|
||||||
if (parent_id && me.get_node(parent_id)) {
|
if (parent_id && me.get_node(parent_id)) {
|
||||||
|
@ -171,18 +172,58 @@ function kolab_folderlist(node, p)
|
||||||
.removeClass('virtual');
|
.removeClass('virtual');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// copy childs, too
|
||||||
|
if (has_children && prop.group == 'other user') {
|
||||||
|
for (var cid, j=0; j < node.children.length; j++) {
|
||||||
|
if ((cid = node.children[j].id) && search_results[cid]) {
|
||||||
|
childs.push(search_results_widget.get_node(cid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// move this result item to the main list widget
|
// move this result item to the main list widget
|
||||||
me.insert({
|
me.insert({
|
||||||
id: id,
|
id: id,
|
||||||
classes: [ prop.group || '' ],
|
classes: [ prop.group || '' ],
|
||||||
virtual: prop.virtual,
|
virtual: prop.virtual,
|
||||||
html: dom_node,
|
html: dom_node,
|
||||||
|
level: node.level,
|
||||||
|
collapsed: true,
|
||||||
|
children: childs
|
||||||
}, parent_id, prop.group);
|
}, parent_id, prop.group);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete prop.html;
|
delete prop.html;
|
||||||
prop.active = active;
|
prop.active = active;
|
||||||
me.triggerEvent('insert-item', { id: id, data: prop, item: li });
|
me.triggerEvent('insert-item', { id: id, data: prop, item: li });
|
||||||
|
|
||||||
|
// register childs, too
|
||||||
|
if (childs.length) {
|
||||||
|
for (var cid, j=0; j < node.children.length; j++) {
|
||||||
|
if ((cid = node.children[j].id) && search_results[cid]) {
|
||||||
|
prop = search_results[cid];
|
||||||
|
delete prop.html;
|
||||||
|
prop.active = false;
|
||||||
|
me.triggerEvent('insert-item', { id: cid, data: prop });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the given item's parent's (partial) subscription state
|
||||||
|
function parent_subscription_status(li)
|
||||||
|
{
|
||||||
|
var top_li = li.closest(me.container.children('li')),
|
||||||
|
all_childs = $('li > div:not(.treetoggle)', top_li),
|
||||||
|
subscribed = all_childs.filter('.subscribed').length;
|
||||||
|
|
||||||
|
if (subscribed == 0) {
|
||||||
|
top_li.children('div:first').removeClass('subscribed partial');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
top_li.children('div:first')
|
||||||
|
.addClass('subscribed')[subscribed < all_childs.length ? 'addClass' : 'removeClass']('partial');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do some magic when search is performed on the widget
|
// do some magic when search is performed on the widget
|
||||||
|
@ -242,21 +283,39 @@ function kolab_folderlist(node, p)
|
||||||
this.container.on('click', 'a.subscribed, span.subscribed', function(e){
|
this.container.on('click', 'a.subscribed, span.subscribed', function(e){
|
||||||
var li = $(this).closest('li'),
|
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), ''),
|
||||||
div = li.children().first();
|
div = li.children().first(),
|
||||||
|
is_subscribed;
|
||||||
|
|
||||||
if (me.is_search())
|
if (me.is_search()) {
|
||||||
id = id.replace(/--xsR$/, '');
|
id = id.replace(/--xsR$/, '');
|
||||||
|
li = $(me.get_item(id, true));
|
||||||
|
div = $(div).add(li.children().first());
|
||||||
|
}
|
||||||
|
|
||||||
if (p.id_decode)
|
if (p.id_decode)
|
||||||
id = p.id_decode(id);
|
id = p.id_decode(id);
|
||||||
|
|
||||||
div.toggleClass('subscribed');
|
div.toggleClass('subscribed');
|
||||||
$(this).attr('aria-checked', div.hasClass('subscribed') ? 'true' : 'false');
|
is_subscribed = div.hasClass('subscribed');
|
||||||
me.triggerEvent('subscribe', { id: id, subscribed: div.hasClass('subscribed'), item: li });
|
$(this).attr('aria-checked', is_subscribed ? 'true' : 'false');
|
||||||
|
me.triggerEvent('subscribe', { id: id, subscribed: is_subscribed, item: li });
|
||||||
|
|
||||||
|
// update subscribe state of all 'virtual user' child folders
|
||||||
|
if (li.hasClass('other user')) {
|
||||||
|
$('ul li > div', li).each(function() {
|
||||||
|
$(this)[is_subscribed ? 'addClass' : 'removeClass']('subscribed');
|
||||||
|
$('.subscribed', div).attr('aria-checked', is_subscribed ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
div.removeClass('partial');
|
||||||
|
}
|
||||||
|
// propagate subscription state to parent 'virtual user' folder
|
||||||
|
else if (li.closest('li.other.user').length) {
|
||||||
|
parent_subscription_status(li);
|
||||||
|
}
|
||||||
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
return false;
|
return false;
|
||||||
})
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1534,6 +1534,16 @@ class kolab_storage
|
||||||
$folders[$foldername] = new kolab_storage_folder_user($foldername, $other_ns);
|
$folders[$foldername] = new kolab_storage_folder_user($foldername, $other_ns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for every (subscribed) user folder, list all (unsubscribed) subfolders
|
||||||
|
foreach ($folders as $userfolder) {
|
||||||
|
foreach ((array)self::list_folders($userfolder->name . $delimiter, '*', $type, false, $folderdata) as $foldername) {
|
||||||
|
if (!$folders[$foldername]) {
|
||||||
|
$folders[$foldername] = new kolab_storage_folder($foldername, $folderdata[$foldername]);
|
||||||
|
$userfolder->children[] = $folders[$foldername];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $folders;
|
return $folders;
|
||||||
|
|
|
@ -326,5 +326,14 @@ abstract class kolab_storage_folder_api
|
||||||
return $subscribed ? kolab_storage::folder_subscribe($this->name) : kolab_storage::folder_unsubscribe($this->name);
|
return $subscribed ? kolab_storage::folder_subscribe($this->name) : kolab_storage::folder_unsubscribe($this->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return folder name as string representation of this object
|
||||||
|
*
|
||||||
|
* @return string Full IMAP folder name
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
|
||||||
protected static $ldapcache = array();
|
protected static $ldapcache = array();
|
||||||
|
|
||||||
public $ldaprec;
|
public $ldaprec;
|
||||||
|
public $type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
|
@ -85,13 +86,28 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check subscription status of this folder
|
* Check subscription status of this folder.
|
||||||
|
* Subscription of a virtual user folder depends on the subscriptions of subfolders.
|
||||||
*
|
*
|
||||||
* @return boolean True if subscribed, false if not
|
* @return boolean True if subscribed, false if not
|
||||||
*/
|
*/
|
||||||
public function is_subscribed()
|
public function is_subscribed()
|
||||||
{
|
{
|
||||||
return kolab_storage::folder_is_subscribed($this->name, true);
|
if (!empty($this->type)) {
|
||||||
|
$children = $subscribed = 0;
|
||||||
|
$delimiter = $this->imap->get_hierarchy_delimiter();
|
||||||
|
foreach ((array)kolab_storage::list_folders($this->name . $delimiter, '*', $this->type, false) as $subfolder) {
|
||||||
|
if (kolab_storage::folder_is_subscribed($subfolder)) {
|
||||||
|
$subscribed++;
|
||||||
|
}
|
||||||
|
$children++;
|
||||||
|
}
|
||||||
|
if ($subscribed > 0) {
|
||||||
|
return $subscribed == $children ? true : 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,9 +119,17 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
|
||||||
*/
|
*/
|
||||||
public function subscribe($subscribed)
|
public function subscribe($subscribed)
|
||||||
{
|
{
|
||||||
return $subscribed ?
|
$success = false;
|
||||||
kolab_storage::folder_subscribe($this->name, true) :
|
|
||||||
kolab_storage::folder_unsubscribe($this->name, true);
|
// (un)subscribe all subfolders of a given type
|
||||||
|
if (!empty($this->type)) {
|
||||||
|
$delimiter = $this->imap->get_hierarchy_delimiter();
|
||||||
|
foreach ((array)kolab_storage::list_folders($this->name . $delimiter, '*', $this->type, false) as $subfolder) {
|
||||||
|
$success |= ($subscribed ? kolab_storage::folder_subscribe($subfolder) : kolab_storage::folder_unsubscribe($subfolder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue