#185 Navigation Breadcrumb - A beta version, based on the navigation history. Comments welcome!

SVN:trunk[4000]
This commit is contained in:
Romain Quetiez
2016-04-18 14:48:43 +00:00
parent f436cece4a
commit e27d61a525
15 changed files with 457 additions and 47 deletions

View File

@@ -1203,6 +1203,15 @@ EOF
$oNewCondition = Expression::FromOQL($sOQLCondition);
return $oNewCondition;
}
/**
* For the result to be meaningful, this function must be called AFTER GetRenderContent() (or Display())
* @return int
*/
public function GetDisplayedCount()
{
return $this->m_oSet->Count();
}
}
/**

View File

@@ -37,6 +37,11 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
private $m_sMessage;
private $m_sInitScript;
protected $m_oTabs;
protected $sBreadCrumbEntryId;
protected $sBreadCrumbEntryLabel;
protected $sBreadCrumbEntryDescription;
protected $sBreadCrumbEntryUrl;
protected $sBreadCrumbEntryIcon;
public function __construct($sTitle, $bPrintable = false)
{
@@ -45,6 +50,12 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
$this->sBreadCrumbEntryId = null;
$this->sBreadCrumbEntryLabel = null;
$this->sBreadCrumbEntryDescription = null;
$this->sBreadCrumbEntryUrl = null;
$this->sBreadCrumbEntryIcon = '';
$this->m_sMenu = "";
$this->m_sMessage = '';
$this->SetRootUrl(utils::GetAbsoluteUrlAppRoot());
@@ -55,7 +66,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_linked_stylesheet("../css/fg.menu.css");
$this->add_linked_stylesheet("../css/jquery.multiselect.css");
$this->add_linked_stylesheet("../css/magnific-popup.css");
$this->add_linked_script('../js/jquery.layout.min.js');
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
$this->add_linked_script("../js/jquery.treeview.js");
@@ -79,7 +90,8 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_linked_script('../js/ajaxfileupload.js');
$this->add_linked_script('../js/jquery.mousewheel.js');
$this->add_linked_script('../js/jquery.magnific-popup.min.js');
$this->add_linked_script('../js/breadcrumb.js');
$sSearchAny = addslashes(Dict::S('UI:SearchValue:Any'));
$sSearchNbSelected = addslashes(Dict::S('UI:SearchValue:NbSelected'));
@@ -244,7 +256,7 @@ EOF;
});
}
});
$('.resizable').filter(':visible').resizable();
}
catch(err)
@@ -517,7 +529,23 @@ EOF
}
EOF
);
}
}
/**
* @param string $sId Identifies the item, to search after it in the current breadcrumb
* @param string $sLabel Label of the breadcrumb item
* @param string $sDescription More information, displayed as a tooltip
* @param string $sUrl Specify a URL if the current URL as perceived on the browser side is not relevant
* @param string $sIcon Icon (relative or absolute) path that will be displayed next to the label
*/
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '')
{
$this->sBreadCrumbEntryId = $sId;
$this->sBreadCrumbEntryLabel = $sLabel;
$this->sBreadCrumbEntryDescription = $sDescription;
$this->sBreadCrumbEntryUrl = $sUrl;
$this->sBreadCrumbEntryIcon = $sIcon;
}
public function AddToMenu($sHtml)
{
@@ -643,7 +671,9 @@ EOF
'selectedList' => 1,
);
$sJSMultiselectOptions = json_encode($aMultiselectOptions);
$siTopInstanceId = json_encode(APPROOT);
$sNewEntry = is_null($this->sBreadCrumbEntryId) ? 'null' : json_encode(array('id' => $this->sBreadCrumbEntryId, 'url' => $this->sBreadCrumbEntryUrl, 'label' => htmlentities($this->sBreadCrumbEntryLabel, ENT_QUOTES, 'UTF-8'), 'description' => htmlentities($this->sBreadCrumbEntryDescription, ENT_QUOTES, 'UTF-8'), 'icon' => $this->sBreadCrumbEntryIcon));
$this->add_ready_script(
<<<EOF
// Since the event is only triggered when the hash changes, we need to trigger
@@ -655,6 +685,8 @@ EOF
$('.multiselect').multiselect($sJSMultiselectOptions);
$('#itop-breadcrumb').breadcrumb({itop_instance_id: $siTopInstanceId, new_entry: $sNewEntry});
FixSearchFormsDisposition();
EOF
@@ -897,7 +929,7 @@ EOF
if (!empty($sNorthPane))
{
$sNorthPane = '<div id="bottom-pane" class="ui-layout-north">'.$sNorthPane.'</div>';
$sNorthPane = '<div id="top-pane" class="ui-layout-north">'.$sNorthPane.'</div>';
}
if (!empty($sSouthPane))
@@ -944,13 +976,27 @@ EOF
$sHtml .= '</div>';
$sHtml .= '<div class="ui-layout-center">';
$sHtml .= ' <div id="top-bar" style="width:100%">';
$sHtml .= ' <div id="top-bar" class="ui-helper-clearfix" style="width:100%">';
$sHtml .= self::FilterXSS($sApplicationBanner);
$sHtml .= ' <table id="top-bar-table">';
$sHtml .= ' <tr>';
$sHtml .= ' <td id="top-bar-table-breadcrumb">';
$sHtml .= ' <div id="itop-breadcrumb"></div>';
$sHtml .= ' </td>';
$sHtml .= ' <td id="top-bar-table-search">';
$sHtml .= ' <div id="global-search"><form action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php"><table><tr><td></td><td><div id="global-search-area"><input id="global-search-input" type="text" name="text" placeholder="'.$sText.'"></input><div '.$sOnClick.' id="global-search-image"></div></div></td>';
//$sHtml .= '<td><input type="image" src="../images/searchBtn.png"/></a></td>';
$sHtml .= '<td><a id="help-link" href="'.$sOnlineHelpUrl.'" target="_blank"><img title="'.Dict::S('UI:Help').'" src="../images/help.png?itopversion='.ITOP_VERSION.'"/></td>';
$sHtml .= '<td>'.self::FilterXSS($sLogOffMenu).'</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
//echo '<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
$sHtml .= ' <td><a id="help-link" href="'.$sOnlineHelpUrl.'" target="_blank"><img title="'.Dict::S('UI:Help').'" src="../images/help.png?itopversion='.ITOP_VERSION.'"/></td>';
$sHtml .= ' <td>'.self::FilterXSS($sLogOffMenu).'</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
$sHtml .= ' </td>';
$sHtml .= ' </tr>';
$sHtml .= ' </table>';
// $sHtml .= ' <div id="global-search"><form action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php"><table><tr><td></td><td><div id="global-search-area"><input id="global-search-input" type="text" name="text" placeholder="'.$sText.'"></input><div '.$sOnClick.' id="global-search-image"></div></div></td>';
// $sHtml .= '<td><a id="help-link" href="'.$sOnlineHelpUrl.'" target="_blank"><img title="'.Dict::S('UI:Help').'" src="../images/help.png?itopversion='.ITOP_VERSION.'"/></td>';
// $sHtml .= '<td>'.self::FilterXSS($sLogOffMenu).'</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
// $sHtml .= ' <div id="itop-breadcrumb"></div>';
$sHtml .= ' </div>';
$sHtml .= ' <div class="ui-layout-content" style="overflow:auto;">';
$sHtml .= ' <!-- Beginning of page content -->';

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2010-2013 Combodo SARL
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
@@ -20,7 +20,7 @@
/**
* Construction and display of the application's main menu
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -296,6 +296,16 @@ class ApplicationMenu
$oAppContext = new ApplicationContext();
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
if ($sMenuId === null)
{
$sMenuId == self::GetDefaultMenuId();
}
return $sMenuId;
}
static public function GetDefaultMenuId()
{
static $sDefaultMenuId = null;
if (is_null($sDefaultMenuId))
{
// Make sure the root menu is sorted on 'rank'
usort(self::$aRootMenus, array('ApplicationMenu', 'CompareOnRank'));
@@ -303,10 +313,10 @@ class ApplicationMenu
$aChildren = self::$aMenusIndex[$oFirstGroup->GetIndex()]['children'];
usort($aChildren, array('ApplicationMenu', 'CompareOnRank'));
$oMenuNode = self::GetMenuNode($aChildren[0]['index']);
$sMenuId = $oMenuNode->GetMenuId();
$sDefaultMenuId = $oMenuNode->GetMenuId();
}
return $sMenuId;
}
return $sDefaultMenuId;
}
}
/**
@@ -339,6 +349,7 @@ abstract class MenuNode
{
protected $sMenuId;
protected $index;
protected $iParentIndex;
/**
* Properties reflecting how the node has been declared
@@ -379,6 +390,7 @@ abstract class MenuNode
public function __construct($sMenuId, $iParentIndex = -1, $fRank = 0, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null)
{
$this->sMenuId = $sMenuId;
$this->iParentIndex = $iParentIndex;
$this->aReflectionProperties = array();
if (strlen($sEnableClass) > 0)
{
@@ -411,7 +423,21 @@ abstract class MenuNode
public function GetLabel()
{
return Dict::S("Menu:$this->sMenuId+", "");
$sRet = Dict::S("Menu:$this->sMenuId+", "");
if ($sRet === '')
{
if ($this->iParentIndex != -1)
{
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
$sRet = $oParentMenu->GetTitle().' / '.$this->GetTitle();
}
else
{
$sRet = $this->GetTitle();
}
//$sRet = $this->GetTitle();
}
return $sRet;
}
public function GetIndex()
@@ -647,11 +673,12 @@ class OQLMenuNode extends MenuNode
$this->bSearch, // Search pane
true, // Search open
$oPage,
array_merge($this->m_aParams, $aExtraParams)
array_merge($this->m_aParams, $aExtraParams),
true
);
}
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array())
public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array(), $bEnableBreadcrumb = false)
{
$sUsageId = utils::GetSafeId($sUsageId);
$oSearch = DBObjectSearch::FromOQL($sOql);
@@ -669,6 +696,15 @@ class OQLMenuNode extends MenuNode
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
$oBlock->Display($oPage, $sUsageId);
if ($bEnableBreadcrumb && ($oPage instanceof iTopWebPage))
{
// Breadcrumb
//$iCount = $oBlock->GetDisplayedCount();
$sPageId = "ui-search-".$oSearch->GetClass();
$sLabel = MetaModel::GetName($oSearch->GetClass());
$oPage->SetBreadCrumbEntry($sPageId, $sLabel, $sTitle, '', '../images/breadcrumb-search.png');
}
}
}
@@ -920,6 +956,29 @@ EOF
$sId = addslashes($this->sMenuId);
$oPage->add_ready_script("EditDashboard('$sId');");
}
else
{
$oParentMenu = ApplicationMenu::GetMenuNode($this->iParentIndex);
$sParentTitle = $oParentMenu->GetTitle();
$sThisTitle = $this->GetTitle();
if ($sParentTitle != $sThisTitle)
{
$sDescription = $sParentTitle.' / '.$sThisTitle;
}
else
{
$sDescription = $sThisTitle;
}
if ($this->sMenuId == ApplicationMenu::GetDefaultMenuId())
{
$sIcon = '../images/breadcrumb_home.png';
}
else
{
$sIcon = '../images/breadcrumb-dashboard.png';
}
$oPage->SetBreadCrumbEntry("ui-dashboard-".$this->sMenuId, $this->GetTitle(), $sDescription, '', $sIcon);
}
}
else
{
@@ -950,7 +1009,7 @@ EOF
}
else
{
$oPage->p("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
}
}

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2010-2013 Combodo SARL
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
@@ -21,7 +21,7 @@
* Persistent class Shortcut and derived
* Shortcuts of any kind
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -200,7 +200,7 @@ class ShortcutOQL extends Shortcut
$bSearchOpen = false;
try
{
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams);
OQLMenuNode::RenderOQLSearch($this->Get('oql'), $this->Get('name'), 'shortcut_'.$this->GetKey(), $bSearchPane, $bSearchOpen, $oPage, $aExtraParams, true);
}
catch (Exception $e)
{

View File

@@ -1151,7 +1151,6 @@ div#logo div {
#top-bar {
height: 55px;
background: #f1f1f1;
text-align: right;
}
@@ -2201,3 +2200,71 @@ span.refresh-button {
}
#top-bar-table {
width: 100%;
}
#top-bar-table #top-bar-table-search {
width: 347px;
}
#itop-breadcrumb {
overflow: hidden;
float: left;
background: #f1f1f1;
margin-left: -20px;
}
#itop-breadcrumb li {
list-style: none;
float: left;
margin: 0 22px 6px 0;
}
#itop-breadcrumb li .icon img {
height: 15px;
width: auto;
margin-right: 5px;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray;
filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
opacity: 0.5;
}
#itop-breadcrumb li:hover .icon img {
-webkit-filter: none;
filter: none;
opacity: 1;
}
#itop-breadcrumb li a {
text-decoration: none;
color: #555555;
font-size: 9pt;
padding: 0;
background: none;
}
#itop-breadcrumb li a span.truncate {
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
#itop-breadcrumb li a:hover {
text-decoration: none;
color: #e87c1e;
}
#itop-breadcrumb li a::after {
content: '';
position: absolute;
background-image: url(../images/breadcrumb-separator.png?v=v2.2.0);
background-repeat: no-repeat;
width: 8px;
height: 16px;
margin-left: 5px;
}
#itop-breadcrumb li:last-child a::after {
display: none;
}

View File

@@ -8,6 +8,10 @@ $popup-menu-highlight-color = $highlight-color;
$popup-menu-text-color: #000;
$popup-menu-background-color: #fff;
$popup-menu-text-higlight-color: #fff;
$breadcrumb-color: #555;
$breadcrumb-text-color: #fff;
$breadcrumb-highlight-color: $highlight-color;
$breadcrumb-text-highlight-color: #fff;
/* CSS Document */
body {
@@ -868,7 +872,6 @@ div#logo div {
overflow: hidden;
}
#top-bar {
height: 55px;
background: $frame-background-color;
text-align: right;
}
@@ -1615,4 +1618,80 @@ span.refresh-button {
}
.history_entry_truncated .history_truncated_toggler {
background-position: 0 -192px;
}
}
#top-bar-table {
width: 100%;
#top-bar-table-search{
width: 347px;
}
}
#itop-breadcrumb{
overflow: hidden;
float: left;
background: $frame-background-color;
margin-left: -20px;
li{
list-style: none;
float: left;
margin: 0 22px 6px 0;
.icon img{
height: 15px;
width: auto;
margin-right: 5px;
-webkit-filter: unquote("grayscale(100%)");
filter: unquote("grayscale(100%)");
filter: unquote("gray");
filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
// IE has no filter option: at least, have some effect when hovering...
opacity: 0.5;
}
&:hover .icon img{
-webkit-filter: none;
filter: none;
opacity: 1;
}
a{
text-decoration: none;
color: #555;
font-size: 9pt;
padding: 0;
background: none;
span.truncate
{
// Ellipsis
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
&:hover{
text-decoration: none;
color: $highlight-color;
}
&::after{
content:'';
position: absolute;
background-image: url(../images/breadcrumb-separator.png?v=#{$version});
background-repeat: no-repeat;
width: 8px;
height: 16px;
margin-left: 5px;
}
}
&:last-child a::after{
display: none;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

BIN
images/breadcrumb_home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

111
js/breadcrumb.js Normal file
View File

@@ -0,0 +1,111 @@
//iTop Form field
;
$(function()
{
// the widget definition, where 'itop' is the namespace,
// 'breadcrumb' the widget name
$.widget( 'itop.breadcrumb',
{
// default options
options:
{
itop_instance_id: '',
new_entry: null,
},
// the constructor
_create: function()
{
var me = this;
this.element
.addClass('breadcrumb');
if(typeof(Storage) !== "undefined")
{
var sBreadCrumbStorageKey = this.options.itop_instance_id + 'breadcrumb-v1';
var aBreadCrumb = [];
var sBreadCrumbData = sessionStorage.getItem(sBreadCrumbStorageKey);
if (sBreadCrumbData !== null)
{
aBreadCrumb = JSON.parse(sBreadCrumbData);
}
var iDisplayableItems = aBreadCrumb.length;
if (this.options.new_entry !== null) {
var sUrl = this.options.new_entry.url;
if (sUrl.length == 0) {
sUrl = window.location.href;
}
// Eliminate items having the same id, before appending the new item
var aBreadCrumb = $.grep(aBreadCrumb, function(item, ipos){
if (item.id == me.options.new_entry.id) return false;
else return true;
});
aBreadCrumb.push({
id: this.options.new_entry.id,
label: this.options.new_entry.label,
description: this.options.new_entry.description,
icon: this.options.new_entry.icon,
url: sUrl
});
// Keep only the last N items
aBreadCrumb = aBreadCrumb.slice(-8);
// Do not show the last = current item
iDisplayableItems = aBreadCrumb.length - 1;
}
sBreadCrumbData = JSON.stringify(aBreadCrumb);
sessionStorage.setItem(sBreadCrumbStorageKey, sBreadCrumbData);
var sBreadCrumbHtml = '<ul>';
for (iEntry in aBreadCrumb)
{
//if (iEntry >= iDisplayableItems) break; // skip the current page
var oEntry = aBreadCrumb[iEntry];
if (oEntry['label'].length > 0)
{
var sIconSpec = '';
if (oEntry['icon'].length > 0)
{
sIconSpec = '<span class="icon"><img src="'+oEntry['icon']+'"/></span>';
}
var sTitle = oEntry['description'];
if (sTitle.length == 0) {
sTitle = oEntry['label'];
}
sBreadCrumbHtml += '<li><a class="itop-breadcrumb-link" breadcrumb-entry="'+iEntry+'" href="'+oEntry['url']+'" title="'+sTitle+'">'+sIconSpec+'<span class="truncate">'+oEntry['label']+'</span></a></li>';
}
}
sBreadCrumbHtml += '</ul>';
$('#itop-breadcrumb').html(sBreadCrumbHtml);
}
else
{
// Sorry! No Web Storage support..
//$('#itop-breadcrumb').html('<span style="display:none;">Session storage not available for the current browser</span>');
}
},
// 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('breadcrumb');
},
// _setOptions is called with a hash of all options that are changing
// always refresh when changing options
_setOptions: function()
{
this._superApply(arguments);
},
// _setOption is called for each individual option that is changing
_setOption: function( key, value )
{
this._super( key, value );
}
});
});

View File

@@ -20,7 +20,7 @@
/**
* Main page of iTop
*
* @copyright Copyright (C) 2010-2015 Combodo SARL
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -174,6 +174,12 @@ function DisplaySearchSet($oP, $oFilter, $bSearchForm = true, $sBaseClass = '',
{
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oP, 1);
// Breadcrumb
//$iCount = $oBlock->GetDisplayedCount();
$sPageId = "ui-search-".$oFilter->GetClass();
$sLabel = MetaModel::GetName($oFilter->GetClass());
$oP->SetBreadCrumbEntry($sPageId, $sLabel, '', '', '../images/breadcrumb-search.png');
}
}
}
@@ -356,11 +362,13 @@ try
}
if (!is_null($oObj))
{
$sClass = get_class($oObj); // get the leaf class
$oP->SetBreadCrumbEntry("ui-details-$sClass-$id", $oObj->Get('friendlyname'), $sClass.': '.$oObj->Get('friendlyname'), '', MetaModel::GetClassIcon($sClass, false));
DisplayDetails($oP, $sClass, $oObj, $id);
}
}
break;
case 'release_lock_and_details':
$sClass = utils::ReadParam('class', '');
$id = utils::ReadParam('id', '');
@@ -414,19 +422,19 @@ try
///////////////////////////////////////////////////////////////////////////////////////////
case 'search_form': // Search form
$sClass = utils::ReadParam('class', '', false, 'class');
$sFormat = utils::ReadParam('format', 'html');
$bSearchForm = utils::ReadParam('search_form', true);
$bDoSearch = utils::ReadParam('do_search', true);
if (empty($sClass))
{
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
}
$oP->set_title(Dict::S('UI:SearchResultsPageTitle'));
$oFilter = new DBObjectSearch($sClass);
DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat, $bDoSearch);
break;
$sClass = utils::ReadParam('class', '', false, 'class');
$sFormat = utils::ReadParam('format', 'html');
$bSearchForm = utils::ReadParam('search_form', true);
$bDoSearch = utils::ReadParam('do_search', true);
if (empty($sClass))
{
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
}
$oP->set_title(Dict::S('UI:SearchResultsPageTitle'));
$oFilter = new DBObjectSearch($sClass);
DisplaySearchSet($oP, $oFilter, $bSearchForm, '' /* sBaseClass */, $sFormat, $bDoSearch);
break;
///////////////////////////////////////////////////////////////////////////////////////////
case 'search': // Serialized DBSearch
@@ -1633,7 +1641,7 @@ catch(Exception $e)
require_once(APPROOT.'/setup/setuppage.class.inc.php');
$oP = new SetupPage(Dict::S('UI:PageTitle:FatalError'));
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
$oP->output();
if (MetaModel::IsLogEnabledIssue())

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2010-2015 Combodo SARL
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
@@ -20,7 +20,7 @@
/**
* Analytical search
*
* @copyright Copyright (C) 2010-2015 Combodo SARL
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -113,7 +113,13 @@ if ($oFilter != null)
// Search results
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
$oResultBlock->Display($oP, 1);
// Breadcrumb
//$iCount = $oBlock->GetDisplayedCount();
$sPageId = "ui-search-".$oFilter->GetClass();
$sLabel = MetaModel::GetName($oFilter->GetClass());
$oP->SetBreadCrumbEntry($sPageId, $sLabel, '', '', '../images/breadcrumb-search.png');
// Menu node
$sFilter = $oFilter->ToOQL();
$oP->add("\n<!-- $sFilter -->\n");

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2013 Combodo SARL
// Copyright (C) 2013-2016 Combodo SARL
//
// This file is part of iTop.
//
@@ -20,7 +20,7 @@
/**
* Page to configuration the notifications (triggers and actions)
*
* @copyright Copyright (C) 2013 Combodo SARL
* @copyright Copyright (C) 2013-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -43,6 +43,8 @@ $oP->add('<div class="page_header" style="padding:0.5em;">');
$oP->add('<h1>'.dict::S('UI:NotificationsMenu:Title').'</h1>');
$oP->add('</div>');
$oP->SetBreadCrumbEntry('ui-tool-notifications', Dict::S('Menu:NotificationsMenu'), Dict::S('Menu:NotificationsMenu+'), '', '../images/bell.png');
$oP->StartCollapsibleSection(Dict::S('UI:NotificationsMenu:Help'), true);
$oP->add('<div style="padding: 1em; font-size:10pt;background:#E8F3CF;margin-top: 0.25em;">');
$oP->add('<img src="../images/bell.png" style="margin-top: -60px; margin-right: 10px; float: right;">');

View File

@@ -192,6 +192,29 @@ try
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
$oResultBlock->Display($oP, 'runquery');
// Breadcrumb
//$iCount = $oResultBlock->GetDisplayedCount();
$sPageId = "ui-search-".$oFilter->GetClass();
$sLabel = MetaModel::GetName($oFilter->GetClass());
$aArgs = array();
foreach (array_merge($_POST, $_GET) as $sKey => $value)
{
if (is_array($value))
{
$aItems = array();
foreach($value as $sItemKey => $sItemValue)
{
$aArgs[] = $sKey.'['.$sItemKey.']='.urlencode($sItemValue);
}
}
else
{
$aArgs[] = $sKey.'='.urlencode($value);
}
}
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/run_query.php?'.implode('&', $aArgs);
$oP->SetBreadCrumbEntry($sPageId, $sLabel, $oFilter->ToOQL(true), $sUrl, '../images/breadcrumb-search.png');
$oP->p('');
$oP->StartCollapsibleSection(Dict::S('UI:RunQuery:MoreInfo'), false);
$oP->p(Dict::S('UI:RunQuery:DevelopedQuery').htmlentities($oFilter->ToOQL(), ENT_QUOTES, 'UTF-8'));