diff --git a/calendar/inc/class.calendar_owner_etemplate_widget.inc.php b/calendar/inc/class.calendar_owner_etemplate_widget.inc.php index 9129487214..196ee1584e 100644 --- a/calendar/inc/class.calendar_owner_etemplate_widget.inc.php +++ b/calendar/inc/class.calendar_owner_etemplate_widget.inc.php @@ -151,7 +151,7 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist $labels = Array(); foreach($id as $index => $_id) { - $labels[$_id] = self::get_owner_label($_id); + $labels[$_id] = self::format_owner($_id, self::get_owner_label($_id)); } Api\Json\Response::get()->data($labels); return $labels; @@ -232,38 +232,7 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist { if($id && $title) { - // Magicsuggest uses id, not value. - $value = array( - 'id' => $type.$id, - 'value'=> $type.$id, - 'label' => $title, - 'app' => lang($data['app']) - ); - if(is_array($value['label'])) - { - $value = array_merge($value, $value['label']); - } - switch($type) - { - case 'r': - // TODO: fetch resources photo - break; - case 'c': - case '': - $contact = $contacts_obj->read($type === '' ? 'account:'.$id : $id, true); - if (is_array($contact)) $value['icon'] = Api\Framework::link('/api/avatar.php', array( - 'contact_id' => $contact['id'], - 'etag' => $contact['etag'] ? $contact['etag'] : 1 - )); - if($id < 0) - { - $value['resources'] = array_map('strval',$GLOBALS['egw']->accounts->members($id, true)); - } - break; - default : - // do nothing - } - $mapped[] = $value; + $mapped[] = static::format_owner($id, $title, $data); } } if(count($mapped)) @@ -280,6 +249,68 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist exit(); } + /** + * Given an ID & title, format the result into data the client side wants + * + * @param $id + * @param $title + * @param $type + */ + protected static function format_owner($id, $title, $data = array()) + { + static $contacts_obj = null; + if(is_null($contacts_obj)) + { + $contacts_obj = new Api\Contacts(); + } + if(!$data) + { + $bo = new calendar_bo(); + if(!is_numeric($id)) + { + $data = $bo->resources[substr($id, 0, 1)]; + } + else + { + $data = $bo->resources['']; + } + } + $type = $data['type']; + + // Magicsuggest uses id, not value. + $value = array( + 'id' => $type.$id, + 'value'=> $type.$id, + 'label' => $title, + 'app' => lang($data['app']) + ); + if(is_array($value['label'])) + { + $value = array_merge($value, $value['label']); + } + switch($type) + { + case 'r': + // TODO: fetch resources photo + break; + case 'c': + case '': + $contact = $contacts_obj->read($type === '' ? 'account:'.$id : $id, true); + if (is_array($contact)) $value['icon'] = Api\Framework::link('/api/avatar.php', array( + 'contact_id' => $contact['id'], + 'etag' => $contact['etag'] ? $contact['etag'] : 1 + )); + if($id < 0) + { + $value['resources'] = array_map('strval',$GLOBALS['egw']->accounts->members($id, true)); + } + break; + default : + // do nothing + } + return $value; + } + /** * Get just the label for a single owner * @param string $id diff --git a/calendar/js/et2_widget_daycol.js b/calendar/js/et2_widget_daycol.js index 77102101cf..1f0ab645d0 100644 --- a/calendar/js/et2_widget_daycol.js +++ b/calendar/js/et2_widget_daycol.js @@ -96,9 +96,9 @@ var et2_calendar_daycol = /** @class */ (function (_super) { if (this.title.text() === '' && this.options.date && this.getParent() && this.getParent().instanceOf(et2_widget_timegrid_1.et2_calendar_timegrid)) { // Forces an update - var date_1 = this.options.date; + var date = this.options.date; this.options.date = ''; - this.set_date(date_1); + this.set_date(date); } return result; }; diff --git a/calendar/js/et2_widget_owner.js b/calendar/js/et2_widget_owner.js index c9ce765a79..3d2b0f0a69 100644 --- a/calendar/js/et2_widget_owner.js +++ b/calendar/js/et2_widget_owner.js @@ -115,8 +115,10 @@ var et2_calendar_owner = /** @class */ (function (_super) { return "continue"; var idx = this_1.options.value.find(function (element) { return element.id == owner; }); if (idx) { - idx.label = data[owner]; + idx = jQuery.extend(idx, data[owner]); } + // Put it in the list of options for next time + this_1.options.select_options.push(data[owner]); }; var this_1 = this; for (var owner in data) { diff --git a/calendar/js/et2_widget_owner.ts b/calendar/js/et2_widget_owner.ts index 5e971975a2..35eadd18a4 100644 --- a/calendar/js/et2_widget_owner.ts +++ b/calendar/js/et2_widget_owner.ts @@ -139,8 +139,10 @@ export class et2_calendar_owner extends et2_taglist_email let idx = this.options.value.find(element => element.id == owner); if(idx) { - idx.label = data[owner]; + idx = jQuery.extend(idx, data[owner]); } + // Put it in the list of options for next time + this.options.select_options.push(data[owner]); } this.set_value(this.options.value); }, this,true,this).sendRequest(); diff --git a/calendar/js/et2_widget_planner.js b/calendar/js/et2_widget_planner.js index be49999535..0715a04a7a 100644 --- a/calendar/js/et2_widget_planner.js +++ b/calendar/js/et2_widget_planner.js @@ -118,7 +118,13 @@ var et2_calendar_planner = /** @class */ (function (_super) { } } } - else if (already_added.indexOf('' + user) < 0) { + else if (user < 0) { + // Group, but no users found. Need those. + egw.accountData(parseInt(user), 'account_fullname', true, function (result) { + this.invalidate(); + }, this); + } + else if (already_added.indexOf('' + user) < 0 && parseInt(user) >= 0) { labels.push({ id: user, label: this._get_owner_name(user), @@ -1628,6 +1634,63 @@ var et2_calendar_planner = /** @class */ (function (_super) { this.invalidate(true); } }; + /** + * Set which users to display + * + * Changing the owner will invalidate the display, and it will be redrawn + * after a timeout. Overwriting here to check for groups without members. + * + * @param {number|number[]|string|string[]} _owner - Owner ID, which can + * be an account ID, a resource ID (as defined in calendar_bo, not + * necessarily an entry from the resource app), or a list containing a + * combination of both. + * + * @memberOf et2_calendar_view + */ + et2_calendar_planner.prototype.set_owner = function (_owner) { + _super.prototype.set_owner.call(this, _owner); + // If we're grouping by user, we need group members + if (this.update_timer !== null && this.options.group_by == 'user') { + var options_1 = []; + var resource = {}; + var missing_resources_1 = []; + if (app.calendar && app.calendar.sidebox_et2 && app.calendar.sidebox_et2.getWidgetById('owner')) { + options_1 = app.calendar.sidebox_et2.getWidgetById('owner').taglist.getSelection(); + } + else { + options_1 = this.getArrayMgr("sel_options").getRoot().getEntry('owner'); + } + for (var i = 0; i < this.options.owner.length; i++) { + var user = this.options.owner[i]; + if (isNaN(user) || user >= 0 || !options_1) + continue; + // Owner is a group, see if we have its members + if (options_1.find && + ((resource = options_1.find(function (element) { + return element.id == user; + })))) { + // Members found + continue; + } + // Group, but no users found. Need those. + missing_resources_1.push(user); + // Maybe api already has them? + egw.accountData(parseInt(user), 'account_fullname', true, function (result) { + missing_resources_1.splice(missing_resources_1.indexOf(this), 1); + }.bind(user), user); + } + if (missing_resources_1.length > 0) { + // Ask server, and WAIT or we have to redraw + egw.json('calendar_owner_etemplate_widget::ajax_owner', [missing_resources_1], function (data) { + for (var owner in data) { + if (!owner || typeof owner == "undefined") + continue; + options_1.push(data[owner]); + } + }, this, false, this).sendRequest(false); + } + } + }; /** * Turn on or off the visibility of weekends * diff --git a/calendar/js/et2_widget_planner.ts b/calendar/js/et2_widget_planner.ts index ab041f5df6..9a69a4be3c 100644 --- a/calendar/js/et2_widget_planner.ts +++ b/calendar/js/et2_widget_planner.ts @@ -446,7 +446,14 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta } } } - else if(already_added.indexOf(''+user) < 0) + else if (user < 0) + { + // Group, but no users found. Need those. + egw.accountData(parseInt(user),'account_fullname',true,function(result) { + this.invalidate(); + },this); + } + else if(already_added.indexOf(''+user) < 0 && parseInt(user) >= 0) { labels.push({ id: user, @@ -2093,6 +2100,75 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta } } + /** + * Set which users to display + * + * Changing the owner will invalidate the display, and it will be redrawn + * after a timeout. Overwriting here to check for groups without members. + * + * @param {number|number[]|string|string[]} _owner - Owner ID, which can + * be an account ID, a resource ID (as defined in calendar_bo, not + * necessarily an entry from the resource app), or a list containing a + * combination of both. + * + * @memberOf et2_calendar_view + */ + set_owner(_owner) + { + super.set_owner(_owner); + + // If we're grouping by user, we need group members + if(this.update_timer !== null && this.options.group_by == 'user') + { + let options = []; + let resource = {}; + let missing_resources = []; + + if(app.calendar && app.calendar.sidebox_et2 && app.calendar.sidebox_et2.getWidgetById('owner')) + { + options = app.calendar.sidebox_et2.getWidgetById('owner').taglist.getSelection(); + } + else + { + options = this.getArrayMgr("sel_options").getRoot().getEntry('owner'); + } + for(var i = 0; i < this.options.owner.length; i++) + { + var user = this.options.owner[i]; + if(isNaN(user) || user >= 0 || !options) continue; + + // Owner is a group, see if we have its members + if(options.find && + ((resource = options.find(function (element) + { + return element.id == user; + })))) + { + // Members found + continue; + } + // Group, but no users found. Need those. + missing_resources.push(user); + + // Maybe api already has them? + egw.accountData(parseInt(user),'account_fullname',true,function(result) { + missing_resources.splice(missing_resources.indexOf(this),1); + }.bind(user),user); + } + if(missing_resources.length > 0) + { + // Ask server, and WAIT or we have to redraw + egw.json('calendar_owner_etemplate_widget::ajax_owner',[missing_resources],function(data) { + for(let owner in data) + { + if(!owner || typeof owner == "undefined") continue; + options.push(data[owner]); + } + }, this,false,this).sendRequest(false); + } + } + } + /** * Turn on or off the visibility of weekends *