mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-13 09:28:31 +01:00
- Use a queue to buffer property updates
- Better support for dropping application entries on Home portlet area - Add a portlet that shows a list of entries, supports dropping into the list
This commit is contained in:
parent
fdfae8dd92
commit
5fea4ed9a5
@ -66,11 +66,11 @@ class home_link_portlet extends home_portlet
|
|||||||
/**
|
/**
|
||||||
* Get a fragment of HTML for display
|
* Get a fragment of HTML for display
|
||||||
*
|
*
|
||||||
* @param content Array Values returned from a submit, if any
|
* @param id String unique ID, provided to the portlet so it can make sure content is
|
||||||
* @param context Settings for customizing the portlet
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
* @return string HTML fragment for display
|
||||||
*/
|
*/
|
||||||
public function get_content()
|
public function get_content($id = null)
|
||||||
{
|
{
|
||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
@ -124,6 +124,7 @@ class home_link_portlet extends home_portlet
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
$actions['view']['enabled'] = (bool)$this->context['entry'];
|
$actions['view']['enabled'] = (bool)$this->context['entry'];
|
||||||
|
|
||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
178
home/inc/class.home_list_portlet.inc.php
Normal file
178
home/inc/class.home_list_portlet.inc.php
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware - Home - A simple portlet for displaying a list of entries
|
||||||
|
*
|
||||||
|
* @link www.egroupware.org
|
||||||
|
* @author Nathan Gray
|
||||||
|
* @copyright (c) 2013 by Nathan Gray
|
||||||
|
* @package home
|
||||||
|
* @subpackage portlet
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The home_list_portlet uses the link system and its associated link-list widget
|
||||||
|
* to display a list of entries. This is a simple static list that the user can manually
|
||||||
|
* add to and remove from.
|
||||||
|
*
|
||||||
|
* Any application that supports the link system should be able to be added into the list.
|
||||||
|
*/
|
||||||
|
class home_list_portlet extends home_portlet
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context for this portlet
|
||||||
|
*/
|
||||||
|
protected $context = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title of entry
|
||||||
|
*/
|
||||||
|
protected $title = 'List';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the portlet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct(Array &$context = array())
|
||||||
|
{
|
||||||
|
if(!is_array($context['list'])) $context['list'] = array();
|
||||||
|
|
||||||
|
// Process dropped data (Should be GUIDs) into something useable
|
||||||
|
if($context['dropped_data'])
|
||||||
|
{
|
||||||
|
foreach((Array)$context['dropped_data'] as $dropped)
|
||||||
|
{
|
||||||
|
$add = array();
|
||||||
|
list($add['app'], $add['id']) = explode('::', $dropped, 2);
|
||||||
|
if($add['app'] && $add['id'])
|
||||||
|
{
|
||||||
|
$context['list'][] = $add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($add);
|
||||||
|
unset($context['dropped_data']);
|
||||||
|
}
|
||||||
|
if($context['title'])
|
||||||
|
{
|
||||||
|
$this->title = $context['title'];
|
||||||
|
}
|
||||||
|
// Add a new entry to the list
|
||||||
|
if($context['add'])
|
||||||
|
{
|
||||||
|
$context['list'][] = $context['add'];
|
||||||
|
unset($context['add']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->context = $context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some descriptive information about the portlet, so that users can decide if
|
||||||
|
* they want it or not, and for inclusion in lists, hover text, etc.
|
||||||
|
*
|
||||||
|
* These should be already translated, no further translation will be done.
|
||||||
|
*
|
||||||
|
* @return Array with keys
|
||||||
|
* - displayName: Used in lists
|
||||||
|
* - title: Put in the portlet header
|
||||||
|
* - description: A short description of what this portlet does or displays
|
||||||
|
*/
|
||||||
|
public function get_description()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'displayName'=> 'List of entries',
|
||||||
|
'title'=> $this->title,
|
||||||
|
'description'=> lang('Show a list of entries')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a fragment of HTML for display
|
||||||
|
*
|
||||||
|
* @param id String unique ID, provided to the portlet so it can make sure content is
|
||||||
|
* unique, if needed.
|
||||||
|
* @return string HTML fragment for display
|
||||||
|
*/
|
||||||
|
public function get_content($id = null)
|
||||||
|
{
|
||||||
|
$list = array();
|
||||||
|
foreach($this->context['list'] as $link_id => $link)
|
||||||
|
{
|
||||||
|
$list[] = $link + 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
|
||||||
|
return "<script>app.home.List.set_content('$id', ".json_encode($list).")</script>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of settings to customize the portlet.
|
||||||
|
*
|
||||||
|
* Settings should be in the same style as for preferences. It is OK to return an empty array
|
||||||
|
* for no customizable settings.
|
||||||
|
*
|
||||||
|
* These should be already translated, no further translation will be done.
|
||||||
|
*
|
||||||
|
* @see preferences/inc/class.preferences_settings.inc.php
|
||||||
|
* @return Array of settings. Each setting should have the following keys:
|
||||||
|
* - name: Internal reference
|
||||||
|
* - type: Widget type for editing
|
||||||
|
* - label: Human name
|
||||||
|
* - help: Description of the setting, and what it does
|
||||||
|
* - default: Default value, for when it's not set yet
|
||||||
|
*/
|
||||||
|
public function get_properties()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'name' => 'title',
|
||||||
|
'type' => 'textbox',
|
||||||
|
'label' => lang('Title'),
|
||||||
|
),
|
||||||
|
// Internal
|
||||||
|
array(
|
||||||
|
'name' => 'list'
|
||||||
|
)
|
||||||
|
) + parent::get_properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of allowable actions for the portlet.
|
||||||
|
*
|
||||||
|
* These actions will be merged with the default porlet actions.
|
||||||
|
* We add an 'edit' action as default so double-clicking the widget
|
||||||
|
* opens the entry
|
||||||
|
*/
|
||||||
|
public function get_actions()
|
||||||
|
{
|
||||||
|
$actions = array(
|
||||||
|
'add' => array(
|
||||||
|
'icon' => 'add',
|
||||||
|
'caption' => lang('add'),
|
||||||
|
'hideOnDisabled' => false,
|
||||||
|
'onExecute' => 'javaScript:app.home.add_link',
|
||||||
|
),
|
||||||
|
'add_drop' => array(
|
||||||
|
'type' => 'drop',
|
||||||
|
'caption' => lang('add'),
|
||||||
|
'onExecute' => 'javaScript:app.home.add_link',
|
||||||
|
'acceptedTypes' => array('file') + array_keys($GLOBALS['egw_info']['apps']),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List portlet displays multiple entries, so it makes sense to accept multiple dropped entries
|
||||||
|
*/
|
||||||
|
public function accept_multiple()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -49,11 +49,11 @@ abstract class home_portlet
|
|||||||
/**
|
/**
|
||||||
* Get a fragment of HTML for display
|
* Get a fragment of HTML for display
|
||||||
*
|
*
|
||||||
* @param content Array Values returned from a submit, if any
|
* @param id String unique ID, provided to the portlet so it can make sure content is
|
||||||
* @param context Settings for customizing the portlet
|
* unique, if needed.
|
||||||
* @return string HTML fragment for display
|
* @return string HTML fragment for display
|
||||||
*/
|
*/
|
||||||
public abstract function get_content();
|
public abstract function get_content($id = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of settings to customize the portlet.
|
* Return a list of settings to customize the portlet.
|
||||||
@ -71,7 +71,8 @@ abstract class home_portlet
|
|||||||
* - help: Description of the setting, and what it does
|
* - help: Description of the setting, and what it does
|
||||||
* - default: Default value, for when it's not set yet
|
* - default: Default value, for when it's not set yet
|
||||||
*/
|
*/
|
||||||
public function get_properties() {
|
public function get_properties()
|
||||||
|
{
|
||||||
// Include the common attributes, or they won't get saved
|
// Include the common attributes, or they won't get saved
|
||||||
$properties = array();
|
$properties = array();
|
||||||
foreach(self::$common_attributes as $prop)
|
foreach(self::$common_attributes as $prop)
|
||||||
@ -84,8 +85,18 @@ abstract class home_portlet
|
|||||||
/**
|
/**
|
||||||
* Return a list of allowable actions for the portlet.
|
* Return a list of allowable actions for the portlet.
|
||||||
*
|
*
|
||||||
* These actions will be merged with the default porlet actions. Use the
|
* These actions will be merged with the default portlet actions. Use the
|
||||||
* same id / key to override the default action.
|
* same id / key to override the default action.
|
||||||
*/
|
*/
|
||||||
public abstract function get_actions();
|
public abstract function get_actions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this portlet can accept, display, or otherwise handle multiple
|
||||||
|
* EgroupWare entries. Used for drag and drop processing. How the entries
|
||||||
|
* are handled are up to the portlet.
|
||||||
|
*/
|
||||||
|
public function accept_multiple()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,31 +65,29 @@ class home_ui
|
|||||||
'caption' => 'Add',
|
'caption' => 'Add',
|
||||||
'onExecute' => 'javaScript:app.home.add',
|
'onExecute' => 'javaScript:app.home.add',
|
||||||
'children' => $portlets
|
'children' => $portlets
|
||||||
),
|
|
||||||
'drop_create' => array(
|
|
||||||
'caption' => 'Add',
|
|
||||||
'type' => 'drop',
|
|
||||||
'acceptedTypes' => array('file') + array_keys($GLOBALS['egw_info']['apps']),
|
|
||||||
'onExecute' => 'javaScript:app.home.add_from_drop',
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 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';
|
||||||
foreach($portlets as $app => $children)
|
foreach($portlets as $app => $children)
|
||||||
{
|
{
|
||||||
// Home portlets
|
// Home portlets - uses link system, so all apps that support that are accepted
|
||||||
if(!$children['children'])
|
if(!$children['children'])
|
||||||
{
|
{
|
||||||
$children['onExecute'] = $actions['drop_create']['onExecute'];
|
$children['onExecute'] = $drop_execute;
|
||||||
$children['acceptedTypes'] = egw_link::app_list();
|
$children['acceptedTypes'] = array_keys(egw_link::app_list());
|
||||||
$actions[$app] = $children;
|
$children['type'] = 'drop';
|
||||||
|
$actions["drop_$app"] = $children;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach($children as $portlet => $app_portlets)
|
foreach($children as $portlet => $app_portlets)
|
||||||
{
|
{
|
||||||
$app_portlets['onExecute'] = $actions['drop_create']['onExecute'];
|
$app_portlets['onExecute'] = $drop_execute;
|
||||||
$app_portlet['acceptedTypes'] = $app;
|
$app_portlet['acceptedTypes'] = $app;
|
||||||
$actions[$portlet] = $app_portlets;
|
$app_portlet['type'] = 'drop';
|
||||||
|
$actions["drop_$portlet"] = $app_portlets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,7 +115,7 @@ class home_ui
|
|||||||
{
|
{
|
||||||
$content = '';
|
$content = '';
|
||||||
$attrs = array();
|
$attrs = array();
|
||||||
$this->get_portlet($context, $content, $attrs);
|
$this->get_portlet($id, $context, $content, $attrs);
|
||||||
$portlets[$id] = $content;
|
$portlets[$id] = $content;
|
||||||
$attributes[$id] = $attrs;
|
$attributes[$id] = $attrs;
|
||||||
|
|
||||||
@ -138,7 +136,7 @@ class home_ui
|
|||||||
* @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
|
||||||
* @return home_portlet The portlet object that created the content
|
* @return home_portlet The portlet object that created the content
|
||||||
*/
|
*/
|
||||||
protected function get_portlet(&$context, &$content, &$attributes)
|
protected function get_portlet($id, &$context, &$content, &$attributes)
|
||||||
{
|
{
|
||||||
if(!$context['class']) $context['class'] = 'home_link_portlet';
|
if(!$context['class']) $context['class'] = 'home_link_portlet';
|
||||||
|
|
||||||
@ -146,14 +144,20 @@ class home_ui
|
|||||||
$portlet = new $classname($context);
|
$portlet = new $classname($context);
|
||||||
|
|
||||||
$desc = $portlet->get_description();
|
$desc = $portlet->get_description();
|
||||||
$content = $portlet->get_content();
|
$content = $portlet->get_content($id);
|
||||||
|
|
||||||
// Exclude common attributes changed through UI
|
// Exclude common attributes changed through UI and settings lacking a type
|
||||||
$settings = $portlet->get_properties() + $context;
|
$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)
|
foreach(home_portlet::$common_attributes as $attr)
|
||||||
{
|
{
|
||||||
unset($settings[$attr]);
|
unset($settings[$attr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$attributes = array(
|
$attributes = array(
|
||||||
'title' => $desc['title'],
|
'title' => $desc['title'],
|
||||||
'settings' => $settings,
|
'settings' => $settings,
|
||||||
@ -223,7 +227,8 @@ class home_ui
|
|||||||
'id' => $portlet,
|
'id' => $portlet,
|
||||||
'caption' => $desc['displayName'],
|
'caption' => $desc['displayName'],
|
||||||
'hint' => $desc['description'],
|
'hint' => $desc['description'],
|
||||||
'onExecute' => 'javaScript:app.home.add'
|
'onExecute' => 'javaScript:app.home.add',
|
||||||
|
'allowOnMultiple' => $instance->accept_multiple()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,12 +264,12 @@ class home_ui
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_log(array2string($attributes));
|
|
||||||
error_log(array2string($values));
|
|
||||||
// Get portlet settings, and merge new with old
|
// Get portlet settings, and merge new with old
|
||||||
$content = '';
|
$content = '';
|
||||||
$portlet = $this->get_portlet(array_merge((array)$attributes, $values), $content, $attributes);
|
$context = $values+(array)$portlets[$portlet_id]; //array('class'=>$attributes['class']);
|
||||||
$context = array('class' => get_class($portlet));
|
$portlet = $this->get_portlet($portlet_id, $context,$content, $attributes);
|
||||||
|
|
||||||
|
$context['class'] = get_class($portlet);
|
||||||
foreach($portlet->get_properties() as $property)
|
foreach($portlet->get_properties() as $property)
|
||||||
{
|
{
|
||||||
if($values[$property['name']])
|
if($values[$property['name']])
|
||||||
@ -277,14 +282,12 @@ error_log(array2string($values));
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update client side
|
// Update client side
|
||||||
$update = array('content' => $content, 'attributes' => $attributes);
|
$update = array('content' => $content, 'attributes' => $attributes);
|
||||||
|
|
||||||
// New portlet? Flag going straight to edit mode
|
// New portlet? Flag going straight to edit mode
|
||||||
if(!array_key_exists($portlet_id,$portlets) && $attributes['settings'])
|
//$update['edit_settings'] = true;
|
||||||
{
|
|
||||||
$update['edit_settings'] = true;
|
|
||||||
}
|
|
||||||
$response->data($update);
|
$response->data($update);
|
||||||
|
|
||||||
// Store for preference update
|
// Store for preference update
|
||||||
|
182
home/js/app.js
182
home/js/app.js
@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* EGroupware - Filemanager - Javascript UI
|
* EGroupware - Home - Javascript UI
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @package filemanager
|
* @package home
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Nathan Gray
|
||||||
* @copyright (c) 2008-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2013 Nathan Gray
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
@ -14,7 +14,6 @@
|
|||||||
/*egw:uses
|
/*egw:uses
|
||||||
jquery.jquery;
|
jquery.jquery;
|
||||||
jquery.jquery-ui;
|
jquery.jquery-ui;
|
||||||
/phpgwapi/js/jquery/shapeshift/core/jquery.shapeshift.js;
|
|
||||||
/phpgwapi/js/jquery/gridster/jquery.gridster.js;
|
/phpgwapi/js/jquery/gridster/jquery.gridster.js;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -25,7 +24,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Uses Gridster for the grid layout
|
* Uses Gridster for the grid layout
|
||||||
* @see https://github.com/dustmoo/gridster.js
|
* @see http://gridster.net
|
||||||
* @augments AppJS
|
* @augments AppJS
|
||||||
*/
|
*/
|
||||||
app.home = AppJS.extend(
|
app.home = AppJS.extend(
|
||||||
@ -35,6 +34,19 @@ app.home = AppJS.extend(
|
|||||||
*/
|
*/
|
||||||
appname: "home",
|
appname: "home",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grid resolution. Must match et2_portlet GRID
|
||||||
|
*/
|
||||||
|
GRID: 50,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default size for new portlets
|
||||||
|
*/
|
||||||
|
DEFAULT: {
|
||||||
|
WIDTH: 2,
|
||||||
|
HEIGHT: 1
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -93,12 +105,12 @@ app.home = AppJS.extend(
|
|||||||
* Add a new portlet from the context menu
|
* Add a new portlet from the context menu
|
||||||
*/
|
*/
|
||||||
add: function(action) {
|
add: function(action) {
|
||||||
var attrs = {id: this._create_id(), class: action.id};
|
var attrs = {id: this._create_id()};
|
||||||
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
||||||
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
|
||||||
portlet._process_edit(et2_dialog.OK_BUTTON, {});
|
portlet._process_edit(et2_dialog.OK_BUTTON, {class: action.id});
|
||||||
|
|
||||||
// Set up sorting/grid of new portlet
|
// Set up sorting/grid of new portlet
|
||||||
var $portlet_container = $j(this.portlet_container.getDOMNode());
|
var $portlet_container = $j(this.portlet_container.getDOMNode());
|
||||||
@ -111,7 +123,25 @@ app.home = AppJS.extend(
|
|||||||
* User dropped something on home. Add a new portlet
|
* User dropped something on home. Add a new portlet
|
||||||
*/
|
*/
|
||||||
add_from_drop: function(action,source,target_action) {
|
add_from_drop: function(action,source,target_action) {
|
||||||
var attrs = {id: this._create_id(), class: action.id};
|
|
||||||
|
// Actions got confused drop vs popup
|
||||||
|
if(source[0].id == 'portlets')
|
||||||
|
{
|
||||||
|
return this.add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
var $portlet_container = $j(this.portlet_container.getDOMNode());
|
||||||
|
|
||||||
|
// Basic portlet attributes
|
||||||
|
var attrs = {id: this._create_id()};
|
||||||
|
|
||||||
|
// Try to find where the drop was
|
||||||
|
if(action != null && action.ui && action.ui.position)
|
||||||
|
{
|
||||||
|
attrs.row = Math.round((action.ui.offset.top - $portlet_container.offset().top )/ this.GRID);
|
||||||
|
attrs.col = Math.max(0,Math.round((action.ui.offset.left - $portlet_container.offset().left) / this.GRID)-1);
|
||||||
|
}
|
||||||
|
|
||||||
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
var portlet = et2_createWidget('portlet',attrs, this.portlet_container);
|
||||||
portlet.loadingFinished();
|
portlet.loadingFinished();
|
||||||
|
|
||||||
@ -121,14 +151,14 @@ app.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});
|
portlet._process_edit(et2_dialog.OK_BUTTON, {dropped_data: drop_data, class: action.id.substr(5)});
|
||||||
|
|
||||||
// Set up sorting/grid of new portlet
|
// Set up sorting/grid of new portlet
|
||||||
var $portlet_container = $j(this.portlet_container.getDOMNode());
|
|
||||||
$portlet_container.data("gridster").add_widget(
|
$portlet_container.data("gridster").add_widget(
|
||||||
portlet.getDOMNode()
|
portlet.getDOMNode(),
|
||||||
|
this.DEFAULT.WIDTH, this.DEFAULT.HEIGHT,
|
||||||
|
attrs.col, attrs.row
|
||||||
);
|
);
|
||||||
console.log(this,arguments);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,6 +186,14 @@ app.home = AppJS.extend(
|
|||||||
egw().open(widget.options.settings.entry, "", 'edit');
|
egw().open(widget.options.settings.entry, "", 'edit');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For list_portlet - adds a new link
|
||||||
|
* This is needed here so action system can find it
|
||||||
|
*/
|
||||||
|
add_link: function(action,source,target_action) {
|
||||||
|
this.List.add_link(action, source, target_action);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the drag / drop / re-order of portlets
|
* Set up the drag / drop / re-order of portlets
|
||||||
*/
|
*/
|
||||||
@ -164,13 +202,11 @@ app.home = AppJS.extend(
|
|||||||
$portlet_container
|
$portlet_container
|
||||||
.addClass("home ui-helper-clearfix")
|
.addClass("home ui-helper-clearfix")
|
||||||
.disableSelection()
|
.disableSelection()
|
||||||
/* Shapeshift
|
|
||||||
.shapeshift();
|
|
||||||
*/
|
|
||||||
/* Gridster */
|
/* Gridster */
|
||||||
.gridster({
|
.gridster({
|
||||||
widget_selector: 'div.et2_portlet',
|
widget_selector: 'div.et2_portlet',
|
||||||
widget_base_dimensions: [45, 45],
|
// Dimensions + margins = grid spacing
|
||||||
|
widget_base_dimensions: [this.GRID-5, this.GRID-5],
|
||||||
widget_margins: [5,5],
|
widget_margins: [5,5],
|
||||||
extra_rows: 1,
|
extra_rows: 1,
|
||||||
extra_cols: 1,
|
extra_cols: 1,
|
||||||
@ -205,13 +241,13 @@ app.home = AppJS.extend(
|
|||||||
var widget = window.app.home.portlet_container.getWidgetById(changed[key].id);
|
var widget = window.app.home.portlet_container.getWidgetById(changed[key].id);
|
||||||
if(!widget || widget == window.app.home.portlet_container) continue;
|
if(!widget || widget == window.app.home.portlet_container) continue;
|
||||||
|
|
||||||
egw().json("home.home_ui.ajax_set_properties",[widget.id, widget.options.settings,{
|
egw().jsonq("home.home_ui.ajax_set_properties",[widget.id, widget.options.settings,{
|
||||||
row: changed[key].row,
|
row: changed[key].row,
|
||||||
col: changed[key].col
|
col: changed[key].col
|
||||||
}],
|
}],
|
||||||
null,
|
null,
|
||||||
widget, true, widget
|
widget, true, widget
|
||||||
).sendRequest();
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,8 +260,8 @@ app.home = AppJS.extend(
|
|||||||
.on("resizestop", function(event, ui) {
|
.on("resizestop", function(event, ui) {
|
||||||
$portlet_container.data("gridster").resize_widget(
|
$portlet_container.data("gridster").resize_widget(
|
||||||
ui.element,
|
ui.element,
|
||||||
Math.round(ui.size.width / 50),
|
Math.round(ui.size.width / this.GRID),
|
||||||
Math.round(ui.size.height / 50)
|
Math.round(ui.size.height / this.GRID)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -243,5 +279,109 @@ app.home = AppJS.extend(
|
|||||||
}
|
}
|
||||||
while(this.portlet_container.getWidgetById(id));
|
while(this.portlet_container.getWidgetById(id));
|
||||||
return id;
|
return id;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions for the list portlet
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var portlet = app.home.portlet_container.getWidgetById(id);
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
add_link: function(action, source, target_action) {
|
||||||
|
// Actions got confused drop vs popup
|
||||||
|
if(source[0].id == 'portlets')
|
||||||
|
{
|
||||||
|
return this.add_link(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get widget
|
||||||
|
var widget = null;
|
||||||
|
while(action.parent != null)
|
||||||
|
{
|
||||||
|
if(action.data && action.data.widget)
|
||||||
|
{
|
||||||
|
widget = action.data.widget;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
action = action.parent;
|
||||||
|
}
|
||||||
|
if(typeof source == undefined)
|
||||||
|
{
|
||||||
|
var link = et2_createWidget('link-entry', {label: egw.lang('Add')}, this.portlet_container);
|
||||||
|
var dialog = et2_dialog.show_dialog(
|
||||||
|
function(button_id) {
|
||||||
|
widget._process_edit(button_id,{list: widget.options.settings.list || {}, add: link.getValue()});
|
||||||
|
link.destroy();
|
||||||
|
},
|
||||||
|
'Add',
|
||||||
|
egw.lang('Add'), {},
|
||||||
|
et2_dialog.BUTTONS_OK_CANCEL
|
||||||
|
);
|
||||||
|
dialog.set_message(link.getDOMNode());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Drag'n'dropped something on the list - just send action IDs
|
||||||
|
var drop_data = [];
|
||||||
|
for(var i = 0; i < source.length; i++)
|
||||||
|
{
|
||||||
|
if(source[i].id) drop_data.push(source[i].id);
|
||||||
|
}
|
||||||
|
widget._process_edit(et2_dialog.BUTTONS_OK_CANCEL,{
|
||||||
|
list: widget.options.settings.list || {},
|
||||||
|
dropped_data: drop_data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a link from the list
|
||||||
|
*/
|
||||||
|
delete_link: function(undef, row) {
|
||||||
|
// Quick response
|
||||||
|
row.slideUp(row.remove);
|
||||||
|
// Actual removal
|
||||||
|
this._parent.options.settings.list.splice(row.index(), 1);
|
||||||
|
this._parent._process_edit(et2_dialog.OK_BUTTON,{list: this._parent.options.settings.list || {}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
.et2_portlet.ui-widget-content {
|
.et2_portlet.ui-widget-content {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.et2_portlet.ui-widget-content > div:last-of-type {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Shapeshift
|
/* Shapeshift
|
||||||
#portlets {
|
#portlets {
|
||||||
|
Loading…
Reference in New Issue
Block a user