Skip to content

Instantly share code, notes, and snippets.

@err
Forked from holyjak/fulcro-rad-notes.md
Created September 8, 2021 23:40
Show Gist options
  • Save err/cc6ef2c916c250fc8845138989f363c6 to your computer and use it in GitHub Desktop.
Save err/cc6ef2c916c250fc8845138989f363c6 to your computer and use it in GitHub Desktop.
Fulcro RAD - assorted notes

Unsorted notes on Fulcro RAD.

Reports

Displaying to-one :ref attributes

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.

Displaying to-many :ref attributes in a report column as a value or a sub-report

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 ", ")))}))})

2) As a custom component, e.g. a sub-report (leveraging a custom BodyItem)

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.

3. Leveraging row query inclusions with a custom column renderer

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment