Drag & Drop support for [infolog] favorite to Home

This commit is contained in:
Nathan Gray 2014-11-11 23:11:16 +00:00
parent 872a11bfdb
commit 95e343cb27
3 changed files with 271 additions and 3 deletions

View File

@ -0,0 +1,125 @@
<?php
/*
* Egroupware - Infolog - A portlet for displaying a list of portlet entries
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package infolog
* @subpackage home
* @link http://www.egroupware.org
* @author Nathan Gray
* @version $Id$
*/
/**
* The infolog_list_portlet uses a nextmatch / favorite
* to display a list of entries.
*/
class infolog_favorite_portlet extends home_favorite_portlet
{
/**
* Construct the portlet
*
*/
public function __construct(Array &$context = array(), &$need_reload = false)
{
$context['appname'] = 'infolog';
// Let parent handle the basic stuff
parent::__construct($context,$need_reload);
$ui = new infolog_ui();
$this->context['template'] = 'infolog.index.rows';
$this->nm_settings += array(
'get_rows' => 'infolog.infolog_ui.get_rows',
// Use a different template so it can be accessed from client side
'template' => 'infolog.home',
// Don't overwrite infolog
'session_for' => 'home',
// Allow add actions even when there's no rows
'placeholder_actions' => array(),
'sel_options' => array(
'info_type' => $ui->bo->enums['type'],
'pm_id' => array(lang('No project')),
'info_priority' => $ui->bo->enums['priority'],
)
);
}
/**
* Here we need to handle any incoming data. Setup is done in the constructor,
* output is handled by parent.
*
* @param type $id
* @param etemplate_new $etemplate
*/
public static function process($values = array())
{
parent::process($values);
$ui = new infolog_ui();
if (is_array($values) && !empty($values['nm']['multi_action']))
{
if (!count($values['nm']['selected']) && !$values['nm']['select_all'])
{
egw_framework::message(lang('You need to select some entries first'));
}
else
{
// Some processing to add values in for links and cats
$multi_action = $values['nm']['multi_action'];
// Action has an additional action - add / delete, etc. Buttons named <multi-action>_action[action_name]
if(in_array($multi_action, array('link', 'responsible')))
{
// eTemplate ignores the _popup namespace, but et2 doesn't
if($values[$multi_action.'_popup'])
{
$popup =& $values[$multi_action.'_popup'];
}
else
{
$popup =& $values;
}
$values['nm']['multi_action'] .= '_' . key($popup[$multi_action . '_action']);
if($multi_action == 'link')
{
$popup[$multi_action] = $popup['link']['app'] . ':'.$popup['link']['id'];
}
else if(is_array($popup[$multi_action]))
{
$popup[$multi_action] = implode(',',$popup[$multi_action]);
}
$values['nm']['multi_action'] .= '_' . $popup[$multi_action];
unset($values[$multi_action.'_popup']);
unset($values[$multi_action]);
}
$success = $failed = $action_msg = null;
if ($ui->action($values['nm']['multi_action'], $values['nm']['selected'], $values['nm']['select_all'],
$success, $failed, $action_msg, $values['nm'], $msg, $values['nm']['checkboxes']['no_notifications']))
{
$msg .= lang('%1 entries %2',$success,$action_msg);
egw_json_response::get()->apply('egw.message',array($msg,'success'));
foreach($values['nm']['selected'] as &$id)
{
$id = 'infolog::'.$id;
}
// Directly request an update - this will get infolog tab too
egw_json_response::get()->apply('egw.dataRefreshUIDs',array($values['nm']['selected']));
}
elseif(is_null($msg))
{
$msg .= lang('%1 entries %2, %3 failed because of insufficent rights !!!',$success,$action_msg,$failed);
egw_json_response::get()->apply('egw.message',array($msg,'error'));
}
elseif($msg)
{
$msg .= "\n".lang('%1 entries %2, %3 failed.',$success,$action_msg,$failed);
egw_json_response::get()->apply('egw.message',array($msg,'error'));
}
unset($values['nm']['multi_action']);
unset($values['nm']['select_all']);
}
}
}
}

View File

@ -0,0 +1,134 @@
<?xml version="1.0"?>
<!-- $Id: index.xet 48261 2014-08-25 19:56:28Z nathangray $ -->
<overlay>
<template id="infolog.home" template="" lang="" group="0" version="1.9.005">
<grid width="100%">
<columns>
<column width="120"/>
<column width="45%"/>
<column width="15%" disabled="@no_customfields"/>
<column/>
<column width="120"/>
<column/>
<column/>
<column width="120" disabled="@no_info_owner_info_responsible"/>
<column width="120"/>
</columns>
<rows>
<row class="th">
<vbox>
<nextmatch-filterheader id="info_type" no_lang="1" options="Type"/>
<nextmatch-filterheader align="center" id="info_status" options="Status" class="selectboxFullWidth"/>
<nextmatch-sortheader align="right" label="Completed" id="info_percent"/>
</vbox>
<grid width="100%" spacing="0" padding="0">
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<nextmatch-customfilter id="linked" options="link-entry"/>
<nextmatch-sortheader align="right" label="Priority" id="info_priority" options="DESC" class="noPrint"/>
</row>
<row>
<nextmatch-sortheader label="Subject" id="info_subject"/>
<nextmatch-sortheader align="right" label="Creation" id="info_id" options="DESC" class="noPrint"/>
</row>
<row>
<nextmatch-sortheader label="Description" id="info_des"/>
<nextmatch-sortheader align="right" label="last changed" id="info_datemodified" options="DESC" class="noPrint"/>
</row>
</rows>
</grid>
<nextmatch-customfields id="customfields"/>
<nextmatch-header label="Category" id="cat_id"/>
<vbox>
<nextmatch-sortheader label="Startdate" id="info_startdate" sortmode="DESC"/>
<nextmatch-sortheader label="Enddate" id="info_enddate" sortmode="DESC"/>
<nextmatch-sortheader label="Date completed" id="info_datecompleted" sortmode="DESC"/>
</vbox>
<vbox>
<nextmatch-sortheader label="Times" id="info_used_time"/>
<nextmatch-sortheader label="planned" id="info_planned_time" class="infolog_planned"/>
</vbox>
<vbox>
<nextmatch-sortheader label="Times" id="info_used_time"/>
<nextmatch-sortheader label="planned" id="info_planned_time" class="infolog_planned"/>
<nextmatch-sortheader label="Re-planned" id="info_replanned_time" class="replanned"/>
</vbox>
<vbox>
<nextmatch-accountfilter statustext="Select to filter by owner" id="info_owner" options="Owner,both" class="infolog_user_filter"/>
<nextmatch-accountfilter statustext="Select to filter by responsible" id="info_responsible" options="Responsible,both" class="infolog_user_filter"/>
</vbox>
<nextmatch-sortheader label="last changed" id="info_datemodified" options="DESC"/>
</row>
<row class="$row_cont[info_cat] $row_cont[class]" valign="top">
<hbox align="center">
<image label="$row_cont[info_type]" src="${row}[info_type]" default_src="infolog/navbar"/>
<image label="$row_cont[info_status_label]" id="edit_status[$row_cont[info_id]]" href="javascript:egw.open($row_cont[info_id],'infolog');" src="$row_cont[info_status_label]" default_src="status"/>
<image label="$row_cont[info_percent]" id="edit_percent[$row_cont[info_id]]" href="javascript:egw.open($row_cont[info_id],'infolog');" src="$row_cont[info_percent]"/>
<progress label="$row_cont[info_percent]" id="{$row}[info_percent2]" href="javascript:egw.open($row_cont[info_id],'infolog');"/>
</hbox>
<vbox class="infolog_fullWidth">
<link label="%s $row_cont[info_addr]" id="${row}[info_link]" options="b"/>
<hbox>
<description id="${row}[info_subject]" no_lang="1" class="$row_cont[sub_class]"/>
<description align="right" id="{$row}[info_number]" no_lang="1" class="infolog_infoId"/>
</hbox>
<box class="infoDes">
<description id="${row}[info_des]" no_lang="1" activate_links="1"/>
</box>
<link-string id="${row}[filelinks]"/>
</vbox>
<customfields-list id="$row" class="customfields"/>
<menulist>
<menupopup type="select-cat" id="${row}[info_cat]" readonly="true"/>
</menulist>
<vbox>
<date-time id="${row}[info_startdate]" readonly="true" options=",8" class="infolog_fixedHeight"/>
<date-time id="${row}[info_enddate]" readonly="true" options=",8" class="$row_cont[end_class] infolog_fixedHeight"/>
<date-time id="${row}[info_datecompleted]" readonly="true" class="infolog_fixedHeight"/>
</vbox>
<vbox>
<hbox readonly="true">
<hbox readonly="true">
<date-duration id="${row}[info_used_time]" readonly="true" options="@@duration_format"/>
<date-duration id="${row}[info_sum_timesheets]" readonly="true" options="@@duration_format" class="timesheet"/>
</hbox>
<description/>
</hbox>
<date-duration id="${row}[info_planned_time]" readonly="true" options="@@duration_format" span="all" class="infolog_planned"/>
</vbox>
<vbox>
<hbox id="r_used_time">
<image label="Times" src="timesheet"/>
<date-duration id="${row}[info_used_time]" readonly="true" options="@@duration_format"/>
<date-duration id="${row}[info_sum_timesheets]" readonly="true" options="@@duration_format" class="timesheet"/>
</hbox>
<hbox id="planified">
<image label="planned time" src="k_alarm.png"/>
<date-duration id="${row}[info_planned_time]" readonly="true" options="@@duration_format" span="all" class="infolog_planned"/>
</hbox>
<hbox id="replanified">
<image label="Re-planned time" src="agt_reload.png"/>
<date-duration id="${row}[info_replanned_time]" readonly="true" options="@@duration_format" span="all" class="replanned"/>
</hbox>
</vbox>
<vbox>
<menulist>
<menupopup type="select-account" id="${row}[info_owner]" readonly="true"/>
</menulist>
<listbox type="select-account" id="${row}[info_responsible]" readonly="true" rows="5"/>
</vbox>
<vbox>
<date-time id="${row}[info_datemodified]" readonly="true"/>
<menulist>
<menupopup type="select-account" id="${row}[info_modifier]" readonly="true"/>
</menulist>
</vbox>
</row>
</rows>
</grid>
</template>
</overlay>

View File

@ -361,11 +361,20 @@ var AppJS = Class.extend(
})
.addClass("ui-helper-clearfix");
//Add Sortable handler to sideBox fav. menu
jQuery('ul','#favorite_sidebox_'+this.appname).sortable({
//Add Sortable handler to sideBox fav. menu
jQuery('ul','#favorite_sidebox_'+this.appname).sortable({
items:'li:not([data-id$="add"])',
placeholder:'ui-fav-sortable-placeholder',
helper: function(event, item) {
// We'll need to know which app this is for
item.attr('data-appname',self.appname);
// Create custom helper so it can be dragged to Home
var h_parent = item.parent().parent().clone();
h_parent.find('li').not('[data-id="'+item.attr('data-id')+'"]').remove();
h_parent.appendTo('body');
return h_parent;
},
refreshPositions: true,
update: function (event, ui)
{
var favSortedList = jQuery(this).sortable('toArray', {attribute:'data-id'});