Unsorted notes on Fulcro RAD.
If you have a :ref
attribute, you typically do not want to display it directly, i.e. its ident, but a more display-friendly prop of the child entity. This is handled automatically for you by Pathom, you only need to specify the attribute you want.
Let's assume you have a Person
entity with the ref attribute person/home-address
with the target address/id
. You can simply have ro/columns [person/name ... address/city address/country]
(assuming these attributes are defined and have :address/id
among their ao/identities
). Pathom can navigate from person/home-address -> address/id -> address/city etc.
You have a report for an entity that has a to-many :ref
attribute. Normally the value of that will be a vector of idents of the referenced entities. But you want to display something nicer - for example some other prop(s) from the child entity or a complete sub-report with these children. How to do that?
For example let's assume that you have a parent report of all Person
which has the to-many ref attribute :person/children
(with ao/target :person/id
) and want to display also the names of each person's children, i.e. :person/name
.
1) As a stringification of some display-friendly child entity props (leveraging a virtual attribute)
The simplest solution is perhaps to create a virtual (not backed by a DB column) attribute with a resolver that returns a string of the concatenated children props that you want to show in the report. Something like:
(defattr children-names :person/children-names :string
{ao/target :person/id
ao/pc-input #{:person/id}
ao/pc-output [:person/children-names]
ao/pc-resolve (fn [{:keys [parser] :as env} {parent-id :person/id}]
;; the env contains already the instance of the Pathom parser
#?(:clj
{:person/children-names
(-> (parser env [{[:person/id parent-id] [{:person/children [:person/name]}]}])
(get [:person/id parent-id])
:person/children
(->>
(map :person/name)
(str/join ", ")))}))})
You can also display the children entities in a sub report. For that, you want to take full control of the row component by providing your own ro/BodyItem
. This must both specify the complete row query (so you can include {:person/children (comp/get-query YourChildComponent)
) - and RAD will thus ignore :row-query-inclusion
and will not add form links for you - and render the body, where it can delegate to rad.report/render-row
. Inside, you can display the children entities in whatever way you want, e.g. leveraging existing report functionality.
Look at what defsc-report
is doing and how it is generating the default *-Row
BodyItem component.
Tony, 1/2021:
Customize the row [via
ro/BodyItem SomeComponent
, see this example of custom BodyItem] but you may have to switch render styles (the default is table, and list is supported). If you use table, then your element (because of DOM, not Fulcro) must be a table row. If you use list it is more general. NOTE: This is all dependent on the internals of the particular render plugin you use. Write the render body of the defsc-report yourself. All the logic is there, there are helpers in report.cljc for triggering all the logic. Render it exactly the way you want. For a special repeated pattern, it might be work making your own render plugin that you can then reuse across your app.
Do not include the person/children
attribute in the report (as it would override the row query inclusion we are about to add). Add something like ro/row-query-inclusion [{:person/children (comp/get-query YourChildComponent)]
.
Now you have the data but no column to display them. One solution is to specify a custom ::rad.report/row-style ::my-style
and having registered a component for it under :com.fulcrologic.rad/controls ::rad.report/row-style->row-layout
in all-control
. The component would be like the default TableRowLayout
but also display the children.