You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/09/20 07:56:33 UTC

[causeway] branch 3582-autoalign.dropdown.links created (now 7fa3d60e33)

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

ahuber pushed a change to branch 3582-autoalign.dropdown.links
in repository https://gitbox.apache.org/repos/asf/causeway.git


      at 7fa3d60e33 CAUSEWAY-3582: prepare for a more advanced drop-down menu item model

This branch includes the following new commits:

     new 7fa3d60e33 CAUSEWAY-3582: prepare for a more advanced drop-down menu item model

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[causeway] 01/01: CAUSEWAY-3582: prepare for a more advanced drop-down menu item model

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch 3582-autoalign.dropdown.links
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 7fa3d60e33db8deb9bbfd1907376c4c95bbd9d21
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 20 09:56:29 2023 +0200

    CAUSEWAY-3582: prepare for a more advanced drop-down menu item model
---
 .../ExcelModuleDemoUploadService_IntegTest.java    |  1 -
 .../restfulobjects/client/AuthenticationMode.java  | 18 ++++++
 .../viewer/wicket/model/links/LinkAndLabel.java    |  6 ++
 ...{ListOfLinksModel.java => ListOfMenuables.java} | 32 +++++-----
 .../viewer/wicket/model/links/Menuable.java        | 70 ++++++++++++++++++++++
 .../wicket/model/modelhelpers/WhereAmIHelper.java  |  3 +-
 .../entityactions/AdditionalLinksPanel.java        | 19 ++++--
 .../CollectionPresentationSelectorPanel.java       | 63 +++++++------------
 8 files changed, 152 insertions(+), 60 deletions(-)

diff --git a/extensions/core/excel/integtests/src/test/java/org/apache/causeway/extensions/excel/integtests/tests/ExcelModuleDemoUploadService_IntegTest.java b/extensions/core/excel/integtests/src/test/java/org/apache/causeway/extensions/excel/integtests/tests/ExcelModuleDemoUploadService_IntegTest.java
index d247708140..1f2bc4264e 100644
--- a/extensions/core/excel/integtests/src/test/java/org/apache/causeway/extensions/excel/integtests/tests/ExcelModuleDemoUploadService_IntegTest.java
+++ b/extensions/core/excel/integtests/src/test/java/org/apache/causeway/extensions/excel/integtests/tests/ExcelModuleDemoUploadService_IntegTest.java
@@ -63,5 +63,4 @@ public class ExcelModuleDemoUploadService_IntegTest extends ExcelModuleIntegTest
         Assertions.assertThat(all.size()).isEqualTo(8);
     }
 
-
 }
diff --git a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/AuthenticationMode.java b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/AuthenticationMode.java
index 1718429754..c00bc2b98c 100644
--- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/AuthenticationMode.java
+++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/AuthenticationMode.java
@@ -1,3 +1,21 @@
+/*
+ *  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.causeway.viewer.restfulobjects.client;
 
 public enum AuthenticationMode {
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/LinkAndLabel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/LinkAndLabel.java
index b954527654..5418af8224 100644
--- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/LinkAndLabel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/LinkAndLabel.java
@@ -40,6 +40,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 public final class LinkAndLabel
 implements
+    Menuable,
     HasUiComponent<AjaxLink<ManagedObject>>,
     HasManagedAction,
     Serializable {
@@ -104,4 +105,9 @@ implements
                         .test(this);
     }
 
+    @Override
+    public Kind menuableKind() {
+        return Kind.LINK;
+    }
+
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfMenuables.java
similarity index 62%
rename from viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java
rename to viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfMenuables.java
index 9f24d51c2f..b7c004b902 100644
--- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfMenuables.java
@@ -18,37 +18,41 @@
  */
 package org.apache.causeway.viewer.wicket.model.links;
 
-import java.util.List;
+import java.util.stream.Stream;
 
 import org.apache.wicket.model.ChainingModel;
 
 import org.apache.causeway.commons.collections.Can;
 
 import lombok.NonNull;
-import lombok.val;
 
-public class ListOfLinksModel
-extends ChainingModel<List<LinkAndLabel>> {
+public class ListOfMenuables
+extends ChainingModel<Can<? extends Menuable>> {
 
     private static final long serialVersionUID = 1L;
 
-    public ListOfLinksModel(final @NonNull Can<LinkAndLabel> links) {
-        super(links);
+    public ListOfMenuables(final @NonNull Can<? extends Menuable> menuables) {
+        super(menuables);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public List<LinkAndLabel> getObject() {
-        return ((Can<LinkAndLabel>)super.getTarget()).toList();
+    public final Can<? extends Menuable> getObject() {
+        return ((Can<? extends Menuable>)super.getTarget());
+    }
+
+    public final Can<? extends Menuable> menuables() {
+        return getObject();
+    }
+
+    public final Stream<LinkAndLabel> streamLinks() {
+        return menuables().stream()
+                .filter(LinkAndLabel.class::isInstance)
+                .map(LinkAndLabel.class::cast);
     }
 
     public boolean hasAnyVisibleLink() {
-        for (val linkAndLabel : getObject()) {
-            if(linkAndLabel.getUiComponent().isVisible()) {
-                return true;
-            }
-        }
-        return false;
+        return streamLinks().anyMatch(linkAndLabel->linkAndLabel.getUiComponent().isVisible());
     }
 
 }
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/Menuable.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/Menuable.java
new file mode 100644
index 0000000000..955fddca8e
--- /dev/null
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/Menuable.java
@@ -0,0 +1,70 @@
+/*
+ *  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.causeway.viewer.wicket.model.links;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Can be added to drop-down menus. Either a link, a separator or a separator label.
+ * @see Menuable.Kind
+ */
+public interface Menuable extends Serializable {
+
+    @RequiredArgsConstructor
+    public enum Kind {
+        SECTION_SEPARATOR("list-separator"),
+        SECTION_LABEL("list-section-label"),
+        LINK("viewItem");
+        @Getter private final String cssClassForLiElement;
+        public boolean isSectionSeparator() { return this==SECTION_SEPARATOR;}
+        public boolean isSectionLabel() { return this==SECTION_LABEL;}
+        public boolean isLink() { return this==LINK;}
+    }
+
+    Kind menuableKind();
+
+    // -- FACTORIES
+
+    public static SectionSeparator sectionSeparator() {
+        return new SectionSeparator();
+    }
+    public static SectionLabel sectionLabel(final @NonNull String sectionLabel) {
+        return new SectionLabel(sectionLabel);
+    }
+
+    // -- IMPLEMENTATIONS
+
+    @lombok.Value
+    public static class SectionSeparator implements Menuable {
+        private static final long serialVersionUID = 1L;
+        @Override public Kind menuableKind() { return Menuable.Kind.SECTION_SEPARATOR; }
+    }
+
+    @lombok.Value
+    public static class SectionLabel implements Menuable {
+        private static final long serialVersionUID = 1L;
+        final String sectionLabel;
+        @Override public Kind menuableKind() { return Menuable.Kind.SECTION_LABEL; }
+    }
+
+}
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/modelhelpers/WhereAmIHelper.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/modelhelpers/WhereAmIHelper.java
index 2c7f5a63d0..c066279e33 100644
--- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/modelhelpers/WhereAmIHelper.java
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/modelhelpers/WhereAmIHelper.java
@@ -29,7 +29,8 @@ import lombok.val;
 
 /**
  *
- * @implNote - previously this was called WhereAmIModel, but it isn't really a model in the Wicket sense (it's not serializable, for a start), hence renamed.
+ * @implNote - previously this was called WhereAmIModel,
+ *      but it isn't really a model in the Wicket sense (it's not serializable, for a start), hence renamed.
  * @since 2.0
  */
 public class WhereAmIHelper {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
index 6bdc311814..4147fdc81c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/AdditionalLinksPanel.java
@@ -19,12 +19,14 @@
 package org.apache.causeway.viewer.wicket.ui.components.actionmenu.entityactions;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.wicket.MarkupContainer;
 
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.viewer.wicket.model.links.LinkAndLabel;
-import org.apache.causeway.viewer.wicket.model.links.ListOfLinksModel;
+import org.apache.causeway.viewer.wicket.model.links.ListOfMenuables;
+import org.apache.causeway.viewer.wicket.model.links.Menuable;
 import org.apache.causeway.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.causeway.viewer.wicket.ui.util.Wkt;
 import org.apache.causeway.viewer.wicket.ui.util.WktComponents;
@@ -33,7 +35,7 @@ import org.apache.causeway.viewer.wicket.ui.util.WktLinks;
 import lombok.val;
 
 public class AdditionalLinksPanel
-extends PanelAbstract<List<LinkAndLabel>, ListOfLinksModel> {
+extends PanelAbstract<Can<? extends Menuable>, ListOfMenuables> {
 
     private static final long serialVersionUID = 1L;
 
@@ -70,17 +72,26 @@ extends PanelAbstract<List<LinkAndLabel>, ListOfLinksModel> {
         return Wkt.add(markupContainer, style.newPanel(id, links));
     }
 
+    protected final ListOfMenuables listOfMenuables() {
+        return getModel();
+    }
+
+    protected final List<LinkAndLabel> listOfLinkAndLabels() {
+        return listOfMenuables().streamLinks().collect(Collectors.toList());
+    }
+
+
     protected AdditionalLinksPanel(
             final String id,
             final Can<LinkAndLabel> linksDoNotUseDirectlyInsteadUseOfListOfLinksModel) {
 
-        super(id, new ListOfLinksModel(linksDoNotUseDirectlyInsteadUseOfListOfLinksModel));
+        super(id, new ListOfMenuables(linksDoNotUseDirectlyInsteadUseOfListOfLinksModel));
         setOutputMarkupId(true);
 
         val container = Wkt.add(this, Wkt.containerWithVisibility(ID_ADDITIONAL_LINK_LIST,
                     ()->AdditionalLinksPanel.this.getModel().hasAnyVisibleLink()));
 
-        Wkt.listViewAdd(container, ID_ADDITIONAL_LINK_ITEM, getModel(), item->{
+        Wkt.listViewAdd(container, ID_ADDITIONAL_LINK_ITEM, listOfLinkAndLabels(), item->{
             val linkAndLabel = item.getModelObject();
             item.addOrReplace(WktLinks.asAdditionalLink(item, ID_ADDITIONAL_LINK_TITLE, linkAndLabel));
         });
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/selector/CollectionPresentationSelectorPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/selector/CollectionPresentationSelectorPanel.java
index f1022ddca8..489935ae0f 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/selector/CollectionPresentationSelectorPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/selector/CollectionPresentationSelectorPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.causeway.viewer.wicket.ui.components.collection.selector;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
@@ -37,6 +36,7 @@ import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.core.metamodel.interactions.managed.nonscalar.DataTableModel;
 import org.apache.causeway.viewer.commons.model.components.UiComponentType;
 import org.apache.causeway.viewer.wicket.model.hints.CausewaySelectorEvent;
+import org.apache.causeway.viewer.wicket.model.links.Menuable;
 import org.apache.causeway.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.causeway.viewer.wicket.model.util.ComponentHintKey;
 import org.apache.causeway.viewer.wicket.ui.CollectionContentsAsFactory;
@@ -47,9 +47,7 @@ import org.apache.causeway.viewer.wicket.ui.util.Wkt;
 import org.apache.causeway.viewer.wicket.ui.util.WktComponents;
 import org.apache.causeway.viewer.wicket.ui.util.WktLinks;
 
-import lombok.Getter;
 import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 /**
@@ -132,12 +130,12 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
         final Label viewButtonIcon = Wkt.labelAdd(views, ID_VIEW_BUTTON_ICON, "");
 
         Wkt.listViewAdd(container, ID_VIEW_ITEM, sorted(componentFactories), item->{
-            val repeatedViewEntry = item.getModelObject();
-            val repeatedViewEntryKind = repeatedViewEntry.repeatedViewEntryKind;
+            val menuable = item.getModelObject();
+            val menuableKind = menuable.menuableKind();
 
-            Wkt.cssAppend(item, repeatedViewEntryKind.getCssClassForLiElement());
+            Wkt.cssAppend(item, menuableKind.getCssClassForLiElement());
 
-            switch(repeatedViewEntryKind) {
+            switch(menuableKind) {
             case SECTION_SEPARATOR:
                 WktComponents.permanentlyHide(item, ID_SECTION_LABEL);
                 WktComponents.permanentlyHide(item, ID_VIEW_LINK);
@@ -146,9 +144,9 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
             case SECTION_LABEL:
                 WktComponents.permanentlyHide(item, ID_SECTION_SEPARATOR);
                 WktComponents.permanentlyHide(item, ID_VIEW_LINK);
-                Wkt.labelAdd(item, ID_SECTION_LABEL, repeatedViewEntry.getSectionLabel());
+                Wkt.labelAdd(item, ID_SECTION_LABEL, ((Menuable.SectionLabel)menuable).getSectionLabel());
                 return;
-            case LINK_ENTRY:
+            case LINK:
                 WktComponents.permanentlyHide(item, ID_SECTION_SEPARATOR);
                 WktComponents.permanentlyHide(item, ID_SECTION_LABEL);
                 break; // fall through
@@ -156,6 +154,7 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
                 return;
             }
 
+            val repeatedViewEntry = (RepeatedViewEntry) menuable;
             final ComponentFactory componentFactory = repeatedViewEntry.getComponentFactory();
 
             // add direct download link instead of a panel
@@ -214,24 +213,24 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
      * @param filter
      * @see CollectionContentsAsFactory#orderOfAppearanceInUiDropdown()
      */
-    private List<RepeatedViewEntry> sorted(final Can<ComponentFactory> componentFactories) {
+    private List<Menuable> sorted(final Can<ComponentFactory> componentFactories) {
         val presentations = sorted(componentFactories, _Util.filterTablePresentations());
         val exports = sorted(componentFactories, _Util.filterTableExports());
-        val sortedWithSeparators = new ArrayList<RepeatedViewEntry>(
+        val sortedWithSeparators = new ArrayList<Menuable>(
                 presentations.size() + exports.size() + 2); // heap optimization, not strictly required
 
         boolean needsSpacer = false;
 
         if(!presentations.isEmpty()) {
-            sortedWithSeparators.add(RepeatedViewEntry.sectionLabel(translate("Presentations")));
+            sortedWithSeparators.add(Menuable.sectionLabel(translate("Presentations")));
             sortedWithSeparators.addAll(presentations);
             needsSpacer = true;
         }
         if(!exports.isEmpty()) {
             if(needsSpacer) {
-                sortedWithSeparators.add(RepeatedViewEntry.sectionSeparator());
+                sortedWithSeparators.add(Menuable.sectionSeparator());
             }
-            sortedWithSeparators.add(RepeatedViewEntry.sectionLabel(translate("Exports")));
+            sortedWithSeparators.add(Menuable.sectionLabel(translate("Exports")));
             sortedWithSeparators.addAll(exports);
         }
 
@@ -255,48 +254,29 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
                 new CausewaySelectorEvent(component, CollectionPresentationSelectorHelper.UIHINT_EVENT_VIEW_KEY, viewName, target));
     }
 
-    @RequiredArgsConstructor
-    enum RepeatedViewEntryKind {
-        SECTION_SEPARATOR("list-separator"),
-        SECTION_LABEL("list-section-label"),
-        LINK_ENTRY("viewItem");
-        @Getter private final String cssClassForLiElement;
-        boolean isSectionSeparator() { return this==SECTION_SEPARATOR;}
-        boolean isSectionLabel() { return this==SECTION_LABEL;}
-        boolean isLinkEntry() { return this==LINK_ENTRY;}
-    }
+
 
     @lombok.Value
-    static class RepeatedViewEntry implements Serializable {
+    static class RepeatedViewEntry implements Menuable {
         private static final long serialVersionUID = 1L;
 
         // -- FACTORIES
 
-        public static RepeatedViewEntry sectionSeparator() {
-            return new RepeatedViewEntry(RepeatedViewEntryKind.SECTION_SEPARATOR, null, null);
-        }
-        public static RepeatedViewEntry sectionLabel(final @NonNull String sectionLabel) {
-            return new RepeatedViewEntry(RepeatedViewEntryKind.SECTION_LABEL, null, sectionLabel);
-        }
         public static RepeatedViewEntry linkEntry(final @NonNull ComponentFactory componentFactory) {
-            return new RepeatedViewEntry(RepeatedViewEntryKind.LINK_ENTRY, componentFactory, null);
+            return new RepeatedViewEntry(componentFactory);
         }
 
         // -- CONSTRUCTION
 
-        final @NonNull RepeatedViewEntryKind repeatedViewEntryKind;
         final ComponentFactory componentFactory;
-        final String sectionLabel;
 
         // -- PREDICATES
 
         boolean isSelectedIn(final CollectionPresentationSelectorPanel panel) {
-           return repeatedViewEntryKind.isLinkEntry()
-                   && componentFactory == panel.selectedComponentFactory;
+           return componentFactory == panel.selectedComponentFactory;
         }
         boolean isPageReloadRequiredOnTableViewActivation() {
-            return repeatedViewEntryKind.isLinkEntry()
-                    && _Util.isPageReloadRequiredOnTableViewActivation(componentFactory);
+            return _Util.isPageReloadRequiredOnTableViewActivation(componentFactory);
         }
 
         // -- UPDATE STATE
@@ -310,9 +290,9 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
         // -- UTILITY
 
         static void addLinkWithIconAndTitle(
-                final @NonNull ListItem<RepeatedViewEntry> item,
+                final @NonNull ListItem<? extends Menuable> item,
                 final @NonNull MarkupContainer link) {
-            WktLinks.listItemAsDropdownLink(item, link,
+            WktLinks.listItemAsDropdownLink((ListItem<RepeatedViewEntry>)item, link,
                     ID_VIEW_ITEM_TITLE, RepeatedViewEntry::nameFor,
                     ID_VIEW_ITEM_ICON, null,
                     RepeatedViewEntry::cssClassFor);
@@ -326,6 +306,9 @@ extends PanelAbstract<DataTableModel, EntityCollectionModel> {
         private static IModel<String> cssClassFor(final RepeatedViewEntry either, final Label viewIcon) {
             return _Util.cssClassFor(either.getComponentFactory(), viewIcon);
         }
+
+        @Override
+        public Kind menuableKind() { return Kind.LINK; }
     }
 
 }