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 2021/10/23 17:42:23 UTC

[isis] branch 2877_compound.value.types created (now 3990503)

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

ahuber pushed a change to branch 2877_compound.value.types
in repository https://gitbox.apache.org/repos/asf/isis.git.


      at 3990503  ISIS-2871: housekeeping around ActionLink

This branch includes the following new commits:

     new 3990503  ISIS-2871: housekeeping around ActionLink

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.


[isis] 01/01: ISIS-2871: housekeeping around ActionLink

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

ahuber pushed a commit to branch 2877_compound.value.types
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 39905039254b2140a720b352622d16e24e3581fc
Author: andi-huber <ah...@apache.org>
AuthorDate: Sat Oct 23 19:42:14 2021 +0200

    ISIS-2871: housekeeping around ActionLink
---
 .../ui/components/layout/bs3/BS3GridPanel.java     |  32 +++
 .../widgets/linkandlabel/ActionLink.java           | 269 +++++++++------------
 2 files changed, 145 insertions(+), 156 deletions(-)

diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
index dd2126c..8f10e7f 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/BS3GridPanel.java
@@ -18,17 +18,27 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.layout.bs3;
 
+import java.util.Optional;
+
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.repeater.RepeatingView;
 
+import org.apache.isis.applib.layout.grid.Grid;
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3Grid;
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3Row;
+import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionMixedIn;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.ui.components.layout.bs3.row.Row;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Wkt;
 
+import lombok.val;
+
 public class BS3GridPanel
 extends PanelAbstract<ManagedObject, EntityModel> {
 
@@ -38,6 +48,28 @@ extends PanelAbstract<ManagedObject, EntityModel> {
 
     private final BS3Grid bs3Page;
 
+    public static Optional<BS3GridPanel> extraContent(final String id, final ActionModel actionModel) {
+        final ObjectAction action = actionModel.getAction();
+        if(action instanceof ObjectActionMixedIn) {
+            final ObjectActionMixedIn actionMixedIn = (ObjectActionMixedIn) action;
+            final ObjectSpecification mixinSpec = actionMixedIn.getMixinType();
+            if(mixinSpec.isViewModel()) {
+                val commonContext = actionModel.getCommonContext();
+                final ManagedObject targetAdapterForMixin = action.realTargetAdapter(actionModel.getActionOwner());
+                final GridFacet gridFacet = mixinSpec.getFacet(GridFacet.class);
+                final Grid gridForMixin = gridFacet.getGrid(targetAdapterForMixin);
+                if(gridForMixin instanceof BS3Grid) {
+                    final BS3Grid bs3Grid = (BS3Grid) gridForMixin;
+                    final EntityModel entityModelForMixin =
+                            EntityModel.ofAdapter(commonContext, targetAdapterForMixin);
+                    return Optional.of(new BS3GridPanel(id, entityModelForMixin, bs3Grid));
+                }
+            }
+        }
+        return Optional.empty();
+    }
+
+
     public BS3GridPanel(final String id, final EntityModel entityModel, final BS3Grid bs3Grid) {
         super(id, entityModel);
         this.bs3Page = bs3Grid;
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
index 7744ef5..036eb74 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
@@ -21,8 +21,6 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel;
 import java.util.Optional;
 
 import org.apache.wicket.Application;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.extensions.ajax.markup.html.AjaxIndicatorAppender;
@@ -30,27 +28,19 @@ import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.request.cycle.RequestCycle;
 
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.layout.grid.Grid;
-import org.apache.isis.applib.layout.grid.bootstrap3.BS3Grid;
 import org.apache.isis.commons.internal.base._Either;
 import org.apache.isis.commons.internal.debug._Probe;
 import org.apache.isis.commons.internal.debug._Probe.EntryPoint;
-import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionMixedIn;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.core.security.authentication.logout.LogoutMenu.LoginRedirect;
 import org.apache.isis.viewer.common.model.components.ComponentType;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettingsAccessor;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
-import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptWithExtraContent;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.models.FormExecutor;
 import org.apache.isis.viewer.wicket.model.models.PageType;
 import org.apache.isis.viewer.wicket.model.util.CommonContextUtils;
@@ -65,11 +55,33 @@ import org.apache.isis.viewer.wicket.ui.panels.FormExecutorDefault;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
 import org.apache.isis.viewer.wicket.ui.util.Wkt;
 
-import lombok.NonNull;
-import lombok.val;
+import static org.apache.isis.commons.internal.base._Casts.castTo;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
+import lombok.NonNull;
+import lombok.val;
 
+/**
+ *
+ * @implNote <pre>
+ * according to
+ * http://wicketinaction.com/2011/11/implement-wicket-component-visibility-changes-properly/
+ * and
+ * http://apache-wicket.1842946.n4.nabble.com/vote-release-Wicket-1-4-14-td3056628.html#a3063795
+ * should be using onConfigure rather than overloading.
+ * eg:
+ *  setVisible(determineIfVisible());
+ *  setEnabled(determineIfEnabled());
+ *
+ * and no longer override isVisible() and isEnabled().
+ *
+ * however, in the case of a button already rendered as visible/enabled that (due to changes
+ * elsewhere in the state of the server-side system) should then become invisible/disabled, it seems
+ * that onConfigure isn't called and so the action continues to display the prompt.
+ * A check is only made when hit OK of the prompt.  This is too late to display a message, so (until
+ * figure out a better way) gonna continue to override isVisible() and isEnabled()
+ *  </pre>
+ */
 public final class ActionLink
 extends IndicatingAjaxLink<ManagedObject> {
 
@@ -103,15 +115,6 @@ extends IndicatingAjaxLink<ManagedObject> {
         }
     }
 
-    @Override
-    public void onClick(final AjaxRequestTarget target) {
-
-        _Probe.entryPoint(EntryPoint.USER_INTERACTION, "Wicket Ajax Request, "
-                + "originating from User clicking an Action Link.");
-
-        doOnClick(this, target);
-    }
-
     ActionModel getActionModel() {
         return (ActionModel) getModel();
     }
@@ -137,38 +140,16 @@ extends IndicatingAjaxLink<ManagedObject> {
     }
 
     @Override
-    protected void onConfigure() {
-        super.onConfigure();
-        // according to
-        //   http://wicketinaction.com/2011/11/implement-wicket-component-visibility-changes-properly/
-        // and
-        //   http://apache-wicket.1842946.n4.nabble.com/vote-release-Wicket-1-4-14-td3056628.html#a3063795
-        // should be using onConfigure rather than overloading.
-        //
-        // eg:
-        //        setVisible(determineIfVisible());
-        //        setEnabled(determineIfEnabled());
-        //
-        // and no longer override isVisible() and isEnabled().
-        //
-        // however, in the case of a button already rendered as visible/enabled that (due to changes
-        // elsewhere in the state of the server-side system) should then become invisible/disabled, it seems
-        // that onConfigure isn't called and so the action continues to display the prompt.
-        // A check is only made when hit OK of the prompt.  This is too late to display a message, so (until
-        // figure out a better way) gonna continue to override isVisible() and isEnabled()
-    }
-
-    @Override
     public boolean isVisible() {
         return getActionModel().getVisibilityConsent().isAllowed();
     }
 
     @Override
-    @Programmatic
     public boolean isEnabled() {
         return getActionModel().getUsabilityConsent().isAllowed();
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     protected void onComponentTag(final ComponentTag tag) {
         super.onComponentTag(tag);
@@ -186,140 +167,116 @@ extends IndicatingAjaxLink<ManagedObject> {
         return ((WicketViewerSettingsAccessor) Application.get()).getSettings();
     }
 
-    /**
-     * @return the prompt, if not inline prompt
-     */
-    private ActionPrompt doOnClick(
-            final ActionLink actionLink,
-            final AjaxRequestTarget target) {
-
-        val actionModel = actionLink.getActionModel();
-        val inlinePromptContext = actionModel.getInlinePromptContext();
-        val promptStyle = actionModel.getPromptStyle();
-
-        if(inlinePromptContext == null || promptStyle.isDialog()) {
-            val promptProvider = ActionPromptProvider.getFrom(actionLink.getPage());
-            val actionOwnerSpec = actionModel.getActionOwner().getSpecification();
-            val actionPrompt = promptProvider.getActionPrompt(promptStyle, actionOwnerSpec.getBeanSort());
-
-            //
-            // previously this if/else was in the ActionParametersPanel
-            //
-            // now though we only build that panel if we know that there *are* parameters.
-            //
-            if(actionModel.hasParameters()) {
-
-                val actionParametersPanel = (ActionParametersPanel)
-                        getComponentFactoryRegistry()
-                        .createComponent(
-                                ComponentType.ACTION_PROMPT, actionPrompt.getContentId(), actionModel);
-
-                actionParametersPanel.setShowHeader(false);
-
-                val label = Wkt.label(actionPrompt.getTitleId(), actionModel::getFriendlyName);
-                actionPrompt.setTitle(label, target);
-                actionPrompt.setPanel(actionParametersPanel, target);
-                actionPrompt.showPrompt(target);
-
-                if(actionPrompt instanceof ActionPromptWithExtraContent) {
-                    final ActionPromptWithExtraContent promptWithExtraContent =
-                            (ActionPromptWithExtraContent) actionPrompt;
-
-                    final ObjectAction action = actionModel.getAction();
-                    if(action instanceof ObjectActionMixedIn) {
-                        final ObjectActionMixedIn actionMixedIn = (ObjectActionMixedIn) action;
-                        final ObjectSpecification mixinSpec = actionMixedIn.getMixinType();
-
-                        if(mixinSpec.isViewModel()) {
-
-                            val commonContext = getCommonContext();
-                            final ManagedObject targetAdapterForMixin = action.realTargetAdapter(actionModel.getActionOwner());
-                            final EntityModel entityModelForMixin =
-                                    EntityModel.ofAdapter(commonContext, targetAdapterForMixin);
+    @Override
+    public void onClick(final AjaxRequestTarget target) {
 
-                            final GridFacet facet = mixinSpec.getFacet(GridFacet.class);
-                            final Grid gridForMixin = facet.getGrid(targetAdapterForMixin);
+        _Probe.entryPoint(EntryPoint.USER_INTERACTION, "Wicket Ajax Request, "
+                + "originating from User clicking an Action Link.");
 
-                            final String extraContentId = promptWithExtraContent.getExtraContentId();
+        val actionModel = this.getActionModel();
 
-                            if(gridForMixin instanceof BS3Grid) {
-                                final BS3Grid bs3Grid = (BS3Grid) gridForMixin;
-                                final BS3GridPanel gridPanel = new BS3GridPanel(extraContentId, entityModelForMixin, bs3Grid);
-                                promptWithExtraContent.setExtraContentPanel(gridPanel, target);
-                            }
-                        }
-                    }
-                }
-
-                return actionPrompt;
+        if(actionModel.getInlinePromptContext() == null ||
+                actionModel.getPromptStyle().isDialog()) {
 
+            if(actionModel.hasParameters()) {
+                startDialogWithParams(target);
             } else {
+                executeWithoutParams();
+            }
 
+        } else {
+            startDialogInline(target);
+        }
+    }
 
-                final Page page = actionLink.getPage();
-
-                // returns true - if redirecting to new page, or repainting all components.
-                // returns false - if invalid args; if concurrency exception;
-
-                final FormExecutor formExecutor =
-                        new FormExecutorDefault(_Either.left(actionModel));
-                boolean succeeded = formExecutor.executeAndProcessResults(page, null, null, actionModel.isWithinPrompt());
-
-                if(succeeded) {
-
-                    // intercept redirect request to sign-in page
-                    Optional.ofNullable(actionModel.getObject())
-                    .ifPresent(actionResultAdapter->{
-                        val actionResultObjectType = actionResultAdapter.getSpecification().getLogicalTypeName();
-                        if(LoginRedirect.LOGICAL_TYPE_NAME.equals(actionResultObjectType)) {
-                            val commonContext = actionModel.getCommonContext();
-                            val pageClassRegistry = commonContext.lookupServiceElseFail(PageClassRegistry.class);
-                            val signInPage = pageClassRegistry.getPageClass(PageType.SIGN_IN);
-                            RequestCycle.get().setResponsePage(signInPage);
-                        }
-                    });
-
-                    // else nothing to do
-
-                    //
-                    // the formExecutor will have either redirected, or scheduled a response,
-                    // or repainted components as required
-                    //
+    private void startDialogWithParams(final AjaxRequestTarget target) {
 
-                } else {
+        val actionModel = this.getActionModel();
+        val actionLink = this;
+        val promptProvider = ActionPromptProvider.getFrom(actionLink.getPage());
+        val actionOwnerSpec = actionModel.getActionOwner().getSpecification();
+        val actionPrompt = promptProvider.getActionPrompt(actionModel.getPromptStyle(), actionOwnerSpec.getBeanSort());
 
-                    // render the target entity again
-                    //
-                    // (One way this can occur is if an event subscriber has a defect and throws an exception; in which case
-                    // the EventBus' exception handler will automatically veto.  This results in a growl message rather than
-                    // an error page, but is probably 'good enough').
-                    val targetAdapter = actionModel.getParentObject();
+        val actionParametersPanel = (ActionParametersPanel)
+                getComponentFactoryRegistry()
+                .createComponent(
+                        ComponentType.ACTION_PROMPT, actionPrompt.getContentId(), actionModel);
 
-                    final EntityPage entityPage = EntityPage.ofAdapter(getCommonContext(), targetAdapter);
+        actionParametersPanel.setShowHeader(false);
 
-                    getCommonContext().getTransactionService().flushTransaction();
+        val label = Wkt.label(actionPrompt.getTitleId(), actionModel::getFriendlyName);
+        actionPrompt.setTitle(label, target);
+        actionPrompt.setPanel(actionParametersPanel, target);
+        actionPrompt.showPrompt(target);
 
-                    // "redirect-after-post"
-                    RequestCycle.get().setResponsePage(entityPage);
+        castTo(actionPrompt, ActionPromptWithExtraContent.class)
+        .ifPresent(promptWithExtraContent->{
+            BS3GridPanel.extraContent(promptWithExtraContent.getExtraContentId(), actionModel)
+            .ifPresent(gridPanel->promptWithExtraContent.setExtraContentPanel(gridPanel, target));
+        });
+    }
 
+    private void executeWithoutParams() {
+        val actionModel = this.getActionModel();
+        val actionLink = this;
+        val page = actionLink.getPage();
+
+        // returns true - if redirecting to new page, or repainting all components.
+        // returns false - if invalid args; if concurrency exception;
+
+        final FormExecutor formExecutor =
+                new FormExecutorDefault(_Either.left(actionModel));
+        boolean succeeded = formExecutor.executeAndProcessResults(page, null, null, actionModel.isWithinPrompt());
+
+        if(succeeded) {
+
+            // intercept redirect request to sign-in page
+            Optional.ofNullable(actionModel.getObject())
+            .ifPresent(actionResultAdapter->{
+                val actionResultObjectType = actionResultAdapter.getSpecification().getLogicalTypeName();
+                if(LoginRedirect.LOGICAL_TYPE_NAME.equals(actionResultObjectType)) {
+                    val commonContext = actionModel.getCommonContext();
+                    val pageClassRegistry = commonContext.lookupServiceElseFail(PageClassRegistry.class);
+                    val signInPage = pageClassRegistry.getPageClass(PageType.SIGN_IN);
+                    RequestCycle.get().setResponsePage(signInPage);
                 }
-            }
+            });
 
+            // else nothing to do
+
+            //
+            // the formExecutor will have either redirected, or scheduled a response,
+            // or repainted components as required
+            //
 
         } else {
 
-            MarkupContainer scalarTypeContainer = inlinePromptContext.getScalarTypeContainer();
+            // render the target entity again
+            //
+            // (One way this can occur is if an event subscriber has a defect and throws an exception; in which case
+            // the EventBus' exception handler will automatically veto.  This results in a growl message rather than
+            // an error page, but is probably 'good enough').
+            val targetAdapter = actionModel.getParentObject();
+            val entityPage = EntityPage.ofAdapter(getCommonContext(), targetAdapter);
+            getCommonContext().getTransactionService().flushTransaction();
+
+            // "redirect-after-post"
+            RequestCycle.get().setResponsePage(entityPage);
+        }
+    }
 
-            getComponentFactoryRegistry().addOrReplaceComponent(scalarTypeContainer,
-                    ScalarPanelAbstract.ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, ComponentType.PARAMETERS, actionModel);
+    private void startDialogInline(final AjaxRequestTarget target) {
 
-            inlinePromptContext.getScalarIfRegular().setVisible(false);
-            inlinePromptContext.getScalarIfRegularInlinePromptForm().setVisible(true);
+        val actionModel = this.getActionModel();
+        val inlinePromptContext = actionModel.getInlinePromptContext();
+        val scalarTypeContainer = inlinePromptContext.getScalarTypeContainer();
 
-            target.add(scalarTypeContainer);
-        }
+        getComponentFactoryRegistry().addOrReplaceComponent(scalarTypeContainer,
+                ScalarPanelAbstract.ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, ComponentType.PARAMETERS, actionModel);
 
-        return null;
+        inlinePromptContext.getScalarIfRegular().setVisible(false);
+        inlinePromptContext.getScalarIfRegularInlinePromptForm().setVisible(true);
+        target.add(scalarTypeContainer);
     }
 
     // -- DEPENDENCIES