From cfefedc8f72f63546dd07ae69487f42e96826502 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Thu, 5 Dec 2013 23:22:54 +0000 Subject: [PATCH] non-et2 Favorites work in progress Add current link shows popup with state details. --- calendar/inc/class.calendar_ui.inc.php | 11 +- phpgwapi/inc/class.egw_framework.inc.php | 132 ++++++++++++++++ phpgwapi/js/jsapi/app_base.js | 188 ++++++++++++++++++++++- 3 files changed, 328 insertions(+), 3 deletions(-) diff --git a/calendar/inc/class.calendar_ui.inc.php b/calendar/inc/class.calendar_ui.inc.php index 180e5ef41a..30e746a46b 100644 --- a/calendar/inc/class.calendar_ui.inc.php +++ b/calendar/inc/class.calendar_ui.inc.php @@ -552,7 +552,16 @@ class calendar_ui { $base_hidden_vars['keywords'] = $_POST['keywords']; } - + // Magic etemplate2 favorites menu (from nextmatch widget) + display_sidebox('calendar',lang('Favorites'),array( + array( + 'no_lang' => true, + 'text'=> egw_framework::favorite_list('calendar',false), + 'link'=>false, + 'icon' => false + ) + )); + $n = 0; // index for file-array $planner_days_for_view = false; diff --git a/phpgwapi/inc/class.egw_framework.inc.php b/phpgwapi/inc/class.egw_framework.inc.php index b61fc6b1e7..f7a2b9d924 100644 --- a/phpgwapi/inc/class.egw_framework.inc.php +++ b/phpgwapi/inc/class.egw_framework.inc.php @@ -1758,6 +1758,138 @@ $LAB.setOptions({AlwaysPreserveOrder:true,BasePath:"'.$GLOBALS['egw_info']['serv $response->script('window.egw.set_preferences('.json_encode($pref).', "'.$app.'");'); } } + + /** + * Include favorites when generating the page server-side + * + * Use this function in your sidebox (or anywhere else, I suppose) to + * get the favorite list when a nextmatch is _not_ on the page. If + * a nextmatch is on the page, it will update / replace this list. + * + * @param $app String Current application, needed to find preferences + * @param $default String Preference name for default favorite + * + * @return String HTML fragment for the list + */ + public static function favorite_list($app, $default) + { + if(!$app) return ''; + + // This target is used client-side to find & enable adding new favorites + $target = 'favorite_sidebox_'.$app; + $pref_prefix = 'favorite_'; + $filters = array( + 'blank' => array( + 'name' => lang('No filters'), + 'filters' => array(), + 'group' => true + ) + ); + $default_filter = $GLOBALS['egw_info']['user']['preferences'][$app][$default]; + if(!$default_filter) $default_filter = "blank"; + + $html = "'; + + return $html; + } + + /** + * Create or delete a favorite for multiple users + * + * Current user needs to be an admin or it will just do nothing quietly + * + * @param $app Current application, needed to save preference + * @param $name String Name of the favorite + * @param $action String add or delete + * @param $group int|String ID of the group to create the favorite for, or 'all' for all users + * @param $filters Array of key => value pairs for the filter + * + * @return boolean Success + */ + public static function ajax_set_favorite($app, $name, $action, $group, $filters = array()) + { + // Only use alphanumeric for preference name, so it can be used directly as DOM ID + $name = strip_tags($name); + $pref_name = "favorite_".preg_replace('/[^A-Za-z0-9-_]/','_',$name); + + if($group && $GLOBALS['egw_info']['apps']['admin']) + { + $prefs = new preferences(is_numeric($group) ? $group: $GLOBALS['egw_info']['user']['account_id']); + } + else + { + $prefs = $GLOBALS['egw']->preferences; + $type = 'user'; + } + $prefs->read_repository(); + $type = $group == "all" ? "default" : "user"; + if($action == "add") + { + $filters = array( + // This is the name as user entered it, minus tags + 'name' => $name, + 'group' => $group ? $group : false, + 'filter' => $filters + ); + $result = $prefs->add($app,$pref_name,$filters,$type); + $prefs->save_repository(false,$type); + + // Update preferences client side, or it could disappear + $pref = $GLOBALS['egw']->preferences->read_repository(false); + $pref = $pref[$app]; + if(!$pref) $pref = Array(); + egw_json_response::get()->script('window.egw.set_preferences('.json_encode($pref).', "'.$app.'");'); + + egw_json_response::get()->data(isset($result[$app][$pref_name])); + return isset($result[$app][$pref_name]); + } + else if ($action == "delete") + { + $result = $prefs->delete($app,$pref_name, $type); + $prefs->save_repository(false,$type); + + // Update preferences client side, or it could come back + $pref = $GLOBALS['egw']->preferences->read_repository(false); + $pref = $pref[$app]; + if(!$pref) $pref = Array(); + egw_json_response::get()->script('window.egw.set_preferences('.json_encode($pref).', "'.$app.'");'); + + egw_json_response::get()->data(!isset($result[$app][$pref_name])); + return !isset($result[$app][$pref_name]); + } + } } // Init all static variables diff --git a/phpgwapi/js/jsapi/app_base.js b/phpgwapi/js/jsapi/app_base.js index a7ba6296d5..667c500497 100644 --- a/phpgwapi/js/jsapi/app_base.js +++ b/phpgwapi/js/jsapi/app_base.js @@ -247,11 +247,195 @@ var AppJS = Class.extend( var et2 = etemplate2.getByApplication(this.appname); for(var i = 0; i < et2.length; i++) { - et2.widgetContainer.iterateOver(function(_widget) { + et2[i].widgetContainer.iterateOver(function(_widget) { state = _widget.getValue(); }, this, et2_nextmatch); } return state; - } + }, + + add_favorite: function() + { + if(typeof this.favorite_popup == "undefined") + { + this._create_favorite_popup(); + } + // Get current state + this.favorite_popup.state = this.getState(); +/* + // Add in extras + for(var extra in this.options.filters) + { + // Don't overwrite what nm has, chances are nm has more up-to-date value + if(typeof this.popup.current_filters == 'undefined') + { + this.popup.current_filters[extra] = this.nextmatch.options.settings[extra]; + } + } + + // Add in application's settings + if(this.filters != true) + { + for(var i = 0; i < this.filters.length; i++) + { + this.popup.current_filters[this.options.filters[i]] = this.nextmatch.options.settings[this.options.filters[i]]; + } + } +*/ + // Remove some internal values + delete this.favorite_popup.state[this.id]; + if(this.favorite_popup.group != undefined) + { + delete this.favorite_popup.state[this.favorite_popup.group.id]; + } + + // Make sure it's an object - deep copy to prevent references in sub-objects (col_filters) + this.favorite_popup.state = jQuery.extend(true,{},this.favorite_popup.state); + + // Update popup with current set filters (more for debug than user) + var filter_list = []; + var add_to_popup = function(arr) { + filter_list.push(""); + } + add_to_popup(this.favorite_popup.state); + $j("#"+this.appname+"_favorites_popup_state",this.favorite_popup) + .replaceWith( + $j(filter_list.join("")).attr("id",this.appname+"_favorites_popup_state") + ); + $j("#"+this.appname+"_favorites_popup_state",this.favorite_popup) + .hide() + .siblings(".ui-icon-circle-plus") + .removeClass("ui-icon-circle-minus"); + + // Popup + this.favorite_popup.dialog("open"); + console.log(this); + }, + + /** + * Create the "Add new" popup dialog + */ + _create_favorite_popup: function() + { + var self = this; + var favorite_prefix = 'favorite_'; + + // Clear old, if existing + if(this.favorite_popup && this.favorite_popup.group) + { + this.favorite_popup.group.free(); + delete this.favorite_popup; + } + + // Create popup + this.favorite_popup = $j('
\ +
\ + ' + + + '\ +
\ + '+ this.egw.lang("Details") + '\ +
    \ + \ +
' + ).appendTo(this.et2 ? this.et2.getDOMNode() : $j('body')); + + $j(".ui-icon-circle-plus",this.favorite_popup).prev().andSelf().click(function() { + var details = $j("#"+self.appname+"_favorites_popup_state",self.favorite_popup) + .slideToggle() + .siblings(".ui-icon-circle-plus") + .toggleClass("ui-icon-circle-minus"); + }); + + // Add some controls if user is an admin + var apps = egw().user('apps'); + var is_admin = (typeof apps['admin'] != "undefined"); + if(is_admin) + { + this.favorite_popup.group = et2_createWidget("select-account",{ + id: "favorite[group]", + account_type: "groups", + empty_label: "Groups", + no_lang: true, + parent_node: this.appname+'_favorites_popup_admin' + },this.et2 || null); + + } + + var buttons = {}; + buttons[this.egw.lang("save")] = function() { + // Add a new favorite + var name = $j("#name",this); + + if(name.val()) + { + // Add to the list + name.val(name.val().replace(/(<([^>]+)>)/ig,"")); + var safe_name = name.val().replace(/[^A-Za-z0-9-_]/g,"_"); + self.stored_filters[safe_name] = { + name: name.val(), + group: (typeof self.favorite_popup.group != "undefined" && + self.favorite_popup.group.get_value() ? self.favorite_popup.group.get_value() : false), + state: self.favorite_popup.state + }; + self.init_filters(self); + + var favorite_pref = favorite_prefix+safe_name; + + // Save to preferences + if(typeof self.favorite_popup.group != "undefined" && self.favorite_popup.group.getValue() != '') + { + // Admin stuff - save preference server side + self.egw.jsonq('home.egw_framework.ajax_set_favorite.template' + [ + self.options.app, + name.val(), + "add", + self.favorite_popup.group.get_value(), + self.favorite_popup.state + ] + ); + self.favorite_popup.group.set_value(''); + } + else + { + // Normal user - just save to preferences client side + self.egw.set_preference(self.appname,favorite_pref,{ + name: name.val(), + group: false, + state:self.favorite_popup.state + }); + } + delete self.favorite_popup.state; + } + // Reset form + name.val(""); + $j("#filters",self.favorite_popup).empty(); + + $j(this).dialog("close"); + }; + buttons[this.egw.lang("cancel")] = function() { + self.favorite_popup.group.set_value(null); + $j(this).dialog("close"); + }; + + this.favorite_popup.dialog({ + autoOpen: false, + modal: true, + buttons: buttons, + close: function() { + } + }); + }, });