You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/01/03 15:50:01 UTC

[isis] 01/04: ISIS-2476: removes EntityLinksSelectorPanel, adds example MyEntityPanel (wip)

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

danhaywood pushed a commit to branch ISIS-2476
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f1075c1303a0a0c7934c985ed74da8df43cfbbd4
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Dec 16 09:04:54 2020 +0000

    ISIS-2476: removes EntityLinksSelectorPanel, adds example MyEntityPanel (wip)
---
 examples/demo/wicket/pom.xml                       |  14 +
 .../java/demoapp/webapp/wicket/DemoAppWicket.java  |  12 +-
 .../webapp/wicket/customview/MyEntityPanel.html    |  28 ++
 .../webapp/wicket/customview/MyEntityPanel.java    |  56 +++
 .../wicket/customview/MyEntityPanelFactory.java    |  34 +-
 .../selector/links/EntityLinksSelectorPanel.html   |  58 ----
 .../selector/links/EntityLinksSelectorPanel.java   | 384 ---------------------
 .../bs3/Bs3GridPanelFactory.java}                  |  32 +-
 .../ComponentFactoryRegistrarDefault.java          |  15 +-
 9 files changed, 137 insertions(+), 496 deletions(-)

diff --git a/examples/demo/wicket/pom.xml b/examples/demo/wicket/pom.xml
index b01731f..d8e778e 100644
--- a/examples/demo/wicket/pom.xml
+++ b/examples/demo/wicket/pom.xml
@@ -70,6 +70,20 @@
 			<type>pom</type>
 		</dependency>
 
+		<!-- Wicket viewer components -->
+
+		<dependency>
+			<groupId>org.apache.isis.viewer</groupId>
+			<artifactId>isis-viewer-wicket-ui</artifactId>
+			<version>2.0.0-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.isis.viewer</groupId>
+			<artifactId>isis-viewer-wicket-viewer</artifactId>
+			<version>2.0.0-SNAPSHOT</version>
+		</dependency>
+
 		<!-- EXTENSIONS -->
 
 		<dependency>
diff --git a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
index 917f6a9..1216076 100644
--- a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
+++ b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
@@ -18,11 +18,6 @@
  */
 package demoapp.webapp.wicket;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-import org.springframework.context.annotation.Import;
-
 import org.apache.isis.extensions.viewer.wicket.pdfjs.ui.IsisModuleExtPdfjsUi;
 import org.apache.isis.valuetypes.asciidoc.metamodel.IsisModuleValAsciidocMetaModel;
 import org.apache.isis.valuetypes.asciidoc.persistence.jdo.dn5.IsisModuleValAsciidocPersistenceJdoDn5;
@@ -31,8 +26,13 @@ import org.apache.isis.valuetypes.markdown.persistence.jdo.dn5.IsisModuleValMark
 import org.apache.isis.valuetypes.markdown.ui.wkt.IsisModuleValMarkdownUiWkt;
 import org.apache.isis.valuetypes.sse.ui.wkt.IsisModuleValSseUiWkt;
 import org.apache.isis.viewer.wicket.viewer.IsisModuleViewerWicketViewer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Import;
 
 import demoapp.web.DemoAppManifest;
+import demoapp.webapp.wicket.customview.MyEntityPanelFactory;
 
 /**
  * Bootstrap the application.
@@ -55,6 +55,8 @@ import demoapp.web.DemoAppManifest;
     IsisModuleValAsciidocPersistenceJdoDn5.class,
     IsisModuleValMarkdownPersistenceJdoDn5.class,
 
+    // @Component's
+    MyEntityPanelFactory.class
 })
 //@Log4j2
 public class DemoAppWicket extends SpringBootServletInitializer {
diff --git a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.html b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.html
new file mode 100644
index 0000000..0e9b129
--- /dev/null
+++ b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<body>
+<wicket:panel>
+    <div class="myEntityPanel">
+        <div><p>MY CUSTOM ENTITY</p></div>
+    </div>
+</wicket:panel>
+</body>
+</html>
diff --git a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.java b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.java
new file mode 100644
index 0000000..13c2911
--- /dev/null
+++ b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanel.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 demoapp.webapp.wicket.customview;
+
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+public class MyEntityPanel extends PanelAbstract<EntityModel>  {
+
+
+    private static final long serialVersionUID = 1L;
+
+
+    public MyEntityPanel(
+            final String id,
+            final EntityModel model,
+            final ComponentFactory componentFactory) {
+        super(id, model);
+    }
+
+
+    @Override
+    public UiHintContainer getUiHintContainer() {
+        // disables hinting by this component
+        return null;
+    }
+
+
+    /**
+     * Build UI only after added to parent.
+     */
+    @Override
+    public void onInitialize() {
+        super.onInitialize();
+    }
+
+}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanelFactory.java
similarity index 50%
copy from viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
copy to examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanelFactory.java
index c07efe0..2859bec 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
+++ b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/customview/MyEntityPanelFactory.java
@@ -1,23 +1,4 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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 org.apache.isis.viewer.wicket.ui.components.entity.selector.links;
+package demoapp.webapp.wicket.customview;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.model.IModel;
@@ -27,22 +8,19 @@ import org.apache.isis.applib.layout.grid.bootstrap3.BS3Grid;
 import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.entity.EntityComponentFactoryAbstract;
 import org.apache.isis.viewer.wicket.ui.components.layout.bs3.BS3GridPanel;
 
 import lombok.val;
 
-/**
- * {@link ComponentFactory} for {@link EntityLinksSelectorPanel}.
- */
-public class EntityLinksSelectorPanelFactory extends EntityComponentFactoryAbstract {
+@org.springframework.stereotype.Component
+public class MyEntityPanelFactory  extends EntityComponentFactoryAbstract {
 
     private static final long serialVersionUID = 1L;
 
-    public EntityLinksSelectorPanelFactory() {
-        super(ComponentType.ENTITY, EntityLinksSelectorPanel.class);
+    public MyEntityPanelFactory() {
+        super(ComponentType.ENTITY, MyEntityPanel.class);
     }
 
     @Override
@@ -60,6 +38,6 @@ public class EntityLinksSelectorPanelFactory extends EntityComponentFactoryAbstr
                 return new BS3GridPanel(id, entityModel, bs3Grid);
             }
         }
-        return new EntityLinksSelectorPanel(id, entityModel, this);
+        return new MyEntityPanel(id, entityModel, this);
     }
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.html b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.html
deleted file mode 100644
index b9196d6..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you 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.
--->
-<html xmlns:wicket="http://wicket.apache.org">
-<body>
-<wicket:panel>
-    <div class="linksSelectorPanel">
-        <div class="btn-group viewLinks" wicket:id="views">
-            <button type="button" class="btn btn-xs btn-info">
-                <span wicket:id="viewButtonIcon" class="ViewLinkItem"></span>
-                <span wicket:id="viewButtonTitle" class="ViewLinkItemTitle"></span>
-            </button>
-            <button type="button" class="btn btn-xs btn-info dropdown-toggle" data-toggle="dropdown">
-                <span class="caret"></span>
-            </button>
-            <ul wicket:id="viewList" class="dropdown-menu dropdown-menu-right" role="menu">
-                <li wicket:id="viewItem" class="viewItem">
-                    <a href="#" wicket:id="viewLink">
-                        <span wicket:id="viewItemIcon" class="ViewLinkItem"></span> <span wicket:id="viewItemTitle" class="ViewLinkItemTitle">[link title]</span>
-                    </a>
-                </li>
-            </ul>
-        </div>
-
-        <span wicket:id="additionalLinks"></span>
-
-        <div class="views">
-            <div wicket:id="entity-0" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-1" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-2" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-3" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-4" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-5" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-6" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-7" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-8" class="entityLinksSelectorPanel entityComponentType"></div>
-            <div wicket:id="entity-9" class="entityLinksSelectorPanel entityComponentType"></div>
-        </div>
-    </div>
-</wicket:panel>
-</body>
-</html>
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.java
deleted file mode 100644
index 62202cf..0000000
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanel.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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 org.apache.isis.viewer.wicket.ui.components.entity.selector.links;
-
-import java.util.List;
-import java.util.function.Predicate;
-
-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.ajax.markup.html.AjaxLink;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.AbstractLink;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.primitives._Ints;
-import org.apache.isis.core.metamodel.commons.StringExtensions;
-import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
-import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
-import org.apache.isis.viewer.wicket.model.links.LinksProvider;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.ui.CollectionContentsAsFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.AdditionalLinksPanel;
-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 lombok.val;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
-
-/**
- * Provides a list of links for selecting other views that support
- * {@link ComponentType#ENTITY} with a backing {@link EntityModel}.
- *
- * <p>
- *     TODO: this code could be simplified
- *     (pushed down common code here and for the CollectionsSelectorPanel in order to do so);
- *     haven't simplified this yet because currently there is only one view, so the markup
- *     rendered by this component 'collapses' to just show that underlying view.
- * </p>
- */
-public class EntityLinksSelectorPanel extends PanelAbstract<EntityModel>  {
-
-
-    private static final long serialVersionUID = 1L;
-
-    private static final int MAX_NUM_UNDERLYING_VIEWS = 10;
-
-    private static final String ID_ADDITIONAL_LINKS = "additionalLinks";
-
-    private static final String ID_VIEWS = "views";
-    private static final String ID_VIEW_LIST = "viewList";
-    private static final String ID_VIEW_LINK = "viewLink";
-    private static final String ID_VIEW_ITEM = "viewItem";
-    private static final String ID_VIEW_ITEM_TITLE = "viewItemTitle";
-    private static final String ID_VIEW_ITEM_ICON = "viewItemIcon";
-
-    private static final String UIHINT_VIEW = "view";
-    private static final String ID_VIEW_BUTTON_TITLE = "viewButtonTitle";
-    private static final String ID_VIEW_BUTTON_ICON = "viewButtonIcon";
-
-    private final ComponentType componentType;
-    private final String underlyingIdPrefix;
-
-    private ComponentFactory selectedComponentFactory;
-    protected Component selectedComponent;
-
-
-    public EntityLinksSelectorPanel(
-            final String id,
-            final EntityModel model,
-            final ComponentFactory factory) {
-        super(id, model);
-        this.underlyingIdPrefix = ComponentType.ENTITY.toString();
-        this.componentType = factory.getComponentType();
-    }
-
-
-    protected int determineInitialFactory(
-            final List<ComponentFactory> componentFactories,
-            final IModel<?> model) {
-        return 0;
-    }
-
-    @Override
-    public UiHintContainer getUiHintContainer() {
-        // disables hinting by this component
-        return null;
-    }
-
-
-    /**
-     * Build UI only after added to parent.
-     */
-    @Override
-    public void onInitialize() {
-        super.onInitialize();
-        ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactoryElseFailFast(getComponentType(), getModel());
-        addAdditionalLinks(getModel());
-        addUnderlyingViews(underlyingIdPrefix, getModel(), componentFactory);
-    }
-
-    protected void addAdditionalLinks(final EntityModel model) {
-        if(!(model instanceof LinksProvider)) {
-            permanentlyHide(ID_ADDITIONAL_LINKS);
-            return;
-        }
-        LinksProvider linksProvider = (LinksProvider) model;
-        List<LinkAndLabel> links = linksProvider.getLinks();
-
-        addAdditionalLinks(this, links);
-    }
-
-    protected void addAdditionalLinks(MarkupContainer markupContainer, List<LinkAndLabel> linkAndLabels) {
-        if(linkAndLabels == null || linkAndLabels.isEmpty()) {
-            Components.permanentlyHide(markupContainer, ID_ADDITIONAL_LINKS);
-            return;
-        }
-        linkAndLabels = _Lists.newArrayList(linkAndLabels); // copy, to serialize any lazy evaluation
-
-        AdditionalLinksPanel.addAdditionalLinks(
-                markupContainer, ID_ADDITIONAL_LINKS,
-                linkAndLabels,
-                AdditionalLinksPanel.Style.INLINE_LIST);
-    }
-
-    private void addUnderlyingViews(final String underlyingIdPrefix, final EntityModel model, final ComponentFactory factory) {
-        final List<ComponentFactory> componentFactories = findOtherComponentFactories(model, factory);
-
-        final int selected = honourViewHintElseDefault(componentFactories, model);
-
-        final EntityLinksSelectorPanel selectorPanel = this;
-
-        // create all, hide the one not selected
-        final Component[] underlyingViews = new Component[MAX_NUM_UNDERLYING_VIEWS];
-        int i = 0;
-        final EntityModel emptyModel = dummyOf(model);
-        for (ComponentFactory componentFactory : componentFactories) {
-            final String underlyingId = underlyingIdPrefix + "-" + i;
-
-            Component underlyingView = componentFactory.createComponent(underlyingId,i==selected? model: emptyModel);
-            underlyingViews[i++] = underlyingView;
-            selectorPanel.addOrReplace(underlyingView);
-        }
-
-        // hide any unused placeholders
-        while(i<MAX_NUM_UNDERLYING_VIEWS) {
-            String underlyingId = underlyingIdPrefix + "-" + i;
-            permanentlyHide(underlyingId);
-            i++;
-        }
-
-        // selector
-        if (componentFactories.size() <= 1) {
-            permanentlyHide(ID_VIEWS);
-        } else {
-            final Model<ComponentFactory> componentFactoryModel = new Model<>();
-
-            selectorPanel.selectedComponentFactory = componentFactories.get(selected);
-            componentFactoryModel.setObject(selectorPanel.selectedComponentFactory);
-
-            final WebMarkupContainer views = new WebMarkupContainer(ID_VIEWS);
-
-            final Label viewButtonTitle = new Label(ID_VIEW_BUTTON_TITLE, "Hidden");
-            views.addOrReplace(viewButtonTitle);
-
-            final Label viewButtonIcon = new Label(ID_VIEW_BUTTON_ICON, "");
-            views.addOrReplace(viewButtonIcon);
-
-            final WebMarkupContainer container = new WebMarkupContainer(ID_VIEW_LIST);
-
-            views.addOrReplace(container);
-            views.setOutputMarkupId(true);
-
-            this.setOutputMarkupId(true);
-
-            final ListView<ComponentFactory> listView = new ListView<ComponentFactory>(ID_VIEW_ITEM, componentFactories) {
-
-                private static final long serialVersionUID = 1L;
-
-                @Override
-                protected void populateItem(ListItem<ComponentFactory> item) {
-
-                    final int underlyingViewNum = item.getIndex();
-
-                    final ComponentFactory componentFactory = item.getModelObject();
-                    final AbstractLink link = new AjaxLink<Void>(ID_VIEW_LINK) {
-                        private static final long serialVersionUID = 1L;
-                        @Override
-                        public void onClick(AjaxRequestTarget target) {
-                            EntityLinksSelectorPanel linksSelectorPanel = EntityLinksSelectorPanel.this;
-                            linksSelectorPanel.setViewHintAndBroadcast(underlyingViewNum, target);
-
-                            final EntityModel dummyModel = dummyOf(model);
-                            for(int i=0; i<MAX_NUM_UNDERLYING_VIEWS; i++) {
-                                final Component component = underlyingViews[i];
-                                if(component == null) {
-                                    continue;
-                                }
-                                final boolean isSelected = i == underlyingViewNum;
-                                PanelAbstract.setVisible(component, isSelected);
-                                component.setDefaultModel(isSelected? model: dummyModel);
-                            }
-
-                            selectorPanel.selectedComponentFactory = componentFactory;
-                            selectorPanel.selectedComponent = underlyingViews[underlyingViewNum];
-                            selectorPanel.onSelect(target);
-                            target.add(selectorPanel, views);
-                        }
-
-                        @Override
-                        protected void onComponentTag(ComponentTag tag) {
-                            super.onComponentTag(tag);
-                            Buttons.fixDisabledState(this, tag);
-                        }
-                    };
-
-                    IModel<String> title = nameFor(componentFactory);
-                    Label viewItemTitleLabel = new Label(ID_VIEW_ITEM_TITLE, title);
-                    link.add(viewItemTitleLabel);
-
-                    Label viewItemIcon = new Label(ID_VIEW_ITEM_ICON, "");
-                    link.add(viewItemIcon);
-
-                    boolean isEnabled = componentFactory != selectorPanel.selectedComponentFactory;
-                    if (!isEnabled) {
-                        viewButtonTitle.setDefaultModel(title);
-                        IModel<String> cssClass = cssClassFor(componentFactory, viewButtonIcon);
-                        viewButtonIcon.add(AttributeModifier.replace("class", "ViewLinkItem " + cssClass.getObject()));
-                        link.setVisible(false);
-                    } else {
-                        IModel<String> cssClass = cssClassFor(componentFactory, viewItemIcon);
-                        viewItemIcon.add(new CssClassAppender(cssClass));
-                    }
-
-                    item.add(link);
-                }
-
-                private IModel<String> cssClassFor(final ComponentFactory componentFactory, Label viewIcon) {
-                    IModel<String> cssClass = null;
-                    if (componentFactory instanceof CollectionContentsAsFactory) {
-                        CollectionContentsAsFactory collectionContentsAsFactory = (CollectionContentsAsFactory) componentFactory;
-                        cssClass = collectionContentsAsFactory.getCssClass();
-                        viewIcon.setDefaultModelObject("");
-                        viewIcon.setEscapeModelStrings(true);
-                    }
-                    if (cssClass == null) {
-                        String name = componentFactory.getName();
-                        cssClass = Model.of(StringExtensions.asLowerDashed(name));
-                        // Small hack: if there is no specific CSS class then we assume that background-image is used
-                        // the span.ViewItemLink should have some content to show it
-                        // FIX: find a way to do this with CSS (width and height don't seems to help)
-                        viewIcon.setDefaultModelObject("&#160;&#160;&#160;&#160;&#160;");
-                        viewIcon.setEscapeModelStrings(false);
-                    }
-                    return cssClass;
-                }
-
-                private IModel<String> nameFor(final ComponentFactory componentFactory) {
-                    IModel<String> name = null;
-                    if (componentFactory instanceof CollectionContentsAsFactory) {
-                        CollectionContentsAsFactory collectionContentsAsFactory = (CollectionContentsAsFactory) componentFactory;
-                        name = collectionContentsAsFactory.getTitleLabel();
-                    }
-                    if (name == null) {
-                        name = Model.of(componentFactory.getName());
-                    }
-                    return name;
-                }
-            };
-            container.add(listView);
-            addOrReplace(views);
-        }
-
-        for(i=0; i<MAX_NUM_UNDERLYING_VIEWS; i++) {
-            Component component = underlyingViews[i];
-            if(component != null) {
-                if(i != selected) {
-                    super.setVisible(component, /*visible*/ false);
-                } else {
-                    selectedComponent = component;
-                }
-            }
-        }
-    }
-
-
-
-    protected void setViewHintAndBroadcast(int viewNum, AjaxRequestTarget target) {
-        final UiHintContainer uiHintContainer = getUiHintContainer();
-        if(uiHintContainer == null) {
-            return;
-        }
-        uiHintContainer.setHint(this, UIHINT_VIEW, ""+viewNum);
-    }
-
-    /**
-     * Overrideable hook.
-     */
-    protected void onSelect(AjaxRequestTarget target) {
-    }
-
-    /**
-     * Ask for a dummy (empty) {@link Model} to pass into those components that are rendered but will be
-     * made invisible using CSS styling.
-     */
-    protected EntityModel dummyOf(EntityModel model) {
-        return model;
-    }
-
-    protected int honourViewHintElseDefault(final List<ComponentFactory> componentFactories, final IModel<?> model) {
-        // honour hints ...
-        final UiHintContainer hintContainer = getUiHintContainer();
-        if(hintContainer != null) {
-            String viewStr = hintContainer.getHint(this, UIHINT_VIEW);
-            if(viewStr != null) {
-                
-                val parseResult = _Ints.parseInt(viewStr, 10);
-                if(parseResult.isPresent()) {
-                    val viewNum = parseResult.getAsInt();
-                    if(viewNum >= 0 && viewNum < componentFactories.size()) {
-                        return viewNum;
-                    }
-                }
-                // else fall through
-                
-            }
-        }
-
-        // ... else default
-        int initialFactory = determineInitialFactory(componentFactories, model);
-        if(hintContainer != null) {
-            hintContainer.setHint(this, UIHINT_VIEW, ""+initialFactory);
-            // don't broadcast (no AjaxRequestTarget, still configuring initial setup)
-        }
-        return initialFactory;
-    }
-
-
-    private List<ComponentFactory> findOtherComponentFactories(final EntityModel model, final ComponentFactory ignoreFactory) {
-        final List<ComponentFactory> componentFactories = getComponentFactoryRegistry().findComponentFactories(componentType, model);
-        val otherFactories = _Lists.filter(componentFactories, new Predicate<ComponentFactory>() {
-            @Override
-            public boolean test(final ComponentFactory input) {
-                return input != ignoreFactory;
-            }
-        });
-        return ordered(otherFactories);
-    }
-
-    protected List<ComponentFactory> ordered(List<ComponentFactory> otherFactories) {
-        return otherFactories;
-    }
-
-
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Bs3GridPanelFactory.java
similarity index 70%
rename from viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
rename to viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Bs3GridPanelFactory.java
index c07efe0..534b0ff 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/Bs3GridPanelFactory.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.viewer.wicket.ui.components.entity.selector.links;
+package org.apache.isis.viewer.wicket.ui.components.layout.bs3;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.model.IModel;
@@ -30,19 +30,29 @@ import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.entity.EntityComponentFactoryAbstract;
-import org.apache.isis.viewer.wicket.ui.components.layout.bs3.BS3GridPanel;
 
 import lombok.val;
 
 /**
- * {@link ComponentFactory} for {@link EntityLinksSelectorPanel}.
+ * {@link ComponentFactory} for {@link BS3GridPanel}.
  */
-public class EntityLinksSelectorPanelFactory extends EntityComponentFactoryAbstract {
+public class Bs3GridPanelFactory extends EntityComponentFactoryAbstract {
 
     private static final long serialVersionUID = 1L;
 
-    public EntityLinksSelectorPanelFactory() {
-        super(ComponentType.ENTITY, EntityLinksSelectorPanel.class);
+    public Bs3GridPanelFactory() {
+        super(ComponentType.ENTITY, BS3GridPanel.class);
+    }
+
+    @Override protected ApplicationAdvice appliesTo(final IModel<?> model) {
+        final EntityModel entityModel = (EntityModel) model;
+
+        val objectAdapter = entityModel.getObject();
+        final ObjectSpecification specification = entityModel.getTypeOfSpecification();
+        final GridFacet facet = specification.getFacet(GridFacet.class);
+
+        final Grid grid = facet.getGrid(objectAdapter);
+        return ApplicationAdvice.appliesIf(grid instanceof BS3Grid);
     }
 
     @Override
@@ -53,13 +63,7 @@ public class EntityLinksSelectorPanelFactory extends EntityComponentFactoryAbstr
         final ObjectSpecification specification = entityModel.getTypeOfSpecification();
         final GridFacet facet = specification.getFacet(GridFacet.class);
 
-        final Grid grid = facet.getGrid(objectAdapter);
-        if (grid != null) {
-            if(grid instanceof BS3Grid) {
-                final BS3Grid bs3Grid = (BS3Grid) grid;
-                return new BS3GridPanel(id, entityModel, bs3Grid);
-            }
-        }
-        return new EntityLinksSelectorPanel(id, entityModel, this);
+        val grid = (BS3Grid) facet.getGrid(objectAdapter);
+        return new BS3GridPanel(id, entityModel, grid);
     }
 }
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index ad80ce4..eef7349 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -23,11 +23,6 @@ import java.util.List;
 
 import javax.inject.Named;
 
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Service;
-
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
@@ -49,9 +44,9 @@ import org.apache.isis.viewer.wicket.ui.components.entity.collection.EntityColle
 import org.apache.isis.viewer.wicket.ui.components.entity.header.EntityHeaderPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory;
-import org.apache.isis.viewer.wicket.ui.components.entity.selector.links.EntityLinksSelectorPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.footer.FooterPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.layout.bs3.Bs3GridPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.blobclob.IsisBlobPanelFactory;
@@ -93,6 +88,10 @@ import org.apache.isis.viewer.wicket.ui.components.value.StandaloneValuePanelFac
 import org.apache.isis.viewer.wicket.ui.components.voidreturn.VoidReturnPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.welcome.WelcomePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.widgets.entitysimplelink.EntityLinkSimplePanelFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
 
 import lombok.extern.log4j.Log4j2;
 
@@ -135,7 +134,6 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
     }
 
     protected void addLinksSelectorFactories(final ComponentFactoryList componentFactories) {
-        componentFactories.add(new EntityLinksSelectorPanelFactory());
         componentFactories.add(new CollectionContentsMultipleViewsPanelFactory());
     }
 
@@ -186,6 +184,9 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
 
     protected void addComponentFactoriesForEntity(final ComponentFactoryList componentFactories) {
 
+        // top level
+        componentFactories.add(new Bs3GridPanelFactory());
+
         // lower-level
         componentFactories.add(new EntityIconAndTitlePanelFactory());
         componentFactories.add(new EntityIconTitleAndCopyLinkPanelFactory());