This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch 3960-row.action.visibility in repository https://gitbox.apache.org/repos/asf/causeway.git
commit c4940342b2ac07e3e309ba3d261a05ca21b790e1 Author: andi-huber <[email protected]> AuthorDate: Wed Jan 21 12:19:47 2026 +0100 CAUSEWAY-3960: fixes Actions in Tables have wrong Usability/Visibility Logic Task-Url: https://issues.apache.org/jira/browse/CAUSEWAY-3960 --- .../viewer/commons/model/action/UiActionForm.java | 14 ++++---- .../viewer/wicket/model/models/ActionModel.java | 16 ++++----- .../interaction/act/ActionInteractionWkt.java | 12 +++---- .../ActionLinksAsButtonInlinePanel.java | 2 +- .../entityactions/ActionLinksAsDropDownPanel.java | 4 +-- .../entityactions/ActionLinksPanel.java | 30 +++++++++-------- .../ui/components/attributes/AttributePanel.java | 39 +++++++++------------- .../parented/ParentedCollectionPanel.java | 2 +- .../present/ajaxtable/columns/ActionColumn.java | 10 +++--- .../wicket/ui/components/layout/bs/col/Col.java | 3 +- .../components/object/fieldset/PropertyGroup.java | 15 ++++----- .../object/header/ObjectHeaderPanel.java | 3 +- .../components/widgets/actionlink/ActionLink.java | 27 ++++++++++++--- 13 files changed, 93 insertions(+), 84 deletions(-) diff --git a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java index 2ec15693118..ec39064ff24 100644 --- a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java +++ b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java @@ -42,32 +42,30 @@ public interface UiActionForm // -- USABILITY - default Consent getUsabilityConsent() { + default Consent getUsabilityConsent(final Where where) { return getAction().isUsable( getActionOwner(), InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + where); } // -- VISABILITY - default Consent getVisibilityConsent() { + default Consent getVisibilityConsent(final Where where) { // guard against missing action owner var actionOwner = getActionOwner(); - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionOwner)) { + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionOwner)) return Veto.DEFAULT; // veto, so we don't render the action - } // check whether action owner type is hidden - if (getActionOwner().objSpec().isHidden()) { + if (getActionOwner().objSpec().isHidden()) return Veto.DEFAULT; - } return getAction().isVisible( actionOwner, InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + where); } // -- VALIDITY diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java index ac8f51d2fa2..a6a4539588b 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java @@ -134,7 +134,7 @@ public static ActionModel forEntityFromActionColumn( return ActionModel.forEntity( parentEntityModel, action.getFeatureIdentifier(), - Where.OBJECT_FORMS, + Where.ALL_TABLES, columnActionModifier, null, null, null); } @@ -153,8 +153,8 @@ public static ActionModel forCollection( public static ActionModel forPropertyOrParameter( final ObjectAction action, final UiAttributeWkt attributeModel) { - return attributeModel instanceof PropertyModel - ? forProperty(action, (PropertyModel)attributeModel) + return attributeModel instanceof PropertyModel p + ? forProperty(action, p) : forParameter(action, (ParameterModel)attributeModel); } @@ -175,14 +175,13 @@ public static ActionModel forParameter( //XXX[CAUSEWAY-3080] only supported, when parameter type is a singular composite value-type var param = parameterModel.getMetaModel(); if(param.isSingular() - && param.getElementType().isCompositeValue()) { + && param.getElementType().isCompositeValue()) return ActionModel.forEntity( parameterModel.getParentUiModel(), action.getFeatureIdentifier(), Where.OBJECT_FORMS, ColumnActionModifier.NONE, null, parameterModel, null); - } return null; } @@ -262,11 +261,11 @@ public Optional<ParameterModel> getAssociatedParameter() { } public boolean isVisible() { - return getVisibilityConsent().isAllowed(); + return getVisibilityConsent(delegate.where()).isAllowed(); } public boolean isEnabled() { - return getUsabilityConsent().isAllowed(); + return getUsabilityConsent(delegate.where()).isAllowed(); } @Override @@ -309,11 +308,10 @@ public String toString() { private static void guardAgainstNotBookmarkable(final ManagedObject objectAdapter) { var isIdentifiable = ManagedObjects.isIdentifiable(objectAdapter); - if (!isIdentifiable) { + if (!isIdentifiable) throw new IllegalArgumentException(String.format( "Object '%s' is not identifiable (has no identifier).", objectAdapter.getTitle())); - } } } diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java index 2cf1497ae99..2a72d233e0a 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java @@ -23,7 +23,6 @@ import java.util.stream.Stream; import org.apache.wicket.model.ChainingModel; - import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; @@ -46,6 +45,9 @@ import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.HasBookmarkedOwnerAbstract; +import lombok.Getter; +import lombok.experimental.Accessors; + /** * The parent (container) model of multiple <i>parameter models</i> which implement * {@link ChainingModel}. @@ -71,7 +73,7 @@ public class ActionInteractionWkt private static final long serialVersionUID = 1L; private final String memberId; - private final Where where; + @Getter @Accessors(fluent=true) private final Where where; /** * memoize, so if we only need the meta-model, @@ -153,16 +155,14 @@ protected ActionInteraction load() { associatedWithParameterIfAny.getParameterNegotiationModel(), paramIndex, memberId, where); } - if(associatedWithCollectionIfAny!=null) { + if(associatedWithCollectionIfAny!=null) return ActionInteraction.startWithMultiselect(getBookmarkedOwner(), memberId, where, associatedWithCollectionIfAny.getDataTableModel()); - } - if(associatedWithPropertyIfAny!=null) { + if(associatedWithPropertyIfAny!=null) // supports composite-value-types via mixin return ActionInteraction.startAsBoundToProperty( associatedWithPropertyIfAny.getManagedProperty(), memberId, where); - } return ActionInteraction.start(getBookmarkedOwner(), memberId, where); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsButtonInlinePanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsButtonInlinePanel.java index 65a0f6da821..ae573434888 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsButtonInlinePanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsButtonInlinePanel.java @@ -26,6 +26,6 @@ class ActionLinksAsButtonInlinePanel extends ActionLinksPanel { private static final long serialVersionUID = 1L; public ActionLinksAsButtonInlinePanel(final String id, final Can<ActionLink> links) { - super(id, links, Style.INLINE_LIST); + super(id, links, ActionPanelStyle.INLINE_LIST); } } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsDropDownPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsDropDownPanel.java index 736c4def7c5..528dadb3784 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsDropDownPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksAsDropDownPanel.java @@ -25,7 +25,7 @@ class ActionLinksAsDropDownPanel extends ActionLinksPanel { private static final long serialVersionUID = 1L; - public ActionLinksAsDropDownPanel(final String id, final Can<ActionLink> links) { - super(id, links, Style.DROPDOWN); + public ActionLinksAsDropDownPanel(final String id, final Can<ActionLink> links, final ActionPanelStyle style) { + super(id, links, style); } } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksPanel.java index 4de7779200c..bd3c5c119e5 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/entityactions/ActionLinksPanel.java @@ -20,11 +20,11 @@ import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.wicket.MarkupContainer; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.viewer.commons.model.decorators.ActionDecorators.ActionStyle; import org.apache.causeway.viewer.wicket.model.models.ActionModel; @@ -36,7 +36,7 @@ import lombok.RequiredArgsConstructor; -public class ActionLinksPanel +public abstract class ActionLinksPanel extends MenuablePanelAbstract { private static final long serialVersionUID = 1L; @@ -46,7 +46,7 @@ public class ActionLinksPanel private static final String ID_ADDITIONAL_LINK_TITLE = "additionalLinkTitle"; @RequiredArgsConstructor - public enum Style { + public enum ActionPanelStyle { INLINE_LIST(ActionStyle.BUTTON) { @Override public ActionLinksPanel newPanel(final String id, final Can<ActionLink> links) { @@ -56,7 +56,7 @@ public ActionLinksPanel newPanel(final String id, final Can<ActionLink> links) { DROPDOWN(ActionStyle.MENU_ITEM) { @Override public ActionLinksPanel newPanel(final String id, final Can<ActionLink> links) { - return new ActionLinksAsDropDownPanel(id, links); + return new ActionLinksAsDropDownPanel(id, links, DROPDOWN); } }; abstract ActionLinksPanel newPanel(String id, Can<ActionLink> links); @@ -71,8 +71,9 @@ public static ActionLinksPanel addActionLinks( final MarkupContainer markupContainer, final String id, final Can<ActionModel> links, - final Style style) { - var panel = actionLinks(id, links, style); + final ActionPanelStyle style, + final Where renderWhere) { + var panel = actionLinks(id, links, style, renderWhere); if(panel.isEmpty()) { WktComponents.permanentlyHide(markupContainer, id); return null; @@ -82,18 +83,19 @@ public static ActionLinksPanel addActionLinks( public static Optional<ActionLinksPanel> actionLinks( final String id, - final Can<ActionModel> links, - final Style style) { - if(links.isEmpty()) { - return Optional.empty(); - } - return Optional.of(style.newPanel(id, links.map(ActionLink::create))); + final Can<ActionModel> actionModels, + final ActionPanelStyle style, + final Where renderWhere) { + + return actionModels.isEmpty() + ? Optional.empty() + : Optional.of(style.newPanel(id, actionModels.map(act->ActionLink.create(act, renderWhere)))); } protected ActionLinksPanel( final String id, final Can<ActionLink> actionLinks, - final Style style) { + final ActionPanelStyle style) { super(id, actionLinks); setOutputMarkupId(true); @@ -122,7 +124,7 @@ protected final Stream<ActionLink> streamActionLinks() { } protected final List<ActionLink> listOfActionLinks() { - return streamActionLinks().collect(Collectors.toList()); + return streamActionLinks().toList(); } public final boolean hasAnyVisibleLink() { diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/AttributePanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/AttributePanel.java index bc249ff4bef..f92ffb62287 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/AttributePanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/AttributePanel.java @@ -39,6 +39,7 @@ import org.apache.causeway.applib.annotation.ActionLayout; import org.apache.causeway.applib.annotation.LabelPosition; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.collections.ImmutableEnumSet; import org.apache.causeway.commons.internal.base._Casts; @@ -147,24 +148,19 @@ public boolean isViewingAndCanEditAny() { static RenderScenario inferFrom(final AttributePanel scalarPanel) { var attributeModel = scalarPanel.attributeModel(); - if(attributeModel.getRenderingHint().isInTable()) { + if(attributeModel.getRenderingHint().isInTable()) return COMPACT; - } - if(attributeModel.isParameter()) { + if(attributeModel.isParameter()) return _Util.canParameterEnterNestedEdit(attributeModel) ? EDITING_WITH_LINK_TO_NESTED // nested/embedded dialog : EDITING; // for params always EDITING even if editing is vetoed - } // at this point we are processing a property (not a parameter) - if(attributeModel.isEditingMode()) { + if(attributeModel.isEditingMode()) return EDITING; - } - if(_Util.canPropertyEnterInlineEditDirectly(attributeModel)) { + if(_Util.canPropertyEnterInlineEditDirectly(attributeModel)) return CAN_EDIT_INLINE; - } - if(_Util.lookupPropertyActionForInlineEdit(attributeModel).isPresent()) { + if(_Util.lookupPropertyActionForInlineEdit(attributeModel).isPresent()) return CAN_EDIT_INLINE_VIA_ACTION; - } return attributeModel.disabledReason().isPresent() ? READONLY : CAN_EDIT; @@ -520,7 +516,8 @@ public void addChangeListener(final AttributeModelChangeListener listener) { protected final <T extends Behavior> void addOrReplaceBehavoir( final @NonNull Class<T> behaviorClass, final @NonNull Supplier<T> factory) { var validationFeedbackReceiver = getValidationFeedbackReceiver(); - if(validationFeedbackReceiver == null) { return; } + if(validationFeedbackReceiver == null) + return; for (var behavior : validationFeedbackReceiver.getBehaviors(behaviorClass)) { validationFeedbackReceiver.remove(behavior); } @@ -559,9 +556,8 @@ protected final void scalarNameLabelAddTo(final MarkupContainer container, final helper.visibleLabelId.ifPresent(visibleLabelId->{ final Label scalarNameLabel = Wkt.labelAdd(container, visibleLabelId, labelCaption); - if(_Strings.isNullOrEmpty(labelCaption.getObject())) { + if(_Strings.isNullOrEmpty(labelCaption.getObject())) return; - } WktDecorators.formLabel() .decorate(scalarNameLabel, FormLabelDecorationModel @@ -601,9 +597,8 @@ void hideHiddenLabels(final MarkupContainer container) { protected abstract Component getValidationFeedbackReceiver(); private void addFeedbackOnlyTo(final MarkupContainer markupContainer, final Component component) { - if(component==null) { + if(component==null) return; - } markupContainer.addOrReplace( RegularFrame.FEEDBACK.createComponent(id-> new NotificationPanel(id, component, new ComponentFeedbackMessageFilter(component)))); @@ -617,13 +612,13 @@ private void addActionLinksBelowAndRight( .filter(ActionModel.isPositionedAt(ActionLayout.Position.BELOW)); ActionLinksPanel.addActionLinks( labelIfRegular, RegularFrame.ASSOCIATED_ACTION_LINKS_BELOW.getContainerId(), - linksBelow, ActionLinksPanel.Style.INLINE_LIST); + linksBelow, ActionLinksPanel.ActionPanelStyle.INLINE_LIST, Where.OBJECT_FORMS); var linksRight = actionModels .filter(ActionModel.isPositionedAt(ActionLayout.Position.RIGHT)); ActionLinksPanel.addActionLinks( labelIfRegular, RegularFrame.ASSOCIATED_ACTION_LINKS_RIGHT.getContainerId(), - linksRight, ActionLinksPanel.Style.DROPDOWN); + linksRight, ActionLinksPanel.ActionPanelStyle.DROPDOWN, Where.OBJECT_FORMS); } /** @@ -698,18 +693,16 @@ public Repaint updateIfNecessary( onMakeNotEditable(usabilityConsent.getReasonAsString().orElse(null)); } - if (visibilityBefore != visibilityAfter) { - // repaint the param panel if visibility has changed + if (visibilityBefore != visibilityAfter) + // repaint the param panel if visibility has changed return visibilityAfter ? Repaint.REQUIRED_ON_PARENT : Repaint.REQUIRED; - } if (usabilityBefore != usabilityAfter - && visibilityAfter) { - // repaint the param panel if usability has changed, but only if visible + && visibilityAfter) + // repaint the param panel if usability has changed, but only if visible return Repaint.REQUIRED; - } return Repaint.OPTIONAL; } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java index 840e9ef5a81..62d93e33304 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java @@ -152,7 +152,7 @@ private void buildGui() { final Can<ActionModel> links = collectionModel.getLinks(); ActionLinksPanel.addActionLinks( - div, ID_ADDITIONAL_LINKS, links, ActionLinksPanel.Style.INLINE_LIST); + div, ID_ADDITIONAL_LINKS, links, ActionLinksPanel.ActionPanelStyle.INLINE_LIST, Where.OBJECT_FORMS); createSelectorDropdownPanel(collectionModel); collectionPanel.setSelectorDropdownPanel(selectorDropdownPanel); diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/ActionColumn.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/ActionColumn.java index 0f07f6af678..d1deb0b53cf 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/ActionColumn.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/ActionColumn.java @@ -21,21 +21,21 @@ import java.util.Optional; import org.apache.wicket.Component; +import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.Identifier; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.ActionModel.ColumnActionModifier; -import org.apache.causeway.viewer.wicket.model.models.coll.DataRowWkt; -import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModel.Variant; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; +import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModel.Variant; +import org.apache.causeway.viewer.wicket.model.models.coll.DataRowWkt; import org.apache.causeway.viewer.wicket.ui.components.actionlinks.entityactions.ActionLinksPanel; import org.apache.causeway.viewer.wicket.ui.util.Wkt; -import org.jspecify.annotations.NonNull; - public final class ActionColumn extends GenericColumnAbstract { @@ -83,7 +83,7 @@ protected Component createCellComponent( determineColumnActionModifier(act, elementType))) .collect(Can.toCan()); - return ActionLinksPanel.actionLinks(componentId, actionModels, ActionLinksPanel.Style.DROPDOWN) + return ActionLinksPanel.actionLinks(componentId, actionModels, ActionLinksPanel.ActionPanelStyle.DROPDOWN, Where.ALL_TABLES) .map(Component.class::cast) .orElseGet(()->Wkt.label(componentId, "")); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/layout/bs/col/Col.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/layout/bs/col/Col.java index 0bb7102a94b..c2a5fa327ec 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/layout/bs/col/Col.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/layout/bs/col/Col.java @@ -26,6 +26,7 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.Model; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.ActionLayoutData; import org.apache.causeway.applib.layout.component.CollectionLayoutData; import org.apache.causeway.applib.layout.component.DomainObjectLayoutData; @@ -132,7 +133,7 @@ private void buildGui() { .collect(Can.toCan()); if (!visibleActions.isEmpty()) { - ActionLinksPanel.addActionLinks(actionOwner, actionIdToUse, visibleActions, ActionLinksPanel.Style.INLINE_LIST); + ActionLinksPanel.addActionLinks(actionOwner, actionIdToUse, visibleActions, ActionLinksPanel.ActionPanelStyle.INLINE_LIST, Where.OBJECT_FORMS); visible = true; } else { WktComponents.permanentlyHide(actionOwner, actionIdToUse); diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/fieldset/PropertyGroup.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/fieldset/PropertyGroup.java index 1e06422b578..197ac45cead 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/fieldset/PropertyGroup.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/fieldset/PropertyGroup.java @@ -112,13 +112,15 @@ private List<Component> buildGui() { panelHeading, ID_ASSOCIATED_ACTION_LINKS_PANEL, memberGroupActions .filter(ActionModel.isPositionedAt(ActionLayout.Position.PANEL)), - ActionLinksPanel.Style.INLINE_LIST); + ActionLinksPanel.ActionPanelStyle.INLINE_LIST, + Where.OBJECT_FORMS); ActionLinksPanel.addActionLinks( panelHeading, ID_ASSOCIATED_ACTION_LINKS_PANEL_DROPDOWN, memberGroupActions .filter(ActionModel.isPositionedAt(ActionLayout.Position.PANEL_DROPDOWN)), - ActionLinksPanel.Style.DROPDOWN); + ActionLinksPanel.ActionPanelStyle.DROPDOWN, + Where.OBJECT_FORMS); } // either add the built content, or hide entire @@ -219,15 +221,12 @@ public boolean isVisible() { // TODO: should remove this hack. We need some sort of SPI for ScalarPanelAbstract2's and any other component, // (eg PdfJsViewer) that can implement. It's "probably" just a matter of having PdfJsViewer do its work in the // correct Wicket callback (probably onConfigure). - if(childComponents.size() > childScalarPanels.size()) { - return true; - } - // HACK:END + if(childComponents.size() > childScalarPanels.size()) + return true; for (final AttributePanel childComponent : childScalarPanels) { - if(childComponent.isVisibilityAllowed()) { + if(childComponent.isVisibilityAllowed()) return true; - } } return false; } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java index 88b94dfc32d..113046c46a4 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java @@ -20,6 +20,7 @@ import org.apache.wicket.Component; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -78,7 +79,7 @@ private void buildEntityActionsGui() { ActionLinksPanel .addActionLinks(this, ID_OBJECT_ACTIONS, topLevelActions, - ActionLinksPanel.Style.INLINE_LIST); + ActionLinksPanel.ActionPanelStyle.INLINE_LIST, Where.OBJECT_FORMS); } else { WktComponents.permanentlyHide(this, ID_OBJECT_ACTIONS); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java index 1d09eba3ade..f0b6c2ed2c6 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java @@ -27,6 +27,7 @@ import org.apache.wicket.request.cycle.RequestCycle; import org.jspecify.annotations.NonNull; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.internal.assertions._Assert; import org.apache.causeway.commons.internal.debug._Probe; import org.apache.causeway.commons.internal.debug._Probe.EntryPoint; @@ -81,22 +82,36 @@ public final class ActionLink private static final long serialVersionUID = 1L; private static final String ID_ACTION_LINK = "actionLink"; + public enum ActionRenderWhere { + ANYWHERE_BUT_NOT_TABLE, + TABLE_ACTION_COLUMN + } + public static ActionLink create( final @NonNull ActionModel actionModel) { + return create(actionModel, Where.OBJECT_FORMS); + } + + public static ActionLink create( + final @NonNull ActionModel actionModel, + final @NonNull Where where) { - var actionLink = new ActionLink(ID_ACTION_LINK, actionModel); + var actionLink = new ActionLink(ID_ACTION_LINK, actionModel, where); return Wkt.cssAppend(actionLink, "noVeil"); } private final AjaxIndicatorAppender indicatorAppenderIfAny; + private final Where where; // where to render the action, used to check action's usability and visibility private ActionLink( final String id, - final ActionModel model) { + final ActionModel model, + final Where where) { super(id, model); _Assert.assertNotNull(model.getAction(), "ActionLink requires an Action"); + this.where = where; this.indicatorAppenderIfAny = getSettings().useIndicatorForNoArgAction() ? new AjaxIndicatorAppender() : null; @@ -134,18 +149,20 @@ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { public String getReasonDisabledIfAny() { // no point evaluating if not visible return isVisible() - ? getActionModel().getUsabilityConsent().getReasonAsString().orElse(null) + ? getActionModel().getUsabilityConsent(where).getReasonAsString().orElse(null) : null; } @Override public boolean isVisible() { - return getActionModel().getVisibilityConsent().isAllowed(); + //TODO honor where + return getActionModel().getVisibilityConsent(where).isAllowed(); } @Override public boolean isEnabled() { - return getActionModel().getUsabilityConsent().isAllowed(); + //TODO honor where + return getActionModel().getUsabilityConsent(where).isAllowed(); } @SuppressWarnings("deprecation")
