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
commit 7d5fa0a83195da8faa7f6a22b01c1c888511a5f4 Author: danhaywood <[email protected]> AuthorDate: Thu Apr 13 07:20:17 2023 +0100 CAUSEWAY-2485: reworks @Action#cssClass --- .../ActionLayoutCssClassPage-description.adoc | 124 ++++++++++++++++++++- .../cssClass/ActionLayoutCssClassPage.java | 113 ++++++++++++++++--- .../ActionLayoutCssClassFaPage-description.adoc | 39 ++++++- .../cssClassFa/ActionLayoutCssClassFaPage.java | 25 ++--- 4 files changed, 266 insertions(+), 35 deletions(-) diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage-description.adoc index 0324c12cc4..c841833134 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage-description.adoc @@ -1,12 +1,128 @@ :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 `cssClass` attribute indicates the CSS class (or classes) that an action should (additionally) have. +To help the end-user navigate a page, it can sometimes be helpful to style individual actions so that their purpose is more obvious. -For the _Wicket Viewer_, this can be a _Bootstrap_ class such as `btn-info`. +The link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/ActionLayout.html#cssclass[@ActionLayout#cssClass] allows a CSS style (or styles) to be defined. + +One option is to reference a style that you have defined yourself in the `application.css` file. +Alternatively, you can exploit the fact that the Wicket viewer uses the link:https://getbootstrap.com/[bootstrap] design system, and so just use one of the styles defined there, for example, the link:https://getbootstrap.com/docs/5.0/components/buttons/#button-tags[button tags] + + +=== How this demo works + +This page defines a single `name` property along with a set of actions, all of which can be used to update that property. +Those actions are rendered in a number of different positions, all using a different _Bootstrap_ class. + +==== Positioned below the property + +Two actions: + +* `btn-info`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=below-btn-info] +---- +<.> appends the `btn-info` CSS class to the action's button, in effect rendering it with _Bootstrap_ `Info` style +<.> when an action is associated with a property, then by default it is rendered below that property; so strictly speaking this element is not required. + +* and `btn-warning`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=below-btn-warning] +---- +<.> appends the `btn-warning` CSS class to the action's button, in effect rendering it with _Bootstrap_ `Warning` style +<.> specifies the order in which associated actions in the same position are rendered + + +==== Positioned on the panel that contains the property + +Two actions: + +* `btn-primary`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=panel-btn-primary] +---- +<.> appends the `btn-primary` CSS class +<.> positions on the containing panel. +(The panel is called the `<fieldset>` if using `.layout.xml`). + +* and `btn-secondary`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=panel-btn-secondary] +---- +<.> appends the `btn-warning` CSS class to the action's button, in effect rendering it with _Bootstrap_ `Warning` style +<.> specifies the order in which associated actions in the same position are rendered + + +==== Positioned on the drop-down of the panel that contains the property: + +WARNING: although the CSS class is applied, the Bootstrap styling does not apply; see link:https://issues.apache.org/jira/browse/CAUSEWAY-3427[CAUSEWAY-3427]. + +Two actions: + +* `btn-light`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=panel-dropdown-btn-light] +---- +<.> appends the `btn-light` CSS class +<.> positions on the drop-down of the panel. + +* and `btn-dark`: ++ +[source,java,indent=0] +---- +include::ActionLayoutCssClassPage.java[tags=panel-dropdown-btn-dark] +---- +<.> appends the `btn-dark` CSS class + +==== At the object level + +One action: [source,java,indent=0] ---- -include::ActionLayoutCssClassPage.java[tags=act] +include::ActionLayoutCssClassPage.java[tags=delete] ---- -<.> appends the `btn-info` CSS class to the action's button and in effect renders it with _Bootstrap_ `Info` style +Yhis last example has no `@ActionLayout#cssClass` defined, but it nevertheless will be rendered with the _Bootstrap_ "btn-danger" class. +This is because it picks up the global configuration property, as described in the next section. + + +=== Related configuration properties + +Rather than styling each action individually, it's possible to use a configuration property which defines styles globally. + +It works by specifying a set of `regex:CSS` pairs; if the action's identifier matches the regex, then the CSS is applied. +This is a great way to ensure that actions with similar semantics have similar names; they will then pick up the same visual cues. + +The following is taken from this demo app: + +[source,yaml] +.application.yml +---- +causeway: + applib: + annotation: + action-layout: + css-class: + patterns: + delete.*:btn-danger <.> +---- +<.> This is a comma separated field. + +This is the reason why the "delete" action (shown in the previous section) is rendered using "btn-danger". + + +=== .layout.xml + +Instead of using `@ActionLayout#cssClass`, it is also possible to specify the CSS class using the `<action id="..." cssClass="...">` in the link:https://causeway.apache.org/userguide/2.0.0-RC1/fun/ui.html#by-example[.layout.xml] file. + +One advantage of using the `.layout.xml` file is that changes can be picked up without having to restart the application. diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage.java index 8386715e1c..6873e2b804 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClass/ActionLayoutCssClassPage.java @@ -19,18 +19,13 @@ package demoapp.dom.domain.actions.ActionLayout.cssClass; import javax.inject.Named; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -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.*; import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; +import lombok.Getter; +import lombok.Setter; //tag::class[] @DomainObject( @@ -45,18 +40,102 @@ public class ActionLayoutCssClassPage implements HasAsciiDocDescription { return "@ActionLayout#cssClass"; } -//tag::act[] + @Property + @XmlElement + @Getter + @Setter + private String name; + +//tag::below-btn-info[] + @Action + @ActionLayout( + cssClass = "btn-info", // <.> + associateWith = "name", + sequence = "1", + position = ActionLayout.Position.BELOW // <.> + ) + public Object updateNameBtnInfo(final String newName) { + setName(newName); + return this; + } +//end::below-btn-info[] + +//tag::below-btn-warning[] @Action @ActionLayout( - cssClass = "btn-info" // <.> -//end::act[] - ,describedAs = "@ActionLayout(cssClass = \"btn-info\")" -//tag::act[] - ) - public Object act(final String arg) { + cssClass = "btn-warning", // <.> + associateWith = "name", + sequence = "2", // <.> + position = ActionLayout.Position.BELOW + ) + public Object updateNameBtnWarning(final String newName) { + setName(newName); + return this; + } +//end::below-btn-warning[] + +//tag::panel-btn-primary[] + @Action + @ActionLayout( + cssClass = "btn-primary", // <.> + associateWith = "name", + sequence = "1", + position = ActionLayout.Position.PANEL // <.> + ) + public Object updateNameFromPanelBtnPrimary(final String newName) { + setName(newName); + return this; + } +//end::panel-btn-primary[] + +//tag::panel-btn-secondary[] + @Action + @ActionLayout( + cssClass = "btn-secondary", // <.> + associateWith = "name", + sequence = "2", + position = ActionLayout.Position.PANEL + ) + public Object updateNameFromPanelBtnSecondary(final String newName) { + setName(newName); + return this; + } +//end::panel-btn-secondary[] + +//tag::panel-dropdown-btn-light[] + @Action + @ActionLayout( + cssClass = "btn-light", // <.> + associateWith = "name", + sequence = "1", + position = ActionLayout.Position.PANEL_DROPDOWN // <.> + ) + public Object updateNameFromPanelDropdownBtnLight(final String newName) { + setName(newName); + return this; + } +//end::panel-dropdown-btn-light[] + +//tag::panel-dropdown-btn-dark[] + @Action + @ActionLayout( + cssClass = "btn-dark", // <.> + associateWith = "name", + sequence = "2", + position = ActionLayout.Position.PANEL_DROPDOWN + ) + public Object updateNameFromPanelDropdownBtnDark(final String newName) { + setName(newName); + return this; + } +//end::panel-dropdown-btn-dark[] + +//tag::delete[] + @Action(semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE) + public Object delete() { return this; } -//end::act[] +//end::delete[] } //end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage-description.adoc index 5ece0d907b..214b72da36 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage-description.adoc +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage-description.adoc @@ -1,6 +1,12 @@ :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 `cssClassFa` attribute indicates the _Font Awesome_ CSS class (or classes) to decorate an action (button or menu item). +It's quite common for user interfaces to include an icon for each action or menu item as a visual clue as to the purpose of that action. +The link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/ActionLayout.html#cssclassfa[@ActionLayout#cssClassFa] element allows this to be done by specifying the _Font Awesome_ CSS class (or classes) with which to decorate an action. +This is used for whether the action is rendered as a button or as a menu item. + +=== How this demo works + +This page includes two actinos [source,java,indent=0] ---- @@ -11,3 +17,34 @@ include::ActionLayoutCssClassFaPage.java[tags=actLeftAndRight] <.> the `cssClassFaPosition` attribute indicates the position of the _Font Awesome_ icon; in effect the icon is rendered on the _right_ of the action button + + +==== Related configuration property + +[source,yaml] +.application.yml +---- +causeway: + + applib: + annotation: + action: + execution-publishing: none + command-publishing: none + action-layout: + css-class-fa: + patterns: + new.*:fa-plus, + add.*:fa-plus-square, + create.*:fa-plus, + update.*:fa-edit, + delete.*:fa-trash, + find.*:fa-search, + list.*:fa-list, + all.*:fa-list, + export.*:fa-file-export, + import.*:fa-file-import + css-class: + patterns: + delete.*:btn-danger +---- diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage.java index 212d22fc81..6afb263ee4 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/ActionLayout/cssClassFa/ActionLayoutCssClassFaPage.java @@ -19,19 +19,14 @@ package demoapp.dom.domain.actions.ActionLayout.cssClassFa; import javax.inject.Named; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -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.*; import org.apache.causeway.applib.layout.component.CssClassFaPosition; import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; +import lombok.Getter; +import lombok.Setter; //tag::class[] @DomainObject( @@ -46,15 +41,19 @@ public class ActionLayoutCssClassFaPage implements HasAsciiDocDescription { return "@ActionLayout#cssClassFa"; } + @Property + @XmlElement + @Getter + @Setter + private String name; + + //tag::actLeftAndRight[] @Action @ActionLayout( cssClassFa = "fa-bus" // <.> -//end::actLeftAndRight[] - ,describedAs = "@ActionLayout(cssClassFa = \"fa-bus\")" -//tag::actLeftAndRight[] ) - public Object actLeft(final String arg) { + public Object actionWithFaIconOnTheLeft(final String arg) { return this; }
