mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 07:53:39 +01:00
Home progress:
- Fix some incorrect sizes on new portlets - Fix mainscreen message - Base for using other app favorites on home screen
This commit is contained in:
parent
af1bf822a9
commit
872a11bfdb
@ -132,6 +132,8 @@ var et2_portlet = et2_valueWidget.extend(
|
||||
null,
|
||||
self, true, self
|
||||
);
|
||||
// Tell children
|
||||
self.iterateOver(function(widget) {widget.resize();},null,et2_IResizeable);
|
||||
}
|
||||
});
|
||||
this.header = $j(document.createElement("div"))
|
||||
@ -288,6 +290,13 @@ var et2_portlet = et2_valueWidget.extend(
|
||||
{
|
||||
this.edit_settings();
|
||||
}
|
||||
|
||||
// Only resize once, and only if needed
|
||||
if(data.attributes.width || data.attributes.height)
|
||||
{
|
||||
// Tell children
|
||||
this.iterateOver(function(widget) {widget.resize();},null,et2_IResizeable);
|
||||
}
|
||||
},
|
||||
this, true, this
|
||||
);
|
||||
@ -350,6 +359,8 @@ var et2_portlet = et2_valueWidget.extend(
|
||||
{
|
||||
this.options.width = value;
|
||||
this.div.attr("data-sizex", value);
|
||||
// Clear what's there from jQuery, we get width from CSS according to sizex
|
||||
this.div.css('width','');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -361,6 +372,8 @@ var et2_portlet = et2_valueWidget.extend(
|
||||
{
|
||||
this.options.height = value;
|
||||
this.div.attr("data-sizey", value);
|
||||
// Clear what's there from jQuery, we get width from CSS according to sizey
|
||||
this.div.css('height','');
|
||||
}
|
||||
|
||||
});
|
||||
|
181
home/inc/class.home_favorite_portlet.inc.php
Normal file
181
home/inc/class.home_favorite_portlet.inc.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?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: class.home_list_portlet.inc.php 49321 2014-11-06 21:40:03Z nathangray $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The home_favorite_portlet extends the list portlet to display the entries for a particular
|
||||
* favorite, for a given app.
|
||||
*/
|
||||
class home_favorite_portlet extends home_portlet
|
||||
{
|
||||
|
||||
/**
|
||||
* Context for this portlet - the application and favorite name
|
||||
*/
|
||||
protected $context = array(
|
||||
'appname' => '',
|
||||
'favorite' => 'blank'
|
||||
);
|
||||
|
||||
/**
|
||||
* Nextmatch settings
|
||||
* @see etemplate_widget_nextmatch
|
||||
* @var array
|
||||
*/
|
||||
protected $nm_settings = array(
|
||||
'no_filter' => true,
|
||||
'no_filter2' => true,
|
||||
'no_cat' => true,
|
||||
'no_search' => true,
|
||||
'lettersearch' => false,
|
||||
'favorites' => false, // Hide favorite control
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor sets up the portlet according to the user's saved property values
|
||||
* for this particular portlet. It is possible to have multiple instances of the
|
||||
* same portlet with different properties.
|
||||
*
|
||||
* The implementing class is allowed to modify the context, if needed, but it is
|
||||
* better to use get_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 function __construct(Array &$context = array(), &$need_reload = false)
|
||||
{
|
||||
// Process dropped data (Should be [appname => <appname>, id => <favorite ID>]) into something useable
|
||||
if($context['dropped_data'])
|
||||
{
|
||||
foreach((Array)$context['dropped_data'] as $dropped)
|
||||
{
|
||||
// Only handle one, but dropped is an array
|
||||
$context['appname'] = $dropped['appname'];
|
||||
$context['favorite'] = $dropped['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
unset($context['dropped_data']);
|
||||
|
||||
$need_reload = true;
|
||||
}
|
||||
// Title not set for new widgets created via context menu
|
||||
if(!$context['title'])
|
||||
{
|
||||
// Set initial size to 6x3, default is way too small
|
||||
$context['width'] = 6;
|
||||
$context['height'] = 3;
|
||||
|
||||
$need_reload = true;
|
||||
}
|
||||
$favorites = egw_favorites::get_favorites($context['appname']);
|
||||
$this->favorite = $favorites[$context['favorite']];
|
||||
$this->title = $context['title'] = $context['title'] ? $context['title'] : lang($context['appname']) . ' ' . $this->favorite['name'];
|
||||
$this->context = $context;
|
||||
if($this->favorite)
|
||||
{
|
||||
$this->nm_settings['favorite'] = $this->context['favorite'];
|
||||
$this->nm_settings['columnselection_pref'] = 'nextmatch-home';
|
||||
if(is_array($this->favorite['state']))
|
||||
{
|
||||
$this->nm_settings += $this->favorite['state'];
|
||||
}
|
||||
}
|
||||
}
|
||||
public function exec($id = null, etemplate_new &$etemplate = null)
|
||||
{
|
||||
if($etemplate == null)
|
||||
{
|
||||
$etemplate = new etemplate_new();
|
||||
}
|
||||
$etemplate->read('home.favorite');
|
||||
|
||||
$etemplate->set_dom_id($id);
|
||||
|
||||
$content = $this->context + array('nm' => $this->nm_settings);
|
||||
$etemplate->setElementAttribute('nm', 'template',$this->nm_settings['template']);
|
||||
|
||||
$etemplate->exec(get_called_class() .'::process',$content);
|
||||
}
|
||||
|
||||
public static function process($content = array())
|
||||
{
|
||||
// We need to keep the template going, thanks.
|
||||
etemplate_widget::setElementAttribute('','','');
|
||||
}
|
||||
|
||||
public function get_actions(){
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'=> lang('Favorite'),
|
||||
'title'=> $this->title,
|
||||
'description'=> lang('Show the entries from a favorite')
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$properties = parent::get_properties();
|
||||
$favorites = egw_favorites::get_favorites($this->context['appname']);
|
||||
$favorite_list = array();
|
||||
foreach($favorites as $id => $favorite)
|
||||
{
|
||||
$favorite_list[$id] = $favorite['name'];
|
||||
}
|
||||
$favorite = array(
|
||||
'label' => lang('Favorite'),
|
||||
'name' => 'favorite',
|
||||
'type' => 'select',
|
||||
'select_options' => $favorite_list
|
||||
);
|
||||
if($this->context['favorite'])
|
||||
{
|
||||
$favorite['type'] = 'select_ro';
|
||||
}
|
||||
$properties[] = $favorite;
|
||||
$properties[] = array(
|
||||
'appname' => 'appname'
|
||||
);
|
||||
return $properties;
|
||||
}
|
||||
}
|
@ -48,17 +48,6 @@ class home_ui
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('home');
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'home';
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
// Main screen message
|
||||
translation::add_app('mainscreen');
|
||||
$greeting = translation::translate('mainscreen_message',false,'');
|
||||
@ -72,6 +61,18 @@ class home_ui
|
||||
{
|
||||
$content['mainscreen_message'] = $greeting;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,6 +87,13 @@ class home_ui
|
||||
$add_portlets = $portlets;
|
||||
foreach($add_portlets as $id => &$add)
|
||||
{
|
||||
if(!$add['id'] && is_array($add['children']))
|
||||
{
|
||||
foreach($add['children'] as $sub_id => &$sub_add)
|
||||
{
|
||||
$sub_add['id'] = 'add_'.$sub_id;
|
||||
}
|
||||
}
|
||||
$add['id'] = 'add_' . $id;
|
||||
$add['class'] = $id;
|
||||
}
|
||||
@ -95,7 +103,9 @@ class home_ui
|
||||
'caption' => 'Add',
|
||||
'onExecute' => 'javaScript:app.home.add',
|
||||
'children' => $add_portlets
|
||||
)
|
||||
),
|
||||
// Favorites are sortable which needs special handling,
|
||||
// handled directly through jQuery
|
||||
);
|
||||
|
||||
// Add all known portlets as drop actions too. If there are multiple matches, there will be a menu
|
||||
@ -113,12 +123,15 @@ class home_ui
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($children as $portlet => $app_portlets)
|
||||
foreach($children['children'] as $portlet => $app_portlet)
|
||||
{
|
||||
$app_portlets['onExecute'] = $drop_execute;
|
||||
if(!is_array($app_portlet)) continue;
|
||||
$app_portlet['class'] = $portlet;
|
||||
$app_portlet['id'] = 'drop_' . $app_portlet['id'];
|
||||
$app_portlet['onExecute'] = $drop_execute;
|
||||
$app_portlet['acceptedTypes'] = $app;
|
||||
$app_portlet['type'] = 'drop';
|
||||
$actions["drop_$portlet"] = $app_portlets;
|
||||
$actions["drop_$portlet"] = $app_portlet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,7 +313,13 @@ class home_ui
|
||||
$list = egw_cache::getTree('home', 'portlet_classes', function() {
|
||||
$list = array();
|
||||
$classes = array();
|
||||
|
||||
|
||||
// Ignore some problem files and base classes that shouldn't be options
|
||||
$ignore = array(
|
||||
'.','..',
|
||||
'class.home_legacy_portlet.inc.php',
|
||||
'class.home_favorite_portlet.inc.php'
|
||||
);
|
||||
// Look through all known classes for portlets - for now, they need 'portlet' in the file name
|
||||
foreach($GLOBALS['egw_info']['apps'] as $appname => $app)
|
||||
{
|
||||
@ -310,7 +329,7 @@ class home_ui
|
||||
|
||||
foreach($files as $entry)
|
||||
{
|
||||
if (!in_array($entry, array('.','..','class.home_legacy_portlet.inc.php')) && substr($entry,-8) == '.inc.php' && strpos($entry,'portlet'))
|
||||
if (!in_array($entry, $ignore) && substr($entry,-8) == '.inc.php' && strpos($entry,'portlet'))
|
||||
{
|
||||
list(,$classname) = explode('.', $entry);
|
||||
if(class_exists($classname) &&
|
||||
|
@ -101,6 +101,35 @@ app.classes.home = AppJS.extend(
|
||||
|
||||
// Set up sorting of portlets
|
||||
this._do_ordering();
|
||||
|
||||
// Accept drops of favorites, which aren't part of action system
|
||||
$j(this.et2.getDOMNode()).droppable({
|
||||
hoverClass: 'drop-hover',
|
||||
accept: function(draggable) {
|
||||
// Check for direct support for that application
|
||||
if(draggable[0].dataset && draggable[0].dataset.appname)
|
||||
{
|
||||
return egw_getActionManager('home',false,1).getActionById('drop_'+draggable[0].dataset.appname +'_favorite_portlet') != null;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
drop: function(event, ui) {
|
||||
// Favorite dropped on home - fake an action and divert to normal handler
|
||||
var action = {
|
||||
data: {
|
||||
class: 'add_home_favorite_portlet'
|
||||
}
|
||||
}
|
||||
|
||||
// Check for direct support for that application
|
||||
if(ui.helper.context.dataset && ui.helper.context.dataset.appname)
|
||||
{
|
||||
var action = egw_getActionManager('home',false,1).getActionById('drop_'+ui.helper.context.dataset.appname +'_favorite_portlet') || {}
|
||||
}
|
||||
action.ui = ui;
|
||||
app.home.add_from_drop(action, [{data: ui.helper.context.dataset}])
|
||||
}
|
||||
})
|
||||
}
|
||||
else if (et2.uniqueId)
|
||||
{
|
||||
@ -127,37 +156,24 @@ app.classes.home = AppJS.extend(
|
||||
var misplaced = $j(etemplate2.getById('home-index').DOMContainer).siblings('#'+et2.DOMContainer.id);
|
||||
if(portlet)
|
||||
{
|
||||
portlet.content = $j(et2.DOMContainer).appendTo(portlet.content);
|
||||
portlet.addChild(et2.widgetContainer);
|
||||
et2.resize();
|
||||
}
|
||||
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() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new portlet from the context menu
|
||||
*/
|
||||
add: function(action, source) {
|
||||
// Put it in the last row, first column, since the mouse position is unknown
|
||||
var max_row = Math.max.apply(null,$j('div',this.portlet_container.div).map(function() {return $j(this).attr('data-row');}));
|
||||
|
||||
var attrs = {id: this._create_id(), row: 1, col: 1};
|
||||
|
||||
// Try to put it about where the menu was opened
|
||||
if(action.menu_context)
|
||||
{
|
||||
var $portlet_container = $j(this.portlet_container.getDOMNode());
|
||||
@ -185,7 +201,7 @@ app.classes.home = AppJS.extend(
|
||||
/**
|
||||
* User dropped something on home. Add a new portlet
|
||||
*/
|
||||
add_from_drop: function(action,source,target_action) {
|
||||
add_from_drop: function(action,source) {
|
||||
|
||||
// Actions got confused drop vs popup
|
||||
if(source[0].id == 'portlets')
|
||||
@ -214,7 +230,14 @@ app.classes.home = AppJS.extend(
|
||||
var drop_data = [];
|
||||
for(var i = 0; i < source.length; i++)
|
||||
{
|
||||
if(source[i].id) drop_data.push(source[i].id);
|
||||
if(source[i].id)
|
||||
{
|
||||
drop_data.push(source[i].id);
|
||||
}
|
||||
else
|
||||
{
|
||||
drop_data.push(source[i].data);
|
||||
}
|
||||
}
|
||||
portlet._process_edit(et2_dialog.OK_BUTTON, {dropped_data: drop_data, class: action.data.class || action.id.substr(5)});
|
||||
|
||||
|
@ -24,10 +24,16 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
.et2_portlet.ui-widget-content > div:last-of-type {
|
||||
/* Allow space for header, as the whole portlet is sized by auto-generated css */
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
.et2_portlet .et2_container {
|
||||
height: 100%;
|
||||
}
|
||||
.et2_portlet.ui-widget-content > div:last-of-type > div {
|
||||
height: 100%;
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,.9) 10%,rgba(255,255,255,.75) 90%) /* W3C */
|
||||
}
|
||||
|
||||
@ -38,10 +44,13 @@
|
||||
.home .et2_portlet {
|
||||
position: absolute;
|
||||
}
|
||||
#portlets .preview-holder {
|
||||
.home .et2_portlet.dragging {
|
||||
z-index: 99;
|
||||
}
|
||||
.preview-holder {
|
||||
margin: 5px;
|
||||
list-style: none;
|
||||
background: transparent;
|
||||
border: 1px dashed silver;
|
||||
background: rgba(0,0,0,.3);
|
||||
border: 1px solid silver;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
<rows>
|
||||
<row>
|
||||
<label for="@${row}[name]" value="@${row}[label]"/>
|
||||
<widget type="@${row}[type]" id="@${row}[name]" no_lang="1" options="@${row}[size]"/>
|
||||
<widget type="@${row}[type]" id="@${row}[name]" no_lang="1" select_options="@${row}[select_options]"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
7
home/templates/default/favorite.xet
Normal file
7
home/templates/default/favorite.xet
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="home.favorite" template="" lang="" group="0" version="1.9.001">
|
||||
<nextmatch id="nm"/>
|
||||
</template>
|
||||
</overlay>
|
Loading…
Reference in New Issue
Block a user