N°2847 - Dashlet header dynamic and badges

This commit is contained in:
Eric
2020-10-29 15:20:44 +01:00
parent 3548d5e264
commit 6c7efb2448
21 changed files with 538 additions and 191 deletions

View File

@@ -16,6 +16,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\UI\Component\Panel\PanelFactory;
require_once(APPROOT.'application/forms.class.inc.php');
/**
@@ -2056,8 +2058,7 @@ class DashletHeaderDynamic extends Dashlet
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$aValues = $this->GetValues();
if (count($aValues) > 0)
{
if (count($aValues) > 0) {
// Stats grouped by <group_by>
$sCSV = implode(',', $aValues);
$aParams = array(
@@ -2067,9 +2068,7 @@ class DashletHeaderDynamic extends Dashlet
'status_codes[block]' => $sCSV,
'context_filter' => 1,
);
}
else
{
} else {
// Simple stats
$aParams = array(
'title[block]' => $sTitle,
@@ -2078,31 +2077,31 @@ class DashletHeaderDynamic extends Dashlet
);
}
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="main_header">');
$oPanel = PanelFactory::MakeEnhancedNeutral(Dict::S(str_replace('_', ':', $sTitle)), $sIconPath);
$oPage->AddUiBlock($oPanel);
$oPage->add('<img src="'.$sIconPath.'">');
if (isset($aExtraParams['query_params']))
{
if (isset($aExtraParams['query_params'])) {
$aQueryParams = $aExtraParams['query_params'];
}
elseif (isset($aExtraParams['this->class']))
{
} elseif (isset($aExtraParams['this->class'])) {
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
$aQueryParams = $oObj->ToArgsForQuery();
}
else
{
} else {
$aQueryParams = array();
}
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
$oBlock = new DisplayBlock($oFilter, 'summary');
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
$oPage->add('</div>');
$oPage->add('</div>');
$oSubTitle = $oPanel->GetSubTitle();
$oSet = new DBObjectSet($oFilter);
$iCount = $oSet->Count();
$oAppContext = new ApplicationContext();
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($oFilter->serialize());
$oSubTitle->AddHtml('<a class="summary" href="'.$sHyperlink.'">'.Dict::Format(str_replace('_', ':', $sSubtitle), $iCount).'</a>');
// $oPage->add('</div>');
// $oPage->add('</div>');
}
/**

View File

@@ -17,6 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\UI\Component\Badge\BadgeFactory;
use Combodo\iTop\Application\UI\Component\Button\ButtonFactory;
use Combodo\iTop\Application\UI\Component\Html\Html;
use Combodo\iTop\Application\UI\Component\Toolbar\Toolbar;
@@ -203,6 +204,11 @@ class DisplayBlock
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
}
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = array())
{
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
}
public function Display(WebPage $oPage, $sId, $aExtraParams = array())
{
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
@@ -304,6 +310,7 @@ class DisplayBlock
public function GetRenderContent(WebPage $oPage, array $aExtraParams = [], string $sId = null): iUIBlock
{
$sHtml = '';
$oBlock = null;
// Add the extra params into the filter if they make sense for such a filter
$bDoSearch = utils::ReadParam('dosearch', false);
$aQueryParams = array();
@@ -763,94 +770,8 @@ HTML;
break;
case 'summary':
$sClass = $this->m_oFilter->GetClass();
$oAppContext = new ApplicationContext();
$sTitle = isset($aExtraParams['title[block]']) ? $aExtraParams['title[block]'] : '';
$sLabel = isset($aExtraParams['label[block]']) ? $aExtraParams['label[block]'] : '';
$sStateAttrCode = isset($aExtraParams['status[block]']) ? $aExtraParams['status[block]'] : 'status';
$sStatesList = isset($aExtraParams['status_codes[block]']) ? $aExtraParams['status_codes[block]'] : '';
$bContextFilter = isset($aExtraParams['context_filter']) ? isset($aExtraParams['context_filter']) != 0 : false;
if ($bContextFilter)
{
foreach($oAppContext->GetNames() as $sFilterCode)
{
$sContextParamValue = $oAppContext->GetCurrentValue($sFilterCode, null);
if (!is_null($sContextParamValue) && ! empty($sContextParamValue) && MetaModel::IsValidFilterCode($sClass, $sFilterCode))
{
$this->AddCondition($sFilterCode, $sContextParamValue);
}
}
$aQueryParams = array();
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
}
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
}
// Summary details
$aCounts = array();
$aStateLabels = array();
if (!empty($sStateAttrCode) && !empty($sStatesList))
{
$aStates = explode(',', $sStatesList);
$oAttDef = MetaModel::GetAttributeDef($sClass, $sStateAttrCode);
// Generate one count + group by query [#1330]
$sClassAlias = $this->m_oFilter->GetClassAlias();
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
$aGroupBy = array('group1' => $oGroupByExpr);
$oGroupBySearch = $this->m_oFilter->DeepClone();
if (isset($this->m_bShowObsoleteData))
{
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
}
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery(array(), $aGroupBy, false);
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
$aCountsQueryResults = array();
foreach ($aCountGroupByResults as $aCountGroupBySingleResult)
{
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
}
foreach($aStates as $sStateValue)
{
$sHtmlValue=$aGroupBy['group1']->MakeValueLabel($this->m_oFilter, $sStateValue, $sStateValue);
$aStateLabels[$sStateValue] = html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8');
$aCounts[$sStateValue] = (array_key_exists($sStateValue, $aCountsQueryResults))
? $aCountsQueryResults[$sStateValue]
: 0;
if ($aCounts[$sStateValue] == 0)
{
$aCounts[$sStateValue] = '-';
}
else
{
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
if (isset($this->m_bShowObsoleteData))
{
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
}
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
.'pages/UI.php?operation=search&'.$oAppContext->GetForLink()
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
$aCounts[$sStateValue] = "<a href=\"$sHyperlink\">{$aCounts[$sStateValue]}</a>";
}
}
}
$sHtml .= '<div class="summary-details"><table><tr><th>'.implode('</th><th>', $aStateLabels).'</th></tr>';
$sHtml .= '<tr><td>'.implode('</td><td>', $aCounts).'</td></tr></table></div>';
// Title & summary
$iCount = $this->m_oSet->Count();
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize());
$sHtml .= '<h1>'.Dict::S(str_replace('_', ':', $sTitle)).'</h1>';
$sHtml .= '<a class="summary" href="'.$sHyperlink.'">'.Dict::Format(str_replace('_', ':', $sLabel), $iCount).'</a>';
$sHtml .= '<div style="clear:both;"></div>';
break;
$oBlock = $this->RenderSummary($aExtraParams, $sHtml);
break;
case 'csv':
$bAdvancedMode = utils::ReadParam('advanced', false);
@@ -1171,6 +1092,10 @@ JS
);
}
if (!empty($oBlock)) {
return $oBlock;
}
return new Html($sHtml);
}
@@ -1354,6 +1279,103 @@ JS
$sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
}
/**
* @param array $aExtraParams
* @param string $sHtml
*
* @return iUIBlock
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreWarning
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected function RenderSummary(array $aExtraParams, string $sHtml): iUIBlock
{
$sClass = $this->m_oFilter->GetClass();
$oAppContext = new ApplicationContext();
$sStateAttrCode = isset($aExtraParams['status[block]']) ? $aExtraParams['status[block]'] : 'status';
$sStatesList = isset($aExtraParams['status_codes[block]']) ? $aExtraParams['status_codes[block]'] : '';
$bContextFilter = isset($aExtraParams['context_filter']) ? isset($aExtraParams['context_filter']) != 0 : false;
if ($bContextFilter) {
foreach ($oAppContext->GetNames() as $sFilterCode) {
$sContextParamValue = $oAppContext->GetCurrentValue($sFilterCode, null);
if (!is_null($sContextParamValue) && !empty($sContextParamValue) && MetaModel::IsValidFilterCode($sClass, $sFilterCode)) {
$this->AddCondition($sFilterCode, $sContextParamValue);
}
}
$aQueryParams = array();
if (isset($aExtraParams['query_params'])) {
$aQueryParams = $aExtraParams['query_params'];
}
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
}
// Summary details
$aCounts = array();
$aStateLabels = array();
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
$aStates = explode(',', $sStatesList);
// Generate one count + group by query [#1330]
$sClassAlias = $this->m_oFilter->GetClassAlias();
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
$aGroupBy = array('group1' => $oGroupByExpr);
$oGroupBySearch = $this->m_oFilter->DeepClone();
if (isset($this->m_bShowObsoleteData)) {
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
}
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery(array(), $aGroupBy, false);
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
$aCountsQueryResults = array();
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
}
foreach ($aStates as $sStateValue) {
$sHtmlValue = $aGroupBy['group1']->MakeValueLabel($this->m_oFilter, $sStateValue, $sStateValue);
$aStateLabels[$sStateValue] = html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8');
$aCounts[$sStateValue] = (array_key_exists($sStateValue, $aCountsQueryResults))
? $aCountsQueryResults[$sStateValue]
: 0;
if ($aCounts[$sStateValue] == 0) {
$aCounts[$sStateValue] = '-';
} else {
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
if (isset($this->m_bShowObsoleteData)) {
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
}
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
.'pages/UI.php?operation=search&'.$oAppContext->GetForLink()
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
$aCounts[$sStateValue] = ['link' => $sHyperlink, 'label' => $aCounts[$sStateValue]];
}
}
}
$oBlock = new UIContentBlock(null, "ibo-dashlet-header-dynamic--container");
foreach ($aStateLabels as $sStateValue => $sStateLabel) {
$aCount = $aCounts[$sStateValue];
$oBadge = BadgeFactory::MakeForState($sClass, $sStateValue);
$sHyperlink = $aCount['link'];
$sCountLabel = $aCount['label'];
$sColor = $oBadge->GetColor();
$oBadge->AddHtml("<a class=\"ibo-dashlet-header-dynamic--count ibo-badge-is-{$sColor}\" href=\"$sHyperlink\">$sCountLabel</a>");
$oBadge->AddHtml("<span class=\"ibo-dashlet-header-dynamic--label ibo-badge-is-{$sColor}\">$sStateLabel</span>");
$oBlock->AddSubBlock($oBadge);
}
return $oBlock;
}
}
/**

View File

@@ -4,6 +4,7 @@
*/
@import "alert";
@import "badge";
@import "button";
@import "breadcrumbs";
@import "quick-create";

View File

@@ -0,0 +1,99 @@
/*!
* Copyright (C) 2013-2020 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
*/
/* SCSS variables */
$ibo-badge--margin: 0px 8px !default;
$ibo-badge--padding: 6px 10px !default;
$ibo-badge--border-radius: $ibo-border-radius-300 !default;
$ibo-badge-new-state-primary-color: $ibo-color-blue-100 !default;
$ibo-badge-new-state-secondary-color: $ibo-color-blue-900 !default;
$ibo-badge-neutral-state-primary-color: $ibo-color-blue-100 !default;
$ibo-badge-neutral-state-secondary-color: $ibo-color-blue-900 !default;
$ibo-badge-waiting-state-primary-color: $ibo-color-orange-100 !default;
$ibo-badge-waiting-state-secondary-color: $ibo-color-orange-800 !default;
$ibo-badge-success-state-primary-color: $ibo-color-green-100 !default;
$ibo-badge-success-state-secondary-color: $ibo-color-green-900 !default;
$ibo-badge-failure-state-primary-color: $ibo-color-red-100 !default;
$ibo-badge-failure-state-secondary-color: $ibo-color-red-800 !default;
$ibo-badge-frozen-state-primary-color: $ibo-color-grey-100 !default;
$ibo-badge-frozen-state-secondary-color: $ibo-color-grey-700 !default;
/* - For basic badge */
$ibo-badge-active-state-primary-color: $ibo-color-green-100 !default;
$ibo-badge-active-state-secondary-color: $ibo-color-green-900 !default;
$ibo-badge-inactive-state-primary-color: $ibo-color-orange-100 !default;
$ibo-badge-inactive-state-secondary-color: $ibo-color-orange-800 !default;
$ibo-badge-states-colors: (
'new': (
'primary-color': $ibo-badge-new-state-primary-color,
'secondary-color': $ibo-badge-new-state-secondary-color,
),
'neutral': (
'primary-color': $ibo-badge-neutral-state-primary-color,
'secondary-color': $ibo-badge-neutral-state-secondary-color,
),
'waiting': (
'primary-color': $ibo-badge-waiting-state-primary-color,
'secondary-color': $ibo-badge-waiting-state-secondary-color,
),
'success': (
'primary-color': $ibo-badge-success-state-primary-color,
'secondary-color': $ibo-badge-success-state-secondary-color,
),
'failure': (
'primary-color': $ibo-badge-failure-state-primary-color,
'secondary-color': $ibo-badge-failure-state-secondary-color,
),
'frozen': (
'primary-color': $ibo-badge-frozen-state-primary-color,
'secondary-color': $ibo-badge-frozen-state-secondary-color,
),
'active': (
'primary-color': $ibo-badge-active-state-primary-color,
'secondary-color': $ibo-badge-active-state-secondary-color,
),
'inactive': (
'primary-color': $ibo-badge-inactive-state-primary-color,
'secondary-color': $ibo-badge-inactive-state-secondary-color,
),
);
@each $sType, $aColors in $ibo-badge-states-colors {
.ibo-badge-is-#{$sType} {
color: map-get($aColors, 'secondary-color');
background-color: map-get($aColors, 'primary-color');
}
}
/* Rules */
.ibo-badge {
display: flex;
flex-direction: row;
align-items: center;
margin: $ibo-badge--margin;
padding: $ibo-badge--padding;
border-radius: $ibo-badge--border-radius;
}

View File

@@ -25,6 +25,7 @@ $ibo-panel--highlight--border-radius: $ibo-border-radius-400 $ibo-border-radius-
$ibo-panel--highlight--padding-bottom: $ibo-panel--highlight--height !default;
$ibo-panel--title--color: $ibo-color-grey-900 !default;
$ibo-panel--subtitle--color: $ibo-color-grey-800 !default;
$ibo-panel--body--background-color: $ibo-color-white-100 !default;
$ibo-panel--body--padding-bottom: 16px !default;
@@ -74,9 +75,36 @@ $ibo-panel-colors: (
margin-top: $ibo-panel--spacing-top;
}
.ibo-panel--header {
display: flex;
}
.ibo-panel--title {
color: $ibo-panel--title--color;
@extend %ibo-font-ral-med-350;
@extend %ibo-font-ral-med-250;
flex-grow: 1;
.ibo-panel--title-icon {
display: inline-block;
}
.ibo-panel--title-title {
display: inline-block;
@extend %ibo-font-ral-med-250;
.ibo-panel--title-title-title {
}
.ibo-panel--title-title-subtitle {
@extend %ibo-font-ral-nor-250;
color: $ibo-panel--subtitle--color;
a.summary {
@extend %ibo-font-ral-nor-250;
color: $ibo-panel--subtitle--color;
}
}
}
}
.ibo-panel--body {

View File

@@ -4,4 +4,5 @@
*/
@import "dashlet";
@import "dashlet-badge";
@import "dashlet-badge";
@import "dashlet-header-dynamic";

View File

@@ -0,0 +1,22 @@
/*!
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/* SCSS variables */
$ibo-dashlet-header-dynamic--count--margin-right: 10px !default;
/* Rules */
.ibo-dashlet-header-dynamic--container {
display: flex;
padding-top: 12px;
}
.ibo-dashlet-header-dynamic--count {
@extend %ibo-font-ral-bol-200;
margin-right: $ibo-dashlet-header-dynamic--count--margin-right;
}
.ibo-dashlet-header-dynamic--label {
@extend %ibo-font-ral-med-100;
}

View File

@@ -152,6 +152,8 @@ return array(
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.php',
'Combodo\\iTop\\Application\\UI\\Component\\Alert\\Alert' => $baseDir . '/sources/application/UI/Component/Alert/Alert.php',
'Combodo\\iTop\\Application\\UI\\Component\\Alert\\AlertFactory' => $baseDir . '/sources/application/UI/Component/Alert/AlertFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Badge\\Badge' => $baseDir . '/sources/application/UI/Component/Badge/Badge.php',
'Combodo\\iTop\\Application\\UI\\Component\\Badge\\BadgeFactory' => $baseDir . '/sources/application/UI/Component/Badge/BadgeFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Breadcrumbs\\Breadcrumbs' => $baseDir . '/sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php',
'Combodo\\iTop\\Application\\UI\\Component\\Button\\Button' => $baseDir . '/sources/application/UI/Component/Button/Button.php',
'Combodo\\iTop\\Application\\UI\\Component\\Button\\ButtonFactory' => $baseDir . '/sources/application/UI/Component/Button/ButtonFactory.php',
@@ -169,6 +171,7 @@ return array(
'Combodo\\iTop\\Application\\UI\\Component\\Input\\Select\\Select' => $baseDir . '/sources/application/UI/Component/Input/Select/Select.php',
'Combodo\\iTop\\Application\\UI\\Component\\Input\\Select\\SelectOption' => $baseDir . '/sources/application/UI/Component/Input/Select/SelectOption.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\Panel' => $baseDir . '/sources/application/UI/Component/Panel/Panel.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\PanelEnhanced' => $baseDir . '/sources/application/UI/Component/Panel/PanelEnhanced.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\PanelFactory' => $baseDir . '/sources/application/UI/Component/Panel/PanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\NewsroomMenu\\NewsroomMenu' => $baseDir . '/sources/application/UI/Component/PopoverMenu/NewsroomMenu/NewsroomMenu.php',
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\NewsroomMenu\\NewsroomMenuFactory' => $baseDir . '/sources/application/UI/Component/PopoverMenu/NewsroomMenu/NewsroomMenuFactory.php',
@@ -186,6 +189,7 @@ return array(
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleFactory' => $baseDir . '/sources/application/UI/Component/Title/TitleFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleForObjectDetails' => $baseDir . '/sources/application/UI/Component/Title/TitleForObjectDetails.php',
'Combodo\\iTop\\Application\\UI\\Component\\Toolbar\\Toolbar' => $baseDir . '/sources/application/UI/Component/Toolbar/Toolbar.php',
'Combodo\\iTop\\Application\\UI\\Helper\\UIHelper' => $baseDir . '/sources/application/UI/Helper/UIHelper.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php',
@@ -373,6 +377,7 @@ return array(
'ExecutionKPI' => $baseDir . '/core/kpi.class.inc.php',
'Expression' => $baseDir . '/core/oql/expression.class.inc.php',
'ExpressionCache' => $baseDir . '/core/expressioncache.class.inc.php',
'ExpressionHelper' => $baseDir . '/core/oql/expression.class.inc.php',
'FalseExpression' => $baseDir . '/core/oql/expression.class.inc.php',
'FieldExpression' => $baseDir . '/core/oql/expression.class.inc.php',
'FieldExpressionResolved' => $baseDir . '/core/oql/expression.class.inc.php',

View File

@@ -13,9 +13,6 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {

View File

@@ -382,6 +382,8 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.php',
'Combodo\\iTop\\Application\\UI\\Component\\Alert\\Alert' => __DIR__ . '/../..' . '/sources/application/UI/Component/Alert/Alert.php',
'Combodo\\iTop\\Application\\UI\\Component\\Alert\\AlertFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Alert/AlertFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Badge\\Badge' => __DIR__ . '/../..' . '/sources/application/UI/Component/Badge/Badge.php',
'Combodo\\iTop\\Application\\UI\\Component\\Badge\\BadgeFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Badge/BadgeFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Breadcrumbs\\Breadcrumbs' => __DIR__ . '/../..' . '/sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php',
'Combodo\\iTop\\Application\\UI\\Component\\Button\\Button' => __DIR__ . '/../..' . '/sources/application/UI/Component/Button/Button.php',
'Combodo\\iTop\\Application\\UI\\Component\\Button\\ButtonFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Button/ButtonFactory.php',
@@ -399,6 +401,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'Combodo\\iTop\\Application\\UI\\Component\\Input\\Select\\Select' => __DIR__ . '/../..' . '/sources/application/UI/Component/Input/Select/Select.php',
'Combodo\\iTop\\Application\\UI\\Component\\Input\\Select\\SelectOption' => __DIR__ . '/../..' . '/sources/application/UI/Component/Input/Select/SelectOption.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\Panel' => __DIR__ . '/../..' . '/sources/application/UI/Component/Panel/Panel.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\PanelEnhanced' => __DIR__ . '/../..' . '/sources/application/UI/Component/Panel/PanelEnhanced.php',
'Combodo\\iTop\\Application\\UI\\Component\\Panel\\PanelFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Panel/PanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\NewsroomMenu\\NewsroomMenu' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/NewsroomMenu/NewsroomMenu.php',
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\NewsroomMenu\\NewsroomMenuFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/NewsroomMenu/NewsroomMenuFactory.php',
@@ -416,6 +419,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Title/TitleFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleForObjectDetails' => __DIR__ . '/../..' . '/sources/application/UI/Component/Title/TitleForObjectDetails.php',
'Combodo\\iTop\\Application\\UI\\Component\\Toolbar\\Toolbar' => __DIR__ . '/../..' . '/sources/application/UI/Component/Toolbar/Toolbar.php',
'Combodo\\iTop\\Application\\UI\\Helper\\UIHelper' => __DIR__ . '/../..' . '/sources/application/UI/Helper/UIHelper.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php',
@@ -603,6 +607,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'ExecutionKPI' => __DIR__ . '/../..' . '/core/kpi.class.inc.php',
'Expression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'ExpressionCache' => __DIR__ . '/../..' . '/core/expressioncache.class.inc.php',
'ExpressionHelper' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'FalseExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'FieldExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'FieldExpressionResolved' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',

View File

@@ -0,0 +1,42 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Component\Badge;
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
class Badge extends UIContentBlock
{
/** @var string */
protected $sColor;
public function __construct(string $sColor)
{
parent::__construct(null, "ibo-badge ibo-badge-is-{$sColor}");
$this->SetColor($sColor);
}
/**
* @return string
*/
public function GetColor(): ?string
{
return $this->sColor;
}
/**
* @param string $sColor
*
* @return Badge
*/
public function SetColor(string $sColor): Badge
{
$this->sColor = $sColor;
return $this;
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Component\Badge;
use Combodo\iTop\Application\UI\Helper\UIHelper;
class BadgeFactory
{
public static function MakeForState(string $sClass, string $sStateCode)
{
$sColor = UIHelper::GetColorFromStatus($sClass, $sStateCode);
return new Badge($sColor);
}
}

View File

@@ -87,8 +87,6 @@ class Panel extends UIContentBlock
/** @var string $sTitle */
protected $sTitle;
/** @var array $aSubBlocks */
protected $aSubBlocks;
/** @var string $sColor */
protected $sColor;

View File

@@ -0,0 +1,74 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Component\Panel;
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
class PanelEnhanced extends Panel
{
public const BLOCK_CODE = 'ibo-panel-enhanced';
public const HTML_TEMPLATE_REL_PATH = 'components/panel/panelenhanced';
/** @var UIContentBlock */
protected $sSubTitle;
/** @var string */
protected $sIconUrl;
/**
* PanelEnhanced constructor.
*
* @param $sTitle
* @param $sIconUrl
*/
public function __construct(string $sTitle, string $sIconUrl)
{
parent::__construct($sTitle);
$this->sSubTitle = new UIContentBlock();
$this->sIconUrl = $sIconUrl;
}
/**
* @return UIContentBlock
*/
public function GetSubTitle(): UIContentBlock
{
return $this->sSubTitle;
}
/**
* @param UIContentBlock $sSubTitle
*
* @return PanelEnhanced
*/
public function SetSubTitle(UIContentBlock $sSubTitle): PanelEnhanced
{
$this->sSubTitle = $sSubTitle;
return $this;
}
/**
* @return string
*/
public function GetIconUrl(): string
{
return $this->sIconUrl;
}
/**
* @param string $sIconUrl
*
* @return PanelEnhanced
*/
public function SetIconUrl(string $sIconUrl): PanelEnhanced
{
$this->sIconUrl = $sIconUrl;
return $this;
}
}

View File

@@ -161,7 +161,24 @@ class PanelFactory
public static function MakeForClass(string $sClass, string $sTitle)
{
$oPanel = new Panel($sTitle);
// TODO 3.0.0: Change this to clas color when done
// TODO 3.0.0: Change this to class color when done
$oPanel->SetColor(Panel::ENUM_COLOR_BLUE);
return $oPanel;
}
/**
* Make a basis Panel component
*
* @param string $sTitle
* @param String $sIconUrl
*
* @return \Combodo\iTop\Application\UI\Component\Panel\Panel
*/
public static function MakeEnhancedNeutral(string $sTitle, string $sIconUrl)
{
$oPanel = new PanelEnhanced($sTitle, $sIconUrl);
// TODO 3.0.0: Change this to class color when done
$oPanel->SetColor(Panel::ENUM_COLOR_BLUE);
return $oPanel;

View File

@@ -8,6 +8,7 @@
namespace Combodo\iTop\Application\UI\Component\Title;
use Combodo\iTop\Application\UI\Helper\UIHelper;
use DBObject;
use MetaModel;
@@ -31,45 +32,10 @@ class TitleFactory
$oTitle->SetIcon($sObjIconUrl);
$sStatusAttCode = MetaModel::GetStateAttributeCode($sObjClass);
if(!empty($sStatusAttCode))
{
if (!empty($sStatusAttCode)) {
$sStateCode = $oObject->GetState();
$sStatusLabel = $oObject->GetStateLabel();
// TODO 3.0.0 : Dehardcode this
switch ($sStateCode)
{
case 'new':
$sStatusColor = 'new';
break;
case 'waiting_for_approval':
case 'pending':
$sStatusColor = 'waiting';
break;
case 'escalated_tto':
case 'escalated_ttr':
case 'rejected':
$sStatusColor = 'failure';
break;
case 'resolved':
$sStatusColor = 'success';
break;
case 'closed':
$sStatusColor = 'frozen';
break;
case 'approved':
case 'assigned':
case 'dispatched':
case 'redispatched':
default:
$sStatusColor = 'neutral';
break;
}
$sStatusColor = UIHelper::GetColorFromStatus(get_class($oObject), $sStateCode);
$oTitle->SetStatus($sStatusAttCode, $sStatusLabel, $sStatusColor);
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Helper;
use MetaModel;
class UIHelper
{
public static function GetColorFromStatus(string $sClass, string $sStateCode)
{
$sStatusColor = 'neutral';
$sRootClass = MetaModel::GetRootClass($sClass);
switch ($sRootClass) {
case 'Ticket':
// TODO 3.0.0 : Dehardcode this
switch ($sStateCode) {
case 'new':
$sStatusColor = 'new';
break;
case 'waiting_for_approval':
case 'pending':
$sStatusColor = 'waiting';
break;
case 'escalated_tto':
case 'escalated_ttr':
case 'rejected':
$sStatusColor = 'failure';
break;
case 'resolved':
$sStatusColor = 'success';
break;
case 'closed':
$sStatusColor = 'frozen';
break;
case 'approved':
case 'assigned':
case 'dispatched':
case 'redispatched':
default:
$sStatusColor = 'neutral';
break;
}
break;
}
return $sStatusColor;
}
}

View File

@@ -8,6 +8,7 @@ namespace Combodo\iTop\Application\UI\Layout\Object;
use Combodo\iTop\Application\UI\Component\Panel\Panel;
use Combodo\iTop\Application\UI\Helper\UIHelper;
use DBObject;
use MetaModel;
@@ -51,39 +52,7 @@ class ObjectDetails extends Panel
if(!empty($sStatusAttCode)) {
$this->sStatusCode = $oObject->GetState();
$this->sStatusLabel = $oObject->GetStateLabel();
// TODO 3.0.0 : Dehardcode this
switch ($this->sStatusCode) {
case 'new':
$this->sStatusColor = 'new';
break;
case 'waiting_for_approval':
case 'pending':
$this->sStatusColor = 'waiting';
break;
case 'escalated_tto':
case 'escalated_ttr':
case 'rejected':
$this->sStatusColor = 'failure';
break;
case 'resolved':
$this->sStatusColor = 'success';
break;
case 'closed':
$this->sStatusColor = 'frozen';
break;
case 'approved':
case 'assigned':
case 'dispatched':
case 'redispatched':
default:
$this->sStatusColor = 'neutral';
break;
}
$this->sStatusColor = UIHelper::GetColorFromStatus($this->sClassName, $this->sStatusCode);
}
parent::__construct('', [], static::DEFAULT_COLOR, $sId);

View File

@@ -21,7 +21,8 @@ use Combodo\iTop\Application\UI\UIBlock;
* @internal
* @since 3.0.0
*/
class UIContentBlock extends UIBlock implements iUIContentBlock {
class UIContentBlock extends UIBlock implements iUIContentBlock
{
// Overloaded constants
public const BLOCK_CODE = 'ibo-content-block';
public const HTML_TEMPLATE_REL_PATH = 'layouts/content-block/layout';
@@ -29,17 +30,18 @@ class UIContentBlock extends UIBlock implements iUIContentBlock {
/** @var array */
protected $aCSSClasses;
/** @var array */
protected $aSubBlocks;
/** @var array */
protected $aDataAttributes;
/** @var array */
protected $aSubBlocks;
/**
* UIContentBlock constructor.
*
* @param string|null $sName
* @param string $sContainerClass
* @param string $sContainerClass
*/
public function __construct(string $sName = null, string $sContainerClass = '') {
public function __construct(string $sName = null, string $sContainerClass = '')
{
parent::__construct($sName);
$this->aSubBlocks = [];

View File

@@ -0,0 +1,3 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{% extends "layout/content-block/layout.html.twig" %}

View File

@@ -0,0 +1,17 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{% extends 'components/panel/layout.html.twig' %}
{% block iboPanelTitle %}
<div class="ibo-panel--title-icon">
<img src="{{ oUIBlock.GetIconUrl() }}" alt="{{ oUIBlock.GetTitle() }}"/>
</div>
<div class="ibo-panel--title-title">
<div class="ibo-panel--title-title-title">{{ oUIBlock.GetTitle() }}</div>
<div class="ibo-panel--title-title-subtitle">
{% for oSubBlock in oUIBlock.GetSubTitle().GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }}
{% endfor %}
</div>
</div>
{% endblock %}