From d7dfd44c8b86452a6e447ac35a74902cc625594d Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Tue, 9 Feb 2016 20:28:57 +0000 Subject: [PATCH] Use taglist for owner --- calendar/inc/class.calendar_ui.inc.php | 31 +++++++++-- calendar/inc/class.calendar_uiforms.inc.php | 53 ++++++++++++++++++ calendar/js/app.js | 22 +++++--- calendar/js/et2_widget_owner.js | 59 +++++++++++++++++++++ calendar/templates/default/sidebox.xet | 2 +- calendar/templates/pixelegg/app.css | 2 +- 6 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 calendar/js/et2_widget_owner.js diff --git a/calendar/inc/class.calendar_ui.inc.php b/calendar/inc/class.calendar_ui.inc.php index d1a68255f3..c863873105 100644 --- a/calendar/inc/class.calendar_ui.inc.php +++ b/calendar/inc/class.calendar_ui.inc.php @@ -618,20 +618,45 @@ class calendar_ui $content['date'] = $this->date ? $this->date : egw_time(); $owners = $this->owner ? is_array($this->owner) ? array($this->owner) : explode(',',$this->owner) : array($GLOBALS['egw_info']['user']['account_id']); - + $sel_options = array(); + // Get user accounts, formatted nicely for grouping and matching + // the ajax call calendar_uiforms->ajax_owner() + $account_options = array('account_type' => 'both'); + $accounts = accounts::link_query('',$account_options); + $sel_options['owner'] = array_map( + function($account_id, $account_name) { + return array( + 'value' => $account_id, + 'label' => $account_name, + 'app' => lang('home-accounts') + ); + }, + array_keys($accounts), $accounts + ); + // Add external owners that a select account widget will not find $linked_owners = array(); - foreach($owners as $owner) + foreach($owners as &$owner) { + $owner = ''.$owner; if(!is_numeric($owner)) { $resource = $this->bo->resources[substr($owner, 0,1)]; $label = egw_link::title($resource['app'], substr($owner,1)); $linked_owners[$resource['app']][substr($owner,1)] = $label; - $sel_options['owner'][] = array('value' => $owner, 'label' => $label); } + else if (!in_array($owner, array_keys($accounts))) + { + $label = egw_link::title('home-accounts',$owner); + $resource = array('app'=> 'home-accounts'); + } + else + { + continue; + } + $sel_options['owner'][] = array('value' => $owner, 'label' => $label, 'app' => lang($resource['app'])); } if($linked_owners) { diff --git a/calendar/inc/class.calendar_uiforms.inc.php b/calendar/inc/class.calendar_uiforms.inc.php index ba800dfd2b..dbd5838479 100644 --- a/calendar/inc/class.calendar_uiforms.inc.php +++ b/calendar/inc/class.calendar_uiforms.inc.php @@ -2941,6 +2941,59 @@ class calendar_uiforms extends calendar_ui } } + /** + * Handle ajax searches for owner across all supported resources + * + * @return Array List of matching results + */ + public function ajax_owner() + { + $query = $_REQUEST['query']; + $options = ['num_rows' => 100]; + $results = []; + if($query) + { + foreach($this->bo->resources as $type => $data) + { + $mapped = array(); + if ($data['app'] && egw_link::get_registry($data['app'], 'query')) + { + $_results = egw_link::query($data['app'], $query,$options); + if(!$_results) continue; + $r_results = array_unique($_results); + foreach($_results as $id => $title) + { + if($id && $title) + { + // Magicsuggest uses id, not value. + $value = [ + 'id' => $type.$id, + 'value'=> $type.$id, + 'label' => $title, + 'app' => lang($data['app']) + ]; + if(is_array($value['label'])) + { + $value = array_merge($value, $value['label']); + } + $mapped[] = $value; + } + } + if(count($mapped)) + { + $results = array_merge($results, $mapped); + } + } + } + } + // switch regular JSON response handling off + egw_json_request::isJSONRequest(false); + + header('Content-Type: application/json; charset=utf-8'); + echo json_encode($results); + common::egw_exit(); + } + /** * imports a mail as Calendar * diff --git a/calendar/js/app.js b/calendar/js/app.js index 8476053d2d..0ae8250e23 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -12,6 +12,7 @@ /*egw:uses /etemplate/js/etemplate2.js; + /calendar/js/et2_widget_owner.js; /calendar/js/et2_widget_timegrid.js; /calendar/js/et2_widget_planner.js; */ @@ -1972,13 +1973,6 @@ app.classes.calendar = AppJS.extend( { state.state.owner[state.state.owner.indexOf('0')] = this.egw.user('account_id'); } - if(state.state.owner.length === 1 && this.sidebox_et2) - { - // If only one owner selected, go back to single select - var owner = this.sidebox_et2.getWidgetById('owner'); - owner.set_multiple(false); - } - // Show the correct number of grids var grid_count = 0; @@ -2747,6 +2741,10 @@ app.classes.calendar = AppJS.extend( } if(!found) { + if(!widget.options.select_options.push) + { + widget.options.select_options = []; + } widget.options.select_options.push(option); } } @@ -2884,7 +2882,7 @@ app.classes.calendar = AppJS.extend( for(var day in updated_days) { // Might be split by user, so we have to check that too - for(var i = 0; i < state.owner.length; i++) + for(var i = 0; i < typeof state.owner == 'object' ? state.owner.length : 1; i++) { var owner = multiple_owner ? state.owner[i] : state.owner; var cache_id = app.classes.calendar._daywise_cache_id(day, owner); @@ -3247,6 +3245,14 @@ app.classes.calendar = AppJS.extend( button.parent().css('margin-right',button.outerWidth(true)+2); button.parent().parent().css('white-space','nowrap'); } + $j(window).on('resize.calendar-owner', function() { + var preferred_width = $j('#calendar-et2_target').children().first().outerWidth()||0; + var owner = app.calendar.sidebox_et2.getWidgetById('owner'); + if(preferred_width && owner.input.hasClass("chzn-done")) + { + owner.input.next().css('width',preferred_width); + } + }); }, /** diff --git a/calendar/js/et2_widget_owner.js b/calendar/js/et2_widget_owner.js new file mode 100644 index 0000000000..5f6a9d4ee2 --- /dev/null +++ b/calendar/js/et2_widget_owner.js @@ -0,0 +1,59 @@ +/* + * Egroupware + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package + * @subpackage + * @link http://www.egroupware.org + * @author Nathan Gray + * @version $Id$ + */ + + +"use strict"; + +/*egw:uses + et2_widget_taglist; +*/ + +/** + * Tag list widget customised for calendar owner, which can be a user + * account or group, or an entry from almost any app, or an email address + * + * A cross between auto complete, selectbox and chosen multiselect + * + * Uses MagicSuggest library + * @see http://nicolasbize.github.io/magicsuggest/ + * @augments et2_selectbox + */ +var et2_calendar_owner = et2_taglist_email.extend( +{ + attributes: { + "autocomplete_url": { + "default": "calendar.calendar_uiforms.ajax_owner.etemplate" + }, + "autocomplete_params": { + "name": "Autocomplete parameters", + "type": "any", + "default": {}, + "description": "Extra parameters passed to autocomplete URL. It should be a stringified JSON object." + }, + allowFreeEntries: { + "default": false, + ignore: true + }, + select_options: { + "type": "any", + "name": "Select options", + // Set to empty object to use selectbox's option finding + "default": {}, + "description": "Internaly used to hold the select options." + }, + }, + + // Allows sub-widgets to override options to the library + lib_options: { + groupBy: 'app', + expandOnFocus: true + } +}); +et2_register_widget(et2_calendar_owner, ["calendar_owner"]); \ No newline at end of file diff --git a/calendar/templates/default/sidebox.xet b/calendar/templates/default/sidebox.xet index b9e6b4d50b..98aee8933d 100644 --- a/calendar/templates/default/sidebox.xet +++ b/calendar/templates/default/sidebox.xet @@ -27,7 +27,7 @@ if(view_change >= 0) {update.view = app.calendar.sidebox_changes_views[view_chan - +