diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php index a43f9d7ee..99a301e35 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php @@ -30,6 +30,7 @@ use BinaryExpression; use CMDBSource; use Combodo\iTop\Portal\Brick\AbstractBrick; use Combodo\iTop\Portal\Brick\ManageBrick; +use Combodo\iTop\Portal\Helper\ApplicationHelper; use DBObject; use DBObjectSet; use DBSearch; @@ -592,6 +593,9 @@ class ManageBrickController extends BrickController /** @var DBObject $oCurrentRow */ while ($oCurrentRow = $oSet->Fetch()) { + $sCurrentObjectClass = get_class($oCurrentRow); + $sCurrentObjectId = $oCurrentRow->GetKey(); + // ... Retrieving item's attributes values $aItemAttrs = array(); foreach ($aColumnsAttrs as $sItemAttr) @@ -631,6 +635,7 @@ class ManageBrickController extends BrickController /** @var \AttributeDefinition $oAttDef */ $oAttDef = MetaModel::GetAttributeDef($sCurrentClass, $sItemAttr); + $sAttDefClass = get_class($oAttDef); if ($oAttDef->IsExternalKey()) { /** @var \AttributeExternalKey $oAttDef */ @@ -688,9 +693,25 @@ class ManageBrickController extends BrickController } unset($oAttDef); + // For simple fields, we get the raw (stored) value as well + $bExcludeRawValue = false; + foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) + { + if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) + { + $bExcludeRawValue = true; + break; + } + } + $attValueRaw = ($bExcludeRawValue === false) ? $oCurrentRow->Get($sItemAttr) : null; + $aItemAttrs[$sItemAttr] = array( - 'att_code' => $sItemAttr, - 'value' => $sValue, + 'object_class' => $sCurrentObjectClass, + 'object_id' => $sCurrentObjectId, + 'attribute_code' => $sItemAttr, + 'attribute_type' => $sAttDefClass, + 'value_raw' => $attValueRaw, + 'value_html' => $sValue, 'sort_value' => $sSortValue, 'actions' => $aActions, ); diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php index 1e2857eb0..8a021cb02 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php @@ -469,4 +469,23 @@ class ApplicationHelper return $aForm; } + /** + * Return an array of AttributeDefinition classes for which the raw value should be excluded from the markup meta (because its too big / complex) + * IMPORTANT: This needs to be refactored when the portal will handle attributes display in a better way. Also this is a duplicate from cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as for the moment we have no clean place to put this. + * + * @return array + * @since 2.7.0 + */ + public static function GetAttDefClassesToExcludeFromMarkupMetadataRawValue(){ + return array( + 'AttributeBlob', + 'AttributeCustomFields', + 'AttributeDashboard', + 'AttributeLinkedSet', + 'AttributeStopWatch', + 'AttributeSubItem', + 'AttributeTable', + 'AttributeText' + ); + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php index 37031857a..3de26bc5b 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php @@ -322,12 +322,26 @@ class BrowseBrickHelper // Retrieving objects from all levels $aItems = array_values($aCurrentRow); + $sCurrentObjectClass = get_class($value); + $sCurrentObjectId = $value->GetKey(); + + $sNameAttCode = $aLevelsProperties[$key]['name_att']; + $sNameAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $sNameAttCode); + $sNameAttDefClass = get_class($sNameAttDef); + $aRow[$key] = array( 'level_alias' => $key, - 'id' => $value->GetKey(), - 'name' => $value->Get($aLevelsProperties[$key]['name_att']), - 'class' => get_class($value), + 'id' => $sCurrentObjectId, + 'name' => $value->Get($sNameAttCode), + 'class' => $sCurrentObjectClass, 'action_rules_token' => $this->PrepareActionRulesForItems($aItems, $key, $aLevelsProperties), + 'metadata' => array( + 'object_class' => $sCurrentObjectClass, + 'object_id' => $sCurrentObjectId, + 'attribute_code' => $sNameAttCode, + 'attribute_type' => $sNameAttDefClass, + 'value_raw' => $value->Get($sNameAttCode), + ), ); // Adding optional attributes if necessary @@ -336,7 +350,7 @@ class BrowseBrickHelper if ($aLevelsProperties[$key][$sOptionalAttribute] !== null) { $sPropertyName = substr($sOptionalAttribute, 0, -4); - $oAttDef = MetaModel::GetAttributeDef(get_class($value), $aLevelsProperties[$key][$sOptionalAttribute]); + $oAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $aLevelsProperties[$key][$sOptionalAttribute]); if ($oAttDef instanceof AttributeImage) { @@ -346,8 +360,8 @@ class BrowseBrickHelper if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty()) { $tmpAttValue = $this->oUrlGenerator->generate('p_object_document_display', array( - 'sObjectClass' => get_class($value), - 'sObjectId' => $value->GetKey(), + 'sObjectClass' => $sCurrentObjectClass, + 'sObjectId' => $sCurrentObjectId, 'sObjectField' => $aLevelsProperties[$key][$sOptionalAttribute], 'cache' => 86400, )); @@ -372,7 +386,8 @@ class BrowseBrickHelper $aRow[$key]['fields'] = array(); foreach ($aLevelsProperties[$key]['fields'] as $aField) { - $oAttDef = MetaModel::GetAttributeDef(get_class($value), $aField['code']); + $oAttDef = MetaModel::GetAttributeDef($sCurrentObjectClass, $aField['code']); + $sAttDefClass = get_class($oAttDef); switch (true) { @@ -390,8 +405,8 @@ class BrowseBrickHelper if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty()) { $sUrl = $this->oUrlGenerator->generate('p_object_document_display', array( - 'sObjectClass' => get_class($value), - 'sObjectId' => $value->GetKey(), + 'sObjectClass' => $sCurrentObjectClass, + 'sObjectId' => $sCurrentObjectId, 'sObjectField' => $aField['code'], 'cache' => 86400, )); @@ -408,7 +423,26 @@ class BrowseBrickHelper break; } - $aRow[$key]['fields'][$aField['code']] = $sHtmlForFieldValue; + // For simple fields, we get the raw (stored) value as well + $bExcludeRawValue = false; + foreach (ApplicationHelper::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) + { + if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) + { + $bExcludeRawValue = true; + break; + } + } + $attValueRaw = ($bExcludeRawValue === false) ? $value->Get($aField['code']) : null; + + $aRow[$key]['fields'][$aField['code']] = array( + 'object_class' => $sCurrentObjectClass, + 'object_id' => $sCurrentObjectId, + 'attribute_code' => $aField['code'], + 'attribute_type' => $sAttDefClass, + 'value_raw' => $attValueRaw, + 'value_html' => $sHtmlForFieldValue, + ); } } } diff --git a/datamodels/2.x/itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig index d796b2166..d9aeeef4d 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig @@ -67,7 +67,14 @@ // Preparing the cell data cellElem = (levelActionsKeys.length > 0) ? $('') : $(''); cellElem.attr('data-item-id', data.id).attr('data-level-alias', data.level_alias); - + + // Building metadata + for(var sPropName in data.metadata) + { + var propValue = data.metadata[sPropName]; + cellElem.attr('data-'+sPropName.replace('_', '-'), propValue); + } + // Building tooltip for the node // We have to concatenate the HTML as we return the raw HTML of the cell. If we did a jQuery.insertAfter, the tooltip would not be returned. // For the same reason, tooltip widget is created in "drawCallback" instead of here. @@ -187,7 +194,26 @@ "title": oLevelsProperties[sKey].fields[i].label, "defaultContent": "", "type": "html", - "data": oLevelsProperties[sKey].alias+".fields."+oLevelsProperties[sKey].fields[i].code + "data": oLevelsProperties[sKey].alias+".fields."+oLevelsProperties[sKey].fields[i].code, + "render": function(data, type, row){ + var cellElem = $(''); + + // Building value and metadata + for(var sPropName in data) + { + var sPropValue = data[sPropName]; + if(sPropName === 'value_html') + { + cellElem.html(sPropValue); + } + else + { + cellElem.attr('data-'+sPropName.replace('_', '-'), sPropValue); + } + } + + return cellElem.prop('outerHTML'); + }, }); } } diff --git a/datamodels/2.x/itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig index b923001a3..132e6d4e5 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig @@ -8,7 +8,7 @@ {% if aGroupingTabsValues|length > 1 %}