You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2023/04/12 18:22:50 UTC
[causeway] branch master updated: CAUSEWAY-2485: reworks @ActionLayout#associateWith
This is an automated email from the ASF dual-hosted git repository.
danhaywood 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 0c33bb5319 CAUSEWAY-2485: reworks @ActionLayout#associateWith
0c33bb5319 is described below
commit 0c33bb531937dcb9fdab8f44e09a7dadcd4047f2
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Apr 12 19:22:12 2023 +0100
CAUSEWAY-2485: reworks @ActionLayout#associateWith
---
.../actions/Action/typeOf/ActionTypeOfPage.java | 2 +-
.../actions/ActionLayout/ActionLayoutMenu.java | 16 +++-
.../ActionLayoutAssociateWithPage-description.adoc | 31 ++++++--
.../ActionLayoutAssociateWithPage.java | 91 +++++++++++++++-------
.../ActionLayoutAssociateWithPage.layout.xml | 32 ++++----
...ionLayoutAssociateWithChildVm-description.adoc} | 20 +----
.../child/ActionLayoutAssociateWithChildVm.java | 57 ++++++++++++++
.../ActionLayoutAssociateWithChildVm.layout.xml} | 20 +----
8 files changed, 174 insertions(+), 95 deletions(-)
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage.java
index 6b88d0a47f..07979c6601 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/typeOf/ActionTypeOfPage.java
@@ -44,7 +44,7 @@ import lombok.NoArgsConstructor;
@XmlRootElement(name = "root")
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
-@Named("demo.ActionTypeOfVm")
+@Named("demo.ActionTypeOfPage")
@DomainObject(
nature=Nature.VIEW_MODEL)
@NoArgsConstructor
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/ActionLayoutMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/ActionLayoutMenu.java
index 0e94c934c1..e7f8b5cd9b 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/ActionLayoutMenu.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/ActionLayoutMenu.java
@@ -18,6 +18,7 @@
*/
package demoapp.dom.domain.actions.ActionLayout;
+import javax.inject.Inject;
import javax.inject.Named;
import org.apache.causeway.applib.annotation.Action;
@@ -27,7 +28,10 @@ import org.apache.causeway.applib.annotation.NatureOfService;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.annotation.SemanticsOf;
+import demoapp.dom._infra.samples.NameSamples;
+import demoapp.dom.domain.actions.Action.typeOf.child.ActionTypeOfChildVm;
import demoapp.dom.domain.actions.ActionLayout.associateWith.ActionLayoutAssociateWithPage;
+import demoapp.dom.domain.actions.ActionLayout.associateWith.child.ActionLayoutAssociateWithChildVm;
import demoapp.dom.domain.actions.ActionLayout.cssClass.ActionLayoutCssClassPage;
import demoapp.dom.domain.actions.ActionLayout.cssClassFa.ActionLayoutCssClassFaPage;
import demoapp.dom.domain.actions.ActionLayout.describedAs.ActionLayoutDescribedAsPage;
@@ -38,18 +42,26 @@ import demoapp.dom.domain.actions.ActionLayout.position.ActionLayoutPositionPage
import demoapp.dom.domain.actions.ActionLayout.promptStyle.ActionLayoutPromptStylePage;
import demoapp.dom.domain.actions.ActionLayout.redirectPolicy.ActionLayoutRedirectPolicyPage;
import demoapp.dom.domain.actions.ActionLayout.sequence.ActionLayoutSequencePage;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
@DomainService(nature=NatureOfService.VIEW)
@Named("demo.ActionLayoutMenu")
@javax.annotation.Priority(PriorityPrecedence.EARLY)
-//@Log4j2
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
public class ActionLayoutMenu {
+ final NameSamples samples;
+
@Action(semantics = SemanticsOf.SAFE)
@ActionLayout(cssClassFa="fa-solid fa-arrows-left-right",
describedAs = "Associate an action with a property or collection, specifying its id")
public ActionLayoutAssociateWithPage associateWith(){
- return new ActionLayoutAssociateWithPage();
+ val page = new ActionLayoutAssociateWithPage();
+ samples.stream()
+ .map(ActionLayoutAssociateWithChildVm::new)
+ .forEach(e -> page.getChildren().add(e));
+ return page;
}
@Action(semantics = SemanticsOf.SAFE)
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc
index 85615d9b64..97d7b676ae 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc
@@ -1,21 +1,38 @@
:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-The `associateWith` attribute associates an action with a property or collection, specifying its id.
+It's quite common for a domain object action to only change one part of a domain object's (visible) state.
+For example, an action might be used to change a name, or a pair of actions be used to add or remove elements from a collection.
+In such cases, it generally makes sense for the action's button to be close to the property or collection to which it relates.
+
+One way to specify this is with the `.layout.xml` files, but another option is to use the link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/ActionLayout.html#associatewith[@ActionLayout#associateWith] element (along with link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/ActionLayout.html#associatewith[@ActionLayout#sequence] if there are several actions associated with the property/collection).
+
+=== How this demo works
+
+This page defines a `name` property, and a `children` collection:
[source,java,indent=0]
----
-include::ActionLayoutAssociateWithPage.java[tags=act_and_prop]
+include::ActionLayoutAssociateWithPage.java[tags=class]
----
-<.> associates this action `'act'` with property `'property'`
+The `updateName` action only updates the `name` property, and so it makes sense to render its button close to this property.
+This is done using `@Action#associateWith`:
+
+[source,java,indent=0]
+----
+include::ActionLayoutAssociateWithPage.java[tags=associate-with-property]
+----
+<.> associates with the `name` property
-To specify the layout order use `ActionLayout#sequence()`.
+Similarly, the `addChild` and `removeChild` actions both modify the `children` collection:
-.for example
+[source,java,indent=0]
----
-@ActionLayout(associateWith="items") @ActionLayout(sequence="2.1")
+include::ActionLayoutAssociateWithPage.java[tags=associate-with-collection]
----
+<.> associates with the `children` collection
+<.> uses `sequence` to specify the order on the page (left to right)
-Note that it is also possible to associate an action with a collection using `Action#choicesFrom`,
+TIP: Note that it is also possible to associate an action with a collection using `Action#choicesFrom`,
which has the additional semantic of the rows of the element being used as choices for that action’s collection parameter
of the same type as the elements of the collection.
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.java
index e394c3c25e..1ac03dc5a5 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.java
@@ -19,54 +19,87 @@
package demoapp.dom.domain.actions.ActionLayout.associateWith;
import javax.inject.Named;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.*;
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
-import org.apache.causeway.applib.annotation.DomainObject;
-import org.apache.causeway.applib.annotation.Nature;
-import org.apache.causeway.applib.annotation.ObjectSupport;
-import org.apache.causeway.applib.annotation.Property;
+import org.apache.causeway.applib.annotation.*;
import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import demoapp.dom.domain.actions.Action.typeOf.child.ActionTypeOfChildVm;
+import demoapp.dom.domain.actions.ActionLayout.associateWith.child.ActionLayoutAssociateWithChildVm;
import lombok.Getter;
import lombok.Setter;
-//tag::class[]
-@DomainObject(
- nature=Nature.VIEW_MODEL)
-@Named("demo.ActionLayoutAssociateWithVm")
+import java.util.ArrayList;
+import java.util.List;
+
+@Named("demo.ActionLayoutAssociateWithPage")
+@DomainObject(nature=Nature.VIEW_MODEL)
@XmlRootElement(name = "root")
-@XmlType
+@XmlType()
@XmlAccessorType(XmlAccessType.FIELD)
-public class ActionLayoutAssociateWithPage implements HasAsciiDocDescription {
+//tag::class[]
+// ...
+public class ActionLayoutAssociateWithPage
+//end::class[]
+ implements HasAsciiDocDescription
+//tag::class[]
+{
+ @Property
+ @XmlElement
+ @Getter @Setter
+ private String name;
+
+ @Collection()
+ @XmlElement
+ @Getter
+ private List<ActionLayoutAssociateWithChildVm> children = new ArrayList<>();
+
+ // ...
+//end::class[]
@ObjectSupport public String title() {
return "@ActionLayout#associateWith";
}
-//tag::act_and_prop[]
+
+//tag::associate-with-property[]
@Action
@ActionLayout(
- associateWith = "property" // <.>
-//end::act_and_prop[]
- ,describedAs = "@ActionLayout(associateWith = \"property\")"
-//tag::act_and_prop[]
- )
- public Object act(final String arg) {
+ associateWith = "name" // <.>
+ )
+ public Object updateName(final String newValue) {
+ setName(newValue);
return this;
}
+ public String default0UpdateName() { return getName(); }
- @Property
- @XmlElement
- @Getter @Setter
- private String property = "a property";
-//end::act_and_prop[]
+//end::associate-with-property[]
+//tag::associate-with-collection[]
+ @Action
+ @ActionLayout(
+ associateWith = "children", // <.>
+ sequence = "1" // <.>
+ )
+ public Object addChild(final String newValue) {
+ getChildren().add(new ActionLayoutAssociateWithChildVm(newValue));
+ return this;
+ }
+ @Action
+ @ActionLayout(
+ associateWith = "children", // <1>
+ sequence = "2" // <2>
+ )
+ public Object removeChild(final ActionLayoutAssociateWithChildVm child) {
+ getChildren().removeIf(x -> x.getValue().equals(child.getValue()));
+ return this;
+ }
+ public List<ActionLayoutAssociateWithChildVm> choices0RemoveChild() {
+ return getChildren();
+ }
+//end::associate-with-collection[]
+
+//tag::class[]
}
//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml
index b7b4ab6651..670bbc997d 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml
@@ -26,25 +26,19 @@
<bs3:row>
<bs3:col span="6">
- <cpt:fieldSet name="General" id="general"/>
- <cpt:fieldSet name="Annotated" id="annotated"/>
- <cpt:fieldSet name="Layout" id="layout">
- <cpt:action id="layoutPanel" position="PANEL">
- <cpt:named>Positioned on panel</cpt:named>
- </cpt:action>
- <cpt:action id="layoutPanelDropDown" position="PANEL_DROPDOWN">
- <cpt:named>Positioned on panel in drop down</cpt:named>
- </cpt:action>
- <cpt:property id="readOnlyProperty2">
- <cpt:action id="layoutBelow" position="BELOW">
- <cpt:named>Positioned below</cpt:named>
- </cpt:action>
- <cpt:action id="layoutRight" position="RIGHT">
- <cpt:named>Positioned right</cpt:named>
- </cpt:action>
- </cpt:property>
- </cpt:fieldSet>
- <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+ <bs3:row>
+ <bs3:col span="12">
+ <cpt:fieldSet name="General" id="general">
+ <cpt:property id="property"/>
+ </cpt:fieldSet>
+ <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="12">
+ <cpt:collection id="children"/>
+ </bs3:col>
+ </bs3:row>
</bs3:col>
<bs3:col span="6">
<cpt:fieldSet name="Description" id="description" >
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm-description.adoc
similarity index 52%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm-description.adoc
index 85615d9b64..bfbe31aec3 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm-description.adoc
@@ -1,21 +1,3 @@
:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-The `associateWith` attribute associates an action with a property or collection, specifying its id.
-
-[source,java,indent=0]
-----
-include::ActionLayoutAssociateWithPage.java[tags=act_and_prop]
-----
-
-<.> associates this action `'act'` with property `'property'`
-
-To specify the layout order use `ActionLayout#sequence()`.
-
-.for example
-----
-@ActionLayout(associateWith="items") @ActionLayout(sequence="2.1")
-----
-
-Note that it is also possible to associate an action with a collection using `Action#choicesFrom`,
-which has the additional semantic of the rows of the element being used as choices for that action’s collection parameter
-of the same type as the elements of the collection.
+This child object exists just to act as the element of the collections of the `ActionLayoutAssociateWithPage` demo object.
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.java
new file mode 100644
index 0000000000..a3ec3477cb
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package demoapp.dom.domain.actions.ActionLayout.associateWith.child;
+
+import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.inject.Named;
+import javax.xml.bind.annotation.*;
+
+import org.apache.causeway.applib.annotation.*;
+
+//tag::class[]
+@XmlRootElement(name = "child")
+@XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
+@Named("demo.ActionLayoutAssociateWithChildVm")
+@DomainObject(nature=Nature.VIEW_MODEL)
+@NoArgsConstructor
+public class ActionLayoutAssociateWithChildVm implements HasAsciiDocDescription {
+
+ public ActionLayoutAssociateWithChildVm(final String value) {
+ setValue(value);
+ }
+
+ @ObjectSupport public String title() {
+ return getValue();
+ }
+
+ @Property()
+ @PropertyLayout(fieldSetId = "annotation", sequence = "1")
+ @XmlElement(required = false)
+ @Getter @Setter
+ private String value;
+
+
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.layout.xml
similarity index 78%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.layout.xml
index b7b4ab6651..2441ccf9e7 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/ActionLayoutAssociateWithPage.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/associateWith/child/ActionLayoutAssociateWithChildVm.layout.xml
@@ -15,6 +15,7 @@
xmlns:cpt="https://causeway.apache.org/applib/layout/component"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
<bs3:row>
<bs3:col span="10" unreferencedActions="true">
<cpt:domainObject />
@@ -26,24 +27,7 @@
<bs3:row>
<bs3:col span="6">
- <cpt:fieldSet name="General" id="general"/>
- <cpt:fieldSet name="Annotated" id="annotated"/>
- <cpt:fieldSet name="Layout" id="layout">
- <cpt:action id="layoutPanel" position="PANEL">
- <cpt:named>Positioned on panel</cpt:named>
- </cpt:action>
- <cpt:action id="layoutPanelDropDown" position="PANEL_DROPDOWN">
- <cpt:named>Positioned on panel in drop down</cpt:named>
- </cpt:action>
- <cpt:property id="readOnlyProperty2">
- <cpt:action id="layoutBelow" position="BELOW">
- <cpt:named>Positioned below</cpt:named>
- </cpt:action>
- <cpt:action id="layoutRight" position="RIGHT">
- <cpt:named>Positioned right</cpt:named>
- </cpt:action>
- </cpt:property>
- </cpt:fieldSet>
+ <cpt:fieldSet name="Annotation" id="variants"/>
<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
</bs3:col>
<bs3:col span="6">