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/01/05 21:52:33 UTC
[isis] branch master updated: ISIS-2256: fixes selection model
running out of sync with checkboxes
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 c10d4c1 ISIS-2256: fixes selection model running out of sync with checkboxes
c10d4c1 is described below
commit c10d4c1b6f6d0690f61583c956e667155b8a43bb
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Jan 5 22:52:25 2020 +0100
ISIS-2256: fixes selection model running out of sync with checkboxes
---
.../wicket/model/models/EntityCollectionModel.java | 25 +++++++++++--------
.../entityactions/EntityActionLinkFactory.java | 2 +-
.../serviceactions/ServiceActionLinkFactory.java | 2 +-
.../ui/components/collection/CollectionPanel.java | 7 +++++-
.../columns/ObjectAdapterToggleboxColumn.java | 29 +++++++++++++---------
.../widgets/checkbox/ContainedToggleboxPanel.java | 11 ++++++--
.../linkandlabel/ActionLinkFactoryAbstract.java | 8 +++---
7 files changed, 51 insertions(+), 33 deletions(-)
diff --git a/core/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java b/core/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index 62a3781..1b998af 100644
--- a/core/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ b/core/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -33,6 +34,7 @@ import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.commons.internal.factory.InstanceUtil;
import org.apache.isis.metamodel.adapter.oid.Oid;
import org.apache.isis.metamodel.adapter.oid.RootOid;
@@ -345,7 +347,7 @@ implements LinksProvider, UiHintContainer {
/**
* Populated only if {@link Type#STANDALONE}.
*/
- private List<ObjectMemento> toggledMementosList;
+ private Map<String, ObjectMemento> toggledMementos;
/**
* Populated only if {@link Type#PARENTED}.
@@ -387,7 +389,7 @@ implements LinksProvider, UiHintContainer {
this.entityModel = entityModel;
this.typeOf = typeOf;
this.pageSize = pageSize;
- this.toggledMementosList = _Lists.<ObjectMemento>newArrayList();
+ this.toggledMementos = _Maps.<String, ObjectMemento>newLinkedHashMap();
}
@@ -511,23 +513,24 @@ implements LinksProvider, UiHintContainer {
}
- public void toggleSelectionOn(ManagedObject selectedAdapter) {
+ public boolean toggleSelectionOn(ManagedObject selectedAdapter) {
//XXX lombok issue, cannot use val here
final ObjectMemento selectedAsMemento = super.getMementoService().mementoForObject(selectedAdapter);
-
- // try to remove; if couldn't, then mustn't have been in there, in which case add.
- boolean removed = toggledMementosList.remove(selectedAsMemento);
- if(!removed) {
- toggledMementosList.add(selectedAsMemento);
- }
+ final String selectedKey = selectedAsMemento.asString();
+ final ObjectMemento newValue =
+ toggledMementos.compute(selectedKey, (k, v) -> (v==null) ? selectedAsMemento : null);
+
+ final boolean isSelected = newValue!=null;
+ return isSelected;
+
}
public Can<ObjectMemento> getToggleMementosList() {
- return Can.ofCollection(this.toggledMementosList);
+ return Can.ofCollection(this.toggledMementos.values());
}
public void clearToggleMementosList() {
- this.toggledMementosList.clear();
+ this.toggledMementos.clear();
}
public void addLinkAndLabels(List<LinkAndLabel> linkAndLabels) {
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
index b817bcf..81a2958 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/entityactions/EntityActionLinkFactory.java
@@ -60,7 +60,7 @@ public final class EntityActionLinkFactory extends ActionLinkFactoryAbstract {
// previously we computed visibility and enablement here, but
// this is now done at the point of rendereing
- final AbstractLink link = newLink(linkId, objectAction, toggledMementosProviderIfAny);
+ final AbstractLink link = super.newLink(linkId, objectAction, toggledMementosProviderIfAny);
return newLinkAndLabel(objectAdapter, objectAction, link);
}
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionLinkFactory.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionLinkFactory.java
index ce01cee..fa9fed7 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionLinkFactory.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionLinkFactory.java
@@ -45,7 +45,7 @@ class ServiceActionLinkFactory extends ActionLinkFactoryAbstract {
val objectAdapter = this.targetEntityModel.load();
- final AbstractLink link = newLink(linkId, objectAction, toggledMementosProviderIfAny);
+ final AbstractLink link = super.newLink(linkId, objectAction, toggledMementosProviderIfAny);
return newLinkAndLabel(objectAdapter, objectAction, link);
}
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
index 5a45366..57c4e64 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
@@ -44,6 +44,7 @@ import org.apache.isis.viewer.wicket.ui.components.collection.selector.Collectio
import org.apache.isis.viewer.wicket.ui.components.collection.selector.CollectionSelectorProvider;
import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.columns.ObjectAdapterToggleboxColumn;
import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
+import org.apache.isis.viewer.wicket.ui.components.widgets.checkbox.ContainedToggleboxPanel;
import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
import org.apache.isis.webapp.context.memento.ObjectMemento;
@@ -157,7 +158,11 @@ implements CollectionSelectorProvider, BulkActionsProvider {
final Component context,
final ManagedObject selectedAdapter,
final AjaxRequestTarget ajaxRequestTarget) {
- getModel().toggleSelectionOn(selectedAdapter);
+
+ ContainedToggleboxPanel togglePanel = (ContainedToggleboxPanel) context;
+
+ boolean isSelected = getModel().toggleSelectionOn(selectedAdapter);
+ togglePanel.setModel(isSelected); // sync the checkbox's model
}
};
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
index 37eb544..a6a1b9f 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/columns/ObjectAdapterToggleboxColumn.java
@@ -69,18 +69,26 @@ public final class ObjectAdapterToggleboxColumn extends ColumnAbstract<ManagedOb
@Override
public Component getHeader(String componentId) {
- final ContainedToggleboxPanel toggle = new ContainedToggleboxPanel(componentId) {
+ final ContainedToggleboxPanel bulkToggle = new ContainedToggleboxPanel(componentId) {
private static final long serialVersionUID = 1L;
@Override
public void onSubmit(AjaxRequestTarget target) {
- for (ContainedToggleboxPanel toggle : rowToggles) {
- toggle.toggle(target);
- target.add(toggle);
+ final boolean setToChecked = !this.isChecked();
+
+ for (ContainedToggleboxPanel rowToggle : rowToggles) {
+
+ // smart update idiom: only toggle when needed
+ if(setToChecked == rowToggle.isChecked()) {
+ continue;
+ }
+
+ rowToggle.toggle(target);
+ target.add(rowToggle);
}
}
};
- toggle.add(new CssClassAppender("title-column"));
- return toggle;
+ bulkToggle.add(new CssClassAppender("title-column"));
+ return bulkToggle;
}
private final List<ContainedToggleboxPanel> rowToggles = _Lists.newArrayList();
@@ -101,12 +109,9 @@ public final class ObjectAdapterToggleboxColumn extends ColumnAbstract<ManagedOb
@Override
public void onSubmit(AjaxRequestTarget target) {
val entityModel = (EntityModel) rowModel;
- ManagedObject selectedAdapter = null;
- {
- selectedAdapter = entityModel.load();
- if(onSelectionHandler != null) {
- onSelectionHandler.onSelected(this, selectedAdapter, target);
- }
+ val selectedAdapter = entityModel.load();
+ if(onSelectionHandler != null) {
+ onSelectionHandler.onSelected(this, selectedAdapter, target);
}
}
};
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
index aa5e643..12302ea 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/checkbox/ContainedToggleboxPanel.java
@@ -77,9 +77,16 @@ public class ContainedToggleboxPanel extends PanelAbstract<Model<Boolean>> {
* @param target
*/
public void toggle(AjaxRequestTarget target) {
- checkbox.setModelObject(!checkbox.getModelObject());
- final boolean checkboxValue = checkbox.getModelObject();
+ setModel(!isChecked());
onSubmit(target);
}
+
+ public boolean isChecked() {
+ return checkbox.getModelObject();
+ }
+
+ public void setModel(boolean isChecked) {
+ checkbox.setModelObject(isChecked);
+ }
}
diff --git a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
index 9c92a41..49858a0 100644
--- a/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
+++ b/core/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
@@ -17,9 +17,6 @@
package org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel;
-import java.io.Serializable;
-import java.util.function.Function;
-
import org.apache.wicket.Application;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.Page;
@@ -107,8 +104,9 @@ public abstract class ActionLinkFactoryAbstract implements ActionLinkFactory {
val actionPrompt = ActionParameterDefaultsFacetFromAssociatedCollection
.applyWithSelected(
selectedPojos,
- //TODO[2253] can we remove the Serializable cast?
- (Function<AjaxRequestTarget, ActionPrompt>&Serializable) this::performOnClick,
+ // if this lambda still needs to be serializable uncomment the cast ...
+ //(Function<AjaxRequestTarget, ActionPrompt>&Serializable)
+ this::performOnClick,
target);
if(actionPrompt != null) {