Modified the "List" tab of the Impact Analysis to display only the actually impacted objects. The content of this tab is now refreshed every time the graph is rebuilt to take into account the "context" changes which causes the actual impact to change, or the filtering.

SVN:trunk[3941]
This commit is contained in:
Denis Flaven
2016-03-09 18:05:14 +00:00
parent daa090d4fe
commit 67c92ab946
4 changed files with 89 additions and 2 deletions

View File

@@ -1116,7 +1116,7 @@ class DisplayableGraph extends SimpleGraph
{
$aContextDefs = static::GetContextDefinitions($sContextKey, false);
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array());
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array(), 'lists' => array());
$iGroupIdx = 0;
$oIterator = new RelationTypeIterator($this, 'Node');
foreach($oIterator as $sId => $oNode)
@@ -1139,10 +1139,35 @@ class DisplayableGraph extends SimpleGraph
$aData['groups'][$iGroupIdx] = array('class' => $sClass, 'keys' => $aKeys);
$oNode->SetProperty('group_index', $iGroupIdx);
$iGroupIdx++;
if ($oNode->GetProperty('is_reached'))
{
// Also add the objects from this group into the 'list' tab
if (!array_key_exists($sClass, $aData['lists']))
{
$aData['lists'][$sClass] = $aKeys;
}
else
{
$aData['lists'][$sClass] = array_merge($aData['lists'][$sClass], $aKeys);
}
}
}
if (($oNode instanceof DisplayableNode) && $oNode->GetProperty('is_reached') && is_object($oNode->GetProperty('object')))
{
$sObjClass = get_class($oNode->GetProperty('object'));
if (!array_key_exists($sObjClass, $aData['lists']))
{
$aData['lists'][$sObjClass] = array();
}
$aData['lists'][$sObjClass][] = $oNode->GetProperty('object')->GetKey();
}
$aData['nodes'][] = $oNode->GetForRaphael($aContextDefs);
}
uksort($aData['lists'], array(get_class($this), 'SortOnClassLabel')); // sort on the localized names of the classes to provide a consistent and stable order
$oIterator = new RelationTypeIterator($this, 'Edge');
foreach($oIterator as $sId => $oEdge)
{
@@ -1158,6 +1183,17 @@ class DisplayableGraph extends SimpleGraph
return json_encode($aData);
}
/**
* Sort class "codes" based on their localized name
* @param string $sClass1
* @param string $sClass2
* @return number -1, 0 or 1
*/
public static function SortOnClassLabel($sClass1, $sClass2)
{
return strcasecmp(MetaModel::GetName($sClass1), MetaModel::GetName($sClass2));
}
/**
* Renders the graph in a PDF document: centered in the current page
* @param PDFPage $oPage The PDFPage representing the PDF document to draw into

View File

@@ -720,6 +720,10 @@ $(function()
{
this.refresh_groups(oData.groups);
}
if (oData.lists)
{
this.refresh_lists(oData.lists);
}
if (this.element.is(':visible'))
{
this._updateBBox();
@@ -754,6 +758,25 @@ $(function()
}
}
},
refresh_lists: function(aLists)
{
if ($('#impacted_objects_lists').length > 0)
{
// The "Lists" tab is present, refresh it
if (aLists.length == 0)
{
$('#impacted_objects_lists').html('');
}
else
{
$('#impacted_objects_lists').html('<img src="../images/indicator.gif">');
var sUrl = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php';
$.post(sUrl, { operation: 'relation_lists', lists: aLists }, function(data) {
$('#impacted_objects_lists').html(data);
});
}
}
},
_reset_pan_and_zoom: function()
{
this.xPan = 0;

View File

@@ -230,6 +230,11 @@ function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
$sOldRelation = 'depends on';
}
$oP->add("<h1>".MetaModel::GetRelationDescription($sOldRelation).' '.$oObj->GetName()."</h1>\n");
$oP->add("<div id=\"impacted_objects_lists\">");
/*
* Content is rendered asynchronously via pages/ajax.render.php?operation=relation_lists
*/
/*
$iBlock = 1; // Zero is not a valid blockid
foreach($aResults as $sListClass => $aObjects)
{
@@ -241,6 +246,8 @@ function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
$oBlock->Display($oP, $iBlock++, array('table_id' => get_class($oObj).'_'.$sRelation.'_'.$sDirection.'_'.$sListClass));
$oP->P('&nbsp;'); // Some space ?
}
*/
$oP->add("</div>");
$oP->add("</div>");
}
@@ -1518,6 +1525,10 @@ EOF
}
}
}
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/tabularfieldsselector.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.dragtable.js');
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/dragtable.css');
// Display the tabs
if ($sFirstTab == 'list')
{

View File

@@ -2011,7 +2011,24 @@ EOF
$oPage->p('&nbsp;'); // Some space ?
}
break;
case 'relation_lists':
$aLists = utils::ReadParam('lists');
$iBlock = 1; // Zero is not a valid blockid
foreach($aLists as $sListClass => $aKeys)
{
$oSearch = new DBObjectSearch($sListClass);
$oSearch->AddCondition('id', $aKeys, 'IN');
$oPage->add("<div class=\"page_header\">\n");
$oPage->add("<h2>".MetaModel::GetClassIcon($sListClass)."&nbsp;<span class=\"hilite\">".Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aKeys), Metamodel::GetName($sListClass))."</h2>\n");
$oPage->add("</div>\n");
$oBlock = new DisplayBlock($oSearch, 'list');
$oBlock->Display($oPage, 'list_'.$iBlock++, array('table_id' => 'ImpactAnalysis_'.$sListClass));
$oPage->p('&nbsp;'); // Some space ?
}
break;
case 'ticket_impact':
require_once(APPROOT.'core/simplegraph.class.inc.php');
require_once(APPROOT.'core/relationgraph.class.inc.php');