You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/05/28 07:48:06 UTC
[isis] branch master updated: ISIS-2340: adds menu decorator,
also polishing action dialog (Vaadin)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 5f4aec6 ISIS-2340: adds menu decorator, also polishing action dialog (Vaadin)
5f4aec6 is described below
commit 5f4aec6396bcc77d182af86b46dc6aafd8f5bc5c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu May 28 09:47:24 2020 +0200
ISIS-2340: adds menu decorator, also polishing action dialog (Vaadin)
---
.../viewer/vaadin/model/decorator/Decorators.java | 38 +++-
.../vaadin/ui/components/action/ActionButton.java | 5 +
.../vaadin/ui/components/action/ActionDialog.java | 191 ++++++++++++---------
.../ui/pages/main/MainView_createHeader.java | 13 +-
4 files changed, 159 insertions(+), 88 deletions(-)
diff --git a/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/decorator/Decorators.java b/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/decorator/Decorators.java
index 5ba4cb0..4596de7 100644
--- a/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/decorator/Decorators.java
+++ b/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/decorator/Decorators.java
@@ -25,14 +25,17 @@ import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import org.apache.isis.applib.layout.component.CssClassFaPosition;
+import org.apache.isis.core.webapp.context.IsisWebAppCommonContext;
import org.apache.isis.viewer.common.model.decorator.fa.FontAwesomeDecorator;
import org.apache.isis.viewer.common.model.decorator.fa.FontAwesomeUiModel;
import org.apache.isis.viewer.common.model.decorator.tooltip.TooltipDecorator;
import org.apache.isis.viewer.common.model.decorator.tooltip.TooltipUiModel;
import org.apache.isis.viewer.common.model.userprofile.UserProfileUiModel;
+import org.apache.isis.viewer.common.model.userprofile.UserProfileUiModelProvider;
import lombok.Getter;
import lombok.val;
@@ -48,6 +51,7 @@ public class Decorators {
@Getter(lazy = true) private final static Tooltip tooltip = new Tooltip();
@Getter(lazy = true) private final static Icon icon = new Icon();
+ @Getter(lazy = true) private final static Menu menu = new Menu();
@Getter(lazy = true) private final static User user = new User();
// -- DECORATOR CLASSES
@@ -78,7 +82,7 @@ public class Decorators {
return CssClassFaPosition.isLeftOrUnspecified(fontAwesome.getPosition())
? new HorizontalLayout(faIcon, uiComponent)
- : new HorizontalLayout(uiComponent, faIcon);
+ : new HorizontalLayout(uiComponent, faIcon);
})
.orElseGet(()->{
@@ -94,10 +98,38 @@ public class Decorators {
}
}
+
+ public final static class Menu {
+
+ public Component decorateTopLevel(
+ final Label label) {
+ val icon = getTopLevelMenuIcon();
+ val layout = new HorizontalLayout(label, icon);
+ layout.setVerticalComponentAlignment(Alignment.END, icon);
+ return (Component) layout;
+ }
+
+ private Component getTopLevelMenuIcon() {
+ val menuIcon = new com.vaadin.flow.component.icon.Icon(VaadinIcon.CARET_DOWN);
+ menuIcon.setSize("1em");
+ menuIcon.getElement().getStyle().set("margin-left", "2px");
+ return menuIcon;
+ }
+
+ }
public final static class User {
- public Component decorate(
+ public Component decorateWithAvatar(
+ final Label label,
+ final IsisWebAppCommonContext commonContext) {
+
+ val profileIfAny = commonContext.lookupServiceElseFail(UserProfileUiModelProvider.class)
+ .getUserProfile();
+ return decorateWithAvatar(label, Optional.ofNullable(profileIfAny));
+ }
+
+ public Component decorateWithAvatar(
final Label label,
final Optional<UserProfileUiModel> userProfileUiModel) {
@@ -137,4 +169,6 @@ public class Decorators {
}
+
+
}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionButton.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionButton.java
index c980807..1dce1fa 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionButton.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionButton.java
@@ -27,6 +27,11 @@ import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryV
import lombok.NonNull;
import lombok.val;
+/**
+ * Button that when clicked opens an {@link ActionDialog}.
+ *
+ * @since May 28, 2020
+ */
public class ActionButton extends Button {
private static final long serialVersionUID = 1L;
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionDialog.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionDialog.java
index b865959..6fccec8 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionDialog.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/action/ActionDialog.java
@@ -20,6 +20,7 @@ package org.apache.isis.incubator.viewer.vaadin.ui.components.action;
import java.util.stream.Stream;
+import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dependency.CssImport;
@@ -31,10 +32,12 @@ import com.vaadin.flow.component.html.Header;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.theme.lumo.Lumo;
+import org.apache.isis.core.commons.collections.Can;
import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryVaa;
import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
import lombok.val;
@CssImport(value = "./css/dialog-overlay.css", themeFor = "vaadin-dialog-overlay")
@@ -42,19 +45,7 @@ import lombok.val;
public class ActionDialog extends Dialog {
private static final long serialVersionUID = 1L;
- private static final String DOCK = "dock";
- private static final String FULLSCREEN = "fullscreen";
-
- private boolean isDocked = false;
- private boolean isFullScreen = false;
-
- private Header header;
- private Button min;
- private Button max;
-
- private Div content;
- private Footer footer;
-
+
public static ActionDialog forManagedAction(
@NonNull final UiComponentFactoryVaa uiComponentFactory,
@NonNull final ManagedAction managedAction) {
@@ -71,100 +62,146 @@ public class ActionDialog extends Dialog {
setModal(false);
setResizable(true);
- // Dialog theming
+ // Dialog Theme
+
getElement().getThemeList().add("action-dialog");
setWidth("600px");
setHeight("auto");
+ // Content
+
+ val actionForm = ActionForm.forManagedAction(uiComponentFactory, managedAction);
+ val content = new Div(actionForm);
+ content.addClassName("dialog-content");
+
+ // Footer
+
+ val footer = footer(managedAction);
+
// Header
+
+ val hidableComponents = Can.of(content, footer);
+ val header = header(managedAction, hidableComponents);
+
+ // Add to Layout
+
+ add(header, content, footer);
+ }
+
+ // -- HELPER
+
+ private Component header(ManagedAction managedAction, Can<Component> hidableComponents) {
+
+ val resizeHandler = DialogResizeHandler.of(this, hidableComponents);
+
val title = new H2(managedAction.getName());
title.addClassName("dialog-title");
- min = new Button(VaadinIcon.ANGLE_DOWN.create());
- min.addClickListener(event -> minimise());
-
- max = new Button(VaadinIcon.EXPAND_SQUARE.create());
- max.addClickListener(event -> maximise());
-
+ val minButton = new Button(VaadinIcon.ANGLE_DOWN.create());
+ val maxButton = new Button(VaadinIcon.EXPAND_SQUARE.create());
val closeButton = new Button(VaadinIcon.CLOSE_SMALL.create());
- header = new Header(title, min, max, closeButton);
+ val header = new Header(title, minButton, maxButton, closeButton);
header.getElement().getThemeList().add(Lumo.DARK);
- add(header);
-
- // Content
- val actionForm = ActionForm.forManagedAction(uiComponentFactory, managedAction);
- content = new Div(actionForm);
- content.addClassName("dialog-content");
- add(content);
-
- // Footer
+ // Button Themes
+ Stream.of(minButton, maxButton, closeButton)
+ .forEach(button->
+ button.addThemeVariants(ButtonVariant.LUMO_CONTRAST, ButtonVariant.LUMO_TERTIARY));
+
+ // Button Events
+ resizeHandler.bindMinimise(minButton);
+ resizeHandler.bindMaximise(maxButton);
+ closeButton.addClickListener(event -> close());
+
+ return header;
+ }
+
+ private Component footer(ManagedAction managedAction) {
+
val okButton = new Button("Ok");
val cancelButton = new Button("Cancel");
- footer = new Footer(okButton, cancelButton);
- add(footer);
-
- // Button Themes
+ val footer = new Footer(okButton, cancelButton);
+ // Button Themes
okButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
cancelButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
- Stream.of(min, max, closeButton)
- .forEach(button->
- button.addThemeVariants(ButtonVariant.LUMO_CONTRAST, ButtonVariant.LUMO_TERTIARY));
-
// Button Events
-
- okButton.addClickListener(event -> close()); //TODO should invoke the action
+ okButton.addClickListener(event -> close()); //TODO should invoke the action and route to the result page
cancelButton.addClickListener(event -> close());
- closeButton.addClickListener(event -> close());
+ return footer;
}
- // -- HELPER
+ // -- RESIZING
- private void minimise() {
- if (isDocked) {
- initialSize();
- } else {
- if (isFullScreen) {
- initialSize();
- }
- min.setIcon(VaadinIcon.ANGLE_UP.create());
- getElement().getThemeList().add(DOCK);
- setWidth("320px");
- }
- isDocked = !isDocked;
- isFullScreen = false;
- content.setVisible(!isDocked);
- footer.setVisible(!isDocked);
- }
+ @RequiredArgsConstructor(staticName = "of")
+ private static class DialogResizeHandler {
+
+ private static final String DOCK = "dock";
+ private static final String FULLSCREEN = "fullscreen";
+
+ private boolean isDocked = false;
+ private boolean isFullScreen = false;
+
+ private final Dialog dialog;
+ private final Can<Component> hidableComponents;
+
+ private Button minButton;
+ private Button maxButton;
- private void initialSize() {
- min.setIcon(VaadinIcon.ANGLE_DOWN.create());
- getElement().getThemeList().remove(DOCK);
- max.setIcon(VaadinIcon.EXPAND_SQUARE.create());
- getElement().getThemeList().remove(FULLSCREEN);
- setHeight("auto");
- setWidth("600px");
- }
+ public void bindMinimise(Button minButton) {
+ this.minButton = minButton;
+ minButton.addClickListener(event -> minimise());
+ }
+
+ public void bindMaximise(Button maxButton) {
+ this.maxButton = maxButton;
+ maxButton.addClickListener(event -> maximise());
+ }
+
+ private void initialSize() {
+ minButton.setIcon(VaadinIcon.ANGLE_DOWN.create());
+ dialog.getElement().getThemeList().remove(DOCK);
+ maxButton.setIcon(VaadinIcon.EXPAND_SQUARE.create());
+ dialog.getElement().getThemeList().remove(FULLSCREEN);
+ dialog.setWidth("600px");
+ dialog.setHeight("auto");
+ }
- private void maximise() {
- if (isFullScreen) {
- initialSize();
- } else {
+ private void minimise() {
if (isDocked) {
initialSize();
+ } else {
+ if (isFullScreen) {
+ initialSize();
+ }
+ minButton.setIcon(VaadinIcon.ANGLE_UP.create());
+ dialog.getElement().getThemeList().add(DOCK);
+ dialog.setWidth("320px");
}
- max.setIcon(VaadinIcon.COMPRESS_SQUARE.create());
- getElement().getThemeList().add(FULLSCREEN);
- setSizeFull();
- content.setVisible(true);
- footer.setVisible(true);
+ isDocked = !isDocked;
+ isFullScreen = false;
+ hidableComponents.forEach(comp->comp.setVisible(!isDocked));
}
- isFullScreen = !isFullScreen;
- isDocked = false;
+
+ private void maximise() {
+ if (isFullScreen) {
+ initialSize();
+ } else {
+ if (isDocked) {
+ initialSize();
+ }
+ maxButton.setIcon(VaadinIcon.COMPRESS_SQUARE.create());
+ dialog.getElement().getThemeList().add(FULLSCREEN);
+ dialog.setSizeFull();
+ hidableComponents.forEach(comp->comp.setVisible(true));
+ }
+ isFullScreen = !isFullScreen;
+ isDocked = false;
+ }
+
}
}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
index 23c6606..6964d1c 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.incubator.viewer.vaadin.ui.pages.main;
-import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -40,7 +39,6 @@ import org.apache.isis.incubator.viewer.vaadin.model.menu.MenuItemVaa;
import org.apache.isis.viewer.common.model.branding.BrandingUiModel;
import org.apache.isis.viewer.common.model.header.HeaderUiModel;
import org.apache.isis.viewer.common.model.menu.MenuUiModel;
-import org.apache.isis.viewer.common.model.userprofile.UserProfileUiModelProvider;
import lombok.val;
@@ -76,13 +74,10 @@ final class MainView_createHeader {
// menu section handler, that creates and adds sub-menus to their parent top level menu
final BiConsumer<MenuBar, MenuItemVaa> menuSectionBuilder = (menuBar, menuSectionUiModel) -> {
val menuItem = menuSectionUiModel.isTertiaryRoot()
- ? menuBar.addItem(Decorators.getUser().decorate(
- new Label(),
- Optional.ofNullable(
- commonContext.lookupServiceElseFail(UserProfileUiModelProvider.class)
- .getUserProfile())
- ))
- : menuBar.addItem(menuSectionUiModel.getName());
+ ? menuBar.addItem(Decorators.getUser()
+ .decorateWithAvatar(new Label(), commonContext))
+ : menuBar.addItem(Decorators.getMenu()
+ .decorateTopLevel(new Label(menuSectionUiModel.getName())));
val subMenu = menuItem.getSubMenu();
menuSectionUiModel.getSubMenuItems().forEach(menuItemModel -> {
val menuActionModel = (ActionVaa)menuItemModel.getMenuActionUiModel();