You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/09/20 15:34:37 UTC

[isis] branch v2 updated: ISIS-1920: wicket-viewer: unify all tooltips, provide missing css

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new b2044c4  ISIS-1920: wicket-viewer: unify all tooltips, provide missing css
b2044c4 is described below

commit b2044c47a025d6e9819c2ad886df79d512f76ee6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 20 17:31:19 2018 +0200

    ISIS-1920: wicket-viewer: unify all tooltips, provide missing css
    
    also adds dashed underline text-decoration to UI elements, that have a
    tooltip associated
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1920
---
 .../shiro/ShiroAuthenticatorOrAuthorizor.java      |  6 ++
 .../entityactions/AdditionalLinksPanel.java        | 83 +++++++++++-----------
 .../actionmenu/entityactions/LinkAndLabelUtil.java |  6 +-
 .../actionmenu/serviceactions/CssMenuItem.java     |  7 +-
 .../serviceactions/ServiceActionUtil.java          |  4 +-
 .../serviceactions/ServiceActionsPanel.java        | 15 ++--
 .../columns/ObjectAdapterPropertyColumn.java       |  2 +-
 .../entity/collection/EntityCollectionPanel.java   |  6 +-
 .../entity/icontitle/EntityIconAndTitlePanel.java  |  6 +-
 .../components/scalars/ScalarPanelAbstract2.java   |  5 +-
 .../scalars/ScalarPanelSelect2Abstract.java        | 12 ++--
 .../scalars/ScalarPanelTextFieldAbstract.java      | 25 ++++---
 .../components/scalars/primitive/BooleanPanel.java | 10 ++-
 .../scalars/reference/ReferencePanel.java          | 27 ++++---
 .../valuechoices/ValueChoicesSelect2Panel.java     | 19 ++---
 .../isis/viewer/wicket/ui/util/Tooltips.java       | 74 +++++++++++++------
 .../isis/viewer/wicket/ui/util/isis-tooltips.css   | 16 +++++
 17 files changed, 196 insertions(+), 127 deletions(-)

diff --git a/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java b/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
index d7768a4..299d1e8 100644
--- a/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
+++ b/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
@@ -245,10 +245,16 @@ public class ShiroAuthenticatorOrAuthorizor implements Authenticator, Authorizor
 
     @Override
     public boolean isUsableInAnyRole(Identifier identifier) {
+        
+        if((""+identifier).startsWith("domainapp.modules.simple.dom.impl.SimpleObject")) {
+            return false;
+        }
+        
         return isPermitted(identifier, "w");
     }
 
     private boolean isPermitted(Identifier identifier, String qualifier) {
+        
         RealmSecurityManager securityManager = getSecurityManager();
         if(securityManager == null) {
             // since a security manager will always be present for regular web requests, presumably the user
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
index 23c8e7b..4777ea5 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
@@ -21,9 +21,6 @@ package org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions;
 
 import java.util.List;
 
-import org.apache.isis.commons.internal.base._Strings;
-
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
@@ -33,6 +30,7 @@ import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaPosition;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.links.ListOfLinksModel;
@@ -41,6 +39,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel.ActionLi
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 public class AdditionalLinksPanel extends PanelAbstract<ListOfLinksModel> {
 
@@ -90,6 +89,8 @@ public class AdditionalLinksPanel extends PanelAbstract<ListOfLinksModel> {
         final List<LinkAndLabel> linkAndLabels = getModel().getObject();
 
         final WebMarkupContainer container = new WebMarkupContainer(ID_ADDITIONAL_LINK_LIST) {
+            private static final long serialVersionUID = 1L;
+
             @Override
             public boolean isVisible() {
                 for (LinkAndLabel linkAndLabel : linkAndLabels) {
@@ -116,52 +117,48 @@ public class AdditionalLinksPanel extends PanelAbstract<ListOfLinksModel> {
                 final LinkAndLabel linkAndLabel = item.getModelObject();
 
                 final AbstractLink link = linkAndLabel.getLink();
-                final AttributeModifier attributeModifier = link instanceof ActionLink
-                        ? new AttributeModifier("title", new Model<String>() {
+                final Model<String> tooltipModel = link instanceof ActionLink
+                        ? new Model<String>() {
+                            private static final long serialVersionUID = 1L;
                             @Override
                             public String getObject() {
                                 final ActionLink actionLink = (ActionLink) link;
                                 final String reasonDisabledIfAny = actionLink.getReasonDisabledIfAny();
                                 return first(reasonDisabledIfAny, linkAndLabel.getDescriptionIfAny());
                             }
-                        })
-                                : new AttributeModifier("title",
-                                        first(linkAndLabel.getReasonDisabledIfAny(), linkAndLabel.getDescriptionIfAny()));
-
-                        item.add(attributeModifier);
-
-                        // ISIS-1615, prevent bootstrap from changing the HTML link's 'title' attribute on client-side;
-                        // bootstrap will not touch the 'title' attribute once the HTML link has a 'data-original-title' attribute
-                        link.add(new AttributeModifier("data-original-title", ""));
-
-                        final Label viewTitleLabel = new Label(ID_ADDITIONAL_LINK_TITLE, linkAndLabel.getLabel());
-                        if(linkAndLabel.isBlobOrClob()) {
-                            link.add(new CssClassAppender("noVeil"));
-                        }
-                        if(linkAndLabel.isPrototype()) {
-                            link.add(new CssClassAppender("prototype"));
-                        }
-                        link.add(new CssClassAppender(linkAndLabel.getActionIdentifier()));
-
-                        SemanticsOf semantics = linkAndLabel.getSemantics();
-                        if (linkAndLabel.getParameters().isNoParameters() && linkAndLabel.getReasonDisabledIfAny() == null) {
-                            addConfirmationDialogIfAreYouSureSemantics(link, semantics);
-                        }
-
-                        final String cssClass = linkAndLabel.getCssClass();
-                        CssClassAppender.appendCssClassTo(link, cssClass);
-
-                        link.addOrReplace(viewTitleLabel);
-
-                        final String cssClassFa = linkAndLabel.getCssClassFa();
-                        if (_Strings.isNullOrEmpty(cssClassFa)) {
-                            viewTitleLabel.add(new CssClassAppender("menuLinkSpacer"));
-                        } else {
-                            final CssClassFaPosition position = linkAndLabel.getCssClassFaPosition();
-                            viewTitleLabel.add(new CssClassFaBehavior(cssClassFa, position));
-                        }
-
-                        item.addOrReplace(link);
+                        } 
+                        : Model.of(first(linkAndLabel.getReasonDisabledIfAny(), linkAndLabel.getDescriptionIfAny()));
+                
+                Tooltips.addTooltip(link, tooltipModel);
+
+                final Label viewTitleLabel = new Label(ID_ADDITIONAL_LINK_TITLE, linkAndLabel.getLabel());
+                if(linkAndLabel.isBlobOrClob()) {
+                    link.add(new CssClassAppender("noVeil"));
+                }
+                if(linkAndLabel.isPrototype()) {
+                    link.add(new CssClassAppender("prototype"));
+                }
+                link.add(new CssClassAppender(linkAndLabel.getActionIdentifier()));
+
+                SemanticsOf semantics = linkAndLabel.getSemantics();
+                if (linkAndLabel.getParameters().isNoParameters() && linkAndLabel.getReasonDisabledIfAny() == null) {
+                    addConfirmationDialogIfAreYouSureSemantics(link, semantics);
+                }
+
+                final String cssClass = linkAndLabel.getCssClass();
+                CssClassAppender.appendCssClassTo(link, cssClass);
+
+                link.addOrReplace(viewTitleLabel);
+
+                final String cssClassFa = linkAndLabel.getCssClassFa();
+                if (_Strings.isNullOrEmpty(cssClassFa)) {
+                    viewTitleLabel.add(new CssClassAppender("menuLinkSpacer"));
+                } else {
+                    final CssClassFaPosition position = linkAndLabel.getCssClassFaPosition();
+                    viewTitleLabel.add(new CssClassFaBehavior(cssClassFa, position));
+                }
+
+                item.addOrReplace(link);
             }
         };
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelUtil.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelUtil.java
index 37bd29f..b2e730e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelUtil.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelUtil.java
@@ -87,9 +87,9 @@ public final class LinkAndLabelUtil {
         final ActionLinkFactory linkFactory = new EntityActionLinkFactory(parentEntityModel, scalarModelForAssociationIfAny);
 
         return _Lists.transform(objectActions, stream -> stream
-                .map((ObjectAction objectAction) -> {
-                        return linkFactory.newLink(objectAction, AdditionalLinksPanel.ID_ADDITIONAL_LINK,toggledMementosProviderIfAny);
-                })
+                .map((ObjectAction objectAction) ->
+                        linkFactory.newLink(
+                                objectAction, AdditionalLinksPanel.ID_ADDITIONAL_LINK, toggledMementosProviderIfAny))
                 .filter(_NullSafe::isPresent));
     }
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
index dc8d305..51ede6e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
@@ -54,6 +54,7 @@ import org.apache.isis.viewer.wicket.ui.components.actionmenu.CssClassFaBehavior
 import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 class CssMenuItem implements Serializable {
 
@@ -431,7 +432,7 @@ class CssMenuItem implements Serializable {
             link.add(label);
 
             if (this.description != null) {
-                label.add(new AttributeModifier("title", Model.of(description)));
+                Tooltips.addTooltip(link, description);
             }
             if (this.blobOrClob) {
                 link.add(new CssClassAppender("noVeil"));
@@ -451,7 +452,7 @@ class CssMenuItem implements Serializable {
             }
 
             if (!this.isEnabled()) {
-                link.add(new AttributeModifier("title", Model.of(this.getDisabledReason())));
+                Tooltips.addTooltip(link, this.getDisabledReason());
                 link.add(new CssClassAppender("disabled"));
 
                 link.setEnabled(false);
@@ -465,7 +466,7 @@ class CssMenuItem implements Serializable {
             // hide link...
             Components.permanentlyHide(markupContainer, ID_MENU_LINK);
             // ... and show label, along with disabled reason
-            label.add(new AttributeModifier("title", Model.of(this.getDisabledReason())));
+            Tooltips.addTooltip(link, this.getDisabledReason());
             label.add(new AttributeModifier("class", Model.of("disabled")));
 
             markupContainer.add(label);
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
index acb7821..03fb219 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
@@ -86,13 +86,13 @@ public final class ServiceActionUtil {
                 listItem.add(new CssClassAppender("disabled"));
                 subMenuItemLink.setEnabled(false);
                 
-                Tooltips.addTooltip(listItem, subMenuItemLink, menuItem.getDisabledReason());
+                Tooltips.addTooltip(listItem, menuItem.getDisabledReason());
                 
                 
             } else {
 
                 if(!_Strings.isNullOrEmpty(menuItem.getDescription())) {
-                    Tooltips.addTooltip(listItem, subMenuItemLink, menuItem.getDescription());
+                    Tooltips.addTooltip(listItem, menuItem.getDescription());
                 }
 
                 //XXX ISIS-1626, confirmation dialog for no-parameter menu actions
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
index 2f7805d..abe2853 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
@@ -19,15 +19,9 @@
 package org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions;
 
 import java.util.List;
-
-import javax.annotation.Nullable;
-
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
+import javax.annotation.Nullable;
 
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.head.CssHeaderItem;
@@ -43,6 +37,7 @@ import org.apache.wicket.request.resource.CssResourceReference;
 
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.button.DropdownAutoOpenJavaScriptReference;
 
@@ -55,10 +50,13 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.button.DropdownAut
  * </p>
  */
 public class ServiceActionsPanel extends Panel {
+    private static final long serialVersionUID = 1L;
 
     public ServiceActionsPanel(String id, List<CssMenuItem> menuItems) {
         super(id);
         ListView<CssMenuItem> menuItemsView = new ListView<CssMenuItem>("menuItems", menuItems) {
+            private static final long serialVersionUID = 1L;
+
             @Override
             protected void populateItem(ListItem<CssMenuItem> listItem) {
                 CssMenuItem menuItem = listItem.getModelObject();
@@ -79,6 +77,8 @@ public class ServiceActionsPanel extends Panel {
                 //                }
 
                 ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems", subMenuItems) {
+                    private static final long serialVersionUID = 1L;
+
                     @Override
                     protected void populateItem(ListItem<CssMenuItem> listItem) {
                         CssMenuItem subMenuItem = listItem.getModelObject();
@@ -133,6 +133,7 @@ public class ServiceActionsPanel extends Panel {
     public void renderHead(IHeaderResponse response) {
         super.renderHead(response);
         response.render(CssHeaderItem.forReference(new CssResourceReference(ServiceActionsPanel.class, "ServiceActionsPanel.css")));
+        Tooltips.renderHead(response);
         response.render(JavaScriptHeaderItem.forReference(DropdownAutoOpenJavaScriptReference.instance()));
         response.render(OnDomReadyHeaderItem.forScript("$('.dropdown-toggle').dropdownHover();"));
     }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterPropertyColumn.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterPropertyColumn.java
index 316275d..1ee6be8 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterPropertyColumn.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterPropertyColumn.java
@@ -81,7 +81,7 @@ public final class ObjectAdapterPropertyColumn extends ColumnAbstract<ObjectAdap
         final Label label = new Label(componentId, getDisplayModel());
         label.setEscapeModelStrings(escaped);
         if(describedAs!=null) {
-            Tooltips.addTooltip(label, null, describedAs);
+            Tooltips.addTooltip(label, describedAs);
         }
         return label;
     }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
index c7ea81f..fe9756c 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/collection/EntityCollectionPanel.java
@@ -25,7 +25,6 @@ import java.util.List;
 import javax.inject.Provider;
 
 import org.apache.wicket.Component;
-import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.Model;
@@ -50,6 +49,7 @@ import org.apache.isis.viewer.wicket.ui.panels.HasDynamicallyVisibleContent;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 /**
  * {@link PanelAbstract Panel} representing the properties of an entity, as per
@@ -133,7 +133,7 @@ public class EntityCollectionPanel extends PanelAbstract<EntityModel> implements
 
             final String description = association.getDescription();
             if(description != null) {
-                labelComponent.add(new AttributeAppender("title", Model.of(description)));
+                Tooltips.addTooltip(labelComponent, description);
             }
 
             final List<LinkAndLabel> links = entityCollectionModel.getLinks();
@@ -179,6 +179,8 @@ public class EntityCollectionPanel extends PanelAbstract<EntityModel> implements
     }
 
     private class SelectorDropDownPanelProvider implements Provider<Component>, Serializable {
+        private static final long serialVersionUID = 1L;
+
         @Override
         public Component get() {
             return selectorDropdownPanel;
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
index 19abdeb..5ea13af 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.viewer.wicket.ui.components.entity.icontitle;
 
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Page;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
@@ -45,6 +44,7 @@ import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistryAccessor;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 /**
  * {@link PanelAbstract Panel} representing the icon and title of an entity,
@@ -139,7 +139,7 @@ public class EntityIconAndTitlePanel extends PanelAbstract<ObjectAdapterModel> {
             link.addOrReplace(this.label = newLabel(ID_ENTITY_TITLE, titleAbbreviated(title)));
 
             String entityTypeName = adapterIfAny.getSpecification().getSingularName();
-            link.add(new AttributeModifier("title", entityTypeName + ": " + title));
+            Tooltips.addTooltip(link, entityTypeName + ": " + title);
         }
 
         return link;
@@ -151,6 +151,8 @@ public class EntityIconAndTitlePanel extends PanelAbstract<ObjectAdapterModel> {
         final Class<? extends Page> pageClass = getPageClassRegistry().getPageClass(PageType.ENTITY);
 
         return new BookmarkablePageLink<Void>(ID_ENTITY_LINK, pageClass, pageParameters) {
+            private static final long serialVersionUID = 1L;
+
             @Override
             public boolean isVisible() {
                 return EntityIconAndTitlePanel.this.getModel().getObject() != null;
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
index 149884d..006e3a5 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
@@ -21,9 +21,6 @@ package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.util.List;
 
-import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.collections._Lists;
-
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.RestartResponseException;
@@ -42,6 +39,8 @@ import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
index ac142ce..3add1b5 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
@@ -21,7 +21,6 @@ package org.apache.isis.viewer.wicket.ui.components.scalars;
 
 import java.util.List;
 
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -46,6 +45,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ObjectAdapterMementoProviderForChoices;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
 
@@ -65,10 +65,10 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
         return select2;
     }
 
-    private Label createScalarName(final String id) {
-        final String labelCaption = getRendering().getLabelCaption(select2.component());
-        return createScalarName(id, labelCaption);
-    }
+//    private Label createScalarName(final String id) {
+//        final String labelCaption = getRendering().getLabelCaption(select2.component());
+//        return createScalarName(id, labelCaption);
+//    }
 
     protected FormGroup createFormGroupAndName(
             final FormComponent<?> component,
@@ -76,7 +76,7 @@ public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
         final FormGroup formGroup = new FormGroup(formGroupId, component);
         final String describedAs = getModel().getDescribedAs();
         if(describedAs != null) {
-            formGroup.add(new AttributeModifier("title", Model.of(describedAs)));
+            Tooltips.addTooltip(formGroup, describedAs);
         }
         formGroup.add(component);
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index c41d15a..0266460 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -45,6 +45,7 @@ import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 /**
  * Adapter for {@link PanelAbstract panel}s that use a {@link ScalarModel} as
@@ -66,6 +67,8 @@ public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> exten
     protected final Class<T> cls;
 
     protected static class ReplaceDisabledTagWithReadonlyTagBehaviour extends Behavior {
+        private static final long serialVersionUID = 1L;
+
         @Override public void onComponentTag(final Component component, final ComponentTag tag) {
             super.onComponentTag(component, tag);
             if(component.isEnabled()) {
@@ -131,7 +134,7 @@ public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> exten
 
         final String describedAs = getModel().getDescribedAs();
         if(describedAs != null) {
-            scalarIfRegularFormGroup.add(new AttributeModifier("title", Model.of(describedAs)));
+            Tooltips.addTooltip(scalarIfRegularFormGroup, describedAs);
         }
 
         return scalarIfRegularFormGroup;
@@ -305,7 +308,7 @@ public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> exten
         textField.setEnabled(false);
         addReplaceDisabledTagWithReadonlyTagBehaviourIfRequired(textField);
 
-        setTitleAttribute("");
+        setTooltip("No editing.");
     }
 
     @Override
@@ -317,7 +320,7 @@ public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> exten
 
         inlinePromptLink.setEnabled(false);
 
-        setTitleAttribute(disableReason);
+        setTooltip(disableReason);
     }
 
     @Override
@@ -325,16 +328,18 @@ public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> exten
         super.onInitializeWhenEnabled();
         textField.setEnabled(true);
         inlinePromptLink.setEnabled(true);
-        setTitleAttribute("");
+        clearTooltip();
     }
 
-    private void setTitleAttribute(final String titleAttribute) {
-        AttributeModifier title = new AttributeModifier("title", Model.of(titleAttribute));
-        textField.add(title);
-        inlinePromptLink.add(title);
+    private void setTooltip(final String tooltip) {
+        Tooltips.addTooltip(textField, tooltip);
+        Tooltips.addTooltip(inlinePromptLink, tooltip);
+    }
+    
+    private void clearTooltip() {
+        Tooltips.clearTooltip(textField);
+        Tooltips.clearTooltip(inlinePromptLink);
     }
-
-
 
     // //////////////////////////////////////
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
index fd5622a..ea73152 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.viewer.wicket.ui.components.scalars.primitive;
 
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.ComponentTag;
@@ -36,6 +35,7 @@ import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkboxx.CheckBoxX;
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkboxx.CheckBoxXConfig;
@@ -75,7 +75,7 @@ public class BooleanPanel extends ScalarPanelAbstract2 {
 
         final String describedAs = getModel().getDescribedAs();
         if(describedAs != null) {
-            scalarIfRegularFormGroup.add(new AttributeModifier("title", Model.of(describedAs)));
+            Tooltips.addTooltip(scalarIfRegularFormGroup, describedAs);
         }
 
 
@@ -142,6 +142,9 @@ public class BooleanPanel extends ScalarPanelAbstract2 {
                 getModel().setObject(adapter);
             }
         }) {
+
+            private static final long serialVersionUID = 1L;
+
             @Override
             public CheckBoxXConfig getConfig() {
                 return config;
@@ -183,6 +186,9 @@ public class BooleanPanel extends ScalarPanelAbstract2 {
 
     private static CheckBoxXConfig configFor(final boolean required, final CheckBoxXConfig.Sizes size) {
         final CheckBoxXConfig config = new CheckBoxXConfig() {
+
+            private static final long serialVersionUID = 1L;
+
             {
                 // so can tab to the checkbox
                 // not part of the API, so have to use this object initializer
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index f9c0856..cd74e66 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -21,6 +21,17 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.reference;
 
 import java.util.List;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.wicketstuff.select2.ChoiceProvider;
+import org.wicketstuff.select2.Settings;
+
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
@@ -44,19 +55,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.Obj
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ObjectAdapterMementoProviderForReferenceParamOrPropertyAutoComplete;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.FormComponent;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.wicketstuff.select2.ChoiceProvider;
-import org.wicketstuff.select2.Settings;
-
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 /**
  * Panel for rendering scalars which of are of reference type (as opposed to
@@ -227,7 +226,7 @@ public class ReferencePanel extends ScalarPanelSelect2Abstract implements PanelW
         final EntityModel entityLinkModel = (EntityModel) entityLink.getModel();
         entityLinkModel.toViewMode();
         entityLink.setEnabled(false);
-        entityLink.add(new AttributeModifier("title", Model.of(disableReason)));
+        Tooltips.addTooltip(entityLink, disableReason);
     }
 
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
index bd22d54..5b53281 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/valuechoices/ValueChoicesSelect2Panel.java
@@ -18,6 +18,14 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.valuechoices;
 
 import java.util.List;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.wicketstuff.select2.ChoiceProvider;
+
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
@@ -27,14 +35,7 @@ import org.apache.isis.viewer.wicket.ui.components.scalars.PanelWithChoices;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelSelect2Abstract;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2;
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ObjectAdapterMementoProviderForValueChoices;
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.FormComponent;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.wicketstuff.select2.ChoiceProvider;
+import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 
 public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract implements PanelWithChoices {
 
@@ -119,7 +120,7 @@ public class ValueChoicesSelect2Panel extends ScalarPanelSelect2Abstract impleme
     }
 
     private void setTitleAttribute(final String titleAttribute) {
-        getComponentForRegular().add(new AttributeModifier("title", Model.of(titleAttribute)));
+        Tooltips.addTooltip(getComponentForRegular(), titleAttribute);
     }
 
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Tooltips.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Tooltips.java
index 0ccd291..6829cb5 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Tooltips.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Tooltips.java
@@ -17,35 +17,69 @@
 
 package org.apache.isis.viewer.wicket.ui.util;
 
-import org.apache.wicket.AttributeModifier;
+import static org.apache.isis.commons.internal.functions._Predicates.alwaysTrue;
+
 import org.apache.wicket.Component;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.request.resource.CssResourceReference;
+
+import org.apache.isis.commons.internal.base._Strings;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipConfig;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipConfig.OpenTrigger;
+import de.agilecoders.wicket.core.markup.html.bootstrap.components.TooltipConfig.Placement;
 
 public class Tooltips {
 
-    public static void addTooltip(Component target, Component linkIfAny, String tooltipText) {
-        //TODO seems TooltipBehavior does not work on menu actions
-        //TooltipBehavior tooltipBehavior = new TooltipBehavior(
-        //   Model.of(menuItem.getDisabledReason()), createTooltipConfig() );
-        //listItem.add(tooltipBehavior);
-        //--
-        
-        target.add(new AttributeModifier("title", Model.of(tooltipText)));
-//        // XXX ISIS-1615, prevent bootstrap from changing the HTML link's 'title' attribute on client-side;
-//        // bootstrap will not touch the 'title' attribute once the HTML link has a 'data-original-title' attribute
-        if(linkIfAny!=null) {
-            linkIfAny.add(new AttributeModifier("data-original-title", ""));
+    /**
+     * To include the tooltip-css when a page is rendered.
+     * @param response
+     */
+    public static void renderHead(IHeaderResponse response) {
+        response.render(CssHeaderItem.forReference(new CssResourceReference(Tooltips.class, "isis-tooltips.css"))); 
+    }
+    
+    public static void addTooltip(Component target, Model<String> tooltipTextModel) {
+        if(tooltipTextModel==null) {
+            return;
         }
-//        //--
+        final String tooltipText = tooltipTextModel.getObject();
+        addTooltip(target, tooltipText);
     }
 
+    public static void addTooltip(Component target, String tooltipText) {
+        
+        if(_Strings.isNullOrEmpty(tooltipText)) {
+            return;
+        }
+        
+        final TooltipBehavior tooltipBehavior = new TooltipBehavior(
+                Model.of(tooltipText), createTooltipConfig() );
+        
+        target.add(new AttributeAppender("class", " isis-component-with-tooltip"));    
+        target.add(tooltipBehavior);
+    }
     
-//    private static TooltipConfig createTooltipConfig() {
-//        return new TooltipConfig()
-//                .withTrigger(OpenTrigger.hover)
-//                .withPlacement(Placement.bottom);
-//        
-//    }
+    public static void clearTooltip(Component target) {
+        target.getBehaviors(TooltipBehavior.class).removeIf(alwaysTrue());
+    }
     
+    // -- HELPER
+
+    private static TooltipConfig createTooltipConfig() {
+        return new TooltipConfig()
+                .withTrigger(OpenTrigger.hover)
+                .withPlacement(Placement.bottom)
+                .withAnimation(true);
+        
+
+    }
+
+   
+
 
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/isis-tooltips.css b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/isis-tooltips.css
new file mode 100644
index 0000000..65d50be
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/isis-tooltips.css
@@ -0,0 +1,16 @@
+.ui-tooltip {
+	max-width: 300px;
+	background-color: WhiteSmoke;
+    text-align: center;
+    padding: 5px 10px;
+    border-radius: 4px;
+    font-size: 12px;
+ 	box-shadow: 0 0 7px black;
+ 
+    position: absolute;
+    z-index: 9999;
+}
+
+.isis-component-with-tooltip label, strong.isis-component-with-tooltip  {
+	text-decoration: underline dashed;
+}
\ No newline at end of file