N°2847 - Dashboards

This commit is contained in:
Eric
2020-11-02 09:59:31 +01:00
parent f3e47a15f6
commit be338e385b
18 changed files with 598 additions and 365 deletions

View File

@@ -15,15 +15,17 @@
//
// 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\Html\Html;
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardColumn;
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardLayout as UIDashboardLayout;
use Combodo\iTop\Application\UI\Layout\Dashboard\DashboardRow;
/**
* Dashboard presentation
*
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
*/
abstract class DashboardLayout
{
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
@@ -114,72 +116,52 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
// Trim the list of cells to remove the invisible/empty ones at the end of the array
$aCells = $this->TrimCellsArray($aCells);
$oPage->add('<table class="ibo-dashboard--grid"><tbody>');
$oDashboardLayout = new UIDashboardLayout();
$oPage->AddUiBlock($oDashboardLayout);
$iCellIdx = 0;
$fColSize = ceil(100 / $this->iNbCols); // Note: ceil() is necessary otherwise the table will be too short since the new flex layout (N°2847)
$iNbRows = ceil(count($aCells) / $this->iNbCols);
$aStyleProperties = [];
// - Explicit full width when single column
if($this->iNbCols > 1)
{
$aStyleProperties[] = 'width: '.$fColSize.'%;';
}
// - Visible borders in editor
if($bEditMode)
{
$aStyleProperties[] = 'border: 1px #ccc dashed;';
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
$oDashboardRow = new DashboardRow();
$oDashboardLayout->AddDashboardRow($oDashboardRow);
}
$sClass = $bEditMode ? 'layout_cell edit_mode' : 'dashboard';
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
$oDashboardColumn = new DashboardColumn($bEditMode);
$oDashboardColumn->SetCellIndex($iCellIdx);
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
for($iRows = 0; $iRows < $iNbRows; $iRows++)
{
$oPage->add("<tr class=\"ibo-dashboard--grid-row\" data-dashboard-grid-row-index=\"$iRows\">");
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
{
$sCellClass = ($iRows == $iNbRows-1) ? $sClass.' layout_last_used_rank' : $sClass;
$oPage->add("<td class=\"ibo-dashboard--grid-column ibo-dashboard--grid-cell $sCellClass\" style=\"".implode(' ', $aStyleProperties)."\" data-dashboard-grid-column-index=\"$iCols\" data-dashboard-grid-cell-index=\"$iCellIdx\">");
if (array_key_exists($iCellIdx, $aCells))
{
if (array_key_exists($iCellIdx, $aCells)) {
$aDashlets = $aCells[$iCellIdx];
if (count($aDashlets) > 0)
{
if (count($aDashlets) > 0) {
/** @var \Dashlet $oDashlet */
foreach($aDashlets as $oDashlet)
{
if ($oDashlet::IsVisible())
{
$oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams);
foreach ($aDashlets as $oDashlet) {
if ($oDashlet::IsVisible()) {
$oDashboardColumn->AddUIBlock($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams));
}
}
} else {
$oDashboardColumn->AddUIBlock(new Html('&nbsp;'));
}
else
{
$oPage->add('&nbsp;');
}
} else {
$oDashboardColumn->AddUIBlock(new Html('&nbsp;'));
}
else
{
$oPage->add('&nbsp;');
}
$oPage->add('</td>');
$iCellIdx++;
}
$oPage->add('</tr>');
}
if ($bEditMode) // Add one row for extensibility
{
$oPage->add("<tr class=\"ibo-dashboard--grid-row\" data-dashboard-grid-row-index=\"$iRows\">");
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
{
$oPage->add("<td class=\"ibo-dashboard--grid-column ibo-dashboard--grid-cell layout_cell edit_mode layout_extension\" style=\"".implode(' ', $aStyleProperties)."\" data-dashboard-grid-column-index=\"$iCols\" data-dashboard-grid-cell-index=\"$iCellIdx\">");
$oPage->add('&nbsp;');
$oPage->add('</td>');
$oDashboardRow = new DashboardRow();
$oDashboardLayout->AddDashboardRow($oDashboardRow);
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
$oDashboardColumn = new DashboardColumn($bEditMode, true);
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
$oDashboardColumn->AddUIBlock(new Html('&nbsp;'));
}
$oPage->add('</tr>');
}
$oPage->add('</tbody></table>');
return;
}
/**

View File

@@ -16,8 +16,11 @@
// 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\Dashlet\DashletContainer;
use Combodo\iTop\Application\UI\Component\Dashlet\DashletFactory;
use Combodo\iTop\Application\UI\Component\Html\Html;
use Combodo\iTop\Application\UI\Component\Panel\PanelFactory;
use Combodo\iTop\Application\UI\iUIBlock;
require_once(APPROOT.'application/forms.class.inc.php');
@@ -69,21 +72,14 @@ abstract class Dashlet
{
$refValue = $this->aProperties[$sProperty];
$sRefType = gettype($refValue);
if (gettype($sValue) == $sRefType)
{
if (gettype($sValue) == $sRefType) {
// Do not change anything in that case!
$ret = $sValue;
}
elseif ($sRefType == 'boolean')
{
} elseif ($sRefType == 'boolean') {
$ret = ($sValue == 'true');
}
elseif ($sRefType == 'array')
{
} elseif (($sRefType == 'array') || (is_array($sValue))) {
$ret = explode(',', $sValue);
}
else
{
} else {
$ret = $sValue;
settype($ret, $sRefType);
}
@@ -212,77 +208,57 @@ abstract class Dashlet
*/
public function DoRender($oPage, $bEditMode = false, $bEnclosingDiv = true, $aExtraParams = array())
{
$sCSSClasses = implode(' ', $this->aCSSClasses);
$sId = $this->GetID();
if ($bEnclosingDiv)
{
if ($bEditMode)
{
$oPage->add('<div class="'.$sCSSClasses.'" id="dashlet_'.$sId.'">');
$sCSSClasses = implode(' ', $this->aCSSClasses);
if ($bEnclosingDiv) {
if ($bEditMode) {
$oDashletContainer = new DashletContainer("dashlet_{$sId}");
} else {
$oDashletContainer = new DashletContainer();
}
else
{
$oPage->add('<div class="'.$sCSSClasses.'">');
}
}
else
{
foreach ($this->aCSSClasses as $sCSSClass)
{
$oDashletContainer->AddCSSClasses($sCSSClasses);
} else {
$oDashletContainer = new DashletContainer();
foreach ($this->aCSSClasses as $sCSSClass) {
$oPage->add_ready_script("$('#dashlet_".$sId."').addClass('$sCSSClass');");
}
}
try
{
if (get_class($this->oModelReflection) == 'ModelReflectionRuntime')
{
$this->Render($oPage, $bEditMode, $aExtraParams);
try {
if (get_class($this->oModelReflection) == 'ModelReflectionRuntime') {
$oBlock = $this->Render($oPage, $bEditMode, $aExtraParams);
} else {
$oBlock = $this->RenderNoData($oPage, $bEditMode, $aExtraParams);
}
else
{
$this->RenderNoData($oPage, $bEditMode, $aExtraParams);
}
}
catch(UnknownClassOqlException $e)
{
$oDashletContainer->AddSubBlock($oBlock);
} catch (UnknownClassOqlException $e) {
// Maybe the class is part of a non-installed module, fail silently
// Except in Edit mode
if ($bEditMode)
{
$oPage->add('<div class="dashlet-content">');
$oPage->add('<h2>'.$e->GetUserFriendlyDescription().'</h2>');
$oPage->add('</div>');
if ($bEditMode) {
$oDashletContainer->AddCSSClasses("dashlet-content");
$oDashletContainer->AddHtml('<h2>'.$e->GetUserFriendlyDescription().'</h2>');
}
}
catch(OqlException $e)
{
$oPage->add('<div class="dashlet-content">');
$oPage->p($e->GetUserFriendlyDescription());
$oPage->add('</div>');
}
catch(Exception $e)
{
$oPage->add('<div class="dashlet-content">');
$oPage->p($e->getMessage());
$oPage->add('</div>');
} catch (OqlException $e) {
$oDashletContainer->AddCSSClasses("dashlet-content");
$oDashletContainer->AddHtml('<p>'.$e->GetUserFriendlyDescription().'</p>');
} catch (Exception $e) {
$oDashletContainer->AddCSSClasses("dashlet-content");
$oDashletContainer->AddHtml('<p>'.$e->getMessage().'</p>');
}
if ($bEnclosingDiv)
{
$oPage->add('</div>');
}
if ($bEditMode)
{
if ($bEditMode) {
$sClass = get_class($this);
$sType = $this->sDashletType;
$oPage->add_ready_script(
<<<EOF
<<<EOF
$('#dashlet_$sId').dashlet({dashlet_id: '$sId', dashlet_class: '$sClass', 'dashlet_type': '$sType'});
EOF
);
}
return $oDashletContainer;
}
/**
@@ -306,7 +282,7 @@ EOF
* @param bool $bEditMode
* @param array $aExtraParams
*
* @return mixed
* @return iUIBlock
*/
abstract public function Render($oPage, $bEditMode = false, $aExtraParams = array());
@@ -316,10 +292,12 @@ EOF
* @param \WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
*
* @return iUIBlock
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$this->Render($oPage, $bEditMode, $aExtraParams);
return $this->Render($oPage, $bEditMode, $aExtraParams);
}
/**
@@ -622,12 +600,12 @@ class DashletUnknown extends Dashlet
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View');
$oPage->add('<div class="dashlet-content">');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oPage->add('</div>');
return $oDashletContainer;
}
/**
@@ -642,12 +620,12 @@ class DashletUnknown extends Dashlet
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType());
$oPage->add('<div class="dashlet-content">');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oDashletContainer->AddHtml('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oDashletContainer->AddHtml('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oPage->add('</div>');
return $oDashletContainer;
}
/**
@@ -766,9 +744,9 @@ class DashletProxy extends DashletUnknown
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
// This should never be called.
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div>This dashlet is not supposed to be rendered as it is just a proxy for third-party widgets.</div>');
$oPage->add('</div>');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oDashletContainer->AddHtml('<div>This dashlet is not supposed to be rendered as it is just a proxy for third-party widgets.</div>');
return $oDashletContainer;
}
/**
@@ -783,12 +761,14 @@ class DashletProxy extends DashletUnknown
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType());
$oPage->add('<div class="dashlet-content">');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oPage->add('<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-pxy-text">'.$sExplainText.'</div>');
$sHtml = '';
$sHtml .= '<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>';
$sHtml .= '<div class="dashlet-pxy-text">'.$sExplainText.'</div>';
$oPage->add('</div>');
$oDashletContainer->AddHtml($sHtml);
return $oDashletContainer;
}
/**
@@ -819,7 +799,7 @@ class DashletEmptyCell extends Dashlet
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$oPage->add('&nbsp;');
return new Html('&nbsp;');
}
/**
@@ -871,8 +851,7 @@ class DashletPlainText extends Dashlet
$sId = 'plaintext_'.($bEditMode ? 'edit_' : '').$this->sId;
$oBlock = DashletFactory::MakeForDashletText($sId, $sText);
$oPage->AddUiBlock($oBlock);
return DashletFactory::MakeForDashletText($sId, $sText);
}
/**
@@ -924,7 +903,6 @@ class DashletObjectList extends Dashlet
$sShowMenu = $this->aProperties['menu'] ? '1' : '0';
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
$oPage->AddUiBlock($oPanel);
$oFilter = $this->GetDBSearch($aExtraParams);
$oBlock = new DisplayBlock($oFilter, 'list');
@@ -934,26 +912,8 @@ class DashletObjectList extends Dashlet
);
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
}
public function GetDBSearch($aExtraParams = array())
{
$sQuery = $this->aProperties['query'];
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
}
elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id']))
{
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
$aQueryParams = $oObj->ToArgsForQuery();
}
else
{
$aQueryParams = array();
}
return DBObjectSearch::FromOQL($sQuery, $aQueryParams);
return $oPanel;
}
/**
@@ -967,22 +927,35 @@ class DashletObjectList extends Dashlet
$oPage->add('<div class="dashlet-content">');
$sHtmlTitle = utils::HtmlEntities($this->oModelReflection->DictString($sTitle)); // done in the itop block
if ($sHtmlTitle != '')
{
if ($sHtmlTitle != '') {
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
}
$oQuery = $this->oModelReflection->GetQuery($sQuery);
$sClass = $oQuery->GetClass();
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
$oPage->p(Dict::S('UI:NoObjectToDisplay'));
if ($bShowMenu)
{
if ($bShowMenu) {
$oPage->p('<a>'.Dict::Format('UI:ClickToCreateNew', $this->oModelReflection->GetName($sClass)).'</a>');
}
$oPage->add('</div>');
$oPage->add('</div>');
}
public function GetDBSearch($aExtraParams = array())
{
$sQuery = $this->aProperties['query'];
if (isset($aExtraParams['query_params'])) {
$aQueryParams = $aExtraParams['query_params'];
} elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id'])) {
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
$aQueryParams = $oObj->ToArgsForQuery();
} else {
$aQueryParams = array();
}
return DBObjectSearch::FromOQL($sQuery, $aQueryParams);
}
/**
* @inheritdoc
*/
@@ -1200,96 +1173,81 @@ abstract class DashletGroupBy extends Dashlet
$sStyle = $this->aProperties['style'];
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
if (isset($aExtraParams['query_params']))
{
if (isset($aExtraParams['query_params'])) {
$aQueryParams = $aExtraParams['query_params'];
}
elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id']))
{
} elseif (isset($aExtraParams['this->class']) && isset($aExtraParams['this->id'])) {
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
$aQueryParams = $oObj->ToArgsForQuery();
}
else
{
} else {
$aQueryParams = array();
}
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
$sClass = $oFilter->GetClass();
if (!$this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode))
{
$oPage->add('<p>'.Dict::S('UI:DashletGroupBy:MissingGroupBy').'</p>');
if (!$this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode)) {
return new Html('<p>'.Dict::S('UI:DashletGroupBy:MissingGroupBy').'</p>');
}
else
{
switch($sStyle)
{
case 'bars':
$sType = 'chart';
$aParams = array(
'chart_type' => 'bars',
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
case 'pie':
$sType = 'chart';
$aParams = array(
'chart_type' => 'pie',
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
switch ($sStyle) {
case 'bars':
$sType = 'chart';
$aParams = array(
'chart_type' => 'bars',
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
case 'table':
default:
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
$sType = 'count';
$aParams = array(
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
break;
}
case 'pie':
$sType = 'chart';
$aParams = array(
'chart_type' => 'pie',
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
$sHtmlTitle = ''; // done in the itop block
break;
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
$oPage->AddUiBlock($oPanel);
// $oPage->add('<div class="dashlet-content">');
// if ($sHtmlTitle != '')
// {
// $oPage->add('<div class="main_header"><h1>&nbsp;'.$sHtmlTitle.'</h1></div>');
// }
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock = new DisplayBlock($oFilter, $sType);
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
if ($bEditMode) {
$oPanel->AddHtml('<div class="dashlet-blocker"></div>');
}
// $oPage->add('</div>');
case 'table':
default:
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
$sType = 'count';
$aParams = array(
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
'aggregation_function' => $this->sAggregationFunction,
'aggregation_attribute' => $this->sAggregationAttribute,
'limit' => $this->sLimit,
'order_direction' => $this->sOrderDirection,
'order_by' => $this->sOrderBy,
);
break;
}
$oPanel = PanelFactory::MakeNeutral(Dict::S($sTitle));
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock = new DisplayBlock($oFilter, $sType);
$oBlock->DisplayIntoContentBlock($oPanel, $oPage, $sBlockId, array_merge($aExtraParams, $aParams));
if ($bEditMode) {
$oPanel->AddHtml('<div class="dashlet-blocker"></div>');
}
return $oPanel;
}
/**
@@ -1372,9 +1330,9 @@ abstract class DashletGroupBy extends Dashlet
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$oPage->add('<div class="dashlet-content">');
$oPage->add('error!');
$oPage->add('</div>');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oDashletContainer->AddHtml('error!');
return $oDashletContainer;
}
/**
@@ -1695,26 +1653,27 @@ class DashletGroupByPie extends DashletGroupBy
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$sTitle = $this->aProperties['title'];
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$oDashletContainer->AddHtml("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$aDisplayValues = $this->MakeSimulatedData();
$aColumns = array();
$aNames = array();
foreach($aDisplayValues as $idx => $aValue)
{
foreach ($aDisplayValues as $idx => $aValue) {
$aColumns[] = array('series_'.$idx, (int)$aValue['value']);
$aNames['series_'.$idx] = $aValue['label'];
}
$sJSColumns = json_encode($aColumns);
$sJSNames = json_encode($aNames);
$oPage->add_ready_script(
<<<EOF
<<<EOF
window.setTimeout(function() {
var chart = c3.generate({
bindto: '#{$sBlockId}',
@@ -1735,6 +1694,8 @@ var chart = c3.generate({
});}, 100);
EOF
);
return $oDashletContainer;
}
}
@@ -1767,25 +1728,26 @@ class DashletGroupByBars extends DashletGroupBy
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$sTitle = $this->aProperties['title'];
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$oDashletContainer->AddHtml("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$aDisplayValues = $this->MakeSimulatedData();
$aNames = array();
foreach($aDisplayValues as $idx => $aValue)
{
foreach ($aDisplayValues as $idx => $aValue) {
$aNames[$idx] = $aValue['label'];
}
$sJSNames = json_encode($aNames);
$sJson = json_encode($aDisplayValues);
$oPage->add_ready_script(
<<<EOF
<<<EOF
window.setTimeout(function() {
var chart = c3.generate({
bindto: '#{$sBlockId}',
@@ -1833,6 +1795,8 @@ window.setTimeout(function() {
}, 100);
EOF
);
return $oDashletContainer;
}
}
@@ -1864,40 +1828,44 @@ class DashletGroupByTable extends DashletGroupBy
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$oDashletContainer = new DashletContainer();
$aDisplayValues = $this->MakeSimulatedData();
$iTotal = 0;
foreach($aDisplayValues as $iRow => $aDisplayData)
{
foreach ($aDisplayValues as $iRow => $aDisplayData) {
$iTotal += $aDisplayData['value'];
}
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$oPage->add('<div id="'.$sBlockId.'" class="display_block">');
$oPage->add('<div class="dashlet-content">');
$oPage->add('<p>'.Dict::Format('UI:Pagination:HeaderNoSelection', $iTotal).'</p>');
$oPage->add('<table class="listResults">');
$oPage->add('<thead>');
$oPage->add('<tr>');
$oPage->add('<th class="header" title="">'.$this->sGroupByLabel.'</th>');
$oPage->add('<th class="header" title="'.Dict::S('UI:GroupBy:Count+').'">'.Dict::S('UI:GroupBy:Count').'</th>');
$oPage->add('</tr>');
$oPage->add('</thead>');
$oPage->add('<tbody>');
foreach($aDisplayValues as $aDisplayData)
{
$oPage->add('<tr class="even">');
$oPage->add('<td class=""><span title="Active">'.$aDisplayData['label'].'</span></td>');
$oPage->add('<td class=""><a>'.$aDisplayData['value'].'</a></td>');
$oPage->add('</tr>');
$sHtml = '';
$sHtml .= '<div id="'.$sBlockId.'" class="display_block">';
$sHtml .= '<div class="dashlet-content">';
$sHtml .= '<p>'.Dict::Format('UI:Pagination:HeaderNoSelection', $iTotal).'</p>';
$sHtml .= '<table class="listResults">';
$sHtml .= '<thead>';
$sHtml .= '<tr>';
$sHtml .= '<th class="header" title="">'.$this->sGroupByLabel.'</th>';
$sHtml .= '<th class="header" title="'.Dict::S('UI:GroupBy:Count+').'">'.Dict::S('UI:GroupBy:Count').'</th>';
$sHtml .= '</tr>';
$sHtml .= '</thead>';
$sHtml .= '<tbody>';
foreach ($aDisplayValues as $aDisplayData) {
$sHtml .= '<tr class="even">';
$sHtml .= '<td class=""><span title="Active">'.$aDisplayData['label'].'</span></td>';
$sHtml .= '<td class=""><a>'.$aDisplayData['value'].'</a></td>';
$sHtml .= '</tr>';
}
$oPage->add('</tbody>');
$oPage->add('</table>');
$oPage->add('</div>');
$sHtml .= '</tbody>';
$sHtml .= '</table>';
$sHtml .= '</div>';
$oPage->add('</div>');
$sHtml .= '</div>';
$oDashletContainer->AddHtml($sHtml);
return $oDashletContainer;
}
}
@@ -1926,8 +1894,7 @@ class DashletHeaderStatic extends Dashlet
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$oBlock = DashletFactory::MakeForDashletHeaderStatic($this->oModelReflection->DictString($sTitle), $sIconPath);
$oPage->AddUiBlock($oBlock);
return DashletFactory::MakeForDashletHeaderStatic($this->oModelReflection->DictString($sTitle), $sIconPath);
}
/**
@@ -2074,7 +2041,6 @@ class DashletHeaderDynamic extends Dashlet
}
$oPanel = PanelFactory::MakeEnhancedNeutral(Dict::S(str_replace('_', ':', $sTitle)), $sIconPath);
$oPage->AddUiBlock($oPanel);
if (isset($aExtraParams['query_params'])) {
$aQueryParams = $aExtraParams['query_params'];
@@ -2096,8 +2062,7 @@ class DashletHeaderDynamic extends Dashlet
$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>');
return $oPanel;
}
/**
@@ -2117,46 +2082,48 @@ class DashletHeaderDynamic extends Dashlet
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="main_header">');
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$oPage->add('<img src="'.$sIconPath.'">');
$sHtml = '';
$sHtml .= '<img src="'.$sIconPath.'">';
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$iTotal = 0;
$aValues = $this->GetValues();
$oPage->add('<div class="display_block" id="'.$sBlockId.'">');
$oPage->add('<div class="summary-details">');
$oPage->add('<table><tbody>');
$oPage->add('<tr>');
foreach ($aValues as $sValue)
{
$sHtml .= '<div class="display_block" id="'.$sBlockId.'">';
$sHtml .= '<div class="summary-details">';
$sHtml .= '<table><tbody>';
$sHtml .= '<tr>';
foreach ($aValues as $sValue) {
$sValueLabel = $this->oModelReflection->GetValueLabel($sClass, $sGroupBy, $sValue);
$oPage->add(' <th>'.$sValueLabel.'</th>');
$sHtml .= ' <th>'.$sValueLabel.'</th>';
}
$oPage->add('</tr>');
$oPage->add('<tr>');
foreach ($aValues as $sValue)
{
$iCount = (int) rand(2, 100);
$sHtml .= '</tr>';
$sHtml .= '<tr>';
foreach ($aValues as $sValue) {
$iCount = (int)rand(2, 100);
$iTotal += $iCount;
$oPage->add(' <td>'.$iCount.'</td>');
$sHtml .= ' <td>'.$iCount.'</td>';
}
$oPage->add('</tr>');
$oPage->add('</tbody></table>');
$oPage->add('</div>');
$sHtml .= '</tr>';
$sHtml .= '</tbody></table>';
$sHtml .= '</div>';
$sTitle = $this->oModelReflection->DictString($sTitle);
$sSubtitle = $this->oModelReflection->DictFormat($sSubtitle, $iTotal);
$oPage->add('<h1>'.utils::HtmlEntities($sTitle).'</h1>');
$oPage->add('<a class="summary">'.utils::HtmlEntities($sSubtitle).'</a>');
$oPage->add('</div>');
$sHtml .= '<h1>'.utils::HtmlEntities($sTitle).'</h1>';
$sHtml .= '<a class="summary">'.utils::HtmlEntities($sSubtitle).'</a>';
$sHtml .= '</div>';
$sHtml .= '</div>';
$oDashletContainer->AddHtml($sHtml);
return $oDashletContainer;
$oPage->add('</div>');
$oPage->add('</div>');
}
/**
@@ -2312,17 +2279,16 @@ class DashletBadge extends Dashlet
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$sClass = $this->aProperties['class'];
$oPage->add('<div class="dashlet-content">');
$oFilter = new DBObjectSearch($sClass);
$oBlock = new DisplayBlock($oFilter, 'actions');
$aExtraParams['context_filter'] = 1;
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock->Display($oPage, $sBlockId, $aExtraParams);
$oBlock->DisplayIntoContentBlock($oDashletContainer, $oPage, $sBlockId, $aExtraParams);
$oPage->add('</div>');
return $oDashletContainer;
}
/**
@@ -2330,23 +2296,25 @@ class DashletBadge extends Dashlet
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$sClass = $this->aProperties['class'];
$oDashletContainer = new DashletContainer(null, 'dashlet-content');
$sClass = $this->aProperties['class'];
$sIconUrl = $this->oModelReflection->GetClassIcon($sClass, false);
$sClassLabel = $this->oModelReflection->GetName($sClass);
$oPage->add('<div class="dashlet-content">');
$sHtml = '';
$sHtml .= '<div id="block_fake_'.$this->sId.'" class="display_block">';
$sHtml .= '<p>';
$sHtml .= ' <a class="actions"><img src="'.utils::HtmlEntities($sIconUrl).'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>';
$sHtml .= '</p>';
$sHtml .= '<p>';
$sHtml .= ' <a>'.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'</a>';
$sHtml .= '</p>';
$sHtml .= '</div>';
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
$oPage->add('<p>');
$oPage->add(' <a class="actions"><img src="'.utils::HtmlEntities($sIconUrl).'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>');
$oPage->add('</p>');
$oPage->add('<p>');
$oPage->add(' <a>'.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'</a>');
$oPage->add('</p>');
$oPage->add('</div>');
$oDashletContainer->AddHtml($sHtml);
$oPage->add('</div>');
return $oDashletContainer;
}
static protected $aClassList = null;

View File

@@ -17,7 +17,7 @@
*/
/* SCSS variables */
$ibo-badge--margin: 0px 8px !default;
$ibo-badge--margin: 4px 8px !default;
$ibo-badge--padding: 6px 10px !default;
$ibo-badge--border-radius: $ibo-border-radius-300 !default;

View File

@@ -9,6 +9,7 @@ $ibo-dashlet-header-dynamic--count--margin-right: 10px !default;
/* Rules */
.ibo-dashlet-header-dynamic--container {
display: flex;
flex-wrap: wrap;
padding-top: 12px;
}

View File

@@ -17,31 +17,39 @@ $ibo-dashboard--grid--elements-spacing-y: $ibo-dashlet--elements-spacing-y !defa
width: $ibo-dashboard--grid--width;
}
.ibo-dashboard--grid-row{
display: flex;
flex-direction: row;
overflow: hidden; /* Because of the column negative margin (which is for the dashlets spacing) */
display: flex;
flex-direction: row;
justify-content: space-between;
overflow: hidden; /* Because of the column negative margin (which is for the dashlets spacing) */
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between rows */
&:not(:last-child){
padding-bottom: calc(#{$ibo-dashboard--grid--elements-spacing-y} / 2);
}
&:not(:first-child){
padding-top: calc(#{$ibo-dashboard--grid--elements-spacing-y} / 2);
}
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between rows */
&:not(:last-child) {
padding-bottom: calc(#{$ibo-dashboard--grid--elements-spacing-y} / 2);
}
&:not(:first-child) {
padding-top: calc(#{$ibo-dashboard--grid--elements-spacing-y} / 2);
}
}
.ibo-dashboard--grid-column{
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: flex-start;
width: calc(100% + (2 * #{$ibo-dashboard--grid--elements-spacing-x}));
margin: calc(-1 * #{$ibo-dashboard--grid--elements-spacing-y} / 2) calc(-1 * #{$ibo-dashboard--grid--elements-spacing-x} / 2); /* Because of the margin all around the dashlets, we need to compensate it */
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between columns */
&:not(:last-child) {
margin-right: 0;
}
&:not(:first-child) {
margin-left: 0;
}
.ibo-dashboard--grid-column {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
align-content: flex-start;
width: calc(100% + (2 * #{$ibo-dashboard--grid--elements-spacing-x}));
margin: calc(-1 * #{$ibo-dashboard--grid--elements-spacing-y} / 2) calc(-1 * #{$ibo-dashboard--grid--elements-spacing-x} / 2); /* Because of the margin all around the dashlets, we need to compensate it */
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between columns */
&:not(:last-child) {
margin-right: 0;
}
&:not(:first-child) {
margin-left: 0;
}
}
.ibo-dashboard--grid-column.edit-mode {
border: 1px #ccc dashed;
}

View File

@@ -158,7 +158,7 @@ return array(
'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',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletBadge' => $baseDir . '/sources/application/UI/Component/Dashlet/DashletBadge.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletComponent' => $baseDir . '/sources/application/UI/Component/Dashlet/DashletComponent.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletContainer' => $baseDir . '/sources/application/UI/Component/Dashlet/DashletContainer.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletFactory' => $baseDir . '/sources/application/UI/Component/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletHeaderStatic' => $baseDir . '/sources/application/UI/Component/Dashlet/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\UI\\Component\\FieldSet\\FieldSet' => $baseDir . '/sources/application/UI/Component/FieldSet/FieldSet.php',
@@ -210,6 +210,9 @@ return array(
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryForm\\ActivityNewEntryForm' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanel' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanelFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardColumn' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardColumn.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardLayout' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardLayout.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardRow' => $baseDir . '/sources/application/UI/Layout/Dashboard/DashboardRow.php',
'Combodo\\iTop\\Application\\UI\\Layout\\MultiColumn\\Column\\Column' => $baseDir . '/sources/application/UI/Layout/MultiColumn/Column/Column.php',
'Combodo\\iTop\\Application\\UI\\Layout\\MultiColumn\\MultiColumn' => $baseDir . '/sources/application/UI/Layout/MultiColumn/MultiColumn.php',
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenu' => $baseDir . '/sources/application/UI/Layout/NavigationMenu/NavigationMenu.php',

View File

@@ -388,7 +388,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'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',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletBadge' => __DIR__ . '/../..' . '/sources/application/UI/Component/Dashlet/DashletBadge.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletComponent' => __DIR__ . '/../..' . '/sources/application/UI/Component/Dashlet/DashletComponent.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletContainer' => __DIR__ . '/../..' . '/sources/application/UI/Component/Dashlet/DashletContainer.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\UI\\Component\\Dashlet\\DashletHeaderStatic' => __DIR__ . '/../..' . '/sources/application/UI/Component/Dashlet/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\UI\\Component\\FieldSet\\FieldSet' => __DIR__ . '/../..' . '/sources/application/UI/Component/FieldSet/FieldSet.php',
@@ -440,6 +440,9 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityNewEntryForm\\ActivityNewEntryForm' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityNewEntryForm/ActivityNewEntryForm.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanel' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityPanel.php',
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityPanelFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityPanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardColumn' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardColumn.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardLayout' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardLayout.php',
'Combodo\\iTop\\Application\\UI\\Layout\\Dashboard\\DashboardRow' => __DIR__ . '/../..' . '/sources/application/UI/Layout/Dashboard/DashboardRow.php',
'Combodo\\iTop\\Application\\UI\\Layout\\MultiColumn\\Column\\Column' => __DIR__ . '/../..' . '/sources/application/UI/Layout/MultiColumn/Column/Column.php',
'Combodo\\iTop\\Application\\UI\\Layout\\MultiColumn\\MultiColumn' => __DIR__ . '/../..' . '/sources/application/UI/Layout/MultiColumn/MultiColumn.php',
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenu' => __DIR__ . '/../..' . '/sources/application/UI/Layout/NavigationMenu/NavigationMenu.php',

View File

@@ -8,7 +8,7 @@
namespace Combodo\iTop\Application\UI\Component\Dashlet;
class DashletBadge extends DashletComponent
class DashletBadge extends DashletContainer
{
public const BLOCK_CODE = 'ibo-dashlet-badge';
public const HTML_TEMPLATE_REL_PATH = 'components/dashlet/dashletbadge';

View File

@@ -1,22 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Component\Dashlet;
use Combodo\iTop\Application\UI\UIBlock;
class DashletComponent extends UIBlock
{
public const BLOCK_CODE = 'ibo-dashlet';
public const HTML_TEMPLATE_REL_PATH = 'components/dashlet/layout';
public function __construct(?string $sId = null)
{
parent::__construct($sId);
}
}

View File

@@ -0,0 +1,16 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Component\Dashlet;
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
class DashletContainer extends UIContentBlock
{
public const BLOCK_CODE = 'ibo-dashlet';
}

View File

@@ -8,7 +8,7 @@
namespace Combodo\iTop\Application\UI\Component\Dashlet;
class DashletHeaderStatic extends DashletComponent
class DashletHeaderStatic extends DashletContainer
{
public const BLOCK_CODE = 'ibo-dashlet-header-static';
public const HTML_TEMPLATE_REL_PATH = 'components/dashlet/dashletheaderstatic';

View File

@@ -0,0 +1,114 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\Dashboard;
use Combodo\iTop\Application\UI\UIBlock;
class DashboardColumn extends UIBlock
{
public const BLOCK_CODE = 'ibo-dashboard-column';
public const HTML_TEMPLATE_REL_PATH = 'layouts/dashboard/column/layout';
/** @var UIBlock[] */
protected $aUIBlocks;
/** @var int */
protected $iColumnIndex;
/** @var int */
protected $iCellIndex;
/** @var bool */
protected $bEditMode;
/** @var bool */
protected $bLastRow;
public function __construct(bool $bEditMode = false, bool $bLastRow = false)
{
parent::__construct();
$this->aUIBlocks = [];
$this->iColumnIndex = 0;
$this->iCellIndex = 0;
$this->bEditMode = $bEditMode;
$this->bLastRow = $bLastRow;
}
/**
*
* @param UIBlock $oUIBlock
*
* @return DashboardColumn
*/
public function AddUIBlock(UIBlock $oUIBlock): DashboardColumn
{
$this->aUIBlocks[] = $oUIBlock;
return $this;
}
public function GetSubBlocks()
{
return $this->aUIBlocks;
}
/**
* @return int
*/
public function GetColumnIndex(): int
{
return $this->iColumnIndex;
}
/**
* @param int $iColumnIndex
*
* @return DashboardColumn
*/
public function SetColumnIndex(int $iColumnIndex): DashboardColumn
{
$this->iColumnIndex = $iColumnIndex;
return $this;
}
/**
* @return bool
*/
public function IsEditMode(): bool
{
return $this->bEditMode;
}
/**
* @param bool $bEditMode
*
* @return DashboardColumn
*/
public function SetEditMode(bool $bEditMode): DashboardColumn
{
$this->bEditMode = $bEditMode;
return $this;
}
/**
* @return int
*/
public function GetCellIndex(): int
{
return $this->iCellIndex;
}
/**
* @param int $iCellIndex
*
* @return DashboardColumn
*/
public function SetCellIndex(int $iCellIndex): DashboardColumn
{
$this->iCellIndex = $iCellIndex;
return $this;
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\Dashboard;
use Combodo\iTop\Application\UI\UIBlock;
class DashboardLayout extends UIBlock
{
public const BLOCK_CODE = 'ibo-dashboard';
public const HTML_TEMPLATE_REL_PATH = 'layouts/dashboard/layout';
/** @var DashboardRow[] */
protected $aDashboardRows;
/** @var int */
protected $iRows;
public function __construct(?string $sId = null)
{
parent::__construct($sId);
$this->aDashboardRows = [];
$this->iRows = 0;
}
/**
*
* @param \Combodo\iTop\Application\UI\Layout\Dashboard\DashboardRow $oDashboardRow
*
* @return DashboardLayout
*/
public function AddDashboardRow(DashboardRow $oDashboardRow): DashboardLayout
{
$oDashboardRow->SetRowIndex($this->iRows);
$this->aDashboardRows[] = $oDashboardRow;
$this->iRows++;
return $this;
}
public function GetSubBlocks()
{
return $this->aDashboardRows;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\UI\Layout\Dashboard;
use Combodo\iTop\Application\UI\UIBlock;
class DashboardRow extends UIBlock
{
public const BLOCK_CODE = 'ibo-dashboard-row';
public const HTML_TEMPLATE_REL_PATH = 'layouts/dashboard/row/layout';
/** @var DashboardColumn[] */
protected $aDashboardColumns;
/** @var int */
protected $iRowIndex;
/** @var int */
protected $iCols;
public function __construct(?string $sId = null)
{
parent::__construct($sId);
$this->aDashboardColumns = [];
$this->iRowIndex = 0;
$this->iCols = 0;
}
/**
*
* @param \Combodo\iTop\Application\UI\Layout\Dashboard\DashboardColumn $oDashboardColumn
*
* @return DashboardRow
*/
public function AddDashboardColumn(DashboardColumn $oDashboardColumn): DashboardRow
{
$oDashboardColumn->SetColumnIndex($this->iCols);
$this->aDashboardColumns[] = $oDashboardColumn;
$this->iCols++;
return $this;
}
public function GetSubBlocks()
{
return $this->aDashboardColumns;
}
/**
* @return int
*/
public function GetRowIndex(): int
{
return $this->iRowIndex;
}
/**
* @param int $iRowIndex
*
* @return DashboardRow
*/
public function SetRowIndex(int $iRowIndex): DashboardRow
{
$this->iRowIndex = $iRowIndex;
return $this;
}
}

View File

@@ -1,3 +1,6 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{# Content Block #}
{% apply spaceless %}
{% block iboContentBlockContainer %}

View File

@@ -0,0 +1,21 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{# Dashboard Column #}
{% apply spaceless %}
{% if oUIBlock.IsEditMode() %}
{% if oUIBlock.IsLastRow() %}
{% set sCellClass = "layout_cell edit_mode layout_extension" %}
{% else %}
{% set sCellClass = "layout_cell edit_mode" %}
{% endif %}
{% else %}
{% set sCellClass = "dashboard" %}
{% endif %}
<div class="ibo-dashboard--grid-column ibo-dashboard--grid-cell {{ sCellClass }}"
data-dashboard-grid-column-index="{{ oUIBlock.GetColumnIndex() }}"
data-dashboard-grid-cell-index="{{ oUIBlock.GetCellIndex() }}">
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }}
{% endfor %}
</div>
{% endapply %}

View File

@@ -0,0 +1,10 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{# Dashboard Layout #}
{% apply spaceless %}
<div class="ibo-dashboard--grid">
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }}
{% endfor %}
</div>
{% endapply %}

View File

@@ -0,0 +1,10 @@
{# @copyright Copyright (C) 2010-2020 Combodo SARL #}
{# @license http://opensource.org/licenses/AGPL-3.0 #}
{# Dashboard Row #}
{% apply spaceless %}
<div class="ibo-dashboard--grid-row" data-dashboard-grid-row-index="{{ oUIBlock.GetRowIndex() }}">
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }}
{% endfor %}
</div>
{% endapply %}