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/causeway.git
The following commit(s) were added to refs/heads/master by this push:
new 22aad05080 CAUSEWAY-3686: improved veto reduction algorithm
22aad05080 is described below
commit 22aad05080a5f7bd9cd2175526b076a1f92d0543
Author: Andi Huber <[email protected]>
AuthorDate: Thu Feb 8 09:15:53 2024 +0100
CAUSEWAY-3686: improved veto reduction algorithm
- merge veto text based on priority
---
.../commons/internal/primitives/_Ints.java | 14 +++++++++
.../causeway/core/metamodel/consent/Consent.java | 35 ++++++++++++++++++----
.../core/metamodel/consent/InteractionResult.java | 2 +-
.../scalars/ScalarPanelAdditionalButton.java | 30 +++++++++++--------
4 files changed, 63 insertions(+), 18 deletions(-)
diff --git
a/commons/src/main/java/org/apache/causeway/commons/internal/primitives/_Ints.java
b/commons/src/main/java/org/apache/causeway/commons/internal/primitives/_Ints.java
index cc706a49ce..6b3361cbf5 100644
---
a/commons/src/main/java/org/apache/causeway/commons/internal/primitives/_Ints.java
+++
b/commons/src/main/java/org/apache/causeway/commons/internal/primitives/_Ints.java
@@ -395,4 +395,18 @@ public class _Ints {
return sb.toString();
}
+ /**
+ * Compares two {@code int} values numerically.
+ * @param x the first {@code int} to compare
+ * @param y the second {@code int} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * {@code -1} if {@code x < y}; and
+ * {@code 1} if {@code x > y}
+ * @apiNote copy of {@link Integer#compress(int, int)}
+ * because their java-doc states that return values -1, +1 are not
guaranteed.
+ */
+ public static int compare(final int x, final int y) {
+ return (x < y) ? -1 : ((x == y) ? 0 : 1);
+ }
+
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java
index a92685258d..cefaee11fa 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java
@@ -19,10 +19,14 @@
package org.apache.causeway.core.metamodel.consent;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.primitives._Ints;
import
org.apache.causeway.core.metamodel.facets.object.immutable.ImmutableFacet;
import lombok.NonNull;
@@ -38,21 +42,42 @@ public interface Consent {
* Introduced to help decide whether or not to display a 'ban' icon
* in the UI, with a tooltip showing the disabled reason.
*/
- private final boolean showInUi;
+ public enum UiHint {
+ /**
+ * When prototyping, icon rendering can be suppressed via config
option.
+ */
+ NO_ICON_UNLESS_PROTOTYPING,
+ SHOW_BAN_ICON;
+ public boolean isNoIconUnlessPrototying() { return
this==NO_ICON_UNLESS_PROTOTYPING; }
+ public boolean isShowBanIcon() { return this==SHOW_BAN_ICON; }
+ /** reduce to max ordinal */
+ static UiHint reduceToMaxOrdinal(final UiHint a, final UiHint b) {
+ return b.ordinal()>a.ordinal() ? b : a;
+ }
+ }
+ private final UiHint uiHint;
private final @NonNull String string;
public static VetoReason explicit(final String reason) {
_Assert.assertTrue(_Strings.isNotEmpty(reason));
- return new VetoReason(true, reason);
+ return new VetoReason(UiHint.SHOW_BAN_ICON, reason);
}
private static VetoReason inferred(final String reason) {
_Assert.assertTrue(_Strings.isNotEmpty(reason));
- return new VetoReason(false, reason);
+ return new VetoReason(UiHint.NO_ICON_UNLESS_PROTOTYPING, reason);
}
public Optional<VetoReason> toOptional() {
return Optional.of(this);
}
- public VetoReason concatenate(final VetoReason other) {
- return new VetoReason(this.showInUi || other.showInUi, this.string
+ "; " + other.string);
+ public VetoReason reduce(final VetoReason other) {
+ final List<String> mergedText = new ArrayList<>(2);
+ switch(_Ints.compare(this.uiHint.ordinal(),
other.uiHint.ordinal())) {
+ case -1: mergedText.add(other.string); break;
+ case 0: mergedText.add(this.string);
mergedText.add(other.string); break;
+ case 1: mergedText.add(this.string); break;
+ }
+ return new VetoReason(
+ UiHint.reduceToMaxOrdinal(this.uiHint, other.uiHint),
+ mergedText.stream().collect(Collectors.joining("; ")));
}
// -- PREDEFINED REASONS
public static VetoReason editingObjectDisabledReasonNotGiven() {
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionResult.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionResult.java
index 926f139762..caa453b377 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionResult.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionResult.java
@@ -131,7 +131,7 @@ public class InteractionResult {
* If {@link #isNotVetoing()}, then returns <tt>Optional.empty()</tt>.
*/
public Optional<Consent.VetoReason> getReason() {
- return reasonBuf.stream().reduce(Consent.VetoReason::concatenate);
+ return reasonBuf.stream().reduce(Consent.VetoReason::reduce);
}
@Override
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelAdditionalButton.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelAdditionalButton.java
index fab9c356fb..8d751ccf2d 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelAdditionalButton.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelAdditionalButton.java
@@ -37,12 +37,14 @@ enum ScalarPanelAdditionalButton {
final ScalarModel scalarModel,
final RenderScenario renderScenario,
final FieldFragment fieldFragment) {
- return renderScenario!=RenderScenario.CAN_EDIT_INLINE_VIA_ACTION
+ var precondition =
renderScenario!=RenderScenario.CAN_EDIT_INLINE_VIA_ACTION;
+ return precondition
&& scalarModel.disabledReason()
- .map(InteractionVeto::getVetoConsent)
- .flatMap(Consent::getReason)
- .map(VetoReason::showInUi)
- .orElse(false);
+ .map(InteractionVeto::getVetoConsent)
+ .flatMap(Consent::getReason)
+ .map(VetoReason::uiHint)
+ .map(VetoReason.UiHint::isShowBanIcon)
+ .orElse(false);
}
},
DISABLED_REASON_PROTOTYPING {
@@ -51,14 +53,18 @@ enum ScalarPanelAdditionalButton {
final ScalarModel scalarModel,
final RenderScenario renderScenario,
final FieldFragment fieldFragment) {
- return scalarModel.getSystemEnvironment().isPrototyping()
- &&
scalarModel.getConfiguration().getViewer().getWicket().isDisableReasonExplanationInPrototypingModeEnabled()
- &&
renderScenario!=RenderScenario.CAN_EDIT_INLINE_VIA_ACTION
+ var precondition =
renderScenario!=RenderScenario.CAN_EDIT_INLINE_VIA_ACTION
+ && scalarModel.getSystemEnvironment().isPrototyping()
+ &&
scalarModel.getConfiguration().getViewer().getWicket().isDisableReasonExplanationInPrototypingModeEnabled();
+ return precondition
&& scalarModel.disabledReason()
- .map(InteractionVeto::getVetoConsent)
- .flatMap(Consent::getReason)
- .map(vetoReason->!vetoReason.showInUi())
- .orElse(false);
+ .map(InteractionVeto::getVetoConsent)
+ .flatMap(Consent::getReason)
+ .map(VetoReason::uiHint)
+ // opposite of logic in DISABLED_REASON above,
+ // because DISABLED_REASON_PROTOTYPING should only
ever activate when DISABLED_REASON is not active
+ .map(VetoReason.UiHint::isNoIconUnlessPrototying)
+ .orElse(false);
}
},
CLEAR_FIELD {