mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Implementation of a new extension "iPopupMenuExtension" to allow a module to add menu items almost anywhere inside iTop.
SVN:trunk[2220]
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -48,4 +48,146 @@ interface iApplicationObjectExtension
|
||||
public function OnDBDelete($oObject, $oChange = null);
|
||||
}
|
||||
|
||||
?>
|
||||
/**
|
||||
* New extension to add menu items in the "popup" menus inside iTop. Provides a greater flexibility than
|
||||
* iApplicationUIExtension::EnumAllowedActions.
|
||||
*
|
||||
* To add some menus into iTop, declare a class that implements this interface, it will be called automatically
|
||||
* by the application, as long as the class definition is included somewhere in the code
|
||||
*/
|
||||
interface iPopupMenuExtension
|
||||
{
|
||||
// Possible types of menu into which new items can be added
|
||||
const MENU_OBJLIST_ACTIONS = 1; // $param is a DBObjectSet containing the list of objects
|
||||
const MENU_OBJLIST_TOOLKIT = 2; // $param is a DBObjectSet containing the list of objects
|
||||
const MENU_OBJDETAILS_ACTIONS = 3; // $param is a DBObject instance: the object currently displayed
|
||||
const MENU_DASHBOARD_ACTIONS = 4; // $param is a Dashboard instance: the dashboard currently displayed
|
||||
const MENU_USER_ACTIONS = 5; // $param is a null ??
|
||||
|
||||
/**
|
||||
* Get the list of items to be added to a menu. The items will be inserted in the menu in the order of the returned array
|
||||
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx above
|
||||
* @param mixed $param Depends on $iMenuId, see the constants defined above
|
||||
* @return Array An array of ApplicationPopupMenuItem or an empty array if no action is to be added to the menu
|
||||
*/
|
||||
public static function EnumItems($iMenuId, $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each menu items is defined by an instance of an object derived from the class
|
||||
* ApplicationPopupMenu below
|
||||
*
|
||||
*/
|
||||
abstract class ApplicationPopupMenuItem
|
||||
{
|
||||
protected $sUID;
|
||||
protected $sLabel;
|
||||
|
||||
public function __construct($sUID, $sLabel)
|
||||
{
|
||||
$this->sUID = $sUID;
|
||||
$this->sLabel = $sLabel;
|
||||
}
|
||||
|
||||
public function GetUID()
|
||||
{
|
||||
return $this->sUID;
|
||||
}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the components to create a popup menu item in HTML
|
||||
* @return Hash A hash array: array('label' => , 'url' => , 'target' => , 'onclick' => )
|
||||
*/
|
||||
abstract public function GetMenuItem();
|
||||
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that browses to the given URL
|
||||
*/
|
||||
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
protected $sURL;
|
||||
protected $sTarget;
|
||||
|
||||
/**
|
||||
* Class for adding an item that browses to the given URL
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sURL If the menu is an hyperlink, provide the absolute hyperlink here
|
||||
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sURL, $sTarget = '_top')
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sURL = $sURL;
|
||||
$this->sTarget = $sTarget;
|
||||
}
|
||||
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array ('label' => $this->GetLabel(), 'url' => $this->sURL, 'target' => $this->sTarget);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that triggers some Javascript code
|
||||
*/
|
||||
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
protected $sJSCode;
|
||||
protected $aIncludeJSFiles;
|
||||
|
||||
/**
|
||||
* Class for adding an item that triggers some Javascript code
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sJSCode In case the menu consists in executing some havascript code inside the page, pass it here. If supplied $sURL ans $sTarget will be ignored
|
||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sJSCode = $sJSCode;
|
||||
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
||||
}
|
||||
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array ('label' => $this->GetLabel(), 'onclick' => $this->sJSCode, 'url' => '#');
|
||||
}
|
||||
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return $this->aIncludeJSFiles;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for adding a separator (horizontal line, not selectable) the output
|
||||
* will automatically reduce several consecutive separators to just one
|
||||
*/
|
||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
/**
|
||||
* Class for inserting a separator into a popup menu
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('', '');
|
||||
}
|
||||
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array ('label' => '<hr class="menu-separator">', 'url' => '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,11 @@ abstract class Dashboard
|
||||
|
||||
public function FromXml($sXml)
|
||||
{
|
||||
$this->aCells = array(); // reset the content of the dashboard
|
||||
set_error_handler(array('Dashboard', 'ErrorHandler'));
|
||||
$oDoc = new DOMDocument();
|
||||
$oDoc->loadXML($sXml);
|
||||
restore_error_handler();
|
||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||
|
||||
$oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0);
|
||||
@@ -68,6 +71,21 @@ abstract class Dashboard
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler to turn XML loading warnings into exceptions
|
||||
*/
|
||||
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno == E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
|
||||
{
|
||||
throw new DOMException($errstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function ToXml()
|
||||
{
|
||||
$oDoc = new DOMDocument();
|
||||
@@ -365,13 +383,21 @@ class RuntimeDashboard extends Dashboard
|
||||
if (!$bEditMode)
|
||||
{
|
||||
$sEditMenu = "<td><span id=\"DashboardMenu\"><ul><li><img src=\"../images/edit.png\"><ul>";
|
||||
|
||||
$aActions = array();
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}')");
|
||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
|
||||
$sEditMenu .= "<li><a href=\"#\" onclick=\"return EditDashboard('{$this->sId}')\">".Dict::S('UI:Dashboard:Edit')."</a></li>";
|
||||
if ($this->bCustomized)
|
||||
{
|
||||
$sEditMenu .= "<li><a href=\"#\" onclick=\"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}'); else return false;\">".Dict::S('UI:Dashboard:Revert')."</a></li>";
|
||||
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:Revert'),
|
||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}'); else return false");
|
||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||
}
|
||||
$sEditMenu .= "</ul></li></ul></span></td>";
|
||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||
$sEditMenu .= $oPage->RenderPopupMenuItems($aActions);
|
||||
|
||||
|
||||
$sEditMenu = addslashes($sEditMenu);
|
||||
//$sEditBtn = addslashes('<div style="display: inline-block; height: 55px; width:200px;vertical-align:center;line-height:60px;text-align:left;"><button onclick="EditDashboard(\''.$this->sId.'\');">Edit This Page</button></div>');
|
||||
$oPage->add_ready_script(
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
|
||||
*/
|
||||
|
||||
class DataTable
|
||||
{
|
||||
protected $iListId; // Unique ID inside the web page
|
||||
protected $sTableId; // identifier for sqve the settings (combined with the class aliases)
|
||||
protected $sTableId; // identifier for saving the settings (combined with the class aliases)
|
||||
protected $oSet; // The set of objects to display
|
||||
protected $aClassAliases; // The aliases (alias => class) inside the set
|
||||
protected $iNbObjects; // Total number of objects inthe set
|
||||
@@ -250,8 +251,16 @@ EOF;
|
||||
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
||||
{
|
||||
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li><img src="../images/toolkit_menu.png"><ul><li><a onclick="$(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'open\');">'.$sMenuTitle.'</a></li></li></ul></div>';
|
||||
//$oPage->add_ready_script("$('#tk_{$this->iListId} > ul').popupmenu();");
|
||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li><img src="../images/toolkit_menu.png"><ul>';
|
||||
|
||||
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
||||
$aActions = array(
|
||||
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
||||
);
|
||||
$this->oSet->Rewind();
|
||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions);
|
||||
$this->oSet->Rewind();
|
||||
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
@@ -1359,7 +1359,7 @@ class MenuBlock extends DisplayBlock
|
||||
{
|
||||
// New plugins can provide javascript handlers via the 'onclick' property
|
||||
//TODO: enable extension of different menus by checking the 'target' property ??
|
||||
$aActions[$sLabel] = array ('label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'url' => isset($data['onclick']) ? $data['onclick'] : '');
|
||||
$aActions[$sLabel] = array ('label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'onclick' => isset($data['onclick']) ? $data['onclick'] : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1368,6 +1368,24 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// New extensions based on iPopupMenuItem interface
|
||||
switch($this->m_sStyle)
|
||||
{
|
||||
case 'list':
|
||||
$oSet->Rewind();
|
||||
$param = $oSet;
|
||||
$iMenuId = iPopupMenuExtension::MENU_OBJLIST_ACTIONS;
|
||||
break;
|
||||
|
||||
case 'details':
|
||||
$oSet->Rewind();
|
||||
$param = $oSet->Fetch();
|
||||
$iMenuId = iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS;
|
||||
break;
|
||||
|
||||
}
|
||||
utils::GetPopupMenuItems($oPage, $iMenuId, $param, $aActions);
|
||||
}
|
||||
$aFavoriteActions = array();
|
||||
$aCallSpec = array($sClass, 'GetShortcutActions');
|
||||
@@ -1395,38 +1413,10 @@ class MenuBlock extends DisplayBlock
|
||||
else
|
||||
{
|
||||
$sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>".Dict::S('UI:Menu:Actions')."\n<ul>\n";
|
||||
}
|
||||
$sPrevUrl = '';
|
||||
foreach ($aActions as $key => $aAction)
|
||||
{
|
||||
if (in_array($key, $aShortcutActions))
|
||||
{
|
||||
$aFavoriteActions[] = $aAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sClass = isset($aAction['class']) ? " class=\"{$aAction['class']}\"" : "";
|
||||
$sOnClick = isset($aAction['onclick']) ? " onclick=\"{$aAction['onclick']}\"" : "";
|
||||
if (empty($aAction['url']))
|
||||
{
|
||||
if ($sPrevUrl != '') // Don't output consecutively two separators...
|
||||
{
|
||||
$sHtml .= "<li>{$aAction['label']}</li>\n";
|
||||
}
|
||||
$sPrevUrl = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<li><a href=\"{$aAction['url']}\"$sClass $sOnClick>{$aAction['label']}</a></li>\n";
|
||||
$sPrevUrl = $aAction['url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHtml .= "</ul>\n</li>\n</ul></div>";
|
||||
foreach(array_reverse($aFavoriteActions) as $aAction)
|
||||
{
|
||||
$sHtml .= "<div class=\"actions_button\"><a href='{$aAction['url']}'>{$aAction['label']}</a></div>";
|
||||
}
|
||||
|
||||
$sHtml .= $oPage->RenderPopupMenuItems($aActions, $aFavoriteActions);
|
||||
|
||||
static $bPopupScript = false;
|
||||
if (!$bPopupScript)
|
||||
{
|
||||
@@ -1456,4 +1446,87 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
/**
|
||||
* Some dummy menus for testing
|
||||
*/
|
||||
class ExtraMenus implements iPopupMenuExtension
|
||||
{
|
||||
/*
|
||||
const MENU_OBJLIST_ACTIONS = 1; // $param is a DBObjectSet containing the list of objects
|
||||
const MENU_OBJLIST_TOOLKIT = 2; // $param is a DBObjectSet containing the list of objects
|
||||
const MENU_OBJDETAILS_ACTIONS = 3; // $param is a DBObject instance: the object currently displayed
|
||||
const MENU_DASHBOARD_ACTIONS = 4; // $param is a Dashboard instance: the dashboard currently displayed
|
||||
const MENU_USER_ACTIONS = 5; // $param is a null ??
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the list of items to be added to a menu. The items will be inserted in the menu in the order of the returned array
|
||||
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx above
|
||||
* @param mixed $param Depends on $iMenuId see the constants define above
|
||||
* @return Array An array of ApplicationPopupMenuItem or an empty array if no action is to be added to the menu
|
||||
*/
|
||||
public static function EnumItems($iMenuId, $param)
|
||||
{
|
||||
switch($iMenuId)
|
||||
{
|
||||
/*
|
||||
case iPopupMenuExtension::MENU_OBJLIST_ACTIONS:
|
||||
// $param is a DBObjectSet
|
||||
$aResult = array(
|
||||
new JSPopupMenuItem('Test::Item1', 'List Test 1', "alert('Test 1')"),
|
||||
new JSPopupMenuItem('Test::Item2', 'List Test 2', "alert('Test 2')"),
|
||||
);
|
||||
break;
|
||||
|
||||
case iPopupMenuExtension::MENU_OBJLIST_TOOLKIT:
|
||||
// $param is a DBObjectSet
|
||||
$aResult = array(
|
||||
new JSPopupMenuItem('Test::Item1', 'Toolkit Test 1', "alert('Test 1')"),
|
||||
new JSPopupMenuItem('Test::Item2', 'Toolkit Test 2', "alert('Test 2')"),
|
||||
);
|
||||
break;
|
||||
|
||||
case iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS:
|
||||
// $param is a DBObject
|
||||
$aResult = array(
|
||||
new JSPopupMenuItem('Test::Item1', 'Object Test 1', "alert('Test 1')"),
|
||||
new JSPopupMenuItem('Test::Item2', 'Object Test 2', "alert('Test 2')"),
|
||||
);
|
||||
break;
|
||||
*/
|
||||
|
||||
case iPopupMenuExtension::MENU_DASHBOARD_ACTIONS:
|
||||
// $param is a Dashboard
|
||||
$oAppContext = new ApplicationContext();
|
||||
$aParams = $oAppContext->GetAsHash();
|
||||
$sMenuId = ApplicationMenu::GetActiveNodeId();
|
||||
$sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle'));
|
||||
$sDlgText = addslashes(Dict::S('UI:ImportDashboardText'));
|
||||
$sCloseBtn = addslashes(Dict::S('UI:Button:Cancel'));
|
||||
$aResult = array(
|
||||
new SeparatorPopupMenuItem(),
|
||||
new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=export_dashboard&id='.$sMenuId),
|
||||
new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '$sMenuId', title: '$sDlgTitle', text: '$sDlgText', close_btn: '$sCloseBtn' })",
|
||||
array('../js/ajaxfileupload.js')),
|
||||
);
|
||||
break;
|
||||
|
||||
/*
|
||||
case iPopupMenuExtension::MENU_USER_ACTIONS:
|
||||
// $param is null ??
|
||||
$aResult = array(
|
||||
new SeparatorPopupMenuItem(),
|
||||
new JSPopupMenuItem('Test::Item1', 'Reset preferences...', "alert('Test 1')"),
|
||||
new JSPopupMenuItem('Test::Item2', 'Do Something Stupid', "alert('Hey Dude !')"),
|
||||
);
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
// Unknown type of menu, do nothing
|
||||
$aResult = array();
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,18 +650,24 @@ EOF
|
||||
}
|
||||
$sLogOffMenu = "<span id=\"logOffBtn\"><ul><li><img src=\"../images/onOffBtn.png\"><ul>";
|
||||
$sLogOffMenu .= "<li><span>$sLogonMessage</span></li>\n";
|
||||
$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/preferences.php?".$oAppContext->GetForLink()."\">".Dict::S('UI:Preferences')."</a></li>\n";
|
||||
$aActions = array();
|
||||
|
||||
$oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'), utils::GetAbsoluteUrlAppRoot()."pages/preferences.php?".$oAppContext->GetForLink());
|
||||
$aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem();
|
||||
|
||||
if (utils::CanLogOff())
|
||||
{
|
||||
//$sLogOffMenu .= "<li><a href=\"../pages/UI.php?loginop=logoff\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
|
||||
$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
|
||||
$oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'), utils::GetAbsoluteUrlAppRoot().'pages/logoff.php');
|
||||
$aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem();
|
||||
}
|
||||
if (UserRights::CanChangePassword())
|
||||
{
|
||||
$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?loginop=change_pwd\">".Dict::S('UI:ChangePwdMenu')."</a></li>\n";
|
||||
$oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'), utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=change_pwd');
|
||||
$aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem();
|
||||
}
|
||||
$sLogOffMenu .= "</ul>\n</li>\n</ul></span>\n";
|
||||
utils::GetPopupMenuItems($this, iPopupMenuExtension::MENU_USER_ACTIONS, null, $aActions);
|
||||
$sLogOffMenu .= $this->RenderPopupMenuItems($aActions);
|
||||
|
||||
|
||||
$sRestrictions = '';
|
||||
if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE))
|
||||
|
||||
@@ -812,7 +812,7 @@ class DashboardMenuNode extends MenuNode
|
||||
return parent::GetHyperlink($aExtraParams);
|
||||
}
|
||||
|
||||
protected function GetDashboard()
|
||||
public function GetDashboard()
|
||||
{
|
||||
$sDashboardDefinition = @file_get_contents($this->sDashboardFile);
|
||||
if ($sDashboardDefinition !== false)
|
||||
|
||||
@@ -768,6 +768,27 @@ class utils
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "Back" button to go out of the current environment
|
||||
*/
|
||||
public static function GetPopupMenuItems($oPage, $iMenuId, $param, &$aActions)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach($oExtensionInstance->EnumItems($iMenuId, $param) as $oMenuItem)
|
||||
{
|
||||
if (is_object($oMenuItem))
|
||||
{
|
||||
$aActions[$oMenuItem->GetUID()] = $oMenuItem->GetMenuItem();
|
||||
|
||||
foreach($oMenuItem->GetLinkedScripts() as $sLinkedScript)
|
||||
{
|
||||
$oPage->add_linked_script($sLinkedScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get target configuration file name (including full path)
|
||||
*/
|
||||
|
||||
@@ -604,5 +604,36 @@ class WebPage implements Page
|
||||
$this->a_OutputOptions[$sFormat][$sOptionName] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
public function RenderPopupMenuItems($aActions, $aFavoriteActions = array())
|
||||
{
|
||||
$sPrevUrl = '';
|
||||
$sHtml = '';
|
||||
foreach ($aActions as $aAction)
|
||||
{
|
||||
$sClass = isset($aAction['class']) ? " class=\"{$aAction['class']}\"" : "";
|
||||
$sOnClick = isset($aAction['onclick']) ? " onclick=\"{$aAction['onclick']}\"" : "";
|
||||
if (empty($aAction['url']))
|
||||
{
|
||||
if ($sPrevUrl != '') // Don't output consecutively two separators...
|
||||
{
|
||||
$sHtml .= "<li>{$aAction['label']}</li>";
|
||||
}
|
||||
$sPrevUrl = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<li><a href=\"{$aAction['url']}\"$sClass $sOnClick>{$aAction['label']}</a></li>";
|
||||
$sPrevUrl = $aAction['url'];
|
||||
}
|
||||
}
|
||||
$sHtml .= "</ul></li></ul></div>";
|
||||
foreach(array_reverse($aFavoriteActions) as $aAction)
|
||||
{
|
||||
$sHtml .= "<div class=\"actions_button\"><a href='{$aAction['url']}'>{$aAction['label']}</a></div>";
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -356,7 +356,6 @@ EOF
|
||||
$oPage->add('<div style="clear:both"></div>');
|
||||
$sMaxUpload = $this->GetMaxUpload();
|
||||
$oPage->p(Dict::S('Attachments:AddAttachment').'<input type="file" name="file" id="file" onChange="ajaxFileUpload();"><span style="display:none;" id="attachment_loading"> <img src="../images/indicator.gif"></span> '.$sMaxUpload);
|
||||
//$oPage->p('<input type="button" onClick="ajaxFileUpload();" value=" Upload !">');
|
||||
$oPage->p('<span style="display:none;" id="attachment_loading">Loading, please wait...</span>');
|
||||
$oPage->p('<input type="hidden" id="attachment_plugin"/>');
|
||||
$oPage->add('</fieldset>');
|
||||
|
||||
@@ -988,6 +988,11 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:Dashboard:Edit' => 'Edit This Page...',
|
||||
'UI:Dashboard:Revert' => 'Revert To Original Version...',
|
||||
'UI:Dashboard:RevertConfirm' => 'Every changes made to the original version will be lost. Please confirm that you want to do this.',
|
||||
'UI:ExportDashBoard' => 'Export to a file',
|
||||
'UI:ImportDashBoard' => 'Import from a file...',
|
||||
'UI:ImportDashboardTitle' => 'Import From a File',
|
||||
'UI:ImportDashboardText' => 'Select a dashboard file to import:',
|
||||
|
||||
|
||||
'UI:DashletCreation:Title' => 'Create a new Dashlet',
|
||||
'UI:DashletCreation:Dashboard' => 'Dashboard',
|
||||
|
||||
@@ -832,6 +832,10 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:Dashboard:Edit' => 'Editer cette page...',
|
||||
'UI:Dashboard:Revert' => 'Revenir à la version d\'origine...',
|
||||
'UI:Dashboard:RevertConfirm' => 'Toutes modifications apportées à la version d\'origine seront perdues. Veuillez confirmer l\'opération.',
|
||||
'UI:ExportDashBoard' => 'Exporter dans un fichier',
|
||||
'UI:ImportDashBoard' => 'Importer depuis un fichier...',
|
||||
'UI:ImportDashboardTitle' => 'Importation depuis un fichier',
|
||||
'UI:ImportDashboardText' => 'Choisissez un fichier de définition de tableau de bord :',
|
||||
|
||||
'UI:DashletCreation:Title' => 'Créer un Indicateur',
|
||||
'UI:DashletCreation:Dashboard' => 'Tableau de bord',
|
||||
|
||||
122
js/dashboard.js
122
js/dashboard.js
@@ -219,4 +219,124 @@ $(function()
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function UploadDashboard(oOptions)
|
||||
{
|
||||
var sFileId = 'dashboard_upload_file';
|
||||
var oDlg = $('<div id="dashboard_upload_dlg"><form><p>'+oOptions.text+'</p><p><input type="file" id="'+sFileId+'" name="dashboard_upload_file"></p></form></div>');
|
||||
$('body').append(oDlg);
|
||||
oOptions.file_id = sFileId;
|
||||
|
||||
oDlg.dashboard_upload_dlg(oOptions);
|
||||
}
|
||||
|
||||
|
||||
//jQuery UI style "widget" for managing a "import dashboard" dialog (file upload)
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where "itop" is the namespace,
|
||||
// "dashboard-upload-dlg" the widget name
|
||||
$.widget( "itop.dashboard_upload_dlg",
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
dashboard_id: '',
|
||||
file_id: '',
|
||||
text: 'Select a dashboard file to import',
|
||||
title: 'Dahsboard Import',
|
||||
close_btn: 'Close',
|
||||
submit_to: GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=import_dashboard'
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
var oButtons = {};
|
||||
oButtons[this.options.close_btn] = function() {
|
||||
me.element.dialog('close');
|
||||
//me.onClose();
|
||||
};
|
||||
$('#'+this.options.file_id).bind('change', function() { me._doUpload(); } );
|
||||
this.element
|
||||
.addClass('itop-dashboard_upload_dlg')
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 500,
|
||||
height: 'auto',
|
||||
title: this.options.title,
|
||||
close: function() { me._onClose(); },
|
||||
buttons: oButtons
|
||||
});
|
||||
},
|
||||
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('itop-dashboard_upload_dlg');
|
||||
|
||||
// call the original destroy method since we overwrote it
|
||||
$.Widget.prototype.destroy.call( this );
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
_setOptions: function()
|
||||
{
|
||||
// in 1.9 would use _superApply
|
||||
$.Widget.prototype._setOptions.apply( this, arguments );
|
||||
this._refresh();
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
// in 1.9 would use _super
|
||||
$.Widget.prototype._setOption.call( this, key, value );
|
||||
},
|
||||
_onClose: function()
|
||||
{
|
||||
this.element.remove();
|
||||
},
|
||||
_doUpload: function()
|
||||
{
|
||||
var me = this;
|
||||
$.ajaxFileUpload
|
||||
(
|
||||
{
|
||||
url: me.options.submit_to+'&id='+me.options.dashboard_id,
|
||||
secureuri:false,
|
||||
fileElementId: me.options.file_id,
|
||||
dataType: 'json',
|
||||
success: function (data, status)
|
||||
{
|
||||
if(typeof(data.error) != 'undefined')
|
||||
{
|
||||
if(data.error != '')
|
||||
{
|
||||
alert(data.error);
|
||||
me.element.dialog('close');
|
||||
}
|
||||
else
|
||||
{
|
||||
me.element.dialog('close');
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (data, status, e)
|
||||
{
|
||||
alert(e);
|
||||
me.element.dialog('close');
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -820,6 +820,56 @@ try
|
||||
}
|
||||
break;
|
||||
|
||||
case 'export_dashboard':
|
||||
$sMenuId = utils::ReadParam('id', '');
|
||||
ApplicationMenu::LoadAdditionalMenus();
|
||||
$index = ApplicationMenu::GetMenuIndexById($sMenuId);
|
||||
$oMenu = ApplicationMenu::GetMenuNode($index);
|
||||
if ($oMenu instanceof DashboardMenuNode)
|
||||
{
|
||||
$oDashboard = $oMenu->GetDashboard();
|
||||
$sPreviousContent = ob_get_clean();
|
||||
if (trim($sPreviousContent) != '')
|
||||
{
|
||||
IssueLog::Error("Output already started before downloading file:\nContent was:'$sPreviousContent'\n");
|
||||
}
|
||||
$oPage->SetContentType('text/xml');
|
||||
$oPage->SetContentDisposition('attachment', $oMenu->GetLabel().'.xml');
|
||||
$oPage->add($oDashboard->ToXml());
|
||||
}
|
||||
break;
|
||||
|
||||
case 'import_dashboard':
|
||||
$sMenuId = utils::ReadParam('id', '');
|
||||
ApplicationMenu::LoadAdditionalMenus();
|
||||
$index = ApplicationMenu::GetMenuIndexById($sMenuId);
|
||||
$oMenu = ApplicationMenu::GetMenuNode($index);
|
||||
$aResult = array('error' => '');
|
||||
try
|
||||
{
|
||||
if ($oMenu instanceof DashboardMenuNode)
|
||||
{
|
||||
$oDoc = utils::ReadPostedDocument('dashboard_upload_file');
|
||||
$oDashboard = $oMenu->GetDashboard();
|
||||
$oDashboard->FromXml($oDoc->GetData());
|
||||
$oDashboard->Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult['error'] = 'Dashboard id="'.$sMenuId.'" not found.';
|
||||
}
|
||||
}
|
||||
catch(DOMException $e)
|
||||
{
|
||||
$aResult = array('error' => Dict::S('UI:Error:InvalidDashboardFile'));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$aResult = array('error' => $e->getMessage());
|
||||
}
|
||||
$oPage->add(json_encode($aResult));
|
||||
break;
|
||||
|
||||
default:
|
||||
$oPage->p("Invalid query.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user