Просмотр исходного кода

Fixing bug #404: context lost when doing certain actions. What was fixed:
- Run Query
- Display Data Model Schema
- Drill-down in charts (OQL & SQL)
- Paginated lists (actually a regression)

What remains:
- Global search...
- Drill-down in Flash "impacts / depends on"

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1377 a333f486-631f-4898-b8df-5754b55c2be0

dflaven 14 лет назад
Родитель
Сommit
0e89f5e89a

+ 8 - 1
application/displayblock.class.inc.php

@@ -718,6 +718,12 @@ EOF
 			
 			case 'open_flash_chart':
 			static $iChartCounter = 0;
+			$oAppContext = new ApplicationContext();
+			$sContext = $oAppContext->GetForLink();
+			if (!empty($sContext))
+			{
+				$sContext = '&'.$sContext;
+			}
 			$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
 			$sTitle = isset($aExtraParams['chart_title']) ? $aExtraParams['chart_title'] : '';
 			$sGroupBy = isset($aExtraParams['group_by']) ? $aExtraParams['group_by'] : '';
@@ -748,6 +754,7 @@ EOF
 				$aData = array();
 				$aLabels = array();
 				$idx = 0;
+				$aURLs = array();
 				foreach($aGroupBy as $sValue => $iValue)
 				{
 					$oDrillDownFilter = clone $this->m_oFilter;
@@ -758,7 +765,7 @@ EOF
 				$sURLList = '';
 				foreach($aURLs as $index => $sURL)
 				{
-					$sURLList .= "\taURLs[$index] = '".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".addslashes($sURL)."';\n";
+					$sURLList .= "\taURLs[$index] = '".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html{$sContext}&filter=".addslashes($sURL)."';\n";
 				}
 				$oPage->add_script(
 <<<EOF

+ 17 - 4
application/itopwebpage.class.inc.php

@@ -53,6 +53,7 @@ class iTopWebPage extends NiceWebPage
 		$sAbsURLAppRoot = addslashes(utils::GetAbsoluteUrlAppRoot()); // Pass it to Javascript scripts
 		$oAppContext = new ApplicationContext();
 		$sExtraParams = $oAppContext->GetForLink();
+		$sAppContext = addslashes($sExtraParams);
 		$this->add_header("Content-type: text/html; charset=utf-8");
 		$this->add_header("Cache-control: no-cache");
 		$this->add_linked_stylesheet("../css/jquery.treeview.css");
@@ -361,18 +362,18 @@ EOF
 		{
 			if (id > 0)
 			{
-				window.location.href = GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=details&class='+sClass+'&id='+id;
+				window.location.href = AddAppContext(GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=details&class='+sClass+'&id='+id);
 			}
 			else
 			{
-				window.location.href = sDefaultUrl;				
+				window.location.href = sDefaultUrl; // Already contains the context...				
 			}
 		}
 
 		
 		function BackToList(sClass)
 		{
-			window.location.href = GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=search_oql&oql_class='+sClass+'&oql_clause=WHERE id=0';
+			window.location.href = AddAppContext(GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=search_oql&oql_class='+sClass+'&oql_clause=WHERE id=0');
 		}
 
 		function ShowDebug()
@@ -388,6 +389,19 @@ EOF
 			return '$sAbsURLAppRoot';
 		}
 		
+		function AddAppContext(sURL)
+		{
+			var sContext = '$sAppContext';
+			if (sContext.length > 0)
+			{
+				if (sURL.indexOf('?') == -1)
+				{
+					return sURL+'?'+sContext;
+				}				
+			}
+			return sURL+'&'+sContext;
+		}
+		
 		var oUserPreferences = $sUserPrefs;
 
 		// For disabling the CKEditor at init time when the corresponding textarea is disabled !
@@ -592,7 +606,6 @@ EOF
 
 
 
-
 		// Render the revision number
 		if (ITOP_REVISION == '$WCREV$')
 		{

+ 16 - 0
application/portalwebpage.class.inc.php

@@ -56,6 +56,8 @@ class PortalWebPage extends NiceWebPage
 		$this->add_linked_stylesheet("../css/jquery.treeview.css");
 		$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
 		$sAbsURLAppRoot = addslashes(utils::GetAbsoluteUrlAppRoot()); // Pass it to Javascript scripts
+		$oAppContext = new ApplicationContext();
+		$sAppContext = addslashes($oAppContext->GetForLink());
 		if ($sAlternateStyleSheet != '')
 		{
 			$this->add_linked_stylesheet("../portal/$sAlternateStyleSheet/portal.css");
@@ -157,6 +159,20 @@ EOF
 		return '$sAbsURLAppRoot';
 	}
 		
+		
+	function AddAppContext(sURL)
+	{
+		var sContext = '$sAppContext';
+		if (sContext.length > 0)
+		{
+			if (sURL.indexOf('?') == -1)
+			{
+				return sURL+'?'+sContext;
+			}
+		}
+		return sURL+'&'+sContext;
+	}
+
 	function GoBack(sFormId)
 	{
 		var form = $('#'+sFormId);

+ 6 - 1
application/sqlblock.class.inc.php

@@ -214,6 +214,11 @@ class SqlBlock
 		default:
 		case 'table':
 			$oAppContext = new ApplicationContext();
+			$sContext = $oAppContext->GetForLink();
+			if (!empty($sContext))
+			{
+				$sContext = '&'.$sContext;
+			}
 			$aDisplayConfig = array();
 			foreach($this->m_aColumns as $sName => $aColumnData)
 			{
@@ -236,7 +241,7 @@ class SqlBlock
 						{
 							$sFilter = str_replace(':'.$sColName, "'".addslashes( $aRow[$sColName] )."'", $sFilter);
 						}
-						$sURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_oql&search_form=0&oql_class='.$sClass.'&oql_clause='.urlencode($sFilter).'&format=html?'.$oAppContext->GetForLink();
+						$sURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_oql&search_form=0&oql_class='.$sClass.'&oql_clause='.urlencode($sFilter).'&format=html'.$sContext;
 						$aDisplayRow[$sName] = '<a href="'.$sURL.'">'.$aRow[$sName]."</a>";					
 					}
 					else

+ 7 - 7
js/extkeywidget.js

@@ -70,7 +70,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and get the result back directly in HTML
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$('#ac_dlg_'+me.id).html(data);
@@ -163,7 +163,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and display the results
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$(sSearchAreaId).html(data);
@@ -208,7 +208,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and get the result back directly in JSON
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$('#label_'+me.id).val(data.name);
@@ -270,7 +270,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and get the result back directly in HTML
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$('#ajax_'+me.id).html(data);
@@ -347,7 +347,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 			me.StopPendingRequest();
 			
 			// Run the query and get the result back directly in JSON
-			me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+			me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 				function(data)
 				{
 					if (me.bSelectMode)
@@ -432,7 +432,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and display the results
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$('#ac_tree_'+me.id).html(data);
@@ -490,7 +490,7 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
 		me.StopPendingRequest();
 		
 		// Run the query and get the result back directly in JSON
-		me.ajax_request = $.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
+		me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap, 
 			function(data)
 			{
 				$('#label_'+me.id).val(data.name);

+ 1 - 1
js/jquery.tablesorter.pager.js

@@ -167,7 +167,7 @@ function sprintf(format, etc) {
 					s_order = (s[1] == 0) ? 'asc' : 'desc';
 				}
 				$('#loading', table.config.container).html('<img src="../images/indicator.gif" />');
-				table.ajax_request = $.post(GetAbsoluteUrlAppRoot()+"pages/ajax.render.php",
+				table.ajax_request = $.post(AddAppContext(GetAbsoluteUrlAppRoot()+"pages/ajax.render.php"),
 						{ operation: 'pagination',
 						  filter: c.filter,
 						  extra_param: c.extra_params,

+ 4 - 1
pages/run_query.php

@@ -55,6 +55,8 @@ function ShowExamples($oP, $sExpression)
 	);
 
 	$aDisplayData = array();
+	$oAppContext = new ApplicationContext();
+	$sContext = $oAppContext->GetForForm();
 	foreach($aExamples as $sTopic => $aQueries)
 	{
 		foreach($aQueries as $sDescription => $sOql)
@@ -73,7 +75,7 @@ function ShowExamples($oP, $sExpression)
 			$aDisplayData[Dict::S('UI:RunQuery:QueryExamples')][] = array(
 				'desc' => "<div style=\"$sHighlight\">".htmlentities($sDescription, ENT_QUOTES, 'UTF-8')."</div>",
 				'oql' => "<div style=\"$sHighlight\">".htmlentities($sOql, ENT_QUOTES, 'UTF-8')."</div>",
-				'go' => "<form method=\"get\"><input type=\"hidden\" name=\"expression\" value=\"$sOql\"><input type=\"submit\" value=\"".Dict::S('UI:Button:Test')."\" $sDisable></form>\n",
+				'go' => "<form method=\"get\"><input type=\"hidden\" name=\"expression\" value=\"$sOql\"><input type=\"submit\" value=\"".Dict::S('UI:Button:Test')."\" $sDisable>$sContext</form>\n",
 			);
 		}
 	}
@@ -121,6 +123,7 @@ try
 	$oP->add(Dict::S('UI:RunQuery:ExpressionToEvaluate')."<br/>\n");
 	$oP->add("<textarea cols=\"120\" rows=\"8\" name=\"expression\">$sExpression</textarea>\n");
 	$oP->add("<input type=\"submit\" value=\"".Dict::S('UI:Button:Evaluate')."\">\n");
+	$oP->add($oAppContext->GetForForm());
 	$oP->add("</form>\n");
 
 	if (!empty($sExpression))

+ 47 - 41
pages/schema.php

@@ -36,24 +36,24 @@ LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be
 /**
  * Helper for this page -> link to a class
  */
-function MakeClassHLink($sClass)
+function MakeClassHLink($sClass, $sContext)
 {
-	return "<a href=\"?operation=details_class&class=$sClass\" title=\"".MetaModel::GetClassDescription($sClass)."\">".MetaModel::GetName($sClass)."</a>";
+	return "<a href=\"?operation=details_class&class=$sClass{$sContext}\" title=\"".MetaModel::GetClassDescription($sClass)."\">".MetaModel::GetName($sClass)."</a>";
 }
 
 /**
  * Helper for this page -> link to a class
  */
-function MakeRelationHLink($sRelCode)
+function MakeRelationHLink($sRelCode, $sContext)
 {
 	$sDesc = MetaModel::GetRelationDescription($sRelCode);
-	return "<a href=\"?operation=details_relation&relcode=$sRelCode\" title=\"$sDesc\">".$sRelCode."</a>";
+	return "<a href=\"?operation=details_relation&relcode=$sRelCode{$sContext}\" title=\"$sDesc\">".$sRelCode."</a>";
 }
 
 /**
  * Helper for the global list and the details of a given class
  */
-function DisplaySubclasses($oPage, $sClass)
+function DisplaySubclasses($oPage, $sClass, $sContext)
 {
 	$aChildClasses = MetaModel::EnumChildClasses($sClass);
 	if (count($aChildClasses) != 0)
@@ -75,8 +75,8 @@ function DisplaySubclasses($oPage, $sClass)
 			// Skip indirect childs, they will be handled somewhere else
 			if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
 			{
-					$oPage->add("<li>".MakeClassHLink($sClassName)."\n");
-					DisplaySubclasses($oPage, $sClassName);
+					$oPage->add("<li>".MakeClassHLink($sClassName, $sContext)."\n");
+					DisplaySubclasses($oPage, $sClassName, $sContext);
 					$oPage->add("</li>\n");
 			}
 		}
@@ -87,7 +87,7 @@ function DisplaySubclasses($oPage, $sClass)
 /**
  * Helper for the global list and the details of a given class
  */
-function DisplayReferencingClasses($oPage, $sClass)
+function DisplayReferencingClasses($oPage, $sClass, $sContext)
 {
 	$bSkipLinkingClasses = false;
 	$aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses);
@@ -98,7 +98,7 @@ function DisplayReferencingClasses($oPage, $sClass)
 		{
 			foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
 			{
-				$oPage->add("<li>".Dict::Format('UI:Schema:Class_ReferencingClasses_From_By', $sClass, MakeClassHLink($sRemoteClass), $sExtKeyAttCode)."</li>\n");
+				$oPage->add("<li>".Dict::Format('UI:Schema:Class_ReferencingClasses_From_By', $sClass, MakeClassHLink($sRemoteClass, $sContext), $sExtKeyAttCode)."</li>\n");
 			}
 		}
 		$oPage->add("</ul>\n");
@@ -108,7 +108,7 @@ function DisplayReferencingClasses($oPage, $sClass)
 /**
  * Helper for the global list and the details of a given class
  */
-function DisplayLinkingClasses($oPage, $sClass)
+function DisplayLinkingClasses($oPage, $sClass, $sContext)
 {
 	$bSkipLinkingClasses = false;
 	$aRefs = MetaModel::EnumLinkingClasses($sClass);
@@ -119,7 +119,7 @@ function DisplayLinkingClasses($oPage, $sClass)
 		{
 			foreach($aRemoteClasses as $sExtKeyAttCode => $sRemoteClass)
 			{
-				$oPage->add("<li>".Dict::Format('UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute', $sClass, MakeClassHLink($sRemoteClass), MakeClassHLink($sLinkClass), $sExtKeyAttCode));
+				$oPage->add("<li>".Dict::Format('UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute', $sClass, MakeClassHLink($sRemoteClass, $sContext), MakeClassHLink($sLinkClass, $sContext), $sExtKeyAttCode));
 			}
 		}
 		$oPage->add("</ul>\n");
@@ -129,7 +129,7 @@ function DisplayLinkingClasses($oPage, $sClass)
 /**
  * Helper for the global list and the details of a given class
  */
-function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVisitedClasses = array(), $bSubtree = true)
+function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVisitedClasses = array(), $bSubtree = true, $sContext)
 {
 	if ($iLevels <= 0) return;
 	$iLevels--;
@@ -140,7 +140,7 @@ function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVis
 	if ($bSubtree) $oPage->add("<ul class=\"treeview\">\n");
 	foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass)
 	{
-		DisplayRelatedClassesBestInClass($oPage, $sParentClass, $iLevels, $aVisitedClasses, false);
+		DisplayRelatedClassesBestInClass($oPage, $sParentClass, $iLevels, $aVisitedClasses, false, $sContext);
 	}
 	////$oPage->add("<div style=\"background-color:#ccc; border: 1px dashed #333;\">");
 	foreach (MetaModel::EnumReferencedClasses($sClass) as $sExtKeyAttCode => $sRemoteClass)
@@ -148,8 +148,8 @@ function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVis
 		$sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
 		if (MetaModel::GetAttributeOrigin($sClass, $sExtKeyAttCode) == $sClass)
 		{
-			$oPage->add("<li>$sClass| <em>$sExtKeyAttCode</em> =&gt;".MakeClassHLink($sRemoteClass)."$sVisited</li>\n");
-			DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses);
+			$oPage->add("<li>$sClass| <em>$sExtKeyAttCode</em> =&gt;".MakeClassHLink($sRemoteClass, $sContext)."$sVisited</li>\n");
+			DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses, true, $sContext);
 		}
 	}
 	foreach (MetaModel::EnumReferencingClasses($sClass) as $sRemoteClass => $aRemoteKeys)
@@ -157,8 +157,8 @@ function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVis
 		foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
 		{
 			$sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
-			$oPage->add("<li>$sClass| &lt;=".MakeClassHLink($sRemoteClass)."::<em>$sExtKeyAttCode</em>$sVisited</li>\n");
-			DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses);
+			$oPage->add("<li>$sClass| &lt;=".MakeClassHLink($sRemoteClass, $sContext)."::<em>$sExtKeyAttCode</em>$sVisited</li>\n");
+			DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses, true, $sContext);
 		}
 	}
 	////$oPage->add("</div>");
@@ -168,16 +168,17 @@ function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVis
 /**
  * Helper for the list of classes related to the given class
  */
-function DisplayRelatedClasses($oPage, $sClass)
+function DisplayRelatedClasses($oPage, $sClass, $sContext)
 {
 	$oPage->add("<h3>".Dict::Format('UI:Schema:Links:1-n', $sClass)."</h3>\n");
-	DisplayReferencingClasses($oPage, $sClass);
+	DisplayReferencingClasses($oPage, $sClass, $sContext);
 
 	$oPage->add("<h3>".Dict::Format('UI:Schema:Links:n-n', $sClass)."</h3>\n");
-	DisplayLinkingClasses($oPage, $sClass);
+	DisplayLinkingClasses($oPage, $sClass, $sContext);
 
 	$oPage->add("<h3>".Dict::S('UI:Schema:Links:All')."</h3>\n");
-	DisplayRelatedClassesBestInClass($oPage, $sClass, 4);
+	$aEmpty = array();
+	DisplayRelatedClassesBestInClass($oPage, $sClass, 4, $aEmpty, true, $sContext);
 }
 
 /**
@@ -279,7 +280,7 @@ function DisplayTriggers($oPage, $sClass)
 /**
  * Display the list of classes from the business model
  */
-function DisplayClassesList($oPage)
+function DisplayClassesList($oPage, $sContext)
 {
 	$oPage->add("<h1>".Dict::S('UI:Schema:Title')."</h1>\n");
 
@@ -303,13 +304,13 @@ function DisplayClassesList($oPage)
 	{
 		if (MetaModel::IsRootClass($sClassName))
 		{
-			$oPage->add("<li class=\"closed\">".MakeClassHLink($sClassName)."\n");
-			DisplaySubclasses($oPage, $sClassName);
+			$oPage->add("<li class=\"closed\">".MakeClassHLink($sClassName, $sContext)."\n");
+			DisplaySubclasses($oPage, $sClassName, $sContext);
 			$oPage->add("</li>\n");
 		}
 		elseif (MetaModel::IsStandaloneClass($sClassName))
 		{
-			$oPage->add("<li>".MakeClassHLink($sClassName)."</li>\n");
+			$oPage->add("<li>".MakeClassHLink($sClassName, $sContext)."</li>\n");
 		}
 	}
 	$oPage->add("</ul>\n");
@@ -319,7 +320,7 @@ function DisplayClassesList($oPage)
 	$oPage->add("<ul id=\"ClassesRelationships\" class=\"treeview\">\n");
 	foreach (MetaModel::EnumRelations() as $sRelCode)
 	{
-		$oPage->add("<li>".MakeRelationHLink($sRelCode)."\n");
+		$oPage->add("<li>".MakeRelationHLink($sRelCode, $sContext)."\n");
 		$oPage->add("<ul>\n");
 		$oPage->add("<li>Description: ".htmlentities(MetaModel::GetRelationDescription($sRelCode), ENT_QUOTES, 'UTF-8')."</li>\n");
 		$oPage->add("<li>Verb up: ".htmlentities(MetaModel::GetRelationVerbUp($sRelCode), ENT_QUOTES, 'UTF-8')."</li>\n");
@@ -335,7 +336,7 @@ function DisplayClassesList($oPage)
 /**
  * Display the details of a given class of objects
  */
-function DisplayClassDetails($oPage, $sClass)
+function DisplayClassDetails($oPage, $sClass, $sContext)
 {
 	$oPage->add("<h2>$sClass - ".MetaModel::GetClassDescription($sClass)."</h2>\n");
 	if (MetaModel::IsAbstract($sClass))
@@ -352,7 +353,7 @@ function DisplayClassDetails($oPage, $sClass)
 	$aParentClasses = array();
 	foreach(MetaModel::EnumParentClasses($sClass) as $sParentClass)
 	{
-		$aParentClasses[] = MakeClassHLink($sParentClass);
+		$aParentClasses[] = MakeClassHLink($sParentClass, $sContext);
 	}
 	if (count($aParentClasses) > 0)
 	{
@@ -362,13 +363,13 @@ function DisplayClassDetails($oPage, $sClass)
 	{
 		$sParents = '';
 	}
-	$oPage->p("[<a href=\"?operation='list'\">".Dict::S('UI:Schema:AllClasses')."</a>] $sParents");
+	$oPage->p("[<a href=\"?operation=list{$sContext}\">".Dict::S('UI:Schema:AllClasses')."</a>] $sParents");
 
 	if (MetaModel::HasChildrenClasses($sClass))
 	{
 		$oPage->add("<ul id=\"ClassHierarchy\">");
 		$oPage->add("<li class=\"closed\">".$sClass."\n");
-		DisplaySubclasses($oPage, $sClass);
+		DisplaySubclasses($oPage, $sClass,$sContext);
 		$oPage->add("</li>\n");
 		$oPage->add("</ul>\n");
 		$oPage->add_ready_script('$("#ClassHierarchy").treeview();');	
@@ -382,7 +383,7 @@ function DisplayClassDetails($oPage, $sClass)
 	{
 		if ($oAttDef->IsExternalKey())
 		{
-		   $sValue = Dict::Format('UI:Schema:ExternalKey_To',MakeClassHLink($oAttDef->GetTargetClass()));
+		   $sValue = Dict::Format('UI:Schema:ExternalKey_To',MakeClassHLink($oAttDef->GetTargetClass(), $sContext));
 		}
 		else
 		{
@@ -446,19 +447,19 @@ function DisplayClassDetails($oPage, $sClass)
 	$oPage->table($aConfig, $aDetails);
 
 	$oPage->SetCurrentTab(Dict::S('UI:Schema:ChildClasses'));
-	DisplaySubclasses($oPage, $sClass);
+	DisplaySubclasses($oPage, $sClass, $sContext);
 
 	$oPage->SetCurrentTab(Dict::S('UI:Schema:ReferencingClasses'));
-	DisplayReferencingClasses($oPage, $sClass);
+	DisplayReferencingClasses($oPage, $sClass, $sContext);
 
 	$oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses'));
-	DisplayRelatedClasses($oPage, $sClass);
+	DisplayRelatedClasses($oPage, $sClass, $sContext);
 
 	$oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle'));
-	DisplayLifecycle($oPage, $sClass);
+	DisplayLifecycle($oPage, $sClass, $sContext);
 
 	$oPage->SetCurrentTab(Dict::S('UI:Schema:Triggers'));
-	DisplayTriggers($oPage, $sClass);
+	DisplayTriggers($oPage, $sClass, $sContext);
 
 	$oPage->SetCurrentTab();
 	$oPage->SetCurrentTabContainer();
@@ -468,7 +469,7 @@ function DisplayClassDetails($oPage, $sClass)
 /**
  * Display the details of a given relation (e.g. "impacts")
  */
-function DisplayRelationDetails($oPage, $sRelCode)
+function DisplayRelationDetails($oPage, $sRelCode, $sContext)
 {
 	$sDesc = MetaModel::GetRelationDescription($sRelCode);
 	$sVerbDown = MetaModel::GetRelationVerbDown($sRelCode);
@@ -483,7 +484,7 @@ function DisplayRelationDetails($oPage, $sRelCode)
 		$aRelQueries = MetaModel::EnumRelationQueries($sClass, $sRelCode);
 		if (count($aRelQueries) > 0)
 		{
-			$oPage->add("<li>class ".MakeClassHLink($sClass)."\n");
+			$oPage->add("<li>class ".MakeClassHLink($sClass, $sContext)."\n");
 			$oPage->add("<ul>\n");
 			foreach ($aRelQueries as $sRelKey => $aQuery)
 			{
@@ -508,6 +509,11 @@ function DisplayRelationDetails($oPage, $sRelCode)
 
 // Display the menu on the left
 $oAppContext = new ApplicationContext();
+$sContext = $oAppContext->GetForLink();
+if (!empty($sContext))
+{
+	$sContext = '&'.$sContext;
+}
 $operation = utils::ReadParam('operation', '');
 
 $oPage = new iTopWebPage(Dict::S('UI:Schema:Title'));
@@ -519,17 +525,17 @@ switch($operation)
 {
 	case 'details_class':
 	$sClass = utils::ReadParam('class', 'logRealObject');
-	DisplayClassDetails($oPage, $sClass);
+	DisplayClassDetails($oPage, $sClass, $sContext);
 	break;
 	
 	case 'details_relation':
 	$sRelCode = utils::ReadParam('relcode', '');
-	DisplayRelationDetails($oPage, $sRelCode);
+	DisplayRelationDetails($oPage, $sRelCode, $sContext);
 	break;
 	
 	case 'list':
 	default:
-	DisplayClassesList($oPage);
+	DisplayClassesList($oPage, $sContext);
 }
 
 $oPage->output();