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 <[email protected]>
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

Reply via email to