mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-08-18 12:30:02 +02:00
Some WIP on getting home working again
This commit is contained in:
@@ -43,12 +43,21 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"default": window.egw_webserverUrl+"/home/templates/default/edit.xet"
|
"default": window.egw_webserverUrl+"/home/templates/default/edit.xet"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"name": "Color",
|
||||||
|
"description": "Set the portlet color",
|
||||||
|
"type": "string",
|
||||||
|
"default": ''
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"name": "Customization settings",
|
"name": "Customization settings",
|
||||||
"description": "Array of customization settings, similar in structure to preference settings",
|
"description": "Array of customization settings, similar in structure to preference settings",
|
||||||
"type": "any",
|
"type": "any",
|
||||||
"default": et2_no_init
|
"default": et2_no_init
|
||||||
},
|
},
|
||||||
|
"actions": {
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
"width": { "default": 2, "ignore": true},
|
"width": { "default": 2, "ignore": true},
|
||||||
"height": { "default": 1, "type": "integer"},
|
"height": { "default": 1, "type": "integer"},
|
||||||
"rows": {"ignore": true},
|
"rows": {"ignore": true},
|
||||||
@@ -66,7 +75,7 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
},
|
},
|
||||||
|
|
||||||
createNamespace: true,
|
createNamespace: true,
|
||||||
GRID: 50,
|
GRID: 100,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are the "normal" actions that every portlet is expected to have.
|
* These are the "normal" actions that every portlet is expected to have.
|
||||||
@@ -126,10 +135,12 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.header = $j(document.createElement("div"))
|
this.header = $j(document.createElement("div"))
|
||||||
|
.attr('id', this.getInstanceManager().uniqueId+'_'+this.id.replace(/\./g, '-') + '_header')
|
||||||
.addClass("ui-widget-header ui-corner-all")
|
.addClass("ui-widget-header ui-corner-all")
|
||||||
.appendTo(this.div)
|
.appendTo(this.div)
|
||||||
.html(this.options.title);
|
.html(this.options.title);
|
||||||
this.content = $j(document.createElement("div"))
|
this.content = $j(document.createElement("div"))
|
||||||
|
.attr('id', this.getInstanceManager().uniqueId+'_'+this.id.replace(/\./g, '-') + '_content')
|
||||||
.appendTo(this.div);
|
.appendTo(this.div);
|
||||||
|
|
||||||
this.setDOMNode(this.div[0]);
|
this.setDOMNode(this.div[0]);
|
||||||
@@ -137,6 +148,15 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
|
|
||||||
destroy: function()
|
destroy: function()
|
||||||
{
|
{
|
||||||
|
for(var i = 0; i < this._children.length; i++)
|
||||||
|
{
|
||||||
|
// Check for child is a different template and clear it,
|
||||||
|
// since it won't be cleared by destroy()
|
||||||
|
if(this._children[i]._inst != this._inst)
|
||||||
|
{
|
||||||
|
this._children[i]._inst.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -233,7 +253,7 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
buttons: et2_dialog.BUTTONS_OK_CANCEL
|
buttons: et2_dialog.BUTTONS_OK_CANCEL
|
||||||
},this);
|
},this);
|
||||||
// Set seperately to avoid translation
|
// Set seperately to avoid translation
|
||||||
dialog.set_title(this.egw().lang("Edit") + " " + this.options.title);
|
dialog.set_title(this.egw().lang("Edit") + " " + (this.options.title || ''));
|
||||||
},
|
},
|
||||||
|
|
||||||
_process_edit: function(button_id, value)
|
_process_edit: function(button_id, value)
|
||||||
@@ -241,10 +261,14 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
if(button_id != et2_dialog.OK_BUTTON) return;
|
if(button_id != et2_dialog.OK_BUTTON) return;
|
||||||
|
|
||||||
|
|
||||||
// Save settings - server will reply with new content, if the portlet needs an update
|
// Save settings - server might reply with new content if the portlet needs an update,
|
||||||
|
// but ideally it doesn't
|
||||||
this.div.addClass("loading");
|
this.div.addClass("loading");
|
||||||
this.egw().jsonq("home.home_ui.ajax_set_properties",[this.id, this.options.settings || {}, value],
|
this.egw().jsonq("home.home_ui.ajax_set_properties",[this.id, this.options.settings || {}, value],
|
||||||
function(data) {
|
function(data) {
|
||||||
|
// This section not for us
|
||||||
|
if(!data || typeof data.attributes == 'undefined') return false;
|
||||||
|
|
||||||
this.div.removeClass("loading");
|
this.div.removeClass("loading");
|
||||||
this.set_value(data.content);
|
this.set_value(data.content);
|
||||||
for(var key in data.attributes)
|
for(var key in data.attributes)
|
||||||
@@ -337,10 +361,6 @@ var et2_portlet = et2_valueWidget.extend(
|
|||||||
{
|
{
|
||||||
this.options.height = value;
|
this.options.height = value;
|
||||||
this.div.attr("data-sizey", value);
|
this.div.attr("data-sizey", value);
|
||||||
|
|
||||||
// Explicitly set the height of the content, so it can properly scroll. Sometimes set_height()
|
|
||||||
// is called before everything is in the DOM though, so use a magic 18px in that case.
|
|
||||||
this.content.height(value * this.GRID - (this.header.outerHeight() > 0 ? this.header.outerHeight() : 18));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -1154,9 +1154,6 @@ div.message.floating {
|
|||||||
/**
|
/**
|
||||||
* et2_portlet
|
* et2_portlet
|
||||||
*/
|
*/
|
||||||
div.et2_portlet {
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
.et2_portlet .ui-widget-header {
|
.et2_portlet .ui-widget-header {
|
||||||
margin: 0em;
|
margin: 0em;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
|
@@ -29,7 +29,7 @@ class home_legacy_portlet extends home_portlet
|
|||||||
*/
|
*/
|
||||||
protected $content = '';
|
protected $content = '';
|
||||||
|
|
||||||
public function __construct(array &$context = array())
|
public function __construct(array &$context = array(), &$need_reload = false)
|
||||||
{
|
{
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
|
||||||
@@ -90,9 +90,13 @@ class home_legacy_portlet extends home_portlet
|
|||||||
* unique, if needed.
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
* @return string HTML fragment for display
|
||||||
*/
|
*/
|
||||||
public function get_content($id = null)
|
public function exec($id = null, etemplate_new &$etemplate = null)
|
||||||
{
|
{
|
||||||
return $this->content;
|
$etemplate->read('home.legacy');
|
||||||
|
|
||||||
|
$etemplate->set_dom_id($id);
|
||||||
|
|
||||||
|
$etemplate->exec('home.home_link_portlet.exec',array('legacy' => $this->content), array(),array(),array(),2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,19 +24,27 @@ class home_link_portlet extends home_portlet
|
|||||||
*/
|
*/
|
||||||
protected $title = 'Link';
|
protected $title = 'Link';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base name for template
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $template_name = 'home.link';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the portlet
|
* Construct the portlet
|
||||||
*
|
*
|
||||||
|
* @param boolean $need_reload Flag to indicate that the portlet needs to be reloaded (exec will be called)
|
||||||
*/
|
*/
|
||||||
public function __construct(Array &$context = array())
|
public function __construct(Array &$context = array(), &$need_reload = false)
|
||||||
{
|
{
|
||||||
// Process dropped data into something useable
|
// Process dropped data into something useable
|
||||||
if($context['dropped_data'])
|
if($context['dropped_data'])
|
||||||
{
|
{
|
||||||
list($context['entry']['app'], $context['entry']['id']) = explode('::', $context['dropped_data'][0], 2);
|
list($context['entry']['app'], $context['entry']['id']) = explode('::', $context['dropped_data'][0], 2);
|
||||||
unset($context['dropped_data']);
|
unset($context['dropped_data']);
|
||||||
|
$need_reload = true;
|
||||||
}
|
}
|
||||||
if($context['entry'])
|
if($context['entry'] && is_array($context['entry']));
|
||||||
{
|
{
|
||||||
$this->title = $context['entry']['title'] = egw_link::title($context['entry']['app'], $context['entry']['id']);
|
$this->title = $context['entry']['title'] = egw_link::title($context['entry']['app'], $context['entry']['id']);
|
||||||
}
|
}
|
||||||
@@ -64,15 +72,33 @@ class home_link_portlet extends home_portlet
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a fragment of HTML for display
|
* Generate display
|
||||||
*
|
*
|
||||||
* @param id String unique ID, provided to the portlet so it can make sure content is
|
* @param id String unique ID, provided to the portlet so it can make sure content is
|
||||||
* unique, if needed.
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
|
||||||
*/
|
*/
|
||||||
public function get_content($id = null)
|
public function exec($id = null, etemplate_new &$etemplate = null)
|
||||||
{
|
{
|
||||||
return $this->title;
|
// Check for custom template for app
|
||||||
|
if($this->context && $this->context['entry'] && $this->context['entry']['app'] &&
|
||||||
|
$etemplate->read($this->context['entry']['app'] . '.' . $this->template_name))
|
||||||
|
{
|
||||||
|
// No action needed, custom template loaded as side-effect
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$etemplate->read($this->template_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$etemplate->set_dom_id($id);
|
||||||
|
|
||||||
|
$content = $this->context;
|
||||||
|
if(!is_array($content['entry']))
|
||||||
|
{
|
||||||
|
$content['entry'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$etemplate->exec('home.home_link_portlet.exec',$content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,13 +119,15 @@ class home_link_portlet extends home_portlet
|
|||||||
*/
|
*/
|
||||||
public function get_properties()
|
public function get_properties()
|
||||||
{
|
{
|
||||||
return array(
|
$properties = parent::get_properties();
|
||||||
array(
|
|
||||||
|
$properties[] = array(
|
||||||
'name' => 'entry',
|
'name' => 'entry',
|
||||||
'type' => 'link-entry',
|
'type' => 'link-entry',
|
||||||
'label' => lang('Entry'),
|
'label' => lang('Entry'),
|
||||||
)
|
'size' => ''
|
||||||
) + parent::get_properties();
|
);
|
||||||
|
return $properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -36,7 +36,7 @@ class home_list_portlet extends home_portlet
|
|||||||
* Construct the portlet
|
* Construct the portlet
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function __construct(Array &$context = array())
|
public function __construct(Array &$context = array(), &$need_reload = false)
|
||||||
{
|
{
|
||||||
if(!is_array($context['list'])) $context['list'] = array();
|
if(!is_array($context['list'])) $context['list'] = array();
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ class home_list_portlet extends home_portlet
|
|||||||
}
|
}
|
||||||
unset($add);
|
unset($add);
|
||||||
unset($context['dropped_data']);
|
unset($context['dropped_data']);
|
||||||
|
$need_reload = true;
|
||||||
}
|
}
|
||||||
if($context['title'])
|
if($context['title'])
|
||||||
{
|
{
|
||||||
@@ -89,37 +90,18 @@ class home_list_portlet extends home_portlet
|
|||||||
* unique, if needed.
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
* @return string HTML fragment for display
|
||||||
*/
|
*/
|
||||||
public function get_content($id = null)
|
public function exec($id = null, etemplate_new &$etemplate = null)
|
||||||
{
|
{
|
||||||
$list = array();
|
$etemplate->read('home.list');
|
||||||
foreach($this->context['list'] as $link_id => $link)
|
|
||||||
|
$etemplate->set_dom_id($id);
|
||||||
|
$content = $this->context;
|
||||||
|
if(!is_array($content['list']))
|
||||||
{
|
{
|
||||||
$list[] = $link + array(
|
$content['list'] = Array();
|
||||||
'title' => egw_link::title($link['app'], $link['id']),
|
|
||||||
'icon' => egw_link::get_registry($link['app'], 'icon')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the portlet widget, and add a link-list to it
|
$etemplate->exec('home.home_list_portlet.exec',$content);
|
||||||
$script = 'app.home.List.set_content("'.$id.'", '.json_encode($list).');';
|
|
||||||
if(egw_json_response::isJSONResponse())
|
|
||||||
{
|
|
||||||
$response = egw_json_response::get();
|
|
||||||
// This has to go last, after the template is loaded
|
|
||||||
$response->addBeforeSendDataCallback(
|
|
||||||
function($response, $script) {
|
|
||||||
// Bind to load event to make sure template is loaded first
|
|
||||||
$response->script('$j("#home-index").on("load", function() {'.$script.'});');
|
|
||||||
}
|
|
||||||
,$response, $script
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Not a JSON Response? Probably an idots first load
|
|
||||||
$response = egw_json_response::get();
|
|
||||||
// Bind to load event to make sure template is loaded first
|
|
||||||
$response->script('$j("#home-index").on("load", function() {'.$script.'});');
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,17 +122,18 @@ class home_list_portlet extends home_portlet
|
|||||||
*/
|
*/
|
||||||
public function get_properties()
|
public function get_properties()
|
||||||
{
|
{
|
||||||
return array(
|
$properties = parent::get_properties();
|
||||||
array(
|
|
||||||
'name' => 'title',
|
$properties[] = array(
|
||||||
'type' => 'textbox',
|
'name' => 'title',
|
||||||
'label' => lang('Title'),
|
'type' => 'textbox',
|
||||||
),
|
'label' => lang('Title'),
|
||||||
// Internal
|
);
|
||||||
array(
|
// Internal - no type means it won't show in configure dialog
|
||||||
'name' => 'list'
|
$properties[] = array(
|
||||||
)
|
'name' => 'list'
|
||||||
) + parent::get_properties();
|
);
|
||||||
|
return $properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +156,7 @@ class home_list_portlet extends home_portlet
|
|||||||
'type' => 'drop',
|
'type' => 'drop',
|
||||||
'caption' => lang('add'),
|
'caption' => lang('add'),
|
||||||
'onExecute' => 'javaScript:app.home.add_link',
|
'onExecute' => 'javaScript:app.home.add_link',
|
||||||
'acceptedTypes' => array('file') + array_keys($GLOBALS['egw_info']['apps']),
|
'acceptedTypes' => array('file','link') + array_keys($GLOBALS['egw_info']['apps']),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return $actions;
|
return $actions;
|
||||||
|
@@ -30,8 +30,9 @@ abstract class home_portlet
|
|||||||
* better to use get_properties().
|
* better to use get_properties().
|
||||||
*
|
*
|
||||||
* @param context Array portlet settings such as size, as well as values for properties
|
* @param context Array portlet settings such as size, as well as values for properties
|
||||||
|
* @param boolean $need_reload Flag to indicate that the portlet needs to be reloaded (exec will be called)
|
||||||
*/
|
*/
|
||||||
public abstract function __construct(Array &$context = array());
|
public abstract function __construct(Array &$context = array(), &$need_reload = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some descriptive information about the portlet, so that users can decide if
|
* Some descriptive information about the portlet, so that users can decide if
|
||||||
@@ -47,13 +48,14 @@ abstract class home_portlet
|
|||||||
public abstract function get_description();
|
public abstract function get_description();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a fragment of HTML for display
|
* Generate the display for the portlet
|
||||||
*
|
*
|
||||||
* @param id String unique ID, provided to the portlet so it can make sure content is
|
* @param id String unique ID, provided to the portlet so it can make sure content is
|
||||||
* unique, if needed.
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
* @param etemplate etemplate_new Etemplate to generate content
|
||||||
|
* @param dom_id String ID of the etemplate targe DOM node. If passed, send -1 to etemplate->exec()
|
||||||
*/
|
*/
|
||||||
public abstract function get_content($id = null);
|
public abstract function exec($id = null, etemplate_new &$etemplate = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of settings to customize the portlet.
|
* Return a list of settings to customize the portlet.
|
||||||
@@ -79,6 +81,12 @@ abstract class home_portlet
|
|||||||
{
|
{
|
||||||
$properties[$prop] = array('name' => $prop);
|
$properties[$prop] = array('name' => $prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$properties[] = array(
|
||||||
|
'name' => 'color',
|
||||||
|
'type' => 'colorpicker',
|
||||||
|
'label' => lang('Color'),
|
||||||
|
);
|
||||||
return $properties;
|
return $properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,22 +34,31 @@ class home_ui
|
|||||||
*/
|
*/
|
||||||
public function index($content = array())
|
public function index($content = array())
|
||||||
{
|
{
|
||||||
// Disabled, for now
|
|
||||||
return;
|
|
||||||
// CSS for Gridster grid layout
|
// CSS for Gridster grid layout
|
||||||
egw_framework::includeCSS('/phpgwapi/js/jquery/gridster/jquery.gridster.css');
|
egw_framework::includeCSS('/phpgwapi/js/jquery/gridster/jquery.gridster.css');
|
||||||
|
|
||||||
$template = new etemplate_new('home.index');
|
$template = new etemplate_new('home.index');
|
||||||
|
|
||||||
|
// Get a list of portlets
|
||||||
$content = array(
|
$content = array(
|
||||||
'portlets' => $this->get_user_portlets($template)
|
'portlets' => $this->get_user_portlets($template)
|
||||||
);
|
);
|
||||||
$template->setElementAttribute('portlets','actions',$this->get_actions());
|
$template->setElementAttribute('home.index','actions',$this->get_actions());
|
||||||
//$template->setElementAttribute('portlets[1]','settings',$settings[1]);
|
//$template->setElementAttribute('portlets[1]','settings',$settings[1]);
|
||||||
|
|
||||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('home');
|
$GLOBALS['egw_info']['flags']['app_header'] = lang('home');
|
||||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'home';
|
$GLOBALS['egw_info']['flags']['currentapp'] = 'home';
|
||||||
|
|
||||||
$template->exec('home.home_ui.index', $content);
|
$template->exec('home.home_ui.index', $content);
|
||||||
|
|
||||||
|
// Now run the portlets themselves
|
||||||
|
foreach($content['portlets'] as $portlet => $p_data)
|
||||||
|
{
|
||||||
|
$id = $p_data['id'];
|
||||||
|
|
||||||
|
if(!$id) continue;
|
||||||
|
$portlet = $this->get_portlet($id, $p_data, $content, $attrs, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,8 +74,8 @@ class home_ui
|
|||||||
foreach($add_portlets as $id => &$add)
|
foreach($add_portlets as $id => &$add)
|
||||||
{
|
{
|
||||||
$add['id'] = 'add_' . $id;
|
$add['id'] = 'add_' . $id;
|
||||||
|
$add['class'] = $id;
|
||||||
}
|
}
|
||||||
error_log(array2string($add_portlets));
|
|
||||||
$actions = array(
|
$actions = array(
|
||||||
'add' => array(
|
'add' => array(
|
||||||
'type' => 'popup',
|
'type' => 'popup',
|
||||||
@@ -78,13 +87,14 @@ class home_ui
|
|||||||
|
|
||||||
// Add all known portlets as drop actions too. If there are multiple matches, there will be a menu
|
// Add all known portlets as drop actions too. If there are multiple matches, there will be a menu
|
||||||
$drop_execute = 'javaScript:app.home.add_from_drop';
|
$drop_execute = 'javaScript:app.home.add_from_drop';
|
||||||
foreach($portlets as $app => $children)
|
foreach($portlets as $app => &$children)
|
||||||
{
|
{
|
||||||
// Home portlets - uses link system, so all apps that support that are accepted
|
// Home portlets - uses link system, so all apps that support that are accepted
|
||||||
if(!$children['children'])
|
if(!$children['children'])
|
||||||
{
|
{
|
||||||
|
$children['class'] = $app;
|
||||||
$children['onExecute'] = $drop_execute;
|
$children['onExecute'] = $drop_execute;
|
||||||
$children['acceptedTypes'] = array_keys(egw_link::app_list());
|
$children['acceptedTypes'] = array('file','link');
|
||||||
$children['type'] = 'drop';
|
$children['type'] = 'drop';
|
||||||
$actions["drop_$app"] = $children;
|
$actions["drop_$app"] = $children;
|
||||||
}
|
}
|
||||||
@@ -111,33 +121,45 @@ class home_ui
|
|||||||
*/
|
*/
|
||||||
protected function get_user_portlets(etemplate_new &$template)
|
protected function get_user_portlets(etemplate_new &$template)
|
||||||
{
|
{
|
||||||
$portlets = array(
|
$portlets = array();
|
||||||
'Just a hard-coded test',
|
|
||||||
);
|
|
||||||
$attributes = array();
|
|
||||||
$attributes[] = array(
|
|
||||||
'title' => 'Has content',
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach((array)$GLOBALS['egw_info']['user']['preferences']['home']['portlets'] as $id => $context)
|
foreach((array)$GLOBALS['egw_info']['user']['preferences']['home']['portlets'] as $id => $context)
|
||||||
{
|
{
|
||||||
error_log("Portlet: $id");
|
|
||||||
error_log(array2string($context));
|
|
||||||
if(!$id || in_array($id, array_keys($GLOBALS['egw_info']['user']['apps']))) continue;
|
if(!$id || in_array($id, array_keys($GLOBALS['egw_info']['user']['apps']))) continue;
|
||||||
$content = '';
|
|
||||||
$attrs = array();
|
$classname = $context['class'];
|
||||||
$this->get_portlet($id, $context, $content, $attrs);
|
$portlet = new $classname($context);
|
||||||
$portlets[$id] = $content;
|
$desc = $portlet->get_description();
|
||||||
$attributes[$id] = $attrs;
|
$portlet_content = array(
|
||||||
|
'id' => $id
|
||||||
|
) + $desc + $context;
|
||||||
|
|
||||||
|
|
||||||
|
// Get settings
|
||||||
|
// Exclude common attributes changed through UI and settings lacking a type
|
||||||
|
$settings = $portlet->get_properties();
|
||||||
|
foreach($settings as $key => $setting)
|
||||||
|
{
|
||||||
|
if(is_array($setting) && !array_key_exists('type',$setting)) unset($settings[$key]);
|
||||||
|
}
|
||||||
|
$settings += $context;
|
||||||
|
foreach(home_portlet::$common_attributes as $attr)
|
||||||
|
{
|
||||||
|
unset($settings[$attr]);
|
||||||
|
}
|
||||||
|
$portlet_content['settings'] = $settings;
|
||||||
|
|
||||||
|
// Set actions
|
||||||
|
// Must be after settings so actions can take settings into account
|
||||||
|
$template->setElementAttribute("portlets[" . count($portlets) . "[$id]", 'actions', $portlet->get_actions());
|
||||||
|
|
||||||
|
$portlets[] = $portlet_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add in legacy HTML home bits
|
// Add in legacy HTML home bits
|
||||||
$this->get_legacy_portlets($template, $portlets, $attributes);
|
// TODO: DOM IDs still collide
|
||||||
|
//$this->get_legacy_portlets($portlets, $attributes);
|
||||||
foreach($portlets as $index => $portlet)
|
|
||||||
{
|
|
||||||
$template->setElementAttribute('portlets', $index, (array)$attributes[$index]);
|
|
||||||
}
|
|
||||||
return $portlets;
|
return $portlets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,18 +170,30 @@ class home_ui
|
|||||||
* These are specific values for the portlet's properties.
|
* These are specific values for the portlet's properties.
|
||||||
* @param content String HTML fragment to be displayed - will be set by the portlet
|
* @param content String HTML fragment to be displayed - will be set by the portlet
|
||||||
* @param attributes Array Settings that can be customized on a per-portlet basis - will be set
|
* @param attributes Array Settings that can be customized on a per-portlet basis - will be set
|
||||||
|
* @param full_exec Boolean If set, the portlet etemplates should use mode 2, if not use mode -1
|
||||||
* @return home_portlet The portlet object that created the content
|
* @return home_portlet The portlet object that created the content
|
||||||
*/
|
*/
|
||||||
protected function get_portlet($id, &$context, &$content, &$attributes)
|
protected function get_portlet($id, &$context, &$content, &$attributes, $full_exec = false)
|
||||||
{
|
{
|
||||||
if(!$context['class']) $context['class'] = 'home_link_portlet';
|
if(!$context['class']) $context['class'] = 'home_link_portlet';
|
||||||
|
|
||||||
|
// This should be set already, but just in case the execution path
|
||||||
|
// is different from normal...
|
||||||
|
if(egw_json_response::isJSONResponse())
|
||||||
|
{
|
||||||
|
$GLOBALS['egw']->framework->response = egw_json_response::get();
|
||||||
|
}
|
||||||
|
|
||||||
$classname = $context['class'];
|
$classname = $context['class'];
|
||||||
$portlet = new $classname($context);
|
$portlet = new $classname($context, $full_exec);
|
||||||
|
|
||||||
$desc = $portlet->get_description();
|
$desc = $portlet->get_description();
|
||||||
$content = $portlet->get_content($id);
|
|
||||||
|
|
||||||
|
// Pre-set up etemplate so it only needs done once
|
||||||
|
$dom_id = 'home-index_'.$id.'_content';
|
||||||
|
|
||||||
|
$etemplate = new etemplate_new();
|
||||||
|
|
||||||
// Exclude common attributes changed through UI and settings lacking a type
|
// Exclude common attributes changed through UI and settings lacking a type
|
||||||
$settings = $portlet->get_properties();
|
$settings = $portlet->get_properties();
|
||||||
foreach($settings as $key => $setting)
|
foreach($settings as $key => $setting)
|
||||||
@@ -174,6 +208,7 @@ class home_ui
|
|||||||
|
|
||||||
$attributes = array(
|
$attributes = array(
|
||||||
'title' => $desc['title'],
|
'title' => $desc['title'],
|
||||||
|
'color' => $settings['color'],
|
||||||
'settings' => $settings,
|
'settings' => $settings,
|
||||||
'actions' => $portlet->get_actions(),
|
'actions' => $portlet->get_actions(),
|
||||||
);
|
);
|
||||||
@@ -186,6 +221,15 @@ class home_ui
|
|||||||
$attributes[$name] = $context[$name];
|
$attributes[$name] = $context[$name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach($attributes as $attr => $value)
|
||||||
|
{
|
||||||
|
$etemplate->setElementAttribute($id, $attr, $value);
|
||||||
|
}
|
||||||
|
if($full_exec)
|
||||||
|
{
|
||||||
|
$content = $portlet->exec($id, $etemplate, $full_exec ? 2 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
return $portlet;
|
return $portlet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +239,7 @@ class home_ui
|
|||||||
* wants some content, we make a portlet for that app using the home_legacy_portlet,
|
* wants some content, we make a portlet for that app using the home_legacy_portlet,
|
||||||
* which fetches content from the home hook.
|
* which fetches content from the home hook.
|
||||||
*/
|
*/
|
||||||
protected function get_legacy_portlets(&$etemplate, &$content, &$attributes)
|
protected function get_legacy_portlets(&$content, &$attributes)
|
||||||
{
|
{
|
||||||
$sorted_apps = array_keys($GLOBALS['egw_info']['user']['apps']);
|
$sorted_apps = array_keys($GLOBALS['egw_info']['user']['apps']);
|
||||||
$portal_oldvarnames = array('mainscreen_showevents', 'homeShowEvents','homeShowLatest','mainscreen_showmail','mainscreen_showbirthdays','mainscreen_show_new_updated', 'homepage_display');
|
$portal_oldvarnames = array('mainscreen_showevents', 'homeShowEvents','homeShowLatest','mainscreen_showmail','mainscreen_showbirthdays','mainscreen_show_new_updated', 'homepage_display');
|
||||||
@@ -253,7 +297,7 @@ class home_ui
|
|||||||
|
|
||||||
foreach($files as $entry)
|
foreach($files as $entry)
|
||||||
{
|
{
|
||||||
if (!in_array($entry, array('.','..')) && substr($entry,-8) == '.inc.php' && strpos($entry,'portlet'))
|
if (!in_array($entry, array('.','..','class.home_legacy_portlet.inc.php')) && substr($entry,-8) == '.inc.php' && strpos($entry,'portlet'))
|
||||||
{
|
{
|
||||||
list(,$classname) = explode('.', $entry);
|
list(,$classname) = explode('.', $entry);
|
||||||
if(class_exists($classname) &&
|
if(class_exists($classname) &&
|
||||||
@@ -323,9 +367,8 @@ class home_ui
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Get portlet settings, and merge new with old
|
// Get portlet settings, and merge new with old
|
||||||
$content = '';
|
|
||||||
$context = $values+(array)$portlets[$portlet_id]; //array('class'=>$attributes['class']);
|
$context = $values+(array)$portlets[$portlet_id]; //array('class'=>$attributes['class']);
|
||||||
|
|
||||||
// Handle add IDs
|
// Handle add IDs
|
||||||
$classname =& $context['class'];
|
$classname =& $context['class'];
|
||||||
if(strpos($classname,'add_') == 0 && !class_exists($classname))
|
if(strpos($classname,'add_') == 0 && !class_exists($classname))
|
||||||
@@ -333,8 +376,8 @@ class home_ui
|
|||||||
$add = true;
|
$add = true;
|
||||||
$classname = substr($classname, 4);
|
$classname = substr($classname, 4);
|
||||||
}
|
}
|
||||||
|
$full_exec = false;
|
||||||
$portlet = $this->get_portlet($portlet_id, $context,$content, $attributes);
|
$portlet = $this->get_portlet($portlet_id, $context, $content, $attributes);
|
||||||
|
|
||||||
$context['class'] = get_class($portlet);
|
$context['class'] = get_class($portlet);
|
||||||
foreach($portlet->get_properties() as $property)
|
foreach($portlet->get_properties() as $property)
|
||||||
@@ -349,17 +392,17 @@ class home_ui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update client side
|
// Update client side
|
||||||
$update = array('content' => $content, 'attributes' => $attributes);
|
$update = array('attributes' => $attributes);
|
||||||
|
|
||||||
// New portlet? Flag going straight to edit mode
|
// New portlet? Flag going straight to edit mode
|
||||||
if($add)
|
if($add)
|
||||||
{
|
{
|
||||||
$update['edit_settings'] = true;
|
$update['edit_settings'] = true;
|
||||||
}
|
}
|
||||||
|
// Send this back to the portlet widget
|
||||||
$response->data($update);
|
$response->data($update);
|
||||||
|
|
||||||
// Store for preference update
|
// Store for preference update
|
||||||
$portlets[$portlet_id] = $context;
|
$portlets[$portlet_id] = $context;
|
||||||
}
|
}
|
||||||
|
233
home/js/app.js
233
home/js/app.js
@@ -37,7 +37,7 @@ app.classes.home = AppJS.extend(
|
|||||||
/**
|
/**
|
||||||
* Grid resolution. Must match et2_portlet GRID
|
* Grid resolution. Must match et2_portlet GRID
|
||||||
*/
|
*/
|
||||||
GRID: 50,
|
GRID: 100,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default size for new portlets
|
* Default size for new portlets
|
||||||
@@ -69,6 +69,13 @@ app.classes.home = AppJS.extend(
|
|||||||
|
|
||||||
// call parent
|
// call parent
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
// Make sure all other sub-etemplates in portlets are done
|
||||||
|
var others = etemplate2.getByApplication(this.appname);
|
||||||
|
for(var i = 0; i < others.length; i++)
|
||||||
|
{
|
||||||
|
others[i].clear();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,31 +83,71 @@ app.classes.home = AppJS.extend(
|
|||||||
* and ready. If you must store a reference to the et2 object,
|
* and ready. If you must store a reference to the et2 object,
|
||||||
* make sure to clean it up in destroy().
|
* make sure to clean it up in destroy().
|
||||||
*
|
*
|
||||||
* @param et2 etemplate2 Newly ready object
|
* @param {etemplate2} et2 Newly ready object
|
||||||
|
* @param {string} Template name
|
||||||
*/
|
*/
|
||||||
et2_ready: function(et2)
|
et2_ready: function(et2, name)
|
||||||
{
|
{
|
||||||
// call parent
|
// Top level
|
||||||
this._super.apply(this, arguments);
|
if(name == 'home.index')
|
||||||
|
|
||||||
this.portlet_container = this.et2.getWidgetById("portlets");
|
|
||||||
|
|
||||||
// Don't do twice
|
|
||||||
if(this.portlet_container._children.length > 0) return;
|
|
||||||
|
|
||||||
// Add portlets
|
|
||||||
var content = this.et2.getArrayMgr("content").getEntry("portlets");
|
|
||||||
var modifications = this.et2.getArrayMgr("modifications").getEntry("portlets");
|
|
||||||
for(var key in content)
|
|
||||||
{
|
{
|
||||||
//var attrs = jQuery.extend({id: key}, content[key], modifications[key]);
|
// call parent
|
||||||
var attrs = {id: key};
|
this._super.apply(this, arguments);
|
||||||
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
|
||||||
}
|
|
||||||
this.et2.loadingFinished();
|
|
||||||
|
|
||||||
// Set up sorting of portlets
|
this.et2.set_id('home.index');
|
||||||
this._do_ordering();
|
this.et2.set_actions(this.et2.getArrayMgr('modifications').getEntry('home.index')['actions']);
|
||||||
|
|
||||||
|
this.portlet_container = this.et2.getWidgetById("portlets");
|
||||||
|
|
||||||
|
// Set up sorting of portlets
|
||||||
|
this._do_ordering();
|
||||||
|
}
|
||||||
|
else if (et2.uniqueId)
|
||||||
|
{
|
||||||
|
// Handle bad timing - a sub-template was finished first
|
||||||
|
if(!this.portlet_container)
|
||||||
|
{
|
||||||
|
window.setTimeout(jQuery.proxy(this, function() {this.et2_ready(et2, name);}),200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var portlet = this.portlet_container.getWidgetById(et2.uniqueId);
|
||||||
|
// Check for existing etemplate, this one loaded over it
|
||||||
|
// NOTE: Moving them around like this can cause problems with event handlers
|
||||||
|
var existing = etemplate2.getById(et2.uniqueId);
|
||||||
|
if(portlet && existing && existing.etemplate_exec_id != et2.etemplate_exec_id)
|
||||||
|
{
|
||||||
|
for(var i = 0; i < portlet._children.length; i++)
|
||||||
|
{
|
||||||
|
portlet._children[i]._inst.clear();
|
||||||
|
}
|
||||||
|
portlet._children = [];
|
||||||
|
}
|
||||||
|
// It's in the right place for original load, but move it into portlet
|
||||||
|
var misplaced = $j(etemplate2.getById('home-index').DOMContainer).siblings('#'+et2.DOMContainer.id);
|
||||||
|
if(portlet)
|
||||||
|
{
|
||||||
|
portlet.addChild(et2.widgetContainer);
|
||||||
|
}
|
||||||
|
if(portlet && misplaced.length)
|
||||||
|
{
|
||||||
|
// etemplate->exec() always adds a new div, so if there's an extra one, move it
|
||||||
|
$j(et2.DOMContainer).remove();
|
||||||
|
et2.DOMContainer = portlet.getDOMNode(et2);
|
||||||
|
et2.DOMContainer.id = et2.uniqueId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set top level actions
|
||||||
|
*
|
||||||
|
* @param {type} action
|
||||||
|
* @param {type} source
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
set_actions: function() {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +159,8 @@ app.classes.home = AppJS.extend(
|
|||||||
var attrs = {id: this._create_id(), row: max_row + 1, col: 1};
|
var attrs = {id: this._create_id(), row: max_row + 1, col: 1};
|
||||||
|
|
||||||
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
||||||
|
// Override content ID so etemplate loads
|
||||||
|
portlet.content.attr('id', attrs.id);
|
||||||
portlet.loadingFinished();
|
portlet.loadingFinished();
|
||||||
|
|
||||||
// Get actual attributes & settings, since they're not available client side yet
|
// Get actual attributes & settings, since they're not available client side yet
|
||||||
@@ -150,6 +199,8 @@ app.classes.home = AppJS.extend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
||||||
|
// Override content ID so etemplate loads
|
||||||
|
portlet.content.attr('id', attrs.id);
|
||||||
portlet.loadingFinished();
|
portlet.loadingFinished();
|
||||||
|
|
||||||
// Get actual attributes & settings, since they're not available client side yet
|
// Get actual attributes & settings, since they're not available client side yet
|
||||||
@@ -158,7 +209,7 @@ app.classes.home = AppJS.extend(
|
|||||||
{
|
{
|
||||||
if(source[i].id) drop_data.push(source[i].id);
|
if(source[i].id) drop_data.push(source[i].id);
|
||||||
}
|
}
|
||||||
portlet._process_edit(et2_dialog.OK_BUTTON, {dropped_data: drop_data, class: action.id.substr(5)});
|
portlet._process_edit(et2_dialog.OK_BUTTON, {dropped_data: drop_data, class: action.data.class || action.id.substr(5)});
|
||||||
|
|
||||||
// Set up sorting/grid of new portlet
|
// Set up sorting/grid of new portlet
|
||||||
$portlet_container.data("gridster").add_widget(
|
$portlet_container.data("gridster").add_widget(
|
||||||
@@ -227,11 +278,11 @@ app.classes.home = AppJS.extend(
|
|||||||
*/
|
*/
|
||||||
serialize_params: function($w, grid) {
|
serialize_params: function($w, grid) {
|
||||||
return {
|
return {
|
||||||
id: $w.attr("id"),
|
id: $w.children('.ui-widget-header').next().attr('id'),
|
||||||
row: grid.row,
|
row: grid.row,
|
||||||
col: grid.col,
|
col: grid.col,
|
||||||
width: grid.width,
|
width: grid.size_x,
|
||||||
height: grid.height
|
height: grid.size_y
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -242,15 +293,18 @@ app.classes.home = AppJS.extend(
|
|||||||
stop: function(event,ui) {
|
stop: function(event,ui) {
|
||||||
// Update widget(s)
|
// Update widget(s)
|
||||||
var changed = this.serialize_changed();
|
var changed = this.serialize_changed();
|
||||||
|
|
||||||
|
// Reset changed, or they keep accumulating
|
||||||
|
this.$changed = $j([]);
|
||||||
|
|
||||||
for (var key in changed)
|
for (var key in changed)
|
||||||
{
|
{
|
||||||
if(!changed[key].id) continue;
|
if(!changed[key].id) continue;
|
||||||
// Changed ID is DOM id
|
// Changed ID is the ID
|
||||||
var widget_id = changed[key].id.substr(window.app.home.et2.getInstanceManager().uniqueId.length + 1);
|
var widget = window.app.home.portlet_container.getWidgetById(changed[key].id);
|
||||||
var widget = window.app.home.portlet_container.getWidgetById(widget_id);
|
|
||||||
if(!widget || widget == window.app.home.portlet_container) continue;
|
if(!widget || widget == window.app.home.portlet_container) continue;
|
||||||
|
|
||||||
egw().jsonq("home.home_ui.ajax_set_properties",[widget.id, widget.options.settings,{
|
egw().jsonq("home.home_ui.ajax_set_properties",[changed[key].id, widget.options.settings,{
|
||||||
row: changed[key].row,
|
row: changed[key].row,
|
||||||
col: changed[key].col
|
col: changed[key].col
|
||||||
}],
|
}],
|
||||||
@@ -263,6 +317,11 @@ app.classes.home = AppJS.extend(
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Bind window resize to re-layout gridster
|
||||||
|
$j(window).one("resize."+this.et2._inst.uniqueId, function() {
|
||||||
|
// Note this doesn't change the positions, just makes them invalid
|
||||||
|
$portlet_container.data('gridster').recalculate_faux_grid();
|
||||||
|
});
|
||||||
// Bind resize to update gridster - this may happen _before_ the widget gets a
|
// Bind resize to update gridster - this may happen _before_ the widget gets a
|
||||||
// chance to update itself, so we can't use the widget
|
// chance to update itself, so we can't use the widget
|
||||||
$portlet_container
|
$portlet_container
|
||||||
@@ -295,48 +354,6 @@ app.classes.home = AppJS.extend(
|
|||||||
*/
|
*/
|
||||||
List:
|
List:
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* List uses mostly JS to generate its content, so we just do it on the JS side by
|
|
||||||
* returning a call to this function as the HTML content.
|
|
||||||
*
|
|
||||||
* @param id String The ID of the portlet
|
|
||||||
* @param list_values Array List of information passed to the link widget
|
|
||||||
*/
|
|
||||||
set_content: function(id, list_values)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
var portlet = app.home.portlet_container.getWidgetById(id);
|
|
||||||
} catch(e) {
|
|
||||||
egw.debug("log", "Tried to set home list content with no etemplate");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
if(portlet != null)
|
|
||||||
{
|
|
||||||
var list = portlet.getWidgetById(id+'-list');
|
|
||||||
if(list)
|
|
||||||
{
|
|
||||||
// List was just rudely pulled from DOM by the call to HTML, put it back
|
|
||||||
portlet.content.append(list.getDOMNode());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create widget
|
|
||||||
list = et2_createWidget('link-list', {id: id+'-list'}, portlet);
|
|
||||||
list.doLoadingFinished();
|
|
||||||
// Abuse link list by overwriting delete handler
|
|
||||||
list._delete_link = app.home.List.delete_link;
|
|
||||||
}
|
|
||||||
list.set_value(list_values);
|
|
||||||
|
|
||||||
// Disable link list context menu
|
|
||||||
$j('tr',list.list).unbind('contextmenu');
|
|
||||||
|
|
||||||
// Allow scroll bars
|
|
||||||
portlet.content.css('overflow', 'auto');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For list_portlet - opens a dialog to add a new entry to the list
|
* For list_portlet - opens a dialog to add a new entry to the list
|
||||||
*/
|
*/
|
||||||
@@ -360,55 +377,79 @@ app.classes.home = AppJS.extend(
|
|||||||
}
|
}
|
||||||
if(target_action == null)
|
if(target_action == null)
|
||||||
{
|
{
|
||||||
var link = et2_createWidget('link-entry', {label: this.egw.lang('Add')}, this.portlet_container);
|
// use template base url from initial template, to continue using webdav, if that was loaded via webdav
|
||||||
var dialog = et2_dialog.show_dialog(
|
var splitted = 'home.edit'.split('.');
|
||||||
function(button_id) {
|
var path = app.home.portlet_container.getRoot()._inst.template_base_url + splitted.shift() + "/templates/default/" +
|
||||||
|
splitted.join('.')+ ".xet";
|
||||||
|
var dialog = et2_createWidget("dialog",{
|
||||||
|
callback: function(button_id, value) {
|
||||||
if(button_id == et2_dialog.CANCEL_BUTTON) return;
|
if(button_id == et2_dialog.CANCEL_BUTTON) return;
|
||||||
var new_list = widget.options.settings.list || [];
|
var new_list = widget.options.settings.list || [];
|
||||||
var add = link.getValue();
|
|
||||||
link.destroy();
|
|
||||||
for(var i = 0; i < new_list.length; i++)
|
for(var i = 0; i < new_list.length; i++)
|
||||||
{
|
{
|
||||||
if(new_list[i].app == add.app && new_list[i].id == add.id)
|
if(new_list[i].app == value.add.app && new_list[i].id == value.add.id)
|
||||||
{
|
{
|
||||||
// Duplicate
|
// Duplicate - skip it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
value.add.link_id = value.add.app + ':' + value.add.id;
|
||||||
new_list.push(add);
|
// Update server side
|
||||||
|
new_list.push(value.add);
|
||||||
widget._process_edit(button_id,{list: new_list});
|
widget._process_edit(button_id,{list: new_list});
|
||||||
|
// Update client side
|
||||||
|
widget.getWidgetById('list').set_value(new_list);
|
||||||
},
|
},
|
||||||
'Add',
|
buttons: et2_dialog.BUTTONS_OK_CANCEL,
|
||||||
this.egw.lang('Add'), {},
|
title: app.home.egw.lang('add'),
|
||||||
et2_dialog.BUTTONS_OK_CANCEL
|
template:path,
|
||||||
);
|
value: { content: [{label: app.home.egw.lang('add'),type: 'link-entry',name: 'add',size:''}]}
|
||||||
dialog.set_message(link.getDOMNode());
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Drag'n'dropped something on the list - just send action IDs
|
// Drag'n'dropped something on the list - just send action IDs
|
||||||
var drop_data = [];
|
var new_list = widget.options.settings.list || [];
|
||||||
|
var changed = false;
|
||||||
|
for(var i = 0; i < new_list.length; i++)
|
||||||
|
{
|
||||||
|
// Avoid duplicates
|
||||||
|
for(var j = 0; j < source.length; j++)
|
||||||
|
{
|
||||||
|
if(!source[j].id || new_list[i].app+"::"+new_list[i].id == source[j].id)
|
||||||
|
{
|
||||||
|
// Duplicate - skip it
|
||||||
|
source.splice(j,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for(var i = 0; i < source.length; i++)
|
for(var i = 0; i < source.length; i++)
|
||||||
{
|
{
|
||||||
if(source[i].id) drop_data.push(source[i].id);
|
var explode = source[i].id.split('::');
|
||||||
|
new_list.push({app: explode[0],id: explode[1], link_id: explode.join(':')});
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
widget.getWidgetById('list').set_value(new_list);
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
widget._process_edit(et2_dialog.OK_BUTTON,{
|
||||||
|
list: new_list || {}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
widget._process_edit(et2_dialog.BUTTONS_OK_CANCEL,{
|
|
||||||
list: widget.options.settings.list || {},
|
|
||||||
dropped_data: drop_data
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a link from the list
|
* Remove a link from the list
|
||||||
*/
|
*/
|
||||||
delete_link: function(undef, row) {
|
link_change: function(list, link_id, row) {
|
||||||
// Quick response
|
// Quick response client side
|
||||||
row.slideUp(row.remove);
|
row.slideUp(row.remove);
|
||||||
|
|
||||||
// Actual removal
|
// Actual removal
|
||||||
this._parent.options.settings.list.splice(row.index(), 1);
|
var portlet = list._parent._parent;
|
||||||
this._parent._process_edit(et2_dialog.OK_BUTTON,{list: this._parent.options.settings.list || {}});
|
portlet.options.settings.list.splice(row.index(), 1);
|
||||||
|
portlet._process_edit(et2_dialog.OK_BUTTON,{list: portlet.options.settings.list || {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -2,6 +2,12 @@
|
|||||||
* Home CSS
|
* Home CSS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#home-index_home-index {
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
|
#home-index_portlets {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
#portlets {
|
#portlets {
|
||||||
border: 1px solid silver;
|
border: 1px solid silver;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -20,20 +26,10 @@
|
|||||||
.et2_portlet.ui-widget-content > div:last-of-type {
|
.et2_portlet.ui-widget-content > div:last-of-type {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.et2_portlet.ui-widget-content > div:last-of-type > div {
|
||||||
/* Shapeshift
|
height: 100%;
|
||||||
#portlets {
|
background: linear-gradient(to bottom, rgba(255,255,255,.9) 10%,rgba(255,255,255,.75) 90%) /* W3C */
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
.home .et2_portlet {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
#portlets .ss-placeholder-child {
|
|
||||||
background: transparent;
|
|
||||||
border: 1px dashed silver;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Gridster */
|
/* Gridster */
|
||||||
#portlets {
|
#portlets {
|
||||||
@@ -41,7 +37,6 @@
|
|||||||
}
|
}
|
||||||
.home .et2_portlet {
|
.home .et2_portlet {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin: 5px;
|
|
||||||
}
|
}
|
||||||
#portlets .preview-holder {
|
#portlets .preview-holder {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<box id="portlets">
|
<box id="portlets">
|
||||||
|
<!-- Box wrapper needed to get box to auto-repeat -->
|
||||||
|
<box id="${row}"><portlet id="${_cont[id]}" title="${_cont[title]}" color="@color" parent_node="home-index_portlets" settings="@settings" width="@width" height="@height" row="@row" col="@col" value="@content"/></box>
|
||||||
</box>
|
</box>
|
||||||
</row>
|
</row>
|
||||||
</rows>
|
</rows>
|
||||||
|
7
home/templates/default/legacy.xet
Normal file
7
home/templates/default/legacy.xet
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- $Id$ -->
|
||||||
|
<overlay>
|
||||||
|
<template id="home.list" template="" lang="" group="0" version="1.9.001">
|
||||||
|
<html id="legacy"/>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
6
home/templates/default/link.xet
Normal file
6
home/templates/default/link.xet
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<overlay>
|
||||||
|
<template id="home.link" template="" lang="" group="0" version="1.9.001">
|
||||||
|
<link id="entry"/>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
7
home/templates/default/list.xet
Normal file
7
home/templates/default/list.xet
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- $Id$ -->
|
||||||
|
<overlay>
|
||||||
|
<template id="home.list" template="" lang="" group="0" version="1.9.001">
|
||||||
|
<link-list id="list" onchange="app.home.List.link_change"/>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
@@ -1,3 +1,4 @@
|
|||||||
|
@import "../default/app.css";
|
||||||
/**
|
/**
|
||||||
* EGroupware: CSS with less preprocessor
|
* EGroupware: CSS with less preprocessor
|
||||||
*
|
*
|
||||||
@@ -9,7 +10,3 @@
|
|||||||
* @package home
|
* @package home
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
#divMain img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
@@ -13,12 +13,4 @@
|
|||||||
@import (reference) "../../../pixelegg/less/def_buttons.less";
|
@import (reference) "../../../pixelegg/less/def_buttons.less";
|
||||||
@import (reference) "../../../pixelegg/less/def_design_pattern_color_font_shadow.less";
|
@import (reference) "../../../pixelegg/less/def_design_pattern_color_font_shadow.less";
|
||||||
|
|
||||||
|
@import (reference) "../default/app.css";
|
||||||
// Dialog: Kalender Ressourcen
|
|
||||||
|
|
||||||
#divMain {
|
|
||||||
|
|
||||||
img {width: 16px; height: 16px;}
|
|
||||||
|
|
||||||
}
|
|
||||||
//
|
|
@@ -1165,8 +1165,6 @@ abstract class egw_framework
|
|||||||
$apps = array();
|
$apps = array();
|
||||||
foreach($GLOBALS['egw_info']['user']['apps'] as $app => $data)
|
foreach($GLOBALS['egw_info']['user']['apps'] as $app => $data)
|
||||||
{
|
{
|
||||||
// disable home until we get it working again
|
|
||||||
if ($app == 'home') continue;
|
|
||||||
if (is_long($app))
|
if (is_long($app))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user