From bc45a25e24fec7de496f1e7a642648220e41cea4 Mon Sep 17 00:00:00 2001
From: izabel <izabel>
Date: Thu, 16 Sep 2010 09:11:37 +0000
Subject: [PATCH] [LMS-1757] allow to configure the server to hide sections

SVN: 17859
---
 openbis/etc/web-client.properties             |  42 ++++++
 .../client/application/CommonViewContext.java |  11 +-
 .../framework/DisplaySettingsManager.java     |  37 ++++--
 .../framework/DisplayTypeIDGenerator.java     |   9 +-
 .../ui/ModulesSectionsManager.java            |   1 +
 .../application/ui/widget/SectionsPanel.java  |  16 ++-
 .../web/client/dto/ApplicationInfo.java       |  14 ++
 .../web/server/AbstractClientService.java     |  12 ++
 .../WebClientConfigurationProvider.java       | 120 ++++++++++++++++++
 .../basic/dto/DetailViewConfiguration.java    |  74 +++++++++++
 .../basic/dto/WebClientConfiguration.java     |  50 ++++++++
 .../dataset/GenericDataSetViewer.java         |   7 +-
 .../experiment/GenericExperimentViewer.java   |   7 +-
 .../material/GenericMaterialViewer.java       |   7 +-
 .../sample/GenericSampleViewer.java           |   7 +-
 .../source/java/genericApplicationContext.xml |   6 +
 openbis/source/java/service.properties        |   5 +-
 .../web/test/DisplaySettingsManagerTest.java  |   6 +-
 18 files changed, 386 insertions(+), 45 deletions(-)
 create mode 100644 openbis/etc/web-client.properties
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/WebClientConfigurationProvider.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailViewConfiguration.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/WebClientConfiguration.java

diff --git a/openbis/etc/web-client.properties b/openbis/etc/web-client.properties
new file mode 100644
index 00000000000..72b46e0a527
--- /dev/null
+++ b/openbis/etc/web-client.properties
@@ -0,0 +1,42 @@
+# Configuration of entity (experiment, sample, data set, material) detail views.
+#
+# Mandatory properties: 
+#   - view (entity detail view id) 
+#   - types (list of entity type codes)
+# Optional properties: 
+#   - hide-sections (list of section ids)
+#   - hide-smart-view (removes "Smart View" from Data Set Detail View -> Data View) (generic_dataset_viewer)
+#   - hide-file-view (removes "File View" from Data Set Detail View -> Data View) (generic_dataset_viewer)
+# Available entity-detail-views:
+#   generic_dataset_viewer
+#   generic_experiment_viewer
+#   generic_sample_viewer
+#   generic_material_viewer
+# Available sections:
+#   attachment-section
+#   container-sample-section
+#   derived-samples-section
+#   parent-samples-section
+#   data-set-section
+#   data-set-parents-section
+#   data-set-children-section
+#   data-set-data-section
+#   module-section
+#
+# Example:
+# 
+detail-views = sample-view, experiment-view, data-view  
+
+sample-view.view = generic_sample_viewer
+sample-view.types = CELL_PLATE, CONTROL_LAYOUT
+sample-view.hide-sections = attachment-section, container-sample-section, derived-samples-section 
+
+experiment-view.view = generic_sample_viewer
+experiment-view.types = SIRNA_HCS
+experiment-view.hide-sections = attachment-section
+
+data-view.view = generic-dataset-viewer
+data-view.types = HCS_IMAGE
+data-view.hide-smart-view = true
+data-view.hide-file-view = false
+
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/CommonViewContext.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/CommonViewContext.java
index 2ca8733a07d..83feafe66f0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/CommonViewContext.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/CommonViewContext.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMess
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.log.IProfilingTable;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.log.ProfilingTable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebClientConfiguration;
 
 /**
  * The <i>generic</i> {@link IViewContext} implementation.
@@ -117,7 +118,9 @@ public final class CommonViewContext implements IViewContext<ICommonClientServic
     {
         final DisplaySettings loggedUserDisplaySettings =
                 viewModel.getSessionContext().getDisplaySettings();
-        displaySettingsManager = createDisplaySettingsManager(loggedUserDisplaySettings);
+        displaySettingsManager =
+                createDisplaySettingsManager(loggedUserDisplaySettings, viewModel
+                        .getApplicationInfo().getWebClientConfiguration());
     }
 
     public DisplaySettingsManager getDisplaySettingsManager()
@@ -127,7 +130,8 @@ public final class CommonViewContext implements IViewContext<ICommonClientServic
     }
 
     private DisplaySettingsManager createDisplaySettingsManager(
-            final DisplaySettings displaySettings)
+            final DisplaySettings displaySettings,
+            WebClientConfiguration webClientConfigurationDTO)
     {
         IDelegatedAction settingsUpdater = new IDelegatedAction()
             {
@@ -144,7 +148,8 @@ public final class CommonViewContext implements IViewContext<ICommonClientServic
                     service.updateDisplaySettings(displaySettings, callback);
                 }
             };
-        return new DisplaySettingsManager(displaySettings, settingsUpdater);
+        return new DisplaySettingsManager(displaySettings, settingsUpdater,
+                webClientConfigurationDTO);
     }
 
     public final IGenericImageBundle getImageBundle()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplaySettingsManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplaySettingsManager.java
index dd99e9639d3..68421e52c07 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplaySettingsManager.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplaySettingsManager.java
@@ -36,8 +36,10 @@ import com.extjs.gxt.ui.client.widget.grid.Grid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext.ClientStaticState;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ColumnSetting;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailViewConfiguration;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RealNumberFormatingParameters;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebClientConfiguration;
 
 /**
  * Manager of {@link DisplaySettings}. The manager itself is stateless. It only changes the wrapped
@@ -97,6 +99,8 @@ public class DisplaySettingsManager
 
     private final IDelayedUpdater updater;
 
+    private final WebClientConfiguration webClientConfiguration;
+
     /**
      * Private, we need this interface to make tests easier. We wrap {@link DelayedTask} which
      * requires the access to the browser.
@@ -111,9 +115,9 @@ public class DisplaySettingsManager
      * Creates an instance for the specified display settings.
      */
     public DisplaySettingsManager(DisplaySettings displaySettings,
-            final IDelegatedAction settingsUpdater)
+            final IDelegatedAction settingsUpdater, WebClientConfiguration webClientConfiguration)
     {
-        this(displaySettings, createDelayedUpdater(settingsUpdater));
+        this(displaySettings, createDelayedUpdater(settingsUpdater), webClientConfiguration);
     }
 
     private static IDelayedUpdater createDelayedUpdater(final IDelegatedAction settingsUpdater)
@@ -146,14 +150,18 @@ public class DisplaySettingsManager
         }
     }
 
-    /** Private, for tests only */
-    public DisplaySettingsManager(DisplaySettings displaySettings, final IDelayedUpdater updater)
+    /**
+     * Private, for tests only
+     */
+    public DisplaySettingsManager(DisplaySettings displaySettings, final IDelayedUpdater updater,
+            WebClientConfiguration webClientConfiguration)
     {
         if (displaySettings == null)
         {
             throw new IllegalArgumentException("Unspecified display manager.");
         }
         this.displaySettings = displaySettings;
+        this.webClientConfiguration = webClientConfiguration;
         this.updater = updater;
     }
 
@@ -358,9 +366,10 @@ public class DisplaySettingsManager
                 .getModifier(), delayMs);
     }
 
-    public void storeTabSettings(String tabGroupDisplayID, String tabDisplayID, Object modifier)
+    public void storeActiveTabSettings(String tabGroupDisplayID, String tabDisplayID,
+            Object modifier)
     {
-        updateTabSettings(tabGroupDisplayID, tabDisplayID, modifier);
+        updateActiveTabSettings(tabGroupDisplayID, tabDisplayID, modifier);
         updater.executeDelayed(QUITE_TIME_BEFORE_SETTINGS_SAVED_MS);
     }
 
@@ -442,17 +451,27 @@ public class DisplaySettingsManager
      *          manually after a modification.
      */
     @SuppressWarnings("deprecation")
-    public final String getTabSettings(String tabGroupDisplayTypeID)
+    public final String getActiveTabSettings(String tabGroupDisplayTypeID)
     {
         return displaySettings.getTabSettings().get(tabGroupDisplayTypeID);
     }
 
+    /**
+     * @returns hidden tabs for given panel - which tab should be selected<br>
+     * <br>
+     *          NOTE: Returned value should be used read only
+     */
+    public final DetailViewConfiguration tryGetDetailViewSettings(String entityDetailViewID)
+    {
+        return webClientConfiguration.getViews().get(entityDetailViewID);
+    }
+
     /**
      * update section settings for given display id (modification date is updated automatically)
      */
     @SuppressWarnings("deprecation")
-    private final void updateTabSettings(String tabGroupDisplayID, String selectedTabDisplayID,
-            Object modifier)
+    private final void updateActiveTabSettings(String tabGroupDisplayID,
+            String selectedTabDisplayID, Object modifier)
     {
         displaySettings.getTabSettings().put(tabGroupDisplayID, selectedTabDisplayID);
         tabModifications.put(tabGroupDisplayID, Modification.create(modifier));
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplayTypeIDGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplayTypeIDGenerator.java
index 49e0a68f74e..4a7770e3740 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplayTypeIDGenerator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DisplayTypeIDGenerator.java
@@ -72,9 +72,13 @@ public enum DisplayTypeIDGenerator implements IDisplayTypeIDGenerator
 
     FILE_FORMAT_TYPE_BROWSER_GRID("file-format-type-browser-grid"),
 
+    SAMPLE_TYPE_BROWSER("sample-type-browser"),
+
+    // -------------- Sections
+
     ATTACHMENT_SECTION("attachment-section"),
 
-    CONTAINER_SAMPLES_SECTION("sample-section"),
+    CONTAINER_SAMPLES_SECTION("container-sample-section"),
 
     DERIVED_SAMPLES_SECTION("derived-samples-section"),
 
@@ -90,7 +94,7 @@ public enum DisplayTypeIDGenerator implements IDisplayTypeIDGenerator
 
     MODULE_SECTION("module-section"),
 
-    SAMPLE_TYPE_BROWSER("sample-type-browser"),
+    // -------------- Viewers (detail view)
 
     GENERIC_DATASET_VIEWER("generic_dataset_viewer"),
 
@@ -118,5 +122,4 @@ public enum DisplayTypeIDGenerator implements IDisplayTypeIDGenerator
     {
         return createID() + suffix;
     }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/ModulesSectionsManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/ModulesSectionsManager.java
index e07af1db226..47219212708 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/ModulesSectionsManager.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/ModulesSectionsManager.java
@@ -77,6 +77,7 @@ public class ModulesSectionsManager
             final Collection<? extends TabContent> sections = module.getSections(entity);
             for (final TabContent panel : sections)
             {
+                // FIXME 2010-09-15, IA: check when this is needed
                 panel.setDisplayID(DisplayTypeIDGenerator.MODULE_SECTION);
                 container.addPanel(panel);
             }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/SectionsPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/SectionsPanel.java
index 1f75a6e50a2..9cd0a3914ac 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/SectionsPanel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/SectionsPanel.java
@@ -19,6 +19,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.TabContent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplaySettingsManager.Modification;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailViewConfiguration;
 
 /**
  * {@link LayoutContainer} which allows to choose which contained panels should be visible and uses
@@ -99,7 +100,7 @@ public class SectionsPanel extends LayoutContainer
                     {
                         final String thisTabID = sectionElement.getPanel().getDisplayID();
                         String tabToActivateID =
-                                viewContext.getDisplaySettingsManager().getTabSettings(
+                                viewContext.getDisplaySettingsManager().getActiveTabSettings(
                                         getDisplayID());
                         if (tabToActivateID != null && tabToActivateID.equals(thisTabID))
                         {
@@ -118,7 +119,14 @@ public class SectionsPanel extends LayoutContainer
 
     public void addPanel(final TabContent panel)
     {
-
+        DetailViewConfiguration viewSettingsOrNull =
+                viewContext.getDisplaySettingsManager().tryGetDetailViewSettings(getDisplayID());
+        if (viewSettingsOrNull != null
+                && viewSettingsOrNull.getDisabledTabs()
+                        .contains(panel.getDisplayID().toUpperCase()))
+        {
+            return;
+        }
         final SectionElement element = new SectionElement(panel, viewContext);
         // sections will be disposed when section panel is removed, not when they are hidden
         // (see onDetach())
@@ -172,8 +180,8 @@ public class SectionsPanel extends LayoutContainer
                     {
                         panel.setContentVisible(true);
                         layout();
-                        viewContext.getDisplaySettingsManager().storeTabSettings(getDisplayID(),
-                                panel.getDisplayID(), SectionsPanel.this);
+                        viewContext.getDisplaySettingsManager().storeActiveTabSettings(
+                                getDisplayID(), panel.getDisplayID(), SectionsPanel.this);
                     }
                 });
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java
index 883fe9f346e..008a5f0e13a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ApplicationInfo.java
@@ -18,6 +18,8 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
 
 import com.google.gwt.user.client.rpc.IsSerializable;
 
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebClientConfiguration;
+
 /**
  * A bean that contains information about the application.
  * 
@@ -33,6 +35,8 @@ public final class ApplicationInfo implements IsSerializable
 
     private boolean archivingConfigured;
 
+    private WebClientConfiguration webClientConfiguration;
+
     public String getCifexRecipient()
     {
         return cifexRecipient;
@@ -73,4 +77,14 @@ public final class ApplicationInfo implements IsSerializable
         this.archivingConfigured = archivingConfigured;
     }
 
+    public void setWebClientConfiguration(WebClientConfiguration configuration)
+    {
+        this.webClientConfiguration = configuration;
+    }
+
+    public WebClientConfiguration getWebClientConfiguration()
+    {
+        return webClientConfiguration;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/AbstractClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/AbstractClientService.java
index eceaaa26465..bbe43c8a729 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/AbstractClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/AbstractClientService.java
@@ -89,6 +89,8 @@ public abstract class AbstractClientService implements IClientService,
 
     private String onlineHelpSpecificPageTemplate;
 
+    private WebClientConfigurationProvider webClientConfigurationProvider;
+
     protected AbstractClientService()
     {
     }
@@ -178,6 +180,12 @@ public abstract class AbstractClientService implements IClientService,
         }
     }
 
+    public final void setWebClientConfigurationProvider(
+            WebClientConfigurationProvider webClientConfigurationProvider)
+    {
+        this.webClientConfigurationProvider = webClientConfigurationProvider;
+    }
+
     public final void setCifexRecipient(String cifexRecipient)
     {
         this.cifexRecipient = cifexRecipient;
@@ -361,11 +369,15 @@ public abstract class AbstractClientService implements IClientService,
         {
             applicationInfo.setCIFEXURL(cifexURL);
             applicationInfo.setCifexRecipient(cifexRecipient);
+            applicationInfo.setWebClientConfiguration(webClientConfigurationProvider
+                    .getWebClientConfiguration());
         } else
         {
             ApplicationInfo commonApplicationInfo = commonClientService.getApplicationInfo();
             applicationInfo.setCIFEXURL(commonApplicationInfo.getCIFEXURL());
             applicationInfo.setCifexRecipient(commonApplicationInfo.getCifexRecipient());
+            applicationInfo.setWebClientConfiguration(commonApplicationInfo
+                    .getWebClientConfiguration());
         }
         applicationInfo.setArchivingConfigured(isArchivingConfigured());
         applicationInfo.setVersion(getVersion());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/WebClientConfigurationProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/WebClientConfigurationProvider.java
new file mode 100644
index 00000000000..4946238ecba
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/WebClientConfigurationProvider.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.server;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import ch.systemsx.cisd.common.utilities.PropertyParametersUtil;
+import ch.systemsx.cisd.common.utilities.PropertyUtils;
+import ch.systemsx.cisd.common.utilities.PropertyParametersUtil.SectionProperties;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailViewConfiguration;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebClientConfiguration;
+
+/**
+ * Loads the Web Client configuration from given file and creates {@link WebClientConfiguration}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class WebClientConfigurationProvider
+{
+    private static final String CONFIGURATION_FILE_NOT_PROVIDED =
+            "${web-client-configuration-file}";
+
+    private static final String HIDE_SECTIONS = "hide-sections";
+
+    private static final String TYPES = "types";
+
+    private static final String VIEW = "view";
+
+    private static final String DETAIL_VIEWS = "detail-views";
+
+    private static final String HIDE_SMART_VIEW = "hide-smart-view";
+
+    private static final String HIDE_FILE_VIEW = "hide-file-view";
+
+    private WebClientConfiguration webClientConfiguration = new WebClientConfiguration();
+
+    public WebClientConfigurationProvider(String configurationFile)
+    {
+        if (configurationFile.equals(CONFIGURATION_FILE_NOT_PROVIDED))
+        {
+            return;
+        }
+        Properties properties = PropertyUtils.loadProperties(configurationFile);
+        webClientConfiguration = new WebClientConfiguration();
+        webClientConfiguration.setViews(extractHiddenSections(properties));
+    }
+
+    private Map<String, DetailViewConfiguration> extractHiddenSections(Properties properties)
+    {
+        Map<String, DetailViewConfiguration> viewConfigurations =
+                new HashMap<String, DetailViewConfiguration>();
+        SectionProperties[] viewsProperties = extractViewsProperties(properties);
+        for (int i = 0; i < viewsProperties.length; i++)
+        {
+            Properties viewProperties = viewsProperties[i].getProperties();
+            String viewId = extractViewId(viewProperties);
+            List<String> types = extractEntityTypes(viewProperties);
+            List<String> hideSectionsIdsOrNull = tryExtractHiddenSections(viewProperties);
+            boolean hideSmartView =
+                    PropertyUtils.getBoolean(viewProperties, HIDE_SMART_VIEW, false);
+            boolean hideFileView = PropertyUtils.getBoolean(viewProperties, HIDE_FILE_VIEW, false);
+            for (String type : types)
+            {
+                DetailViewConfiguration viewConfiguration = new DetailViewConfiguration();
+                if (hideSectionsIdsOrNull != null)
+                {
+                    viewConfiguration.setDisabledTabs(new HashSet<String>(hideSectionsIdsOrNull));
+                }
+                viewConfiguration.setHideSmartView(hideSmartView);
+                viewConfiguration.setHideFileView(hideFileView);
+                viewConfigurations.put(viewId + type, viewConfiguration);
+            }
+        }
+        return viewConfigurations;
+    }
+
+    private SectionProperties[] extractViewsProperties(Properties properties)
+    {
+        return PropertyParametersUtil.extractSectionProperties(properties, DETAIL_VIEWS, false);
+    }
+
+    private List<String> tryExtractHiddenSections(Properties viewProperties)
+    {
+        return PropertyUtils.tryGetList(viewProperties, HIDE_SECTIONS);
+    }
+
+    private List<String> extractEntityTypes(Properties viewProperties)
+    {
+        return PropertyUtils.getMandatoryList(viewProperties, TYPES);
+    }
+
+    private String extractViewId(Properties viewProperties)
+    {
+        return PropertyUtils.getMandatoryProperty(viewProperties, VIEW);
+    }
+
+    public WebClientConfiguration getWebClientConfiguration()
+    {
+        return webClientConfiguration;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailViewConfiguration.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailViewConfiguration.java
new file mode 100644
index 00000000000..266d359ba86
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailViewConfiguration.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * Entity detail view configuration.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DetailViewConfiguration implements IsSerializable, Serializable
+{
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+
+    Set<String> disabledTabs = new HashSet<String>();
+
+    private boolean hideSmartView = false;
+
+    private boolean hideFileView = false;
+
+    public DetailViewConfiguration()
+    {
+    }
+
+    public Set<String> getDisabledTabs()
+    {
+        return disabledTabs;
+    }
+
+    public void setDisabledTabs(Set<String> disabledTabs)
+    {
+        this.disabledTabs = disabledTabs;
+    }
+
+    public void setHideSmartView(boolean hideSmartView)
+    {
+        this.hideSmartView = hideSmartView;
+    }
+
+    public boolean isHideSmartView()
+    {
+        return hideSmartView;
+    }
+
+    public void setHideFileView(boolean hideFileView)
+    {
+        this.hideFileView = hideFileView;
+    }
+
+    public boolean isHideFileView()
+    {
+        return hideFileView;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/WebClientConfiguration.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/WebClientConfiguration.java
new file mode 100644
index 00000000000..bda404eea4b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/WebClientConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * Stores Web Client configuration.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class WebClientConfiguration implements IsSerializable, Serializable
+{
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+
+    Map<String, DetailViewConfiguration> views = new HashMap<String, DetailViewConfiguration>();
+
+    public Map<String, DetailViewConfiguration> getViews()
+    {
+        return views;
+    }
+
+    public void setViews(Map<String, DetailViewConfiguration> views)
+    {
+        this.views = views;
+    }
+
+    public WebClientConfiguration()
+    {
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
index 59b88b65edb..adb6b228342 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
@@ -169,7 +169,7 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
     private final Component createRightPanel(final ExternalData dataset)
     {
         final SectionsPanel container = new SectionsPanel(viewContext.getCommonViewContext());
-        displayIdSuffix = getDisplayIdSuffix(dataset.getDataSetType().getCode());
+        displayIdSuffix = dataset.getDataSetType().getCode();
         container.setDisplayID(DisplayTypeIDGenerator.GENERIC_DATASET_VIEWER, displayIdSuffix);
 
         List<TabContent> additionalPanels = createAdditionalSectionPanels();
@@ -197,11 +197,6 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
         return container;
     }
 
-    private static final String getDisplayIdSuffix(String suffix)
-    {
-        return PREFIX + suffix;
-    }
-
     /**
      * Adds listeners and sets up the initial left panel state.
      * <p>
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewer.java
index a3ca048ff2e..8de668f30a8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewer.java
@@ -147,7 +147,7 @@ public class GenericExperimentViewer extends AbstractViewer<Experiment> implemen
 
         this.propertiesPanelOrNull = new ExperimentPropertiesPanel(experiment, viewContext, this);
         add(propertiesPanelOrNull, createLeftBorderLayoutData());
-        final String displayIdSuffix = getDisplayIdSuffix(this.experimentType.getCode());
+        final String displayIdSuffix = this.experimentType.getCode();
 
         configureLeftPanel(displayIdSuffix);
 
@@ -229,11 +229,6 @@ public class GenericExperimentViewer extends AbstractViewer<Experiment> implemen
             };
     }
 
-    private static final String getDisplayIdSuffix(String suffix)
-    {
-        return GENERIC_EXPERIMENT_VIEWER + "-" + suffix;
-    }
-
     private List<DisposableTabContent> createRightPanel()
     {
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialViewer.java
index 16549e59aa4..794018cf526 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialViewer.java
@@ -127,7 +127,7 @@ abstract public class GenericMaterialViewer extends AbstractViewer<Material> imp
 
     private final Component createRightPanel(Material material)
     {
-        displayIdSuffix = getDisplayIdSuffix(material.getMaterialType().getCode());
+        displayIdSuffix = material.getMaterialType().getCode();
 
         final SectionsPanel container = new SectionsPanel(viewContext.getCommonViewContext());
         container.setDisplayID(DisplayTypeIDGenerator.GENERIC_MATERIAL_VIEWER, displayIdSuffix);
@@ -141,11 +141,6 @@ abstract public class GenericMaterialViewer extends AbstractViewer<Material> imp
         return container;
     }
 
-    private static final String getDisplayIdSuffix(String suffix)
-    {
-        return GENERIC_MATERIAL_VIEWER + "-" + suffix;
-    }
-
     protected void reloadAllData()
     {
         reloadMaterialData(new MaterialInfoCallback(viewContext, this));
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
index 52e592d69bb..d00e90d4259 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
@@ -182,15 +182,10 @@ abstract public class GenericSampleViewer extends AbstractViewer<Sample> impleme
         return ID_PREFIX + sampleId;
     }
 
-    private static final String getDisplayIdSuffix(String suffix)
-    {
-        return GENERIC_SAMPLE_VIEWER + "-" + suffix;
-    }
-
     private final Component createRightPanel(SampleParentWithDerived sampleGeneration)
     {
         final Sample generator = sampleGeneration.getParent();
-        displayIdSuffix = getDisplayIdSuffix(generator.getSampleType().getCode());
+        displayIdSuffix = generator.getSampleType().getCode();
 
         final SectionsPanel container = new SectionsPanel(viewContext.getCommonViewContext());
         container.setDisplayID(DisplayTypeIDGenerator.GENERIC_SAMPLE_VIEWER, displayIdSuffix);
diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml
index e877a95020a..1a2e115708b 100644
--- a/openbis/source/java/genericApplicationContext.xml
+++ b/openbis/source/java/genericApplicationContext.xml
@@ -87,6 +87,11 @@
         <constructor-arg ref="last-modification-state" />
     </bean>
 
+		<bean id="web-client-configuration-provider"
+        class="ch.systemsx.cisd.openbis.generic.client.web.server.WebClientConfigurationProvider">
+        <constructor-arg value="${web-client-configuration-file}" />
+    </bean>
+
     <bean id="common-service" class="ch.systemsx.cisd.openbis.generic.client.web.server.CommonClientService">
         <constructor-arg ref="common-server" />
         <constructor-arg ref="request-context-provider" />
@@ -96,6 +101,7 @@
         <property name="onlineHelpGenericPageTemplate" value="${onlinehelp.generic.page-template}"/>
         <property name="onlineHelpSpecificRootURL" value="${onlinehelp.specific.root-url}"/>
         <property name="onlineHelpSpecificPageTemplate" value="${onlinehelp.specific.page-template}"/>
+        <property name="webClientConfigurationProvider" ref="web-client-configuration-provider"/>
     </bean>
     
     <bean id="rpc-name-server" class="ch.systemsx.cisd.common.api.server.RpcServiceNameServer" />
diff --git a/openbis/source/java/service.properties b/openbis/source/java/service.properties
index 98d9dcfe0d1..d65f137e976 100644
--- a/openbis/source/java/service.properties
+++ b/openbis/source/java/service.properties
@@ -120,4 +120,7 @@ demo.class = ch.systemsx.cisd.openbis.generic.server.task.DemoMaintenanceTask
 demo.interval = 60
 #demo.execute-only-once = true
 demo.property_1 = some value
-demo.property_2 = some value 2
\ No newline at end of file
+demo.property_2 = some value 2
+
+# Name of the file that stores Web Client configuration
+web-client-configuration-file = etc/web-client.properties
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/test/DisplaySettingsManagerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/test/DisplaySettingsManagerTest.java
index bdf39fc4c8c..8af84072733 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/test/DisplaySettingsManagerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/test/DisplaySettingsManagerTest.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplaySettingsManager.IDelayedUpdater;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ColumnSetting;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebClientConfiguration;
 
 /**
  * @author Franz-Josef Elmer
@@ -90,6 +91,8 @@ public class DisplaySettingsManagerTest extends AssertJUnit
 
     private ColumnModelEvent event;
 
+    private WebClientConfiguration webClientConfiguration;
+
     @BeforeMethod
     public void setUp()
     {
@@ -97,7 +100,8 @@ public class DisplaySettingsManagerTest extends AssertJUnit
         updater = context.mock(IDelayedUpdater.class);
         grid = context.mock(IDisplaySettingsGetter.class);
         displaySettings = new DisplaySettings();
-        manager = new DisplaySettingsManager(displaySettings, updater);
+        webClientConfiguration = new WebClientConfiguration();
+        manager = new DisplaySettingsManager(displaySettings, updater, webClientConfiguration);
         event = new ColumnModelEvent(null);
     }
 
-- 
GitLab