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