From d3788888a30fc1ecf3e70e2984a80bfaf209d025 Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Mon, 20 Aug 2012 08:12:14 +0000
Subject: [PATCH] SP-241 / BIS-122 : Embedded grids need to persist display
 settings

SVN: 26394
---
 .../client/application/GenericViewModel.java  |  3 +-
 .../client/application/ui/TypedTableGrid.java | 10 ++++++
 .../aggregation/AggregationServicePanel.java  | 30 +++++++++++-----
 .../ui/data/DataSetReportGenerator.java       |  2 +-
 .../ui/report/ReportGeneratedCallback.java    | 12 ++++---
 .../application/ui/report/ReportGrid.java     | 35 ++++++++++++++----
 .../application/ui/webapp/WebAppUrl.java      |  1 +
 .../ui/webapp/WebAppUrlParameter.java         |  5 +--
 .../application/module/QueryEditor.java       | 36 ++++++++++++++-----
 .../application/module/QueryViewer.java       |  6 +++-
 .../openbis/public/resources/js/openbis.js    |  5 +++
 .../application/ui/webapp/WebAppUrlTest.java  | 12 ++++---
 12 files changed, 121 insertions(+), 36 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
index 88f1e42392e..6463ad8f238 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
@@ -83,7 +83,8 @@ public class GenericViewModel
 
     public boolean isDisplaySettingsSaving()
     {
-        return isAnonymousLogin() == false && ViewMode.NORMAL.equals(getViewMode());
+        return isAnonymousLogin() == false
+                && (ViewMode.NORMAL.equals(getViewMode()) || ViewMode.GRID.equals(getViewMode()));
     }
 
     public void setAnonymousAllowed(boolean anonymousAllowed)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
index 83e7e57b749..444ac0148eb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
@@ -1529,6 +1529,14 @@ public abstract class TypedTableGrid<T extends Serializable> extends LayoutConta
     {
         int id = log("refresh (refreshColumnsDefinition=" + refreshColumnsDefinition + ")");
         pagingToolbar.updateDefaultRefreshButton(false);
+
+        SortInfo sortInfo = getGridSortInfo();
+        if (sortInfo != null)
+        {
+            pagingLoader.setSortField(sortInfo.getSortField());
+            pagingLoader.setSortDir(translate(sortInfo.getSortDir()));
+        }
+
         debug("clean cache for refresh");
         this.refreshCallback = createRefreshCallback(externalRefreshCallbackOrNull);
         if (columnDefinitions == null || refreshColumnsDefinition)
@@ -2740,6 +2748,8 @@ public abstract class TypedTableGrid<T extends Serializable> extends LayoutConta
                                 customColumnsMetadataProvider
                                         .setCustomColumnsMetadata(customColumnMetadata);
                                 recreateColumnModelAndRefreshColumnsWithFilters();
+
+                                saveColumnDisplaySettings();
                             }
                             callback.onSuccess(resultSet);
                         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
index bdea6d34e40..f788ea36e5c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
@@ -20,6 +20,13 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.HTML;
+
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.locator.ViewLocator;
@@ -30,13 +37,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableModelReferenc
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ReportingPluginType;
 
-import com.extjs.gxt.ui.client.widget.ContentPanel;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.HTML;
-
 /**
  * A panel that shows the results of an aggregation service.
  * 
@@ -48,6 +48,8 @@ public class AggregationServicePanel extends ContentPanel
 
     private static final String DSS_CODE_PARAM = "dss";
 
+    private static final String DISPLAY_SETTINGS_ID = "displaySettingsId";
+
     private static class AggregationServiceGeneratedAction implements
             IOnReportComponentGeneratedAction
     {
@@ -65,7 +67,7 @@ public class AggregationServicePanel extends ContentPanel
             layoutContainer.add(reportComponent.getComponent());
             layoutContainer.layout();
         }
-    };
+    }
 
     private final IViewContext<ICommonClientServiceAsync> viewContext;
 
@@ -75,6 +77,8 @@ public class AggregationServicePanel extends ContentPanel
 
     private final String dataStoreCode;
 
+    private final String displaySettingsId;
+
     public AggregationServicePanel(IViewContext<ICommonClientServiceAsync> viewContext,
             String idPrefix, ViewLocator viewLocator)
     {
@@ -84,6 +88,7 @@ public class AggregationServicePanel extends ContentPanel
         this.viewLocator = viewLocator;
         serviceKey = viewLocator.getParameters().get(SERVICE_KEY_PARAM);
         dataStoreCode = viewLocator.getParameters().get(DSS_CODE_PARAM);
+        displaySettingsId = viewLocator.getParameters().get(DISPLAY_SETTINGS_ID);
 
         if (areRequiredParametersSpecified())
         {
@@ -146,14 +151,21 @@ public class AggregationServicePanel extends ContentPanel
             {
                 continue;
             }
+            if (DISPLAY_SETTINGS_ID.equals(entry.getKey()))
+            {
+                continue;
+            }
             parameterMap.put(entry.getKey(), entry.getValue());
         }
         DatastoreServiceDescription description =
                 DatastoreServiceDescription.reporting(serviceKey, "", new String[0], dataStoreCode,
                         ReportingPluginType.AGGREGATION_TABLE_MODEL);
 
+        String notNullDisplaySettingsId =
+                displaySettingsId != null ? displaySettingsId : serviceKey;
+
         AsyncCallback<TableModelReference> callback =
-                ReportGeneratedCallback.create(viewContext, description,
+                ReportGeneratedCallback.create(viewContext, description, notNullDisplaySettingsId,
                         new AggregationServiceGeneratedAction(this));
 
         viewContext.getCommonService().createReportFromAggregationService(description,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
index f907fb7e817..bdecaeb4f7f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
@@ -65,7 +65,7 @@ public class DataSetReportGenerator
             IOnReportComponentGeneratedAction action)
     {
         AsyncCallback<TableModelReference> callback =
-                ReportGeneratedCallback.create(viewContext, service, action);
+                ReportGeneratedCallback.create(viewContext, service, service.getKey(), action);
         viewContext.getService().createReportFromDatasets(service, criteria, callback);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
index 6d5fff5d1e6..d87437a1a03 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
@@ -44,22 +44,25 @@ public class ReportGeneratedCallback extends AbstractAsyncCallback<TableModelRef
 
     private final IReportInformationProvider reportInformationProvider;
 
+    private final String displaySettingsId;
+
     public static AsyncCallback<TableModelReference> create(
             IViewContext<ICommonClientServiceAsync> viewContext,
-            IReportInformationProvider reportInformationProvider,
+            IReportInformationProvider reportInformationProvider, String displaySettingsId,
             IOnReportComponentGeneratedAction action)
     {
         return AsyncCallbackWithProgressBar.decorate(new ReportGeneratedCallback(viewContext,
-                reportInformationProvider, action), "Generating the report...");
+                reportInformationProvider, displaySettingsId, action), "Generating the report...");
     }
 
     private ReportGeneratedCallback(IViewContext<ICommonClientServiceAsync> viewContext,
-            IReportInformationProvider reportInformationProvider,
+            IReportInformationProvider reportInformationProvider, String displaySettingsId,
             IOnReportComponentGeneratedAction action)
     {
         super(viewContext);
         this.localViewContext = viewContext;
         this.reportInformationProvider = reportInformationProvider;
+        this.displaySettingsId = displaySettingsId;
         this.action = action;
     }
 
@@ -67,7 +70,8 @@ public class ReportGeneratedCallback extends AbstractAsyncCallback<TableModelRef
     protected void process(final TableModelReference tableModelReference)
     {
         final IDisposableComponent reportComponent =
-                ReportGrid.create(localViewContext, tableModelReference, reportInformationProvider);
+                ReportGrid.create(localViewContext, tableModelReference, reportInformationProvider,
+                        displaySettingsId);
         action.execute(reportComponent);
         if (StringUtils.isBlank(tableModelReference.tryGetMessage()) == false)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
index ab77b40d6e7..bc4b7cfbe0c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.report;
 
+import java.util.HashSet;
 import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
@@ -30,10 +31,13 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSetFetchConf
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableModelReference;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IReportInformationProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ReportRowModel;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableGridColumnDefinition;
 
 /**
  * @author Franz-Josef Elmer
@@ -45,10 +49,11 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
 
     public static IDisposableComponent create(
             final IViewContext<ICommonClientServiceAsync> viewContext,
-            TableModelReference tableModelReference, IReportInformationProvider infoProvider)
+            TableModelReference tableModelReference, IReportInformationProvider infoProvider,
+            String displaySettingsId)
     {
         final ReportGrid grid =
-                new ReportGrid(viewContext, tableModelReference, infoProvider.getKey(),
+                new ReportGrid(viewContext, tableModelReference, displaySettingsId,
                         infoProvider.getDownloadURL());
         return grid.asDisposableWithoutToolbar();
     }
@@ -60,23 +65,26 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
 
     private final String resultSetKey;
 
-    private final String reportKind;
+    private final String displaySettingsId;
+
+    private final TableModelReference tableModelReference;
 
     private ReportGrid(IViewContext<ICommonClientServiceAsync> viewContext,
-            TableModelReference tableModelReference, String reportKind, String downloadURL)
+            TableModelReference tableModelReference, String displaySettingsId, String downloadURL)
     {
         super(viewContext, BROWSER_ID, true, DisplayTypeIDGenerator.DATA_SET_REPORTING_GRID);
         setDownloadURL(downloadURL);
         setId(BROWSER_ID);
+        this.tableModelReference = tableModelReference;
         this.resultSetKey = tableModelReference.getResultSetKey();
-        this.reportKind = reportKind;
+        this.displaySettingsId = displaySettingsId;
         updateDefaultRefreshButton();
     }
 
     @Override
     public String getGridDisplayTypeID()
     {
-        return createGridDisplayTypeID(reportKind);
+        return createGridDisplayTypeID(displaySettingsId);
     }
 
     @Override
@@ -88,6 +96,21 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
         // The custom columns should be recomputed.
         resultSetConfig.setCacheConfig(ResultSetFetchConfig
                 .createFetchFromCacheAndRecompute(resultSetKey));
+
+        Set<IColumnDefinition<TableModelRowWithObject<ReportRowModel>>> availableColumns =
+                new HashSet<IColumnDefinition<TableModelRowWithObject<ReportRowModel>>>();
+
+        if (tableModelReference.getHeader() != null)
+        {
+            for (TableModelColumnHeader header : tableModelReference.getHeader())
+            {
+                availableColumns.add(new TypedTableGridColumnDefinition<ReportRowModel>(header,
+                        null, null, null));
+            }
+        }
+
+        resultSetConfig.setAvailableColumns(availableColumns);
+
         viewContext.getService().listReport(resultSetConfig, callback);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
index 8929bc9c2bc..12f4fd75754 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
@@ -51,6 +51,7 @@ public class WebAppUrl
 
         builder =
                 new URLMethodWithParameters(openbisProtocol + "//" + openbisHost + "/" + webAppCode);
+        builder.addParameter(WebAppUrlParameter.WEBAPP_CODE.getName(), webAppCode);
         builder.addParameter(WebAppUrlParameter.SESSION_ID.getName(), sessionId);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
index ad8f65a7574..09ee0aca86a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
@@ -24,8 +24,9 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.webapp
 public enum WebAppUrlParameter
 {
 
-    SESSION_ID("session-id"), ENTITY_KIND("entity-kind"), ENTITY_TYPE("entity-type"),
-    ENTITY_IDENTIFIER("entity-identifier"), ENTITY_PERM_ID("entity-perm-id");
+    WEBAPP_CODE("webapp-code"), SESSION_ID("session-id"), ENTITY_KIND("entity-kind"), ENTITY_TYPE(
+            "entity-type"), ENTITY_IDENTIFIER("entity-identifier"),
+    ENTITY_PERM_ID("entity-perm-id");
 
     private final String name;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
index e13a47bb675..f15ff750bb9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
@@ -86,7 +86,9 @@ public class QueryEditor extends Dialog
 
     private static Button createCancelButton(IViewContext<?> viewContext, final Window window)
     {
-        return new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_CANCEL),
+        return new Button(
+                viewContext
+                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_CANCEL),
                 new SelectionListener<ButtonEvent>()
                     {
                         @Override
@@ -146,7 +148,9 @@ public class QueryEditor extends Dialog
             }
 
             add(form, new BorderLayoutData(LayoutRegion.CENTER));
-            addButton(new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SUBMIT),
+            addButton(new Button(
+                    viewContext
+                            .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SUBMIT),
                     new SelectionListener<ButtonEvent>()
                         {
                             @Override
@@ -216,14 +220,25 @@ public class QueryEditor extends Dialog
         setButtons("");
 
         nameField =
-                AbstractRegistrationDialog.createTextField(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.NAME), true);
+                AbstractRegistrationDialog
+                        .createTextField(
+                                viewContext
+                                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.NAME),
+                                true);
         nameField.setMaxLength(200);
         descriptionField =
-                AbstractRegistrationDialog.createTextField(
-                        viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.DESCRIPTION), false);
+                AbstractRegistrationDialog
+                        .createTextField(
+                                viewContext
+                                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.DESCRIPTION),
+                                false);
         descriptionField.setMaxLength(GenericConstants.DESCRIPTION_2000);
         statementField = createStatementField();
-        isPublicField = new CheckBoxField(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.IS_PUBLIC), false);
+        isPublicField =
+                new CheckBoxField(
+                        viewContext
+                                .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.IS_PUBLIC),
+                        false);
         queryDatabaseSelectionWidget =
                 new QueryDatabaseSelectionWidget(viewContext,
                         (queryOrNull != null) ? queryOrNull.getQueryDatabase() : null);
@@ -406,7 +421,9 @@ public class QueryEditor extends Dialog
     private Button createSaveButton(final FormPanel form, final IDelegatedAction refreshAction)
     {
         final Button button =
-                new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SAVE),
+                new Button(
+                        viewContext
+                                .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SAVE),
                         new SelectionListener<ButtonEvent>()
                             {
                                 @Override
@@ -515,12 +532,15 @@ public class QueryEditor extends Dialog
         QueryDatabase queryDatabase = queryDatabaseSelectionWidget.tryGetSelected();
         if (sqlStatement != null && sqlStatement.length() > 0 && queryDatabase != null)
         {
+            IReportInformationProvider reportInformation =
+                    createReportInformationProvider(sqlStatement);
+
             viewContext.getService().createQueryResultsReport(
                     queryDatabase,
                     sqlStatement,
                     parameterBindings,
                     ReportGeneratedCallback.create(viewContext.getCommonViewContext(),
-                            createReportInformationProvider(sqlStatement),
+                            reportInformation, reportInformation.getKey(),
                             createDisplayQueryResultsAction()));
         }
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
index 2dd8c5fd01c..b89b98e0b9d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
@@ -99,9 +99,13 @@ public class QueryViewer extends ContentPanel implements IDatabaseModificationOb
         {
             return;
         }
+
+        IReportInformationProvider reportInformation =
+                createReportInformationProvider(sqlQueryOrNull, queryIdOrNull);
+
         AsyncCallback<TableModelReference> callback =
                 ReportGeneratedCallback.create(viewContext.getCommonViewContext(),
-                        createReportInformationProvider(sqlQueryOrNull, queryIdOrNull),
+                        reportInformation, reportInformation.getKey(),
                         createDisplayQueryResultsAction());
         if (queryIdOrNull != null)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
index c74b37249a0..1de93b624f7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
@@ -432,6 +432,7 @@ actionDeferrer.prototype.dependencyCompleted = function(key) {
  * Provides a context information for webapps that are embedded inside the OpenBIS UI.
  */
 function openbisWebAppContext(){
+	this.webappCode = this.getParameter("webapp-code");
 	this.sessionId = this.getParameter("session-id");
 	this.entityKind = this.getParameter("entity-kind");
 	this.entityType = this.getParameter("entity-type");
@@ -439,6 +440,10 @@ function openbisWebAppContext(){
 	this.entityPermId = this.getParameter("entity-perm-id");
 }
 
+openbisWebAppContext.prototype.getWebappCode = function(){
+	return this.webappCode;
+}
+
 openbisWebAppContext.prototype.getSessionId = function(){
 	return this.sessionId;
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
index 788d6a2039f..76279ddf2ef 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
@@ -33,7 +33,9 @@ public class WebAppUrlTest
     public void testUrlWithoutParameters()
     {
         WebAppUrl url = new WebAppUrl("http:", "localhost:8888", "webapp1", "mysessionid");
-        Assert.assertEquals("http://localhost:8888/webapp1?session-id=mysessionid", url.toString());
+        Assert.assertEquals(
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid",
+                url.toString());
     }
 
     @Test
@@ -44,7 +46,9 @@ public class WebAppUrlTest
         url.addEntityType(null);
         url.addEntityIdentifier(null);
         url.addEntityPermId(null);
-        Assert.assertEquals("http://localhost:8888/webapp1?session-id=mysessionid", url.toString());
+        Assert.assertEquals(
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid",
+                url.toString());
     }
 
     @Test
@@ -56,7 +60,7 @@ public class WebAppUrlTest
         url.addEntityIdentifier("TEST_EXPERIMENT_IDENTIFIER");
         url.addEntityPermId("TEST_EXPERIMENT_PERM_ID");
         Assert.assertEquals(
-                "http://localhost:8888/webapp1?session-id=mysessionid&entity-kind=EXPERIMENT"
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid&entity-kind=EXPERIMENT"
                         + "&entity-type=TEST_EXPERIMENT_TYPE&entity-identifier=TEST_EXPERIMENT_IDENTIFIER"
                         + "&entity-perm-id=TEST_EXPERIMENT_PERM_ID", url.toString());
     }
@@ -70,7 +74,7 @@ public class WebAppUrlTest
         url.addEntityIdentifier("TEST/EXPERIMENT/IDENTIFIER");
         url.addEntityPermId("TEST&EXPERIMENT&PERM&ID");
         Assert.assertEquals(
-                "http://localhost:8888/%28webapp1%29?session-id=%5Bmysessionid%5D&entity-kind=EXPERIMENT"
+                "http://localhost:8888/%28webapp1%29?webapp-code=%28webapp1%29&session-id=%5Bmysessionid%5D&entity-kind=EXPERIMENT"
                         + "&entity-type=TEST+EXPERIMENT+TYPE&entity-identifier=TEST%2FEXPERIMENT%2FIDENTIFIER"
                         + "&entity-perm-id=TEST%26EXPERIMENT%26PERM%26ID", url.toString());
     }
-- 
GitLab