N°4076 - Allow block parameters to change the behaviour of blocks on the page

This commit is contained in:
Eric
2021-07-26 17:20:22 +02:00
parent bfcfcdd4cc
commit 344cce9fdd
11 changed files with 126 additions and 77 deletions

View File

@@ -547,31 +547,24 @@ try
// Save search to history // Save search to history
// - Prepare icon // - Prepare icon
$sQueryIconUrl = null; $sQueryIconUrl = null;
if(!empty($sClassName)) if(!empty($sClassName)) {
{
$sQueryIconUrl = MetaModel::GetClassIcon($sClassName, false); $sQueryIconUrl = MetaModel::GetClassIcon($sClassName, false);
} }
// - Prepare label // - Prepare label
$sQueryLabel = null; $sQueryLabel = null;
if($sQuery !== $sFullText) if ($sQuery !== $sFullText) {
{
$sQueryLabel = $sFullText; $sQueryLabel = $sFullText;
} }
GlobalSearchHelper::AddQueryToHistory($sQuery, $sQueryIconUrl, $sQueryLabel); GlobalSearchHelper::AddQueryToHistory($sQuery, $sQueryIconUrl, $sQueryLabel);
$oP->GetTopBarLayout() $oP->AddBlockParam('global_search.query', $sQuery);
->GetGlobalSearch()
->SetQuery($sQuery)
->SetLastQueries(GlobalSearchHelper::GetLastQueries());
// Check the needle length // Check the needle length
$iMinLenth = MetaModel::GetConfig()->Get('full_text_needle_min'); $iMinLenth = MetaModel::GetConfig()->Get('full_text_needle_min');
foreach ($aFullTextNeedles as $sNeedle) foreach ($aFullTextNeedles as $sNeedle) {
{ if (strlen($sNeedle) < $iMinLenth) {
if (strlen($sNeedle) < $iMinLenth)
{
$oP->p(Dict::Format('UI:Search:NeedleTooShort', $sNeedle, $iMinLenth)); $oP->p(Dict::Format('UI:Search:NeedleTooShort', $sNeedle, $iMinLenth));
$key = array_search($sNeedle, $aFullTextNeedles); $key = array_search($sNeedle, $aFullTextNeedles);
if($key!== false) if ($key !== false)
{ {
unset($aFullTextNeedles[$key]); unset($aFullTextNeedles[$key]);
} }

View File

@@ -65,6 +65,7 @@ abstract class Controller
private $m_aLinkedStylesheets; private $m_aLinkedStylesheets;
private $m_aSaas; private $m_aSaas;
private $m_aAjaxTabs; private $m_aAjaxTabs;
private $m_aBlockParams;
/** @var string */ /** @var string */
private $m_sAccessTokenConfigParamId = null; private $m_sAccessTokenConfigParamId = null;
@@ -76,21 +77,19 @@ abstract class Controller
*/ */
public function __construct($sViewPath, $sModuleName = 'core') public function __construct($sViewPath, $sModuleName = 'core')
{ {
$this->m_aLinkedScripts = array(); $this->m_aLinkedScripts = [];
$this->m_aLinkedStylesheets = array(); $this->m_aLinkedStylesheets = [];
$this->m_aSaas = array(); $this->m_aSaas = [];
$this->m_aAjaxTabs = array(); $this->m_aAjaxTabs = [];
$this->m_aDefaultParams = array(); $this->m_aDefaultParams = [];
$this->m_aBlockParams = [];
$this->SetViewPath($sViewPath); $this->SetViewPath($sViewPath);
$this->SetModuleName($sModuleName); $this->SetModuleName($sModuleName);
if ($sModuleName != 'core') if ($sModuleName != 'core') {
{ try {
try $this->m_aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
{
$this->m_aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'));
} }
catch (Exception $e) catch (Exception $e) {
{
IssueLog::Error($e->getMessage()); IssueLog::Error($e->getMessage());
} }
} }
@@ -392,6 +391,9 @@ abstract class Controller
foreach ($this->m_aSaas as $sSaasRelPath) { foreach ($this->m_aSaas as $sSaasRelPath) {
$this->AddSaasToPage($sSaasRelPath); $this->AddSaasToPage($sSaasRelPath);
} }
foreach ($this->m_aBlockParams as $sKey => $value) {
$this->SetBlockParamToPage($sKey, $value);
}
$this->OutputPage(); $this->OutputPage();
} }
@@ -550,13 +552,20 @@ abstract class Controller
*/ */
public function AddAjaxTab($sCode, $sURL, $bCache = true, $sLabel = null) public function AddAjaxTab($sCode, $sURL, $bCache = true, $sLabel = null)
{ {
if (is_null($sLabel)) if (is_null($sLabel)) {
{
$sLabel = Dict::S($sCode); $sLabel = Dict::S($sCode);
} }
$this->m_aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache); $this->m_aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache);
} }
/**
* @param array $aBlockParams
*/
public function AddBlockParams(array $aBlockParams)
{
$this->m_aBlockParams = $aBlockParams;
}
/** /**
* @param $aParams * @param $aParams
* @param $sName * @param $sName
@@ -595,7 +604,7 @@ abstract class Controller
switch ($sPageType) switch ($sPageType)
{ {
case self::ENUM_PAGE_TYPE_HTML: case self::ENUM_PAGE_TYPE_HTML:
$this->m_oPage = new iTopWebPage($this->GetOperationTitle()); $this->m_oPage = new iTopWebPage($this->GetOperationTitle(), false);
$this->m_oPage->add_xframe_options(); $this->m_oPage->add_xframe_options();
break; break;
@@ -679,6 +688,11 @@ abstract class Controller
$this->m_oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle); $this->m_oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle);
} }
public function SetBlockParamToPage(string $sKey, $value)
{
$this->m_oPage->SetBlockParam($sKey, $value);
}
/** /**
* @throws \Exception * @throws \Exception
*/ */

View File

@@ -70,8 +70,8 @@ class GlobalSearch extends UIBlock implements iKeyboardShortcut
$this->SetEndpoint(static::DEFAULT_ENDPOINT_REL_URL); $this->SetEndpoint(static::DEFAULT_ENDPOINT_REL_URL);
$this->SetQuery(''); $this->SetQuery('');
$this->SetLastQueries($aLastQueries); $this->SetLastQueries($aLastQueries);
$this->bShowHistory = (bool) MetaModel::GetConfig()->Get('global_search.show_history'); $this->bShowHistory = (bool)MetaModel::GetConfig()->Get('global_search.show_history');
$this->iMaxHistoryResults = (int) MetaModel::GetConfig()->Get('global_search.max_history_results'); $this->iMaxHistoryResults = (int)MetaModel::GetConfig()->Get('global_search.max_history_results');
} }
/** /**

View File

@@ -41,6 +41,7 @@ class TopBarFactory
* @param array|null $aBreadcrumbsEntry Current breadcrumbs entry to add * @param array|null $aBreadcrumbsEntry Current breadcrumbs entry to add
* *
* @return \Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBar * @return \Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBar
* @throws \ConfigException
* @throws \CoreException * @throws \CoreException
* @throws \CoreUnexpectedValue * @throws \CoreUnexpectedValue
* @throws \MySQLException * @throws \MySQLException
@@ -49,18 +50,15 @@ class TopBarFactory
{ {
$oTopBar = new TopBar(TopBar::BLOCK_CODE); $oTopBar = new TopBar(TopBar::BLOCK_CODE);
if (utils::GetConfig()->Get('quick_create.enabled') === true) if (utils::GetConfig()->Get('quick_create.enabled') === true) {
{
$oTopBar->SetQuickCreate(QuickCreateFactory::MakeFromUserHistory()); $oTopBar->SetQuickCreate(QuickCreateFactory::MakeFromUserHistory());
} }
if (utils::GetConfig()->Get('global_search.enabled') === true) if (utils::GetConfig()->Get('global_search.enabled') === true) {
{
$oTopBar->SetGlobalSearch(GlobalSearchFactory::MakeFromUserHistory()); $oTopBar->SetGlobalSearch(GlobalSearchFactory::MakeFromUserHistory());
} }
if(utils::GetConfig()->Get('breadcrumb.enabled') === true) if (utils::GetConfig()->Get('breadcrumb.enabled') === true) {
{
$oBreadcrumbs = new Breadcrumbs($aBreadcrumbsEntry, Breadcrumbs::BLOCK_CODE); $oBreadcrumbs = new Breadcrumbs($aBreadcrumbsEntry, Breadcrumbs::BLOCK_CODE);
$oTopBar->SetBreadcrumbs($oBreadcrumbs); $oTopBar->SetBreadcrumbs($oBreadcrumbs);

View File

@@ -177,25 +177,27 @@ class AjaxPage extends WebPage implements iTabbedPage
$aData['aPage'] = [ $aData['aPage'] = [
'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()), 'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()),
'sTitle' => $this->s_title, 'sTitle' => $this->s_title,
'aMetadata' => [ 'aMetadata' => [
'sCharset' => static::PAGES_CHARSET, 'sCharset' => static::PAGES_CHARSET,
'sLang' => $this->GetLanguageForMetadata(), 'sLang' => $this->GetLanguageForMetadata(),
], ],
'aCssFiles' => $this->a_linked_stylesheets, 'aCssFiles' => $this->a_linked_stylesheets,
'aCssInline' => $this->a_styles, 'aCssInline' => $this->a_styles,
'aJsFiles' => $this->a_linked_scripts, 'aJsFiles' => $this->a_linked_scripts,
'aJsInlineLive' => $this->a_scripts, 'aJsInlineLive' => $this->a_scripts,
'aJsInlineOnDomReady' => $this->GetReadyScripts(), 'aJsInlineOnDomReady' => $this->GetReadyScripts(),
'aJsInlineOnInit' => $this->a_init_scripts, 'aJsInlineOnInit' => $this->a_init_scripts,
'bEscapeContent' => ($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'), 'bEscapeContent' => ($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'),
// TODO 3.0.0: TEMP, used while developping, remove it. // TODO 3.0.0: TEMP, used while developping, remove it.
'sSanitizedContent' => utils::FilterXSS($this->s_content), 'sSanitizedContent' => utils::FilterXSS($this->s_content),
'sDeferredContent' => utils::FilterXSS(addslashes(str_replace("\n", '', $this->s_deferred_content))), 'sDeferredContent' => utils::FilterXSS(addslashes(str_replace("\n", '', $this->s_deferred_content))),
'sCapturedOutput' => utils::FilterXSS($s_captured_output), 'sCapturedOutput' => utils::FilterXSS($s_captured_output),
'sPromiseId' => $this->sPromiseId 'sPromiseId' => $this->sPromiseId,
]; ];
$aData['aBlockParams'] = $this->GetBlockParams();
$oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS); $oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS);
// Render final TWIG into global HTML // Render final TWIG into global HTML
$oKpi = new ExecutionKPI(); $oKpi = new ExecutionKPI();

View File

@@ -30,7 +30,7 @@ class NiceWebPage extends WebPage
$this->m_sRootUrl = $this->GetAbsoluteUrlAppRoot(); $this->m_sRootUrl = $this->GetAbsoluteUrlAppRoot();
parent::__construct($s_title, $bPrintable); parent::__construct($s_title, $bPrintable);
$this->LoadTheme(); $this->LoadTheme();
} }
/** /**

View File

@@ -99,6 +99,8 @@ class WebPage implements Page
protected $a_styles; protected $a_styles;
/** @var array Stylesheets linked (external) to the page through URIs */ /** @var array Stylesheets linked (external) to the page through URIs */
protected $a_linked_stylesheets; protected $a_linked_stylesheets;
/** @var array Parameters to be used by page blocks */
protected $aBlockParams;
protected $a_headers; protected $a_headers;
protected $a_base; protected $a_base;
protected $iNextId; protected $iNextId;
@@ -133,7 +135,7 @@ class WebPage implements Page
* @param string $s_title * @param string $s_title
* @param bool $bPrintable * @param bool $bPrintable
*/ */
public function __construct($s_title, $bPrintable = false) public function __construct(string $s_title, bool $bPrintable = false)
{ {
$this->s_title = $s_title; $this->s_title = $s_title;
$this->s_content = ""; $this->s_content = "";
@@ -146,8 +148,8 @@ class WebPage implements Page
$this->InitializeDictEntries(); $this->InitializeDictEntries();
$this->InitializeStyles(); $this->InitializeStyles();
$this->InitializeLinkedStylesheets(); $this->InitializeLinkedStylesheets();
$this->a_headers = array(); $this->a_headers = [];
$this->a_base = array('href' => '', 'target' => ''); $this->a_base = ['href' => '', 'target' => ''];
$this->iNextId = 0; $this->iNextId = 0;
$this->iTransactionId = 0; $this->iTransactionId = 0;
$this->sContentType = ''; $this->sContentType = '';
@@ -155,7 +157,8 @@ class WebPage implements Page
$this->sContentFileName = ''; $this->sContentFileName = '';
$this->bTrashUnexpectedOutput = false; $this->bTrashUnexpectedOutput = false;
$this->s_OutputFormat = utils::ReadParam('output_format', 'html'); $this->s_OutputFormat = utils::ReadParam('output_format', 'html');
$this->a_OutputOptions = array(); $this->a_OutputOptions = [];
$this->aBlockParams = [];
$this->bHasCollapsibleSection = false; $this->bHasCollapsibleSection = false;
$this->bPrintable = $bPrintable; $this->bPrintable = $bPrintable;
$this->bAddJSDict = true; $this->bAddJSDict = true;
@@ -1168,24 +1171,26 @@ JS;
// Base structure of data to pass to the TWIG template // Base structure of data to pass to the TWIG template
$aData['aPage'] = [ $aData['aPage'] = [
'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()), 'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()),
'sTitle' => $this->s_title, 'sTitle' => $this->s_title,
'aMetadata' => [ 'aMetadata' => [
'sCharset' => static::PAGES_CHARSET, 'sCharset' => static::PAGES_CHARSET,
'sLang' => $this->GetLanguageForMetadata(), 'sLang' => $this->GetLanguageForMetadata(),
], ],
'aCssFiles' => $this->a_linked_stylesheets, 'aCssFiles' => $this->a_linked_stylesheets,
'aCssInline' => $this->a_styles, 'aCssInline' => $this->a_styles,
'aJsInlineEarly' => $this->a_early_scripts, 'aJsInlineEarly' => $this->a_early_scripts,
'aJsFiles' => $this->a_linked_scripts, 'aJsFiles' => $this->a_linked_scripts,
'aJsInlineLive' => $this->a_scripts, 'aJsInlineLive' => $this->a_scripts,
'aJsInlineOnDomReady' => $this->GetReadyScripts(), 'aJsInlineOnDomReady' => $this->GetReadyScripts(),
'aJsInlineOnInit' => $this->a_init_scripts, 'aJsInlineOnInit' => $this->a_init_scripts,
// TODO 3.0.0: TEMP, used while developing, remove it. // TODO 3.0.0: TEMP, used while developing, remove it.
'sCapturedOutput' => utils::FilterXSS($s_captured_output), 'sCapturedOutput' => utils::FilterXSS($s_captured_output),
'sDeferredContent' => utils::FilterXSS($this->s_deferred_content), 'sDeferredContent' => utils::FilterXSS($this->s_deferred_content),
]; ];
$aData['aBlockParams'] = $this->GetBlockParams();
if ($this->a_base['href'] != '') { if ($this->a_base['href'] != '') {
$aData['aPage']['aMetadata']['sBaseUrl'] = $this->a_base['href']; $aData['aPage']['aMetadata']['sBaseUrl'] = $this->a_base['href'];
} }
@@ -1602,4 +1607,25 @@ EOD
{ {
return $this->sTemplateRelPath; return $this->sTemplateRelPath;
} }
/**
* @return array
*/
public function GetBlockParams(): array
{
return $this->aBlockParams;
}
/**
* @param string $sKey
* @param $value
*
* @return $this
*/
public function SetBlockParam(string $sKey, $value)
{
$this->aBlockParams[$sKey] = $value;
return $this;
}
} }

View File

@@ -72,7 +72,11 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
* @param string $sTitle * @param string $sTitle
* @param bool $bPrintable * @param bool $bPrintable
* *
* @throws \Exception * @throws \ConfigException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DictExceptionMissingString
* @throws \MySQLException
*/ */
public function __construct($sTitle, $bPrintable = false) public function __construct($sTitle, $bPrintable = false)
{ {
@@ -102,10 +106,9 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET); $this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET);
$this->no_cache(); $this->no_cache();
$this->add_xframe_options(); $this->add_xframe_options();
if (!$this->IsPrintableVersion()) if (!$this->IsPrintableVersion()) {
{
$this->PrepareLayout(); $this->PrepareLayout();
} else{ } else {
$oPrintHeader = $this->OutputPrintable(); $oPrintHeader = $this->OutputPrintable();
$this->AddUiBlock($oPrintHeader); $this->AddUiBlock($oPrintHeader);
} }
@@ -800,16 +803,18 @@ HTML;
// Base structure of data to pass to the TWIG template // Base structure of data to pass to the TWIG template
$aData['aPage'] = [ $aData['aPage'] = [
'sAbsoluteUrlAppRoot' => $sAbsoluteUrlAppRoot, 'sAbsoluteUrlAppRoot' => $sAbsoluteUrlAppRoot,
'sTitle' => $this->s_title, 'sTitle' => $this->s_title,
'sFaviconUrl' => $sFaviconUrl, 'sFaviconUrl' => $sFaviconUrl,
'aMetadata' => [ 'aMetadata' => [
'sCharset' => static::PAGES_CHARSET, 'sCharset' => static::PAGES_CHARSET,
'sLang' => $sMetadataLanguage, 'sLang' => $sMetadataLanguage,
], ],
'oPrintHeader' => $oPrintHeader, 'oPrintHeader' => $oPrintHeader,
'isPrintable' => $this->IsPrintableVersion(), 'isPrintable' => $this->IsPrintableVersion(),
]; ];
$aData['aBlockParams'] = $this->GetBlockParams();
// Base tag // Base tag
// Note: We might consider to put the app_root_url parameter here, but that would need a BIG rework on iTop AND the extensions to replace all the "../images|js|css/xxx.yyy"... // Note: We might consider to put the app_root_url parameter here, but that would need a BIG rework on iTop AND the extensions to replace all the "../images|js|css/xxx.yyy"...
if (!empty($this->a_base['href'])) { if (!empty($this->a_base['href'])) {
@@ -1167,4 +1172,17 @@ EOF
return $oBlock; return $oBlock;
} }
public function SetBlockParam(string $sKey, $value)
{
$oGlobalSearch = $this->GetTopBarLayout()->GetGlobalSearch();
$sGlobalSearchId = $oGlobalSearch->GetId();
switch ($sKey) {
case "$sGlobalSearchId.sQuery":
$oGlobalSearch->SetQuery($value);
break;
}
return parent::SetBlockParam($sKey, $value); // TODO: Change the autogenerated stub
}
} }

View File

@@ -53,4 +53,3 @@ class iTopWizardWebPage extends iTopWebPage
parent::output(); parent::output();
} }
} }
?>

View File

@@ -1,7 +1,7 @@
<div id="{{ oUIBlock.GetId() }}" <div id="{{ oUIBlock.GetId() }}"
{# Note: The "ibo-is-opened" class is put there and not through the JS widget to avoid visual glitches #} {# Note: The "ibo-is-opened" class is put there and not through the JS widget to avoid visual glitches #}
{# Otherwise it would open only when the DOM is ready and the JS widget instantiated #} {# Otherwise it would open only when the DOM is ready and the JS widget instantiated #}
class="ibo-global-search {% if oUIBlock.HasQuery() %}ibo-is-opened{% endif %}" class="ibo-global-search"
data-role="ibo-global-search"> data-role="ibo-global-search">
<form action="{{ oUIBlock.GetEndpoint() }}" method="get" class="ibo-global-search--head" data-role="ibo-global-search--head"> <form action="{{ oUIBlock.GetEndpoint() }}" method="get" class="ibo-global-search--head" data-role="ibo-global-search--head">
<a href="#" class="ibo-global-search--icon" data-role="ibo-global-search--icon" <a href="#" class="ibo-global-search--icon" data-role="ibo-global-search--icon"

View File

@@ -1,3 +1,2 @@
$('#{{ oUIBlock.GetId() }}').global_search({ $('#{{ oUIBlock.GetId() }}').global_search({
init_opened: {{ oUIBlock.HasQuery()|var_export }}
}); });