This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch spring6
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/spring6 by this push:
new 28d011e35b CAUSEWAY-3407: simplified menu model (trivially
serializable)
28d011e35b is described below
commit 28d011e35b58f9e3a0e2d9cf894580610ab7355f
Author: Andi Huber <[email protected]>
AuthorDate: Fri Apr 7 09:43:49 2023 +0200
CAUSEWAY-3407: simplified menu model (trivially serializable)
---
.../interactions/managed/ManagedAction.java | 2 +
.../viewer/javafx/ui/main/MainViewFx.java | 6 +-
.../viewer/javafx/ui/main/MenuBuilderFx.java | 19 +++---
.../viewer/thymeflux/model/root/MenuBuilder.java | 57 ----------------
.../model/root/ThymefluxRootController.java | 2 -
.../test/src/main/resources/application.yml | 28 ++++++++
.../thymeflux/test/ThymefluxViewerTests.java | 23 ++++++-
.../viewer/src/main/resources/templates/root.html | 18 ++---
.../ui/pages/main/MainView_createHeader.java | 9 +--
.../vaadin/ui/pages/main/MenuBuilderVaa.java | 25 +++----
.../commons/applib/src/main/java/module-info.java | 9 ++-
.../applib/services/header/HeaderUiModel.java | 6 +-
.../commons/applib/services/menu/MenuUiModel.java | 58 ----------------
.../applib/services/menu/MenuUiService.java | 7 +-
.../commons/applib/services/menu/MenuVisitor.java | 14 ++--
.../applib/services/menu/model/MenuAction.java | 52 +++++++++++++++
.../{MenuVisitor.java => model/MenuDropdown.java} | 15 ++---
.../MenuDropdownBuilder.java} | 32 ++++++---
.../{MenuUiService.java => model/MenuEntry.java} | 21 +++---
.../{MenuVisitor.java => model/MenuSpacer.java} | 19 +++---
.../applib/services/menu/model/NavBarSection.java | 66 ++++++++++++++++++
.../{MenuVisitor.java => model/NavbarUiModel.java} | 16 ++---
.../services/src/main/java/module-info.java | 12 ++--
.../services/header/HeaderUiServiceDefault.java | 5 +-
.../services/menu/MenuUiServiceDefault.java | 78 ++++++++++++----------
.../commons/services/menu/_MenuItemBuilder.java | 22 ++++--
.../wicket/model/models/ServiceActionsModel.java | 16 ++---
.../entityactions/LinkAndLabelFactory.java | 12 ++--
.../serviceactions/ServiceActionUtil.java | 39 ++++-------
.../serviceactions/ServiceActionsPanelFactory.java | 8 +--
.../serviceactions/TertiaryMenuPanelFactory.java | 6 +-
.../wicket/ui/components/header/HeaderPanel.java | 15 +++--
32 files changed, 400 insertions(+), 317 deletions(-)
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java
index e18a23f346..4ee38304ec 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java
@@ -238,4 +238,6 @@ public final class ManagedAction extends ManagedMember {
}
+
+
}
diff --git
a/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MainViewFx.java
b/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MainViewFx.java
index 9ea2c64a59..edaed5b32a 100644
---
a/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MainViewFx.java
+++
b/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MainViewFx.java
@@ -104,9 +104,9 @@ public class MainViewFx {
val leftMenuBuilder = MenuBuilderFx.of(uiContext, menuBarLeft,
uiActionHandler::handleActionLinkClicked);
val rightMenuBuilder = MenuBuilderFx.of(uiContext, menuBarRight,
uiActionHandler::handleActionLinkClicked);
- header.getPrimary().buildMenuItems(metaModelContext, leftMenuBuilder);
- header.getSecondary().buildMenuItems(metaModelContext,
rightMenuBuilder);
- header.getTertiary().buildMenuItems(metaModelContext,
rightMenuBuilder);
+ header.getNavbar().primary().visitMenuItems(leftMenuBuilder);
+ header.getNavbar().secondary().visitMenuItems(rightMenuBuilder);
+ header.getNavbar().tertiary().visitMenuItems(rightMenuBuilder);
}
private void replaceContent(final Node node) {
diff --git
a/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
b/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
index 7cb3862677..0e7053c44e 100644
---
a/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
+++
b/incubator/viewers/javafx/ui/src/main/java/org/apache/causeway/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
@@ -22,8 +22,9 @@ import java.util.function.Consumer;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.incubator.viewer.javafx.model.context.UiContextFx;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuAction;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdown;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
@@ -44,18 +45,18 @@ public class MenuBuilderFx implements MenuVisitor {
private Menu currentTopLevelMenu = null;
@Override
- public void addTopLevel(MenuItemDto menuDto) {
- log.debug("top level menu {}", menuDto.getName());
+ public void onTopLevel(final MenuDropdown menuDto) {
+ log.debug("top level menu {}", menuDto.name());
menuBar.getMenus()
- .add(currentTopLevelMenu = new Menu(menuDto.getName()));
+ .add(currentTopLevelMenu = new Menu(menuDto.name()));
}
@Override
- public void addSubMenu(MenuItemDto menuDto) {
- val managedAction = menuDto.getManagedAction();
+ public void onMenuAction(final MenuAction menuDto) {
+ val managedAction = menuDto.managedAction();
- log.debug("sub menu {}", menuDto.getName());
+ log.debug("sub menu {}", menuDto.name());
val actionUiModel =
uiContext.getActionUiModelFactory().newActionUiModel(uiContext, managedAction);
val menuItem = actionUiModel.createMenuUiComponent();
@@ -64,13 +65,13 @@ public class MenuBuilderFx implements MenuVisitor {
}
@Override
- public void addSectionSpacer() {
+ public void onSectionSpacer() {
log.debug("menu spacer");
currentTopLevelMenu.getItems().add(new SeparatorMenuItem());
}
@Override
- public void addSectionLabel(String named) {
+ public void onSectionLabel(final String named) {
log.debug("section label {}", named);
val menuItem = new MenuItem(named);
currentTopLevelMenu.getItems().add(menuItem);
diff --git
a/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/MenuBuilder.java
b/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/MenuBuilder.java
deleted file mode 100644
index 69e3ddcc36..0000000000
---
a/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/MenuBuilder.java
+++ /dev/null
@@ -1,57 +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.causeway.viewer.thymeflux.model.root;
-
-import java.awt.MenuItem;
-
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
-
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-//TODO just a stub yet
-@RequiredArgsConstructor(staticName = "of")
-@Log4j2
-class MenuBuilder implements MenuVisitor {
-
- @Override
- public void addTopLevel(final MenuItemDto menuDto) {
- log.debug("top level menu {}", menuDto.getName());
- }
-
- @Override
- public void addSubMenu(final MenuItemDto menuDto) {
- val managedAction = menuDto.getManagedAction();
- log.debug("sub menu {}", menuDto.getName());
- }
-
- @Override
- public void addSectionSpacer() {
- log.debug("menu spacer");
- }
-
- @Override
- public void addSectionLabel(final String named) {
- log.debug("section label {}", named);
- val menuItem = new MenuItem(named);
- }
-
-}
diff --git
a/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/ThymefluxRootController.java
b/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/ThymefluxRootController.java
index 4cf53ddf38..2cb59f7b91 100644
---
a/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/ThymefluxRootController.java
+++
b/incubator/viewers/thymeflux/model/src/main/java/org/apache/causeway/viewer/thymeflux/model/root/ThymefluxRootController.java
@@ -47,9 +47,7 @@ public class ThymefluxRootController {
interactionService.run(interactionContextMockup, ()->{
var headerUiModel = headerUiModelProvider.getHeader();
-
model.addAttribute("headerUiModel", headerUiModel);
-
});
//TODO on error use error template instead
diff --git
a/incubator/viewers/thymeflux/test/src/main/resources/application.yml
b/incubator/viewers/thymeflux/test/src/main/resources/application.yml
index d89e5ba630..1afed3a6d7 100644
--- a/incubator/viewers/thymeflux/test/src/main/resources/application.yml
+++ b/incubator/viewers/thymeflux/test/src/main/resources/application.yml
@@ -91,6 +91,34 @@ causeway:
- url: https://causeway.apache.org
image: images/gift_48.png
name: Apache Causeway
+
+ # schema auto creation etc. ...
+ persistence:
+ schema:
+ autoCreateSchemas:
causewayExtSecman,causewayExtCommandLog,causewayExtExecutionLog,causewayExtExecutionOutbox,causewayExtSessionLog,causewayExtAuditTrail,demo
+
+ extensions:
+ secman:
+ seed:
+ admin:
+ user-name: "sven"
+ password: "pass"
+ role-name: "causeway-ext-secman-admin"
+ namespace-permissions:
+ sticky: "causeway"
+ additional: "demo"
+ regular-user:
+ role-name: "causeway-ext-secman-user"
+ permissionsEvaluationPolicy: ALLOW_BEATS_VETO
+
+ testing:
+ fixtures:
+ fixture-scripts-specification:
+ context-class: demoapp.dom._infra.fixtures.DemoFixtureScript
+ multiple-execution-strategy: execute_once_by_value
+ non-persisted-objects-strategy: ignore
+ recreate: demoapp.dom._infra.fixtures.DemoFixtureScript
+ run-script-default: demoapp.dom._infra.fixtures.DemoFixtureScript
server:
http2:
diff --git
a/incubator/viewers/thymeflux/test/src/test/java/org/apache/causeway/viewer/thymeflux/test/ThymefluxViewerTests.java
b/incubator/viewers/thymeflux/test/src/test/java/org/apache/causeway/viewer/thymeflux/test/ThymefluxViewerTests.java
index a819ec3587..b8bf73f4a1 100644
---
a/incubator/viewers/thymeflux/test/src/test/java/org/apache/causeway/viewer/thymeflux/test/ThymefluxViewerTests.java
+++
b/incubator/viewers/thymeflux/test/src/test/java/org/apache/causeway/viewer/thymeflux/test/ThymefluxViewerTests.java
@@ -26,8 +26,12 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.ui.Model;
import org.springframework.validation.support.BindingAwareModelMap;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import org.apache.causeway.applib.annotation.DomainServiceLayout.MenuBar;
+import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavBarSection;
import org.apache.causeway.viewer.thymeflux.model.root.ThymefluxRootController;
import
org.apache.causeway.viewer.thymeflux.viewer.CausewayModuleIncViewerThymefluxViewer;
@@ -55,8 +59,25 @@ class ThymefluxViewerTests {
final Model model = new BindingAwareModelMap();
rootController.root(model);
- var headerUiModel = model.getAttribute("headerUiModel");
+ var headerUiModel = (HeaderUiModel)model.getAttribute("headerUiModel");
assertNotNull(headerUiModel);
+
+ var primary = (NavBarSection)headerUiModel.getNavbar().primary();
+ var secondary = (NavBarSection)headerUiModel.getNavbar().secondary();
+ var tertiary = (NavBarSection)headerUiModel.getNavbar().tertiary();
+
+ assertEquals(MenuBar.PRIMARY, primary.menuBarSelect());
+ assertEquals(MenuBar.SECONDARY, secondary.menuBarSelect());
+ assertEquals(MenuBar.TERTIARY, tertiary.menuBarSelect());
+
+ primary.topLevelEntries().forEach(top->System.err.printf("prim: %s%n",
top.name()));
+ secondary.topLevelEntries().forEach(top->System.err.printf("sec:
%s%n", top.name()));
+ tertiary.topLevelEntries().forEach(top->System.err.printf("tert:
%s%n", top.name()));
+
+ primary.topLevelEntries().forEach(top->System.err.printf("prim: %s%n",
top));
+ secondary.topLevelEntries().forEach(top->System.err.printf("sec:
%s%n", top));
+ tertiary.topLevelEntries().forEach(top->System.err.printf("tert:
%s%n", top));
+
}
diff --git
a/incubator/viewers/thymeflux/viewer/src/main/resources/templates/root.html
b/incubator/viewers/thymeflux/viewer/src/main/resources/templates/root.html
index 0cfb934923..4e00613028 100644
--- a/incubator/viewers/thymeflux/viewer/src/main/resources/templates/root.html
+++ b/incubator/viewers/thymeflux/viewer/src/main/resources/templates/root.html
@@ -87,17 +87,17 @@
<td>[[${headerUiModel.branding.logoHref}]]</td>
</tr>
- <tr class="result" th:each="menuModel : ${headerUiModel.primary}">
- <td>[[${menuModel.menuBarSelect}]]</td>
- <td>[[${menuModel.menuContributingServiceIds}]]</td>
+ <tr class="result" th:each="topLevelEntry :
${primary.topLevelEntries()}">
+ <td>[[${topLevelEntry.name}]]</td>
+ <td>[[${topLevelEntry.subEntries}]]</td>
</tr>
- <tr class="result" th:each="menuModel :
${headerUiModel.secondary}">
- <td>[[${menuModel.menuBarSelect}]]</td>
- <td>[[${menuModel.menuContributingServiceIds}]]</td>
+ <tr class="result" th:each="topLevelEntry :
${secondary.topLevelEntries()}">
+ <td>[[${topLevelEntry.name}]]</td>
+ <td>[[${topLevelEntry.subEntries}]]</td>
</tr>
- <tr class="result" th:each="menuModel : ${headerUiModel.tertiary}">
- <td>[[${menuModel.menuBarSelect}]]</td>
- <td>[[${menuModel.menuContributingServiceIds}]]</td>
+ <tr class="result" th:each="topLevelEntry :
${tertiary.topLevelEntries()}">
+ <td>[[${topLevelEntry.name}]]</td>
+ <td>[[${topLevelEntry.subEntries}]]</td>
</tr>
<tr class="result">
diff --git
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
index 0e95b8e915..3cc271493a 100644
---
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
+++
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
@@ -34,7 +34,6 @@ import
org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.incubator.viewer.vaadin.model.util.Vaa;
import
org.apache.causeway.viewer.commons.applib.services.branding.BrandingUiModel;
import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiService;
import lombok.val;
@@ -73,11 +72,9 @@ final class MainView_createHeader {
val leftMenuBuilder = MenuBuilderVaa.of(commonContext,
menuActionEventHandler, leftMenuBar);
val rightMenuBuilder = MenuBuilderVaa.of(commonContext,
menuActionEventHandler, rightMenuBar);
- val menuUiModelProvider =
commonContext.lookupServiceElseFail(MenuUiService.class);
-
- headerUiModel.getPrimary().buildMenuItems(menuUiModelProvider,
leftMenuBuilder);
- headerUiModel.getSecondary().buildMenuItems(menuUiModelProvider,
rightMenuBuilder);
- headerUiModel.getTertiary().buildMenuItems(menuUiModelProvider,
rightMenuBuilder);
+ headerUiModel.getNavbar().primary().visitMenuItems(leftMenuBuilder);
+ headerUiModel.getNavbar().secondary().visitMenuItems(rightMenuBuilder);
+ headerUiModel.getNavbar().tertiary().visitMenuItems(rightMenuBuilder);
return menuBarContainer;
diff --git
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
index 1bc5352401..ac4910355b 100644
---
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
+++
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
@@ -29,8 +29,9 @@ import
org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import
org.apache.causeway.incubator.viewer.vaadin.model.action.ActionUiModelFactoryVaa;
import org.apache.causeway.incubator.viewer.vaadin.model.decorator.Decorators;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuAction;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdown;
import lombok.RequiredArgsConstructor;
import lombok.val;
@@ -47,20 +48,20 @@ class MenuBuilderVaa implements MenuVisitor {
private ActionUiModelFactoryVaa actionUiModelFactory = new
ActionUiModelFactoryVaa();
@Override
- public void addTopLevel(MenuItemDto menuDto) {
+ public void onTopLevel(final MenuDropdown menuDto) {
- if(menuDto.isTertiaryRoot()) {
- currentTopLevelMenu = menuBar.addItem(Decorators.getUser()
- .decorateWithAvatar(new Label(), commonContext));
- } else {
+// if(menuDto.isTertiaryRoot()) {
+// currentTopLevelMenu = menuBar.addItem(Decorators.getUser()
+// .decorateWithAvatar(new Label(), commonContext));
+// } else {
currentTopLevelMenu = menuBar.addItem(Decorators.getMenu()
- .decorateTopLevel(new Label(menuDto.getName())));
- }
+ .decorateTopLevel(new Label(menuDto.name())));
+// }
}
@Override
- public void addSubMenu(MenuItemDto menu) {
- val managedAction = menu.getManagedAction();
+ public void onMenuAction(final MenuAction menuAction) {
+ val managedAction = menuAction.managedAction();
val actionUiModel =
actionUiModelFactory.newActionUiModel(managedAction);
currentTopLevelMenu.getSubMenu()
@@ -68,7 +69,7 @@ class MenuBuilderVaa implements MenuVisitor {
}
@Override
- public void addSectionSpacer() {
+ public void onSectionSpacer() {
val sectionSpacer = new Hr();
val menuItem = currentTopLevelMenu.getSubMenu().addItem(sectionSpacer);
menuItem.setEnabled(false);
@@ -77,7 +78,7 @@ class MenuBuilderVaa implements MenuVisitor {
}
@Override
- public void addSectionLabel(String named) {
+ public void onSectionLabel(final String named) {
val sectionLabel = new Label(named);
sectionLabel.addClassName("section-label");
val menuItem = currentTopLevelMenu.getSubMenu().addItem(sectionLabel);
diff --git a/viewers/commons/applib/src/main/java/module-info.java
b/viewers/commons/applib/src/main/java/module-info.java
index 55d4d4b33a..c0c5de8169 100644
--- a/viewers/commons/applib/src/main/java/module-info.java
+++ b/viewers/commons/applib/src/main/java/module-info.java
@@ -21,13 +21,16 @@ module org.apache.causeway.viewer.commons.applib {
exports org.apache.causeway.viewer.commons.applib.services.header;
exports org.apache.causeway.viewer.commons.applib.services.branding;
exports org.apache.causeway.viewer.commons.applib.services.menu;
+ exports org.apache.causeway.viewer.commons.applib.services.menu.model;
exports org.apache.causeway.viewer.commons.applib;
exports org.apache.causeway.viewer.commons.applib.mixins;
+ requires static lombok;
+
+ requires transitive org.apache.causeway.applib;
+ requires transitive org.apache.causeway.commons;
+
requires jakarta.inject;
- requires lombok;
- requires org.apache.causeway.applib;
- requires org.apache.causeway.commons;
requires org.apache.causeway.core.config;
requires org.apache.causeway.core.metamodel;
requires spring.context;
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiModel.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiModel.java
index 7269a03347..06b037d2a1 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiModel.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiModel.java
@@ -19,7 +19,7 @@
package org.apache.causeway.viewer.commons.applib.services.header;
import
org.apache.causeway.viewer.commons.applib.services.branding.BrandingUiModel;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiModel;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavbarUiModel;
import
org.apache.causeway.viewer.commons.applib.services.userprof.UserProfileUiModel;
import lombok.AllArgsConstructor;
@@ -31,8 +31,6 @@ public class HeaderUiModel {
private final BrandingUiModel branding;
private final UserProfileUiModel userProfile;
- private final MenuUiModel primary;
- private final MenuUiModel secondary;
- private final MenuUiModel tertiary;
+ private final NavbarUiModel navbar;
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiModel.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiModel.java
deleted file mode 100644
index 18cf3ae5bb..0000000000
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiModel.java
+++ /dev/null
@@ -1,58 +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.causeway.viewer.commons.applib.services.menu;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.causeway.applib.annotation.DomainServiceLayout;
-import org.apache.causeway.core.metamodel.context.MetaModelContext;
-
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-
-@Getter
-@RequiredArgsConstructor(staticName = "of")
-//@Log4j2
-public class MenuUiModel implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @NonNull private final DomainServiceLayout.MenuBar menuBarSelect;
- @NonNull private final List<String> menuContributingServiceIds;
-
- public String getCssClass() {
- return menuBarSelect.name().toLowerCase(Locale.ENGLISH);
- }
-
- public void buildMenuItems(
- final MetaModelContext mmc,
- final MenuVisitor menuBuilder) {
-
buildMenuItems(mmc.getServiceRegistry().lookupServiceElseFail(MenuUiService.class),
menuBuilder);
- }
-
- public void buildMenuItems(
- final MenuUiService menuUiService,
- final MenuVisitor menuBuilder) {
- menuUiService.buildMenuItems(this, menuBuilder);
- }
-
-}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
index fb87b1f7d9..8579198cca 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
@@ -18,14 +18,13 @@
*/
package org.apache.causeway.viewer.commons.applib.services.menu;
-import org.apache.causeway.applib.annotation.DomainServiceLayout;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavbarUiModel;
/**
- * @since 2.0 {@index}}
+ * @since 2.0 {@index}
*/
public interface MenuUiService {
- MenuUiModel getMenu(DomainServiceLayout.MenuBar menuBarSelect);
- void buildMenuItems(MenuUiModel menuUiModel, MenuVisitor menuBuilder);
+ NavbarUiModel getMenu();
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
index 22b3d6bb05..a26d179f58 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
@@ -18,15 +18,21 @@
*/
package org.apache.causeway.viewer.commons.applib.services.menu;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuAction;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdown;
+
+/**
+ * Depth first visitor of the nav-bar model.
+ */
public interface MenuVisitor {
- void addTopLevel(MenuItemDto menuDto);
- void addSectionSpacer();
- void addSubMenu(MenuItemDto menuDto);
+ void onTopLevel(MenuDropdown menuDropdown);
+ void onMenuAction(MenuAction menuAction);
+ void onSectionSpacer();
/**
* @param named - not null and not empty
*/
- void addSectionLabel(String named);
+ void onSectionLabel(String named);
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java
new file mode 100644
index 0000000000..e691d68ecf
--- /dev/null
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java
@@ -0,0 +1,52 @@
+/*
+ * 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.commons.applib.services.menu.model;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.causeway.applib.Identifier;
+import org.apache.causeway.applib.services.bookmark.Bookmark;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
+
+import lombok.NonNull;
+
+public record MenuAction (
+ @NonNull Bookmark serviceBookmark,
+ @NonNull Identifier actionId,
+ @NonNull String name,
+ @Nullable String cssClassFa
+ ) implements MenuEntry {
+
+
+ public static MenuAction of(final @NonNull ManagedAction managedAction) {
+ // TODO missing cssClass
+ return new MenuAction(
+ managedAction.getOwner().getBookmark().orElseThrow(),
+ managedAction.getIdentifier(),
+ managedAction.getFriendlyName(),
+ null);
+ }
+
+ @Deprecated
+ public ManagedAction managedAction(){
+ throw _Exceptions.notImplemented();
+ }
+
+}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdown.java
similarity index 72%
copy from
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
copy to
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdown.java
index 22b3d6bb05..252a103c23 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdown.java
@@ -16,17 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.commons.applib.services.menu;
+package org.apache.causeway.viewer.commons.applib.services.menu.model;
-public interface MenuVisitor {
+import org.apache.causeway.commons.collections.Can;
- void addTopLevel(MenuItemDto menuDto);
- void addSectionSpacer();
- void addSubMenu(MenuItemDto menuDto);
+import lombok.NonNull;
- /**
- * @param named - not null and not empty
- */
- void addSectionLabel(String named);
+public record MenuDropdown (
+ @NonNull String name,
+ @NonNull Can<MenuEntry> subEntries) implements MenuEntry {
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdownBuilder.java
similarity index 51%
copy from
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
copy to
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdownBuilder.java
index fb87b1f7d9..cec5e4847f 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuDropdownBuilder.java
@@ -16,16 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.commons.applib.services.menu;
+package org.apache.causeway.viewer.commons.applib.services.menu.model;
-import org.apache.causeway.applib.annotation.DomainServiceLayout;
+import java.util.List;
-/**
- * @since 2.0 {@index}}
- */
-public interface MenuUiService {
+import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
+
+import lombok.NonNull;
+
+public record MenuDropdownBuilder (
+ @NonNull String name,
+ @NonNull List<MenuEntry> subEntries) {
+
+ public void addSectionSpacer() {
+ subEntries().add(MenuSpacer.empty());
+ }
+
+ public void addSectionSpacer(final @NonNull String label) {
+ subEntries().add(new MenuSpacer(label));
+ }
- MenuUiModel getMenu(DomainServiceLayout.MenuBar menuBarSelect);
- void buildMenuItems(MenuUiModel menuUiModel, MenuVisitor menuBuilder);
+ public void addAction(final ManagedAction action) {
+ subEntries().add(MenuAction.of(action));
+ }
+ public MenuDropdown build() {
+ return new MenuDropdown(name, Can.ofCollection(subEntries));
+ }
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuEntry.java
similarity index 65%
copy from
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
copy to
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuEntry.java
index fb87b1f7d9..2d72d6f771 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuEntry.java
@@ -16,16 +16,21 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.commons.applib.services.menu;
+package org.apache.causeway.viewer.commons.applib.services.menu.model;
-import org.apache.causeway.applib.annotation.DomainServiceLayout;
+import java.io.Serializable;
+import java.util.Optional;
-/**
- * @since 2.0 {@index}}
- */
-public interface MenuUiService {
+import org.apache.causeway.commons.internal.base._Casts;
+
+public interface MenuEntry extends Serializable {
+
+ default Optional<MenuAction> asAction() {
+ return _Casts.castTo(MenuAction.class, this);
+ }
- MenuUiModel getMenu(DomainServiceLayout.MenuBar menuBarSelect);
- void buildMenuItems(MenuUiModel menuUiModel, MenuVisitor menuBuilder);
+ default Optional<MenuSpacer> asSpacer() {
+ return _Casts.castTo(MenuSpacer.class, this);
+ }
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuSpacer.java
similarity index 72%
copy from
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
copy to
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuSpacer.java
index 22b3d6bb05..e8ed5ccbbd 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuSpacer.java
@@ -16,17 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.commons.applib.services.menu;
+package org.apache.causeway.viewer.commons.applib.services.menu.model;
-public interface MenuVisitor {
+import lombok.NonNull;
- void addTopLevel(MenuItemDto menuDto);
- void addSectionSpacer();
- void addSubMenu(MenuItemDto menuDto);
+public record MenuSpacer(@NonNull String label) implements MenuEntry {
- /**
- * @param named - not null and not empty
- */
- void addSectionLabel(String named);
+ public static MenuSpacer empty() {
+ return new MenuSpacer("");
+ }
+
+ public boolean isEmpty() {
+ return label.length() == 0;
+ }
}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavBarSection.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavBarSection.java
new file mode 100644
index 0000000000..aa43a2c830
--- /dev/null
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavBarSection.java
@@ -0,0 +1,66 @@
+/*
+ * 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.commons.applib.services.menu.model;
+
+import java.util.Locale;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.causeway.applib.annotation.DomainServiceLayout;
+import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
+
+import lombok.val;
+
+public record NavBarSection(
+ DomainServiceLayout.MenuBar menuBarSelect,
+ Can<MenuDropdown> topLevelEntries) {
+
+ public String cssClass() {
+ return menuBarSelect.name().toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Depth-first visit of the model.
+ * @param menuVisitor
+ */
+ public void visitMenuItems(final @Nullable MenuVisitor menuVisitor) {
+ if(menuVisitor==null) return;
+
+ topLevelEntries.forEach(topLevel->{
+ menuVisitor.onTopLevel(topLevel);
+ topLevel.subEntries().forEach(subEntry->{
+ val asAction = subEntry.asAction();
+ asAction.ifPresentOrElse(menuVisitor::onMenuAction, ()->{
+ val asSpacer = subEntry.asSpacer();
+ asSpacer.ifPresent(spacer->{
+ if(spacer.isEmpty()) {
+ menuVisitor.onSectionSpacer();
+ } else {
+ menuVisitor.onSectionLabel(spacer.label());
+ }
+ });
+ });
+
+ });
+ });
+
+ }
+
+}
diff --git
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavbarUiModel.java
similarity index 72%
copy from
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
copy to
viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavbarUiModel.java
index 22b3d6bb05..9c45633373 100644
---
a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuVisitor.java
+++
b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/NavbarUiModel.java
@@ -16,17 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.commons.applib.services.menu;
+package org.apache.causeway.viewer.commons.applib.services.menu.model;
-public interface MenuVisitor {
+import lombok.NonNull;
- void addTopLevel(MenuItemDto menuDto);
- void addSectionSpacer();
- void addSubMenu(MenuItemDto menuDto);
-
- /**
- * @param named - not null and not empty
- */
- void addSectionLabel(String named);
+public record NavbarUiModel(
+ @NonNull NavBarSection primary,
+ @NonNull NavBarSection secondary,
+ @NonNull NavBarSection tertiary) {
}
diff --git a/viewers/commons/services/src/main/java/module-info.java
b/viewers/commons/services/src/main/java/module-info.java
index 51f4929a98..9d81d11495 100644
--- a/viewers/commons/services/src/main/java/module-info.java
+++ b/viewers/commons/services/src/main/java/module-info.java
@@ -23,14 +23,18 @@ module org.apache.causeway.viewer.commons.services {
exports org.apache.causeway.viewer.commons.services.menu;
exports org.apache.causeway.viewer.commons.services;
+ requires static lombok;
+
requires jakarta.annotation;
requires jakarta.inject;
- requires lombok;
- requires org.apache.causeway.applib;
- requires org.apache.causeway.commons;
+
+ requires transitive org.apache.causeway.applib;
+ requires transitive org.apache.causeway.commons;
+ requires transitive org.apache.causeway.viewer.commons.applib;
+
requires org.apache.causeway.core.config;
requires org.apache.causeway.core.metamodel;
- requires org.apache.causeway.viewer.commons.applib;
+
requires org.apache.logging.log4j;
requires spring.beans;
requires spring.context;
diff --git
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java
index 6a86374843..5cd1b72255 100644
---
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java
+++
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java
@@ -25,7 +25,6 @@ import jakarta.inject.Named;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
-import org.apache.causeway.applib.annotation.DomainServiceLayout.MenuBar;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import
org.apache.causeway.viewer.commons.applib.services.branding.BrandingUiService;
import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel;
@@ -53,9 +52,7 @@ implements HeaderUiService {
return HeaderUiModel.of(
brandingUiService.getHeaderBranding(),
userProfileUiService.userProfile(),
- menuUiService.getMenu(MenuBar.PRIMARY),
- menuUiService.getMenu(MenuBar.SECONDARY),
- menuUiService.getMenu(MenuBar.TERTIARY));
+ menuUiService.getMenu());
}
}
diff --git
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
index 3309edebfd..1e14541239 100644
---
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
+++
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
@@ -18,9 +18,7 @@
*/
package org.apache.causeway.viewer.commons.services.menu;
-import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
+import java.util.ArrayList;
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
@@ -29,17 +27,17 @@ import jakarta.inject.Named;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
-import org.apache.causeway.applib.annotation.DomainServiceLayout;
+import org.apache.causeway.applib.annotation.DomainServiceLayout.MenuBar;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBar;
import org.apache.causeway.applib.services.menu.MenuBarsService;
+import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
-import org.apache.causeway.core.metamodel.object.ManagedObject;
-import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.util.Facets;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiModel;
+import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiService;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdownBuilder;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavBarSection;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavbarUiModel;
import
org.apache.causeway.viewer.commons.services.CausewayModuleViewerCommonsServices;
import lombok.RequiredArgsConstructor;
@@ -57,41 +55,51 @@ implements MenuUiService {
private final MenuBarsService menuBarsService;
@Override
- public MenuUiModel getMenu(final DomainServiceLayout.MenuBar
menuBarSelect) {
- return MenuUiModel.of(menuBarSelect, select(menuBarSelect));
+ public NavbarUiModel getMenu() {
+ return new NavbarUiModel(
+ buildNavBarSection(MenuBar.PRIMARY),
+ buildNavBarSection(MenuBar.SECONDARY),
+ buildNavBarSection(MenuBar.TERTIARY));
}
- @Override
- public void buildMenuItems(
- final MenuUiModel menuUiModel,
- final MenuVisitor menuBuilder) {
+ // -- HELPER
- val menuBars = menuBarsService.menuBars();
- val menuBar = (BSMenuBar)
menuBars.menuBarFor(menuUiModel.getMenuBarSelect());
+ private NavBarSection buildNavBarSection(final MenuBar menuBarSelect) {
- _MenuItemBuilder.buildMenuItems(
- metaModelContext,
- menuBar,
- menuBuilder);
+ val menuBar = (BSMenuBar) menuBarsService.menuBars()
+ .menuBarFor(menuBarSelect);
- }
+ val topLevelEntries = new ArrayList<MenuDropdownBuilder>();
- // -- HELPER
+ _MenuItemBuilder.buildMenuItems(metaModelContext, menuBar, new
_MenuItemBuilder.Visitor() {
- private List<String> select(final DomainServiceLayout.MenuBar
menuBarSelect) {
- return metaModelContext.streamServiceAdapters()
- .filter(with(menuBarSelect))
- .map(ManagedObject::getSpecification)
- .map(ObjectSpecification::getLogicalTypeName)
- .collect(Collectors.toList());
- }
+ private MenuDropdownBuilder currentMenu;
+
+ @Override
+ public void addTopLevel(final MenuItemDto menuDto) {
+ topLevelEntries.add(currentMenu = new
MenuDropdownBuilder(menuDto.getName(), new ArrayList<>()));
+ }
+
+ @Override
+ public void addSectionSpacer() {
+ currentMenu.addSectionSpacer();
+ }
+
+ @Override
+ public void addSectionLabel(final String named) {
+ currentMenu.addSectionSpacer(named);
+ }
+
+ @Override
+ public void addMenuAction(final MenuItemDto menuDto) {
+ val action = menuDto.getManagedAction();
+ currentMenu.addAction(action);
+ }
- private static Predicate<ManagedObject> with(final
DomainServiceLayout.MenuBar menuBarSelect) {
- return (final ManagedObject adapter) ->
+ });
- Facets.domainServiceLayoutMenuBar(adapter.getSpecification())
- .orElse(DomainServiceLayout.MenuBar.PRIMARY)
- .equals(menuBarSelect);
+ return new NavBarSection(menuBarSelect,
Can.ofCollection(topLevelEntries)
+ .map(MenuDropdownBuilder::build));
}
}
diff --git
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java
index 77fe38c045..2e0ec4c10d 100644
---
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java
+++
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java
@@ -29,7 +29,6 @@ import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
import
org.apache.causeway.viewer.commons.services.userprof.UserProfileUiServiceDefault;
import lombok.NonNull;
@@ -40,10 +39,23 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
final class _MenuItemBuilder {
- public static void buildMenuItems(
+ static interface Visitor {
+
+ void addTopLevel(MenuItemDto menuDto);
+ void addSectionSpacer();
+ void addMenuAction(MenuItemDto menuDto);
+
+ /**
+ * @param named - not null and not empty
+ */
+ void addSectionLabel(String named);
+
+ }
+
+ static void buildMenuItems(
final MetaModelContext mmc,
final BSMenuBar menuBar,
- final MenuVisitor menuBuilder) {
+ final Visitor menuBuilder) {
val itemsPerSectionCounter = new LongAdder();
@@ -98,7 +110,7 @@ final class _MenuItemBuilder {
private static class MenuProcessor {
private final MetaModelContext metaModelContext;
- private final MenuVisitor menuVisitor;
+ private final Visitor menuVisitor;
private BSMenu currentTopLevel;
private boolean pushedCurrentTopLevel = false;
@@ -143,7 +155,7 @@ final class _MenuItemBuilder {
actionLayoutData.getNamed(),
actionLayoutData.getCssClassFa());
- menuVisitor.addSubMenu(menuDto);
+ menuVisitor.addMenuAction(menuDto);
}
}
diff --git
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ServiceActionsModel.java
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ServiceActionsModel.java
index 30a48e220a..79d33b22ec 100644
---
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ServiceActionsModel.java
+++
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ServiceActionsModel.java
@@ -20,32 +20,32 @@ package org.apache.causeway.viewer.wicket.model.models;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiModel;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavBarSection;
/**
* Backing model for actions of application services menu bar (typically, as
* displayed along the top or side of the page).
*/
-public class ServiceActionsModel extends ModelAbstract<MenuUiModel> {
+public class ServiceActionsModel extends ModelAbstract<NavBarSection> {
private static final long serialVersionUID = 1L;
- private final MenuUiModel menuUiModel;
+ private final NavBarSection navBarSection;
/**
* @param commonContext
- * @param menuUiModel - may be null in special case of rendering the
tertiary menu on the error page.
+ * @param navBarSection - may be null in special case of rendering the
tertiary menu on the error page.
*/
public ServiceActionsModel(
final MetaModelContext commonContext,
- final MenuUiModel menuUiModel) {
+ final NavBarSection navBarSection) {
super(commonContext);
- this.menuUiModel = menuUiModel;
+ this.navBarSection = navBarSection;
}
@Override
- protected MenuUiModel load() {
- return menuUiModel;
+ protected NavBarSection load() {
+ return navBarSection;
}
}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelFactory.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelFactory.java
index fa9111179d..a0e22380f8 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelFactory.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/entityactions/LinkAndLabelFactory.java
@@ -21,9 +21,11 @@ package
org.apache.causeway.viewer.wicket.ui.components.actionmenu.entityactions
import java.util.function.Function;
import org.apache.causeway.applib.annotation.Where;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuAction;
import
org.apache.causeway.viewer.wicket.model.links.ActionLinkUiComponentFactoryWkt;
import org.apache.causeway.viewer.wicket.model.links.LinkAndLabel;
import org.apache.causeway.viewer.wicket.model.models.ActionModel;
@@ -43,12 +45,14 @@ import lombok.val;
public interface LinkAndLabelFactory
extends Function<ObjectAction, LinkAndLabel> {
- public static LinkAndLabelFactory forMenu(
- final UiObjectWkt serviceModel) {
- return action -> LinkAndLabel.of(
+ public static LinkAndLabel linkAndLabelForMenu(
+ @NonNull final MetaModelContext commonContext,
+ @NonNull final MenuAction menuAction) {
+ val serviceModel = UiObjectWkt.ofBookmark(commonContext,
menuAction.serviceBookmark());
+ return LinkAndLabel.of(
ActionModelImpl.forEntity(
serviceModel,
- action.getFeatureIdentifier(),
+ menuAction.actionId(),
Where.ANYWHERE,
null, null, null),
new MenuLinkFactory());
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
index 8b58620648..dc271361fd 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
@@ -26,12 +26,10 @@ import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
-import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiModel;
import org.apache.causeway.viewer.commons.applib.services.menu.MenuVisitor;
-import org.apache.causeway.viewer.wicket.model.links.LinkAndLabel;
-import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuAction;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdown;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavBarSection;
import
org.apache.causeway.viewer.wicket.ui.components.actionmenu.entityactions.LinkAndLabelFactory;
import org.apache.causeway.viewer.wicket.ui.util.Wkt;
import org.apache.causeway.viewer.wicket.ui.util.WktDecorators;
@@ -104,50 +102,37 @@ public final class ServiceActionUtil {
private CssMenuItem currentTopLevelMenu = null;
@Override
- public void addTopLevel(final MenuItemDto menuDto) {
- currentTopLevelMenu = CssMenuItem.newMenuItem(menuDto.getName());
+ public void onTopLevel(final MenuDropdown menuDto) {
+ currentTopLevelMenu = CssMenuItem.newMenuItem(menuDto.name());
onNewMenuItem.accept(currentTopLevelMenu);
}
@Override
- public void addSectionSpacer() {
+ public void onSectionSpacer() {
val menuSection = CssMenuItem.newSpacer();
currentTopLevelMenu.addSubMenuItem(menuSection);
}
@Override
- public void addSubMenu(final MenuItemDto menuDto) {
- val managedAction = menuDto.getManagedAction();
-
- val menuItem = CssMenuItem.newMenuItem(menuDto.getName());
+ public void onMenuAction(final MenuAction menuAction) {
+ val menuItem = CssMenuItem.newMenuItem(menuAction.name());
currentTopLevelMenu.addSubMenuItem(menuItem);
-
- menuItem.setLinkAndLabel(newActionLink(managedAction));
+
menuItem.setLinkAndLabel(LinkAndLabelFactory.linkAndLabelForMenu(commonContext,
menuAction));
}
@Override
- public void addSectionLabel(final String named) {
+ public void onSectionLabel(final String named) {
val menuSectionLabel = CssMenuItem.newSectionLabel(named);
currentTopLevelMenu.addSubMenuItem(menuSectionLabel);
}
-
- private LinkAndLabel newActionLink(
- final ManagedAction managedAction) {
-
- val serviceModel = UiObjectWkt.ofAdapter(commonContext,
managedAction.getOwner());
-
- return LinkAndLabelFactory.forMenu(serviceModel)
- .apply(managedAction.getAction());
- }
-
}
public static void buildMenu(
final MetaModelContext commonContext,
- final MenuUiModel menuUiModel,
+ final NavBarSection navBarSection,
final Consumer<CssMenuItem> onNewMenuItem) {
- menuUiModel.buildMenuItems(commonContext.getMetaModelContext(),
+ navBarSection.visitMenuItems(
MenuBuilderWkt.of(
commonContext,
onNewMenuItem));
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanelFactory.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanelFactory.java
index b971d865cd..4cb701ea9b 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanelFactory.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanelFactory.java
@@ -50,8 +50,8 @@ public class ServiceActionsPanelFactory extends
ComponentFactoryAbstract {
if(!(model instanceof ServiceActionsModel)) {
return ApplicationAdvice.DOES_NOT_APPLY;
}
- val menuUiModel = ((ServiceActionsModel) model).getObject();
- val menuBarSelect = menuUiModel.getMenuBarSelect();
+ val navBarSection = ((ServiceActionsModel) model).getObject();
+ val menuBarSelect = navBarSection.menuBarSelect();
return appliesIf(
menuBarSelect != DomainServiceLayout.MenuBar.TERTIARY
&& menuBarSelect != null);
@@ -59,11 +59,11 @@ public class ServiceActionsPanelFactory extends
ComponentFactoryAbstract {
@Override
public Component createComponent(final String id, final IModel<?> model) {
- val menuUiModel = ((ServiceActionsModel) model).getObject();
+ val navBarSection = ((ServiceActionsModel) model).getObject();
val menuItems = _Lists.<CssMenuItem>newArrayList();
ServiceActionUtil.buildMenu(
- super.getMetaModelContext(), menuUiModel, menuItems::add);
+ super.getMetaModelContext(), navBarSection, menuItems::add);
return new ServiceActionsPanel(id, menuItems);
}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryMenuPanelFactory.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryMenuPanelFactory.java
index cbdde29760..f30701c8dd 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryMenuPanelFactory.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionmenu/serviceactions/TertiaryMenuPanelFactory.java
@@ -50,7 +50,7 @@ public class TertiaryMenuPanelFactory extends
ComponentFactoryAbstract {
return ApplicationAdvice.DOES_NOT_APPLY;
}
val menuUiModel = ((ServiceActionsModel) model).getObject();
- val menuBarSelect = menuUiModel.getMenuBarSelect();
+ val menuBarSelect = menuUiModel.menuBarSelect();
return appliesIf(
menuBarSelect == DomainServiceLayout.MenuBar.TERTIARY
|| menuBarSelect == null);
@@ -58,11 +58,11 @@ public class TertiaryMenuPanelFactory extends
ComponentFactoryAbstract {
@Override
public Component createComponent(final String id, final IModel<?> model) {
- val menuUiModel = ((ServiceActionsModel) model).getObject();
+ val navBarSection = ((ServiceActionsModel) model).getObject();
val menuItems = _Lists.<CssMenuItem>newArrayList();
ServiceActionUtil.buildMenu(
- super.getMetaModelContext(), menuUiModel, menuItems::add);
+ super.getMetaModelContext(), navBarSection, menuItems::add);
return new TertiaryActionsPanel(id, menuItems);
}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/header/HeaderPanel.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/header/HeaderPanel.java
index 43fcc8046c..ae1de90d13 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/header/HeaderPanel.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/header/HeaderPanel.java
@@ -25,7 +25,7 @@ import
org.apache.wicket.request.mapper.parameter.PageParameters;
import
org.apache.causeway.viewer.commons.applib.services.branding.BrandingUiModel;
import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel;
-import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiModel;
+import
org.apache.causeway.viewer.commons.applib.services.menu.model.NavBarSection;
import
org.apache.causeway.viewer.commons.applib.services.userprof.UserProfileUiModel;
import org.apache.causeway.viewer.commons.model.components.UiComponentType;
import org.apache.causeway.viewer.wicket.model.models.ServiceActionsModel;
@@ -108,26 +108,27 @@ extends PanelAbstract<String, Model<String>> {
}
protected void addServiceActionMenuBars(final HeaderUiModel headerUiModel)
{
+ val navbar = headerUiModel.getNavbar();
if (getPage() instanceof ErrorPage) {
WktComponents.permanentlyHide(this, ID_PRIMARY_MENU_BAR);
WktComponents.permanentlyHide(this, ID_SECONDARY_MENU_BAR);
- addMenuBar(ID_TERTIARY_MENU_BAR, headerUiModel.getTertiary());
+ addMenuBar(ID_TERTIARY_MENU_BAR, navbar.tertiary());
} else {
- addMenuBar(ID_PRIMARY_MENU_BAR, headerUiModel.getPrimary());
- addMenuBar(ID_SECONDARY_MENU_BAR, headerUiModel.getSecondary());
- addMenuBar(ID_TERTIARY_MENU_BAR, headerUiModel.getTertiary());
+ addMenuBar(ID_PRIMARY_MENU_BAR, navbar.primary());
+ addMenuBar(ID_SECONDARY_MENU_BAR, navbar.secondary());
+ addMenuBar(ID_TERTIARY_MENU_BAR, navbar.tertiary());
}
}
private void addMenuBar(
final String id,
- final MenuUiModel menuUiModel) {
+ final NavBarSection menuUiModel) {
final MarkupContainer container = this;
val menuModel = new ServiceActionsModel(super.getMetaModelContext(),
menuUiModel);
val menuBarComponent = getComponentFactoryRegistry()
.createComponent(id, UiComponentType.SERVICE_ACTIONS,
menuModel);
- Wkt.cssAppend(menuBarComponent, menuUiModel.getCssClass());
+ Wkt.cssAppend(menuBarComponent, menuUiModel.cssClass());
container.add(menuBarComponent);
}