New feature: shortcuts to a search result. The feature is not automatically available with upgrade of custom versions -requires a ShortcutContainerMenuNode.

SVN:trunk[2431]
This commit is contained in:
Romain Quetiez
2012-11-16 11:21:00 +00:00
parent 8f398bd130
commit 7792b54d26
14 changed files with 677 additions and 27 deletions

View File

@@ -36,6 +36,7 @@ class ajax_page extends WebPage
protected $m_sCurrentTab;
protected $m_sCurrentTabContainer;
protected $m_aTabs;
private $m_sMenu; // If set, then the menu will be updated
/**
* constructor for the web page
@@ -52,6 +53,7 @@ class ajax_page extends WebPage
$this->m_aTabs = array();
$this->sContentType = 'text/html';
$this->sContentDisposition = 'inline';
$this->m_sMenu = "";
}
public function AddTabContainer($sTabContainer, $sPrefix = '')
@@ -93,6 +95,11 @@ class ajax_page extends WebPage
return $this->m_sCurrentTab;
}
public function AddToMenu($sHtml)
{
$this->m_sMenu .= $sHtml;
}
/**
* Echoes the content of the whole page
* @return void
@@ -221,6 +228,24 @@ EOF
{
echo $this->s_content;
}
if (!empty($this->m_sMenu))
{
$uid = time();
echo "<div id=\"accordion_temp_$uid\">\n";
echo "<div id=\"accordion\">\n";
echo "<!-- Beginning of the accordion menu -->\n";
echo self::FilterXSS($this->m_sMenu);
echo "<!-- End of the accordion menu-->\n";
echo "</div>\n";
echo "</div>\n";
echo "<script type=\"text/javascript\">\n";
echo "$('#inner_menu').html($('#accordion_temp_$uid').html());\n";
echo "$('#accordion_temp_$uid').remove();\n";
echo "$('#accordion').accordion({ header: 'h3', navigation: true, autoHeight: false, collapsible: false, icons: false });\n";
echo "\n</script>\n";
}
//echo $this->s_deferred_content;
if (count($this->a_scripts) > 0)
{
@@ -240,6 +265,7 @@ EOF
echo $this->m_sReadyScript; // Ready Scripts are output as simple scripts
echo "\n</script>\n";
}
if (trim($s_captured_output) != "")
{
echo self::FilterXSS($s_captured_output);

View File

@@ -1614,6 +1614,7 @@ class ExtraMenus implements iPopupMenuExtension
new URLPopupMenuItem('UI:Menu:EMail', Dict::S('UI:Menu:EMail'), "mailto:?body=".urlencode($sUrl)),
new URLPopupMenuItem('UI:Menu:CSVExport', Dict::S('UI:Menu:CSVExport'), $sUrl."&format=csv"),
new JSPopupMenuItem('UI:Menu:AddToDashboard', Dict::S('UI:Menu:AddToDashboard'), "DashletCreationDlg('$sOQL')"),
new JSPopupMenuItem('UI:Menu:ShortcutList', Dict::S('UI:Menu:ShortcutList'), "ShortcutListDlg('$sOQL', '$sContext')"),
);
break;

View File

@@ -80,6 +80,15 @@ class ApplicationMenu
call_user_func($aCallSpec);
}
}
// Build menus from the menus themselves (e.g. the ShortcutContainerMenuNode will do that)
//
foreach(self::$aRootMenus as $aMenu)
{
$oMenuNode = self::GetMenuNode($aMenu['index']);
$oMenuNode->PopulateChildMenus();
}
self::$bAdditionalMenusLoaded = true;
}
}
@@ -131,7 +140,7 @@ class ApplicationMenu
// they were not used to display the menus (redundant or unused)
//
$aBacktrace = debug_backtrace();
$sFile = $aBacktrace[2]["file"];
$sFile = isset($aBacktrace[2]["file"]) ? $aBacktrace[2]["file"] : $aBacktrace[1]["file"];
self::$aMenusIndex[$index] = array('node' => $oMenuNode, 'children' => array(), 'parent' => $sParentId, 'rank' => $fRank, 'source_file' => $sFile);
}
else
@@ -154,7 +163,7 @@ class ApplicationMenu
/**
* Entry point to display the whole menu into the web page, used by iTopWebPage
*/
static public function DisplayMenu(iTopWebPage $oPage, $aExtraParams)
static public function DisplayMenu($oPage, $aExtraParams)
{
self::LoadAdditionalMenus();
// Sort the root menu based on the rank
@@ -253,7 +262,7 @@ class ApplicationMenu
/**
* Helper function to get the list of child(ren) of a menu
*/
static protected function GetChildren($index)
static public function GetChildren($index)
{
return self::$aMenusIndex[$index]['children'];
}
@@ -407,6 +416,16 @@ abstract class MenuNode
return $this->index;
}
public function PopulateChildMenus()
{
foreach (ApplicationMenu::GetChildren($this->GetIndex()) as $aMenu)
{
$index = $aMenu['index'];
$oMenu = ApplicationMenu::GetMenuNode($index);
$oMenu->PopulateChildMenus();
}
}
public function GetHyperlink($aExtraParams)
{
$aExtraParams['c[menu]'] = $this->GetMenuId();
@@ -617,31 +636,38 @@ class OQLMenuNode extends MenuNode
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
try
{
$oSearch = DBObjectSearch::FromOQL($this->sOQL);
$sIcon = MetaModel::GetClassIcon($oSearch->GetClass());
}
catch(Exception $e)
{
$sIcon = '';
}
OQLMenuNode::RenderOQLSearch
(
$this->sOQL,
Dict::S($this->sPageTitle),
'Menu_'.$this->GetMenuId(),
$this->bSearch, // Search pane
true, // Search open
$oPage,
$aExtraParams
);
}
if ($this->bSearch)
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array())
{
$oSearch = DBObjectSearch::FromOQL($sOql);
$sIcon = MetaModel::GetClassIcon($oSearch->GetClass());
if ($bSearchPane)
{
$aParams = array_merge(array('open' => true, 'table_id' => 'Menu_'.$this->GetMenuId()), $aExtraParams);
$aParams = array_merge(array('open' => $bSearchOpen, 'table_id' => $sUsageId), $aExtraParams);
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
$oBlock->Display($oPage, 0);
}
$oPage->add("<p class=\"page-header\">$sIcon ".Dict::S($this->sPageTitle)."</p>");
$oPage->add("<p class=\"page-header\">$sIcon ".Dict::S($sTitle)."</p>");
$aParams = array_merge(array('table_id' => 'Menu_'.$this->GetMenuId()), $aExtraParams);
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
$oBlock->Display($oPage, 1);
$oBlock->Display($oPage, $sUsageId);
}
}
/**
* This class defines a menu item that displays a search form for the given class of objects
*/
@@ -893,3 +919,95 @@ class DashboardMenuNode extends MenuNode
}
/**
* A shortcut container is the preferred destination of newly created shortcuts
*/
class ShortcutContainerMenuNode extends MenuNode
{
public function GetHyperlink($aExtraParams)
{
return '';
}
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
}
public function PopulateChildMenus()
{
// Load user shortcuts in DB
//
$oBMSearch = new DBObjectSearch('Shortcut');
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
$oBMSet = new DBObjectSet($oBMSearch, array('friendlyname' => true)); // ascending on friendlyname
$fRank = 1;
while ($oShortcut = $oBMSet->Fetch())
{
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
$oShortcutMenu = new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
}
// Complete the tree
//
parent::PopulateChildMenus();
}
}
require_once(APPROOT.'application/shortcut.class.inc.php');
/**
* This class defines a menu item which content is a shortcut.
*/
class ShortcutMenuNode extends MenuNode
{
protected $oShortcut;
/**
* Create a menu item based on a custom template and inserts it into the application's main menu
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
* @param object $oShortcut Shortcut object
* @param integer $iParentIndex ID of the parent menu
* @param float $fRank Number used to order the list, any number will do, but for a given level (i.e same parent) all menus are sorted based on this value
* @param string $sEnableClass Name of class of object
* @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE
* @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them...
* @return MenuNode
*/
public function __construct($sMenuId, $oShortcut, $iParentIndex, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
{
parent::__construct($sMenuId, $iParentIndex, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus);
$this->oShortcut = $oShortcut;
$this->aReflectionProperties['shortcut'] = $oShortcut->GetKey();
}
public function GetHyperlink($aExtraParams)
{
$sContext = $this->oShortcut->Get('context');
$aContext = unserialize($sContext);
if (isset($aContext['menu']))
{
unset($aContext['menu']);
}
foreach ($aContext as $sArgName => $sArgValue)
{
$aExtraParams[$sArgName] = $sArgValue;
}
return parent::GetHyperlink($aExtraParams);
}
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
$this->oShortcut->RenderContent($oPage, $aExtraParams);
}
public function GetTitle()
{
return $this->oShortcut->Get('name');
}
public function GetLabel()
{
return $this->oShortcut->Get('name');
}
}

View File

@@ -0,0 +1,257 @@
<?php
// Copyright (C) 2010-2012 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Persistent class Shortcut and derived
* Shortcuts of any kind
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
abstract class Shortcut extends cmdbAbstractObject
{
public static function Init()
{
$aParams = array
(
"category" => "core/cmdb,view_in_gui,application",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_shortcut",
"db_key_field" => "id",
"db_finalclass_field" => "realclass",
"display_template" => "",
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("context", array("allowed_values"=>null, "sql"=>"context", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('name', 'context')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
abstract public function RenderContent(WebPage $oPage, $aExtraParams = array());
protected function OnInsert()
{
$this->Set('user_id', UserRights::GetUserId());
}
public function StartRenameDialog($oPage)
{
$oPage->add('<div id="shortcut_rename_dlg">');
$oForm = new DesignerForm();
$sDefault = $this->Get('name');
$oField = new DesignerTextField('name', Dict::S('Class:Shortcut/Attribute:name'), $sDefault);
$oField->SetMandatory(true);
$oForm->AddField($oField);
$oForm->Render($oPage);
$oPage->add('</div>');
$sDialogTitle = Dict::S('UI:ShortcutRenameDlg:Title');
$sOkButtonLabel = Dict::S('UI:Button:Ok');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$iShortcut = $this->GetKey();
$oPage->add_ready_script(
<<<EOF
function ShortcutRenameOK()
{
var oForm = $(this).find('form');
var sFormId = oForm.attr('id');
var oParams = null;
var aErrors = ValidateForm(sFormId, false);
if (aErrors.length == 0)
{
oParams = ReadFormParams(sFormId);
}
oParams.operation = 'shortcut_rename_go';
oParams.id = $iShortcut;
var me = $(this);
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data) {
me.dialog( "close" );
me.remove();
$('body').append(data);
});
}
$('#shortcut_rename_dlg form').bind('submit', function() { return false; });
$('#shortcut_rename_dlg').dialog({
width: 400,
modal: true,
title: '$sDialogTitle',
buttons: [
{ text: "$sOkButtonLabel", click: ShortcutRenameOK},
{ text: "$sCancelButtonLabel", click: function() {
$(this).dialog( "close" ); $(this).remove();
} },
],
close: function() { $(this).remove(); }
});
EOF
);
}
}
class ShortcutOQL extends Shortcut
{
public static function Init()
{
$aParams = array
(
"category" => "core/cmdb,view_in_gui,application",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_shortcut_oql",
"db_key_field" => "id",
"db_finalclass_field" => "",
"display_template" => "",
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeOQL("oql", array("allowed_values"=>null, "sql"=>"oql", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('name', 'context', 'oql')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('name')); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
$oPage->set_title($this->Get('name'));
$bSearchPane = true;
$bSearchOpen = false;
try
{
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams);
}
catch (Exception $e)
{
throw new Exception("The OQL shortcut '".$this->Get('name')."' (id: ".$this->GetKey().") could not be displayed: ".$e->getMessage());
}
}
public static function GetCreationForm($sOQL = null)
{
$oForm = new DesignerForm();
// Find a unique default name
// -> The class of the query + an index if necessary
if ($sOQL == null)
{
$sDefault = '';
}
else
{
$oBMSearch = new DBObjectSearch('Shortcut');
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
$oBMSet = new DBObjectSet($oBMSearch);
$aNames = $oBMSet->GetColumnAsArray('name');
$oSearch = DBObjectSearch::FromOQL($sOQL);
$sDefault = utils::MakeUniqueName($oSearch->GetClass(), $aNames);
}
$oField = new DesignerTextField('name', Dict::S('Class:Shortcut/Attribute:name'), $sDefault);
$oField->SetMandatory(true);
$oForm->AddField($oField);
//$oField = new DesignerLongTextField('oql', Dict::S('Class:Shortcut/Attribute:oql'), $sOQL);
//$oField->SetMandatory();
$oField = new DesignerHiddenField('oql', '', $sOQL);
$oForm->AddField($oField);
return $oForm;
}
public static function GetCreationDlgFromOQL($oPage, $sOQL)
{
$oPage->add('<div id="shortcut_creation_dlg">');
$oForm = self::GetCreationForm($sOQL);
$oForm->Render($oPage);
$oPage->add('</div>');
$sDialogTitle = Dict::S('UI:ShortcutListDlg:Title');
$sOkButtonLabel = Dict::S('UI:Button:Ok');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink();
$oPage->add_ready_script(
<<<EOF
function ShortcutCreationOK()
{
var oForm = $('#shortcut_creation_dlg form');
var sFormId = oForm.attr('id');
var oParams = null;
var aErrors = ValidateForm(sFormId, false);
if (aErrors.length == 0)
{
oParams = ReadFormParams(sFormId);
}
oParams.operation = 'shortcut_list_create';
var me = $('#shortcut_creation_dlg');
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?$sContext', oParams, function(data) {
me.dialog( "close" );
me.remove();
$('body').append(data);
});
}
$('#shortcut_creation_dlg form').bind('submit', function() { ShortcutCreationOK(); return false; });
$('#shortcut_creation_dlg').dialog({
width: 400,
modal: true,
title: '$sDialogTitle',
buttons: [
{ text: "$sOkButtonLabel", click: ShortcutCreationOK },
{ text: "$sCancelButtonLabel", click: function() {
$(this).dialog( "close" ); $(this).remove();
} },
],
close: function() { $(this).remove(); }
});
EOF
);
}
}
?>

View File

@@ -819,5 +819,27 @@ class utils
$sUrl = self::GetAbsoluteUrlAppRoot().'env-'.self::GetCurrentEnvironment().'/';
return $sUrl;
}
/**
* Returns a name unique amongst the given list
* @param string $sProposed The default value
* @param array $aExisting An array of existing values (strings)
*/
static public function MakeUniqueName($sProposed, $aExisting)
{
if (in_array($sProposed, $aExisting))
{
$i = 1;
while (in_array($sProposed.$i, $aExisting) && ($i < 50))
{
$i++;
}
return $sProposed.$i;
}
else
{
return $sProposed;
}
}
}
?>

View File

@@ -45,7 +45,9 @@ class ItopWelcome extends ModuleHandlerAPI
public static function OnMenuCreation()
{
$oWelcomeMenu = new MenuGroup('WelcomeMenu', 10 /* fRank */);
new DashboardMenuNode('WelcomeMenuPage', dirname(__FILE__).'/welcome_menu.xml', $oWelcomeMenu->GetIndex() /* oParent */, 1 /* fRank */);
new DashboardMenuNode('WelcomeMenuPage', dirname(__FILE__).'/welcome_menu.xml', $oWelcomeMenu->GetIndex() /* oParent */, 10 /* fRank */);
new ShortcutContainerMenuNode('MyShortcuts', $oWelcomeMenu->GetIndex(), 20 /* fRank */);
$oToolsMenu = new MenuGroup('DataAdministration', 70 /* fRank */, 'Organization', UR_ACTION_MODIFY, UR_ALLOWED_YES|UR_ALLOWED_DEPENDS);
new WebPageMenuNode('CSVImportMenu', utils::GetAbsoluteUrlAppRoot().'pages/csvimport.php', $oToolsMenu->GetIndex(), 1 /* fRank */);

View File

@@ -5,7 +5,7 @@
<rank>10</rank>
</menu>
<menu id="WelcomeMenuPage" xsi:type="DashboardMenuNode" _delta="define">
<rank>1</rank>
<rank>10</rank>
<parent>WelcomeMenu</parent>
<definition>
<layout>DashboardLayoutOneCol</layout>
@@ -52,5 +52,9 @@
</cells>
</definition>
</menu>
<menu id="MyShortcuts" xsi:type="ShortcutContainerMenuNode" _delta="define">
<rank>20</rank>
<parent>WelcomeMenu</parent>
</menu>
</menus>
</itop_design>

View File

@@ -375,6 +375,7 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Button:FilterList' => ' Filter... ',
'UI:Button:Create' => ' Create ',
'UI:Button:Delete' => ' Delete ! ',
'UI:Button:Rename' => ' Rename... ',
'UI:Button:ChangePassword' => ' Change Password ',
'UI:Button:ResetPassword' => ' Reset Password ',
@@ -1122,5 +1123,19 @@ When associated with a trigger, each action is given an "order" number, specifyi
'DayOfWeek-Thursday' => 'Thursday',
'DayOfWeek-Friday' => 'Friday',
'DayOfWeek-Saturday' => 'Saturday',
'UI:Menu:ShortcutList' => 'Create a Shortcut...',
'UI:ShortcutRenameDlg:Title' => 'Rename the shortcut',
'UI:ShortcutListDlg:Title' => 'Create a shortcut for the list',
'UI:ShortcutDelete:Confirm' => 'Please confirm that wou wish to delete the shortcut(s).',
'Menu:MyShortcuts' => 'My Shortcuts',
'Class:Shortcut' => 'Shortcut',
'Class:Shortcut+' => '',
'Class:Shortcut/Attribute:name' => 'Name',
'Class:Shortcut/Attribute:name+' => 'Label used in the menu and page title',
'Class:ShortcutOQL' => 'Search result shortcut',
'Class:ShortcutOQL+' => '',
'Class:ShortcutOQL/Attribute:oql' => 'Query',
'Class:ShortcutOQL/Attribute:oql+' => 'OQL defining the list of objects to search for',
));
?>

View File

@@ -256,6 +256,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'UI:Button:FilterList' => ' Filtrer... ',
'UI:Button:Create' => ' Créer ',
'UI:Button:Delete' => ' Supprimer ! ',
'UI:Button:Rename' => ' Renommer... ',
'UI:Button:ChangePassword' => ' Changer ! ',
'UI:Button:ResetPassword' => ' Ràz du mot de passe ',
'UI:SearchToggle' => 'Recherche',
@@ -964,5 +965,19 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'DayOfWeek-Thursday' => 'Jeudi',
'DayOfWeek-Friday' => 'Vendredi',
'DayOfWeek-Saturday' => 'Samedi',
'UI:Menu:ShortcutList' => 'Créer un Raccourci...',
'UI:ShortcutListDlg:Title' => 'Créer un raccourci pour la liste',
'UI:ShortcutRenameDlg:Title' => 'Renommer le raccourci',
'UI:ShortcutDelete:Confirm' => 'Veuillez confirmer la suppression du ou des raccourci(s)',
'Menu:MyShortcuts' => 'Mes raccourcis',
'Class:Shortcut' => 'Raccourci',
'Class:Shortcut+' => '',
'Class:Shortcut/Attribute:name' => 'Nom',
'Class:Shortcut/Attribute:name+' => 'Label utilisé dans le menu et comme titre de la page',
'Class:ShortcutOQL' => 'Raccourci vers une liste d\'objets',
'Class:ShortcutOQL+' => '',
'Class:ShortcutOQL/Attribute:oql' => 'Requête',
'Class:ShortcutOQL/Attribute:oql+' => 'Requête de définition de l\'ensemble des objets',
));
?>

View File

@@ -255,6 +255,28 @@ $(function()
var oDlgOpen = $('#datatable_dlg_'+sListId+' :visible');
return (oDlgOpen.length > 0);
},
GetMultipleSelectionParams: function()
{
var oRes = {};
oRes.selectionMode = '';
if (this.element.find(':input[name=selectionMode]').length > 0)
{
oRes.selectionMode = this.element.find(':input[name=selectionMode]').val();
}
oRes.selectObject = [];
this.element.find(':input[name^=selectObject]').each(function() {
oRes.selectObject.push($(this).val());
});
oRes.storedSelection = [];
this.element.find(':input[name^=storedSelection]').each(function() {
oRes.storedSelection.push($(this).val());
});
return oRes;
}
});
});

View File

@@ -319,3 +319,11 @@ function DashletCreationDlg(sOQL)
});
return false;
}
function ShortcutListDlg(sOQL, sContext)
{
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?'+sContext, {operation: 'shortcut_list_dlg', oql: sOQL}, function(data){
$('body').append(data);
});
return false;
}

View File

@@ -861,6 +861,69 @@ EOF
}
break;
case 'shortcut_list_dlg':
$sOQL = utils::ReadParam('oql', '', false, 'raw_data');
ShortcutOQL::GetCreationDlgFromOQL($oPage, $sOQL);
break;
case 'shortcut_list_create':
$oForm = ShortcutOQL::GetCreationForm();
$aValues = $oForm->ReadParams();
$oAppContext = new ApplicationContext();
$aContext = $oAppContext->GetAsHash();
$sContext = serialize($aContext);
$oShortcut = MetaModel::NewObject("ShortcutOQL");
$oShortcut->Set('user_id', UserRights::GetUserId());
$oShortcut->Set("context", $sContext);
$oShortcut->Set("name", $aValues['name']);
$oShortcut->Set("oql", $aValues['oql']);
$iId = $oShortcut->DBInsertNoReload();
// Add the menu node in the right place
//
// Mmmm... already done because the newly created menu is read from the DB
// as soon as we invoke DisplayMenu
// Refresh the menu pane
$aExtraParams = array();
ApplicationMenu::DisplayMenu($oPage, $aExtraParams);
break;
case 'shortcut_rename_dlg':
$oSearch = new DBObjectSearch('Shortcut');
$aShortcuts = utils::ReadMultipleSelection($oSearch);
$iShortcut = $aShortcuts[0];
$oShortcut = MetaModel::GetObject('Shortcut', $iShortcut);
$oShortcut->StartRenameDialog($oPage);
break;
case 'shortcut_rename_go':
$iShortcut = utils::ReadParam('id', 0);
$oShortcut = MetaModel::GetObject('Shortcut', $iShortcut);
$sName = utils::ReadParam('attr_name', '', false, 'raw_data');
if (strlen($sName) > 0)
{
$oShortcut->Set('name', $sName);
$oShortcut->DBUpdate();
$oPage->add_ready_script('window.location.reload();');
}
break;
case 'shortcut_delete_go':
$oSearch = new DBObjectSearch('Shortcut');
$aShortcuts = utils::ReadMultipleSelection($oSearch);
foreach ($aShortcuts as $iShortcut)
{
$oShortcut = MetaModel::GetObject('Shortcut', $iShortcut);
$oShortcut->DBDelete();
$oPage->add_ready_script('window.location.reload();');
}
break;
case 'export_dashboard':
$sMenuId = utils::ReadParam('id', '', false, 'raw_data');
ApplicationMenu::LoadAdditionalMenus();

View File

@@ -144,7 +144,6 @@ EOF
var pager = $('#user_prefs form .pager');
$(':input[name=selectionMode]', pager).val('negative');
$('#user_prefs table.listResults').trigger('load_selection');
}
else
{
@@ -187,6 +186,101 @@ EOF
);
}
//////////////////////////////////////////////////////////////////////////
//
// Shortcuts
//
//////////////////////////////////////////////////////////////////////////
$oP->add('<fieldset><legend>'.Dict::S('Menu:MyShortcuts').'</legend>');
//$oP->p(Dict::S('UI:Menu:MyShortcuts+'));
$oBMSearch = new DBObjectSearch('Shortcut');
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
//$aExtraParams = array('menu' => false, 'toolkit_menu' => false, 'display_limit' => false, 'localize_values' => $bLocalize, 'zlist' => 'details');
$aExtraParams = array();
$oBlock = new DisplayBlock($oBMSearch, 'list', false, $aExtraParams);
$oBlock->Display($oP, 'shortcut_list', array('view_link' => false, 'menu' => false, 'toolkit_menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount'=> '#shortcut_selection_count', 'table_id' => 'user_prefs_shortcuts'));
$oP->add('<p>');
$oSet = new DBObjectSet($oBMSearch);
if ($oSet->Count() > 0)
{
$sButtons = '<img src="../images/tv-item-last.gif">';
$sButtons .= '&nbsp;';
$sButtons .= '<button id="shortcut_btn_rename">'.Dict::S('UI:Button:Rename').'</button>';
$sButtons .= '&nbsp;';
$sButtons .= '<button id="shortcut_btn_delete">'.Dict::S('UI:Button:Delete').'</button>';
// Selection count updated by the pager, and used to enable buttons
$oP->add('<input type="hidden" id="shortcut_selection_count"/>');
$oP->add('</fieldset>');
$sConfirmDelete = addslashes(Dict::S('UI:ShortcutDelete:Confirm'));
$oP->add_ready_script(
<<<EOF
function OnShortcutBtnRename()
{
var oParams = $('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
oParams.operation = 'shortcut_rename_dlg';
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
$('body').append(data);
});
return false;
}
function OnShortcutBtnDelete()
{
if (confirm('$sConfirmDelete'))
{
var oParams = $('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
oParams.operation = 'shortcut_delete_go';
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
$('body').append(data);
});
}
return false;
}
function OnSelectionCountChange()
{
var iCountSelected = $("#shortcut_selection_count").val();
if (iCountSelected == 0)
{
$('#shortcut_btn_rename').attr('disabled', 'disabled');
$('#shortcut_btn_delete').attr('disabled', 'disabled');
}
else if (iCountSelected == 1)
{
$('#shortcut_btn_rename').removeAttr('disabled');
$('#shortcut_btn_delete').removeAttr('disabled');
}
else
{
$('#shortcut_btn_rename').attr('disabled', 'disabled');
$('#shortcut_btn_delete').removeAttr('disabled');
}
}
var oUpperCheckBox = $('#datatable_shortcut_list .checkAll').first();
oUpperCheckBox.parent().width(oUpperCheckBox.width() + 2);
$('#datatable_shortcut_list').append('<tr><td colspan="2">&nbsp;&nbsp;&nbsp;$sButtons</td></tr>');
$('#shortcut_selection_count').bind('change', OnSelectionCountChange);
$('#shortcut_btn_rename').bind('click', OnShortcutBtnRename);
$('#shortcut_btn_delete').bind('click', OnShortcutBtnDelete);
OnSelectionCountChange();
EOF
);
} // if count > 0
//////////////////////////////////////////////////////////////////////////
//
// Footer
//
$oP->add('</div>');
$oP->add_ready_script("$('#fav_page_length').bind('keyup change', function(){ ValidateOtherSettings(); })");
}

View File

@@ -178,7 +178,7 @@ EOF;
{
$sCompiledCode .= $this->CompileMenu($oMenuNode, $sTargetDir, $sRelativeDir, $oP);
}
catch (ssDOMFormatException $e)
catch (DOMFormatException $e)
{
throw new Exception("Failed to process menu '$sMenuId', from '$sModuleRootDir': ".$e->getMessage());
}
@@ -1018,6 +1018,10 @@ EOF;
$sNewMenu = "new TemplateMenuNode('$sMenuId', $sTemplateSpec, $sParentSpec, $fRank);";
break;
case 'ShortcutContainerMenuNode':
$sNewMenu = "new ShortcutContainerMenuNode('$sMenuId', $sParentSpec, $fRank);";
break;
case 'OQLMenuNode':
$sOQL = self::QuoteForPHP($oMenu->GetChildText('oql'));
$bSearch = ($oMenu->GetChildText('do_search') == '1') ? 'true' : 'false';
@@ -1043,17 +1047,16 @@ EOF;
$sEnableStimulus = $oMenu->GetChildText('enable_stimulus');
if (strlen($sEnableStimulus) > 0)
{
$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');";
$sNewMenu = "new $sMenuClass('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission, '$sEnableStimulus');";
}
else
{
$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);";
$sNewMenu = "new $sMenuClass('$sMenuId', $fRank, '$sEnableClass', $sEnableAction, $sEnablePermission);";
}
//$sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sEnableClass', UR_ACTION_MODIFY, UR_ALLOWED_YES|UR_ALLOWED_DEPENDS);";
}
else
{
$sNewMenu = "new MenuGroup('$sMenuId', $fRank);";
$sNewMenu = "new $sMenuClass('$sMenuId', $fRank);";
}
}