mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Allow to filter which class(es) of objects are displayed in the graphical impact analysis view
SVN:trunk[1741]
This commit is contained in:
@@ -886,6 +886,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:RelationshipGraph' => 'Graphical view',
|
||||
'UI:RelationshipList' => 'List',
|
||||
'UI:OperationCancelled' => 'Operation Cancelled',
|
||||
'UI:ElementsDisplayed' => 'Filtering',
|
||||
|
||||
'Portal:Title' => 'iTop user portal',
|
||||
'Portal:Refresh' => 'Refresh',
|
||||
|
||||
@@ -730,7 +730,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:DisplayThisMessageAtStartup' => 'Afficher ce message au démarrage',
|
||||
'UI:RelationshipGraph' => 'Vue graphique',
|
||||
'UI:RelationshipList' => 'Liste',
|
||||
'UI:ElementsDisplayed' => 'Eléments Affichés',
|
||||
'UI:ElementsDisplayed' => 'Filtrage',
|
||||
'UI:OperationCancelled' => 'Opération Annulée',
|
||||
'Portal:Title' => 'Portail utilisateur iTop',
|
||||
'Portal:Refresh' => 'Rafraîchir',
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import fl.controls.Slider;
|
||||
import fl.events.SliderEvent;
|
||||
import fl.controls.Label;
|
||||
// For callbacks from Javascript
|
||||
import flash.external.ExternalInterface;
|
||||
|
||||
// The main canvas
|
||||
public class Navigator extends MovieClip
|
||||
@@ -26,6 +28,7 @@
|
||||
protected var m_sRelation:String;
|
||||
protected var m_sObjClass:String;
|
||||
protected var m_sObjId:String;
|
||||
protected var m_sExclude:String;
|
||||
|
||||
// Constants
|
||||
protected var m_RADIUS = 150;
|
||||
@@ -43,14 +46,60 @@
|
||||
{
|
||||
m_aLinks = new Array();
|
||||
m_aNodes = new Array();
|
||||
m_sExclude = '';
|
||||
m_fZoom = 1;
|
||||
initParameters();
|
||||
doLoadData();
|
||||
var success = true;
|
||||
if (ExternalInterface.available)
|
||||
{
|
||||
//Security.allowDomain(loader.contentLoaderInfo.url);
|
||||
//the addCallback registers a function to be called from javascript, and this is what you wanted to do:
|
||||
try
|
||||
{
|
||||
ExternalInterface.addCallback("Filter", DoFilter);
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
m_sTitle.text = 'E: '+err.description;
|
||||
success = false
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
//m_sTitle.text = 'Ok...';
|
||||
doLoadData();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sTitle.text = 'Failed to addCallback';
|
||||
}
|
||||
|
||||
addEventListener(Event.ENTER_FRAME, initGraphics);
|
||||
//Stop scaling the flash content
|
||||
stage.scaleMode = StageScaleMode.NO_SCALE;
|
||||
}
|
||||
|
||||
function Reset()
|
||||
{
|
||||
m_aLinks = new Array();
|
||||
for (var i:String in m_aNodes)
|
||||
{
|
||||
m_oCanvas.removeChild(m_aNodes[i]);
|
||||
}
|
||||
m_aNodes = new Array();
|
||||
removeEventListener(Event.ENTER_FRAME, drawLines);
|
||||
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown)
|
||||
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseReleased);
|
||||
}
|
||||
|
||||
function DoFilter(sExcludeList:String):void
|
||||
{
|
||||
//do something
|
||||
m_sExclude = sExcludeList;
|
||||
doLoadData();
|
||||
}
|
||||
|
||||
protected function initParameters():void
|
||||
{
|
||||
|
||||
@@ -70,6 +119,8 @@
|
||||
m_oCanvas.scaleY = m_fZoom;
|
||||
// Handle listeners...
|
||||
removeEventListener(Event.ENTER_FRAME,initGraphics);
|
||||
m_oZoomSlider.value = 100;
|
||||
m_oZoomSlider.addEventListener(SliderEvent.CHANGE, onZoomChange);
|
||||
}
|
||||
function mouseDown(event:MouseEvent):void
|
||||
{
|
||||
@@ -99,19 +150,22 @@
|
||||
m_oCanvas.scaleX = m_fZoom;
|
||||
m_oCanvas.scaleY = m_fZoom;
|
||||
}
|
||||
function GetZommLevel()
|
||||
function GetZoomLevel()
|
||||
{
|
||||
return m_fZoom;
|
||||
}
|
||||
|
||||
function doLoadData()
|
||||
{
|
||||
m_sTitle.text = "Loading...";
|
||||
m_oPreloader.visible = true;
|
||||
m_oZoomSlider.enabled = true;
|
||||
var sSeparator:String = '?';
|
||||
if (m_sDataUrl.indexOf(sSeparator) != -1)
|
||||
{
|
||||
sSeparator = '&';
|
||||
}
|
||||
var myString:String = m_sDataUrl+sSeparator+'relation='+m_sRelation+'&class='+m_sObjClass+'&id='+m_sObjId;
|
||||
var myString:String = m_sDataUrl+sSeparator+'relation='+m_sRelation+'&class='+m_sObjClass+'&id='+m_sObjId+'&exclude='+m_sExclude;
|
||||
trace("Requesting:"+myString);
|
||||
var myXMLURL:URLRequest = new URLRequest(myString);
|
||||
m_oLoader = new URLLoader();
|
||||
@@ -125,6 +179,7 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
Reset();
|
||||
var myXML:XML = XML(m_oLoader.data);
|
||||
//trace("Data loaded." + myXML);
|
||||
//trace("===========================");
|
||||
@@ -132,8 +187,6 @@
|
||||
m_sTitle.text = decodeEntities(myXML.attribute("title").toString());
|
||||
m_oZoomSlider.enabled = true;
|
||||
addEventListener(Event.ENTER_FRAME, drawLines);
|
||||
m_oZoomSlider.value = 100;
|
||||
m_oZoomSlider.addEventListener(SliderEvent.CHANGE, onZoomChange);
|
||||
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown)
|
||||
stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
|
||||
//trace('======= Initial Posistions =========');
|
||||
@@ -155,8 +208,7 @@
|
||||
{
|
||||
if (m_oPreloader != null)
|
||||
{
|
||||
removeChild(m_oPreloader);
|
||||
m_oPreloader = null;
|
||||
m_oPreloader.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,8 +217,7 @@
|
||||
{
|
||||
if (m_oPreloader != null)
|
||||
{
|
||||
removeChild(m_oPreloader);
|
||||
m_oPreloader = null;
|
||||
m_oPreloader.visible = false;
|
||||
}
|
||||
m_sTitle.text = "I/O Error: unable to load the graph data ("+event+")";
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
86
pages/UI.php
86
pages/UI.php
@@ -2029,25 +2029,101 @@ EOF
|
||||
$oP->AddTabContainer('Navigator');
|
||||
$oP->SetCurrentTabContainer('Navigator');
|
||||
$oP->SetCurrentTab(Dict::S('UI:RelationshipGraph'));
|
||||
|
||||
$oP->add("<div id=\"ds_flash\" class=\"SearchDrawer\">\n");
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$("#dh_flash").click( function() {
|
||||
$("#ds_flash").slideToggle('normal', function() { $("#ds_flash").parent().resize(); } );
|
||||
$("#dh_flash").toggleClass('open');
|
||||
});
|
||||
EOF
|
||||
);
|
||||
$aElements = MetaModel::GetSubclasses('FunctionalCI');
|
||||
$aResults = array();
|
||||
$aSortedElements = array();
|
||||
$oObj = MetaModel::GetObject($sClass, $id);
|
||||
$oObj->GetRelatedObjects($sRelation, 20 /* iMaxDepth */, $aResults);
|
||||
foreach($aResults as $sClassIdx => $aObjects)
|
||||
{
|
||||
foreach($aObjects as $oCurrObj)
|
||||
{
|
||||
$sSubClass = get_class($oCurrObj);
|
||||
$aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
|
||||
}
|
||||
}
|
||||
|
||||
asort($aSortedElements);
|
||||
$idx = 0;
|
||||
foreach($aSortedElements as $sSubClass => $sClassName)
|
||||
{
|
||||
$oP->add("<span style=\"padding-right:2em; white-space:nowrap;\"><input type=\"checkbox\" id=\"exclude_$idx\" name=\"excluded[]\" value=\"$sSubClass\" checked onChange=\"DoReload()\"><label for=\"exclude_$idx\"> ".MetaModel::GetClassIcon($sSubClass)." $sClassName</label></span> ");
|
||||
$idx++;
|
||||
}
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("<div class=\"HRDrawer\"></div>\n");
|
||||
$oP->add("<div id=\"dh_flash\" class=\"DrawerHandle\">".Dict::S('UI:ElementsDisplayed')."</div>\n");
|
||||
|
||||
$width = 1000;
|
||||
$height = 700;
|
||||
$sDrillUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&'.$oAppContext->GetForLink();
|
||||
$sParams = "pWidth=$width&pHeight=$height&drillUrl=".urlencode($sDrillUrl)."&displayController=false&xmlUrl=".urlencode("./xml.navigator.php")."&obj_class=$sClass&obj_id=$id&relation=$sRelation";
|
||||
|
||||
$oP->add("<div style=\"z-index:1;background:white\"><object style=\"z-index:2\" classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0\" width=\"$width\" height=\"$height\" id=\"navigator\" align=\"middle\">
|
||||
<param name=\"allowScriptAccess\" value=\"sameDomain\" />
|
||||
$oP->add("<div style=\"z-index:1;background:white;width:100%;height:{$height}px\"><object style=\"z-index:2\" classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0\" width=\"100%\" height=\"$height\" id=\"navigator\" align=\"middle\">
|
||||
<param name=\"allowScriptAccess\" value=\"always\" />
|
||||
<param name=\"allowFullScreen\" value=\"false\" />
|
||||
<param name=\"FlashVars\" value=\"$sParams\" />
|
||||
<param name=\"wmode\" value=\"transparent\">
|
||||
<param name=\"movie\" value=\"../navigator/navigator.swf\" /><param name=\"quality\" value=\"high\" /><param name=\"bgcolor\" value=\"#ffffff\" />
|
||||
<embed src=\"../navigator/navigator.swf\" wmode=\"transparent\" flashVars=\"$sParams\" quality=\"high\" bgcolor=\"#ffffff\" width=\"$width\" height=\"$height\" name=\"navigator\" align=\"middle\" allowScriptAccess=\"sameDomain\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.adobe.com/go/getflashplayer\" />
|
||||
<embed src=\"../navigator/navigator.swf\" wmode=\"transparent\" flashVars=\"$sParams\" quality=\"high\" bgcolor=\"#ffffff\" width=\"100%\" height=\"$height\" name=\"navigator\" align=\"middle\" swliveconnect=\"true\" allowScriptAccess=\"always\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.adobe.com/go/getflashplayer\" />
|
||||
</object></div>\n");
|
||||
$oP->SetCurrentTab(Dict::S('UI:RelationshipList'));
|
||||
$oP->add("<div id=\"impacted_objects\" style=\"width:100%;background-color:#fff;padding:10px;\"><p style=\"height:150px;\"> </p></div>");
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
function getFlashMovieObject(movieName)
|
||||
{
|
||||
if (window.document[movieName])
|
||||
{
|
||||
return window.document[movieName];
|
||||
}
|
||||
if (navigator.appName.indexOf("Microsoft Internet")==-1)
|
||||
{
|
||||
if (document.embeds && document.embeds[movieName])
|
||||
return document.embeds[movieName];
|
||||
}
|
||||
else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
|
||||
{
|
||||
return document.getElementById(movieName);
|
||||
}
|
||||
}
|
||||
|
||||
function DoReload()
|
||||
{
|
||||
var oMovie = getFlashMovieObject('navigator');
|
||||
try
|
||||
{
|
||||
var aExcluded = [];
|
||||
$('input[name^=excluded]').each( function() {
|
||||
if (!$(this).attr('checked'))
|
||||
{
|
||||
aExcluded.push($(this).val());
|
||||
}
|
||||
} );
|
||||
oMovie.Filter(aExcluded.join(','));
|
||||
//oMovie.SetVariable("/:message", "foo");
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
alert(err);
|
||||
}
|
||||
}
|
||||
EOF
|
||||
);
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
var ajax_request = null;
|
||||
|
||||
|
||||
function UpdateImpactedObjects(sClass, iId, sRelation)
|
||||
{
|
||||
var class_name = sClass; //$('select[name=class_name]').val();
|
||||
@@ -2185,4 +2261,4 @@ catch(Exception $e)
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
?>
|
||||
@@ -59,9 +59,10 @@ function AddNodeDetails(&$oNode, $oObj)
|
||||
* @param DBObject $oObj The current object
|
||||
* @param string $sRelation The name of the relation to search with
|
||||
*/
|
||||
function GetRelatedObjectsAsXml(DBObject $oObj, $sRelationName, &$oLinks, &$oXmlDoc, &$oXmlNode, $iDepth = 0)
|
||||
function GetRelatedObjectsAsXml(DBObject $oObj, $sRelationName, &$oLinks, &$oXmlDoc, &$oXmlNode, $iDepth = 0, $aExcludedClasses)
|
||||
{
|
||||
$aResults = array();
|
||||
$bAddLinks = false;
|
||||
$oObj->GetRelatedObjects($sRelationName, 1 /* iMaxDepth */, $aResults);
|
||||
if ($iDepth > MAX_RECURSION_DEPTH) return;
|
||||
|
||||
@@ -71,25 +72,33 @@ function GetRelatedObjectsAsXml(DBObject $oObj, $sRelationName, &$oLinks, &$oXml
|
||||
{
|
||||
if (is_object($oTargetObj))
|
||||
{
|
||||
$oLinkingNode = $oXmlDoc->CreateElement('link');
|
||||
$oLinkingNode->SetAttribute('relation', $sRelationName);
|
||||
$oLinkingNode->SetAttribute('arrow', 1); // Such relations have a direction, display an arrow
|
||||
$oLinkedNode = $oXmlDoc->CreateElement('node');
|
||||
$oLinkedNode->SetAttribute('id', $oTargetObj->GetKey());
|
||||
$oLinkedNode->SetAttribute('obj_class', get_class($oTargetObj));
|
||||
$oLinkedNode->SetAttribute('obj_class_name', htmlspecialchars(MetaModel::GetName(get_class($oTargetObj))));
|
||||
$oLinkedNode->SetAttribute('name', htmlspecialchars($oTargetObj->GetRawName())); // htmlentities is too much for XML
|
||||
$oLinkedNode->SetAttribute('icon', BuildIconPath($oTargetObj->GetIcon(false /* No IMG tag */)));
|
||||
AddNodeDetails($oLinkedNode, $oTargetObj);
|
||||
$oSubLinks = $oXmlDoc->CreateElement('links');
|
||||
// Recurse
|
||||
GetRelatedObjectsAsXml($oTargetObj, $sRelationName, $oSubLinks, $oXmlDoc, $oLinkedNode, $iDepth++);
|
||||
$oLinkingNode->AppendChild($oLinkedNode);
|
||||
$oLinks->AppendChild($oLinkingNode);
|
||||
if (in_array(get_class($oTargetObj), $aExcludedClasses))
|
||||
{
|
||||
GetRelatedObjectsAsXml($oTargetObj, $sRelationName, $oLinks, $oXmlDoc, $oXmlNode, $iDepth++, $aExcludedClasses);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oLinkingNode = $oXmlDoc->CreateElement('link');
|
||||
$oLinkingNode->SetAttribute('relation', $sRelationName);
|
||||
$oLinkingNode->SetAttribute('arrow', 1); // Such relations have a direction, display an arrow
|
||||
$oLinkedNode = $oXmlDoc->CreateElement('node');
|
||||
$oLinkedNode->SetAttribute('id', $oTargetObj->GetKey());
|
||||
$oLinkedNode->SetAttribute('obj_class', get_class($oTargetObj));
|
||||
$oLinkedNode->SetAttribute('obj_class_name', htmlspecialchars(MetaModel::GetName(get_class($oTargetObj))));
|
||||
$oLinkedNode->SetAttribute('name', htmlspecialchars($oTargetObj->GetRawName())); // htmlentities is too much for XML
|
||||
$oLinkedNode->SetAttribute('icon', BuildIconPath($oTargetObj->GetIcon(false /* No IMG tag */)));
|
||||
AddNodeDetails($oLinkedNode, $oTargetObj);
|
||||
$oSubLinks = $oXmlDoc->CreateElement('links');
|
||||
// Recurse
|
||||
GetRelatedObjectsAsXml($oTargetObj, $sRelationName, $oSubLinks, $oXmlDoc, $oLinkedNode, $iDepth++, $aExcludedClasses);
|
||||
$oLinkingNode->AppendChild($oLinkedNode);
|
||||
$oLinks->AppendChild($oLinkingNode);
|
||||
$bAddLinks = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($aResults) > 0)
|
||||
if ($bAddLinks)
|
||||
{
|
||||
$oXmlNode->AppendChild($oLinks);
|
||||
}
|
||||
@@ -117,6 +126,9 @@ $id = utils::ReadParam('id', 1);
|
||||
$sRelation = utils::ReadParam('relation', 'impacts');
|
||||
$aValidRelations = MetaModel::EnumRelations();
|
||||
$sFormat = utils::ReadParam('format', 'xml');
|
||||
$sExcludedClasses = utils::ReadParam('exclude', '', false, 'raw_data');
|
||||
$aExcludedClasses = explode(',', $sExcludedClasses);
|
||||
|
||||
|
||||
if (!in_array($sRelation, $aValidRelations))
|
||||
{
|
||||
@@ -167,7 +179,7 @@ try
|
||||
|
||||
$oXmlRoot->SetAttribute('position', 'left');
|
||||
$oXmlRoot->SetAttribute('title', MetaModel::GetRelationDescription($sRelation).' '. htmlspecialchars($oObj->GetRawName()));
|
||||
GetRelatedObjectsAsXml($oObj, $sRelation, $oLinks, $oXmlDoc, $oXmlNode);
|
||||
GetRelatedObjectsAsXml($oObj, $sRelation, $oLinks, $oXmlDoc, $oXmlNode, 0, $aExcludedClasses);
|
||||
|
||||
$oXmlRoot->AppendChild($oXmlNode);
|
||||
$oXmlDoc->AppendChild($oXmlRoot);
|
||||
|
||||
Reference in New Issue
Block a user