diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 0e75a5662..f1e5a6f15 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -415,75 +415,8 @@ class DisplayBlock switch($this->m_sStyle) { case 'count': - if (isset($aExtraParams['group_by'])) - { - $this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql); - - $aRes = CMDBSource::QueryToArray($sSql); - - $aGroupBy = array(); - $aLabels = array(); - $aValues = array(); - $iTotalCount = 0; - foreach ($aRes as $iRow => $aRow) - { - $sValue = $aRow['grouped_by_1']; - $aValues[$iRow] = $sValue; - $sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue); - $aLabels[$iRow] = $sHtmlValue; - $aGroupBy[$iRow] = (int) $aRow[$sFctVar]; - $iTotalCount += $aRow['_itop_count_']; - } - - - $aData = array(); - $oAppContext = new ApplicationContext(); - $sParams = $oAppContext->GetForLink(); - foreach($aGroupBy as $iRow => $iCount) - { - // Build the search for this subset - $oSubsetSearch = $this->m_oFilter->DeepClone(); - $oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($aValues[$iRow])); - $oSubsetSearch->AddConditionExpression($oCondition); - if (isset($aExtraParams['query_params'])) - { - $aQueryParams = $aExtraParams['query_params']; - } - else - { - $aQueryParams = array(); - } - $sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams)); - - $aData[] = array ('group' => $aLabels[$iRow], - 'value' => "$iCount"); // TO DO: add the context information - } - $aAttribs =array( - 'group' => array('label' => $sGroupByLabel, 'description' => ''), - 'value' => array( - 'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction), - 'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr), - ), - ); - $sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection'; - $sHtml .= $oPage->GetP(Dict::Format($sFormat, $iTotalCount)); - $sHtml .= $oPage->GetTable($aAttribs, $aData); - - $oPage->add_ready_script("LoadGroupBySortOrder('$sId');\n$('#{$sId} table.listResults').unbind('sortEnd.group_by').bind('sortEnd.group_by', function() { SaveGroupBySortOrder('$sId', $(this)[0].config.sortList); })"); - } - else - { - // Simply count the number of elements in the set - $iCount = $this->m_oSet->Count(); - $sFormat = 'UI:CountOfObjects'; - if (isset($aExtraParams['format'])) - { - $sFormat = $aExtraParams['format']; - } - $sHtml .= $oPage->GetP(Dict::Format($sFormat, $iCount)); - } - - break; + $oBlock = $this->RenderCount($aExtraParams, $oPage, $sId); + break; case 'join': $aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']): array(); @@ -1382,6 +1315,83 @@ JS return $oBlock; } + + /** + * @param array $aExtraParams + * @param \WebPage $oPage + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\iUIBlock + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \Exception + */ + protected function RenderCount(array $aExtraParams, WebPage $oPage, ?string $sId): iUIBlock + { + if (isset($aExtraParams['group_by'])) { + $this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql); + + $aRes = CMDBSource::QueryToArray($sSql); + + $aGroupBy = array(); + $aLabels = array(); + $aValues = array(); + $iTotalCount = 0; + foreach ($aRes as $iRow => $aRow) { + $sValue = $aRow['grouped_by_1']; + $aValues[$iRow] = $sValue; + $sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue); + $aLabels[$iRow] = $sHtmlValue; + $aGroupBy[$iRow] = (int)$aRow[$sFctVar]; + $iTotalCount += $aRow['_itop_count_']; + } + + $aData = array(); + $oAppContext = new ApplicationContext(); + $sParams = $oAppContext->GetForLink(); + foreach ($aGroupBy as $iRow => $iCount) { + // Build the search for this subset + $oSubsetSearch = $this->m_oFilter->DeepClone(); + $oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($aValues[$iRow])); + $oSubsetSearch->AddConditionExpression($oCondition); + if (isset($aExtraParams['query_params'])) { + $aQueryParams = $aExtraParams['query_params']; + } else { + $aQueryParams = array(); + } + $sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams)); + + $aData[] = array( + 'group' => $aLabels[$iRow], + 'value' => "$iCount" + ); // TO DO: add the context information + } + $aAttribs = array( + 'group' => array('label' => $sGroupByLabel, 'description' => ''), + 'value' => array( + 'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction), + 'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr), + ), + ); + $sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection'; + $sTitle = Dict::Format($sFormat, $iTotalCount); + $oBlock = DataTableFactory::MakeForStaticData($sTitle, $aAttribs, $aData); + + // $oPage->add_ready_script("LoadGroupBySortOrder('$sId');\n$('#{$sId} table.listResults').unbind('sortEnd.group_by').bind('sortEnd.group_by', function() { SaveGroupBySortOrder('$sId', $(this)[0].config.sortList); })"); + } else { + // Simply count the number of elements in the set + $iCount = $this->m_oSet->Count(); + $sFormat = 'UI:CountOfObjects'; + if (isset($aExtraParams['format'])) { + $sFormat = $aExtraParams['format']; + } + $oBlock = new Html($oPage->GetP(Dict::Format($sFormat, $iCount))); + } + return $oBlock; +} } /** diff --git a/css/backoffice/components/_datatable.scss b/css/backoffice/components/_datatable.scss index 6ad6b0644..93c645fba 100644 --- a/css/backoffice/components/_datatable.scss +++ b/css/backoffice/components/_datatable.scss @@ -72,7 +72,7 @@ } .ibo-datatable-toolbar { /*position: relative;*/ - height: 30px; + //height: 30px; } .ibo-criterion-area{ font-size: $ibo-font-size-50 ; diff --git a/dictionaries/ui/components/en.dictionary.itop.datatable.php b/dictionaries/ui/components/en.dictionary.itop.datatable.php index 9268242d4..281bed56f 100644 --- a/dictionaries/ui/components/en.dictionary.itop.datatable.php +++ b/dictionaries/ui/components/en.dictionary.itop.datatable.php @@ -21,9 +21,9 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Datatables:Language:Processing' => 'Please wait...', 'UI:Datatables:Language:Search' => 'Filter:', - 'UI:Datatables:Language:LengthMenu' => 'Showing _MENU_ out', + 'UI:Datatables:Language:LengthMenu' => 'Showing _MENU_ out of', 'UI:Datatables:Language:ZeroRecords' => 'No result', - 'UI:Datatables:Language:Info' => 'of _TOTAL_ items', + 'UI:Datatables:Language:Info' => '_TOTAL_ items', 'UI:Datatables:Language:InfoEmpty' => 'No information', 'UI:Datatables:Language:InfoFiltered' => 'filtered out of _MAX_ items', 'UI:Datatables:Language:EmptyTable' => 'No data available in this table', diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 757f2dc5a..bedd4f246 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -164,6 +164,7 @@ return array( 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableBlock' => $baseDir . '/sources/application/UI/Component/DataTable/DataTable.php', 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableFactory' => $baseDir . '/sources/application/UI/Component/DataTable/DataTableFactory.php', 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableSettings' => $baseDir . '/sources/application/UI/Component/DataTable/DataTableSettings.php', + 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\StaticTable\\StaticTable' => $baseDir . '/sources/application/UI/Component/DataTable/StaticTable/StaticTable.php', 'Combodo\\iTop\\Application\\UI\\Component\\FieldSet\\FieldSet' => $baseDir . '/sources/application/UI/Component/FieldSet/FieldSet.php', 'Combodo\\iTop\\Application\\UI\\Component\\Field\\Field' => $baseDir . '/sources/application/UI/Component/Field/Field.php', 'Combodo\\iTop\\Application\\UI\\Component\\Form\\Form' => $baseDir . '/sources/application/UI/Component/Form/Form.php', diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index a88877f24..a892eca86 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -394,6 +394,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableBlock' => __DIR__ . '/../..' . '/sources/application/UI/Component/DataTable/DataTable.php', 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/DataTable/DataTableFactory.php', 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\DataTableSettings' => __DIR__ . '/../..' . '/sources/application/UI/Component/DataTable/DataTableSettings.php', + 'Combodo\\iTop\\Application\\UI\\Component\\DataTable\\StaticTable\\StaticTable' => __DIR__ . '/../..' . '/sources/application/UI/Component/DataTable/StaticTable/StaticTable.php', 'Combodo\\iTop\\Application\\UI\\Component\\FieldSet\\FieldSet' => __DIR__ . '/../..' . '/sources/application/UI/Component/FieldSet/FieldSet.php', 'Combodo\\iTop\\Application\\UI\\Component\\Field\\Field' => __DIR__ . '/../..' . '/sources/application/UI/Component/Field/Field.php', 'Combodo\\iTop\\Application\\UI\\Component\\Form\\Form' => __DIR__ . '/../..' . '/sources/application/UI/Component/Form/Form.php', diff --git a/sources/application/UI/Component/DataTable/DataTableFactory.php b/sources/application/UI/Component/DataTable/DataTableFactory.php index 70bb2b3e6..8544d93aa 100644 --- a/sources/application/UI/Component/DataTable/DataTableFactory.php +++ b/sources/application/UI/Component/DataTable/DataTableFactory.php @@ -10,7 +10,9 @@ use ApplicationException; use AttributeLinkedSet; use CMDBObjectSet; use cmdbAbstractObject; +use Combodo\iTop\Application\UI\Component\DataTable\StaticTable\StaticTable; use Combodo\iTop\Application\UI\Component\Panel\PanelFactory; +use Combodo\iTop\Application\UI\Component\Title\TitleFactory; use MetaModel; use appUserPreferences; use UserRights; @@ -639,7 +641,19 @@ class DataTableFactory } )' ]; - return $aOptions; } + + public static function MakeForStaticData(string $sTitle, array $aColumns, array $aData, ?string $sId = null) + { + $oBlock = new UIContentBlock(); + $oTitle = TitleFactory::MakeNeutral($sTitle, 3); + $oBlock->AddSubBlock($oTitle); + $oTable = new StaticTable($sId); + $oTable->SetColumns($aColumns); + $oTable->SetData($aData); + $oBlock->AddSubBlock($oTable); + + return $oBlock; + } } \ No newline at end of file diff --git a/sources/application/UI/Component/DataTable/StaticTable/StaticTable.php b/sources/application/UI/Component/DataTable/StaticTable/StaticTable.php new file mode 100644 index 000000000..64aaa5a55 --- /dev/null +++ b/sources/application/UI/Component/DataTable/StaticTable/StaticTable.php @@ -0,0 +1,83 @@ + [ + * 'description' => tooltip, + * 'label' => label to display, + * 'class' => cell CSS class, + * 'metadata' => [key => value] transformed into data-key="value" + * ] + */ + private $aColumns; + + /** + * @var array of [ + * '@class' => css class of the row, + * 'entry name' => [ + * 'value_html' => value to display in the cell, + * 'value_raw' => real value put into data-value-raw + * ], ... + * ] + */ + private $aData; + + public function __construct(string $sId = null, string $sContainerCSSClass = '') + { + parent::__construct($sId, $sContainerCSSClass); + $this->aColumns = []; + $this->aData = []; + } + + /** + * @return array + */ + public function GetColumns(): array + { + return $this->aColumns; + } + + /** + * @param array $aColumns + */ + public function SetColumns(array $aColumns): void + { + $this->aColumns = $aColumns; + } + + /** + * @return array + */ + public function GetData(): array + { + return $this->aData; + } + + /** + * @param array $aData + */ + public function SetData(array $aData): void + { + $this->aData = $aData; + } + +} \ No newline at end of file diff --git a/sources/application/UI/Component/Title/TitleFactory.php b/sources/application/UI/Component/Title/TitleFactory.php index 37123bca1..5e4fbcc00 100644 --- a/sources/application/UI/Component/Title/TitleFactory.php +++ b/sources/application/UI/Component/Title/TitleFactory.php @@ -62,4 +62,9 @@ class TitleFactory return $oTitle; } + + public static function MakeNeutral(string $sTitle, int $iLevel = 1, ?string $sId = null) + { + return new Title($sTitle, $iLevel, $sId); + } } \ No newline at end of file diff --git a/templates/components/datatable/static/layout.html.twig b/templates/components/datatable/static/layout.html.twig new file mode 100644 index 000000000..3527d1ad4 --- /dev/null +++ b/templates/components/datatable/static/layout.html.twig @@ -0,0 +1,48 @@ +{# @copyright Copyright (C) 2010-2020 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} + +{% set columns = oUIBlock.GetColumns() %} +
| {{ column.label }} | + {% endfor %} +
|---|
| {{ cellValueHtml|raw }} | + {% endfor %} +